diff options
author | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2015-01-17 23:27:39 -0500 |
---|---|---|
committer | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2015-01-22 01:14:53 -0500 |
commit | f8eeeaf9b783ebbab30672629abf3920db286811 (patch) | |
tree | dde9bca6dd3cf7ad995f1434edbd760e31a44934 /src | |
parent | 3f93da987961c139215d3a55fd25496310537d1b (diff) | |
download | systemd-f8eeeaf9b783ebbab30672629abf3920db286811.tar.gz |
tmpfiles: add 'a' type to set ACLs
Diffstat (limited to 'src')
-rw-r--r-- | src/journal/coredump.c | 6 | ||||
-rw-r--r-- | src/journal/journalctl.c | 6 | ||||
-rw-r--r-- | src/journal/journald-server.c | 5 | ||||
-rw-r--r-- | src/login/logind-acl.c | 2 | ||||
-rw-r--r-- | src/shared/acl-util.c | 66 | ||||
-rw-r--r-- | src/shared/acl-util.h | 19 | ||||
-rw-r--r-- | src/tmpfiles/tmpfiles.c | 81 |
7 files changed, 160 insertions, 25 deletions
diff --git a/src/journal/coredump.c b/src/journal/coredump.c index a37e5eb8a7..d322e7984c 100644 --- a/src/journal/coredump.c +++ b/src/journal/coredump.c @@ -49,11 +49,7 @@ #include "path-util.h" #include "compress.h" #include "coredump-vacuum.h" - -#ifdef HAVE_ACL -# include <sys/acl.h> -# include "acl-util.h" -#endif +#include "acl-util.h" /* The maximum size up to which we process coredumps */ #define PROCESS_SIZE_MAX ((off_t) (2LLU*1024LLU*1024LLU*1024LLU)) diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c index 27a6187e50..c17cf55c30 100644 --- a/src/journal/journalctl.c +++ b/src/journal/journalctl.c @@ -37,17 +37,13 @@ #include <sys/inotify.h> #include <linux/fs.h> -#ifdef HAVE_ACL -#include <sys/acl.h> -#include "acl-util.h" -#endif - #include "sd-journal.h" #include "sd-bus.h" #include "log.h" #include "logs-show.h" #include "util.h" +#include "acl-util.h" #include "path-util.h" #include "fileio.h" #include "build.h" diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c index 5999724edc..87b459b3ca 100644 --- a/src/journal/journald-server.c +++ b/src/journal/journald-server.c @@ -52,12 +52,7 @@ #include "journald-native.h" #include "journald-audit.h" #include "journald-server.h" - -#ifdef HAVE_ACL -#include <sys/acl.h> -#include <acl/libacl.h> #include "acl-util.h" -#endif #ifdef HAVE_SELINUX #include <selinux/selinux.h> diff --git a/src/login/logind-acl.c b/src/login/logind-acl.c index f7c6f3a4ef..5856f9079d 100644 --- a/src/login/logind-acl.c +++ b/src/login/logind-acl.c @@ -22,8 +22,6 @@ #include <assert.h> #include <errno.h> #include <string.h> -#include <sys/acl.h> -#include <acl/libacl.h> #include "util.h" #include "acl-util.h" diff --git a/src/shared/acl-util.c b/src/shared/acl-util.c index c93f58a739..22bb8444e5 100644 --- a/src/shared/acl-util.c +++ b/src/shared/acl-util.c @@ -20,8 +20,6 @@ ***/ #include <assert.h> -#include <sys/acl.h> -#include <acl/libacl.h> #include <errno.h> #include <stdbool.h> @@ -151,3 +149,67 @@ 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) { + _cleanup_free_ char **a = NULL, **d = NULL; /* strings are not be freed */ + _cleanup_strv_free_ char **split; + char **entry; + int r = -EINVAL; + _cleanup_(acl_freep) acl_t a_acl = NULL, d_acl = NULL; + + split = strv_split(text, ","); + if (!split) + return log_oom(); + + STRV_FOREACH(entry, split) { + char *p; + + p = startswith(*entry, "default:"); + if (!p) + p = startswith(*entry, "d:"); + + if (p) + r = strv_push(&d, p); + else + r = strv_push(&a, *entry); + } + if (r < 0) + return r; + + if (!strv_isempty(a)) { + _cleanup_free_ char *join; + + join = strv_join(a, ","); + if (!join) + return -ENOMEM; + + a_acl = acl_from_text(join); + if (!a_acl) + return -EINVAL; + + r = calc_acl_mask_if_needed(&a_acl); + if (r < 0) + return r; + } + + if (!strv_isempty(d)) { + _cleanup_free_ char *join; + + join = strv_join(d, ","); + if (!join) + return -ENOMEM; + + d_acl = acl_from_text(join); + if (!d_acl) + return -EINVAL; + + r = calc_acl_mask_if_needed(&d_acl); + if (r < 0) + return r; + } + + *acl_access = a_acl; + *acl_default = d_acl; + a_acl = d_acl = NULL; + return 0; +} diff --git a/src/shared/acl-util.h b/src/shared/acl-util.h index a753ad14fd..4133214d25 100644 --- a/src/shared/acl-util.h +++ b/src/shared/acl-util.h @@ -21,16 +21,23 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ +#ifdef HAVE_ACL + #include <stdbool.h> +#include <sys/acl.h> +#include <acl/libacl.h> + +#include "macro.h" 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); -static inline void acl_freep(acl_t *acl) { - - if (!*acl) - return; +/* acl_free takes multiple argument types. + * Multiple cleanup functions are necessary. */ +DEFINE_TRIVIAL_CLEANUP_FUNC(acl_t, acl_free); +#define acl_free_charp acl_free +DEFINE_TRIVIAL_CLEANUP_FUNC(char*, acl_free_charp); - acl_free(*acl); -} +#endif diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c index c44dfaf1d2..7081b4dc57 100644 --- a/src/tmpfiles/tmpfiles.c +++ b/src/tmpfiles/tmpfiles.c @@ -57,6 +57,7 @@ #include "copy.h" #include "selinux-util.h" #include "btrfs-util.h" +#include "acl-util.h" /* This reads all files listed in /etc/tmpfiles.d/?*.conf and creates * them in the file system. This is intended to be used to create @@ -76,6 +77,7 @@ typedef enum ItemType { CREATE_BLOCK_DEVICE = 'b', COPY_FILES = 'C', SET_XATTR = 't', + SET_ACL = 'a', /* These ones take globs */ WRITE_FILE = 'w', @@ -94,6 +96,10 @@ typedef struct Item { char *path; char *argument; char **xattrs; +#ifdef HAVE_ACL + acl_t acl_access; + acl_t acl_default; +#endif uid_t uid; gid_t gid; mode_t mode; @@ -581,6 +587,59 @@ static int item_set_xattrs(Item *i, const char *path) { return 0; } +static int get_acls_from_arg(Item *item) { +#ifdef HAVE_ACL + int r; + _cleanup_(acl_freep) acl_t a = NULL, d = NULL; + + assert(item); + + r = parse_acl(item->argument, &item->acl_access, &item->acl_default); + if (r < 0) + log_warning_errno(errno, "Failed to parse ACL \"%s\": %m. Ignoring", + item->argument); +#else + log_warning_errno(ENOSYS, "ACLs are not supported. Ignoring"); +#endif + + return 0; +} + +static int item_set_acl(Item *item, const char *path) { +#ifdef HAVE_ACL + int r; + + assert(item); + 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); + } + } + + 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); + } + } +#endif + + return 0; +} + static int write_one_file(Item *i, const char *path) { _cleanup_close_ int fd = -1; int flags, r = 0; @@ -974,6 +1033,11 @@ static int create_item(Item *i) { if (r < 0) return r; break; + + case SET_ACL: + r = item_set_acl(i, i->path); + if (r < 0) + return r; } log_debug("%s created successfully.", i->path); @@ -1004,6 +1068,7 @@ static int remove_item_instance(Item *i, const char *instance) { case WRITE_FILE: case COPY_FILES: case SET_XATTR: + case SET_ACL: break; case REMOVE_PATH: @@ -1049,6 +1114,7 @@ static int remove_item(Item *i) { case WRITE_FILE: case COPY_FILES: case SET_XATTR: + case SET_ACL: break; case REMOVE_PATH: @@ -1190,6 +1256,11 @@ static void item_free_contents(Item *i) { free(i->path); free(i->argument); strv_free(i->xattrs); + +#ifdef HAVE_ACL + acl_free(i->acl_access); + acl_free(i->acl_default); +#endif } static void item_array_free(ItemArray *a) { @@ -1396,6 +1467,16 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) { return r; break; + case SET_ACL: + if (!i.argument) { + log_error("[%s:%u] Set ACLs requires argument.", fname, line); + return -EBADMSG; + } + r = get_acls_from_arg(&i); + if (r < 0) + return r; + break; + default: log_error("[%s:%u] Unknown command type '%c'.", fname, line, i.type); return -EBADMSG; |