From 9db59d928356e63f0d06bdcc528e579b92c20b89 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 21 Jul 2020 22:14:57 +0200 Subject: [PATCH] acl-util: beef up add_acls_for_user() Let's add support for controlling r/w/x bits separetely. This is useful for using it to control access to directories, where r + x shall be enabled. --- src/coredump/coredump.c | 2 +- src/journal/journald-server.c | 2 +- src/shared/acl-util.c | 23 ++++++++++++++++++----- src/shared/acl-util.h | 2 +- src/test/test-acl-util.c | 6 +++--- 5 files changed, 24 insertions(+), 11 deletions(-) diff --git a/src/coredump/coredump.c b/src/coredump/coredump.c index 8b052dac26..9b7811ae54 100644 --- a/src/coredump/coredump.c +++ b/src/coredump/coredump.c @@ -186,7 +186,7 @@ static int fix_acl(int fd, uid_t uid) { return 0; /* Make sure normal users can read (but not write or delete) their own coredumps */ - r = add_acls_for_user(fd, uid); + r = fd_add_uid_acl_permission(fd, uid, /* read = */ true, /* write = */ false, /* execute = */ false); if (r < 0) return log_error_errno(r, "Failed to adjust ACL of coredump: %m"); #endif diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c index 0d8e3618ee..8a8c41b7a5 100644 --- a/src/journal/journald-server.c +++ b/src/journal/journald-server.c @@ -256,7 +256,7 @@ static void server_add_acls(JournalFile *f, uid_t uid) { if (uid_for_system_journal(uid)) return; - r = add_acls_for_user(f->fd, uid); + r = fd_add_uid_acl_permission(f->fd, uid, /* read = */ true, /* write = */ false, /* execute = */ false); if (r < 0) log_warning_errno(r, "Failed to set ACL on %s, ignoring: %m", f->path); #endif diff --git a/src/shared/acl-util.c b/src/shared/acl-util.c index 641e5bda7a..02c94f9358 100644 --- a/src/shared/acl-util.c +++ b/src/shared/acl-util.c @@ -378,12 +378,21 @@ int acls_for_file(const char *path, acl_type_t type, acl_t new, acl_t *acl) { return 0; } -int add_acls_for_user(int fd, uid_t uid) { +int fd_add_uid_acl_permission( + int fd, + uid_t uid, + bool rd, + bool wr, + bool ex) { + _cleanup_(acl_freep) acl_t acl = NULL; acl_permset_t permset; acl_entry_t entry; int r; + /* Adds an ACL entry for the specified file to allow the indicated access to the specified + * user. Operates purely incrementally. */ + assert(fd >= 0); assert(uid_is_valid(uid)); @@ -399,10 +408,14 @@ int add_acls_for_user(int fd, uid_t uid) { return -errno; } - /* We do not recalculate the mask unconditionally here, so that the fchmod() mask above stays - * intact. */ - if (acl_get_permset(entry, &permset) < 0 || - acl_add_perm(permset, ACL_READ) < 0) + if (acl_get_permset(entry, &permset) < 0) + return -errno; + + if (rd && acl_add_perm(permset, ACL_READ) < 0) + return -errno; + if (wr && acl_add_perm(permset, ACL_WRITE) < 0) + return -errno; + if (ex && acl_add_perm(permset, ACL_EXECUTE) < 0) return -errno; r = calc_acl_mask_if_needed(&acl); diff --git a/src/shared/acl-util.h b/src/shared/acl-util.h index 10b2a3d9f0..ace0fe0955 100644 --- a/src/shared/acl-util.h +++ b/src/shared/acl-util.h @@ -15,7 +15,7 @@ int add_base_acls_if_needed(acl_t *acl_p, const char *path); int acl_search_groups(const char* path, char ***ret_groups); int parse_acl(const 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); -int add_acls_for_user(int fd, uid_t uid); +int fd_add_uid_acl_permission(int fd, uid_t uid, bool rd, bool wr, bool ex); /* acl_free takes multiple argument types. * Multiple cleanup functions are necessary. */ diff --git a/src/test/test-acl-util.c b/src/test/test-acl-util.c index 9f0e594e67..9a3db3c8e3 100644 --- a/src/test/test-acl-util.c +++ b/src/test/test-acl-util.c @@ -41,8 +41,8 @@ static void test_add_acls_for_user(void) { } else uid = getuid(); - r = add_acls_for_user(fd, uid); - log_info_errno(r, "add_acls_for_user(%d, "UID_FMT"): %m", fd, uid); + r = fd_add_uid_acl_permission(fd, uid, true, false, false); + log_info_errno(r, "fd_add_uid_acl_permission(%i, "UID_FMT", true, false, false): %m", fd, uid); assert_se(r >= 0); cmd = strjoina("ls -l ", fn); @@ -53,7 +53,7 @@ static void test_add_acls_for_user(void) { /* set the acls again */ - r = add_acls_for_user(fd, uid); + r = fd_add_uid_acl_permission(fd, uid, true, false, false); assert_se(r >= 0); cmd = strjoina("ls -l ", fn);