chiark / gitweb /
Modernization
[elogind.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 search_acl_groups(char*** dst, const char* path, bool* belong) {
73         acl_t acl;
74
75         assert(path);
76         assert(belong);
77
78         acl = acl_get_file(path, ACL_TYPE_DEFAULT);
79         if (acl) {
80                 acl_entry_t entry;
81                 int r;
82
83                 r = acl_get_entry(acl, ACL_FIRST_ENTRY, &entry);
84                 while (r > 0) {
85                         acl_tag_t tag;
86                         gid_t *gid;
87                         char *name;
88
89                         r = acl_get_tag_type(entry, &tag);
90                         if (r < 0)
91                                 break;
92
93                         if (tag != ACL_GROUP)
94                                 goto next;
95
96                         gid = acl_get_qualifier(entry);
97                         if (!gid)
98                                 break;
99
100                         if (in_gid(*gid) > 0) {
101                                 *belong = true;
102                                 break;
103                         }
104
105                         name = gid_to_name(*gid);
106                         if (!name) {
107                                 acl_free(acl);
108                                 return log_oom();
109                         }
110
111                         r = strv_push(dst, name);
112                         if (r < 0) {
113                                 free(name);
114                                 acl_free(acl);
115                                 return log_oom();
116                         }
117
118                 next:
119                         r = acl_get_entry(acl, ACL_NEXT_ENTRY, &entry);
120                 }
121
122                 acl_free(acl);
123         }
124
125         return 0;
126 }