X-Git-Url: https://git.saurik.com/apple/file_cmds.git/blobdiff_plain/40bf83fed3260cbe00f8bd41f2f5a5f622d625be..refs/heads/master:/chmod/chmod_acl.c diff --git a/chmod/chmod_acl.c b/chmod/chmod_acl.c index 16ed9f2..5ac4c17 100644 --- a/chmod/chmod_acl.c +++ b/chmod/chmod_acl.c @@ -100,31 +100,22 @@ static struct { 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 */ @@ -341,7 +332,7 @@ compare_acl_permsets(acl_permset_t aperms, acl_permset_t bperms) return MATCH_EXACT; } -int +static int compare_acl_flagsets(acl_flagset_t aflags, acl_flagset_t bflags) { int i; @@ -362,9 +353,16 @@ compare_acl_entries(acl_entry_t a, acl_entry_t b) 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)) @@ -531,7 +529,7 @@ subtract_from_entry(acl_entry_t rentry, acl_entry_t modifier, int* valid_perms) 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; @@ -672,13 +670,13 @@ ma_exit: } 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; @@ -701,26 +699,52 @@ modify_file_acl(unsigned int optflags, const char *path, acl_t modifier, int pos 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) @@ -807,11 +831,23 @@ modify_file_acl(unsigned int optflags, const char *path, acl_t modifier, int pos * "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)