Deleted Added
full compact
ugidfw_vnode.c (170689) ugidfw_vnode.c (171253)
1/*-
1/*-
2 * Copyright (c) 2005 Tom Rhodes
3 * Copyright (c) 1999-2002, 2007 Robert N. M. Watson
4 * Copyright (c) 2001-2005 Networks Associates Technology, Inc.
2 * Copyright (c) 1999-2002, 2007 Robert N. M. Watson
3 * Copyright (c) 2001-2005 Networks Associates Technology, Inc.
4 * Copyright (c) 2005 Tom Rhodes
5 * All rights reserved.
6 *
7 * This software was developed by Robert Watson for the TrustedBSD Project.
8 * It was later enhanced by Tom Rhodes for the TrustedBSD Project.
9 *
10 * This software was developed for the FreeBSD Project in part by Network
11 * Associates Laboratories, the Security Research Division of Network
12 * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"),

--- 15 unchanged lines hidden (view full) ---

28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 *
5 * All rights reserved.
6 *
7 * This software was developed by Robert Watson for the TrustedBSD Project.
8 * It was later enhanced by Tom Rhodes for the TrustedBSD Project.
9 *
10 * This software was developed for the FreeBSD Project in part by Network
11 * Associates Laboratories, the Security Research Division of Network
12 * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"),

--- 15 unchanged lines hidden (view full) ---

28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 *
36 * $FreeBSD: head/sys/security/mac_bsdextended/mac_bsdextended.c 170689 2007-06-13 22:42:43Z rwatson $
36 * $FreeBSD: head/sys/security/mac_bsdextended/mac_bsdextended.c 171253 2007-07-05 13:16:04Z rwatson $
37 */
38
39/*
40 * Developed by the TrustedBSD Project.
37 */
38
39/*
40 * Developed by the TrustedBSD Project.
41 * "BSD Extended" MAC policy, allowing the administrator to impose
42 * mandatory rules regarding users and some system objects.
41 *
42 * "BSD Extended" MAC policy, allowing the administrator to impose mandatory
43 * firewall-like rules regarding users and file system objects.
43 */
44
45#include <sys/param.h>
46#include <sys/acl.h>
47#include <sys/kernel.h>
48#include <sys/jail.h>
49#include <sys/lock.h>
50#include <sys/malloc.h>

--- 32 unchanged lines hidden (view full) ---

83SYSCTL_INT(_security_mac_bsdextended, OID_AUTO, rule_count, CTLFLAG_RD,
84 &rule_count, 0, "Number of defined rules\n");
85SYSCTL_INT(_security_mac_bsdextended, OID_AUTO, rule_slots, CTLFLAG_RD,
86 &rule_slots, 0, "Number of used rule slots\n");
87SYSCTL_INT(_security_mac_bsdextended, OID_AUTO, rule_version, CTLFLAG_RD,
88 &rule_version, 0, "Version number for API\n");
89
90/*
44 */
45
46#include <sys/param.h>
47#include <sys/acl.h>
48#include <sys/kernel.h>
49#include <sys/jail.h>
50#include <sys/lock.h>
51#include <sys/malloc.h>

--- 32 unchanged lines hidden (view full) ---

