]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/shared/acl-util.c
Introduce strv_consume which takes ownership
[thirdparty/systemd.git] / src / shared / acl-util.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4 This file is part of systemd.
5
6 Copyright 2011,2013 Lennart Poettering
7
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.
12
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.
17
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/>.
20 ***/
21
22 #include <assert.h>
23 #include <sys/acl.h>
24 #include <acl/libacl.h>
25 #include <errno.h>
26 #include <stdbool.h>
27
28 #include "acl-util.h"
29 #include "util.h"
30 #include "strv.h"
31
32 int acl_find_uid(acl_t acl, uid_t uid, acl_entry_t *entry) {
33 acl_entry_t i;
34 int found;
35
36 assert(acl);
37 assert(entry);
38
39 for (found = acl_get_entry(acl, ACL_FIRST_ENTRY, &i);
40 found > 0;
41 found = acl_get_entry(acl, ACL_NEXT_ENTRY, &i)) {
42
43 acl_tag_t tag;
44 uid_t *u;
45 bool b;
46
47 if (acl_get_tag_type(i, &tag) < 0)
48 return -errno;
49
50 if (tag != ACL_USER)
51 continue;
52
53 u = acl_get_qualifier(i);
54 if (!u)
55 return -errno;
56
57 b = *u == uid;
58 acl_free(u);
59
60 if (b) {
61 *entry = i;
62 return 1;
63 }
64 }
65
66 if (found < 0)
67 return -errno;
68
69 return 0;
70 }
71
72 int calc_acl_mask_if_needed(acl_t *acl_p) {
73 acl_entry_t i;
74 int found;
75
76 assert(acl_p);
77
78 for (found = acl_get_entry(*acl_p, ACL_FIRST_ENTRY, &i);
79 found > 0;
80 found = acl_get_entry(*acl_p, ACL_NEXT_ENTRY, &i)) {
81
82 acl_tag_t tag;
83
84 if (acl_get_tag_type(i, &tag) < 0)
85 return -errno;
86
87 if (tag == ACL_MASK)
88 return 0;
89 }
90
91 if (found < 0)
92 return -errno;
93
94 if (acl_calc_mask(acl_p) < 0)
95 return -errno;
96
97 return 0;
98 }
99
100 int search_acl_groups(char*** dst, const char* path, bool* belong) {
101 acl_t acl;
102
103 assert(path);
104 assert(belong);
105
106 acl = acl_get_file(path, ACL_TYPE_DEFAULT);
107 if (acl) {
108 acl_entry_t entry;
109 int r;
110
111 r = acl_get_entry(acl, ACL_FIRST_ENTRY, &entry);
112 while (r > 0) {
113 acl_tag_t tag;
114 gid_t *gid;
115 char *name;
116
117 r = acl_get_tag_type(entry, &tag);
118 if (r < 0)
119 break;
120
121 if (tag != ACL_GROUP)
122 goto next;
123
124 gid = acl_get_qualifier(entry);
125 if (!gid)
126 break;
127
128 if (in_gid(*gid) > 0) {
129 *belong = true;
130 break;
131 }
132
133 name = gid_to_name(*gid);
134 if (!name) {
135 acl_free(acl);
136 return log_oom();
137 }
138
139 r = strv_consume(dst, name);
140 if (r < 0) {
141 acl_free(acl);
142 return log_oom();
143 }
144
145 next:
146 r = acl_get_entry(acl, ACL_NEXT_ENTRY, &entry);
147 }
148
149 acl_free(acl);
150 }
151
152 return 0;
153 }