From 23b400b919b2078165b33bcaa5f5225ceaf35837 Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Tue, 14 Aug 2012 16:34:10 -0400 Subject: [PATCH] Fix the logic so that it removes user/other read/write perms not specified in the default ACL. Don't print "Success." --- src/aclq.c | 224 +++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 166 insertions(+), 58 deletions(-) diff --git a/src/aclq.c b/src/aclq.c index 5cdcea9..27b0224 100644 --- a/src/aclq.c +++ b/src/aclq.c @@ -73,7 +73,7 @@ bool is_directory(const char* path) { } -int has_default_tag_acl(const char* path, acl_tag_t tag_type) { +int has_default_tag_acl(const char* path, acl_tag_t desired_tag) { /* Returns one if the given path has a default ACL for the supplied tag, zero if it doesn't, and -1 on error. */ acl_t defacl = acl_get_file(path, ACL_TYPE_DEFAULT); @@ -94,7 +94,7 @@ int has_default_tag_acl(const char* path, acl_tag_t tag_type) { return -1; } else { - if (tag == tag_type) { + if (tag == desired_tag) { return 1; } } @@ -142,54 +142,41 @@ int has_default_other_acl(const char* path) { } -int get_default_tag_permset(const char* path, - acl_tag_t tag_type, - acl_permset_t* output_perms) { - /* Returns one if successful, zero when the ACL doesn't exist, and +int get_default_tag_entry(const char* path, + acl_tag_t desired_tag, + acl_entry_t* entry) { + /* Returns one if successful, zero when the ACL doesn't exist, and -1 on unexpected errors. */ acl_t defacl = acl_get_file(path, ACL_TYPE_DEFAULT); if (defacl == (acl_t)NULL) { /* Follow the acl_foo convention of -1 == error. */ - errno = EINVAL; return 0; } - acl_entry_t entry; - int result = acl_get_entry(defacl, ACL_FIRST_ENTRY, &entry); + int result = acl_get_entry(defacl, ACL_FIRST_ENTRY, entry); while (result == 1) { acl_tag_t tag = ACL_UNDEFINED_TAG; - int tag_result = acl_get_tag_type(entry, &tag); + int tag_result = acl_get_tag_type(*entry, &tag); if (tag_result == -1) { - perror("get_default_tag_permset (acl_get_tag_type)"); + perror("get_default_tag_entry (acl_get_tag_type)"); return -1; } - else { - if (tag == tag_type) { - /* We found the right tag, now get the permset. */ - int ps_result = acl_get_permset(entry, output_perms); - if (ps_result == -1) { - perror("get_default_tag_permset (acl_get_permset)"); - } - - if (ps_result == 0) { - return 1; - } - else { - return 0; - } - } + + if (tag == desired_tag) { + /* We found the right tag, so return successfully. */ + return 1; } - result = acl_get_entry(defacl, ACL_NEXT_ENTRY, &entry); + result = acl_get_entry(defacl, ACL_NEXT_ENTRY, entry); } /* This catches both the initial acl_get_entry and the ones at the end of the loop. */ if (result == -1) { - perror("get_default_tag_permset (acl_get_entry)"); + perror("get_default_tag_entry (acl_get_entry)"); return -1; } @@ -197,6 +184,42 @@ int get_default_tag_permset(const char* path, } + +int get_default_tag_permset(const char* path, + acl_tag_t desired_tag, + acl_permset_t* output_perms) { + /* Returns one if successful, zero when the ACL doesn't exist, and + -1 on unexpected errors. */ + acl_t defacl = acl_get_file(path, ACL_TYPE_DEFAULT); + + if (defacl == (acl_t)NULL) { + /* Follow the acl_foo convention of -1 == error. */ + return 0; + } + + acl_entry_t entry; + int result = get_default_tag_entry(path, desired_tag, &entry); + + if (result == 1) { + /* We found the right tag, now get the permset. */ + int ps_result = acl_get_permset(entry, output_perms); + if (ps_result == -1) { + perror("get_default_tag_permset (acl_get_permset)"); + } + + if (ps_result == 0) { + return 1; + } + else { + return 0; + } + } + else { + return result; + } +} + + int has_default_tag_perm(const char* path, acl_tag_t tag, acl_perm_t perm) { @@ -224,6 +247,61 @@ int has_default_tag_perm(const char* path, return p_result; } +int remove_default_tag_perm(const char* path, + acl_tag_t tag, + acl_perm_t perm) { + /* Attempt to remove perm from tag. Returns one if successful, zero + if there was nothing to do, and -1 on errors. */ + int hdta = has_default_tag_acl(path, tag); + if (hdta != 1) { + /* Failure or error. */ + return hdta; + } + + acl_permset_t permset; + bool ps_result = get_default_tag_permset(path, tag, &permset); + + if (ps_result != 1) { + /* Failure or error. */ + return ps_result; + } + + int d_result = acl_delete_perm(permset, perm); + if (d_result == -1) { + perror("remove_default_tag_perm (acl_delete_perm)"); + return -1; + } + + /* We've only removed perm from the permset; now we have to replace + the permset. */ + acl_entry_t entry; + int entry_result = get_default_tag_entry(path, tag, &entry); + + if (entry_result == -1) { + perror("remove_default_tag_perm (get_default_tag_entry)"); + return -1; + } + + if (entry_result == 1) { + /* Success. */ + int s_result = acl_set_permset(entry, permset); + if (s_result == -1) { + perror("remove_default_tag_perm (acl_set_permset)"); + return -1; + } + + return 1; + } + else { + return 0; + } +} + +int remove_default_group_obj_execute(const char* path) { + return remove_default_tag_perm(path, ACL_GROUP_OBJ, ACL_EXECUTE); +} + + int has_default_user_obj_read(const char* path) { return has_default_tag_perm(path, ACL_USER_OBJ, ACL_READ); } @@ -304,56 +382,87 @@ int reapply_default_acl(const char* path) { mode_t path_mode = get_mode(path); - /* If parent has a default user ACL, apply it to path via chmod. */ - if (has_default_user_obj_read(parent)) { - path_mode |= S_IRUSR; - } + /* If parent has a default user ACL, apply it. */ + if (has_default_user_obj_acl(parent)) { - if (has_default_user_obj_write(parent)) { - path_mode |= S_IWUSR; - } + if (has_default_user_obj_read(parent)) { + /* Add user read. */ + path_mode |= S_IRUSR; + } + else { + /* Remove user read. */ + path_mode &= ~S_IRUSR; + } - /* However, we don't want to set the execute bit on via the ACL - unless it was on originally. Furthermore, if the ACL denies - execute, we want to honor that. */ - if (has_default_user_obj_acl(parent)) { + + if (has_default_user_obj_write(parent)) { + /* Add user write. */ + path_mode |= S_IWUSR; + } + else { + /* Remove user write. */ + path_mode &= ~S_IWUSR; + } + + + /* We don't want to set the execute bit on via the ACL unless it + was on originally. */ if (!has_default_user_obj_execute(parent)) { - /* It has a user ACL, but no user execute is granted. */ + /* Remove user execute. */ path_mode &= ~S_IXUSR; } } /* Do the same thing with the other perms/ACL. */ - if (has_default_other_read(parent)) { - path_mode |= S_IROTH; - } + if (has_default_other_acl(parent)) { - if (has_default_other_write(parent)) { - path_mode |= S_IWOTH; - } + if (has_default_other_read(parent)) { + path_mode |= S_IROTH; + } + else { + path_mode &= ~S_IROTH; + } - if (has_default_other_acl(parent)) { + + if (has_default_other_write(parent)) { + path_mode |= S_IWOTH; + } + else { + path_mode &= ~S_IWOTH; + } + + + /* We don't want to set the execute bit on via the ACL unless it + was on originally. */ if (!has_default_other_execute(parent)) { - /* It has an other ACL, but no other execute is granted. */ path_mode &= ~S_IXOTH; } } + if (has_minimal_default_acl(parent)) { /* With a minimal ACL, we'll repeat for the group bits what we already did for the owner/other bits. */ - if (has_default_group_obj_read(parent)) { - path_mode |= S_IRGRP; - } + if (has_default_group_obj_acl(parent)) { + if (has_default_group_obj_read(parent)) { + path_mode |= S_IRGRP; + } + else { + path_mode &= ~S_IRGRP; + } - if (has_default_group_obj_write(parent)) { - path_mode |= S_IWGRP; - } - if (has_default_group_obj_acl(parent)) { + if (has_default_group_obj_write(parent)) { + path_mode |= S_IWGRP; + } + else { + path_mode &= ~S_IWGRP; + } + + /* We don't want to set the execute bit on via the ACL unless it + was on originally. */ if (!has_default_group_obj_execute(parent)) { - /* It has a group ACL, but no group execute is granted. */ path_mode &= ~S_IXGRP; } } @@ -388,7 +497,7 @@ int reapply_default_acl(const char* path) { from the mode bits, but from the group:: ACL entry. So, to do this, we remove the group::x entry. */ if (has_default_group_obj_execute(path)) { - /* remove_default_group_obj_execute(path);*/ + remove_default_group_obj_execute(path); } } } @@ -409,7 +518,6 @@ int main(int argc, char* argv[]) { bool result = reapply_default_acl(target); if (result) { - printf("Success.\n"); return EXIT_SUCCESS; } else { -- 2.44.2