84SYSCTL_INT(_security_mac_bsdextended, OID_AUTO, rule_count, CTLFLAG_RD,
85 &rule_count, 0, "Number of defined rules\n");
86SYSCTL_INT(_security_mac_bsdextended, OID_AUTO, rule_slots, CTLFLAG_RD,
87 &rule_slots, 0, "Number of used rule slots\n");
88SYSCTL_INT(_security_mac_bsdextended, OID_AUTO, rule_version, CTLFLAG_RD,
89 &rule_version, 0, "Version number for API\n");
90
91/*
91 * This is just used for logging purposes, eventually we would like
92 * to log much more then failed requests.
92 * This is just used for logging purposes, eventually we would like to log
93 * much more then failed requests.
93 */
94static int mac_bsdextended_logging;
95SYSCTL_INT(_security_mac_bsdextended, OID_AUTO, logging, CTLFLAG_RW,
96 &mac_bsdextended_logging, 0, "Log failed authorization requests");
97
98/*
94 */
95static int mac_bsdextended_logging;
96SYSCTL_INT(_security_mac_bsdextended, OID_AUTO, logging, CTLFLAG_RW,
97 &mac_bsdextended_logging, 0, "Log failed authorization requests");
98
99/*
99 * This tunable is here for compatibility. It will allow the user
100 * to switch between the new mode (first rule matches) and the old
101 * functionality (all rules match).
100 * This tunable is here for compatibility. It will allow the user to switch
101 * between the new mode (first rule matches) and the old functionality (all
102 * rules match).
102 */
103static int
104mac_bsdextended_firstmatch_enabled;
105SYSCTL_INT(_security_mac_bsdextended, OID_AUTO, firstmatch_enabled,
103 */
104static int
105mac_bsdextended_firstmatch_enabled;
106SYSCTL_INT(_security_mac_bsdextended, OID_AUTO, firstmatch_enabled,
106 CTLFLAG_RW, &mac_bsdextended_firstmatch_enabled, 1,
107 "Disable/enable match first rule functionality");
107 CTLFLAG_RW, &mac_bsdextended_firstmatch_enabled, 1,
108 "Disable/enable match first rule functionality");
108
109static int
110mac_bsdextended_rule_valid(struct mac_bsdextended_rule *rule)
111{
112
113 if ((rule->mbr_subject.mbs_flags | MBS_ALL_FLAGS) != MBS_ALL_FLAGS)
114 return (EINVAL);
109
110static int
111mac_bsdextended_rule_valid(struct mac_bsdextended_rule *rule)
112{
113
114 if ((rule->mbr_subject.mbs_flags | MBS_ALL_FLAGS) != MBS_ALL_FLAGS)
115 return (EINVAL);
115
116 if ((rule->mbr_subject.mbs_neg | MBS_ALL_FLAGS) != MBS_ALL_FLAGS)
117 return (EINVAL);
116 if ((rule->mbr_subject.mbs_neg | MBS_ALL_FLAGS) != MBS_ALL_FLAGS)
117 return (EINVAL);
118
119 if ((rule->mbr_object.mbo_flags | MBO_ALL_FLAGS) != MBO_ALL_FLAGS)
120 return (EINVAL);
118 if ((rule->mbr_object.mbo_flags | MBO_ALL_FLAGS) != MBO_ALL_FLAGS)
119 return (EINVAL);
121
122 if ((rule->mbr_object.mbo_neg | MBO_ALL_FLAGS) != MBO_ALL_FLAGS)
123 return (EINVAL);
120 if ((rule->mbr_object.mbo_neg | MBO_ALL_FLAGS) != MBO_ALL_FLAGS)
121 return (EINVAL);
124
125 if ((rule->mbr_object.mbo_neg | MBO_TYPE_DEFINED) &&
126 (rule->mbr_object.mbo_type | MBO_ALL_TYPE) != MBO_ALL_TYPE)
127 return (EINVAL);
122 if ((rule->mbr_object.mbo_neg | MBO_TYPE_DEFINED) &&
123 (rule->mbr_object.mbo_type | MBO_ALL_TYPE) != MBO_ALL_TYPE)
124 return (EINVAL);
128
129 if ((rule->mbr_mode | MBI_ALLPERM) != MBI_ALLPERM)
130 return (EINVAL);
125 if ((rule->mbr_mode | MBI_ALLPERM) != MBI_ALLPERM)
126 return (EINVAL);
131
132 return (0);
133}
134
135static int
136sysctl_rule(SYSCTL_HANDLER_ARGS)
137{
138 struct mac_bsdextended_rule temprule, *ruleptr;
139 u_int namelen;
140 int error, index, *name;
141
142 error = 0;
143 name = (int *)arg1;
144 namelen = arg2;
127 return (0);
128}
129
130static int
131sysctl_rule(SYSCTL_HANDLER_ARGS)
132{
133 struct mac_bsdextended_rule temprule, *ruleptr;
134 u_int namelen;
135 int error, index, *name;
136
137 error = 0;
138 name = (int *)arg1;
139 namelen = arg2;
145
146 /* printf("bsdextended sysctl handler (namelen %d)\n", namelen); */
147
148 if (namelen != 1)
149 return (EINVAL);
140 if (namelen != 1)
141 return (EINVAL);
150
151 index = name[0];
152 if (index >= MAC_BSDEXTENDED_MAXRULES)
153 return (ENOENT);
154
155 ruleptr = NULL;
156 if (req->newptr && req->newlen != 0) {
157 error = SYSCTL_IN(req, &temprule, sizeof(temprule));
158 if (error)
159 return (error);
160 MALLOC(ruleptr, struct mac_bsdextended_rule *,
161 sizeof(*ruleptr), M_MACBSDEXTENDED, M_WAITOK | M_ZERO);
162 }
163
164 mtx_lock(&mac_bsdextended_mtx);
142 index = name[0];
143 if (index >= MAC_BSDEXTENDED_MAXRULES)
144 return (ENOENT);
145
146 ruleptr = NULL;
147 if (req->newptr && req->newlen != 0) {
148 error = SYSCTL_IN(req, &temprule, sizeof(temprule));
149 if (error)
150 return (error);
151 MALLOC(ruleptr, struct mac_bsdextended_rule *,
152 sizeof(*ruleptr), M_MACBSDEXTENDED, M_WAITOK | M_ZERO);
153 }
154
155 mtx_lock(&mac_bsdextended_mtx);
165
166 if (req->oldptr) {
167 if (index < 0 || index > rule_slots + 1) {
168 error = ENOENT;
169 goto out;
170 }
171 if (rules[index] == NULL) {
172 error = ENOENT;
173 goto out;
174 }
175 temprule = *rules[index];
176 }
156 if (req->oldptr) {
157 if (index < 0 || index > rule_slots + 1) {
158 error = ENOENT;
159 goto out;
160 }
161 if (rules[index] == NULL) {
162 error = ENOENT;
163 goto out;
164 }
165 temprule = *rules[index];
166 }
177
178 if (req->newptr && req->newlen == 0) {
167 if (req->newptr && req->newlen == 0) {
179 /* printf("deletion\n"); */
180 KASSERT(ruleptr == NULL, ("sysctl_rule: ruleptr != NULL"));
181 ruleptr = rules[index];
182 if (ruleptr == NULL) {
183 error = ENOENT;
184 goto out;
185 }
186 rule_count--;
187 rules[index] = NULL;
188 } else if (req->newptr) {
189 error = mac_bsdextended_rule_valid(&temprule);
190 if (error)
191 goto out;
168 KASSERT(ruleptr == NULL, ("sysctl_rule: ruleptr != NULL"));
169 ruleptr = rules[index];
170 if (ruleptr == NULL) {
171 error = ENOENT;
172 goto out;
173 }
174 rule_count--;
175 rules[index] = NULL;
176 } else if (req->newptr) {
177 error = mac_bsdextended_rule_valid(&temprule);
178 if (error)
179 goto out;
192
193 if (rules[index] == NULL) {
180 if (rules[index] == NULL) {
194 /* printf("addition\n"); */
195 *ruleptr = temprule;
196 rules[index] = ruleptr;
197 ruleptr = NULL;
198 if (index + 1 > rule_slots)
199 rule_slots = index + 1;
200 rule_count++;
181 *ruleptr = temprule;
182 rules[index] = ruleptr;
183 ruleptr = NULL;
184 if (index + 1 > rule_slots)
185 rule_slots = index + 1;
186 rule_count++;
201 } else {
202 /* printf("replacement\n"); */
187 } else
203 *rules[index] = temprule;
188 *rules[index] = temprule;
204 }
205 }
189 }
206
207out:
208 mtx_unlock(&mac_bsdextended_mtx);
209 if (ruleptr != NULL)
210 FREE(ruleptr, M_MACBSDEXTENDED);
211 if (req->oldptr && error == 0)
212 error = SYSCTL_OUT(req, &temprule, sizeof(temprule));
190out:
191 mtx_unlock(&mac_bsdextended_mtx);
192 if (ruleptr != NULL)
193 FREE(ruleptr, M_MACBSDEXTENDED);
194 if (req->oldptr && error == 0)
195 error = SYSCTL_OUT(req, &temprule, sizeof(temprule));
213
214 return (error);
215}
216
196 return (error);
197}
198
217SYSCTL_NODE(_security_mac_bsdextended, OID_AUTO, rules,
218 CTLFLAG_RW, sysctl_rule, "BSD extended MAC rules");
199SYSCTL_NODE(_security_mac_bsdextended, OID_AUTO, rules, CTLFLAG_RW,
200 sysctl_rule, "BSD extended MAC rules");
219
220static void
221mac_bsdextended_init(struct mac_policy_conf *mpc)
222{
223
201
202static void
203mac_bsdextended_init(struct mac_policy_conf *mpc)
204{
205
224 /* Initialize ruleset lock. */
225 mtx_init(&mac_bsdextended_mtx, "mac_bsdextended lock", NULL, MTX_DEF);
206 mtx_init(&mac_bsdextended_mtx, "mac_bsdextended lock", NULL, MTX_DEF);
226
227 /* Register dynamic sysctl's for rules. */
228}
229
230static void
231mac_bsdextended_destroy(struct mac_policy_conf *mpc)
232{
233
207}
208
209static void
210mac_bsdextended_destroy(struct mac_policy_conf *mpc)
211{
212
234 /* Destroy ruleset lock. */
235 mtx_destroy(&mac_bsdextended_mtx);
213 mtx_destroy(&mac_bsdextended_mtx);
236
237 /* Tear down sysctls. */
238}
239
240static int
241mac_bsdextended_rulecheck(struct mac_bsdextended_rule *rule,
242 struct ucred *cred, struct vnode *vp, struct vattr *vap, int acc_mode)
243{
244 int match;
245 int i;

--- 4 unchanged lines hidden (view full) ---

250 mtx_assert(&mac_bsdextended_mtx, MA_OWNED);
251 if (rule->mbr_subject.mbs_flags & MBS_UID_DEFINED) {
252 match = ((cred->cr_uid <= rule->mbr_subject.mbs_uid_max &&
253 cred->cr_uid >= rule->mbr_subject.mbs_uid_min) ||
254 (cred->cr_ruid <= rule->mbr_subject.mbs_uid_max &&
255 cred->cr_ruid >= rule->mbr_subject.mbs_uid_min) ||
256 (cred->cr_svuid <= rule->mbr_subject.mbs_uid_max &&
257 cred->cr_svuid >= rule->mbr_subject.mbs_uid_min));
214}
215
216static int
217mac_bsdextended_rulecheck(struct mac_bsdextended_rule *rule,
218 struct ucred *cred, struct vnode *vp, struct vattr *vap, int acc_mode)
219{
220 int match;
221 int i;

--- 4 unchanged lines hidden (view full) ---

226 mtx_assert(&mac_bsdextended_mtx, MA_OWNED);
227 if (rule->mbr_subject.mbs_flags & MBS_UID_DEFINED) {
228 match = ((cred->cr_uid <= rule->mbr_subject.mbs_uid_max &&
229 cred->cr_uid >= rule->mbr_subject.mbs_uid_min) ||
230 (cred->cr_ruid <= rule->mbr_subject.mbs_uid_max &&
231 cred->cr_ruid >= rule->mbr_subject.mbs_uid_min) ||
232 (cred->cr_svuid <= rule->mbr_subject.mbs_uid_max &&
233 cred->cr_svuid >= rule->mbr_subject.mbs_uid_min));
258
259 if (rule->mbr_subject.mbs_neg & MBS_UID_DEFINED)
260 match = !match;
234 if (rule->mbr_subject.mbs_neg & MBS_UID_DEFINED)
235 match = !match;
261
262 if (!match)
263 return (0);
264 }
265
266 if (rule->mbr_subject.mbs_flags & MBS_GID_DEFINED) {
267 match = ((cred->cr_rgid <= rule->mbr_subject.mbs_gid_max &&
268 cred->cr_rgid >= rule->mbr_subject.mbs_gid_min) ||
269 (cred->cr_svgid <= rule->mbr_subject.mbs_gid_max &&
270 cred->cr_svgid >= rule->mbr_subject.mbs_gid_min));
236 if (!match)
237 return (0);
238 }
239
240 if (rule->mbr_subject.mbs_flags & MBS_GID_DEFINED) {
241 match = ((cred->cr_rgid <= rule->mbr_subject.mbs_gid_max &&
242 cred->cr_rgid >= rule->mbr_subject.mbs_gid_min) ||
243 (cred->cr_svgid <= rule->mbr_subject.mbs_gid_max &&
244 cred->cr_svgid >= rule->mbr_subject.mbs_gid_min));
271
272 if (!match) {
245 if (!match) {
273 for (i = 0; i < cred->cr_ngroups; i++)
246 for (i = 0; i < cred->cr_ngroups; i++) {
274 if (cred->cr_groups[i]
275 <= rule->mbr_subject.mbs_gid_max &&
276 cred->cr_groups[i]
277 >= rule->mbr_subject.mbs_gid_min) {
278 match = 1;
279 break;
280 }
247 if (cred->cr_groups[i]
248 <= rule->mbr_subject.mbs_gid_max &&
249 cred->cr_groups[i]
250 >= rule->mbr_subject.mbs_gid_min) {
251 match = 1;
252 break;
253 }
254 }
281 }
255 }
282
283 if (rule->mbr_subject.mbs_neg & MBS_GID_DEFINED)
284 match = !match;
256 if (rule->mbr_subject.mbs_neg & MBS_GID_DEFINED)
257 match = !match;
285
286 if (!match)
287 return (0);
288 }
289
290 if (rule->mbr_subject.mbs_flags & MBS_PRISON_DEFINED) {
291 match = (cred->cr_prison != NULL &&
292 cred->cr_prison->pr_id == rule->mbr_subject.mbs_prison);
258 if (!match)
259 return (0);
260 }
261
262 if (rule->mbr_subject.mbs_flags & MBS_PRISON_DEFINED) {
263 match = (cred->cr_prison != NULL &&
264 cred->cr_prison->pr_id == rule->mbr_subject.mbs_prison);
293
294 if (rule->mbr_subject.mbs_neg & MBS_PRISON_DEFINED)
295 match = !match;
265 if (rule->mbr_subject.mbs_neg & MBS_PRISON_DEFINED)
266 match = !match;
296
297 if (!match)
298 return (0);
299 }
300
301 /*
302 * Is there an object match?
303 */
304 if (rule->mbr_object.mbo_flags & MBO_UID_DEFINED) {
305 match = (vap->va_uid <= rule->mbr_object.mbo_uid_max &&
306 vap->va_uid >= rule->mbr_object.mbo_uid_min);
267 if (!match)
268 return (0);
269 }
270
271 /*
272 * Is there an object match?
273 */
274 if (rule->mbr_object.mbo_flags & MBO_UID_DEFINED) {
275 match = (vap->va_uid <= rule->mbr_object.mbo_uid_max &&
276 vap->va_uid >= rule->mbr_object.mbo_uid_min);
307
308 if (rule->mbr_object.mbo_neg & MBO_UID_DEFINED)
309 match = !match;
277 if (rule->mbr_object.mbo_neg & MBO_UID_DEFINED)
278 match = !match;
310
311 if (!match)
312 return (0);
313 }
314
315 if (rule->mbr_object.mbo_flags & MBO_GID_DEFINED) {
316 match = (vap->va_gid <= rule->mbr_object.mbo_gid_max &&
317 vap->va_gid >= rule->mbr_object.mbo_gid_min);
279 if (!match)
280 return (0);
281 }
282
283 if (rule->mbr_object.mbo_flags & MBO_GID_DEFINED) {
284 match = (vap->va_gid <= rule->mbr_object.mbo_gid_max &&
285 vap->va_gid >= rule->mbr_object.mbo_gid_min);
318
319 if (rule->mbr_object.mbo_neg & MBO_GID_DEFINED)
320 match = !match;
286 if (rule->mbr_object.mbo_neg & MBO_GID_DEFINED)
287 match = !match;
321
322 if (!match)
323 return (0);
324 }
325
326 if (rule->mbr_object.mbo_flags & MBO_FSID_DEFINED) {
327 match = (bcmp(&(vp->v_mount->mnt_stat.f_fsid),
328 &(rule->mbr_object.mbo_fsid),
329 sizeof(rule->mbr_object.mbo_fsid)) == 0);
288 if (!match)
289 return (0);
290 }
291
292 if (rule->mbr_object.mbo_flags & MBO_FSID_DEFINED) {
293 match = (bcmp(&(vp->v_mount->mnt_stat.f_fsid),
294 &(rule->mbr_object.mbo_fsid),
295 sizeof(rule->mbr_object.mbo_fsid)) == 0);
330
331 if (rule->mbr_object.mbo_neg & MBO_FSID_DEFINED)
332 match = !match;
296 if (rule->mbr_object.mbo_neg & MBO_FSID_DEFINED)
297 match = !match;
333
334 if (!match)
298 if (!match)
335 return 0;
299 return (0);
336 }
337
338 if (rule->mbr_object.mbo_flags & MBO_SUID) {
339 match = (vap->va_mode & VSUID);
300 }
301
302 if (rule->mbr_object.mbo_flags & MBO_SUID) {
303 match = (vap->va_mode & VSUID);
340
341 if (rule->mbr_object.mbo_neg & MBO_SUID)
342 match = !match;
304 if (rule->mbr_object.mbo_neg & MBO_SUID)
305 match = !match;
343
344 if (!match)
306 if (!match)
345 return 0;
307 return (0);
346 }
347
348 if (rule->mbr_object.mbo_flags & MBO_SGID) {
349 match = (vap->va_mode & VSGID);
308 }
309
310 if (rule->mbr_object.mbo_flags & MBO_SGID) {
311 match = (vap->va_mode & VSGID);
350
351 if (rule->mbr_object.mbo_neg & MBO_SGID)
352 match = !match;
312 if (rule->mbr_object.mbo_neg & MBO_SGID)
313 match = !match;
353
354 if (!match)
314 if (!match)
355 return 0;
315 return (0);
356 }
357
358 if (rule->mbr_object.mbo_flags & MBO_UID_SUBJECT) {
359 match = (vap->va_uid == cred->cr_uid ||
360 vap->va_uid == cred->cr_ruid ||
361 vap->va_uid == cred->cr_svuid);
316 }
317
318 if (rule->mbr_object.mbo_flags & MBO_UID_SUBJECT) {
319 match = (vap->va_uid == cred->cr_uid ||
320 vap->va_uid == cred->cr_ruid ||
321 vap->va_uid == cred->cr_svuid);
362
363 if (rule->mbr_object.mbo_neg & MBO_UID_SUBJECT)
364 match = !match;
322 if (rule->mbr_object.mbo_neg & MBO_UID_SUBJECT)
323 match = !match;
365
366 if (!match)
324 if (!match)
367 return 0;
325 return (0);
368 }
369
370 if (rule->mbr_object.mbo_flags & MBO_GID_SUBJECT) {
371 match = (groupmember(vap->va_gid, cred) ||
372 vap->va_gid == cred->cr_rgid ||
373 vap->va_gid == cred->cr_svgid);
326 }
327
328 if (rule->mbr_object.mbo_flags & MBO_GID_SUBJECT) {
329 match = (groupmember(vap->va_gid, cred) ||
330 vap->va_gid == cred->cr_rgid ||
331 vap->va_gid == cred->cr_svgid);
374
375 if (rule->mbr_object.mbo_neg & MBO_GID_SUBJECT)
376 match = !match;
332 if (rule->mbr_object.mbo_neg & MBO_GID_SUBJECT)
333 match = !match;
377
378 if (!match)
334 if (!match)
379 return 0;
335 return (0);
380 }
381
382 if (rule->mbr_object.mbo_flags & MBO_TYPE_DEFINED) {
383 switch (vap->va_type) {
384 case VREG:
385 match = (rule->mbr_object.mbo_type & MBO_TYPE_REG);
386 break;
387 case VDIR:

--- 12 unchanged lines hidden (view full) ---

400 match = (rule->mbr_object.mbo_type & MBO_TYPE_SOCK);
401 break;
402 case VFIFO:
403 match = (rule->mbr_object.mbo_type & MBO_TYPE_FIFO);
404 break;
405 default:
406 match = 0;
407 }
336 }
337
338 if (rule->mbr_object.mbo_flags & MBO_TYPE_DEFINED) {
339 switch (vap->va_type) {
340 case VREG:
341 match = (rule->mbr_object.mbo_type & MBO_TYPE_REG);
342 break;
343 case VDIR:

--- 12 unchanged lines hidden (view full) ---

356 match = (rule->mbr_object.mbo_type & MBO_TYPE_SOCK);
357 break;
358 case VFIFO:
359 match = (rule->mbr_object.mbo_type & MBO_TYPE_FIFO);
360 break;
361 default:
362 match = 0;
363 }
408
409 if (rule->mbr_object.mbo_neg & MBO_TYPE_DEFINED)
410 match = !match;
364 if (rule->mbr_object.mbo_neg & MBO_TYPE_DEFINED)
365 match = !match;
411
412 if (!match)
366 if (!match)
413 return 0;
367 return (0);
414 }
415
416 /*
417 * Is the access permitted?
418 */
419 if ((rule->mbr_mode & acc_mode) != acc_mode) {
420 if (mac_bsdextended_logging)
421 log(LOG_AUTHPRIV, "mac_bsdextended: %d:%d request %d"
422 " on %d:%d failed. \n", cred->cr_ruid,
368 }
369
370 /*
371 * Is the access permitted?
372 */
373 if ((rule->mbr_mode & acc_mode) != acc_mode) {
374 if (mac_bsdextended_logging)
375 log(LOG_AUTHPRIV, "mac_bsdextended: %d:%d request %d"
376 " on %d:%d failed. \n", cred->cr_ruid,
423 cred->cr_rgid, acc_mode, vap->va_uid, vap->va_gid);
424 return (EACCES); /* Matching rule denies access */
377 cred->cr_rgid, acc_mode, vap->va_uid,
378 vap->va_gid);
379 return (EACCES);
425 }
426
427 /*
428 * If the rule matched, permits access, and first match is enabled,
429 * return success.
430 */
431 if (mac_bsdextended_firstmatch_enabled)
432 return (EJUSTRETURN);
433 else
380 }
381
382 /*
383 * If the rule matched, permits access, and first match is enabled,
384 * return success.
385 */
386 if (mac_bsdextended_firstmatch_enabled)
387 return (EJUSTRETURN);
388 else
434 return(0);
389 return (0);
435}
436
437static int
438mac_bsdextended_check(struct ucred *cred, struct vnode *vp, struct vattr *vap,
439 int acc_mode)
440{
441 int error, i;
442
443 /*
390}
391
392static int
393mac_bsdextended_check(struct ucred *cred, struct vnode *vp, struct vattr *vap,
394 int acc_mode)
395{
396 int error, i;
397
398 /*
444 * XXXRW: More specific privilege selection needed?
399 * XXXRW: More specific privilege selection needed.
445 */
446 if (suser_cred(cred, 0) == 0)
447 return (0);
448
449 /*
450 * Since we do not separately handle append, map append to write.
451 */
452 if (acc_mode & MBI_APPEND) {
453 acc_mode &= ~MBI_APPEND;
454 acc_mode |= MBI_WRITE;
455 }
400 */
401 if (suser_cred(cred, 0) == 0)
402 return (0);
403
404 /*
405 * Since we do not separately handle append, map append to write.
406 */
407 if (acc_mode & MBI_APPEND) {
408 acc_mode &= ~MBI_APPEND;
409 acc_mode |= MBI_WRITE;
410 }
456
457 mtx_lock(&mac_bsdextended_mtx);
458 for (i = 0; i < rule_slots; i++) {
459 if (rules[i] == NULL)
460 continue;
411 mtx_lock(&mac_bsdextended_mtx);
412 for (i = 0; i < rule_slots; i++) {
413 if (rules[i] == NULL)
414 continue;
461
462 error = mac_bsdextended_rulecheck(rules[i], cred,
463 vp, vap, acc_mode);
464 if (error == EJUSTRETURN)
465 break;
466 if (error) {
467 mtx_unlock(&mac_bsdextended_mtx);
468 return (error);
469 }

--- 5 unchanged lines hidden (view full) ---

475static int
476mac_bsdextended_check_vp(struct ucred *cred, struct vnode *vp, int acc_mode)
477{
478 int error;
479 struct vattr vap;
480
481 if (!mac_bsdextended_enabled)
482 return (0);
415 error = mac_bsdextended_rulecheck(rules[i], cred,
416 vp, vap, acc_mode);
417 if (error == EJUSTRETURN)
418 break;
419 if (error) {
420 mtx_unlock(&mac_bsdextended_mtx);
421 return (error);
422 }

--- 5 unchanged lines hidden (view full) ---

428static int
429mac_bsdextended_check_vp(struct ucred *cred, struct vnode *vp, int acc_mode)
430{
431 int error;
432 struct vattr vap;
433
434 if (!mac_bsdextended_enabled)
435 return (0);
483
484 error = VOP_GETATTR(vp, &vap, cred, curthread);
485 if (error)
486 return (error);
436 error = VOP_GETATTR(vp, &vap, cred, curthread);
437 if (error)
438 return (error);
487
488 return (mac_bsdextended_check(cred, vp, &vap, acc_mode));
489}
490
491static int
492mac_bsdextended_check_system_acct(struct ucred *cred, struct vnode *vp,
493 struct label *vplabel)
494{
495

--- 61 unchanged lines hidden (view full) ---

557 struct label *dvplabel, struct vnode *vp, struct label *vplabel,
558 struct componentname *cnp)
559{
560 int error;
561
562 error = mac_bsdextended_check_vp(cred, dvp, MBI_WRITE);
563 if (error)
564 return (error);
439 return (mac_bsdextended_check(cred, vp, &vap, acc_mode));
440}
441
442static int
443mac_bsdextended_check_system_acct(struct ucred *cred, struct vnode *vp,
444 struct label *vplabel)
445{
446

--- 61 unchanged lines hidden (view full) ---

508 struct label *dvplabel, struct vnode *vp, struct label *vplabel,
509 struct componentname *cnp)
510{
511 int error;
512
513 error = mac_bsdextended_check_vp(cred, dvp, MBI_WRITE);
514 if (error)
515 return (error);
565
566 return (mac_bsdextended_check_vp(cred, vp, MBI_WRITE));
567}
568
569static int
570mac_bsdextended_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp,
571 struct label *vplabel, acl_type_t type)
572{
573

--- 40 unchanged lines hidden (view full) ---

614 struct label *dvplabel, struct vnode *vp, struct label *label,
615 struct componentname *cnp)
616{
617 int error;
618
619 error = mac_bsdextended_check_vp(cred, dvp, MBI_WRITE);
620 if (error)
621 return (error);
516 return (mac_bsdextended_check_vp(cred, vp, MBI_WRITE));
517}
518
519static int
520mac_bsdextended_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp,
521 struct label *vplabel, acl_type_t type)
522{
523

--- 40 unchanged lines hidden (view full) ---

564 struct label *dvplabel, struct vnode *vp, struct label *label,
565 struct componentname *cnp)
566{
567 int error;
568
569 error = mac_bsdextended_check_vp(cred, dvp, MBI_WRITE);
570 if (error)
571 return (error);
622
623 error = mac_bsdextended_check_vp(cred, vp, MBI_WRITE);
624 if (error)
625 return (error);
626 return (0);
627}
628
629static int
630mac_bsdextended_check_vnode_listextattr(struct ucred *cred, struct vnode *vp,

--- 40 unchanged lines hidden (view full) ---

671 struct label *dvplabel, struct vnode *vp, struct label *vplabel,
672 struct componentname *cnp)
673{
674 int error;
675
676 error = mac_bsdextended_check_vp(cred, dvp, MBI_WRITE);
677 if (error)
678 return (error);
572 error = mac_bsdextended_check_vp(cred, vp, MBI_WRITE);
573 if (error)
574 return (error);
575 return (0);
576}
577
578static int
579mac_bsdextended_check_vnode_listextattr(struct ucred *cred, struct vnode *vp,

--- 40 unchanged lines hidden (view full) ---

620 struct label *dvplabel, struct vnode *vp, struct label *vplabel,
621 struct componentname *cnp)
622{
623 int error;
624
625 error = mac_bsdextended_check_vp(cred, dvp, MBI_WRITE);
626 if (error)
627 return (error);
679 error = mac_bsdextended_check_vp(cred, vp, MBI_WRITE);
680
681 return (error);
628 return (mac_bsdextended_check_vp(cred, vp, MBI_WRITE));
682}
683
684static int
685mac_bsdextended_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp,
686 struct label *dvplabel, struct vnode *vp, struct label *vplabel,
687 int samedir, struct componentname *cnp)
688{
689 int error;
690
691 error = mac_bsdextended_check_vp(cred, dvp, MBI_WRITE);
692 if (error)
693 return (error);
629}
630
631static int
632mac_bsdextended_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp,
633 struct label *dvplabel, struct vnode *vp, struct label *vplabel,
634 int samedir, struct componentname *cnp)
635{
636 int error;
637
638 error = mac_bsdextended_check_vp(cred, dvp, MBI_WRITE);
639 if (error)
640 return (error);
694
695 if (vp != NULL)
696 error = mac_bsdextended_check_vp(cred, vp, MBI_WRITE);
641 if (vp != NULL)
642 error = mac_bsdextended_check_vp(cred, vp, MBI_WRITE);
697
698 return (error);
699}
700
701static int
702mac_bsdextended_check_vnode_revoke(struct ucred *cred, struct vnode *vp,
703 struct label *vplabel)
704{
705

--- 98 unchanged lines hidden ---
643 return (error);
644}
645
646static int
647mac_bsdextended_check_vnode_revoke(struct ucred *cred, struct vnode *vp,
648 struct label *vplabel)
649{
650

--- 98 unchanged lines hidden ---