/* 23.4.7 */ int acl_create_entry(acl_t *acl_p, acl_entry_t *entry_p) { acl_obj *acl_obj_p; acl_entry_obj *entry_obj_p; if (!acl_p || !entry_p) { if (entry_p) *entry_p = NULL; errno = EINVAL; return -1; } acl_obj_p = ext2int(acl, *acl_p); if (!acl_obj_p) return -1; entry_obj_p = __acl_create_entry_obj(acl_obj_p); if (entry_obj_p == NULL) return -1; *entry_p = int2ext(entry_obj_p); return 0; }
/* 23.4.6 */ acl_t acl_copy_int(const void *buf_p) { const struct __acl *ext_acl = (struct __acl *)buf_p; const struct __acl_entry *ent_p = ext_acl->x_entries, *end_p; size_t size = ext_acl ? ext_acl->x_size : 0; int entries; acl_obj *acl_obj_p; acl_entry_obj *entry_obj_p; if (!ext_acl || size < sizeof(struct __acl)) { errno = EINVAL; return NULL; } size -= sizeof(struct __acl); if (size % sizeof(struct __acl_entry)) { errno = EINVAL; return NULL; } entries = size / sizeof(struct __acl_entry); acl_obj_p = __acl_init_obj(entries); if (acl_obj_p == NULL) goto fail; end_p = ext_acl->x_entries + entries; for(; ent_p != end_p; ent_p++) { entry_obj_p = __acl_create_entry_obj(acl_obj_p); if (!entry_obj_p) goto fail; /* XXX Convert to machine endianness */ entry_obj_p->eentry = *ent_p; } if (__acl_reorder_obj_p(acl_obj_p)) goto fail; return int2ext(acl_obj_p); fail: __acl_free_acl_obj(acl_obj_p); return NULL; }
static int parse_acl_entry(const char **text_p, acl_t *acl_p) { acl_entry_obj entry_obj; acl_entry_t entry_d; char *str; const char *backup; int error, perm_chars; new_obj_p_here(acl_entry, &entry_obj); init_acl_entry_obj(entry_obj); /* parse acl entry type */ SKIP_WS(*text_p); switch (**text_p) { case 'u': /* user */ if (!skip_tag_name(text_p, "user")) goto fail; backup = *text_p; str = get_token(text_p); if (str) { entry_obj.etag = ACL_USER; error = get_uid(unquote(str), &entry_obj.eid.qid); free(str); if (error) { *text_p = backup; return -1; } } else { entry_obj.etag = ACL_USER_OBJ; } break; case 'g': /* group */ if (!skip_tag_name(text_p, "group")) goto fail; backup = *text_p; str = get_token(text_p); if (str) { entry_obj.etag = ACL_GROUP; error = get_gid(unquote(str), &entry_obj.eid.qid); free(str); if (error) { *text_p = backup; return -1; } } else { entry_obj.etag = ACL_GROUP_OBJ; } break; case 'm': /* mask */ if (!skip_tag_name(text_p, "mask")) goto fail; /* skip empty entry qualifier field (this field may be missing for compatibility with Solaris.) */ SKIP_WS(*text_p); if (**text_p == ':') (*text_p)++; entry_obj.etag = ACL_MASK; break; case 'o': /* other */ if (!skip_tag_name(text_p, "other")) goto fail; /* skip empty entry qualifier field (this field may be missing for compatibility with Solaris.) */ SKIP_WS(*text_p); if (**text_p == ':') (*text_p)++; entry_obj.etag = ACL_OTHER; break; default: goto fail; } for (perm_chars=0; perm_chars<3; perm_chars++, (*text_p)++) { switch(**text_p) { case 'r': if (entry_obj.eperm.sperm & ACL_READ) goto fail; entry_obj.eperm.sperm |= ACL_READ; break; case 'w': if (entry_obj.eperm.sperm & ACL_WRITE) goto fail; entry_obj.eperm.sperm |= ACL_WRITE; break; case 'x': if (entry_obj.eperm.sperm & ACL_EXECUTE) goto fail; entry_obj.eperm.sperm |= ACL_EXECUTE; break; case '-': /* ignore */ break; default: if (perm_chars == 0) goto fail; goto create_entry; } } create_entry: if (acl_create_entry(acl_p, &entry_d) != 0) return -1; if (acl_copy_entry(entry_d, int2ext(&entry_obj)) != 0) return -1; return 0; fail: errno = EINVAL; return -1; }