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;
- if (0 != compare_acl_qualifiers(acl_get_qualifier(a),
- acl_get_qualifier(b)))
+ aqual = acl_get_qualifier(a);
+ bqual = acl_get_qualifier(b);
+
+ int compare = compare_acl_qualifiers(aqual, bqual);
+ acl_free(aqual);
+ acl_free(bqual);
+
+ if (compare != 0)
return MATCH_NONE;
if (0 != acl_get_tag_type(a, &atag))
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_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)
* "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)