tizen 2.4 release
[external/systemd.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 <unistd.h>
25 #include <string.h>
26 #include <sys/xattr.h>
27
28 #include "util.h"
29 #include "smack-util.h"
30
31 bool use_smack(void) {
32 #ifdef HAVE_SMACK
33         static int use_smack_cached = -1;
34
35         if (use_smack_cached < 0)
36                 use_smack_cached = access("/sys/fs/smackfs/", F_OK) >= 0;
37
38         return use_smack_cached;
39 #else
40         return false;
41 #endif
42
43 }
44
45 int smack_label_path(const char *path, const char *label) {
46 #ifdef HAVE_SMACK
47         if (!use_smack())
48                 return 0;
49
50         if (label)
51                 return setxattr(path, "security.SMACK64", label, strlen(label), 0);
52         else
53                 return lremovexattr(path, "security.SMACK64");
54 #else
55         return 0;
56 #endif
57 }
58
59 int smack_label_get_path(const char *path, char **label) {
60         int i;
61         int r = 0;
62         char buf[SMACK_LABEL_LEN + 1];
63         char *result = NULL;
64
65         assert(path);
66
67 #ifdef HAVE_SMACK
68         if (!use_smack())
69                 return 0;
70
71         r = lgetxattr(path, "security.SMACK64", buf, SMACK_LABEL_LEN + 1);
72         if (r < 0)
73                 return -errno;
74         else if (buf[0] == '\0' || buf[0] == '-')
75                 return -EINVAL;
76
77         result = calloc(r + 1, 1);
78         if (result == NULL)
79                  return -errno;
80
81         for (i = 0; i < (SMACK_LABEL_LEN + 1) && buf[i]; i++) {
82                 if (buf[i] <= ' ' || buf[i] > '~')
83                     return -EINVAL;
84                 switch (buf[i]) {
85                 case '/':
86                 case '"':
87                 case '\\':
88                 case '\'':
89                         return -EINVAL;
90                 default:
91                         break;
92                 }
93
94                 if (result)
95                         result[i] = buf[i];
96         }
97
98         if (result && i < (SMACK_LABEL_LEN + 1))
99                 result[i] = '\0';
100
101         if (i < 0) {
102                 free(result);
103                 return -EINVAL;
104         }
105         *label = result;
106
107         return i;
108 #endif
109
110         return r;
111 }
112
113 int smack_label_fd(int fd, const char *label) {
114 #ifdef HAVE_SMACK
115         if (!use_smack())
116                 return 0;
117
118         return fsetxattr(fd, "security.SMACK64", label, strlen(label), 0);
119 #else
120         return 0;
121 #endif
122 }
123
124 int smack_label_apply_pid(pid_t pid, const char *label) {
125         int r = 0;
126         const char *p;
127
128         assert(label);
129
130 #ifdef HAVE_SMACK
131         if (!use_smack())
132                 return 0;
133
134         p = procfs_file_alloca(pid, "attr/current");
135         r = write_string_file(p, label);
136         if (r < 0)
137                 return r;
138 #endif
139
140         return r;
141 }
142
143 int smack_label_ip_out_fd(int fd, const char *label) {
144 #ifdef HAVE_SMACK
145         if (!use_smack())
146                 return 0;
147
148         return fsetxattr(fd, "security.SMACK64IPOUT", label, strlen(label), 0);
149 #else
150         return 0;
151 #endif
152 }
153
154 int smack_label_ip_in_fd(int fd, const char *label) {
155 #ifdef HAVE_SMACK
156         if (!use_smack())
157                 return 0;
158
159         return fsetxattr(fd, "security.SMACK64IPIN", label, strlen(label), 0);
160 #else
161         return 0;
162 #endif
163 }