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
This commit is contained in:
parent
15fca934f6
commit
0f6263079e
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=75928
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 \
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
*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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
{
|
||||
|
139
lib/libc/posix1e/acl_get_entry.3
Normal file
139
lib/libc/posix1e/acl_get_entry.3
Normal file
@ -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 .
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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:
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user