-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
- This file is part of systemd.
-
- Copyright 2011,2013 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
+/* SPDX-License-Identifier: LGPL-2.1+ */
#include <errno.h>
#include <stdbool.h>
#include "acl-util.h"
-#include "util.h"
+#include "alloc-util.h"
+#include "string-util.h"
#include "strv.h"
+#include "user-util.h"
+#include "util.h"
int acl_find_uid(acl_t acl, uid_t uid, acl_entry_t *entry) {
acl_entry_t i;
return 0;
}
-/// UNNEEDED by elogind
-#if 0
+#if 0 /// UNNEEDED by elogind
int calc_acl_mask_if_needed(acl_t *acl_p) {
acl_entry_t i;
int r;
+ bool need = false;
assert(acl_p);
if (tag == ACL_MASK)
return 0;
- if (IN_SET(tag, ACL_USER, ACL_GROUP)) {
- if (acl_calc_mask(acl_p) < 0)
- return -errno;
-
- return 1;
- }
+ if (IN_SET(tag, ACL_USER, ACL_GROUP))
+ need = true;
}
if (r < 0)
return -errno;
- return 0;
+ if (need && acl_calc_mask(acl_p) < 0)
+ return -errno;
+
+ return need;
}
int add_base_acls_if_needed(acl_t *acl_p, const char *path) {
int acl_search_groups(const char *path, char ***ret_groups) {
_cleanup_strv_free_ char **g = NULL;
- _cleanup_(acl_free) acl_t acl = NULL;
+ _cleanup_(acl_freep) acl_t acl = NULL;
bool ret = false;
acl_entry_t entry;
int r;
r = acl_get_entry(acl, ACL_NEXT_ENTRY, &entry);
}
- if (ret_groups) {
- *ret_groups = g;
- g = NULL;
- }
+ if (ret_groups)
+ *ret_groups = TAKE_PTR(g);
return ret;
}
int parse_acl(const 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_free_ char **a = NULL, **d = NULL; /* strings are not freed */
_cleanup_strv_free_ char **split;
char **entry;
int r = -EINVAL;
}
}
- *acl_access = a_acl;
- *acl_default = d_acl;
- a_acl = d_acl = NULL;
+ *acl_access = TAKE_PTR(a_acl);
+ *acl_default = TAKE_PTR(d_acl);
return 0;
}
if (r < 0)
return -errno;
- *acl = old;
- old = NULL;
+ *acl = TAKE_PTR(old);
+
return 0;
}
+
+int add_acls_for_user(int fd, uid_t uid) {
+ _cleanup_(acl_freep) acl_t acl = NULL;
+ acl_entry_t entry;
+ acl_permset_t permset;
+ int r;
+
+ acl = acl_get_fd(fd);
+ if (!acl)
+ return -errno;
+
+ r = acl_find_uid(acl, uid, &entry);
+ if (r <= 0) {
+ if (acl_create_entry(&acl, &entry) < 0 ||
+ acl_set_tag_type(entry, ACL_USER) < 0 ||
+ acl_set_qualifier(entry, &uid) < 0)
+ 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)
+ return -errno;
+
+ r = calc_acl_mask_if_needed(&acl);
+ if (r < 0)
+ return r;
+
+ return acl_set_fd(fd, acl);
+}
#endif // 0