policy.c revision 6134:27ee74117a16
1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21/*
22 * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
23 * Use is subject to license terms.
24 */
25
26#pragma ident	"%Z%%M%	%I%	%E% SMI"
27
28#include <sys/types.h>
29#include <sys/sysmacros.h>
30#include <sys/param.h>
31#include <sys/systm.h>
32#include <sys/cred_impl.h>
33#include <sys/vnode.h>
34#include <sys/vfs.h>
35#include <sys/stat.h>
36#include <sys/errno.h>
37#include <sys/kmem.h>
38#include <sys/user.h>
39#include <sys/proc.h>
40#include <sys/acct.h>
41#include <sys/ipc_impl.h>
42#include <sys/cmn_err.h>
43#include <sys/debug.h>
44#include <sys/policy.h>
45#include <sys/kobj.h>
46#include <sys/msg.h>
47#include <sys/devpolicy.h>
48#include <c2/audit.h>
49#include <sys/varargs.h>
50#include <sys/klpd.h>
51#include <sys/modctl.h>
52#include <sys/disp.h>
53#include <sys/zone.h>
54#include <inet/optcom.h>
55#include <sys/sdt.h>
56#include <sys/vfs.h>
57#include <sys/mntent.h>
58#include <sys/contract_impl.h>
59
60/*
61 * There are two possible layers of privilege routines and two possible
62 * levels of secpolicy.  Plus one other we may not be interested in, so
63 * we may need as many as 6 but no more.
64 */
65#define	MAXPRIVSTACK		6
66
67int priv_debug = 0;
68
69/*
70 * This file contains the majority of the policy routines.
71 * Since the policy routines are defined by function and not
72 * by privilege, there is quite a bit of duplication of
73 * functions.
74 *
75 * The secpolicy functions must not make assumptions about
76 * locks held or not held as any lock can be held while they're
77 * being called.
78 *
79 * Credentials are read-only so no special precautions need to
80 * be taken while locking them.
81 *
82 * When a new policy check needs to be added to the system the
83 * following procedure should be followed:
84 *
85 *		Pick an appropriate secpolicy_*() function
86 *			-> done if one exists.
87 *		Create a new secpolicy function, preferably with
88 *		a descriptive name using the standard template.
89 *		Pick an appropriate privilege for the policy.
90 *		If no appropraite privilege exists, define new one
91 *		(this should be done with extreme care; in most cases
92 *		little is gained by adding another privilege)
93 *
94 * WHY ROOT IS STILL SPECIAL.
95 *
96 * In a number of the policy functions, there are still explicit
97 * checks for uid 0.  The rationale behind these is that many root
98 * owned files/objects hold configuration information which can give full
99 * privileges to the user once written to.  To prevent escalation
100 * of privilege by allowing just a single privilege to modify root owned
101 * objects, we've added these root specific checks where we considered
102 * them necessary: modifying root owned files, changing uids to 0, etc.
103 *
104 * PRIVILEGE ESCALATION AND ZONES.
105 *
106 * A number of operations potentially allow the caller to achieve
107 * privileges beyond the ones normally required to perform the operation.
108 * For example, if allowed to create a setuid 0 executable, a process can
109 * gain privileges beyond PRIV_FILE_SETID.  Zones, however, place
110 * restrictions on the ability to gain privileges beyond those available
111 * within the zone through file and process manipulation.  Hence, such
112 * operations require that the caller have an effective set that includes
113 * all privileges available within the current zone, or all privileges
114 * if executing in the global zone.
115 *
116 * This is indicated in the priv_policy* policy checking functions
117 * through a combination of parameters.  The "priv" parameter indicates
118 * the privilege that is required, and the "allzone" parameter indicates
119 * whether or not all privileges in the zone are required.  In addition,
120 * priv can be set to PRIV_ALL to indicate that all privileges are
121 * required (regardless of zone).  There are three scenarios of interest:
122 * (1) operation requires a specific privilege
123 * (2) operation requires a specific privilege, and requires all
124 *     privileges available within the zone (or all privileges if in
125 *     the global zone)
126 * (3) operation requires all privileges, regardless of zone
127 *
128 * For (1), priv should be set to the specific privilege, and allzone
129 * should be set to B_FALSE.
130 * For (2), priv should be set to the specific privilege, and allzone
131 * should be set to B_TRUE.
132 * For (3), priv should be set to PRIV_ALL, and allzone should be set
133 * to B_FALSE.
134 *
135 */
136
137/*
138 * The privileges are checked against the Effective set for
139 * ordinary processes and checked against the Limit set
140 * for euid 0 processes that haven't manipulated their privilege
141 * sets.
142 */
143#define	HAS_ALLPRIVS(cr)	priv_isfullset(&CR_OEPRIV(cr))
144#define	ZONEPRIVS(cr)		((cr)->cr_zone->zone_privset)
145#define	HAS_ALLZONEPRIVS(cr)	priv_issubset(ZONEPRIVS(cr), &CR_OEPRIV(cr))
146#define	HAS_PRIVILEGE(cr, pr)	((pr) == PRIV_ALL ? \
147					HAS_ALLPRIVS(cr) : \
148					PRIV_ISASSERT(&CR_OEPRIV(cr), pr))
149
150/*
151 * Policy checking functions.
152 *
153 * All of the system's policy should be implemented here.
154 */
155
156/*
157 * Private functions which take an additional va_list argument to
158 * implement an object specific policy override.
159 */
160static int priv_policy_ap(const cred_t *, int, boolean_t, int,
161    const char *, va_list);
162static int priv_policy_va(const cred_t *, int, boolean_t, int,
163    const char *, ...);
164
165/*
166 * Generic policy calls
167 *
168 * The "bottom" functions of policy control
169 */
170static char *
171mprintf(const char *fmt, ...)
172{
173	va_list args;
174	char *buf;
175	size_t len;
176
177	va_start(args, fmt);
178	len = vsnprintf(NULL, 0, fmt, args) + 1;
179	va_end(args);
180
181	buf = kmem_alloc(len, KM_NOSLEEP);
182
183	if (buf == NULL)
184		return (NULL);
185
186	va_start(args, fmt);
187	(void) vsnprintf(buf, len, fmt, args);
188	va_end(args);
189
190	return (buf);
191}
192
193/*
194 * priv_policy_errmsg()
195 *
196 * Generate an error message if privilege debugging is enabled system wide
197 * or for this particular process.
198 */
199
200#define	FMTHDR	"%s[%d]: missing privilege \"%s\" (euid = %d, syscall = %d)"
201#define	FMTMSG	" for \"%s\""
202#define	FMTFUN	" needed at %s+0x%lx"
203
204/* The maximum size privilege format: the concatenation of the above */
205#define	FMTMAX	FMTHDR FMTMSG FMTFUN "\n"
206
207static void
208priv_policy_errmsg(const cred_t *cr, int priv, const char *msg)
209{
210	struct proc *me;
211	pc_t stack[MAXPRIVSTACK];
212	int depth;
213	int i;
214	char *sym;
215	ulong_t off;
216	const char *pname;
217
218	char *cmd;
219	char fmt[sizeof (FMTMAX)];
220
221	if ((me = curproc) == &p0)
222		return;
223
224	/* Privileges must be defined  */
225	ASSERT(priv == PRIV_ALL || priv == PRIV_MULTIPLE ||
226	    priv == PRIV_ALLZONE || priv == PRIV_GLOBAL ||
227	    priv_getbynum(priv) != NULL);
228
229	if (priv == PRIV_ALLZONE && INGLOBALZONE(me))
230		priv = PRIV_ALL;
231
232	if (curthread->t_pre_sys)
233		ttolwp(curthread)->lwp_badpriv = (short)priv;
234
235	if (priv_debug == 0 && (CR_FLAGS(cr) & PRIV_DEBUG) == 0)
236		return;
237
238	(void) strcpy(fmt, FMTHDR);
239
240	if (me->p_user.u_comm[0])
241		cmd = &me->p_user.u_comm[0];
242	else
243		cmd = "priv_policy";
244
245	if (msg != NULL && *msg != '\0') {
246		(void) strcat(fmt, FMTMSG);
247	} else {
248		(void) strcat(fmt, "%s");
249		msg = "";
250	}
251
252	sym = NULL;
253
254	depth = getpcstack(stack, MAXPRIVSTACK);
255
256	/*
257	 * Try to find the first interesting function on the stack.
258	 * priv_policy* that's us, so completely uninteresting.
259	 * suser(), drv_priv(), secpolicy_* are also called from
260	 * too many locations to convey useful information.
261	 */
262	for (i = 0; i < depth; i++) {
263		sym = kobj_getsymname((uintptr_t)stack[i], &off);
264		if (sym != NULL &&
265		    strstr(sym, "hasprocperm") == 0 &&
266		    strcmp("suser", sym) != 0 &&
267		    strcmp("ipcaccess", sym) != 0 &&
268		    strcmp("drv_priv", sym) != 0 &&
269		    strncmp("secpolicy_", sym, 10) != 0 &&
270		    strncmp("priv_policy", sym, 11) != 0)
271			break;
272	}
273
274	if (sym != NULL)
275		(void) strcat(fmt, FMTFUN);
276
277	(void) strcat(fmt, "\n");
278
279	switch (priv) {
280	case PRIV_ALL:
281		pname = "ALL";
282		break;
283	case PRIV_MULTIPLE:
284		pname = "MULTIPLE";
285		break;
286	case PRIV_ALLZONE:
287		pname = "ZONE";
288		break;
289	case PRIV_GLOBAL:
290		pname = "GLOBAL";
291		break;
292	default:
293		pname = priv_getbynum(priv);
294		break;
295	}
296
297	if (CR_FLAGS(cr) & PRIV_DEBUG) {
298		/* Remember last message, just like lwp_badpriv. */
299		if (curthread->t_pdmsg != NULL) {
300			kmem_free(curthread->t_pdmsg,
301			    strlen(curthread->t_pdmsg) + 1);
302		}
303
304		curthread->t_pdmsg = mprintf(fmt, cmd, me->p_pid, pname,
305		    cr->cr_uid, curthread->t_sysnum, msg, sym, off);
306
307		curthread->t_post_sys = 1;
308	}
309	if (priv_debug) {
310		cmn_err(CE_NOTE, fmt, cmd, me->p_pid, pname, cr->cr_uid,
311		    curthread->t_sysnum, msg, sym, off);
312	}
313}
314
315/*
316 * Override the policy, if appropriate.  Return 0 if the external
317 * policy engine approves.
318 */
319static int
320priv_policy_override(const cred_t *cr, int priv, boolean_t allzone, va_list ap)
321{
322	priv_set_t set;
323	int ret;
324
325	if (!(CR_FLAGS(cr) & PRIV_XPOLICY))
326		return (-1);
327
328	if (priv == PRIV_ALL) {
329		priv_fillset(&set);
330	} else if (allzone) {
331		set = *ZONEPRIVS(cr);
332	} else {
333		priv_emptyset(&set);
334		priv_addset(&set, priv);
335	}
336	ret = klpd_call(cr, &set, ap);
337	return (ret);
338}
339
340static int
341priv_policy_override_set(const cred_t *cr, const priv_set_t *req, ...)
342{
343	va_list ap;
344
345	if (CR_FLAGS(cr) & PRIV_XPOLICY) {
346		va_start(ap, req);
347		return (klpd_call(cr, req, ap));
348	}
349	return (-1);
350}
351
352/*
353 * Audit failure, log error message.
354 */
355static void
356priv_policy_err(const cred_t *cr, int priv, boolean_t allzone, const char *msg)
357{
358
359	if (audit_active)
360		audit_priv(priv, allzone ? ZONEPRIVS(cr) : NULL, 0);
361	DTRACE_PROBE2(priv__err, int, priv, boolean_t, allzone);
362
363	if (priv_debug || (CR_FLAGS(cr) & PRIV_DEBUG) ||
364	    curthread->t_pre_sys) {
365		if (allzone && !HAS_ALLZONEPRIVS(cr)) {
366			priv_policy_errmsg(cr, PRIV_ALLZONE, msg);
367		} else {
368			ASSERT(!HAS_PRIVILEGE(cr, priv));
369			priv_policy_errmsg(cr, priv, msg);
370		}
371	}
372}
373
374/*
375 * priv_policy_ap()
376 * return 0 or error.
377 * See block comment above for a description of "priv" and "allzone" usage.
378 */
379static int
380priv_policy_ap(const cred_t *cr, int priv, boolean_t allzone, int err,
381    const char *msg, va_list ap)
382{
383	if ((HAS_PRIVILEGE(cr, priv) && (!allzone || HAS_ALLZONEPRIVS(cr))) ||
384	    (!servicing_interrupt() &&
385	    priv_policy_override(cr, priv, allzone, ap) == 0)) {
386		if ((allzone || priv == PRIV_ALL ||
387		    !PRIV_ISASSERT(priv_basic, priv)) &&
388		    !servicing_interrupt()) {
389			PTOU(curproc)->u_acflag |= ASU; /* Needed for SVVS */
390			if (audit_active)
391				audit_priv(priv,
392				    allzone ? ZONEPRIVS(cr) : NULL, 1);
393		}
394		err = 0;
395		DTRACE_PROBE2(priv__ok, int, priv, boolean_t, allzone);
396	} else if (!servicing_interrupt()) {
397		/* Failure audited in this procedure */
398		priv_policy_err(cr, priv, allzone, msg);
399	}
400	return (err);
401}
402
403int
404priv_policy_va(const cred_t *cr, int priv, boolean_t allzone, int err,
405    const char *msg, ...)
406{
407	int ret;
408	va_list ap;
409
410	va_start(ap, msg);
411	ret = priv_policy_ap(cr, priv, allzone, err, msg, ap);
412	va_end(ap);
413
414	return (ret);
415}
416
417int
418priv_policy(const cred_t *cr, int priv, boolean_t allzone, int err,
419    const char *msg)
420{
421	return (priv_policy_va(cr, priv, allzone, err, msg, KLPDARG_NOMORE));
422}
423
424/*
425 * Return B_TRUE for sufficient privileges, B_FALSE for insufficient privileges.
426 */
427boolean_t
428priv_policy_choice(const cred_t *cr, int priv, boolean_t allzone)
429{
430	boolean_t res = HAS_PRIVILEGE(cr, priv) &&
431	    (!allzone || HAS_ALLZONEPRIVS(cr));
432
433	/* Audit success only */
434	if (res && audit_active &&
435	    (allzone || priv == PRIV_ALL || !PRIV_ISASSERT(priv_basic, priv)) &&
436	    !servicing_interrupt()) {
437		audit_priv(priv, allzone ? ZONEPRIVS(cr) : NULL, 1);
438	}
439	if (res) {
440		DTRACE_PROBE2(priv__ok, int, priv, boolean_t, allzone);
441	} else {
442		DTRACE_PROBE2(priv__err, int, priv, boolean_t, allzone);
443	}
444	return (res);
445}
446
447/*
448 * Non-auditing variant of priv_policy_choice().
449 */
450boolean_t
451priv_policy_only(const cred_t *cr, int priv, boolean_t allzone)
452{
453	boolean_t res = HAS_PRIVILEGE(cr, priv) &&
454	    (!allzone || HAS_ALLZONEPRIVS(cr));
455
456	if (res) {
457		DTRACE_PROBE2(priv__ok, int, priv, boolean_t, allzone);
458	} else {
459		DTRACE_PROBE2(priv__err, int, priv, boolean_t, allzone);
460	}
461	return (res);
462}
463
464/*
465 * Check whether all privileges in the required set are present.
466 */
467static int
468secpolicy_require_set(const cred_t *cr, const priv_set_t *req, const char *msg)
469{
470	int priv;
471	int pfound = -1;
472	priv_set_t pset;
473
474	if (req == PRIV_FULLSET ? HAS_ALLPRIVS(cr) : priv_issubset(req,
475	    &CR_OEPRIV(cr))) {
476		return (0);
477	}
478
479	if (priv_policy_override_set(cr, req, KLPDARG_NOMORE) == 0)
480		return (0);
481
482	if (req == PRIV_FULLSET || priv_isfullset(req)) {
483		priv_policy_err(cr, PRIV_ALL, B_FALSE, msg);
484		return (EACCES);
485	}
486
487	pset = CR_OEPRIV(cr);		/* present privileges */
488	priv_inverse(&pset);		/* all non present privileges */
489	priv_intersect(req, &pset);	/* the actual missing privs */
490
491	if (audit_active)
492		audit_priv(PRIV_NONE, &pset, 0);
493	/*
494	 * Privilege debugging; special case "one privilege in set".
495	 */
496	if (priv_debug || (CR_FLAGS(cr) & PRIV_DEBUG) || curthread->t_pre_sys) {
497		for (priv = 0; priv < nprivs; priv++) {
498			if (priv_ismember(&pset, priv)) {
499				if (pfound != -1) {
500					/* Multiple missing privs */
501					priv_policy_errmsg(cr, PRIV_MULTIPLE,
502					    msg);
503					return (EACCES);
504				}
505				pfound = priv;
506			}
507		}
508		ASSERT(pfound != -1);
509		/* Just the one missing privilege */
510		priv_policy_errmsg(cr, pfound, msg);
511	}
512
513	return (EACCES);
514}
515
516/*
517 * Called when an operation requires that the caller be in the
518 * global zone, regardless of privilege.
519 */
520static int
521priv_policy_global(const cred_t *cr)
522{
523	if (crgetzoneid(cr) == GLOBAL_ZONEID)
524		return (0);	/* success */
525
526	if (priv_debug || (CR_FLAGS(cr) & PRIV_DEBUG) ||
527	    curthread->t_pre_sys) {
528		priv_policy_errmsg(cr, PRIV_GLOBAL, NULL);
529	}
530	return (EPERM);
531}
532
533/*
534 * Changing process priority
535 */
536int
537secpolicy_setpriority(const cred_t *cr)
538{
539	return (PRIV_POLICY(cr, PRIV_PROC_PRIOCNTL, B_FALSE, EPERM, NULL));
540}
541
542/*
543 * Binding to a privileged port, port must be specified in host byte
544 * order.
545 */
546int
547secpolicy_net_privaddr(const cred_t *cr, in_port_t port, int proto)
548{
549	char *reason;
550	int priv;
551
552	switch (port) {
553	case 137:
554	case 138:
555	case 139:
556	case 445:
557		/*
558		 * NBT and SMB ports, these are extra privileged ports,
559		 * allow bind only if the SYS_SMB privilege is present.
560		 */
561		priv = PRIV_SYS_SMB;
562		reason = "NBT or SMB port";
563		break;
564
565	case 2049:
566	case 4045:
567		/*
568		 * NFS ports, these are extra privileged ports, allow bind
569		 * only if the SYS_NFS privilege is present.
570		 */
571		priv = PRIV_SYS_NFS;
572		reason = "NFS port";
573		break;
574
575	default:
576		priv = PRIV_NET_PRIVADDR;
577		reason = NULL;
578		break;
579
580	}
581
582	return (priv_policy_va(cr, priv, B_FALSE, EACCES, reason,
583	    KLPDARG_PORT, (int)proto, (int)port, KLPDARG_NOMORE));
584}
585
586/*
587 * Binding to a multilevel port on a trusted (labeled) system.
588 */
589int
590secpolicy_net_bindmlp(const cred_t *cr)
591{
592	return (PRIV_POLICY(cr, PRIV_NET_BINDMLP, B_FALSE, EACCES, NULL));
593}
594
595/*
596 * Allow a communication between a zone and an unlabeled host when their
597 * labels don't match.
598 */
599int
600secpolicy_net_mac_aware(const cred_t *cr)
601{
602	return (PRIV_POLICY(cr, PRIV_NET_MAC_AWARE, B_FALSE, EACCES, NULL));
603}
604
605/*
606 * Common routine which determines whether a given credential can
607 * act on a given mount.
608 * When called through mount, the parameter needoptcheck is a pointer
609 * to a boolean variable which will be set to either true or false,
610 * depending on whether the mount policy should change the mount options.
611 * In all other cases, needoptcheck should be a NULL pointer.
612 */
613static int
614secpolicy_fs_common(cred_t *cr, vnode_t *mvp, const vfs_t *vfsp,
615    boolean_t *needoptcheck)
616{
617	boolean_t allzone = B_FALSE;
618	boolean_t mounting = needoptcheck != NULL;
619
620	/*
621	 * Short circuit the following cases:
622	 *	vfsp == NULL or mvp == NULL (pure privilege check)
623	 *	have all privileges - no further checks required
624	 *	and no mount options need to be set.
625	 */
626	if (vfsp == NULL || mvp == NULL || HAS_ALLPRIVS(cr)) {
627		if (mounting)
628			*needoptcheck = B_FALSE;
629
630		return (priv_policy_va(cr, PRIV_SYS_MOUNT, allzone, EPERM,
631		    NULL, KLPDARG_VNODE, mvp, (char *)NULL, KLPDARG_NOMORE));
632	}
633
634	/*
635	 * When operating on an existing mount (either we're not mounting
636	 * or we're doing a remount and VFS_REMOUNT will be set), zones
637	 * can operate only on mounts established by the zone itself.
638	 */
639	if (!mounting || (vfsp->vfs_flag & VFS_REMOUNT) != 0) {
640		zoneid_t zoneid = crgetzoneid(cr);
641
642		if (zoneid != GLOBAL_ZONEID &&
643		    vfsp->vfs_zone->zone_id != zoneid) {
644			return (EPERM);
645		}
646	}
647
648	if (mounting)
649		*needoptcheck = B_TRUE;
650
651	/*
652	 * Overlay mounts may hide important stuff; if you can't write to a
653	 * mount point but would be able to mount on top of it, you can
654	 * escalate your privileges.
655	 * So we go about asking the same questions namefs does when it
656	 * decides whether you can mount over a file or not but with the
657	 * added restriction that you can only mount on top of a regular
658	 * file or directory.
659	 * If we have all the zone's privileges, we skip all other checks,
660	 * or else we may actually get in trouble inside the automounter.
661	 */
662	if ((mvp->v_flag & VROOT) != 0 ||
663	    (mvp->v_type != VDIR && mvp->v_type != VREG) ||
664	    HAS_ALLZONEPRIVS(cr)) {
665		allzone = B_TRUE;
666	} else {
667		vattr_t va;
668		int err;
669
670		va.va_mask = AT_UID|AT_MODE;
671		err = VOP_GETATTR(mvp, &va, 0, cr, NULL);
672		if (err != 0)
673			return (err);
674
675		if ((err = secpolicy_vnode_owner(cr, va.va_uid)) != 0)
676			return (err);
677
678		if ((va.va_mode & VWRITE) == 0 &&
679		    secpolicy_vnode_access(cr, mvp, va.va_uid, VWRITE) != 0) {
680			return (EACCES);
681		}
682	}
683	return (priv_policy_va(cr, PRIV_SYS_MOUNT, allzone, EPERM,
684	    NULL, KLPDARG_VNODE, mvp, (char *)NULL, KLPDARG_NOMORE));
685}
686
687void
688secpolicy_fs_mount_clearopts(cred_t *cr, struct vfs *vfsp)
689{
690	boolean_t amsuper = HAS_ALLZONEPRIVS(cr);
691
692	/*
693	 * check; if we don't have either "nosuid" or
694	 * both "nosetuid" and "nodevices", then we add
695	 * "nosuid"; this depends on how the current
696	 * implementation works (it first checks nosuid).  In a
697	 * zone, a user with all zone privileges can mount with
698	 * "setuid" but never with "devices".
699	 */
700	if (!vfs_optionisset(vfsp, MNTOPT_NOSUID, NULL) &&
701	    (!vfs_optionisset(vfsp, MNTOPT_NODEVICES, NULL) ||
702	    !vfs_optionisset(vfsp, MNTOPT_NOSETUID, NULL))) {
703		if (crgetzoneid(cr) == GLOBAL_ZONEID || !amsuper)
704			vfs_setmntopt(vfsp, MNTOPT_NOSUID, NULL, 0);
705		else
706			vfs_setmntopt(vfsp, MNTOPT_NODEVICES, NULL, 0);
707	}
708	/*
709	 * If we're not the local super user, we set the "restrict"
710	 * option to indicate to automountd that this mount should
711	 * be handled with care.
712	 */
713	if (!amsuper)
714		vfs_setmntopt(vfsp, MNTOPT_RESTRICT, NULL, 0);
715
716}
717
718extern vnode_t *rootvp;
719extern vfs_t *rootvfs;
720
721int
722secpolicy_fs_mount(cred_t *cr, vnode_t *mvp, struct vfs *vfsp)
723{
724	boolean_t needoptchk;
725	int error;
726
727	/*
728	 * If it's a remount, get the underlying mount point,
729	 * except for the root where we use the rootvp.
730	 */
731	if ((vfsp->vfs_flag & VFS_REMOUNT) != 0) {
732		if (vfsp == rootvfs)
733			mvp = rootvp;
734		else
735			mvp = vfsp->vfs_vnodecovered;
736	}
737
738	error = secpolicy_fs_common(cr, mvp, vfsp, &needoptchk);
739
740	if (error == 0 && needoptchk) {
741		secpolicy_fs_mount_clearopts(cr, vfsp);
742	}
743
744	return (error);
745}
746
747/*
748 * Does the policy computations for "ownership" of a mount;
749 * here ownership is defined as the ability to "mount"
750 * the filesystem originally.  The rootvfs doesn't cover any
751 * vnodes; we attribute its ownership to the rootvp.
752 */
753static int
754secpolicy_fs_owner(cred_t *cr, const struct vfs *vfsp)
755{
756	vnode_t *mvp;
757
758	if (vfsp == NULL)
759		mvp = NULL;
760	else if (vfsp == rootvfs)
761		mvp = rootvp;
762	else
763		mvp = vfsp->vfs_vnodecovered;
764
765	return (secpolicy_fs_common(cr, mvp, vfsp, NULL));
766}
767
768int
769secpolicy_fs_unmount(cred_t *cr, struct vfs *vfsp)
770{
771	return (secpolicy_fs_owner(cr, vfsp));
772}
773
774/*
775 * Quotas are a resource, but if one has the ability to mount a filesystem, he
776 * should be able to modify quotas on it.
777 */
778int
779secpolicy_fs_quota(const cred_t *cr, const vfs_t *vfsp)
780{
781	return (secpolicy_fs_owner((cred_t *)cr, vfsp));
782}
783
784/*
785 * Exceeding minfree: also a per-mount resource constraint.
786 */
787int
788secpolicy_fs_minfree(const cred_t *cr, const vfs_t *vfsp)
789{
790	return (secpolicy_fs_owner((cred_t *)cr, vfsp));
791}
792
793int
794secpolicy_fs_config(const cred_t *cr, const vfs_t *vfsp)
795{
796	return (secpolicy_fs_owner((cred_t *)cr, vfsp));
797}
798
799/* ARGSUSED */
800int
801secpolicy_fs_linkdir(const cred_t *cr, const vfs_t *vfsp)
802{
803	return (PRIV_POLICY(cr, PRIV_SYS_LINKDIR, B_FALSE, EPERM, NULL));
804}
805
806/*
807 * Name:        secpolicy_vnode_access()
808 *
809 * Parameters:  Process credential
810 *		vnode
811 *		uid of owner of vnode
812 *		permission bits not granted to the caller when examining
813 *		file mode bits (i.e., when a process wants to open a
814 *		mode 444 file for VREAD|VWRITE, this function should be
815 *		called only with a VWRITE argument).
816 *
817 * Normal:      Verifies that cred has the appropriate privileges to
818 *              override the mode bits that were denied.
819 *
820 * Override:    file_dac_execute - if VEXEC bit was denied and vnode is
821 *                      not a directory.
822 *              file_dac_read - if VREAD bit was denied.
823 *              file_dac_search - if VEXEC bit was denied and vnode is
824 *                      a directory.
825 *              file_dac_write - if VWRITE bit was denied.
826 *
827 *		Root owned files are special cased to protect system
828 *		configuration files and such.
829 *
830 * Output:      EACCES - if privilege check fails.
831 */
832
833/* ARGSUSED */
834int
835secpolicy_vnode_access(const cred_t *cr, vnode_t *vp, uid_t owner, mode_t mode)
836{
837	if ((mode & VREAD) && priv_policy_va(cr, PRIV_FILE_DAC_READ, B_FALSE,
838	    EACCES, NULL, KLPDARG_VNODE, vp, (char *)NULL,
839	    KLPDARG_NOMORE) != 0) {
840		return (EACCES);
841	}
842
843	if (mode & VWRITE) {
844		boolean_t allzone;
845
846		if (owner == 0 && cr->cr_uid != 0)
847			allzone = B_TRUE;
848		else
849			allzone = B_FALSE;
850		if (priv_policy_va(cr, PRIV_FILE_DAC_WRITE, allzone, EACCES,
851		    NULL, KLPDARG_VNODE, vp, (char *)NULL,
852		    KLPDARG_NOMORE) != 0) {
853			return (EACCES);
854		}
855	}
856
857	if (mode & VEXEC) {
858		/*
859		 * Directories use file_dac_search to override the execute bit.
860		 */
861		int p = vp->v_type == VDIR ? PRIV_FILE_DAC_SEARCH :
862		    PRIV_FILE_DAC_EXECUTE;
863
864		return (priv_policy_va(cr, p, B_FALSE, EACCES, NULL,
865		    KLPDARG_VNODE, vp, (char *)NULL, KLPDARG_NOMORE));
866	}
867	return (0);
868}
869
870/*
871 * Name:	secpolicy_vnode_setid_modify()
872 *
873 * Normal:	verify that subject can set the file setid flags.
874 *
875 * Output:	EPERM - if not privileged.
876 */
877
878static int
879secpolicy_vnode_setid_modify(const cred_t *cr, uid_t owner)
880{
881	/* If changing to suid root, must have all zone privs */
882	boolean_t allzone = B_TRUE;
883
884	if (owner != 0) {
885		if (owner == cr->cr_uid)
886			return (0);
887		allzone = B_FALSE;
888	}
889	return (PRIV_POLICY(cr, PRIV_FILE_SETID, allzone, EPERM, NULL));
890}
891
892/*
893 * Are we allowed to retain the set-uid/set-gid bits when
894 * changing ownership or when writing to a file?
895 * "issuid" should be true when set-uid; only in that case
896 * root ownership is checked (setgid is assumed).
897 */
898int
899secpolicy_vnode_setid_retain(const cred_t *cred, boolean_t issuidroot)
900{
901	if (issuidroot && !HAS_ALLZONEPRIVS(cred))
902		return (EPERM);
903
904	return (!PRIV_POLICY_CHOICE(cred, PRIV_FILE_SETID, B_FALSE));
905}
906
907/*
908 * Name:	secpolicy_vnode_setids_setgids()
909 *
910 * Normal:	verify that subject can set the file setgid flag.
911 *
912 * Output:	EPERM - if not privileged
913 */
914
915int
916secpolicy_vnode_setids_setgids(const cred_t *cred, gid_t gid)
917{
918	if (!groupmember(gid, cred))
919		return (PRIV_POLICY(cred, PRIV_FILE_SETID, B_FALSE, EPERM,
920		    NULL));
921	return (0);
922}
923
924/*
925 * Create a file with a group different than any of the groups allowed:
926 * the group of the directory the file is created in, the effective
927 * group or any of the supplementary groups.
928 */
929int
930secpolicy_vnode_create_gid(const cred_t *cred)
931{
932	if (HAS_PRIVILEGE(cred, PRIV_FILE_CHOWN))
933		return (PRIV_POLICY(cred, PRIV_FILE_CHOWN, B_FALSE, EPERM,
934		    NULL));
935	else
936		return (PRIV_POLICY(cred, PRIV_FILE_CHOWN_SELF, B_FALSE, EPERM,
937		    NULL));
938}
939
940/*
941 * Name:	secpolicy_vnode_utime_modify()
942 *
943 * Normal:	verify that subject can modify the utime on a file.
944 *
945 * Output:	EPERM - if access denied.
946 */
947
948static int
949secpolicy_vnode_utime_modify(const cred_t *cred)
950{
951	return (PRIV_POLICY(cred, PRIV_FILE_OWNER, B_FALSE, EPERM,
952	    "modify file times"));
953}
954
955
956/*
957 * Name:	secpolicy_vnode_setdac()
958 *
959 * Normal:	verify that subject can modify the mode of a file.
960 *		allzone privilege needed when modifying root owned object.
961 *
962 * Output:	EPERM - if access denied.
963 */
964
965int
966secpolicy_vnode_setdac(const cred_t *cred, uid_t owner)
967{
968	if (owner == cred->cr_uid)
969		return (0);
970
971	return (PRIV_POLICY(cred, PRIV_FILE_OWNER, owner == 0, EPERM, NULL));
972}
973/*
974 * Name:	secpolicy_vnode_stky_modify()
975 *
976 * Normal:	verify that subject can make a file a "sticky".
977 *
978 * Output:	EPERM - if access denied.
979 */
980
981int
982secpolicy_vnode_stky_modify(const cred_t *cred)
983{
984	return (PRIV_POLICY(cred, PRIV_SYS_CONFIG, B_FALSE, EPERM,
985	    "set file sticky"));
986}
987
988/*
989 * Policy determines whether we can remove an entry from a directory,
990 * regardless of permission bits.
991 */
992int
993secpolicy_vnode_remove(const cred_t *cr)
994{
995	return (PRIV_POLICY(cr, PRIV_FILE_OWNER, B_FALSE, EACCES,
996	    "sticky directory"));
997}
998
999int
1000secpolicy_vnode_owner(const cred_t *cr, uid_t owner)
1001{
1002	boolean_t allzone = (owner == 0);
1003
1004	if (owner == cr->cr_uid)
1005		return (0);
1006
1007	return (PRIV_POLICY(cr, PRIV_FILE_OWNER, allzone, EPERM, NULL));
1008}
1009
1010void
1011secpolicy_setid_clear(vattr_t *vap, cred_t *cr)
1012{
1013	if ((vap->va_mode & (S_ISUID | S_ISGID)) != 0 &&
1014	    secpolicy_vnode_setid_retain(cr,
1015	    (vap->va_mode & S_ISUID) != 0 &&
1016	    (vap->va_mask & AT_UID) != 0 && vap->va_uid == 0) != 0) {
1017		vap->va_mask |= AT_MODE;
1018		vap->va_mode &= ~(S_ISUID|S_ISGID);
1019	}
1020}
1021
1022int
1023secpolicy_setid_setsticky_clear(vnode_t *vp, vattr_t *vap, const vattr_t *ovap,
1024    cred_t *cr)
1025{
1026	int error;
1027
1028	if ((vap->va_mode & S_ISUID) != 0 &&
1029	    (error = secpolicy_vnode_setid_modify(cr,
1030	    ovap->va_uid)) != 0) {
1031		return (error);
1032	}
1033
1034	/*
1035	 * Check privilege if attempting to set the
1036	 * sticky bit on a non-directory.
1037	 */
1038	if (vp->v_type != VDIR && (vap->va_mode & S_ISVTX) != 0 &&
1039	    secpolicy_vnode_stky_modify(cr) != 0) {
1040		vap->va_mode &= ~S_ISVTX;
1041	}
1042
1043	/*
1044	 * Check for privilege if attempting to set the
1045	 * group-id bit.
1046	 */
1047	if ((vap->va_mode & S_ISGID) != 0 &&
1048	    secpolicy_vnode_setids_setgids(cr, ovap->va_gid) != 0) {
1049		vap->va_mode &= ~S_ISGID;
1050	}
1051
1052	return (0);
1053}
1054
1055#define	ATTR_FLAG_PRIV(attr, value, cr)	\
1056	PRIV_POLICY(cr, value ? PRIV_FILE_FLAG_SET : PRIV_ALL, \
1057	B_FALSE, EPERM, NULL)
1058
1059/*
1060 * Check privileges for setting xvattr attributes
1061 */
1062int
1063secpolicy_xvattr(xvattr_t *xvap, uid_t owner, cred_t *cr, vtype_t vtype)
1064{
1065	xoptattr_t *xoap;
1066	int error = 0;
1067
1068	if ((xoap = xva_getxoptattr(xvap)) == NULL)
1069		return (EINVAL);
1070
1071	/*
1072	 * First process the DOS bits
1073	 */
1074	if (XVA_ISSET_REQ(xvap, XAT_ARCHIVE) ||
1075	    XVA_ISSET_REQ(xvap, XAT_HIDDEN) ||
1076	    XVA_ISSET_REQ(xvap, XAT_READONLY) ||
1077	    XVA_ISSET_REQ(xvap, XAT_SYSTEM) ||
1078	    XVA_ISSET_REQ(xvap, XAT_CREATETIME)) {
1079		if ((error = secpolicy_vnode_owner(cr, owner)) != 0)
1080			return (error);
1081	}
1082
1083	/*
1084	 * Now handle special attributes
1085	 */
1086
1087	if (XVA_ISSET_REQ(xvap, XAT_IMMUTABLE))
1088		error = ATTR_FLAG_PRIV(XAT_IMMUTABLE,
1089		    xoap->xoa_immutable, cr);
1090	if (error == 0 && XVA_ISSET_REQ(xvap, XAT_NOUNLINK))
1091		error = ATTR_FLAG_PRIV(XAT_NOUNLINK,
1092		    xoap->xoa_nounlink, cr);
1093	if (error == 0 && XVA_ISSET_REQ(xvap, XAT_APPENDONLY))
1094		error = ATTR_FLAG_PRIV(XAT_APPENDONLY,
1095		    xoap->xoa_appendonly, cr);
1096	if (error == 0 && XVA_ISSET_REQ(xvap, XAT_NODUMP))
1097		error = ATTR_FLAG_PRIV(XAT_NODUMP,
1098		    xoap->xoa_nodump, cr);
1099	if (error == 0 && XVA_ISSET_REQ(xvap, XAT_OPAQUE))
1100		error = EPERM;
1101	if (error == 0 && XVA_ISSET_REQ(xvap, XAT_AV_QUARANTINED)) {
1102		error = ATTR_FLAG_PRIV(XAT_AV_QUARANTINED,
1103		    xoap->xoa_av_quarantined, cr);
1104		if (error == 0 && vtype != VREG && xoap->xoa_av_quarantined)
1105			error = EINVAL;
1106	}
1107	if (error == 0 && XVA_ISSET_REQ(xvap, XAT_AV_MODIFIED))
1108		error = ATTR_FLAG_PRIV(XAT_AV_MODIFIED,
1109		    xoap->xoa_av_modified, cr);
1110	if (error == 0 && XVA_ISSET_REQ(xvap, XAT_AV_SCANSTAMP)) {
1111		error = ATTR_FLAG_PRIV(XAT_AV_SCANSTAMP,
1112		    xoap->xoa_av_scanstamp, cr);
1113		if (error == 0 && vtype != VREG)
1114			error = EINVAL;
1115	}
1116	return (error);
1117}
1118
1119/*
1120 * This function checks the policy decisions surrounding the
1121 * vop setattr call.
1122 *
1123 * It should be called after sufficient locks have been established
1124 * on the underlying data structures.  No concurrent modifications
1125 * should be allowed.
1126 *
1127 * The caller must pass in unlocked version of its vaccess function
1128 * this is required because vop_access function should lock the
1129 * node for reading.  A three argument function should be defined
1130 * which accepts the following argument:
1131 * 	A pointer to the internal "node" type (inode *)
1132 *	vnode access bits (VREAD|VWRITE|VEXEC)
1133 *	a pointer to the credential
1134 *
1135 * This function makes the following policy decisions:
1136 *
1137 *		- change permissions
1138 *			- permission to change file mode if not owner
1139 *			- permission to add sticky bit to non-directory
1140 *			- permission to add set-gid bit
1141 *
1142 * The ovap argument should include AT_MODE|AT_UID|AT_GID.
1143 *
1144 * If the vap argument does not include AT_MODE, the mode will be copied from
1145 * ovap.  In certain situations set-uid/set-gid bits need to be removed;
1146 * this is done by marking vap->va_mask to include AT_MODE and va_mode
1147 * is updated to the newly computed mode.
1148 */
1149
1150int
1151secpolicy_vnode_setattr(cred_t *cr, struct vnode *vp, struct vattr *vap,
1152	const struct vattr *ovap, int flags,
1153	int unlocked_access(void *, int, cred_t *),
1154	void *node)
1155{
1156	int mask = vap->va_mask;
1157	int error = 0;
1158	boolean_t skipaclchk = (flags & ATTR_NOACLCHECK) ? B_TRUE : B_FALSE;
1159
1160	if (mask & AT_SIZE) {
1161		if (vp->v_type == VDIR) {
1162			error = EISDIR;
1163			goto out;
1164		}
1165
1166		/*
1167		 * If ATTR_NOACLCHECK is set in the flags, then we don't
1168		 * perform the secondary unlocked_access() call since the
1169		 * ACL (if any) is being checked there.
1170		 */
1171		if (skipaclchk == B_FALSE) {
1172			error = unlocked_access(node, VWRITE, cr);
1173			if (error)
1174				goto out;
1175		}
1176	}
1177	if (mask & AT_MODE) {
1178		/*
1179		 * If not the owner of the file then check privilege
1180		 * for two things: the privilege to set the mode at all
1181		 * and, if we're setting setuid, we also need permissions
1182		 * to add the set-uid bit, if we're not the owner.
1183		 * In the specific case of creating a set-uid root
1184		 * file, we need even more permissions.
1185		 */
1186		if ((error = secpolicy_vnode_setdac(cr, ovap->va_uid)) != 0)
1187			goto out;
1188
1189		if ((error = secpolicy_setid_setsticky_clear(vp, vap,
1190		    ovap, cr)) != 0)
1191			goto out;
1192	} else
1193		vap->va_mode = ovap->va_mode;
1194
1195	if (mask & (AT_UID|AT_GID)) {
1196		boolean_t checkpriv = B_FALSE;
1197		int priv;
1198		boolean_t allzone = B_FALSE;
1199
1200		/*
1201		 * Chowning files.
1202		 *
1203		 * If you are the file owner:
1204		 *	chown to other uid		FILE_CHOWN_SELF
1205		 *	chown to gid (non-member) 	FILE_CHOWN_SELF
1206		 *	chown to gid (member) 		<none>
1207		 *
1208		 * Instead of PRIV_FILE_CHOWN_SELF, FILE_CHOWN is also
1209		 * acceptable but the first one is reported when debugging.
1210		 *
1211		 * If you are not the file owner:
1212		 *	chown from root			PRIV_FILE_CHOWN + zone
1213		 *	chown from other to any		PRIV_FILE_CHOWN
1214		 *
1215		 */
1216		if (cr->cr_uid != ovap->va_uid) {
1217			checkpriv = B_TRUE;
1218			allzone = (ovap->va_uid == 0);
1219			priv = PRIV_FILE_CHOWN;
1220		} else {
1221			if (((mask & AT_UID) && vap->va_uid != ovap->va_uid) ||
1222			    ((mask & AT_GID) && vap->va_gid != ovap->va_gid &&
1223			    !groupmember(vap->va_gid, cr))) {
1224				checkpriv = B_TRUE;
1225				priv = HAS_PRIVILEGE(cr, PRIV_FILE_CHOWN) ?
1226				    PRIV_FILE_CHOWN : PRIV_FILE_CHOWN_SELF;
1227			}
1228		}
1229		/*
1230		 * If necessary, check privilege to see if update can be done.
1231		 */
1232		if (checkpriv &&
1233		    (error = PRIV_POLICY(cr, priv, allzone, EPERM, NULL))
1234		    != 0) {
1235			goto out;
1236		}
1237
1238		/*
1239		 * If the file has either the set UID or set GID bits
1240		 * set and the caller can set the bits, then leave them.
1241		 */
1242		secpolicy_setid_clear(vap, cr);
1243	}
1244	if (mask & (AT_ATIME|AT_MTIME)) {
1245		/*
1246		 * If not the file owner and not otherwise privileged,
1247		 * always return an error when setting the
1248		 * time other than the current (ATTR_UTIME flag set).
1249		 * If setting the current time (ATTR_UTIME not set) then
1250		 * unlocked_access will check permissions according to policy.
1251		 */
1252		if (cr->cr_uid != ovap->va_uid) {
1253			if (flags & ATTR_UTIME)
1254				error = secpolicy_vnode_utime_modify(cr);
1255			else if (skipaclchk == B_FALSE) {
1256				error = unlocked_access(node, VWRITE, cr);
1257				if (error == EACCES &&
1258				    secpolicy_vnode_utime_modify(cr) == 0)
1259					error = 0;
1260			}
1261			if (error)
1262				goto out;
1263		}
1264	}
1265
1266	/*
1267	 * Check for optional attributes here by checking the following:
1268	 */
1269	if (mask & AT_XVATTR)
1270		error = secpolicy_xvattr((xvattr_t *)vap, ovap->va_uid, cr,
1271		    vp->v_type);
1272out:
1273	return (error);
1274}
1275
1276/*
1277 * Name:	secpolicy_pcfs_modify_bootpartition()
1278 *
1279 * Normal:	verify that subject can modify a pcfs boot partition.
1280 *
1281 * Output:	EACCES - if privilege check failed.
1282 */
1283/*ARGSUSED*/
1284int
1285secpolicy_pcfs_modify_bootpartition(const cred_t *cred)
1286{
1287	return (PRIV_POLICY(cred, PRIV_ALL, B_FALSE, EACCES,
1288	    "modify pcfs boot partition"));
1289}
1290
1291/*
1292 * System V IPC routines
1293 */
1294int
1295secpolicy_ipc_owner(const cred_t *cr, const struct kipc_perm *ip)
1296{
1297	if (crgetzoneid(cr) != ip->ipc_zoneid ||
1298	    (cr->cr_uid != ip->ipc_uid && cr->cr_uid != ip->ipc_cuid)) {
1299		boolean_t allzone = B_FALSE;
1300		if (ip->ipc_uid == 0 || ip->ipc_cuid == 0)
1301			allzone = B_TRUE;
1302		return (PRIV_POLICY(cr, PRIV_IPC_OWNER, allzone, EPERM, NULL));
1303	}
1304	return (0);
1305}
1306
1307int
1308secpolicy_ipc_config(const cred_t *cr)
1309{
1310	return (PRIV_POLICY(cr, PRIV_SYS_IPC_CONFIG, B_FALSE, EPERM, NULL));
1311}
1312
1313int
1314secpolicy_ipc_access(const cred_t *cr, const struct kipc_perm *ip, mode_t mode)
1315{
1316
1317	boolean_t allzone = B_FALSE;
1318
1319	ASSERT((mode & (MSG_R|MSG_W)) != 0);
1320
1321	if ((mode & MSG_R) &&
1322	    PRIV_POLICY(cr, PRIV_IPC_DAC_READ, allzone, EACCES, NULL) != 0)
1323		return (EACCES);
1324
1325	if (mode & MSG_W) {
1326		if (cr->cr_uid != 0 && (ip->ipc_uid == 0 || ip->ipc_cuid == 0))
1327			allzone = B_TRUE;
1328
1329		return (PRIV_POLICY(cr, PRIV_IPC_DAC_WRITE, allzone, EACCES,
1330		    NULL));
1331	}
1332	return (0);
1333}
1334
1335int
1336secpolicy_rsm_access(const cred_t *cr, uid_t owner, mode_t mode)
1337{
1338	boolean_t allzone = B_FALSE;
1339
1340	ASSERT((mode & (MSG_R|MSG_W)) != 0);
1341
1342	if ((mode & MSG_R) &&
1343	    PRIV_POLICY(cr, PRIV_IPC_DAC_READ, allzone, EACCES, NULL) != 0)
1344		return (EACCES);
1345
1346	if (mode & MSG_W) {
1347		if (cr->cr_uid != 0 && owner == 0)
1348			allzone = B_TRUE;
1349
1350		return (PRIV_POLICY(cr, PRIV_IPC_DAC_WRITE, allzone, EACCES,
1351		    NULL));
1352	}
1353	return (0);
1354}
1355
1356/*
1357 * Audit configuration.
1358 */
1359int
1360secpolicy_audit_config(const cred_t *cr)
1361{
1362	return (PRIV_POLICY(cr, PRIV_SYS_AUDIT, B_FALSE, EPERM, NULL));
1363}
1364
1365/*
1366 * Audit record generation.
1367 */
1368int
1369secpolicy_audit_modify(const cred_t *cr)
1370{
1371	return (PRIV_POLICY(cr, PRIV_PROC_AUDIT, B_FALSE, EPERM, NULL));
1372}
1373
1374/*
1375 * Get audit attributes.
1376 * Either PRIV_SYS_AUDIT or PRIV_PROC_AUDIT required; report the
1377 * "Least" of the two privileges on error.
1378 */
1379int
1380secpolicy_audit_getattr(const cred_t *cr)
1381{
1382	if (!PRIV_POLICY_ONLY(cr, PRIV_SYS_AUDIT, B_FALSE)) {
1383		return (PRIV_POLICY(cr, PRIV_PROC_AUDIT, B_FALSE, EPERM,
1384		    NULL));
1385	} else {
1386		return (PRIV_POLICY(cr, PRIV_SYS_AUDIT, B_FALSE, EPERM, NULL));
1387	}
1388}
1389
1390
1391/*
1392 * Locking physical memory
1393 */
1394int
1395secpolicy_lock_memory(const cred_t *cr)
1396{
1397	return (PRIV_POLICY(cr, PRIV_PROC_LOCK_MEMORY, B_FALSE, EPERM, NULL));
1398}
1399
1400/*
1401 * Accounting (both acct(2) and exacct).
1402 */
1403int
1404secpolicy_acct(const cred_t *cr)
1405{
1406	return (PRIV_POLICY(cr, PRIV_SYS_ACCT, B_FALSE, EPERM, NULL));
1407}
1408
1409/*
1410 * Is this process privileged to change its uids at will?
1411 * Uid 0 is still considered "special" and having the SETID
1412 * privilege is not sufficient to get uid 0.
1413 * Files are owned by root, so the privilege would give
1414 * full access and euid 0 is still effective.
1415 *
1416 * If you have the privilege and euid 0 only then do you
1417 * get the powers of root wrt uid 0.
1418 *
1419 * For gid manipulations, this is should be called with an
1420 * uid of -1.
1421 *
1422 */
1423int
1424secpolicy_allow_setid(const cred_t *cr, uid_t newuid, boolean_t checkonly)
1425{
1426	boolean_t allzone = B_FALSE;
1427
1428	if (newuid == 0 && cr->cr_uid != 0 && cr->cr_suid != 0 &&
1429	    cr->cr_ruid != 0) {
1430		allzone = B_TRUE;
1431	}
1432
1433	return (checkonly ? !PRIV_POLICY_ONLY(cr, PRIV_PROC_SETID, allzone) :
1434	    PRIV_POLICY(cr, PRIV_PROC_SETID, allzone, EPERM, NULL));
1435}
1436
1437
1438/*
1439 * Acting on a different process: if the mode is for writing,
1440 * the restrictions are more severe.  This is called after
1441 * we've verified that the uids do not match.
1442 */
1443int
1444secpolicy_proc_owner(const cred_t *scr, const cred_t *tcr, int mode)
1445{
1446	boolean_t allzone = B_FALSE;
1447
1448	if ((mode & VWRITE) && scr->cr_uid != 0 &&
1449	    (tcr->cr_uid == 0 || tcr->cr_ruid == 0 || tcr->cr_suid == 0))
1450		allzone = B_TRUE;
1451
1452	return (PRIV_POLICY(scr, PRIV_PROC_OWNER, allzone, EPERM, NULL));
1453}
1454
1455int
1456secpolicy_proc_access(const cred_t *scr)
1457{
1458	return (PRIV_POLICY(scr, PRIV_PROC_OWNER, B_FALSE, EACCES, NULL));
1459}
1460
1461int
1462secpolicy_proc_excl_open(const cred_t *scr)
1463{
1464	return (PRIV_POLICY(scr, PRIV_PROC_OWNER, B_FALSE, EBUSY, NULL));
1465}
1466
1467int
1468secpolicy_proc_zone(const cred_t *scr)
1469{
1470	return (PRIV_POLICY(scr, PRIV_PROC_ZONE, B_FALSE, EPERM, NULL));
1471}
1472
1473/*
1474 * Destroying the system
1475 */
1476
1477int
1478secpolicy_kmdb(const cred_t *scr)
1479{
1480	return (PRIV_POLICY(scr, PRIV_ALL, B_FALSE, EPERM, NULL));
1481}
1482
1483int
1484secpolicy_error_inject(const cred_t *scr)
1485{
1486	return (PRIV_POLICY(scr, PRIV_ALL, B_FALSE, EPERM, NULL));
1487}
1488
1489/*
1490 * Processor sets, cpu configuration, resource pools.
1491 */
1492int
1493secpolicy_pset(const cred_t *cr)
1494{
1495	return (PRIV_POLICY(cr, PRIV_SYS_RES_CONFIG, B_FALSE, EPERM, NULL));
1496}
1497
1498int
1499secpolicy_ponline(const cred_t *cr)
1500{
1501	return (PRIV_POLICY(cr, PRIV_SYS_RES_CONFIG, B_FALSE, EPERM, NULL));
1502}
1503
1504int
1505secpolicy_pool(const cred_t *cr)
1506{
1507	return (PRIV_POLICY(cr, PRIV_SYS_RES_CONFIG, B_FALSE, EPERM, NULL));
1508}
1509
1510int
1511secpolicy_blacklist(const cred_t *cr)
1512{
1513	return (PRIV_POLICY(cr, PRIV_SYS_RES_CONFIG, B_FALSE, EPERM, NULL));
1514}
1515
1516/*
1517 * Catch all system configuration.
1518 */
1519int
1520secpolicy_sys_config(const cred_t *cr, boolean_t checkonly)
1521{
1522	if (checkonly) {
1523		return (PRIV_POLICY_ONLY(cr, PRIV_SYS_CONFIG, B_FALSE) ? 0 :
1524		    EPERM);
1525	} else {
1526		return (PRIV_POLICY(cr, PRIV_SYS_CONFIG, B_FALSE, EPERM, NULL));
1527	}
1528}
1529
1530/*
1531 * Zone administration (halt, reboot, etc.) from within zone.
1532 */
1533int
1534secpolicy_zone_admin(const cred_t *cr, boolean_t checkonly)
1535{
1536	if (checkonly) {
1537		return (PRIV_POLICY_ONLY(cr, PRIV_SYS_ADMIN, B_FALSE) ? 0 :
1538		    EPERM);
1539	} else {
1540		return (PRIV_POLICY(cr, PRIV_SYS_ADMIN, B_FALSE, EPERM,
1541		    NULL));
1542	}
1543}
1544
1545/*
1546 * Zone configuration (create, halt, enter).
1547 */
1548int
1549secpolicy_zone_config(const cred_t *cr)
1550{
1551	/*
1552	 * Require all privileges to avoid possibility of privilege
1553	 * escalation.
1554	 */
1555	return (secpolicy_require_set(cr, PRIV_FULLSET, NULL));
1556}
1557
1558/*
1559 * Various other system configuration calls
1560 */
1561int
1562secpolicy_coreadm(const cred_t *cr)
1563{
1564	return (PRIV_POLICY(cr, PRIV_SYS_ADMIN, B_FALSE, EPERM, NULL));
1565}
1566
1567int
1568secpolicy_systeminfo(const cred_t *cr)
1569{
1570	return (PRIV_POLICY(cr, PRIV_SYS_ADMIN, B_FALSE, EPERM, NULL));
1571}
1572
1573int
1574secpolicy_dispadm(const cred_t *cr)
1575{
1576	return (PRIV_POLICY(cr, PRIV_SYS_CONFIG, B_FALSE, EPERM, NULL));
1577}
1578
1579int
1580secpolicy_settime(const cred_t *cr)
1581{
1582	return (PRIV_POLICY(cr, PRIV_SYS_TIME, B_FALSE, EPERM, NULL));
1583}
1584
1585/*
1586 * For realtime users: high resolution clock.
1587 */
1588int
1589secpolicy_clock_highres(const cred_t *cr)
1590{
1591	return (PRIV_POLICY(cr, PRIV_PROC_CLOCK_HIGHRES, B_FALSE, EPERM,
1592	    NULL));
1593}
1594
1595/*
1596 * drv_priv() is documented as callable from interrupt context, not that
1597 * anyone ever does, but still.  No debugging or auditing can be done when
1598 * it is called from interrupt context.
1599 * returns 0 on succes, EPERM on failure.
1600 */
1601int
1602drv_priv(cred_t *cr)
1603{
1604	return (PRIV_POLICY(cr, PRIV_SYS_DEVICES, B_FALSE, EPERM, NULL));
1605}
1606
1607int
1608secpolicy_sys_devices(const cred_t *cr)
1609{
1610	return (PRIV_POLICY(cr, PRIV_SYS_DEVICES, B_FALSE, EPERM, NULL));
1611}
1612
1613int
1614secpolicy_excl_open(const cred_t *cr)
1615{
1616	return (PRIV_POLICY(cr, PRIV_SYS_DEVICES, B_FALSE, EBUSY, NULL));
1617}
1618
1619int
1620secpolicy_rctlsys(const cred_t *cr, boolean_t is_zone_rctl)
1621{
1622	/* zone.* rctls can only be set from the global zone */
1623	if (is_zone_rctl && priv_policy_global(cr) != 0)
1624		return (EPERM);
1625	return (PRIV_POLICY(cr, PRIV_SYS_RESOURCE, B_FALSE, EPERM, NULL));
1626}
1627
1628int
1629secpolicy_resource(const cred_t *cr)
1630{
1631	return (PRIV_POLICY(cr, PRIV_SYS_RESOURCE, B_FALSE, EPERM, NULL));
1632}
1633
1634/*
1635 * Processes with a real uid of 0 escape any form of accounting, much
1636 * like before.
1637 */
1638int
1639secpolicy_newproc(const cred_t *cr)
1640{
1641	if (cr->cr_ruid == 0)
1642		return (0);
1643
1644	return (PRIV_POLICY(cr, PRIV_SYS_RESOURCE, B_FALSE, EPERM, NULL));
1645}
1646
1647/*
1648 * Networking
1649 */
1650int
1651secpolicy_net_rawaccess(const cred_t *cr)
1652{
1653	return (PRIV_POLICY(cr, PRIV_NET_RAWACCESS, B_FALSE, EACCES, NULL));
1654}
1655
1656/*
1657 * Need this privilege for accessing the ICMP device
1658 */
1659int
1660secpolicy_net_icmpaccess(const cred_t *cr)
1661{
1662	return (PRIV_POLICY(cr, PRIV_NET_ICMPACCESS, B_FALSE, EACCES, NULL));
1663}
1664
1665/*
1666 * There are a few rare cases where the kernel generates ioctls() from
1667 * interrupt context with a credential of kcred rather than NULL.
1668 * In those cases, we take the safe and cheap test.
1669 */
1670int
1671secpolicy_net_config(const cred_t *cr, boolean_t checkonly)
1672{
1673	if (checkonly) {
1674		return (PRIV_POLICY_ONLY(cr, PRIV_SYS_NET_CONFIG, B_FALSE) ?
1675		    0 : EPERM);
1676	} else {
1677		return (PRIV_POLICY(cr, PRIV_SYS_NET_CONFIG, B_FALSE, EPERM,
1678		    NULL));
1679	}
1680}
1681
1682
1683/*
1684 * PRIV_SYS_NET_CONFIG is a superset of PRIV_SYS_IP_CONFIG.
1685 *
1686 * There are a few rare cases where the kernel generates ioctls() from
1687 * interrupt context with a credential of kcred rather than NULL.
1688 * In those cases, we take the safe and cheap test.
1689 */
1690int
1691secpolicy_ip_config(const cred_t *cr, boolean_t checkonly)
1692{
1693	if (PRIV_POLICY_ONLY(cr, PRIV_SYS_NET_CONFIG, B_FALSE))
1694		return (secpolicy_net_config(cr, checkonly));
1695
1696	if (checkonly) {
1697		return (PRIV_POLICY_ONLY(cr, PRIV_SYS_IP_CONFIG, B_FALSE) ?
1698		    0 : EPERM);
1699	} else {
1700		return (PRIV_POLICY(cr, PRIV_SYS_IP_CONFIG, B_FALSE, EPERM,
1701		    NULL));
1702	}
1703}
1704
1705
1706/*
1707 * Map IP pseudo privileges to actual privileges.
1708 * So we don't need to recompile IP when we change the privileges.
1709 */
1710int
1711secpolicy_ip(const cred_t *cr, int netpriv, boolean_t checkonly)
1712{
1713	int priv = PRIV_ALL;
1714
1715	switch (netpriv) {
1716	case OP_CONFIG:
1717		priv = PRIV_SYS_IP_CONFIG;
1718		break;
1719	case OP_RAW:
1720		priv = PRIV_NET_RAWACCESS;
1721		break;
1722	case OP_PRIVPORT:
1723		priv = PRIV_NET_PRIVADDR;
1724		break;
1725	}
1726	ASSERT(priv != PRIV_ALL);
1727	if (checkonly)
1728		return (PRIV_POLICY_ONLY(cr, priv, B_FALSE) ? 0 : EPERM);
1729	else
1730		return (PRIV_POLICY(cr, priv, B_FALSE, EPERM, NULL));
1731}
1732
1733/*
1734 * Map network pseudo privileges to actual privileges.
1735 * So we don't need to recompile IP when we change the privileges.
1736 */
1737int
1738secpolicy_net(const cred_t *cr, int netpriv, boolean_t checkonly)
1739{
1740	int priv = PRIV_ALL;
1741
1742	switch (netpriv) {
1743	case OP_CONFIG:
1744		priv = PRIV_SYS_NET_CONFIG;
1745		break;
1746	case OP_RAW:
1747		priv = PRIV_NET_RAWACCESS;
1748		break;
1749	case OP_PRIVPORT:
1750		priv = PRIV_NET_PRIVADDR;
1751		break;
1752	}
1753	ASSERT(priv != PRIV_ALL);
1754	if (checkonly)
1755		return (PRIV_POLICY_ONLY(cr, priv, B_FALSE) ? 0 : EPERM);
1756	else
1757		return (PRIV_POLICY(cr, priv, B_FALSE, EPERM, NULL));
1758}
1759
1760/*
1761 * Checks for operations that are either client-only or are used by
1762 * both clients and servers.
1763 */
1764int
1765secpolicy_nfs(const cred_t *cr)
1766{
1767	return (PRIV_POLICY(cr, PRIV_SYS_NFS, B_FALSE, EPERM, NULL));
1768}
1769
1770/*
1771 * Special case for opening rpcmod: have NFS privileges or network
1772 * config privileges.
1773 */
1774int
1775secpolicy_rpcmod_open(const cred_t *cr)
1776{
1777	if (PRIV_POLICY_ONLY(cr, PRIV_SYS_NFS, B_FALSE))
1778		return (secpolicy_nfs(cr));
1779	else
1780		return (secpolicy_net_config(cr, NULL));
1781}
1782
1783int
1784secpolicy_chroot(const cred_t *cr)
1785{
1786	return (PRIV_POLICY(cr, PRIV_PROC_CHROOT, B_FALSE, EPERM, NULL));
1787}
1788
1789int
1790secpolicy_tasksys(const cred_t *cr)
1791{
1792	return (PRIV_POLICY(cr, PRIV_PROC_TASKID, B_FALSE, EPERM, NULL));
1793}
1794
1795/*
1796 * Basic privilege checks.
1797 */
1798int
1799secpolicy_basic_exec(const cred_t *cr, vnode_t *vp)
1800{
1801	return (priv_policy_va(cr, PRIV_PROC_EXEC, B_FALSE, EPERM, NULL,
1802	    KLPDARG_VNODE, vp, (char *)NULL, KLPDARG_NOMORE));
1803}
1804
1805int
1806secpolicy_basic_fork(const cred_t *cr)
1807{
1808	return (PRIV_POLICY(cr, PRIV_PROC_FORK, B_FALSE, EPERM, NULL));
1809}
1810
1811int
1812secpolicy_basic_proc(const cred_t *cr)
1813{
1814	return (PRIV_POLICY(cr, PRIV_PROC_SESSION, B_FALSE, EPERM, NULL));
1815}
1816
1817/*
1818 * Slightly complicated because we don't want to trigger the policy too
1819 * often.  First we shortcircuit access to "self" (tp == sp) or if
1820 * we don't have the privilege but if we have permission
1821 * just return (0) and we don't flag the privilege as needed.
1822 * Else, we test for the privilege because we either have it or need it.
1823 */
1824int
1825secpolicy_basic_procinfo(const cred_t *cr, proc_t *tp, proc_t *sp)
1826{
1827	if (tp == sp ||
1828	    !HAS_PRIVILEGE(cr, PRIV_PROC_INFO) && prochasprocperm(tp, sp, cr)) {
1829		return (0);
1830	} else {
1831		return (PRIV_POLICY(cr, PRIV_PROC_INFO, B_FALSE, EPERM, NULL));
1832	}
1833}
1834
1835int
1836secpolicy_basic_link(const cred_t *cr)
1837{
1838	return (PRIV_POLICY(cr, PRIV_FILE_LINK_ANY, B_FALSE, EPERM, NULL));
1839}
1840
1841/*
1842 * Additional device protection.
1843 *
1844 * Traditionally, a device has specific permissions on the node in
1845 * the filesystem which govern which devices can be opened by what
1846 * processes.  In certain cases, it is desirable to add extra
1847 * restrictions, as writing to certain devices is identical to
1848 * having a complete run of the system.
1849 *
1850 * This mechanism is called the device policy.
1851 *
1852 * When a device is opened, its policy entry is looked up in the
1853 * policy cache and checked.
1854 */
1855int
1856secpolicy_spec_open(const cred_t *cr, struct vnode *vp, int oflag)
1857{
1858	devplcy_t *plcy;
1859	int err;
1860	struct snode *csp = VTOS(common_specvp(vp));
1861	priv_set_t pset;
1862
1863	mutex_enter(&csp->s_lock);
1864
1865	if (csp->s_plcy == NULL || csp->s_plcy->dp_gen != devplcy_gen) {
1866		plcy = devpolicy_find(vp);
1867		if (csp->s_plcy)
1868			dpfree(csp->s_plcy);
1869		csp->s_plcy = plcy;
1870		ASSERT(plcy != NULL);
1871	} else
1872		plcy = csp->s_plcy;
1873
1874	if (plcy == nullpolicy) {
1875		mutex_exit(&csp->s_lock);
1876		return (0);
1877	}
1878
1879	dphold(plcy);
1880
1881	mutex_exit(&csp->s_lock);
1882
1883	if (oflag & FWRITE)
1884		pset = plcy->dp_wrp;
1885	else
1886		pset = plcy->dp_rdp;
1887	/*
1888	 * Special case:
1889	 * PRIV_SYS_NET_CONFIG is a superset of PRIV_SYS_IP_CONFIG.
1890	 * If PRIV_SYS_NET_CONFIG is present and PRIV_SYS_IP_CONFIG is
1891	 * required, replace PRIV_SYS_IP_CONFIG with PRIV_SYS_NET_CONFIG
1892	 * in the required privilege set before doing the check.
1893	 */
1894	if (priv_ismember(&pset, PRIV_SYS_IP_CONFIG) &&
1895	    priv_ismember(&CR_OEPRIV(cr), PRIV_SYS_NET_CONFIG) &&
1896	    !priv_ismember(&CR_OEPRIV(cr), PRIV_SYS_IP_CONFIG)) {
1897		priv_delset(&pset, PRIV_SYS_IP_CONFIG);
1898		priv_addset(&pset, PRIV_SYS_NET_CONFIG);
1899	}
1900
1901	err = secpolicy_require_set(cr, &pset, "devpolicy");
1902	dpfree(plcy);
1903
1904	return (err);
1905}
1906
1907int
1908secpolicy_modctl(const cred_t *cr, int cmd)
1909{
1910	switch (cmd) {
1911	case MODINFO:
1912	case MODGETMAJBIND:
1913	case MODGETPATH:
1914	case MODGETPATHLEN:
1915	case MODGETNAME:
1916	case MODGETFBNAME:
1917	case MODGETDEVPOLICY:
1918	case MODGETDEVPOLICYBYNAME:
1919	case MODDEVT2INSTANCE:
1920	case MODSIZEOF_DEVID:
1921	case MODGETDEVID:
1922	case MODSIZEOF_MINORNAME:
1923	case MODGETMINORNAME:
1924	case MODGETDEVFSPATH_LEN:
1925	case MODGETDEVFSPATH:
1926	case MODGETDEVFSPATH_MI_LEN:
1927	case MODGETDEVFSPATH_MI:
1928		/* Unprivileged */
1929		return (0);
1930	case MODLOAD:
1931	case MODSETDEVPOLICY:
1932		return (secpolicy_require_set(cr, PRIV_FULLSET, NULL));
1933	default:
1934		return (secpolicy_sys_config(cr, B_FALSE));
1935	}
1936}
1937
1938int
1939secpolicy_console(const cred_t *cr)
1940{
1941	return (PRIV_POLICY(cr, PRIV_SYS_DEVICES, B_FALSE, EPERM, NULL));
1942}
1943
1944int
1945secpolicy_power_mgmt(const cred_t *cr)
1946{
1947	return (PRIV_POLICY(cr, PRIV_SYS_DEVICES, B_FALSE, EPERM, NULL));
1948}
1949
1950/*
1951 * Simulate terminal input; another escalation of privileges avenue.
1952 */
1953
1954int
1955secpolicy_sti(const cred_t *cr)
1956{
1957	return (secpolicy_require_set(cr, PRIV_FULLSET, NULL));
1958}
1959
1960boolean_t
1961secpolicy_net_reply_equal(const cred_t *cr)
1962{
1963	return (PRIV_POLICY(cr, PRIV_SYS_CONFIG, B_FALSE, EPERM, NULL));
1964}
1965
1966int
1967secpolicy_swapctl(const cred_t *cr)
1968{
1969	return (PRIV_POLICY(cr, PRIV_SYS_CONFIG, B_FALSE, EPERM, NULL));
1970}
1971
1972int
1973secpolicy_cpc_cpu(const cred_t *cr)
1974{
1975	return (PRIV_POLICY(cr, PRIV_CPC_CPU, B_FALSE, EACCES, NULL));
1976}
1977
1978/*
1979 * secpolicy_contract_identity
1980 *
1981 * Determine if the subject may set the process contract FMRI value
1982 */
1983int
1984secpolicy_contract_identity(const cred_t *cr)
1985{
1986	return (PRIV_POLICY(cr, PRIV_CONTRACT_IDENTITY, B_FALSE, EPERM, NULL));
1987}
1988
1989/*
1990 * secpolicy_contract_observer
1991 *
1992 * Determine if the subject may observe a specific contract's events.
1993 */
1994int
1995secpolicy_contract_observer(const cred_t *cr, struct contract *ct)
1996{
1997	if (contract_owned(ct, cr, B_FALSE))
1998		return (0);
1999	return (PRIV_POLICY(cr, PRIV_CONTRACT_OBSERVER, B_FALSE, EPERM, NULL));
2000}
2001
2002/*
2003 * secpolicy_contract_observer_choice
2004 *
2005 * Determine if the subject may observe any contract's events.  Just
2006 * tests privilege and audits on success.
2007 */
2008boolean_t
2009secpolicy_contract_observer_choice(const cred_t *cr)
2010{
2011	return (PRIV_POLICY_CHOICE(cr, PRIV_CONTRACT_OBSERVER, B_FALSE));
2012}
2013
2014/*
2015 * secpolicy_contract_event
2016 *
2017 * Determine if the subject may request critical contract events or
2018 * reliable contract event delivery.
2019 */
2020int
2021secpolicy_contract_event(const cred_t *cr)
2022{
2023	return (PRIV_POLICY(cr, PRIV_CONTRACT_EVENT, B_FALSE, EPERM, NULL));
2024}
2025
2026/*
2027 * secpolicy_contract_event_choice
2028 *
2029 * Determine if the subject may retain contract events in its critical
2030 * set when a change in other terms would normally require a change in
2031 * the critical set.  Just tests privilege and audits on success.
2032 */
2033boolean_t
2034secpolicy_contract_event_choice(const cred_t *cr)
2035{
2036	return (PRIV_POLICY_CHOICE(cr, PRIV_CONTRACT_EVENT, B_FALSE));
2037}
2038
2039/*
2040 * secpolicy_gart_access
2041 *
2042 * Determine if the subject has sufficient priveleges to make ioctls to agpgart
2043 * device.
2044 */
2045int
2046secpolicy_gart_access(const cred_t *cr)
2047{
2048	return (PRIV_POLICY(cr, PRIV_GRAPHICS_ACCESS, B_FALSE, EPERM, NULL));
2049}
2050
2051/*
2052 * secpolicy_gart_map
2053 *
2054 * Determine if the subject has sufficient priveleges to map aperture range
2055 * through agpgart driver.
2056 */
2057int
2058secpolicy_gart_map(const cred_t *cr)
2059{
2060	if (PRIV_POLICY_ONLY(cr, PRIV_GRAPHICS_ACCESS, B_FALSE)) {
2061		return (PRIV_POLICY(cr, PRIV_GRAPHICS_ACCESS, B_FALSE, EPERM,
2062		    NULL));
2063	} else {
2064		return (PRIV_POLICY(cr, PRIV_GRAPHICS_MAP, B_FALSE, EPERM,
2065		    NULL));
2066	}
2067}
2068
2069/*
2070 * secpolicy_zinject
2071 *
2072 * Determine if the subject can inject faults in the ZFS fault injection
2073 * framework.  Requires all privileges.
2074 */
2075int
2076secpolicy_zinject(const cred_t *cr)
2077{
2078	return (secpolicy_require_set(cr, PRIV_FULLSET, NULL));
2079}
2080
2081/*
2082 * secpolicy_zfs
2083 *
2084 * Determine if the subject has permission to manipulate ZFS datasets
2085 * (not pools).  Equivalent to the SYS_MOUNT privilege.
2086 */
2087int
2088secpolicy_zfs(const cred_t *cr)
2089{
2090	return (PRIV_POLICY(cr, PRIV_SYS_MOUNT, B_FALSE, EPERM, NULL));
2091}
2092
2093/*
2094 * secpolicy_idmap
2095 *
2096 * Determine if the calling process has permissions to register an SID
2097 * mapping daemon and allocate ephemeral IDs.
2098 */
2099int
2100secpolicy_idmap(const cred_t *cr)
2101{
2102	return (PRIV_POLICY(cr, PRIV_FILE_SETID, B_TRUE, EPERM, NULL));
2103}
2104
2105/*
2106 * secpolicy_ucode_update
2107 *
2108 * Determine if the subject has sufficient privilege to update microcode.
2109 */
2110int
2111secpolicy_ucode_update(const cred_t *scr)
2112{
2113	return (PRIV_POLICY(scr, PRIV_ALL, B_FALSE, EPERM, NULL));
2114}
2115
2116/*
2117 * secpolicy_sadopen
2118 *
2119 * Determine if the subject has sufficient privilege to access /dev/sad/admin.
2120 * /dev/sad/admin appear in global zone and exclusive-IP zones only.
2121 * In global zone, sys_config is required.
2122 * In exclusive-IP zones, sys_ip_config is required.
2123 * Note that sys_config is prohibited in non-global zones.
2124 */
2125int
2126secpolicy_sadopen(const cred_t *credp)
2127{
2128	priv_set_t pset;
2129
2130	priv_emptyset(&pset);
2131
2132	if (crgetzoneid(credp) == GLOBAL_ZONEID)
2133		priv_addset(&pset, PRIV_SYS_CONFIG);
2134	else
2135		priv_addset(&pset, PRIV_SYS_IP_CONFIG);
2136
2137	return (secpolicy_require_set(credp, &pset, "devpolicy"));
2138}
2139
2140
2141/*
2142 * Add privileges to a particular privilege set; this is called when the
2143 * current sets of privileges are not sufficient.  I.e., we should always
2144 * call the policy override functions from here.
2145 * What we are allowed to have is in the Observed Permitted set; so
2146 * we compute the difference between that and the newset.
2147 */
2148int
2149secpolicy_require_privs(const cred_t *cr, const priv_set_t *nset)
2150{
2151	priv_set_t rqd;
2152
2153	rqd = CR_OPPRIV(cr);
2154
2155	priv_inverse(&rqd);
2156	priv_intersect(nset, &rqd);
2157
2158	return (secpolicy_require_set(cr, &rqd, NULL));
2159}
2160
2161/*
2162 * secpolicy_smb
2163 *
2164 * Determine if the cred_t has PRIV_SYS_SMB privilege, indicating
2165 * that it has permission to access the smbsrv kernel driver.
2166 * PRIV_POLICY checks the privilege and audits the check.
2167 *
2168 * Returns:
2169 * 0       Driver access is allowed.
2170 * EPERM   Driver access is NOT permitted.
2171 */
2172int
2173secpolicy_smb(const cred_t *cr)
2174{
2175	return (PRIV_POLICY(cr, PRIV_SYS_SMB, B_FALSE, EPERM, NULL));
2176}
2177
2178/*
2179 * secpolicy_vscan
2180 *
2181 * Determine if cred_t has the necessary privileges to access a file
2182 * for virus scanning and update its extended system attributes.
2183 * PRIV_FILE_DAC_SEARCH, PRIV_FILE_DAC_READ - file access
2184 * PRIV_FILE_FLAG_SET - set extended system attributes
2185 *
2186 * PRIV_POLICY checks the privilege and audits the check.
2187 *
2188 * Returns:
2189 * 0      file access for virus scanning allowed.
2190 * EPERM  file access for virus scanning is NOT permitted.
2191 */
2192int
2193secpolicy_vscan(const cred_t *cr)
2194{
2195	if ((PRIV_POLICY(cr, PRIV_FILE_DAC_SEARCH, B_FALSE, EPERM, NULL)) ||
2196	    (PRIV_POLICY(cr, PRIV_FILE_DAC_READ, B_FALSE, EPERM, NULL)) ||
2197	    (PRIV_POLICY(cr, PRIV_FILE_FLAG_SET, B_FALSE, EPERM, NULL))) {
2198		return (EPERM);
2199	}
2200
2201	return (0);
2202}
2203
2204/*
2205 * secpolicy_smbfs_login
2206 *
2207 * Determines if the caller can add and delete the smbfs login
2208 * password in the the nsmb kernel module for the CIFS client.
2209 *
2210 * Returns:
2211 * 0       access is allowed.
2212 * EPERM   access is NOT allowed.
2213 */
2214int
2215secpolicy_smbfs_login(const cred_t *cr, uid_t uid)
2216{
2217	uid_t cruid = crgetruid(cr);
2218
2219	if (cruid == uid)
2220		return (0);
2221	return (PRIV_POLICY(cr, PRIV_PROC_OWNER, B_FALSE,
2222	    EPERM, NULL));
2223}
2224