📄 sysacls.c
字号:
* 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 + -