/* * acl_from_text -- Convert a string into an ACL. * Postpone most validity checking until the end and call acl_valid() to do * that. */ acl_t acl_from_text(const char *buf_p) { acl_t acl; char *mybuf_p, *line, *cur, *notcomment, *comment, *entry; int error; /* Local copy we can mess up. */ mybuf_p = strdup(buf_p); if (mybuf_p == NULL) return(NULL); acl = acl_init(3); /* XXX: WTF, 3? */ if (acl == NULL) { free(mybuf_p); return(NULL); } /* Outer loop: delimit at \n boundaries. */ cur = mybuf_p; while ((line = strsep(&cur, "\n"))) { /* Now split the line on the first # to strip out comments. */ comment = line; notcomment = strsep(&comment, "#"); /* Inner loop: delimit at ',' boundaries. */ while ((entry = strsep(¬comment, ","))) { /* Skip empty lines. */ if (strlen(string_skip_whitespace(entry)) == 0) continue; if (_acl_brand(acl) == ACL_BRAND_UNKNOWN) { if (_text_is_nfs4_entry(entry)) _acl_brand_as(acl, ACL_BRAND_NFS4); else _acl_brand_as(acl, ACL_BRAND_POSIX); } switch (_acl_brand(acl)) { case ACL_BRAND_NFS4: error = _nfs4_acl_entry_from_text(acl, entry); break; case ACL_BRAND_POSIX: error = _posix1e_acl_entry_from_text(acl, entry); break; default: error = EINVAL; break; } if (error) goto error_label; } } #if 0 /* XXX Should we only return ACLs valid according to acl_valid? */ /* Verify validity of the ACL we read in. */ if (acl_valid(acl) == -1) { errno = EINVAL; goto error_label; } #endif free(mybuf_p); return(acl); error_label: acl_free(acl); free(mybuf_p); return(NULL); }
void _entry_brand_as(const acl_entry_t entry, int brand) { _acl_brand_as(entry2acl(entry), brand); }
/* * acl_calc_mask() (23.4.2): calculate and set the permissions * associated with the ACL_MASK ACL entry. If the ACL already * contains an ACL_MASK entry, its permissions shall be * overwritten; if not, one shall be added. */ int acl_calc_mask(acl_t *acl_p) { struct acl *acl_int, *acl_int_new; acl_t acl_new; int i, mask_mode, mask_num; /* * (23.4.2.4) requires acl_p to point to a pointer to a valid ACL. * Since one of the primary reasons to use this function would be * to calculate the appropriate mask to obtain a valid ACL, we only * perform sanity checks here and validate the ACL prior to * returning. */ if (acl_p == NULL || *acl_p == NULL) { errno = EINVAL; return (-1); } if (!_acl_brand_may_be(*acl_p, ACL_BRAND_POSIX)) { errno = EINVAL; return (-1); } _acl_brand_as(*acl_p, ACL_BRAND_POSIX); acl_int = &(*acl_p)->ats_acl; if ((acl_int->acl_cnt < 3) || (acl_int->acl_cnt > ACL_MAX_ENTRIES)) { errno = EINVAL; return (-1); } acl_new = acl_dup(*acl_p); if (acl_new == NULL) return (-1); acl_int_new = &acl_new->ats_acl; mask_mode = 0; mask_num = -1; /* gather permissions and find a mask entry */ for (i = 0; i < acl_int_new->acl_cnt; i++) { switch(acl_int_new->acl_entry[i].ae_tag) { case ACL_USER: case ACL_GROUP: case ACL_GROUP_OBJ: mask_mode |= acl_int_new->acl_entry[i].ae_perm & ACL_PERM_BITS; break; case ACL_MASK: mask_num = i; break; } } /* if a mask entry already exists, overwrite the perms */ if (mask_num != -1) acl_int_new->acl_entry[mask_num].ae_perm = mask_mode; else { /* if no mask exists, check acl_cnt... */ if (acl_int_new->acl_cnt == ACL_MAX_ENTRIES) { errno = ENOMEM; acl_free(acl_new); return (-1); } /* ...and add the mask entry */ acl_int_new->acl_entry[acl_int_new->acl_cnt].ae_tag = ACL_MASK; acl_int_new->acl_entry[acl_int_new->acl_cnt].ae_id = ACL_UNDEFINED_ID; acl_int_new->acl_entry[acl_int_new->acl_cnt].ae_perm = mask_mode; acl_int_new->acl_cnt++; } if (acl_valid(acl_new) == -1) { errno = EINVAL; acl_free(acl_new); return (-1); } **acl_p = *acl_new; acl_free(acl_new); return (0); }