aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris D. Faulhaber <jedgar@FreeBSD.org>2001-04-24 22:45:41 +0000
committerChris D. Faulhaber <jedgar@FreeBSD.org>2001-04-24 22:45:41 +0000
commit0f6263079e626b2fababe9cc131b589d1ecb3337 (patch)
treeefb3dda9df6725fd1e4073173d30bd26c7a03b89
parent15fca934f63619777be51e7b38a7f55dc69294d1 (diff)
downloadsrc-0f6263079e626b2fababe9cc131b589d1ecb3337.tar.gz
src-0f6263079e626b2fababe9cc131b589d1ecb3337.zip
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
Notes
Notes: svn path=/head/; revision=75928
-rw-r--r--bin/setfacl/mask.c24
-rw-r--r--bin/setfacl/merge.c121
-rw-r--r--bin/setfacl/remove.c81
-rw-r--r--bin/setfacl/setfacl.c26
-rw-r--r--bin/setfacl/setfacl.h14
-rw-r--r--lib/libc/posix1e/Makefile.inc1
-rw-r--r--lib/libc/posix1e/acl_calc_mask.c83
-rw-r--r--lib/libc/posix1e/acl_copy.c2
-rw-r--r--lib/libc/posix1e/acl_delete_entry.c35
-rw-r--r--lib/libc/posix1e/acl_entry.c44
-rw-r--r--lib/libc/posix1e/acl_free.c10
-rw-r--r--lib/libc/posix1e/acl_from_text.c14
-rw-r--r--lib/libc/posix1e/acl_get.c37
-rw-r--r--lib/libc/posix1e/acl_get_entry.3139
-rw-r--r--lib/libc/posix1e/acl_init.c17
-rw-r--r--lib/libc/posix1e/acl_perm.c40
-rw-r--r--lib/libc/posix1e/acl_set.c14
-rw-r--r--lib/libc/posix1e/acl_support.c25
-rw-r--r--lib/libc/posix1e/acl_support.h2
-rw-r--r--lib/libc/posix1e/acl_to_text.c35
-rw-r--r--lib/libc/posix1e/acl_valid.c7
-rw-r--r--sys/sys/acl.h13
22 files changed, 551 insertions, 233 deletions
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;
- 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;
+ 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;
- 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 <errno.h>
+#include <stdio.h>
/*
- * 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 <string.h>
/*
- * 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 <sys/types.h>
#include "namespace.h"
#include <sys/acl.h>
@@ -35,26 +33,41 @@
#include <errno.h>
#include <string.h>
+/*
+ * 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;
+ }
+
+ 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->acl_cnt; i++) {
+ 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 <errno.h>
#include <stdlib.h>
+/*
+ * 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;
+
+ if ((acl_int->acl_cnt >= ACL_MAX_ENTRIES) || (acl_int->acl_cnt < 0)) {
+ errno = EINVAL;
+ return -1;
+ }
- *entry_p = &acl->acl_entry[acl->acl_cnt++];
+ *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;
+
+ 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 = ENOSYS;
+ 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 <sys/errno.h>
#include <stdlib.h>
+/*
+ * 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 <sys/types.h>
+.Fd #include <sys/acl.h>
+.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 <string.h>
/*
- * 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);
+ acl_int = &acl->ats_acl;
+
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;
-
- 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;
+ 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);