uuid_t *
name_to_uuid(char *tok, int nametype) {
- struct passwd *tpass = NULL;
- struct group *tgrp = NULL;
uuid_t *entryg = NULL;
+ size_t len = strlen(tok);
- if ((entryg = (uuid_t *) calloc(1,sizeof(uuid_t))) == NULL)
- err(1, "Unable to allocate a uuid");
-
- if (nametype & NAME_USER)
- tpass = getpwnam(tok);
-
- if (NULL == tpass && (nametype & NAME_GROUP))
- tgrp = getgrnam(tok);
+ if ((entryg = (uuid_t *) calloc(1, sizeof(uuid_t))) == NULL) {
+ errx(1, "Unable to allocate a uuid");
+ }
- if (tpass) {
- if (0 != mbr_uid_to_uuid(tpass->pw_uid, *entryg)) {
- errx(1, "mbr_uid_to_uuid(): Unable to translate uid %d", tpass->pw_uid);
- }
- } else if (tgrp) {
- if (0 != mbr_gid_to_uuid(tgrp->gr_gid, *entryg)) {
- errx(1, "mbr_gid_to_uuid(): Unable to translate gid %d", tgrp->gr_gid);
- }
- } else {
- errx(1, "Unable to translate '%s' to a UID/GID", tok);
+ if ((nametype & NAME_USER) && mbr_identifier_to_uuid(ID_TYPE_USERNAME, tok, len, *entryg) == 0) {
+ return entryg;
+ }
+
+ if ((nametype & NAME_GROUP) && mbr_identifier_to_uuid(ID_TYPE_GROUPNAME, tok, len, *entryg) == 0) {
+ return entryg;
}
- return entryg;
+
+ errx(1, "Unable to translate '%s' to a UUID", tok);
}
/* Convert an acl entry in string form to an acl_entry_t */
return MATCH_EXACT;
}
-int
+static int
compare_acl_flagsets(acl_flagset_t aflags, acl_flagset_t bflags)
{
int i;
acl_permset_t aperms, bperms;
acl_flagset_t aflags, bflags;
int pcmp = 0, fcmp = 0;
+ void *aqual, *bqual;
+
+ aqual = acl_get_qualifier(a);
+ bqual = acl_get_qualifier(b);
+
+ int compare = compare_acl_qualifiers(aqual, bqual);
+ acl_free(aqual);
+ acl_free(bqual);
- if (0 != compare_acl_qualifiers(acl_get_qualifier(a),
- acl_get_qualifier(b)))
+ if (compare != 0)
return MATCH_NONE;
if (0 != acl_get_tag_type(a, &atag))
/* Remove all perms specified in modifier from rentry*/
int
-subtract_from_entry(acl_entry_t rentry, acl_entry_t modifier)
+subtract_from_entry(acl_entry_t rentry, acl_entry_t modifier, int* valid_perms)
{
acl_permset_t rperms, mperms;
acl_flagset_t rflags, mflags;
+ if (valid_perms)
+ *valid_perms = 0;
int i;
if ((acl_get_permset(rentry, &rperms) != 0) ||
for (i = 0; acl_perms[i].name != NULL; i++) {
if (acl_get_perm_np(mperms, acl_perms[i].perm))
acl_delete_perm(rperms, acl_perms[i].perm);
+ else if (valid_perms && acl_get_perm_np(rperms, acl_perms[i].perm))
+ (*valid_perms)++;
}
for (i = 0; acl_flags[i].name != NULL; i++) {
if (acl_get_flag_np(mflags, acl_flags[i].flag))
return 0;
}
/* Add the perms specified in modifier to rentry */
-int
+static int
merge_entry_perms(acl_entry_t rentry, acl_entry_t modifier)
{
acl_permset_t rperms, mperms;
int
modify_acl(acl_t *oaclp, acl_entry_t modifier, unsigned int optflags,
int position, int inheritance_level,
- unsigned flag_new_acl) {
+ unsigned flag_new_acl, const char* path) {
unsigned cpos = 0;
acl_entry_t newent = NULL;
if (0 != acl_create_entry_np(&oacl, &newent, position))
err(1, "acl_create_entry() failed");
acl_copy_entry(newent, modifier);
- }
- else {
+ } else {
/* If an entry exists, add the new permissions to it, else add an
* entry in the canonical position.
*/
err(1, "acl_create_entry() failed");
acl_copy_entry(newent, modifier);
}
- }
- else
- if (optflags & ACL_DELETE_FLAG) {
-
- if (flag_new_acl) {
- errx(1, "No ACL present");
- }
- if (position != -1 ) {
- if (0 != acl_get_entry(oacl, position, &rentry))
- err(1, "Invalid entry number");
+ } else if (optflags & ACL_DELETE_FLAG) {
+ if (flag_new_acl) {
+ warnx("No ACL present '%s'", path);
+ retval = 1;
+ } else if (position != -1 ) {
+ if (0 != acl_get_entry(oacl, position, &rentry)) {
+ warnx("Invalid entry number '%s'", path);
+ retval = 1;
+ } else {
acl_delete_entry(oacl, rentry);
}
- else {
- unsigned match_found = 0, aindex;
- for (aindex = 0;
- acl_get_entry(oacl, rentry == NULL ?
- ACL_FIRST_ENTRY :
- ACL_NEXT_ENTRY, &rentry)
- == 0; aindex++) {
- unsigned cmp;
- cmp = compare_acl_entries(rentry,
- modifier);
- if ((cmp == MATCH_EXACT) ||
- (cmp == MATCH_PARTIAL)) {
- match_found++;
- if (cmp == MATCH_EXACT)
- acl_delete_entry(oacl, rentry);
- else
+ } else {
+ unsigned match_found = 0, aindex;
+ for (aindex = 0;
+ acl_get_entry(oacl, rentry == NULL ?
+ ACL_FIRST_ENTRY :
+ ACL_NEXT_ENTRY, &rentry) == 0;
+ aindex++) {
+ unsigned cmp;
+ cmp = compare_acl_entries(rentry, modifier);
+ if ((cmp == MATCH_EXACT) ||
+ (cmp == MATCH_PARTIAL)) {
+ match_found++;
+ if (cmp == MATCH_EXACT)
+ acl_delete_entry(oacl, rentry);
+ else {
+ int valid_perms;
/* In the event of a partial match, remove the specified perms from the
* entry */
- subtract_from_entry(rentry, modifier);
+ subtract_from_entry(rentry, modifier, &valid_perms);
+ /* if no perms survived then delete the entry */
+ if (valid_perms == 0)
+ acl_delete_entry(oacl, rentry);
}
}
- if (0 == match_found) {
- warnx("Entry not found when attempting delete");
- retval = 1;
- }
}
- }
- else
- if (optflags & ACL_REWRITE_FLAG) {
- acl_entry_t rentry;
-
- if (-1 == position) {
- usage();
- }
- if (0 == flag_new_acl) {
- if (0 != acl_get_entry(oacl, position,
- &rentry))
- err(1, "Invalid entry number");
-
- if (0 != acl_delete_entry(oacl, rentry))
- err(1, "Unable to delete entry");
- }
- if (0!= acl_create_entry_np(&oacl, &newent, position))
- err(1, "acl_create_entry() failed");
- acl_copy_entry(newent, modifier);
+ if (0 == match_found) {
+ warnx("Entry not found when attempting delete '%s'",path);
+ retval = 1;
}
+ }
+ } else if (optflags & ACL_REWRITE_FLAG) {
+ acl_entry_t rentry;
+
+ if (-1 == position) {
+ usage();
+ }
+ if (0 == flag_new_acl) {
+ if (0 != acl_get_entry(oacl, position,
+ &rentry))
+ err(1, "Invalid entry number '%s'", path);
+
+ if (0 != acl_delete_entry(oacl, rentry))
+ err(1, "Unable to delete entry '%s'", path);
+ }
+ if (0!= acl_create_entry_np(&oacl, &newent, position))
+ err(1, "acl_create_entry() failed");
+ acl_copy_entry(newent, modifier);
+ }
ma_exit:
*oaclp = oacl;
return retval;
}
int
-modify_file_acl(unsigned int optflags, const char *path, acl_t modifier, int position, int inheritance_level) {
+modify_file_acl(unsigned int optflags, const char *path, acl_t modifier, int position, int inheritance_level, int follow) {
acl_t oacl = NULL;
unsigned aindex = 0, flag_new_acl = 0;
acl_entry_t newent = NULL;
acl_entry_t entry = NULL;
- unsigned retval = 0 ;
+ unsigned retval = 0;
extern int fflag;
if (optflags & ACL_CLEAR_FLAG) {
filesec_t fsec = filesec_init();
- if (fsec == NULL)
+ if (fsec == NULL) {
err(1, "filesec_init() failed");
- if (filesec_set_property(fsec, FILESEC_ACL,
- _FILESEC_REMOVE_ACL) != 0)
+ }
+ if (filesec_set_property(fsec, FILESEC_ACL, _FILESEC_REMOVE_ACL) != 0) {
err(1, "filesec_set_property() failed");
- if (chmodx_np(path, fsec) != 0) {
- if (!fflag)
- warn("Failed to clear ACL on file %s", path);
- retval = 1;
- } else
- retval = 0;
+ }
+ if (follow) {
+ if (chmodx_np(path, fsec) != 0) {
+ if (!fflag) {
+ warn("Failed to clear ACL on file %s", path);
+ }
+ retval = 1;
+ }
+ } else {
+ int fd = open(path, O_SYMLINK);
+ if (fd != -1) {
+ if (fchmodx_np(fd, fsec) != 0) {
+ if (!fflag) {
+ warn("Failed to clear ACL on file %s", path);
+ }
+ retval = 1;
+ }
+ close(fd);
+ } else {
+ if (!fflag) {
+ warn("Failed to open file %s", path);
+ }
+ retval = 1;
+ }
+ }
filesec_free(fsec);
return (retval);
}
- if (optflags & ACL_FROM_STDIN)
+ if (optflags & ACL_FROM_STDIN) {
oacl = acl_dup(modifier);
- else {
- oacl = acl_get_file(path, ACL_TYPE_EXTENDED);
-
+ } else {
+ if (follow) {
+ oacl = acl_get_file(path, ACL_TYPE_EXTENDED);
+ } else {
+ int fd = open(path, O_SYMLINK);
+ if (fd != -1) {
+ oacl = acl_get_fd_np(fd, ACL_TYPE_EXTENDED);
+ close(fd);
+ }
+ }
if ((oacl == NULL) ||
(acl_get_entry(oacl,ACL_FIRST_ENTRY, &newent) != 0)) {
if ((oacl = acl_init(1)) == NULL)
} else if (((optflags & ACL_DELETE_FLAG) && (position != -1))
|| (optflags & ACL_CHECK_CANONICITY)) {
retval = modify_acl(&oacl, NULL, optflags, position,
- inheritance_level, flag_new_acl);
+ inheritance_level, flag_new_acl, path);
} else if ((optflags & (ACL_REMOVE_INHERIT_FLAG|ACL_REMOVE_INHERITED_ENTRIES)) && flag_new_acl) {
warnx("No ACL currently associated with file '%s'", path);
retval = 1;
retval += modify_acl(&oacl, entry, optflags,
position, inheritance_level,
- flag_new_acl);
+ flag_new_acl, path);
}
}
}
* "changeset" mechanism, common locking strategy, or kernel
* supplied reservation mechanism to prevent this race.
*/
- if (!(optflags & (ACL_TO_STDOUT|ACL_CHECK_CANONICITY)) &&
- (0 != acl_set_file(path, ACL_TYPE_EXTENDED, oacl))){
- if (!fflag)
- warn("Failed to set ACL on file '%s'", path);
- retval = 1;
+ if (!(optflags & (ACL_TO_STDOUT|ACL_CHECK_CANONICITY))) {
+ int status = -1;
+ if (follow) {
+ status = acl_set_file(path, ACL_TYPE_EXTENDED, oacl);
+ } else {
+ int fd = open(path, O_SYMLINK);
+ if (fd != -1) {
+ status = acl_set_fd_np(fd, oacl,
+ ACL_TYPE_EXTENDED);
+ close(fd);
+ }
+ }
+ if (status != 0) {
+ if (!fflag)
+ warn("Failed to set ACL on file '%s'", path);
+ retval = 1;
+ }
}
if (oacl)