1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2011,2013 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
30 int acl_find_uid(acl_t acl, uid_t uid, acl_entry_t *entry) {
37 for (r = acl_get_entry(acl, ACL_FIRST_ENTRY, &i);
39 r = acl_get_entry(acl, ACL_NEXT_ENTRY, &i)) {
45 if (acl_get_tag_type(i, &tag) < 0)
51 u = acl_get_qualifier(i);
69 int calc_acl_mask_if_needed(acl_t *acl_p) {
75 for (r = acl_get_entry(*acl_p, ACL_FIRST_ENTRY, &i);
77 r = acl_get_entry(*acl_p, ACL_NEXT_ENTRY, &i)) {
80 if (acl_get_tag_type(i, &tag) < 0)
85 if (IN_SET(tag, ACL_USER, ACL_GROUP))
93 if (acl_calc_mask(acl_p) < 0)
98 int add_base_acls_if_needed(acl_t *acl_p, const char *path) {
101 bool have_user_obj = false, have_group_obj = false, have_other = false;
103 _cleanup_(acl_freep) acl_t basic = NULL;
107 for (r = acl_get_entry(*acl_p, ACL_FIRST_ENTRY, &i);
109 r = acl_get_entry(*acl_p, ACL_NEXT_ENTRY, &i)) {
112 if (acl_get_tag_type(i, &tag) < 0)
115 if (tag == ACL_USER_OBJ)
116 have_user_obj = true;
117 else if (tag == ACL_GROUP_OBJ)
118 have_group_obj = true;
119 else if (tag == ACL_OTHER)
121 if (have_user_obj && have_group_obj && have_other)
131 basic = acl_from_mode(st.st_mode);
135 for (r = acl_get_entry(basic, ACL_FIRST_ENTRY, &i);
137 r = acl_get_entry(basic, ACL_NEXT_ENTRY, &i)) {
141 if (acl_get_tag_type(i, &tag) < 0)
144 if ((tag == ACL_USER_OBJ && have_user_obj) ||
145 (tag == ACL_GROUP_OBJ && have_group_obj) ||
146 (tag == ACL_OTHER && have_other))
149 r = acl_create_entry(acl_p, &dst);
153 r = acl_copy_entry(dst, i);
162 int search_acl_groups(char*** dst, const char* path, bool* belong) {
168 acl = acl_get_file(path, ACL_TYPE_DEFAULT);
173 r = acl_get_entry(acl, ACL_FIRST_ENTRY, &entry);
179 r = acl_get_tag_type(entry, &tag);
183 if (tag != ACL_GROUP)
186 gid = acl_get_qualifier(entry);
190 if (in_gid(*gid) > 0) {
195 name = gid_to_name(*gid);
201 r = strv_consume(dst, name);
208 r = acl_get_entry(acl, ACL_NEXT_ENTRY, &entry);
217 int parse_acl(char *text, acl_t *acl_access, acl_t *acl_default, bool want_mask) {
218 _cleanup_free_ char **a = NULL, **d = NULL; /* strings are not be freed */
219 _cleanup_strv_free_ char **split;
222 _cleanup_(acl_freep) acl_t a_acl = NULL, d_acl = NULL;
224 split = strv_split(text, ",");
228 STRV_FOREACH(entry, split) {
231 p = startswith(*entry, "default:");
233 p = startswith(*entry, "d:");
236 r = strv_push(&d, p);
238 r = strv_push(&a, *entry);
243 if (!strv_isempty(a)) {
244 _cleanup_free_ char *join;
246 join = strv_join(a, ",");
250 a_acl = acl_from_text(join);
255 r = calc_acl_mask_if_needed(&a_acl);
261 if (!strv_isempty(d)) {
262 _cleanup_free_ char *join;
264 join = strv_join(d, ",");
268 d_acl = acl_from_text(join);
273 r = calc_acl_mask_if_needed(&d_acl);
280 *acl_default = d_acl;
281 a_acl = d_acl = NULL;
285 int acls_for_file(const char *path, acl_type_t type, acl_t new, acl_t *acl) {
286 _cleanup_(acl_freep) acl_t old;
290 old = acl_get_file(path, type);
294 for (r = acl_get_entry(new, ACL_FIRST_ENTRY, &i);
296 r = acl_get_entry(new, ACL_NEXT_ENTRY, &i)) {
300 if (acl_create_entry(&old, &j) < 0)
303 if (acl_copy_entry(j, i) < 0)