From 0f6263079e626b2fababe9cc131b589d1ecb3337 Mon Sep 17 00:00:00 2001 From: "Chris D. Faulhaber" Date: Tue, 24 Apr 2001 22:45:41 +0000 Subject: [PATCH] o Separate acl_t into internal and external representations as required by POSIX.1e. This maintains the current 'struct acl' in the kernel while providing the generic external acl_t interface required to complete the ACL editing library. o Add the acl_get_entry() function. o Convert the existing ACL utilities, getfacl and setfacl, to fully make use of the ACL editing library. Obtained from: TrustedBSD Project --- bin/setfacl/mask.c | 24 +++-- bin/setfacl/merge.c | 121 ++++++++++++++++-------- bin/setfacl/remove.c | 81 +++++++++------- bin/setfacl/setfacl.c | 26 +++--- bin/setfacl/setfacl.h | 14 +-- lib/libc/posix1e/Makefile.inc | 1 + lib/libc/posix1e/acl_calc_mask.c | 83 ++++++++--------- lib/libc/posix1e/acl_copy.c | 2 +- lib/libc/posix1e/acl_delete_entry.c | 35 ++++--- lib/libc/posix1e/acl_entry.c | 44 +++++++-- lib/libc/posix1e/acl_free.c | 10 +- lib/libc/posix1e/acl_from_text.c | 14 +-- lib/libc/posix1e/acl_get.c | 37 ++++++-- lib/libc/posix1e/acl_get_entry.3 | 139 ++++++++++++++++++++++++++++ lib/libc/posix1e/acl_init.c | 17 ++-- lib/libc/posix1e/acl_perm.c | 40 ++++---- lib/libc/posix1e/acl_set.c | 14 ++- lib/libc/posix1e/acl_support.c | 25 +++-- lib/libc/posix1e/acl_support.h | 2 +- lib/libc/posix1e/acl_to_text.c | 35 +++---- lib/libc/posix1e/acl_valid.c | 7 +- sys/sys/acl.h | 13 ++- 22 files changed, 551 insertions(+), 233 deletions(-) create mode 100644 lib/libc/posix1e/acl_get_entry.3 diff --git a/bin/setfacl/mask.c b/bin/setfacl/mask.c index 5992e9435e3b..595ab44aeb39 100644 --- a/bin/setfacl/mask.c +++ b/bin/setfacl/mask.c @@ -40,10 +40,14 @@ /* set the appropriate mask the given ACL's */ int -set_acl_mask(acl_t prev_acl) +set_acl_mask(acl_t *prev_acl) { + acl_entry_t entry; acl_t acl; - int i; + acl_tag_t tag; + int entry_id; + + entry = NULL; /* * ... if a mask entry is specified, then the permissions of the mask @@ -53,7 +57,7 @@ set_acl_mask(acl_t prev_acl) if (have_mask) return 0; - acl = acl_dup(prev_acl); + acl = acl_dup(*prev_acl); if (!acl) err(EX_OSERR, "acl_dup() failed"); @@ -76,11 +80,19 @@ set_acl_mask(acl_t prev_acl) * specified, then the permissions of the resulting ACL * mask entry shall remain unchanged ... */ - for (i = 0; i < acl->acl_cnt; i++) - if (acl->acl_entry[i].ae_tag == ACL_MASK) { + + entry_id = ACL_FIRST_ENTRY; + + while (acl_get_entry(acl, entry_id, &entry) == 1) { + entry_id = ACL_NEXT_ENTRY; + if (acl_get_tag_type(entry, &tag) == -1) + err(1, "acl_get_tag_type() failed"); + + if (tag == ACL_MASK) { acl_free(acl); return 0; } + } /* * If no mask entry is specified, the -n option is specified, @@ -93,7 +105,7 @@ set_acl_mask(acl_t prev_acl) return 0; } - *prev_acl = *acl; + prev_acl = &acl; acl_free(acl); return 0; diff --git a/bin/setfacl/merge.c b/bin/setfacl/merge.c index c739b26cd50f..acb01f4ce6e5 100644 --- a/bin/setfacl/merge.c +++ b/bin/setfacl/merge.c @@ -40,11 +40,12 @@ int merge_acl(acl_t acl, acl_t *prev_acl) { + acl_entry_t entry, entry_new; + acl_permset_t permset; acl_t acl_new; - int blank_acl_user, blank_acl_group, have_entry, i, j; - struct stat sb; - - blank_acl_user = blank_acl_group = 0; + acl_tag_t tag, tag_new; + int entry_id, entry_id_new, have_entry; + uid_t *id, *id_new; if (acl_type == ACL_TYPE_ACCESS) acl_new = acl_dup(prev_acl[0]); @@ -53,61 +54,99 @@ merge_acl(acl_t acl, acl_t *prev_acl) if (!acl_new) err(EX_OSERR, "acl_dup() failed"); - /* step through new ACL entries */ - for (i = 0; i < acl->acl_cnt; i++) { + entry_id = ACL_FIRST_ENTRY; + + while (acl_get_entry(acl, entry_id, &entry) == 1) { + entry_id = ACL_NEXT_ENTRY; have_entry = 0; - /* oh look, we have an ACL_MASK entry */ - if (acl->acl_entry[i].ae_tag == ACL_MASK) + /* keep track of existing ACL_MASK entries */ + if (acl_get_tag_type(entry, &tag) == -1) + err(EX_OSERR, + "acl_get_tag_type() failed - invalid ACL entry"); + if (tag == ACL_MASK) have_mask = 1; /* check against the existing ACL entries */ - for (j = 0; j < acl_new->acl_cnt && !have_entry; j++) { - if (acl_new->acl_entry[j].ae_tag == - acl->acl_entry[i].ae_tag) { - switch(acl->acl_entry[i].ae_tag) { - case ACL_USER_OBJ: - acl_new->acl_entry[j].ae_perm = - acl->acl_entry[i].ae_perm; - acl_new->acl_entry[j].ae_id = sb.st_uid; + entry_id_new = ACL_FIRST_ENTRY; + while (!have_entry && + acl_get_entry(acl_new, entry_id_new, &entry_new) == 1) { + entry_id_new = ACL_NEXT_ENTRY; + + if (acl_get_tag_type(entry, &tag) == -1) + err(EX_OSERR, "acl_get_tag_type() failed"); + if (acl_get_tag_type(entry_new, &tag_new) == -1) + err(EX_OSERR, "acl_get_tag_type() failed"); + if (tag != tag_new) + continue; + + switch(tag) { + case ACL_USER: + case ACL_GROUP: + id = acl_get_qualifier(entry); + if (id == NULL) + err(EX_OSERR, + "acl_get_qualifier() failed"); + id_new = acl_get_qualifier(entry_new); + if (id_new == NULL) + err(EX_OSERR, + "acl_get_qualifier() failed"); + if (*id == *id_new) { + /* any other matches */ + if (acl_get_permset(entry, &permset) + == -1) + err(EX_OSERR, + "acl_get_permset() failed"); + if (acl_set_permset(entry_new, permset) + == -1) + err(EX_OSERR, + "acl_set_permset() failed"); have_entry = 1; - break; - case ACL_GROUP_OBJ: - acl_new->acl_entry[j].ae_perm = - acl->acl_entry[i].ae_perm; - acl_new->acl_entry[j].ae_id = sb.st_gid; - have_entry = 1; - break; - default: - if (acl_new->acl_entry[j].ae_id == - acl->acl_entry[i].ae_id) { - /* any other matches */ - acl_new->acl_entry[j].ae_perm = - acl->acl_entry[i].ae_perm; - have_entry = 1; - } - break; } + acl_free(id); + acl_free(id_new); + if (!have_entry) + break; + /* FALLTHROUGH */ + case ACL_USER_OBJ: + case ACL_GROUP_OBJ: + case ACL_OTHER: + case ACL_MASK: + if (acl_get_permset(entry, &permset) == -1) + err(EX_OSERR, + "acl_get_permset() failed"); + if (acl_set_permset(entry_new, permset) == -1) + err(EX_OSERR, + "acl_set_permset() failed"); + have_entry = 1; + break; + default: + /* should never be here */ + errx(EX_OSERR, "Invalid tag type: %i", tag); + break; } } /* if this entry has not been found, it must be new */ if (!have_entry) { - if (acl_new->acl_cnt == ACL_MAX_ENTRIES) { - warn("too many ACL entries"); + if (acl_create_entry(&acl_new, &entry_new) == -1) { acl_free(acl_new); return -1; } - acl_new->acl_entry[acl_new->acl_cnt++] = - acl->acl_entry[i]; + if (acl_copy_entry(entry_new, entry) == -1) + err(EX_OSERR, "acl_copy_entry() failed"); } } - if (acl_type == ACL_TYPE_ACCESS) - *prev_acl[0] = *acl_new; - else - *prev_acl[1] = *acl_new; - acl_free(acl_new); + + if (acl_type == ACL_TYPE_ACCESS) { + acl_free(prev_acl[0]); + prev_acl[0] = acl_new; + } else { + acl_free(prev_acl[1]); + prev_acl[1] = acl_new; + } + return 0; } diff --git a/bin/setfacl/remove.c b/bin/setfacl/remove.c index 0fe02d17e1c7..e987df77b96e 100644 --- a/bin/setfacl/remove.c +++ b/bin/setfacl/remove.c @@ -41,8 +41,10 @@ int remove_acl(acl_t acl, acl_t *prev_acl) { - acl_t acl_new; - int carried_error, i; + acl_entry_t entry; + acl_t acl_new; + acl_tag_t tag; + int carried_error, entry_id; carried_error = 0; @@ -53,11 +55,17 @@ remove_acl(acl_t acl, acl_t *prev_acl) if (!acl_new) err(EX_OSERR, "acl_dup() failed"); + tag = ACL_UNDEFINED_TAG; + /* find and delete the entry */ - for (i = 0; i < acl->acl_cnt; i++) { - if (acl->acl_entry[i].ae_tag == ACL_MASK) + entry_id = ACL_FIRST_ENTRY; + while (acl_get_entry(acl, entry_id, &entry) == 1) { + entry_id = ACL_NEXT_ENTRY; + if (acl_get_tag_type(entry, &tag) == -1) + err(1, "acl_get_tag_type() failed"); + if (tag == ACL_MASK) have_mask++; - if (acl_delete_entry(acl_new, &acl->acl_entry[i]) == -1) { + if (acl_delete_entry(acl_new, entry) == -1) { carried_error++; warnx("cannot remove non-existent acl entry"); } @@ -83,8 +91,10 @@ remove_default(acl_t *prev_acl) { if (prev_acl[1]) { - bzero(prev_acl[1], sizeof(struct acl)); - prev_acl[1]->acl_cnt = 0; + acl_free(prev_acl[1]); + prev_acl[1] = acl_init(ACL_MAX_ENTRIES); + if (!prev_acl[1]) + err(1, "acl_init() failed"); } else { warn("cannot remove default ACL"); return -1; @@ -97,8 +107,10 @@ void remove_ext(acl_t *prev_acl) { acl_t acl_new, acl_old; - acl_perm_t group_perm, mask_perm; - int have_mask_entry, i; + acl_entry_t entry, entry_new; + acl_permset_t perm; + acl_tag_t tag; + int entry_id, have_mask_entry; if (acl_type == ACL_TYPE_ACCESS) acl_old = acl_dup(prev_acl[0]); @@ -107,41 +119,50 @@ remove_ext(acl_t *prev_acl) if (!acl_old) err(EX_OSERR, "acl_dup() failed"); - group_perm = mask_perm = 0; have_mask_entry = 0; acl_new = acl_init(ACL_MAX_ENTRIES); if (!acl_new) err(EX_OSERR, "%s", "acl_init() failed"); + tag = ACL_UNDEFINED_TAG; /* only save the default user/group/other entries */ - for (i = 0; i < acl_old->acl_cnt; i++) - switch(acl_old->acl_entry[i].ae_tag) { + entry_id = ACL_FIRST_ENTRY; + while (acl_get_entry(acl_old, entry_id, &entry) == 1) { + entry_id = ACL_NEXT_ENTRY; + + if (acl_get_tag_type(entry, &tag) == -1) + err(1, "acl_get_tag_type() failed"); + + switch(tag) { case ACL_USER_OBJ: - acl_new->acl_entry[0] = acl_old->acl_entry[i]; - break; case ACL_GROUP_OBJ: - acl_new->acl_entry[1] = acl_old->acl_entry[i]; - group_perm = acl_old->acl_entry[i].ae_perm; - break; - case ACL_OTHER_OBJ: - acl_new->acl_entry[2] = acl_old->acl_entry[i]; + case ACL_OTHER: + if (acl_get_tag_type(entry, &tag) == -1) + err(1, "acl_get_tag_type() failed"); + if (acl_get_permset(entry, &perm) == -1) + err(1, "acl_get_permset() failed"); + if (acl_create_entry(&acl_new, &entry_new) == -1) + err(1, "acl_create_entry() failed"); + if (acl_set_tag_type(entry_new, tag) == -1) + err(1, "acl_set_tag_type() failed"); + if (acl_set_permset(entry_new, perm) == -1) + err(1, "acl_get_permset() failed"); + if (acl_copy_entry(entry_new, entry) == -1) + err(1, "acl_copy_entry() failed"); break; case ACL_MASK: - mask_perm = acl_old->acl_entry[i].ae_perm; have_mask_entry = 1; break; default: break; } - /* - * If the ACL contains a mask entry, then the permissions associated - * with the owning group entry in the resulting ACL shall be set to - * only those permissions associated with both the owning group entry - * and the mask entry of the current ACL. - */ - if (have_mask_entry) - acl_new->acl_entry[1].ae_perm = group_perm & mask_perm; - acl_new->acl_cnt = 3; + } + if (have_mask_entry && !n_flag) { + if (acl_calc_mask(&acl_new) == -1) + err(1, "acl_calc_mask() failed"); + } else { + have_mask = 1; + } if (acl_type == ACL_TYPE_ACCESS) { acl_free(prev_acl[0]); @@ -150,6 +171,4 @@ remove_ext(acl_t *prev_acl) acl_free(prev_acl[1]); prev_acl[1] = acl_new; } - - have_mask = 0; } diff --git a/bin/setfacl/setfacl.c b/bin/setfacl/setfacl.c index c18c3f90c610..b2d8578a5c10 100644 --- a/bin/setfacl/setfacl.c +++ b/bin/setfacl/setfacl.c @@ -56,7 +56,7 @@ add_filename(const char *filename) } file = zmalloc(sizeof(struct sf_file)); file->filename = filename; - STAILQ_INSERT_TAIL(&filelist, file, next); + TAILQ_INSERT_TAIL(&filelist, file, next); } static acl_t * @@ -106,8 +106,8 @@ main(int argc, char *argv[]) carried_error = local_error = 0; have_mask = have_stdin = n_flag = need_mask = 0; - STAILQ_INIT(&entrylist); - STAILQ_INIT(&filelist); + TAILQ_INIT(&entrylist); + TAILQ_INIT(&filelist); while ((ch = getopt(argc, argv, "M:X:bdkm:nx:")) != -1) switch(ch) { @@ -117,18 +117,18 @@ main(int argc, char *argv[]) if (!entry->acl) err(EX_OSERR, "get_acl_from_file() failed"); entry->op = OP_MERGE_ACL; - STAILQ_INSERT_TAIL(&entrylist, entry, next); + TAILQ_INSERT_TAIL(&entrylist, entry, next); break; case 'X': entry = zmalloc(sizeof(struct sf_entry)); entry->acl = get_acl_from_file(optarg); entry->op = OP_REMOVE_ACL; - STAILQ_INSERT_TAIL(&entrylist, entry, next); + TAILQ_INSERT_TAIL(&entrylist, entry, next); break; case 'b': entry = zmalloc(sizeof(struct sf_entry)); entry->op = OP_REMOVE_EXT; - STAILQ_INSERT_TAIL(&entrylist, entry, next); + TAILQ_INSERT_TAIL(&entrylist, entry, next); break; case 'd': acl_type = ACL_TYPE_DEFAULT; @@ -136,7 +136,7 @@ main(int argc, char *argv[]) case 'k': entry = zmalloc(sizeof(struct sf_entry)); entry->op = OP_REMOVE_DEF; - STAILQ_INSERT_TAIL(&entrylist, entry, next); + TAILQ_INSERT_TAIL(&entrylist, entry, next); break; case 'm': entry = zmalloc(sizeof(struct sf_entry)); @@ -144,7 +144,7 @@ main(int argc, char *argv[]) if (!entry->acl) err(EX_USAGE, "acl_from_text() failed"); entry->op = OP_MERGE_ACL; - STAILQ_INSERT_TAIL(&entrylist, entry, next); + TAILQ_INSERT_TAIL(&entrylist, entry, next); break; case 'n': n_flag++; @@ -155,7 +155,7 @@ main(int argc, char *argv[]) if (!entry->acl) err(EX_USAGE, "acl_from_text() failed"); entry->op = OP_REMOVE_ACL; - STAILQ_INSERT_TAIL(&entrylist, entry, next); + TAILQ_INSERT_TAIL(&entrylist, entry, next); break; default: usage(); @@ -164,7 +164,7 @@ main(int argc, char *argv[]) argc -= optind; argv += optind; - if (STAILQ_EMPTY(&entrylist)) + if (!n_flag && TAILQ_EMPTY(&entrylist)) usage(); /* take list of files from stdin */ @@ -183,7 +183,7 @@ main(int argc, char *argv[]) add_filename(argv[i]); /* cycle through each file */ - STAILQ_FOREACH(file, &filelist, next) { + TAILQ_FOREACH(file, &filelist, next) { /* get our initial access and default ACL's */ acl = get_file_acls(file->filename); if (!acl) @@ -196,7 +196,7 @@ main(int argc, char *argv[]) local_error = 0; /* cycle through each option */ - STAILQ_FOREACH(entry, &entrylist, next) { + TAILQ_FOREACH(entry, &entrylist, next) { if (local_error) continue; @@ -236,7 +236,7 @@ main(int argc, char *argv[]) else final_acl = acl[1]; - if (need_mask && (set_acl_mask(final_acl) == -1)) { + if (need_mask && (set_acl_mask(&final_acl) == -1)) { warnx("failed to set ACL mask on %s", file->filename); carried_error++; } else if (acl_set_file(file->filename, acl_type, diff --git a/bin/setfacl/setfacl.h b/bin/setfacl/setfacl.h index b80fa44ab927..d3c79230a92f 100644 --- a/bin/setfacl/setfacl.h +++ b/bin/setfacl/setfacl.h @@ -39,20 +39,20 @@ #define OP_REMOVE_EXT 0x02 /* remove extended acl's (-b) */ #define OP_REMOVE_ACL 0x03 /* remove acl's (-xX) */ -/* STAILQ entry for acl operations */ +/* TAILQ entry for acl operations */ struct sf_entry { uint op; acl_t acl; - STAILQ_ENTRY(sf_entry) next; + TAILQ_ENTRY(sf_entry) next; }; -STAILQ_HEAD(, sf_entry) entrylist; +TAILQ_HEAD(, sf_entry) entrylist; -/* STAILQ entry for files */ +/* TAILQ entry for files */ struct sf_file { const char *filename; - STAILQ_ENTRY(sf_file) next; + TAILQ_ENTRY(sf_file) next; }; -STAILQ_HEAD(, sf_file) filelist; +TAILQ_HEAD(, sf_file) filelist; /* files.c */ acl_t get_acl_from_file(const char *filename); @@ -63,7 +63,7 @@ int remove_acl(acl_t acl, acl_t *prev_acl); int remove_default(acl_t *prev_acl); void remove_ext(acl_t *prev_acl); /* mask.c */ -int set_acl_mask(acl_t prev_acl); +int set_acl_mask(acl_t *prev_acl); /* util.c */ void *zmalloc(size_t size); diff --git a/lib/libc/posix1e/Makefile.inc b/lib/libc/posix1e/Makefile.inc index d6f51fea009a..d7b4faa13532 100644 --- a/lib/libc/posix1e/Makefile.inc +++ b/lib/libc/posix1e/Makefile.inc @@ -47,6 +47,7 @@ MAN+= acl.3 \ acl_free.3 \ acl_from_text.3 \ acl_get.3 \ + acl_get_entry.3 \ acl_get_permset.3 \ acl_get_perm_np.3 \ acl_get_qualifier.3 \ diff --git a/lib/libc/posix1e/acl_calc_mask.c b/lib/libc/posix1e/acl_calc_mask.c index d9d93227f14c..90fe224712cc 100644 --- a/lib/libc/posix1e/acl_calc_mask.c +++ b/lib/libc/posix1e/acl_calc_mask.c @@ -32,22 +32,34 @@ #include "un-namespace.h" #include +#include /* - * acl_calc_mask() calculates 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. + * 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) { - acl_t acl_new; - int group_obj, i, mask_mode, mask_num, other_obj, user_obj; + struct acl *acl_int, *acl_int_new; + acl_t acl_new; + int i, mask_mode, mask_num; - /* check args */ - if (!acl_p || !*acl_p || ((*acl_p)->acl_cnt < 3) || - ((*acl_p)->acl_cnt > ACL_MAX_ENTRIES)) { + /* + * (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 || !*acl_p) { + errno = EINVAL; + return -1; + } + acl_int = &(*acl_p)->ats_acl; + if ((acl_int->acl_cnt < 3) || (acl_int->acl_cnt > ACL_MAX_ENTRIES)) { errno = EINVAL; return -1; } @@ -55,57 +67,42 @@ acl_calc_mask(acl_t *acl_p) acl_new = acl_dup(*acl_p); if (!acl_new) return -1; + acl_int_new = &acl_new->ats_acl; - user_obj = group_obj = other_obj = mask_mode = 0; + mask_mode = 0; mask_num = -1; /* gather permissions and find a mask entry */ - for (i = 0; i < acl_new->acl_cnt; i++) { - switch(acl_new->acl_entry[i].ae_tag) { - case ACL_USER_OBJ: - user_obj++; - break; - case ACL_OTHER: - other_obj++; - break; - case ACL_GROUP_OBJ: - group_obj++; - /* FALLTHROUGH */ - case ACL_GROUP: + 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_new->acl_entry[i].ae_perm & ACL_PERM_BITS; + acl_int_new->acl_entry[i].ae_perm & ACL_PERM_BITS; break; case ACL_MASK: mask_num = i; break; - default: - errno = EINVAL; - acl_free(acl_new); - return -1; - /* NOTREACHED */ } } - if ((user_obj != 1) || (group_obj != 1) || (other_obj != 1)) { - errno = EINVAL; - acl_free(acl_new); - return -1; - } + /* if a mask entry already exists, overwrite the perms */ - if (mask_num != -1) { - acl_new->acl_entry[mask_num].ae_perm = mask_mode; - } else { + 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_new->acl_cnt == ACL_MAX_ENTRIES) { - errno = EINVAL; - acl_free(acl_new); + if (acl_int_new->acl_cnt == ACL_MAX_ENTRIES) { + errno = ENOMEM; return -1; } /* ...and add the mask entry */ - acl_new->acl_entry[acl_new->acl_cnt].ae_tag = ACL_MASK; - acl_new->acl_entry[acl_new->acl_cnt].ae_id = 0; - acl_new->acl_entry[acl_new->acl_cnt].ae_perm = mask_mode; - acl_new->acl_cnt++; + 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) { diff --git a/lib/libc/posix1e/acl_copy.c b/lib/libc/posix1e/acl_copy.c index 972523125df1..800648a7ca01 100644 --- a/lib/libc/posix1e/acl_copy.c +++ b/lib/libc/posix1e/acl_copy.c @@ -35,7 +35,7 @@ #include /* - * acl_copy_entry() - copy the contents of ACL entry src_d to + * acl_copy_entry() (23.4.4): copy the contents of ACL entry src_d to * ACL entry dest_d */ int diff --git a/lib/libc/posix1e/acl_delete_entry.c b/lib/libc/posix1e/acl_delete_entry.c index e961ab269c2a..760078f17b06 100644 --- a/lib/libc/posix1e/acl_delete_entry.c +++ b/lib/libc/posix1e/acl_delete_entry.c @@ -26,8 +26,6 @@ * $FreeBSD$ */ -/* acl_delete_entry() - delete an ACL entry from an ACL */ - #include #include "namespace.h" #include @@ -35,26 +33,41 @@ #include #include +/* + * acl_delete_entry() (23.4.9): remove the ACL entry indicated by entry_d + * from acl. + */ int acl_delete_entry(acl_t acl, acl_entry_t entry_d) { + struct acl *acl_int; int i; - if (!acl || !entry_d || (acl->acl_cnt < 1) || - (acl->acl_cnt > ACL_MAX_ENTRIES)) { + if (!acl || !entry_d) { errno = EINVAL; return -1; } - for (i = 0; i < acl->acl_cnt; i++) { + + acl_int = &acl->ats_acl; + + if ((acl->ats_acl.acl_cnt < 1) || + (acl->ats_acl.acl_cnt > ACL_MAX_ENTRIES)) { + errno = EINVAL; + return -1; + } + for (i = 0; i < acl->ats_acl.acl_cnt; i++) { /* if this is our entry... */ - if ((acl->acl_entry[i].ae_tag == entry_d->ae_tag) && - (acl->acl_entry[i].ae_id == entry_d->ae_id)) { + if ((acl->ats_acl.acl_entry[i].ae_tag == entry_d->ae_tag) && + (acl->ats_acl.acl_entry[i].ae_id == entry_d->ae_id)) { /* ...shift the remaining entries... */ - while (i < acl->acl_cnt - 1) - acl->acl_entry[i] = acl->acl_entry[++i]; + while (i < acl->ats_acl.acl_cnt - 1) + acl->ats_acl.acl_entry[i] = + acl->ats_acl.acl_entry[++i]; /* ...drop the count and zero the unused entry... */ - acl->acl_cnt--; - bzero(&acl->acl_entry[i], sizeof(struct acl_entry)); + acl->ats_acl.acl_cnt--; + bzero(&acl->ats_acl.acl_entry[i], + sizeof(struct acl_entry)); + acl->ats_cur_entry = 0; return 0; } } diff --git a/lib/libc/posix1e/acl_entry.c b/lib/libc/posix1e/acl_entry.c index cfb5e8049c6f..337340da6fc4 100644 --- a/lib/libc/posix1e/acl_entry.c +++ b/lib/libc/posix1e/acl_entry.c @@ -34,32 +34,64 @@ #include #include +/* + * acl_create_entry() (23.4.7): create a new ACL entry in the ACL pointed + * to by acl_p. + */ int acl_create_entry(acl_t *acl_p, acl_entry_t *entry_p) { - acl_t acl; + struct acl *acl_int; - if (!acl_p || !*acl_p || ((*acl_p)->acl_cnt >= ACL_MAX_ENTRIES) || - ((*acl_p)->acl_cnt < 0)) { + if (!acl_p) { errno = EINVAL; return -1; } - acl = *acl_p; + acl_int = &(*acl_p)->ats_acl; - *entry_p = &acl->acl_entry[acl->acl_cnt++]; + if ((acl_int->acl_cnt >= ACL_MAX_ENTRIES) || (acl_int->acl_cnt < 0)) { + errno = EINVAL; + return -1; + } + + *entry_p = &acl_int->acl_entry[acl_int->acl_cnt++]; (**entry_p).ae_tag = ACL_UNDEFINED_TAG; (**entry_p).ae_id = ACL_UNDEFINED_ID; (**entry_p).ae_perm = ACL_PERM_NONE; + (*acl_p)->ats_cur_entry = 0; + return 0; } +/* + * acl_get_entry() (23.4.14): returns an ACL entry from an ACL + * indicated by entry_id. + */ int acl_get_entry(acl_t acl, int entry_id, acl_entry_t *entry_p) { + struct acl *acl_int; - errno = ENOSYS; + if (!acl) { + errno = EINVAL; + return -1; + } + acl_int = &acl->ats_acl; + + switch(entry_id) { + case ACL_FIRST_ENTRY: + acl->ats_cur_entry = 0; + /* PASSTHROUGH */ + case ACL_NEXT_ENTRY: + if (acl->ats_cur_entry >= acl->ats_acl.acl_cnt) + return 0; + *entry_p = &acl_int->acl_entry[acl->ats_cur_entry++]; + return 1; + } + + errno = EINVAL; return -1; } diff --git a/lib/libc/posix1e/acl_free.c b/lib/libc/posix1e/acl_free.c index 9dd9ee907df0..b4aeb1ab297e 100644 --- a/lib/libc/posix1e/acl_free.c +++ b/lib/libc/posix1e/acl_free.c @@ -36,10 +36,18 @@ #include #include +/* + * acl_free() (23.4.12): free any releasable memory allocated to the + * ACL data object identified by obj_p. + */ int acl_free(void *obj_p) { - free(obj_p); + if (obj_p) { + free(obj_p); + obj_p = NULL; + } + return (0); } diff --git a/lib/libc/posix1e/acl_from_text.c b/lib/libc/posix1e/acl_from_text.c index 8b4733860609..d3910898b917 100644 --- a/lib/libc/posix1e/acl_from_text.c +++ b/lib/libc/posix1e/acl_from_text.c @@ -109,13 +109,13 @@ acl_string_to_tag(char *tag, char *qualifier) acl_t acl_from_text(const char *buf_p) { - acl_tag_t t; - acl_perm_t p; - acl_t acl; - uid_t id; - char *mybuf_p, *line, *cur, *notcomment, *comment, *entry; - char *tag, *qualifier, *permission; - int error; + acl_tag_t t; + acl_perm_t p; + acl_t acl; + char *mybuf_p, *line, *cur, *notcomment, *comment, *entry; + char *tag, *qualifier, *permission; + int error; + uid_t id; /* Local copy we can mess up. */ mybuf_p = strdup(buf_p); diff --git a/lib/libc/posix1e/acl_get.c b/lib/libc/posix1e/acl_get.c index 3388041e2f56..4f84ceff8020 100644 --- a/lib/libc/posix1e/acl_get.c +++ b/lib/libc/posix1e/acl_get.c @@ -48,7 +48,7 @@ acl_t acl_get_file(const char *path_p, acl_type_t type) { - struct acl *aclp; + acl_t aclp; int error; aclp = acl_init(ACL_MAX_ENTRIES); @@ -56,7 +56,7 @@ acl_get_file(const char *path_p, acl_type_t type) return (NULL); } - error = __acl_get_file(path_p, type, aclp); + error = __acl_get_file(path_p, type, &aclp->ats_acl); if (error) { acl_free(aclp); return (NULL); @@ -68,7 +68,7 @@ acl_get_file(const char *path_p, acl_type_t type) acl_t acl_get_fd(int fd) { - struct acl *aclp; + acl_t aclp; int error; aclp = acl_init(ACL_MAX_ENTRIES); @@ -76,7 +76,7 @@ acl_get_fd(int fd) return (NULL); } - error = ___acl_get_fd(fd, ACL_TYPE_ACCESS, aclp); + error = ___acl_get_fd(fd, ACL_TYPE_ACCESS, &aclp->ats_acl); if (error) { acl_free(aclp); return (NULL); @@ -88,7 +88,7 @@ acl_get_fd(int fd) acl_t acl_get_fd_np(int fd, acl_type_t type) { - struct acl *aclp; + acl_t aclp; int error; aclp = acl_init(ACL_MAX_ENTRIES); @@ -96,7 +96,7 @@ acl_get_fd_np(int fd, acl_type_t type) return (NULL); } - error = ___acl_get_fd(fd, type, aclp); + error = ___acl_get_fd(fd, type, &aclp->ats_acl); if (error) { acl_free(aclp); return (NULL); @@ -109,6 +109,11 @@ int acl_get_perm_np(acl_permset_t permset_d, acl_perm_t perm) { + if (!permset_d) { + errno = EINVAL; + return -1; + } + switch(perm) { case ACL_READ: case ACL_WRITE: @@ -124,6 +129,10 @@ acl_get_perm_np(acl_permset_t permset_d, acl_perm_t perm) return 0; } +/* + * acl_get_permset() (23.4.17): return via permset_p a descriptor to + * the permission set in the ACL entry entry_d. + */ int acl_get_permset(acl_entry_t entry_d, acl_permset_t *permset_p) { @@ -138,6 +147,10 @@ acl_get_permset(acl_entry_t entry_d, acl_permset_t *permset_p) return 0; } +/* + * acl_get_qualifier() (23.4.18): retrieve the qualifier of the tag + * for the ACL entry entry_d. + */ void * acl_get_qualifier(acl_entry_t entry_d) { @@ -152,16 +165,20 @@ acl_get_qualifier(acl_entry_t entry_d) case ACL_USER: case ACL_GROUP: retval = malloc(sizeof(uid_t)); - if (retval) { - *retval = entry_d->ae_id; - return retval; - } + if (!retval) + return NULL; + *retval = entry_d->ae_id; + return retval; } errno = EINVAL; return NULL; } +/* + * acl_get_tag_type() (23.4.19): return the tag type for the ACL + * entry entry_p. + */ int acl_get_tag_type(acl_entry_t entry_d, acl_tag_t *tag_type_p) { diff --git a/lib/libc/posix1e/acl_get_entry.3 b/lib/libc/posix1e/acl_get_entry.3 new file mode 100644 index 000000000000..e9269c90b9cd --- /dev/null +++ b/lib/libc/posix1e/acl_get_entry.3 @@ -0,0 +1,139 @@ +.\"- +.\" Copyright (c) 2001 Chris D. Faulhaber +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR THE VOICES IN HIS HEAD BE +.\" LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +.\" POSSIBILITY OF SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd April 13, 2001 +.Dt ACL_GET_ENTRY 3 +.Os +.Sh NAME +.Nm acl_get_entry +.Nd retrieve an ACL entry from an ACL +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.Fd #include +.Fd #include +.Ft void * +.Fn acl_get_entry "acl_t acl" "int entry_id" "acl_entry_t entry_p" +.Sh DESCRIPTION +.Fn acl_get_entry +is a POSIX.1e call that retrieves a descriptor for an ACL entry +specified by the argument +.Fa entry_d +within the ACL indicated by the argument +.Fa acl . +.Pp +If the value of +.Fa entry_id +is +.Dv ACL_FIRST_ENTRY , +then the function will return in +.Fa entry_p +a descriptor for the first ACL entry within +.Fa acl . +If a call is made to +.Fn acl_get_entry +with +.Fa entry_id +set to +.Dv ACL_NEXT_ENTRY +when there has not been either an initial successful call to +.Fn acl_get_entry , +or a previous successfull call to +.Fn acl_create_entry , +.Fn acl_delete_entry , +.Fn acl_dup , +.Fn acl_from_text , +.Fn acl_get_fd , +.Fn acl_get_file , +.Fn acl_set_fd , +.Fn acl_set_file, +or +.Fn acl_valid , +then the result is unspecified. +.Pp +.Sh RETURN VALUES +If the +.Fn acl_get_entry +function successfully obtains an ACL entry, a value of 1 is returned. +If the ACL has no ACL entries, the +.Fn function +returns a value of 0. If the value of +.Fa entry_id +is +.Dv ACL_NEXT_ENTRY +and the last ACL entry in the ACL has already been returned by a +previous call to +.Fn acl_get_entry , +a value of 0 will be returned until a successful call with +.Fa entry_id +of +.Dv ACL_FIRST_ENTRY +is made. Otherwise, a value of -1 will be returned and +.Va errno +will be set to indicate the error. +.Sh ERRORS +The +.Fn acl_get_entry +fails if: +.Bl -tag -width Er +.It Bq Er EINVAL +Argument +.Fa acl +does not point to a valid ACL. Argument +.Fa entry_id +is neither +.Dv ACL_FIRST_ENTRY +nor +.Dv ACL_NEXT_ENTRY . +.Sh SEE ALSO +.Xr acl 3 , +.Xr acl_calc_mask 3 , +.Xr acl_create_entry 3 , +.Xr acl_delete_entry 3 , +.Xr acl_dup 3 , +.Xr acl_from_text 3 , +.Xr acl_get_fd 3 , +.Xr acl_get_file 3 , +.Xr acl_init 3 , +.Xr acl_set_fd 3 , +.Xr acl_set_file 3 , +.Xr acl_valid 3 , +.Xr posix1e 3 +.Sh STANDARDS +POSIX.1e is described in IEEE POSIX.1e draft 17. +.Sh HISTORY +POSIX.1e support was introduced in +.Fx 4.0 . +The +.Fn acl_get_entry +function was added in +.Fx 5.0 . +.Sh AUTHORS +The +.Fn acl_get_entry +function was written by +.An Chris D. Faulhaber Aq jedgar@fxp.org . diff --git a/lib/libc/posix1e/acl_init.c b/lib/libc/posix1e/acl_init.c index d6e8f0531b0c..da36156579dd 100644 --- a/lib/libc/posix1e/acl_init.c +++ b/lib/libc/posix1e/acl_init.c @@ -41,16 +41,20 @@ acl_t acl_init(int count) { - struct acl *acl; + acl_t acl; if (count > ACL_MAX_ENTRIES) { errno = ENOMEM; return (NULL); } + if (count < 0) { + errno = EINVAL; + return (NULL); + } - acl = (struct acl *) malloc(sizeof(struct acl)); + acl = malloc(sizeof(struct acl_t_struct)); if (acl != NULL) - bzero(acl, sizeof(struct acl)); + bzero(acl, sizeof(struct acl_t_struct)); return (acl); } @@ -58,13 +62,14 @@ acl_init(int count) acl_t acl_dup(acl_t acl) { - struct acl *acl_new; + acl_t acl_new; acl_new = acl_init(ACL_MAX_ENTRIES); if (!acl_new) - return(NULL); - + return NULL; *acl_new = *acl; + acl->ats_cur_entry = 0; + acl_new->ats_cur_entry = 0; return(acl_new); } diff --git a/lib/libc/posix1e/acl_perm.c b/lib/libc/posix1e/acl_perm.c index cdd8e3064774..8f634cb4ecb1 100644 --- a/lib/libc/posix1e/acl_perm.c +++ b/lib/libc/posix1e/acl_perm.c @@ -35,25 +35,29 @@ #include /* - * acl_add_perm() adds the permission contained in perm to the + * acl_add_perm() (23.4.1): add the permission contained in perm to the * permission set permset_d */ int acl_add_perm(acl_permset_t permset_d, acl_perm_t perm) { - if (!permset_d || (perm & !(ACL_PERM_BITS))) { - errno = EINVAL; - return -1; + if (permset_d) { + switch(perm) { + case ACL_READ: + case ACL_WRITE: + case ACL_EXECUTE: + *permset_d |= perm; + return 0; + } } - *permset_d |= perm; - - return 0; + errno = EINVAL; + return -1; } /* - * acl_clear_perms() clears all permisions from the permission + * acl_clear_perms() (23.4.3): clear all permisions from the permission * set permset_d */ int @@ -65,25 +69,29 @@ acl_clear_perms(acl_permset_t permset_d) return -1; } - *permset_d = 0; + *permset_d = ACL_PERM_NONE; return 0; } /* - * acl_delete_perm() removes the permission in perm from the + * acl_delete_perm() (23.4.10): remove the permission in perm from the * permission set permset_d */ int acl_delete_perm(acl_permset_t permset_d, acl_perm_t perm) { - if (!permset_d) { - errno = EINVAL; - return -1; + if (permset_d) { + switch(perm) { + case ACL_READ: + case ACL_WRITE: + case ACL_EXECUTE: + *permset_d &= ~(perm & ACL_PERM_BITS); + return 0; + } } - *permset_d &= ~(perm & ACL_PERM_BITS); - - return 0; + errno = EINVAL; + return -1; } diff --git a/lib/libc/posix1e/acl_set.c b/lib/libc/posix1e/acl_set.c index e8f177d010e4..6b7ddedff8e3 100644 --- a/lib/libc/posix1e/acl_set.c +++ b/lib/libc/posix1e/acl_set.c @@ -59,7 +59,9 @@ acl_set_file(const char *path_p, acl_type_t type, acl_t acl) } } - return (__acl_set_file(path_p, type, acl)); + acl->ats_cur_entry = 0; + + return (__acl_set_file(path_p, type, &acl->ats_acl)); } int @@ -73,7 +75,9 @@ acl_set_fd(int fd, acl_t acl) return(-1); } - return (___acl_set_fd(fd, ACL_TYPE_ACCESS, acl)); + acl->ats_cur_entry = 0; + + return (___acl_set_fd(fd, ACL_TYPE_ACCESS, &acl->ats_acl)); } int @@ -89,11 +93,13 @@ acl_set_fd_np(int fd, acl_t acl, acl_type_t type) } } - return (___acl_set_fd(fd, type, acl)); + acl->ats_cur_entry = 0; + + return (___acl_set_fd(fd, type, &acl->ats_acl)); } /* - * acl_set_permset() sets the permissions of ACL entry entry_d + * acl_set_permset() (23.4.23): sets the permissions of ACL entry entry_d * with the permissions in permset_d */ int diff --git a/lib/libc/posix1e/acl_support.c b/lib/libc/posix1e/acl_support.c index 26fcf0752938..0ab061ded8d4 100644 --- a/lib/libc/posix1e/acl_support.c +++ b/lib/libc/posix1e/acl_support.c @@ -96,9 +96,12 @@ _posix1e_acl_entry_compare(struct acl_entry *a, struct acl_entry *b) int _posix1e_acl_sort(acl_t acl) { + struct acl *acl_int; - qsort(&acl->acl_entry[0], acl->acl_cnt, sizeof(struct acl_entry), - (compare) _posix1e_acl_entry_compare); + acl_int = &acl->ats_acl; + + qsort(&acl_int->acl_entry[0], acl_int->acl_cnt, + sizeof(struct acl_entry), (compare) _posix1e_acl_entry_compare); return (0); } @@ -130,8 +133,9 @@ _posix1e_acl(acl_t acl, acl_type_t type) * this. Returns 0 on success, EINVAL on failure. */ int -_posix1e_acl_check(struct acl *acl) +_posix1e_acl_check(acl_t acl) { + struct acl *acl_int; struct acl_entry *entry; /* current entry */ uid_t obj_uid=-1, obj_gid=-1, highest_uid=0, highest_gid=0; int stage = ACL_USER_OBJ; @@ -139,10 +143,12 @@ _posix1e_acl_check(struct acl *acl) int count_user_obj=0, count_user=0, count_group_obj=0, count_group=0, count_mask=0, count_other=0; + acl_int = &acl->ats_acl; + /* printf("_posix1e_acl_check: checking acl with %d entries\n", acl->acl_cnt); */ - while (i < acl->acl_cnt) { - entry = &acl->acl_entry[i]; + while (i < acl_int->acl_cnt) { + entry = &acl_int->acl_entry[i]; if ((entry->ae_perm | ACL_PERM_BITS) != ACL_PERM_BITS) return (EINVAL); @@ -408,18 +414,21 @@ _posix1e_acl_string_to_perm(char *string, acl_perm_t *perm) int _posix1e_acl_add_entry(acl_t acl, acl_tag_t tag, uid_t id, acl_perm_t perm) { + struct acl *acl_int; struct acl_entry *e; - if (acl->acl_cnt >= ACL_MAX_ENTRIES) { + acl_int = &acl->ats_acl; + + if (acl_int->acl_cnt >= ACL_MAX_ENTRIES) { errno = ENOMEM; return (-1); } - e = &(acl->acl_entry[acl->acl_cnt]); + e = &(acl_int->acl_entry[acl_int->acl_cnt]); e->ae_perm = perm; e->ae_tag = tag; e->ae_id = id; - acl->acl_cnt++; + acl_int->acl_cnt++; return (0); } diff --git a/lib/libc/posix1e/acl_support.h b/lib/libc/posix1e/acl_support.h index a907e5261aa9..6cccf0b434f9 100644 --- a/lib/libc/posix1e/acl_support.h +++ b/lib/libc/posix1e/acl_support.h @@ -34,7 +34,7 @@ #define _POSIX1E_ACL_STRING_PERM_MAXSIZE 3 /* read, write, exec */ -int _posix1e_acl_check(struct acl *acl); +int _posix1e_acl_check(acl_t acl); int _posix1e_acl_sort(acl_t acl); int _posix1e_acl(acl_t acl, acl_type_t type); int _posix1e_acl_id_to_name(acl_tag_t tag, uid_t id, ssize_t buf_len, diff --git a/lib/libc/posix1e/acl_to_text.c b/lib/libc/posix1e/acl_to_text.c index 20f2b9e0bf44..4c079e42df6e 100644 --- a/lib/libc/posix1e/acl_to_text.c +++ b/lib/libc/posix1e/acl_to_text.c @@ -52,28 +52,31 @@ char * acl_to_text(acl_t acl, ssize_t *len_p) { - char *buf, *tmpbuf; - char name_buf[UT_NAMESIZE+1]; - char perm_buf[_POSIX1E_ACL_STRING_PERM_MAXSIZE+1], - effective_perm_buf[_POSIX1E_ACL_STRING_PERM_MAXSIZE+1]; - int i, error, len; - uid_t ae_id; - acl_tag_t ae_tag; - acl_perm_t ae_perm, effective_perm, mask_perm; + struct acl *acl_int; + char *buf, *tmpbuf; + char name_buf[UT_NAMESIZE+1]; + char perm_buf[_POSIX1E_ACL_STRING_PERM_MAXSIZE+1], + effective_perm_buf[_POSIX1E_ACL_STRING_PERM_MAXSIZE+1]; + int i, error, len; + uid_t ae_id; + acl_tag_t ae_tag; + acl_perm_t ae_perm, effective_perm, mask_perm; buf = strdup(""); if (!buf) return(NULL); - mask_perm = ACL_PERM_BITS; /* effective is regular if no mask */ - for (i = 0; i < acl->acl_cnt; i++) - if (acl->acl_entry[i].ae_tag == ACL_MASK) - mask_perm = acl->acl_entry[i].ae_perm; + acl_int = &acl->ats_acl; - for (i = 0; i < acl->acl_cnt; i++) { - ae_tag = acl->acl_entry[i].ae_tag; - ae_id = acl->acl_entry[i].ae_id; - ae_perm = acl->acl_entry[i].ae_perm; + mask_perm = ACL_PERM_BITS; /* effective is regular if no mask */ + for (i = 0; i < acl_int->acl_cnt; i++) + if (acl_int->acl_entry[i].ae_tag == ACL_MASK) + mask_perm = acl_int->acl_entry[i].ae_perm; + + for (i = 0; i < acl_int->acl_cnt; i++) { + ae_tag = acl_int->acl_entry[i].ae_tag; + ae_id = acl_int->acl_entry[i].ae_id; + ae_perm = acl_int->acl_entry[i].ae_perm; switch(ae_tag) { case ACL_USER_OBJ: diff --git a/lib/libc/posix1e/acl_valid.c b/lib/libc/posix1e/acl_valid.c index fe50889d6184..6eaa6ac058ab 100644 --- a/lib/libc/posix1e/acl_valid.c +++ b/lib/libc/posix1e/acl_valid.c @@ -78,7 +78,7 @@ acl_valid_file_np(const char *pathp, acl_type_t type, acl_t acl) } } - return (__acl_aclcheck_file(pathp, type, acl)); + return (__acl_aclcheck_file(pathp, type, &acl->ats_acl)); } @@ -95,5 +95,8 @@ acl_valid_fd_np(int fd, acl_type_t type, acl_t acl) } } - return (___acl_aclcheck_fd(fd, type, acl)); + acl->ats_cur_entry = 0; + + + return (___acl_aclcheck_fd(fd, type, &acl->ats_acl)); } diff --git a/sys/sys/acl.h b/sys/sys/acl.h index ec5a8364c83f..f274b26852dd 100644 --- a/sys/sys/acl.h +++ b/sys/sys/acl.h @@ -56,11 +56,18 @@ struct acl_entry { }; typedef struct acl_entry *acl_entry_t; +/* internal ACL structure */ struct acl { int acl_cnt; struct acl_entry acl_entry[ACL_MAX_ENTRIES]; }; -typedef struct acl *acl_t; + +/* external ACL structure */ +struct acl_t_struct { + struct acl ats_acl; + int ats_cur_entry; +}; +typedef struct acl_t_struct *acl_t; /* * Possible valid values for ae_tag field. @@ -148,14 +155,14 @@ __END_DECLS */ __BEGIN_DECLS int acl_add_perm(acl_permset_t _permset_d, acl_perm_t _perm); -int acl_calc_mask(acl_t *acl_p); +int acl_calc_mask(acl_t *_acl_p); int acl_clear_perms(acl_permset_t _permset_d); int acl_copy_entry(acl_entry_t _dest_d, acl_entry_t _src_d); ssize_t acl_copy_ext(void *_buf_p, acl_t _acl, ssize_t _size); acl_t acl_copy_int(const void *_buf_p); int acl_create_entry(acl_t *_acl_p, acl_entry_t *_entry_p); int acl_delete_fd_np(int _filedes, acl_type_t _type); -int acl_delete_entry(acl_t acl, acl_entry_t entry_d); +int acl_delete_entry(acl_t _acl, acl_entry_t _entry_d); int acl_delete_file_np(const char *_path_p, acl_type_t _type); int acl_delete_def_file(const char *_path_p); int acl_delete_perm(acl_permset_t _permset_d, acl_perm_t _perm);