summaryrefslogtreecommitdiffstats
path: root/bin/setfacl/merge.c
diff options
context:
space:
mode:
authorjedgar <jedgar@FreeBSD.org>2001-04-24 22:45:41 +0000
committerjedgar <jedgar@FreeBSD.org>2001-04-24 22:45:41 +0000
commit2da23531d99e45f34811fd6982a681112de0e182 (patch)
tree0b8830fcccafadf6607f3658e96733124ef8617d /bin/setfacl/merge.c
parentecbf3eacd9a17a3a9b238e2fa65b2d33d85e8d1f (diff)
downloadFreeBSD-src-2da23531d99e45f34811fd6982a681112de0e182.zip
FreeBSD-src-2da23531d99e45f34811fd6982a681112de0e182.tar.gz
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
Diffstat (limited to 'bin/setfacl/merge.c')
-rw-r--r--bin/setfacl/merge.c121
1 files changed, 80 insertions, 41 deletions
diff --git a/bin/setfacl/merge.c b/bin/setfacl/merge.c
index c739b26..acb01f4 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;
}
OpenPOWER on IntegriCloud