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/tmpfiles/tmpfiles.c | |
parent | b705ab6a838937f947216af7b2d1fffb00f8b0dc (diff) |
tmpfiles: implement augmenting of existing ACLs
This is much more useful in practice (equivalent to setfacl -m).
Diffstat (limited to 'src/tmpfiles/tmpfiles.c')
-rw-r--r-- | src/tmpfiles/tmpfiles.c | 54 |
1 files changed, 35 insertions, 19 deletions
diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c index 44a087807e..3c8993e894 100644 --- a/src/tmpfiles/tmpfiles.c +++ b/src/tmpfiles/tmpfiles.c @@ -600,7 +600,9 @@ static int get_acls_from_arg(Item *item) { assert(item); - r = parse_acl(item->argument, &item->acl_access, &item->acl_default); + /* If force (= modify) is set, we will not modify the acl + * afterwards, so the mask can be added now if necessary. */ + r = parse_acl(item->argument, &item->acl_access, &item->acl_default, !item->force); if (r < 0) log_warning_errno(errno, "Failed to parse ACL \"%s\": %m. Ignoring", item->argument); @@ -611,6 +613,32 @@ static int get_acls_from_arg(Item *item) { return 0; } +static int path_set_acl(const char *path, acl_type_t type, acl_t acl, bool modify) { + _cleanup_(acl_freep) acl_t cleanme = NULL; + int r; + + if (modify) { + r = acls_for_file(path, type, acl, &cleanme); + if (r < 0) + return r; + acl = cleanme; + }; + + r = acl_set_file(path, type, acl); + if (r < 0) { + _cleanup_(acl_free_charpp) char *t; + + r = -errno; + t = acl_to_any_text(acl, NULL, ',', TEXT_ABBREVIATE); + log_error_errno(r, + "Setting %s ACL \"%s\" on %s failed: %m", + type == ACL_TYPE_ACCESS ? "access" : "default", + strna(t), path); + } + + return r; +} + static int path_set_acls(Item *item, const char *path) { #ifdef HAVE_ACL int r; @@ -619,27 +647,15 @@ static int path_set_acls(Item *item, const char *path) { assert(path); if (item->acl_access) { - r = acl_set_file(path, ACL_TYPE_ACCESS, item->acl_access); - if (r < 0) { - _cleanup_(acl_free_charpp) char *t; - - t = acl_to_any_text(item->acl_access, NULL, ',', TEXT_ABBREVIATE); - return log_error_errno(errno, - "Setting access ACL \"%s\" on %s failed: %m", - strna(t), path); - } + r = path_set_acl(path, ACL_TYPE_ACCESS, item->acl_access, item->force); + if (r < 0) + return r; } if (item->acl_default) { - r = acl_set_file(path, ACL_TYPE_DEFAULT, item->acl_default); - if (r < 0) { - _cleanup_(acl_free_charpp) char *t; - - t = acl_to_any_text(item->acl_default, NULL, ',', TEXT_ABBREVIATE); - return log_error_errno(errno, - "Setting default ACL \"%s\" on %s failed: %m", - strna(t), path); - } + r = path_set_acl(path, ACL_TYPE_DEFAULT, item->acl_default, item->force); + if (r < 0) + return r; } #endif |