chiark / gitweb /
Prep v224: Major cleanup of unneeded functions and some source files.
[elogind.git] / src / basic / smack-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 2013 Intel Corporation
7
8   Author: Auke Kok <auke-jan.h.kok@intel.com>
9
10   systemd is free software; you can redistribute it and/or modify it
11   under the terms of the GNU Lesser General Public License as published by
12   the Free Software Foundation; either version 2.1 of the License, or
13   (at your option) any later version.
14
15   systemd is distributed in the hope that it will be useful, but
16   WITHOUT ANY WARRANTY; without even the implied warranty of
17   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18   Lesser General Public License for more details.
19
20   You should have received a copy of the GNU Lesser General Public License
21   along with systemd; If not, see <http://www.gnu.org/licenses/>.
22 ***/
23
24 #include <sys/xattr.h>
25
26 #include "util.h"
27 #include "process-util.h"
28 #include "path-util.h"
29 #include "fileio.h"
30 #include "smack-util.h"
31
32 #define SMACK_FLOOR_LABEL "_"
33 #define SMACK_STAR_LABEL  "*"
34
35 bool mac_smack_use(void) {
36 #ifdef HAVE_SMACK
37         static int cached_use = -1;
38
39         if (cached_use < 0)
40                 cached_use = access("/sys/fs/smackfs/", F_OK) >= 0;
41
42         return cached_use;
43 #else
44         return false;
45 #endif
46 }
47
48 int mac_smack_apply(const char *path, const char *label) {
49         int r = 0;
50
51         assert(path);
52
53 #ifdef HAVE_SMACK
54         if (!mac_smack_use())
55                 return 0;
56
57         if (label)
58                 r = lsetxattr(path, "security.SMACK64", label, strlen(label), 0);
59         else
60                 r = lremovexattr(path, "security.SMACK64");
61         if (r < 0)
62                 return -errno;
63 #endif
64
65         return r;
66 }
67
68 /// UNNEEDED by elogind
69 #if 0
70 int mac_smack_apply_fd(int fd, const char *label) {
71         int r = 0;
72
73         assert(fd >= 0);
74
75 #ifdef HAVE_SMACK
76         if (!mac_smack_use())
77                 return 0;
78
79         if (label)
80                 r = fsetxattr(fd, "security.SMACK64", label, strlen(label), 0);
81         else
82                 r = fremovexattr(fd, "security.SMACK64");
83         if (r < 0)
84                 return -errno;
85 #endif
86
87         return r;
88 }
89
90 int mac_smack_apply_ip_out_fd(int fd, const char *label) {
91         int r = 0;
92
93         assert(fd >= 0);
94
95 #ifdef HAVE_SMACK
96         if (!mac_smack_use())
97                 return 0;
98
99         if (label)
100                 r = fsetxattr(fd, "security.SMACK64IPOUT", label, strlen(label), 0);
101         else
102                 r = fremovexattr(fd, "security.SMACK64IPOUT");
103         if (r < 0)
104                 return -errno;
105 #endif
106
107         return r;
108 }
109
110 int mac_smack_apply_ip_in_fd(int fd, const char *label) {
111         int r = 0;
112
113         assert(fd >= 0);
114
115 #ifdef HAVE_SMACK
116         if (!mac_smack_use())
117                 return 0;
118
119         if (label)
120                 r = fsetxattr(fd, "security.SMACK64IPIN", label, strlen(label), 0);
121         else
122                 r = fremovexattr(fd, "security.SMACK64IPIN");
123         if (r < 0)
124                 return -errno;
125 #endif
126
127         return r;
128 }
129
130 int mac_smack_apply_pid(pid_t pid, const char *label) {
131
132 #ifdef HAVE_SMACK
133         const char *p;
134 #endif
135         int r = 0;
136
137         assert(label);
138
139 #ifdef HAVE_SMACK
140         if (!mac_smack_use())
141                 return 0;
142
143         p = procfs_file_alloca(pid, "attr/current");
144         r = write_string_file(p, label, 0);
145         if (r < 0)
146                 return r;
147 #endif
148
149         return r;
150 }
151 #endif // 0
152
153 int mac_smack_fix(const char *path, bool ignore_enoent, bool ignore_erofs) {
154
155 #ifdef HAVE_SMACK
156         struct stat st;
157 #endif
158         int r = 0;
159
160         assert(path);
161
162 #ifdef HAVE_SMACK
163         if (!mac_smack_use())
164                 return 0;
165
166         /*
167          * Path must be in /dev and must exist
168          */
169         if (!path_startswith(path, "/dev"))
170                 return 0;
171
172         r = lstat(path, &st);
173         if (r >= 0) {
174                 const char *label;
175
176                 /*
177                  * Label directories and character devices "*".
178                  * Label symlinks "_".
179                  * Don't change anything else.
180                  */
181
182                 if (S_ISDIR(st.st_mode))
183                         label = SMACK_STAR_LABEL;
184                 else if (S_ISLNK(st.st_mode))
185                         label = SMACK_FLOOR_LABEL;
186                 else if (S_ISCHR(st.st_mode))
187                         label = SMACK_STAR_LABEL;
188                 else
189                         return 0;
190
191                 r = lsetxattr(path, "security.SMACK64", label, strlen(label), 0);
192
193                 /* If the FS doesn't support labels, then exit without warning */
194                 if (r < 0 && errno == EOPNOTSUPP)
195                         return 0;
196         }
197
198         if (r < 0) {
199                 /* Ignore ENOENT in some cases */
200                 if (ignore_enoent && errno == ENOENT)
201                         return 0;
202
203                 if (ignore_erofs && errno == EROFS)
204                         return 0;
205
206                 r = log_debug_errno(errno, "Unable to fix SMACK label of %s: %m", path);
207         }
208 #endif
209
210         return r;
211 }