1 /* $NetBSD: policy.c,v 1.1 2009/03/26 22:11:45 ad Exp $ */
4 * Copyright (c) 2009 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
33 * Copyright (c) 2007 Pawel Jakub Dawidek <pjd@FreeBSD.org>
34 * All rights reserved.
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
39 * 1. Redistributions of source code must retain the above copyright
40 * notice, this list of conditions and the following disclaimer.
41 * 2. Redistributions in binary form must reproduce the above copyright
42 * notice, this list of conditions and the following disclaimer in the
43 * documentation and/or other materials provided with the distribution.
45 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
46 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
47 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
48 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
49 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
50 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
51 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
52 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
53 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
54 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
58 #include <sys/param.h>
60 #include <sys/vnode.h>
61 #include <sys/mount.h>
63 #include <sys/policy.h>
66 secpolicy_zfs(kauth_cred_t cred
)
69 return kauth_authorize_generic(cred
, KAUTH_GENERIC_ISSUSER
, NULL
);
73 secpolicy_sys_config(kauth_cred_t cred
, int checkonly __unused
)
76 return kauth_authorize_generic(cred
, KAUTH_GENERIC_ISSUSER
, NULL
);
80 secpolicy_zinject(kauth_cred_t cred
)
83 return kauth_authorize_generic(cred
, KAUTH_GENERIC_ISSUSER
, NULL
);
87 secpolicy_fs_mount(kauth_cred_t cred
, vnode_t
*mvp
, struct mount
*vfsp
)
90 return kauth_authorize_system(cred
, KAUTH_SYSTEM_MOUNT
,
91 KAUTH_REQ_SYSTEM_MOUNT_NEW
, vfsp
, NULL
, NULL
);
95 secpolicy_fs_unmount(kauth_cred_t cred
, struct mount
*vfsp
)
98 return kauth_authorize_system(cred
, KAUTH_SYSTEM_MOUNT
,
99 KAUTH_REQ_SYSTEM_MOUNT_UNMOUNT
, vfsp
, NULL
, NULL
);
103 * This check is done in kern_link(), so we could just return 0 here.
106 secpolicy_basic_link(kauth_cred_t cred
)
109 return kauth_authorize_generic(cred
, KAUTH_GENERIC_ISSUSER
, NULL
);
113 secpolicy_vnode_stky_modify(kauth_cred_t cred
)
120 secpolicy_vnode_remove(kauth_cred_t cred
)
123 return kauth_authorize_generic(cred
, KAUTH_GENERIC_ISSUSER
, NULL
);
128 secpolicy_vnode_owner(cred_t
*cred
, uid_t owner
)
132 uid
= crgetuid(cred
);
138 // return kauth_authorize_system(cred, KAUTH_SYSTEM_MOUNT,
139 // KAUTH_REQ_SYSTEM_MOUNT_NEW, vfsp, NULL, NULL);
143 secpolicy_vnode_access(kauth_cred_t cred
, struct vnode
*vp
, uint64_t owner
,
148 vn_lock(vp
, LK_EXCLUSIVE
| LK_RETRY
);
149 error
= VOP_ACCESS(vp
, mode
, cred
);
155 * Check privileges for setting xvattr attributes
158 secpolicy_xvattr(xvattr_t
*xvap
, uid_t owner
, cred_t
*cr
, vtype_t vtype
)
160 /* return kauth_authorize_system(cred, KAUTH_SYSTEM_MOUNT,
161 KAUTH_REQ_SYSTEM_MOUNT_UPDATE, vfsp, NULL, NULL);*/
166 secpolicy_vnode_setid_retain(kauth_cred_t cred
, boolean_t issuidroot __unused
)
169 return (kauth_authorize_generic(cred
, KAUTH_GENERIC_ISSUSER
, NULL
));
173 secpolicy_vnode_setids_setgids(kauth_cred_t cred
, gid_t gid
)
176 if (!groupmember(gid
, cred
))
177 return (kauth_authorize_generic(cred
, KAUTH_GENERIC_ISSUSER
,
183 secpolicy_vnode_chown(struct kauth_cred
*cred
, boolean_t check_self
)
186 return (kauth_authorize_generic(cred
, KAUTH_GENERIC_ISSUSER
,
188 /* return (priv_check_cred(cred, PRIV_VFS_CHOWN, 0)); */
192 secpolicy_vnode_create_gid(struct kauth_cred
*cred
)
199 secpolicy_vnode_setdac(struct kauth_cred
*cred
, uid_t owner
)
203 /*return (priv_check_cred(cred, PRIV_VFS_ADMIN, 0));*/
207 secpolicy_setid_setsticky_clear(struct vnode
*vp
, struct vattr
*vap
,
208 const struct vattr
*ovap
, kauth_cred_t cred
)
211 * Privileged processes may set the sticky bit on non-directories,
212 * as well as set the setgid bit on a file with a group that the process
213 * is not a member of. Both of these are allowed in jail(8).
215 if (vp
->v_type
!= VDIR
&& (vap
->va_mode
& S_ISTXT
)) {
216 if (kauth_authorize_generic(cred
, KAUTH_GENERIC_ISSUSER
, NULL
) != 0)
220 * Check for privilege if attempting to set the
223 if ((vap
->va_mode
& S_ISGID
) != 0)
224 return (secpolicy_vnode_setids_setgids(cred
, ovap
->va_gid
));
230 secpolicy_vnode_setattr(kauth_cred_t cred
, struct vnode
*vp
, struct vattr
*vap
,
231 const struct vattr
*ovap
, int flags
,
232 int unlocked_access(void *, int, kauth_cred_t
), void *node
)
239 secpolicy_setid_clear(struct vattr
*vap
, kauth_cred_t cred
)
241 if (kauth_authorize_generic(cred
, KAUTH_GENERIC_ISSUSER
, NULL
) != 0)
244 if ((vap
->va_mode
& (S_ISUID
| S_ISGID
)) != 0) {
245 vap
->va_mask
|= AT_MODE
;
246 vap
->va_mode
&= ~(S_ISUID
|S_ISGID
);
254 secpolicy_vnode_setdac(kauth_cred_t cred
, uid_t owner
)
257 if (owner
== cred
->cr_uid
)
259 return (priv_check_cred(cred
, PRIV_VFS_ADMIN
, 0));
263 secpolicy_vnode_setattr(kauth_cred_t cred
, struct vnode
*vp
, struct vattr
*vap
,
264 const struct vattr
*ovap
, int flags
,
265 int unlocked_access(void *, int, kauth_cred_t
), void *node
)
267 int mask
= vap
->va_mask
;
270 if (mask
& AT_SIZE
) {
271 if (vp
->v_type
== VDIR
)
273 error
= unlocked_access(node
, VWRITE
, cred
);
277 if (mask
& AT_MODE
) {
279 * If not the owner of the file then check privilege
280 * for two things: the privilege to set the mode at all
281 * and, if we're setting setuid, we also need permissions
282 * to add the set-uid bit, if we're not the owner.
283 * In the specific case of creating a set-uid root
284 * file, we need even more permissions.
286 error
= secpolicy_vnode_setdac(cred
, ovap
->va_uid
);
289 error
= secpolicy_setid_setsticky_clear(vp
, vap
, ovap
, cred
);
293 vap
->va_mode
= ovap
->va_mode
;
295 if (mask
& (AT_UID
| AT_GID
)) {
296 error
= secpolicy_vnode_setdac(cred
, ovap
->va_uid
);
301 * To change the owner of a file, or change the group of a file to a
302 * group of which we are not a member, the caller must have
305 if (((mask
& AT_UID
) && vap
->va_uid
!= ovap
->va_uid
) ||
306 ((mask
& AT_GID
) && vap
->va_gid
!= ovap
->va_gid
&&
307 !groupmember(vap
->va_gid
, cred
))) {
308 error
= priv_check_cred(cred
, PRIV_VFS_CHOWN
, 0);
313 if (((mask
& AT_UID
) && vap
->va_uid
!= ovap
->va_uid
) ||
314 ((mask
& AT_GID
) && vap
->va_gid
!= ovap
->va_gid
)) {
315 secpolicy_setid_clear(vap
, cred
);
318 if (mask
& (AT_ATIME
| AT_MTIME
)) {
321 * If times is NULL, ... The caller must be the owner of
322 * the file, have permission to write the file, or be the
324 * If times is non-NULL, ... The caller must be the owner of
325 * the file or be the super-user.
327 error
= secpolicy_vnode_setdac(cred
, ovap
->va_uid
);
328 if (error
&& (vap
->va_vaflags
& VA_UTIMES_NULL
))
329 error
= unlocked_access(node
, VWRITE
, cred
);
337 secpolicy_vnode_create_gid(kauth_cred_t cred
)
344 secpolicy_vnode_setid_retain(kauth_cred_t cred
, boolean_t issuidroot __unused
)
347 return (priv_check_cred(cred
, PRIV_VFS_RETAINSUGID
, 0));
351 secpolicy_setid_clear(struct vattr
*vap
, kauth_cred_t cred
)
354 if (kauth_authorize_generic(cred
, KAUTH_GENERIC_ISSUSER
, NULL
))
357 if ((vap
->va_mode
& (S_ISUID
| S_ISGID
)) != 0) {
358 if (priv_check_cred(cred
, PRIV_VFS_RETAINSUGID
, 0)) {
359 vap
->va_mask
|= AT_MODE
;
360 vap
->va_mode
&= ~(S_ISUID
|S_ISGID
);