⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sysacls.c

📁 Rsync 3.0.5 source code
💻 C
📖 第 1 页 / 共 5 页
字号:
 * aclp           - Array of ACL structures. * acl_type_count - Pointer to acl_types structure. Should already be *                  allocated. * Output:  * * acl_type_count - This structure is filled up with counts of various  *                  acl types. */static void hpux_count_obj(int acl_count, struct acl *aclp, struct hpux_acl_types *acl_type_count){	int i;	memset(acl_type_count, 0, sizeof(struct hpux_acl_types));	for(i=0;i<acl_count;i++) {		switch(aclp[i].a_type) {		case USER: 			acl_type_count->n_user++;			break;		case USER_OBJ: 			acl_type_count->n_user_obj++;			break;		case DEF_USER_OBJ: 			acl_type_count->n_def_user_obj++;			break;		case GROUP: 			acl_type_count->n_group++;			break;		case GROUP_OBJ: 			acl_type_count->n_group_obj++;			break;		case DEF_GROUP_OBJ: 			acl_type_count->n_def_group_obj++;			break;		case OTHER_OBJ: 			acl_type_count->n_other_obj++;			break;		case DEF_OTHER_OBJ: 			acl_type_count->n_def_other_obj++;			break;		case CLASS_OBJ:			acl_type_count->n_class_obj++;			break;		case DEF_CLASS_OBJ:			acl_type_count->n_def_class_obj++;			break;		case DEF_USER:			acl_type_count->n_def_user++;			break;		case DEF_GROUP:			acl_type_count->n_def_group++;			break;		default: 			acl_type_count->n_illegal_obj++;			break;		}	}}/* swap_acl_entries:  Swaps two ACL entries.  * * Inputs: aclp0, aclp1 - ACL entries to be swapped. */static void hpux_swap_acl_entries(struct acl *aclp0, struct acl *aclp1){	struct acl temp_acl;	temp_acl.a_type = aclp0->a_type;	temp_acl.a_id = aclp0->a_id;	temp_acl.a_perm = aclp0->a_perm;	aclp0->a_type = aclp1->a_type;	aclp0->a_id = aclp1->a_id;	aclp0->a_perm = aclp1->a_perm;	aclp1->a_type = temp_acl.a_type;	aclp1->a_id = temp_acl.a_id;	aclp1->a_perm = temp_acl.a_perm;}/* prohibited_duplicate_type * Identifies if given ACL type can have duplicate entries or  * not. * * Inputs: acl_type - ACL Type. * * Outputs:  * * Return..  * * True - If the ACL type matches any of the prohibited types. * False - If the ACL type doesn't match any of the prohibited types. */ static BOOL hpux_prohibited_duplicate_type(int acl_type){	switch(acl_type) {		case USER:		case GROUP:		case DEF_USER: 		case DEF_GROUP:			return True;		default:			return False;	}}/* get_needed_class_perm * Returns the permissions of a ACL structure only if the ACL * type matches one of the pre-determined types for computing  * CLASS_OBJ permissions. * * Inputs: aclp - Pointer to ACL structure. */static int hpux_get_needed_class_perm(struct acl *aclp){	switch(aclp->a_type) {		case USER: 		case GROUP_OBJ: 		case GROUP: 		case DEF_USER_OBJ: 		case DEF_USER:		case DEF_GROUP_OBJ: 		case DEF_GROUP:		case DEF_CLASS_OBJ:		case DEF_OTHER_OBJ: 			return aclp->a_perm;		default: 			return 0;	}}/* acl_sort for HPUX. * Sorts the array of ACL structures as per the description in * aclsort man page. Refer to aclsort man page for more details * * Inputs: * * acl_count - Count of ACLs in the array of ACL structures. * calclass  - If this is not zero, then we compute the CLASS_OBJ *             permissions. * aclp      - Array of ACL structures. * * Outputs: * * aclp     - Sorted array of ACL structures. * * Outputs: * * Returns 0 for success -1 for failure. Prints a message to the Samba * debug log in case of failure. */static int hpux_acl_sort(int acl_count, int calclass, struct acl *aclp){#if !defined(HAVE_HPUX_ACLSORT)	/*	 * The aclsort() system call is availabe on the latest HPUX General	 * Patch Bundles. So for HPUX, we developed our version of acl_sort 	 * function. Because, we don't want to update to a new 	 * HPUX GR bundle just for aclsort() call.	 */	struct hpux_acl_types acl_obj_count;	int n_class_obj_perm = 0;	int i, j; 	if(!acl_count) {		DEBUG(10,("Zero acl count passed. Returning Success\n"));		return 0;	}	if(aclp == NULL) {		DEBUG(0,("Null ACL pointer in hpux_acl_sort. Returning Failure. \n"));		return -1;	}	/* Count different types of ACLs in the ACLs array */	hpux_count_obj(acl_count, aclp, &acl_obj_count);	/* There should be only one entry each of type USER_OBJ, GROUP_OBJ, 	 * CLASS_OBJ and OTHER_OBJ 	 */	if( (acl_obj_count.n_user_obj  != 1) || 		(acl_obj_count.n_group_obj != 1) || 		(acl_obj_count.n_class_obj != 1) ||		(acl_obj_count.n_other_obj != 1) 	) {		DEBUG(0,("hpux_acl_sort: More than one entry or no entries for \USER OBJ or GROUP_OBJ or OTHER_OBJ or CLASS_OBJ\n"));		return -1;	}	/* If any of the default objects are present, there should be only	 * one of them each.	 */	if( (acl_obj_count.n_def_user_obj  > 1) || (acl_obj_count.n_def_group_obj > 1) || 			(acl_obj_count.n_def_other_obj > 1) || (acl_obj_count.n_def_class_obj > 1) ) {		DEBUG(0,("hpux_acl_sort: More than one entry for DEF_CLASS_OBJ \or DEF_USER_OBJ or DEF_GROUP_OBJ or DEF_OTHER_OBJ\n"));		return -1;	}	/* We now have proper number of OBJ and DEF_OBJ entries. Now sort the acl 	 * structures.  	 *	 * Sorting crieteria - First sort by ACL type. If there are multiple entries of	 * same ACL type, sort by ACL id.	 *	 * I am using the trival kind of sorting method here because, performance isn't 	 * really effected by the ACLs feature. More over there aren't going to be more	 * than 17 entries on HPUX. 	 */	for(i=0; i<acl_count;i++) {		for (j=i+1; j<acl_count; j++) {			if( aclp[i].a_type > aclp[j].a_type ) {				/* ACL entries out of order, swap them */				hpux_swap_acl_entries((aclp+i), (aclp+j));			} else if ( aclp[i].a_type == aclp[j].a_type ) {				/* ACL entries of same type, sort by id */				if(aclp[i].a_id > aclp[j].a_id) {					hpux_swap_acl_entries((aclp+i), (aclp+j));				} else if (aclp[i].a_id == aclp[j].a_id) {					/* We have a duplicate entry. */					if(hpux_prohibited_duplicate_type(aclp[i].a_type)) {						DEBUG(0, ("hpux_acl_sort: Duplicate entry: Type(hex): %x Id: %d\n",							aclp[i].a_type, aclp[i].a_id));						return -1;					}				}			}		}	}	/* set the class obj permissions to the computed one. */	if(calclass) {		int n_class_obj_index = -1;		for(i=0;i<acl_count;i++) {			n_class_obj_perm |= hpux_get_needed_class_perm((aclp+i));			if(aclp[i].a_type == CLASS_OBJ)				n_class_obj_index = i;		}		aclp[n_class_obj_index].a_perm = n_class_obj_perm;	}	return 0;#else	return aclsort(acl_count, calclass, aclp);#endif}/* * sort the ACL and check it for validity * * if it's a minimal ACL with only 4 entries then we * need to recalculate the mask permissions to make * sure that they are the same as the GROUP_OBJ * permissions as required by the UnixWare acl() system call. * * (note: since POSIX allows minimal ACLs which only contain * 3 entries - ie there is no mask entry - we should, in theory, * check for this and add a mask entry if necessary - however * we "know" that the caller of this interface always specifies * a mask so, in practice "this never happens" (tm) - if it *does* * happen aclsort() will fail and return an error and someone will * have to fix it ...) */static int acl_sort(SMB_ACL_T acl_d){	int fixmask = (acl_d->count <= 4);	if (hpux_acl_sort(acl_d->count, fixmask, acl_d->acl) != 0) {		errno = EINVAL;		return -1;	}	return 0;} int sys_acl_valid(SMB_ACL_T acl_d){	return acl_sort(acl_d);}int sys_acl_set_file(const char *name, SMB_ACL_TYPE_T type, SMB_ACL_T acl_d){	struct stat	s;	struct acl	*acl_p;	int		acl_count;	struct acl	*acl_buf	= NULL;	int		ret;	if(hpux_acl_call_presence() == False) {		/* Looks like we don't have the acl() system call on HPUX. 		 * May be the system doesn't have the latest version of JFS.		 */		errno=ENOSYS;		return -1; 	}	if (type != SMB_ACL_TYPE_ACCESS && type != SMB_ACL_TYPE_DEFAULT) {		errno = EINVAL;		return -1;	}	if (acl_sort(acl_d) != 0) {		return -1;	}	acl_p		= &acl_d->acl[0];	acl_count	= acl_d->count;	/*	 * if it's a directory there is extra work to do	 * since the acl() system call will replace both	 * the access ACLs and the default ACLs (if any)	 */	if (stat(name, &s) != 0) {		return -1;	}	if (S_ISDIR(s.st_mode)) {		SMB_ACL_T	acc_acl;		SMB_ACL_T	def_acl;		SMB_ACL_T	tmp_acl;		int		i;		if (type == SMB_ACL_TYPE_ACCESS) {			acc_acl = acl_d;			def_acl = tmp_acl = sys_acl_get_file(name, SMB_ACL_TYPE_DEFAULT);		} else {			def_acl = acl_d;			acc_acl = tmp_acl = sys_acl_get_file(name, SMB_ACL_TYPE_ACCESS);		}		if (tmp_acl == NULL) {			return -1;		}		/*		 * allocate a temporary buffer for the complete ACL		 */		acl_count = acc_acl->count + def_acl->count;		acl_p = acl_buf = SMB_MALLOC_ARRAY(struct acl, acl_count);		if (acl_buf == NULL) {			sys_acl_free_acl(tmp_acl);			errno = ENOMEM;			return -1;		}		/*		 * copy the access control and default entries into the buffer		 */		memcpy(&acl_buf[0], &acc_acl->acl[0],			acc_acl->count * sizeof(acl_buf[0]));		memcpy(&acl_buf[acc_acl->count], &def_acl->acl[0],			def_acl->count * sizeof(acl_buf[0]));		/*		 * set the ACL_DEFAULT flag on the default entries		 */		for (i = acc_acl->count; i < acl_count; i++) {			acl_buf[i].a_type |= ACL_DEFAULT;		}		sys_acl_free_acl(tmp_acl);	} else if (type != SMB_ACL_TYPE_ACCESS) {		errno = EINVAL;		return -1;	}	ret = acl(name, ACL_SET, acl_count, acl_p);	if (acl_buf) {		free(acl_buf);	}	return ret;}#if 0int sys_acl_set_fd(int fd, SMB_ACL_T acl_d){	/*	 * HPUX doesn't have the facl call. Fake it using the path.... JRA.	 */	files_struct *fsp = file_find_fd(fd);	if (fsp == NULL) {		errno = EBADF;		return NULL;	}	if (acl_sort(acl_d) != 0) {		return -1;	}	/*	 * We know we're in the same conn context. So we	 * can use the relative path.	 */	return sys_acl_set_file(fsp->fsp_name, SMB_ACL_TYPE_ACCESS, acl_d);}#endifint sys_acl_delete_def_file(const char *path){	SMB_ACL_T	acl_d;	int		ret;	/*	 * fetching the access ACL and rewriting it has	 * the effect of deleting the default ACL	 */	if ((acl_d = sys_acl_get_file(path, SMB_ACL_TYPE_ACCESS)) == NULL) {		return -1;	}	ret = acl(path, ACL_SET, acl_d->count, acl_d->acl);	sys_acl_free_acl(acl_d);		return ret;}int sys_acl_free_acl(SMB_ACL_T acl_d) {	free(acl_d);	return 0;}#elif defined(HAVE_IRIX_ACLS) /*---------------------------------------------*/int sys_acl_get_entry(SMB_ACL_T acl_d, int entry_id, SMB_ACL_ENTRY_T *entry_p){	if (entry_id != SMB_ACL_FIRST_ENTRY && entry_id != SMB_ACL_NEXT_ENTRY) {		errno = EINVAL;		return -1;	}	if (entry_p == NULL) {		errno = EINVAL;		return -1;	}	if (entry_id == SMB_ACL_FIRST_ENTRY) {		acl_d->next = 0;	}	if (acl_d->next < 0) {		errno = EINVAL;		return -1;	}	if (acl_d->next >= acl_d->aclp->acl_cnt) {		return 0;	}	*entry_p = &acl_d->aclp->acl_entry[acl_d->next++];	return 1;}int sys_acl_get_tag_type(SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *type_p){	*type_p = entry_d->ae_tag;	return 0;}SMB_ACL_T sys_acl_get_file(const char *path_p, SMB_ACL_TYPE_T type){	SMB_ACL_T	a;	if ((a = SMB_MALLOC_P(struct SMB_ACL_T)) == NULL) {		errno = ENOMEM;		return NULL;	}	if ((a->aclp = acl_get_file(path_p, type)) == NULL) {		SAFE_FREE(a);		return NULL;	}	a->next = -1;	a->freeaclp = True;	return a;}#if 0SMB_ACL_T sys_acl_get_fd(int fd){	SMB_ACL_T	a;	if ((a = SMB_MALLOC_P(struct SMB_ACL_T)) == NULL) {		errno = ENOMEM;		return NULL;	}	if ((a->aclp = acl_get_fd(fd)) == NULL) {		SAFE_FREE(a);		return NULL;	}	a->next = -1;	a->freeaclp = True;	return a;}#endifint sys_acl_get_info(SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T *tag_type_p, uint32 *bits_p, id_t *u_g_id_p){	*tag_type_p = entry->ae_tag;	*bits_p = entry->ae_perm;	if (*tag_type_p == SMB_ACL_USER || *tag_type_p == SMB_ACL_GROUP)		*u_g_id_p = entry->ae_id;	return 0;}SMB_ACL_T sys_acl_init(int count){	SMB_ACL_T	a;	if (count < 0) {		errno = EINVAL;		return NULL;	}	if ((a = (SMB_ACL_T)SMB_MALLOC(sizeof a[0] + sizeof (struct acl))) == NULL) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -