diff options
author | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2015-01-18 05:02:47 -0500 |
---|---|---|
committer | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2015-01-22 01:14:53 -0500 |
commit | 50d9e46dbb8400d4570781728c63b151d9ca982b (patch) | |
tree | c628f4011aaa45315d20106f6f78eb74e127b8b9 /src/shared | |
parent | b705ab6a838937f947216af7b2d1fffb00f8b0dc (diff) |
tmpfiles: implement augmenting of existing ACLs
This is much more useful in practice (equivalent to setfacl -m).
Diffstat (limited to 'src/shared')
-rw-r--r-- | src/shared/acl-util.c | 49 | ||||
-rw-r--r-- | src/shared/acl-util.h | 3 |
2 files changed, 44 insertions, 8 deletions
diff --git a/src/shared/acl-util.c b/src/shared/acl-util.c index 22bb8444e5..950f472ddd 100644 --- a/src/shared/acl-util.c +++ b/src/shared/acl-util.c @@ -150,7 +150,7 @@ int search_acl_groups(char*** dst, const char* path, bool* belong) { return 0; } -int parse_acl(char *text, acl_t *acl_access, acl_t *acl_default) { +int parse_acl(char *text, acl_t *acl_access, acl_t *acl_default, bool want_mask) { _cleanup_free_ char **a = NULL, **d = NULL; /* strings are not be freed */ _cleanup_strv_free_ char **split; char **entry; @@ -187,9 +187,11 @@ int parse_acl(char *text, acl_t *acl_access, acl_t *acl_default) { if (!a_acl) return -EINVAL; - r = calc_acl_mask_if_needed(&a_acl); - if (r < 0) - return r; + if (want_mask) { + r = calc_acl_mask_if_needed(&a_acl); + if (r < 0) + return r; + } } if (!strv_isempty(d)) { @@ -203,9 +205,11 @@ int parse_acl(char *text, acl_t *acl_access, acl_t *acl_default) { if (!d_acl) return -EINVAL; - r = calc_acl_mask_if_needed(&d_acl); - if (r < 0) - return r; + if (want_mask) { + r = calc_acl_mask_if_needed(&d_acl); + if (r < 0) + return r; + } } *acl_access = a_acl; @@ -213,3 +217,34 @@ int parse_acl(char *text, acl_t *acl_access, acl_t *acl_default) { a_acl = d_acl = NULL; return 0; } + +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; + + 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)) { + + acl_entry_t j; + + if (acl_create_entry(&old, &j) < 0) + return -errno; + + if (acl_copy_entry(j, i) < 0) + return -errno; + } + + r = calc_acl_mask_if_needed(&old); + if (r < 0) + return r; + + *acl = old; + old = NULL; + return 0; +} diff --git a/src/shared/acl-util.h b/src/shared/acl-util.h index 4133214d25..1ad4a2ebc7 100644 --- a/src/shared/acl-util.h +++ b/src/shared/acl-util.h @@ -32,7 +32,8 @@ 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 search_acl_groups(char*** dst, const char* path, bool* belong); -int parse_acl(char *text, acl_t *acl_access, acl_t *acl_default); +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); /* acl_free takes multiple argument types. * Multiple cleanup functions are necessary. */ |