diff options
Diffstat (limited to 'src/shared/acl-util.c')
-rw-r--r-- | src/shared/acl-util.c | 102 |
1 files changed, 82 insertions, 20 deletions
diff --git a/src/shared/acl-util.c b/src/shared/acl-util.c index 950f472ddd..a4ff1ab878 100644 --- a/src/shared/acl-util.c +++ b/src/shared/acl-util.c @@ -29,14 +29,14 @@ int acl_find_uid(acl_t acl, uid_t uid, acl_entry_t *entry) { acl_entry_t i; - int found; + int r; assert(acl); assert(entry); - for (found = acl_get_entry(acl, ACL_FIRST_ENTRY, &i); - found > 0; - found = acl_get_entry(acl, ACL_NEXT_ENTRY, &i)) { + for (r = acl_get_entry(acl, ACL_FIRST_ENTRY, &i); + r > 0; + r = acl_get_entry(acl, ACL_NEXT_ENTRY, &i)) { acl_tag_t tag; uid_t *u; @@ -60,8 +60,7 @@ int acl_find_uid(acl_t acl, uid_t uid, acl_entry_t *entry) { return 1; } } - - if (found < 0) + if (r < 0) return -errno; return 0; @@ -69,14 +68,13 @@ int acl_find_uid(acl_t acl, uid_t uid, acl_entry_t *entry) { int calc_acl_mask_if_needed(acl_t *acl_p) { acl_entry_t i; - int found; + int r; assert(acl_p); - for (found = acl_get_entry(*acl_p, ACL_FIRST_ENTRY, &i); - found > 0; - found = acl_get_entry(*acl_p, ACL_NEXT_ENTRY, &i)) { - + for (r = acl_get_entry(*acl_p, ACL_FIRST_ENTRY, &i); + r > 0; + r = acl_get_entry(*acl_p, ACL_NEXT_ENTRY, &i)) { acl_tag_t tag; if (acl_get_tag_type(i, &tag) < 0) @@ -84,14 +82,80 @@ int calc_acl_mask_if_needed(acl_t *acl_p) { if (tag == ACL_MASK) return 0; + if (IN_SET(tag, ACL_USER, ACL_GROUP)) + goto calc; } - - if (found < 0) + if (r < 0) return -errno; + return 0; +calc: if (acl_calc_mask(acl_p) < 0) return -errno; + return 1; +} + +int add_base_acls_if_needed(acl_t *acl_p, const char *path) { + acl_entry_t i; + int r; + bool have_user_obj = false, have_group_obj = false, have_other = false; + struct stat st; + _cleanup_(acl_freep) acl_t basic = NULL; + + assert(acl_p); + + for (r = acl_get_entry(*acl_p, ACL_FIRST_ENTRY, &i); + r > 0; + r = acl_get_entry(*acl_p, ACL_NEXT_ENTRY, &i)) { + acl_tag_t tag; + + if (acl_get_tag_type(i, &tag) < 0) + return -errno; + + if (tag == ACL_USER_OBJ) + have_user_obj = true; + else if (tag == ACL_GROUP_OBJ) + have_group_obj = true; + else if (tag == ACL_OTHER) + have_other = true; + if (have_user_obj && have_group_obj && have_other) + return 0; + } + if (r < 0) + return -errno; + r = stat(path, &st); + if (r < 0) + return -errno; + + basic = acl_from_mode(st.st_mode); + if (!basic) + return -errno; + + for (r = acl_get_entry(basic, ACL_FIRST_ENTRY, &i); + r > 0; + r = acl_get_entry(basic, ACL_NEXT_ENTRY, &i)) { + acl_tag_t tag; + acl_entry_t dst; + + if (acl_get_tag_type(i, &tag) < 0) + return -errno; + + if ((tag == ACL_USER_OBJ && have_user_obj) || + (tag == ACL_GROUP_OBJ && have_group_obj) || + (tag == ACL_OTHER && have_other)) + continue; + + r = acl_create_entry(acl_p, &dst); + if (r < 0) + return -errno; + + r = acl_copy_entry(dst, i); + if (r < 0) + return -errno; + } + if (r < 0) + return -errno; return 0; } @@ -221,15 +285,15 @@ int parse_acl(char *text, acl_t *acl_access, acl_t *acl_default, bool want_mask) int acls_for_file(const char *path, acl_type_t type, acl_t new, acl_t *acl) { _cleanup_(acl_freep) acl_t old; acl_entry_t i; - int found, r; + int r; old = acl_get_file(path, type); if (!old) return -errno; - for (found = acl_get_entry(new, ACL_FIRST_ENTRY, &i); - found > 0; - found = acl_get_entry(new, ACL_NEXT_ENTRY, &i)) { + for (r = acl_get_entry(new, ACL_FIRST_ENTRY, &i); + r > 0; + r = acl_get_entry(new, ACL_NEXT_ENTRY, &i)) { acl_entry_t j; @@ -239,10 +303,8 @@ int acls_for_file(const char *path, acl_type_t type, acl_t new, acl_t *acl) { if (acl_copy_entry(j, i) < 0) return -errno; } - - r = calc_acl_mask_if_needed(&old); if (r < 0) - return r; + return -errno; *acl = old; old = NULL; |