diff options
Diffstat (limited to 'src/shared')
-rw-r--r-- | src/shared/acl-util.c | 102 | ||||
-rw-r--r-- | src/shared/acl-util.h | 2 |
2 files changed, 57 insertions, 47 deletions
diff --git a/src/shared/acl-util.c b/src/shared/acl-util.c index 36b3f0c16a..466f9aa601 100644 --- a/src/shared/acl-util.c +++ b/src/shared/acl-util.c @@ -81,17 +81,18 @@ 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 (IN_SET(tag, ACL_USER, ACL_GROUP)) { + if (acl_calc_mask(acl_p) < 0) + return -errno; + + return 1; + } } if (r < 0) return -errno; - return 0; -calc: - if (acl_calc_mask(acl_p) < 0) - return -errno; - return 1; + return 0; } int add_base_acls_if_needed(acl_t *acl_p, const char *path) { @@ -158,59 +159,68 @@ int add_base_acls_if_needed(acl_t *acl_p, const char *path) { return 0; } -int search_acl_groups(char*** dst, const char* path, bool* belong) { - acl_t acl; +int acl_search_groups(const char *path, char ***ret_groups) { + _cleanup_strv_free_ char **g = NULL; + _cleanup_(acl_free) acl_t acl = NULL; + bool ret = false; + acl_entry_t entry; + int r; assert(path); - assert(belong); acl = acl_get_file(path, ACL_TYPE_DEFAULT); - if (acl) { - acl_entry_t entry; - int r; - - r = acl_get_entry(acl, ACL_FIRST_ENTRY, &entry); - while (r > 0) { - acl_tag_t tag; - gid_t *gid; - char *name; + if (!acl) + return -errno; - r = acl_get_tag_type(entry, &tag); - if (r < 0) - break; + r = acl_get_entry(acl, ACL_FIRST_ENTRY, &entry); + for (;;) { + _cleanup_(acl_free_gid_tpp) gid_t *gid = NULL; + acl_tag_t tag; + + if (r < 0) + return -errno; + if (r == 0) + break; + + if (acl_get_tag_type(entry, &tag) < 0) + return -errno; - if (tag != ACL_GROUP) - goto next; + if (tag != ACL_GROUP) + goto next; - gid = acl_get_qualifier(entry); - if (!gid) - break; + gid = acl_get_qualifier(entry); + if (!gid) + return -errno; + + if (in_gid(*gid) > 0) { + if (!ret_groups) + return true; - if (in_gid(*gid) > 0) { - *belong = true; - break; - } + ret = true; + } + + if (ret_groups) { + char *name; name = gid_to_name(*gid); - if (!name) { - acl_free(acl); - return log_oom(); - } - - r = strv_consume(dst, name); - if (r < 0) { - acl_free(acl); - return log_oom(); - } - - next: - r = acl_get_entry(acl, ACL_NEXT_ENTRY, &entry); + if (!name) + return -ENOMEM; + + r = strv_consume(&g, name); + if (r < 0) + return r; } - acl_free(acl); + next: + r = acl_get_entry(acl, ACL_NEXT_ENTRY, &entry); } - return 0; + if (ret_groups) { + *ret_groups = g; + g = NULL; + } + + return ret; } int parse_acl(char *text, acl_t *acl_access, acl_t *acl_default, bool want_mask) { diff --git a/src/shared/acl-util.h b/src/shared/acl-util.h index fdb90063fa..c8bcc266d0 100644 --- a/src/shared/acl-util.h +++ b/src/shared/acl-util.h @@ -32,7 +32,7 @@ int acl_find_uid(acl_t acl, uid_t uid, acl_entry_t *entry); int calc_acl_mask_if_needed(acl_t *acl_p); int add_base_acls_if_needed(acl_t *acl_p, const char *path); -int search_acl_groups(char*** dst, const char* path, bool* belong); +int acl_search_groups(const char* path, char ***ret_groups); 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); |