Merge changes from current upstream master branch.
[framework/security/smack.git] / utils / common.c
1 /*
2  * This file is part of libsmack.
3  *
4  * Copyright (C) 2011 Intel Corporation
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public License
8  * version 2.1 as published by the Free Software Foundation.
9  *
10  * This library is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18  * 02110-1301 USA
19  *
20  * Authors:
21  * Jarkko Sakkinen <jarkko.sakkinen@intel.com>
22  * Brian McGillion <brian.mcgillion@intel.com>
23  */
24
25 #include "common.h"
26 #include <sys/types.h>
27 #include <sys/stat.h>
28 #include <unistd.h>
29 #include <errno.h>
30 #include <sys/vfs.h>
31 #include <fcntl.h>
32 #include <sys/smack.h>
33 #include <ftw.h>
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <string.h>
37 #include <limits.h>
38
39 #define SMACK_MAGIC 0x43415d53
40
41 static int apply_rules_cb(const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf);
42 static int apply_cipso_cb(const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf);
43
44 int is_smackfs_mounted(void)
45 {
46         struct statfs sfs;
47         int ret;
48         const char * smack_mnt;
49
50         smack_mnt = smack_smackfs_path();
51         if (!smack_mnt) {
52                 errno = EFAULT;
53                 return -1;
54         }
55
56         do {
57                 ret = statfs(smack_mnt, &sfs);
58         } while (ret < 0 && errno == EINTR);
59
60         if (ret)
61                 return -1;
62
63         if (sfs.f_type == SMACK_MAGIC)
64                 return 1;
65
66         return 0;
67 }
68
69 int clear(void)
70 {
71         int fd;
72         int ret;
73         const char * smack_mnt;
74         char path[PATH_MAX];
75
76         smack_mnt = smack_smackfs_path();
77         if (!smack_mnt) {
78                 errno = EFAULT;
79                 return -1;
80         }
81
82         if (is_smackfs_mounted() != 1)
83                 return -1;
84
85         snprintf(path, sizeof path, "%s/load2", smack_mnt);
86         fd = open(path, O_RDONLY);
87         if (fd < 0)
88                 return -1;
89
90         ret = apply_rules_file(fd, 1);
91         close(fd);
92         return ret;
93 }
94
95 int apply_rules(const char *path, int clear)
96 {
97         struct stat sbuf;
98         int fd;
99         int ret;
100
101         errno = 0;
102         if (stat(path, &sbuf))
103                 return -1;
104
105         if (S_ISDIR(sbuf.st_mode))
106                 return nftw(path, apply_rules_cb, 1, FTW_PHYS|FTW_ACTIONRETVAL);
107
108         fd = open(path, O_RDONLY);
109         if (fd < 0)
110                 return -1;
111
112         ret = apply_rules_file(fd, clear);
113         close(fd);
114         return ret;
115 }
116
117 int apply_cipso(const char *path)
118 {
119         struct stat sbuf;
120         int fd;
121         int ret;
122
123         errno = 0;
124         if (stat(path, &sbuf))
125                 return -1;
126
127         if (S_ISDIR(sbuf.st_mode))
128                 return nftw(path, apply_cipso_cb, 1, FTW_PHYS|FTW_ACTIONRETVAL);
129
130         fd = open(path, O_RDONLY);
131         if (fd < 0)
132                 return -1;
133
134         ret = apply_cipso_file(fd);
135         close(fd);
136         return ret;
137 }
138
139 int apply_rules_file(int fd, int clear)
140 {
141         struct smack_accesses *rules = NULL;
142         int ret = 0;
143
144         if (smack_accesses_new(&rules))
145                 return -1;
146
147         if (smack_accesses_add_from_file(rules, fd)) {
148                 smack_accesses_free(rules);
149                 return -1;
150         }
151
152         if (!clear)
153                 ret = smack_accesses_apply(rules);
154         else
155                 ret = smack_accesses_clear(rules);
156
157         smack_accesses_free(rules);
158
159         return ret;
160 }
161
162 int apply_cipso_file(int fd)
163 {
164         struct smack_cipso *cipso = NULL;
165         int ret;
166
167         cipso = smack_cipso_new(fd);
168         if (cipso == NULL)
169                 return -1;
170
171         ret = smack_cipso_apply(cipso);
172         smack_cipso_free(cipso);
173         if (ret)
174                 return -1;
175
176         return 0;
177 }
178
179 static int apply_rules_cb(const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf)
180 {
181         int fd;
182         int ret;
183
184         if (typeflag == FTW_D)
185                 return ftwbuf->level ? FTW_SKIP_SUBTREE : FTW_CONTINUE;
186         else if (typeflag != FTW_F)
187                 return FTW_STOP;
188
189         fd = open(fpath, O_RDONLY);
190         if (fd < 0)
191                 return -1;
192
193         ret = apply_rules_file(fd, 0) ? FTW_STOP : FTW_CONTINUE;
194         close(fd);
195         return ret;
196 }
197
198 static int apply_cipso_cb(const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf)
199 {
200         int fd;
201         int ret;
202
203         if (typeflag == FTW_D)
204                 return ftwbuf->level ? FTW_SKIP_SUBTREE : FTW_CONTINUE;
205         else if (typeflag != FTW_F)
206                 return FTW_STOP;
207
208         fd = open(fpath, O_RDONLY);
209         if (fd < 0)
210                 return -1;
211
212         ret = apply_rules_file(fd, 0) ? FTW_STOP : FTW_CONTINUE;
213         close(fd);
214         return ret;
215 }