chiark / gitweb /
smack: never follow symlinks when relabelling
[elogind.git] / src / shared / 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 "path-util.h"
28 #include "smack-util.h"
29
30 bool mac_smack_use(void) {
31 #ifdef HAVE_SMACK
32         static int cached_use = -1;
33
34         if (cached_use < 0)
35                 cached_use = access("/sys/fs/smackfs/", F_OK) >= 0;
36
37         return cached_use;
38 #else
39         return false;
40 #endif
41 }
42
43 int mac_smack_apply(const char *path, const char *label) {
44         int r = 0;
45
46         assert(path);
47
48 #ifdef HAVE_SMACK
49         if (!mac_smack_use())
50                 return 0;
51
52         if (label)
53                 r = lsetxattr(path, "security.SMACK64", label, strlen(label), 0);
54         else
55                 r = lremovexattr(path, "security.SMACK64");
56         if (r < 0)
57                 return -errno;
58 #endif
59
60         return r;
61 }
62
63 int mac_smack_apply_fd(int fd, const char *label) {
64         int r = 0;
65
66         assert(fd >= 0);
67
68 #ifdef HAVE_SMACK
69         if (!mac_smack_use())
70                 return 0;
71
72         if (label)
73                 r = fsetxattr(fd, "security.SMACK64", label, strlen(label), 0);
74         else
75                 r = fremovexattr(fd, "security.SMACK64");
76         if (r < 0)
77                 return -errno;
78 #endif
79
80         return r;
81 }
82
83 int mac_smack_apply_ip_out_fd(int fd, const char *label) {
84         int r = 0;
85
86         assert(fd >= 0);
87
88 #ifdef HAVE_SMACK
89         if (!mac_smack_use())
90                 return 0;
91
92         if (label)
93                 r = fsetxattr(fd, "security.SMACK64IPOUT", label, strlen(label), 0);
94         else
95                 r = fremovexattr(fd, "security.SMACK64IPOUT");
96         if (r < 0)
97                 return -errno;
98 #endif
99
100         return r;
101 }
102
103 int mac_smack_apply_ip_in_fd(int fd, const char *label) {
104         int r = 0;
105
106         assert(fd >= 0);
107
108 #ifdef HAVE_SMACK
109         if (!mac_smack_use())
110                 return 0;
111
112         if (label)
113                 r = fsetxattr(fd, "security.SMACK64IPIN", label, strlen(label), 0);
114         else
115                 r = fremovexattr(fd, "security.SMACK64IPIN");
116         if (r < 0)
117                 return -errno;
118 #endif
119
120         return r;
121 }
122
123 int mac_smack_fix(const char *path) {
124         int r = 0;
125
126 #ifdef HAVE_SMACK
127         struct stat sb;
128         const char *label;
129 #endif
130
131         assert(path);
132
133 #ifdef HAVE_SMACK
134         if (!mac_smack_use())
135                 return 0;
136
137         /*
138          * Path must be in /dev and must exist
139          */
140         if (!path_startswith(path, "/dev"))
141                 return 0;
142
143         r = lstat(path, &sb);
144         if (r < 0)
145                 return -errno;
146
147         /*
148          * Label directories and character devices "*".
149          * Label symlinks "_".
150          * Don't change anything else.
151          */
152         if (S_ISDIR(sb.st_mode))
153                 label = SMACK_STAR_LABEL;
154         else if (S_ISLNK(sb.st_mode))
155                 label = SMACK_FLOOR_LABEL;
156         else if (S_ISCHR(sb.st_mode))
157                 label = SMACK_STAR_LABEL;
158         else
159                 return 0;
160
161         r = setxattr(path, "security.SMACK64", label, strlen(label), 0);
162         if (r < 0) {
163                 log_error("Smack relabeling \"%s\" %m", path);
164                 return -errno;
165         }
166 #endif
167
168         return r;
169 }