xref: /illumos-gate/usr/src/uts/common/c2/audit.c (revision 7d10cd4d)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
545916cd2Sjpk  * Common Development and Distribution License (the "License").
645916cd2Sjpk  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
21794f0adbSRoger A. Faulkner 
227c478bd9Sstevel@tonic-gate /*
23134a1f4eSCasper H.S. Dik  * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate /*
277c478bd9Sstevel@tonic-gate  * This file contains the audit hook support code for auditing.
287c478bd9Sstevel@tonic-gate  */
297c478bd9Sstevel@tonic-gate 
307c478bd9Sstevel@tonic-gate #include <sys/types.h>
317c478bd9Sstevel@tonic-gate #include <sys/proc.h>
327c478bd9Sstevel@tonic-gate #include <sys/vnode.h>
337c478bd9Sstevel@tonic-gate #include <sys/vfs.h>
347c478bd9Sstevel@tonic-gate #include <sys/file.h>
357c478bd9Sstevel@tonic-gate #include <sys/user.h>
367c478bd9Sstevel@tonic-gate #include <sys/stropts.h>
377c478bd9Sstevel@tonic-gate #include <sys/systm.h>
387c478bd9Sstevel@tonic-gate #include <sys/pathname.h>
397c478bd9Sstevel@tonic-gate #include <sys/syscall.h>
407c478bd9Sstevel@tonic-gate #include <sys/fcntl.h>
417c478bd9Sstevel@tonic-gate #include <sys/ipc_impl.h>
427c478bd9Sstevel@tonic-gate #include <sys/msg_impl.h>
437c478bd9Sstevel@tonic-gate #include <sys/sem_impl.h>
447c478bd9Sstevel@tonic-gate #include <sys/shm_impl.h>
457c478bd9Sstevel@tonic-gate #include <sys/kmem.h>		/* for KM_SLEEP */
467c478bd9Sstevel@tonic-gate #include <sys/socket.h>
477c478bd9Sstevel@tonic-gate #include <sys/cmn_err.h>	/* snprintf... */
487c478bd9Sstevel@tonic-gate #include <sys/debug.h>
497c478bd9Sstevel@tonic-gate #include <sys/thread.h>
507c478bd9Sstevel@tonic-gate #include <netinet/in.h>
517c478bd9Sstevel@tonic-gate #include <c2/audit.h>		/* needs to be included before user.h */
527c478bd9Sstevel@tonic-gate #include <c2/audit_kernel.h>	/* for M_DONTWAIT */
537c478bd9Sstevel@tonic-gate #include <c2/audit_kevents.h>
547c478bd9Sstevel@tonic-gate #include <c2/audit_record.h>
557c478bd9Sstevel@tonic-gate #include <sys/strsubr.h>
567c478bd9Sstevel@tonic-gate #include <sys/tihdr.h>
577c478bd9Sstevel@tonic-gate #include <sys/tiuser.h>
587c478bd9Sstevel@tonic-gate #include <sys/timod.h>
597c478bd9Sstevel@tonic-gate #include <sys/model.h>		/* for model_t */
607c478bd9Sstevel@tonic-gate #include <sys/disp.h>		/* for servicing_interrupt() */
617c478bd9Sstevel@tonic-gate #include <sys/devpolicy.h>
627c478bd9Sstevel@tonic-gate #include <sys/crypto/ioctladmin.h>
63134a1f4eSCasper H.S. Dik #include <sys/cred_impl.h>
64799bd290Spwernau #include <net/pfpolicy.h>
657c478bd9Sstevel@tonic-gate 
667c478bd9Sstevel@tonic-gate static void add_return_token(caddr_t *, unsigned int scid, int err, int rval);
677c478bd9Sstevel@tonic-gate 
687c478bd9Sstevel@tonic-gate static void audit_pathbuild(struct pathname *pnp);
697c478bd9Sstevel@tonic-gate 
707c478bd9Sstevel@tonic-gate 
717c478bd9Sstevel@tonic-gate /*
727c478bd9Sstevel@tonic-gate  * ROUTINE:	AUDIT_SAVEPATH
737c478bd9Sstevel@tonic-gate  * PURPOSE:
747c478bd9Sstevel@tonic-gate  * CALLBY:	LOOKUPPN
757c478bd9Sstevel@tonic-gate  *
767c478bd9Sstevel@tonic-gate  * NOTE:	We have reached the end of a path in fs/lookup.c.
777c478bd9Sstevel@tonic-gate  *		We get two pieces of information here:
787c478bd9Sstevel@tonic-gate  *		the vnode of the last component (vp) and
797c478bd9Sstevel@tonic-gate  *		the status of the last access (flag).
807c478bd9Sstevel@tonic-gate  * TODO:
817c478bd9Sstevel@tonic-gate  * QUESTION:
827c478bd9Sstevel@tonic-gate  */
837c478bd9Sstevel@tonic-gate 
847c478bd9Sstevel@tonic-gate /*ARGSUSED*/
857c478bd9Sstevel@tonic-gate int
audit_savepath(struct pathname * pnp,struct vnode * vp,struct vnode * pvp,int flag,cred_t * cr)867c478bd9Sstevel@tonic-gate audit_savepath(
877c478bd9Sstevel@tonic-gate 	struct pathname *pnp,		/* pathname to lookup */
887c478bd9Sstevel@tonic-gate 	struct vnode *vp,		/* vnode of the last component */
894a0fa546SMarek Pospisil 	struct vnode *pvp,		/* vnode of the last parent component */
907c478bd9Sstevel@tonic-gate 	int    flag,			/* status of the last access */
917c478bd9Sstevel@tonic-gate 	cred_t *cr)			/* cred of requestor */
927c478bd9Sstevel@tonic-gate {
937c478bd9Sstevel@tonic-gate 
947c478bd9Sstevel@tonic-gate 	t_audit_data_t *tad;	/* current thread */
959e9e6ab8Spaulson 	au_kcontext_t	*kctx = GET_KCTX_PZ;
967c478bd9Sstevel@tonic-gate 
977c478bd9Sstevel@tonic-gate 	tad = U2A(u);
987c478bd9Sstevel@tonic-gate 
994a0fa546SMarek Pospisil 	/*
1004a0fa546SMarek Pospisil 	 * Noise elimination in audit trails - this event will be discarded if:
1014a0fa546SMarek Pospisil 	 * - the public policy is not active AND
1024a0fa546SMarek Pospisil 	 * - the system call is a public operation AND
1034a0fa546SMarek Pospisil 	 * - the file was not found: VFS lookup failed with ENOENT error AND
1044a0fa546SMarek Pospisil 	 * - the missing file would have been located in the public directory
1054a0fa546SMarek Pospisil 	 *   owned by root if it had existed
1064a0fa546SMarek Pospisil 	 */
1074a0fa546SMarek Pospisil 	if (tad->tad_flag != 0 && flag == ENOENT && pvp != NULL &&
1084a0fa546SMarek Pospisil 	    (tad->tad_ctrl & TAD_PUBLIC_EV) &&
1094a0fa546SMarek Pospisil 	    !(kctx->auk_policy & AUDIT_PUBLIC)) {
1104a0fa546SMarek Pospisil 		struct vattr attr;
1114a0fa546SMarek Pospisil 
1124a0fa546SMarek Pospisil 		attr.va_mask = AT_ALL;
1134a0fa546SMarek Pospisil 		if (VOP_GETATTR(pvp, &attr, 0, CRED(), NULL) == 0) {
1144a0fa546SMarek Pospisil 			if (object_is_public(&attr)) {
1154a0fa546SMarek Pospisil 				tad->tad_ctrl |= TAD_NOAUDIT;
1164a0fa546SMarek Pospisil 			}
1174a0fa546SMarek Pospisil 		}
1184a0fa546SMarek Pospisil 	}
1194a0fa546SMarek Pospisil 
1207c478bd9Sstevel@tonic-gate 	/*
1217c478bd9Sstevel@tonic-gate 	 * this event being audited or do we need path information
1227c478bd9Sstevel@tonic-gate 	 * later? This might be for a chdir/chroot or open (add path
1237c478bd9Sstevel@tonic-gate 	 * to file pointer. If the path has already been found for an
1247c478bd9Sstevel@tonic-gate 	 * open/creat then we don't need to process the path.
1257c478bd9Sstevel@tonic-gate 	 *
1264a0fa546SMarek Pospisil 	 * S2E_SP (TAD_SAVPATH) flag comes from audit_s2e[].au_ctrl. Used with
1277c478bd9Sstevel@tonic-gate 	 *	chroot, chdir, open, creat system call processing. It determines
1287c478bd9Sstevel@tonic-gate 	 *	if audit_savepath() will discard the path or we need it later.
1294a0fa546SMarek Pospisil 	 * TAD_PATHFND means path already included in this audit record. It
1307c478bd9Sstevel@tonic-gate 	 *	is used in cases where multiple path lookups are done per
1317c478bd9Sstevel@tonic-gate 	 *	system call. The policy flag, AUDIT_PATH, controls if multiple
1327c478bd9Sstevel@tonic-gate 	 *	paths are allowed.
1334a0fa546SMarek Pospisil 	 * S2E_NPT (TAD_NOPATH) flag comes from audit_s2e[].au_ctrl. Used with
1347c478bd9Sstevel@tonic-gate 	 *	exit processing to inhibit any paths that may be added due to
1357c478bd9Sstevel@tonic-gate 	 *	closes.
1367c478bd9Sstevel@tonic-gate 	 */
1374a0fa546SMarek Pospisil 	if ((tad->tad_flag == 0 && !(tad->tad_ctrl & TAD_SAVPATH)) ||
1384a0fa546SMarek Pospisil 	    ((tad->tad_ctrl & TAD_PATHFND) &&
13951d48dedSMarek Pospisil 	    !(kctx->auk_policy & AUDIT_PATH)) ||
1404a0fa546SMarek Pospisil 	    (tad->tad_ctrl & TAD_NOPATH)) {
14151d48dedSMarek Pospisil 		return (0);
1427c478bd9Sstevel@tonic-gate 	}
1437c478bd9Sstevel@tonic-gate 
1444a0fa546SMarek Pospisil 	tad->tad_ctrl |= TAD_NOPATH;		/* prevent possible reentry */
14545916cd2Sjpk 
1467c478bd9Sstevel@tonic-gate 	audit_pathbuild(pnp);
1477c478bd9Sstevel@tonic-gate 
1487c478bd9Sstevel@tonic-gate 	/*
1497c478bd9Sstevel@tonic-gate 	 * are we auditing only if error, or if it is not open or create
1507c478bd9Sstevel@tonic-gate 	 * otherwise audit_setf will do it
1517c478bd9Sstevel@tonic-gate 	 */
1527c478bd9Sstevel@tonic-gate 
1537c478bd9Sstevel@tonic-gate 	if (tad->tad_flag) {
1548fd04b83SRoger A. Faulkner 		if (flag &&
1558fd04b83SRoger A. Faulkner 		    (tad->tad_scid == SYS_open ||
1567c478bd9Sstevel@tonic-gate 		    tad->tad_scid == SYS_open64 ||
1578fd04b83SRoger A. Faulkner 		    tad->tad_scid == SYS_openat ||
1588fd04b83SRoger A. Faulkner 		    tad->tad_scid == SYS_openat64)) {
1594a0fa546SMarek Pospisil 			tad->tad_ctrl |= TAD_TRUE_CREATE;
1607c478bd9Sstevel@tonic-gate 		}
1617c478bd9Sstevel@tonic-gate 
1627c478bd9Sstevel@tonic-gate 		/* add token to audit record for this name */
1637c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_path(tad->tad_aupath));
1647c478bd9Sstevel@tonic-gate 
1657c478bd9Sstevel@tonic-gate 		/* add the attributes of the object */
1667c478bd9Sstevel@tonic-gate 		if (vp) {
1677c478bd9Sstevel@tonic-gate 			/*
1687c478bd9Sstevel@tonic-gate 			 * only capture attributes when there is no error
1697c478bd9Sstevel@tonic-gate 			 * lookup will not return the vnode of the failing
1707c478bd9Sstevel@tonic-gate 			 * component.
1717c478bd9Sstevel@tonic-gate 			 *
1727c478bd9Sstevel@tonic-gate 			 * if there was a lookup error, then don't add
1737c478bd9Sstevel@tonic-gate 			 * attribute. if lookup in vn_create(),
1747c478bd9Sstevel@tonic-gate 			 * then don't add attribute,
1757c478bd9Sstevel@tonic-gate 			 * it will be added at end of vn_create().
1767c478bd9Sstevel@tonic-gate 			 */
1774a0fa546SMarek Pospisil 			if (!flag && !(tad->tad_ctrl & TAD_NOATTRB))
1787c478bd9Sstevel@tonic-gate 				audit_attributes(vp);
1797c478bd9Sstevel@tonic-gate 		}
1807c478bd9Sstevel@tonic-gate 	}
1817c478bd9Sstevel@tonic-gate 
1828fd04b83SRoger A. Faulkner 	/* free up space if we're not going to save path (open, creat) */
1834a0fa546SMarek Pospisil 	if ((tad->tad_ctrl & TAD_SAVPATH) == 0) {
1847c478bd9Sstevel@tonic-gate 		if (tad->tad_aupath != NULL) {
1857c478bd9Sstevel@tonic-gate 			au_pathrele(tad->tad_aupath);
1867c478bd9Sstevel@tonic-gate 			tad->tad_aupath = NULL;
1877c478bd9Sstevel@tonic-gate 		}
1887c478bd9Sstevel@tonic-gate 	}
1894a0fa546SMarek Pospisil 	if (tad->tad_ctrl & TAD_MLD)
1904a0fa546SMarek Pospisil 		tad->tad_ctrl |= TAD_PATHFND;
1917c478bd9Sstevel@tonic-gate 
1924a0fa546SMarek Pospisil 	tad->tad_ctrl &= ~TAD_NOPATH;		/* restore */
1937c478bd9Sstevel@tonic-gate 	return (0);
1947c478bd9Sstevel@tonic-gate }
1957c478bd9Sstevel@tonic-gate 
1967c478bd9Sstevel@tonic-gate static void
audit_pathbuild(struct pathname * pnp)1977c478bd9Sstevel@tonic-gate audit_pathbuild(struct pathname *pnp)
1987c478bd9Sstevel@tonic-gate {
1997c478bd9Sstevel@tonic-gate 	char *pp;	/* pointer to path */
2007c478bd9Sstevel@tonic-gate 	int len;	/* length of incoming segment */
2017c478bd9Sstevel@tonic-gate 	int newsect;	/* path requires a new section */
2027c478bd9Sstevel@tonic-gate 	struct audit_path	*pfxapp;	/* prefix for path */
2037c478bd9Sstevel@tonic-gate 	struct audit_path	*newapp;	/* new audit_path */
2047c478bd9Sstevel@tonic-gate 	t_audit_data_t *tad;	/* current thread */
2057c478bd9Sstevel@tonic-gate 	p_audit_data_t *pad;	/* current process */
2067c478bd9Sstevel@tonic-gate 
2077c478bd9Sstevel@tonic-gate 	tad = U2A(u);
2087c478bd9Sstevel@tonic-gate 	ASSERT(tad != NULL);
2097c478bd9Sstevel@tonic-gate 	pad = P2A(curproc);
2107c478bd9Sstevel@tonic-gate 	ASSERT(pad != NULL);
2117c478bd9Sstevel@tonic-gate 
2127c478bd9Sstevel@tonic-gate 	len = (pnp->pn_path - pnp->pn_buf) + 1;		/* +1 for terminator */
2137c478bd9Sstevel@tonic-gate 	ASSERT(len > 0);
2147c478bd9Sstevel@tonic-gate 
2157c478bd9Sstevel@tonic-gate 	/* adjust for path prefix: tad_aupath, ATPATH, CRD, or CWD */
2167c478bd9Sstevel@tonic-gate 	mutex_enter(&pad->pad_lock);
2177c478bd9Sstevel@tonic-gate 	if (tad->tad_aupath != NULL) {
2187c478bd9Sstevel@tonic-gate 		pfxapp = tad->tad_aupath;
2194a0fa546SMarek Pospisil 	} else if ((tad->tad_ctrl & TAD_ATCALL) && pnp->pn_buf[0] != '/') {
2207c478bd9Sstevel@tonic-gate 		ASSERT(tad->tad_atpath != NULL);
2217c478bd9Sstevel@tonic-gate 		pfxapp = tad->tad_atpath;
2224a0fa546SMarek Pospisil 	} else if (tad->tad_ctrl & TAD_ABSPATH) {
2237c478bd9Sstevel@tonic-gate 		pfxapp = pad->pad_root;
2247c478bd9Sstevel@tonic-gate 	} else {
2257c478bd9Sstevel@tonic-gate 		pfxapp = pad->pad_cwd;
2267c478bd9Sstevel@tonic-gate 	}
2277c478bd9Sstevel@tonic-gate 	au_pathhold(pfxapp);
2287c478bd9Sstevel@tonic-gate 	mutex_exit(&pad->pad_lock);
2297c478bd9Sstevel@tonic-gate 
2307c478bd9Sstevel@tonic-gate 	/* get an expanded buffer to hold the anchored path */
2314a0fa546SMarek Pospisil 	newsect = tad->tad_ctrl & TAD_ATTPATH;
2327c478bd9Sstevel@tonic-gate 	newapp = au_pathdup(pfxapp, newsect, len);
2337c478bd9Sstevel@tonic-gate 	au_pathrele(pfxapp);
2347c478bd9Sstevel@tonic-gate 
2357c478bd9Sstevel@tonic-gate 	pp = newapp->audp_sect[newapp->audp_cnt] - len;
2367c478bd9Sstevel@tonic-gate 	if (!newsect) {
2377c478bd9Sstevel@tonic-gate 		/* overlay previous NUL terminator */
2387c478bd9Sstevel@tonic-gate 		*(pp - 1) = '/';
2397c478bd9Sstevel@tonic-gate 	}
2407c478bd9Sstevel@tonic-gate 
2417c478bd9Sstevel@tonic-gate 	/* now add string of processed path */
2427c478bd9Sstevel@tonic-gate 	bcopy(pnp->pn_buf, pp, len);
2437c478bd9Sstevel@tonic-gate 	pp[len - 1] = '\0';
2447c478bd9Sstevel@tonic-gate 
2457c478bd9Sstevel@tonic-gate 	/* perform path simplification as necessary */
2467c478bd9Sstevel@tonic-gate 	audit_fixpath(newapp, len);
2477c478bd9Sstevel@tonic-gate 
2487c478bd9Sstevel@tonic-gate 	if (tad->tad_aupath)
2497c478bd9Sstevel@tonic-gate 		au_pathrele(tad->tad_aupath);
2507c478bd9Sstevel@tonic-gate 	tad->tad_aupath = newapp;
2517c478bd9Sstevel@tonic-gate 
2527c478bd9Sstevel@tonic-gate 	/* for case where multiple lookups in one syscall (rename) */
2534a0fa546SMarek Pospisil 	tad->tad_ctrl &= ~(TAD_ABSPATH | TAD_ATTPATH);
2547c478bd9Sstevel@tonic-gate }
2557c478bd9Sstevel@tonic-gate 
2567c478bd9Sstevel@tonic-gate 
2577c478bd9Sstevel@tonic-gate /*
2587c478bd9Sstevel@tonic-gate  * ROUTINE:	AUDIT_ANCHORPATH
2597c478bd9Sstevel@tonic-gate  * PURPOSE:
2607c478bd9Sstevel@tonic-gate  * CALLBY:	LOOKUPPN
2617c478bd9Sstevel@tonic-gate  * NOTE:
2627c478bd9Sstevel@tonic-gate  * anchor path at "/". We have seen a symbolic link or entering for the
2637c478bd9Sstevel@tonic-gate  * first time we will throw away any saved path if path is anchored.
2647c478bd9Sstevel@tonic-gate  *
2657c478bd9Sstevel@tonic-gate  * flag = 0, path is relative.
2664a0fa546SMarek Pospisil  * flag = 1, path is absolute. Free any saved path and set flag to TAD_ABSPATH.
2677c478bd9Sstevel@tonic-gate  *
2687c478bd9Sstevel@tonic-gate  * If the (new) path is absolute, then we have to throw away whatever we have
269da6c28aaSamw  * already accumulated since it is being superseded by new path which is
2707c478bd9Sstevel@tonic-gate  * anchored at the root.
2717c478bd9Sstevel@tonic-gate  *		Note that if the path is relative, this function does nothing
2727c478bd9Sstevel@tonic-gate  * TODO:
2737c478bd9Sstevel@tonic-gate  * QUESTION:
2747c478bd9Sstevel@tonic-gate  */
2757c478bd9Sstevel@tonic-gate /*ARGSUSED*/
2767c478bd9Sstevel@tonic-gate void
audit_anchorpath(struct pathname * pnp,int flag)2777c478bd9Sstevel@tonic-gate audit_anchorpath(struct pathname *pnp, int flag)
2787c478bd9Sstevel@tonic-gate {
2799e9e6ab8Spaulson 	au_kcontext_t	*kctx = GET_KCTX_PZ;
2807c478bd9Sstevel@tonic-gate 	t_audit_data_t *tad;
2817c478bd9Sstevel@tonic-gate 
2827c478bd9Sstevel@tonic-gate 	tad = U2A(u);
2837c478bd9Sstevel@tonic-gate 
2847c478bd9Sstevel@tonic-gate 	/*
2857c478bd9Sstevel@tonic-gate 	 * this event being audited or do we need path information
2867c478bd9Sstevel@tonic-gate 	 * later? This might be for a chdir/chroot or open (add path
2877c478bd9Sstevel@tonic-gate 	 * to file pointer. If the path has already been found for an
2887c478bd9Sstevel@tonic-gate 	 * open/creat then we don't need to process the path.
2897c478bd9Sstevel@tonic-gate 	 *
2904a0fa546SMarek Pospisil 	 * S2E_SP (TAD_SAVPATH) flag comes from audit_s2e[].au_ctrl. Used with
2917c478bd9Sstevel@tonic-gate 	 *	chroot, chdir, open, creat system call processing. It determines
2927c478bd9Sstevel@tonic-gate 	 *	if audit_savepath() will discard the path or we need it later.
2934a0fa546SMarek Pospisil 	 * TAD_PATHFND means path already included in this audit record. It
2947c478bd9Sstevel@tonic-gate 	 *	is used in cases where multiple path lookups are done per
2957c478bd9Sstevel@tonic-gate 	 *	system call. The policy flag, AUDIT_PATH, controls if multiple
2967c478bd9Sstevel@tonic-gate 	 *	paths are allowed.
2974a0fa546SMarek Pospisil 	 * S2E_NPT (TAD_NOPATH) flag comes from audit_s2e[].au_ctrl. Used with
2987c478bd9Sstevel@tonic-gate 	 *	exit processing to inhibit any paths that may be added due to
2997c478bd9Sstevel@tonic-gate 	 *	closes.
3007c478bd9Sstevel@tonic-gate 	 */
3014a0fa546SMarek Pospisil 	if ((tad->tad_flag == 0 && !(tad->tad_ctrl & TAD_SAVPATH)) ||
3024a0fa546SMarek Pospisil 	    ((tad->tad_ctrl & TAD_PATHFND) &&
30351d48dedSMarek Pospisil 	    !(kctx->auk_policy & AUDIT_PATH)) ||
3044a0fa546SMarek Pospisil 	    (tad->tad_ctrl & TAD_NOPATH)) {
30551d48dedSMarek Pospisil 		return;
3067c478bd9Sstevel@tonic-gate 	}
3077c478bd9Sstevel@tonic-gate 
3087c478bd9Sstevel@tonic-gate 	if (flag) {
3094a0fa546SMarek Pospisil 		tad->tad_ctrl |= TAD_ABSPATH;
3107c478bd9Sstevel@tonic-gate 		if (tad->tad_aupath != NULL) {
3117c478bd9Sstevel@tonic-gate 			au_pathrele(tad->tad_aupath);
3127c478bd9Sstevel@tonic-gate 			tad->tad_aupath = NULL;
3137c478bd9Sstevel@tonic-gate 		}
3147c478bd9Sstevel@tonic-gate 	}
3157c478bd9Sstevel@tonic-gate }
3167c478bd9Sstevel@tonic-gate 
3177c478bd9Sstevel@tonic-gate 
3187c478bd9Sstevel@tonic-gate /*
3197c478bd9Sstevel@tonic-gate  * symbolic link. Save previous components.
3207c478bd9Sstevel@tonic-gate  *
3217c478bd9Sstevel@tonic-gate  * the path seen so far looks like this
3227c478bd9Sstevel@tonic-gate  *
3237c478bd9Sstevel@tonic-gate  *  +-----------------------+----------------+
3247c478bd9Sstevel@tonic-gate  *  | path processed so far | remaining path |
3257c478bd9Sstevel@tonic-gate  *  +-----------------------+----------------+
3267c478bd9Sstevel@tonic-gate  *  \-----------------------/
3277c478bd9Sstevel@tonic-gate  *	save this string if
3287c478bd9Sstevel@tonic-gate  *	symbolic link relative
3297c478bd9Sstevel@tonic-gate  *	(but don't include  symlink component)
3307c478bd9Sstevel@tonic-gate  */
3317c478bd9Sstevel@tonic-gate 
3327c478bd9Sstevel@tonic-gate /*ARGSUSED*/
3337c478bd9Sstevel@tonic-gate 
3347c478bd9Sstevel@tonic-gate 
3357c478bd9Sstevel@tonic-gate /*
3367c478bd9Sstevel@tonic-gate  * ROUTINE:	AUDIT_SYMLINK
3377c478bd9Sstevel@tonic-gate  * PURPOSE:
3387c478bd9Sstevel@tonic-gate  * CALLBY:	LOOKUPPN
3397c478bd9Sstevel@tonic-gate  * NOTE:
3407c478bd9Sstevel@tonic-gate  * TODO:
3417c478bd9Sstevel@tonic-gate  * QUESTION:
3427c478bd9Sstevel@tonic-gate  */
3437c478bd9Sstevel@tonic-gate void
audit_symlink(struct pathname * pnp,struct pathname * sympath)3447c478bd9Sstevel@tonic-gate audit_symlink(struct pathname *pnp, struct pathname *sympath)
3457c478bd9Sstevel@tonic-gate {
3467c478bd9Sstevel@tonic-gate 	char *sp;	/* saved initial pp */
3477c478bd9Sstevel@tonic-gate 	char *cp;	/* start of symlink path */
3487c478bd9Sstevel@tonic-gate 	uint_t len_path;	/* processed path before symlink */
3497c478bd9Sstevel@tonic-gate 	t_audit_data_t *tad;
3509e9e6ab8Spaulson 	au_kcontext_t	*kctx = GET_KCTX_PZ;
3517c478bd9Sstevel@tonic-gate 
3527c478bd9Sstevel@tonic-gate 	tad = U2A(u);
3537c478bd9Sstevel@tonic-gate 
3547c478bd9Sstevel@tonic-gate 	/*
3557c478bd9Sstevel@tonic-gate 	 * this event being audited or do we need path information
3567c478bd9Sstevel@tonic-gate 	 * later? This might be for a chdir/chroot or open (add path
3577c478bd9Sstevel@tonic-gate 	 * to file pointer. If the path has already been found for an
3587c478bd9Sstevel@tonic-gate 	 * open/creat then we don't need to process the path.
3597c478bd9Sstevel@tonic-gate 	 *
3604a0fa546SMarek Pospisil 	 * S2E_SP (TAD_SAVPATH) flag comes from audit_s2e[].au_ctrl. Used with
3617c478bd9Sstevel@tonic-gate 	 *	chroot, chdir, open, creat system call processing. It determines
3627c478bd9Sstevel@tonic-gate 	 *	if audit_savepath() will discard the path or we need it later.
3634a0fa546SMarek Pospisil 	 * TAD_PATHFND means path already included in this audit record. It
3647c478bd9Sstevel@tonic-gate 	 *	is used in cases where multiple path lookups are done per
3657c478bd9Sstevel@tonic-gate 	 *	system call. The policy flag, AUDIT_PATH, controls if multiple
3667c478bd9Sstevel@tonic-gate 	 *	paths are allowed.
3674a0fa546SMarek Pospisil 	 * S2E_NPT (TAD_NOPATH) flag comes from audit_s2e[].au_ctrl. Used with
3687c478bd9Sstevel@tonic-gate 	 *	exit processing to inhibit any paths that may be added due to
3697c478bd9Sstevel@tonic-gate 	 *	closes.
3707c478bd9Sstevel@tonic-gate 	 */
3717c478bd9Sstevel@tonic-gate 	if ((tad->tad_flag == 0 &&
3724a0fa546SMarek Pospisil 	    !(tad->tad_ctrl & TAD_SAVPATH)) ||
3734a0fa546SMarek Pospisil 	    ((tad->tad_ctrl & TAD_PATHFND) &&
37451d48dedSMarek Pospisil 	    !(kctx->auk_policy & AUDIT_PATH)) ||
3754a0fa546SMarek Pospisil 	    (tad->tad_ctrl & TAD_NOPATH)) {
37651d48dedSMarek Pospisil 		return;
3777c478bd9Sstevel@tonic-gate 	}
3787c478bd9Sstevel@tonic-gate 
3797c478bd9Sstevel@tonic-gate 	/*
3807c478bd9Sstevel@tonic-gate 	 * if symbolic link is anchored at / then do nothing.
3817c478bd9Sstevel@tonic-gate 	 * When we cycle back to begin: in lookuppn() we will
3827c478bd9Sstevel@tonic-gate 	 * call audit_anchorpath() with a flag indicating if the
3837c478bd9Sstevel@tonic-gate 	 * path is anchored at / or is relative. We will release
3847c478bd9Sstevel@tonic-gate 	 * any saved path at that point.
3857c478bd9Sstevel@tonic-gate 	 *
3867c478bd9Sstevel@tonic-gate 	 * Note In the event that an error occurs in pn_combine then
3877c478bd9Sstevel@tonic-gate 	 * we want to remain pointing at the component that caused the
3887c478bd9Sstevel@tonic-gate 	 * path to overflow the pnp structure.
3897c478bd9Sstevel@tonic-gate 	 */
3907c478bd9Sstevel@tonic-gate 	if (sympath->pn_buf[0] == '/')
3917c478bd9Sstevel@tonic-gate 		return;
3927c478bd9Sstevel@tonic-gate 
3937c478bd9Sstevel@tonic-gate 	/* backup over last component */
3947c478bd9Sstevel@tonic-gate 	sp = cp = pnp->pn_path;
3957c478bd9Sstevel@tonic-gate 	while (*--cp != '/' && cp > pnp->pn_buf)
3967c478bd9Sstevel@tonic-gate 		;
3977c478bd9Sstevel@tonic-gate 
3987c478bd9Sstevel@tonic-gate 	len_path = cp - pnp->pn_buf;
3997c478bd9Sstevel@tonic-gate 
4007c478bd9Sstevel@tonic-gate 	/* is there anything to save? */
4017c478bd9Sstevel@tonic-gate 	if (len_path) {
402405e5d68Stz 		pnp->pn_path = pnp->pn_buf;
4037c478bd9Sstevel@tonic-gate 		audit_pathbuild(pnp);
4047c478bd9Sstevel@tonic-gate 		pnp->pn_path = sp;
4057c478bd9Sstevel@tonic-gate 	}
4067c478bd9Sstevel@tonic-gate }
4077c478bd9Sstevel@tonic-gate 
4087c478bd9Sstevel@tonic-gate /*
4094a0fa546SMarek Pospisil  * object_is_public : determine whether events for the object (corresponding to
4104a0fa546SMarek Pospisil  *			the specified file/directory attr) should be audited or
4114a0fa546SMarek Pospisil  *			ignored.
4127c478bd9Sstevel@tonic-gate  *
413*0f48f68dSToomas Soome  * returns:	1 - if audit policy and object attributes indicate that
4144a0fa546SMarek Pospisil  *			file/directory is effectively public. read events for
4157c478bd9Sstevel@tonic-gate  *			the file should not be audited.
4167c478bd9Sstevel@tonic-gate  *		0 - otherwise
4177c478bd9Sstevel@tonic-gate  *
4187c478bd9Sstevel@tonic-gate  * The required attributes to be considered a public object are:
4197c478bd9Sstevel@tonic-gate  * - owned by root, AND
4207c478bd9Sstevel@tonic-gate  * - world-readable (permissions for other include read), AND
4217c478bd9Sstevel@tonic-gate  * - NOT world-writeable (permissions for other don't
4227c478bd9Sstevel@tonic-gate  *	include write)
4237c478bd9Sstevel@tonic-gate  *   (mode doesn't need to be checked for symlinks)
4247c478bd9Sstevel@tonic-gate  */
4257c478bd9Sstevel@tonic-gate int
object_is_public(struct vattr * attr)4264a0fa546SMarek Pospisil object_is_public(struct vattr *attr)
4277c478bd9Sstevel@tonic-gate {
4289e9e6ab8Spaulson 	au_kcontext_t	*kctx = GET_KCTX_PZ;
4297c478bd9Sstevel@tonic-gate 
4307c478bd9Sstevel@tonic-gate 	if (!(kctx->auk_policy & AUDIT_PUBLIC) && (attr->va_uid == 0) &&
4317c478bd9Sstevel@tonic-gate 	    ((attr->va_type == VLNK) ||
4327c478bd9Sstevel@tonic-gate 	    ((attr->va_mode & (VREAD>>6)) != 0) &&
4337c478bd9Sstevel@tonic-gate 	    ((attr->va_mode & (VWRITE>>6)) == 0))) {
4347c478bd9Sstevel@tonic-gate 		return (1);
4357c478bd9Sstevel@tonic-gate 	}
4367c478bd9Sstevel@tonic-gate 	return (0);
4377c478bd9Sstevel@tonic-gate }
4387c478bd9Sstevel@tonic-gate 
4397c478bd9Sstevel@tonic-gate 
4407c478bd9Sstevel@tonic-gate /*
4417c478bd9Sstevel@tonic-gate  * ROUTINE:	AUDIT_ATTRIBUTES
442da6c28aaSamw  * PURPOSE:	Audit the attributes so we can tell why the error occurred
4437c478bd9Sstevel@tonic-gate  * CALLBY:	AUDIT_SAVEPATH
4447c478bd9Sstevel@tonic-gate  *		AUDIT_VNCREATE_FINISH
4457c478bd9Sstevel@tonic-gate  *		AUS_FCHOWN...audit_event.c...audit_path.c
4467c478bd9Sstevel@tonic-gate  * NOTE:
4477c478bd9Sstevel@tonic-gate  * TODO:
4487c478bd9Sstevel@tonic-gate  * QUESTION:
4497c478bd9Sstevel@tonic-gate  */
4507c478bd9Sstevel@tonic-gate void
audit_attributes(struct vnode * vp)4517c478bd9Sstevel@tonic-gate audit_attributes(struct vnode *vp)
4527c478bd9Sstevel@tonic-gate {
4537c478bd9Sstevel@tonic-gate 	struct vattr attr;
4547c478bd9Sstevel@tonic-gate 	struct t_audit_data *tad;
4557c478bd9Sstevel@tonic-gate 
4567c478bd9Sstevel@tonic-gate 	tad = U2A(u);
4577c478bd9Sstevel@tonic-gate 
4587c478bd9Sstevel@tonic-gate 	if (vp) {
4597c478bd9Sstevel@tonic-gate 		attr.va_mask = AT_ALL;
460da6c28aaSamw 		if (VOP_GETATTR(vp, &attr, 0, CRED(), NULL) != 0)
4617c478bd9Sstevel@tonic-gate 			return;
4627c478bd9Sstevel@tonic-gate 
4634a0fa546SMarek Pospisil 		if (object_is_public(&attr) &&
4644a0fa546SMarek Pospisil 		    (tad->tad_ctrl & TAD_PUBLIC_EV)) {
4657c478bd9Sstevel@tonic-gate 			/*
4667c478bd9Sstevel@tonic-gate 			 * This is a public object and a "public" event
4677c478bd9Sstevel@tonic-gate 			 * (i.e., read only) -- either by definition
4687c478bd9Sstevel@tonic-gate 			 * (e.g., stat, access...) or by virtue of write access
4697c478bd9Sstevel@tonic-gate 			 * not being requested (e.g. mmap).
4707c478bd9Sstevel@tonic-gate 			 * Flag it in the tad to prevent this audit at the end.
4717c478bd9Sstevel@tonic-gate 			 */
4724a0fa546SMarek Pospisil 			tad->tad_ctrl |= TAD_NOAUDIT;
4737c478bd9Sstevel@tonic-gate 		} else {
4747c478bd9Sstevel@tonic-gate 			au_uwrite(au_to_attr(&attr));
47545916cd2Sjpk 			audit_sec_attributes(&(u_ad), vp);
4767c478bd9Sstevel@tonic-gate 		}
4777c478bd9Sstevel@tonic-gate 	}
4787c478bd9Sstevel@tonic-gate }
4797c478bd9Sstevel@tonic-gate 
4807c478bd9Sstevel@tonic-gate 
4817c478bd9Sstevel@tonic-gate /*
4827c478bd9Sstevel@tonic-gate  * ROUTINE:	AUDIT_EXIT
4837c478bd9Sstevel@tonic-gate  * PURPOSE:
4847c478bd9Sstevel@tonic-gate  * CALLBY:	EXIT
4857c478bd9Sstevel@tonic-gate  * NOTE:
4867c478bd9Sstevel@tonic-gate  * TODO:
4877c478bd9Sstevel@tonic-gate  * QUESTION:	why cmw code as offset by 2 but not here
4887c478bd9Sstevel@tonic-gate  */
4897c478bd9Sstevel@tonic-gate /* ARGSUSED */
4907c478bd9Sstevel@tonic-gate void
audit_exit(int code,int what)4917c478bd9Sstevel@tonic-gate audit_exit(int code, int what)
4927c478bd9Sstevel@tonic-gate {
4937c478bd9Sstevel@tonic-gate 	struct t_audit_data *tad;
4947c478bd9Sstevel@tonic-gate 	tad = U2A(u);
4957c478bd9Sstevel@tonic-gate 
4967c478bd9Sstevel@tonic-gate 	/*
4977c478bd9Sstevel@tonic-gate 	 * tad_scid will be set by audit_start even if we are not auditing
4987c478bd9Sstevel@tonic-gate 	 * the event.
4997c478bd9Sstevel@tonic-gate 	 */
5007c478bd9Sstevel@tonic-gate 	if (tad->tad_scid == SYS_exit) {
5017c478bd9Sstevel@tonic-gate 		/*
5027c478bd9Sstevel@tonic-gate 		 * if we are auditing the exit system call, then complete
5037c478bd9Sstevel@tonic-gate 		 * audit record generation (no return from system call).
5047c478bd9Sstevel@tonic-gate 		 */
5057c478bd9Sstevel@tonic-gate 		if (tad->tad_flag && tad->tad_event == AUE_EXIT)
5067c478bd9Sstevel@tonic-gate 			audit_finish(0, SYS_exit, 0, 0);
5077c478bd9Sstevel@tonic-gate 		return;
5087c478bd9Sstevel@tonic-gate 	}
5097c478bd9Sstevel@tonic-gate 
5107c478bd9Sstevel@tonic-gate 	/*
5117c478bd9Sstevel@tonic-gate 	 * Anyone auditing the system call that was aborted?
5127c478bd9Sstevel@tonic-gate 	 */
5137c478bd9Sstevel@tonic-gate 	if (tad->tad_flag) {
5147c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_text("event aborted"));
5157c478bd9Sstevel@tonic-gate 		audit_finish(0, tad->tad_scid, 0, 0);
5167c478bd9Sstevel@tonic-gate 	}
5177c478bd9Sstevel@tonic-gate 
5187c478bd9Sstevel@tonic-gate 	/*
5197c478bd9Sstevel@tonic-gate 	 * Generate an audit record for process exit if preselected.
5207c478bd9Sstevel@tonic-gate 	 */
521005d3febSMarek Pospisil 	(void) audit_start(0, SYS_exit, AUC_UNSET, 0, 0);
5227c478bd9Sstevel@tonic-gate 	audit_finish(0, SYS_exit, 0, 0);
5237c478bd9Sstevel@tonic-gate }
5247c478bd9Sstevel@tonic-gate 
5257c478bd9Sstevel@tonic-gate /*
5267c478bd9Sstevel@tonic-gate  * ROUTINE:	AUDIT_CORE_START
5277c478bd9Sstevel@tonic-gate  * PURPOSE:
528*0f48f68dSToomas Soome  * CALLBY:	PSIG
5297c478bd9Sstevel@tonic-gate  * NOTE:
5307c478bd9Sstevel@tonic-gate  * TODO:
5317c478bd9Sstevel@tonic-gate  */
5327c478bd9Sstevel@tonic-gate void
audit_core_start(int sig)5337c478bd9Sstevel@tonic-gate audit_core_start(int sig)
5347c478bd9Sstevel@tonic-gate {
5357c478bd9Sstevel@tonic-gate 	au_event_t event;
5367c478bd9Sstevel@tonic-gate 	au_state_t estate;
5377c478bd9Sstevel@tonic-gate 	t_audit_data_t *tad;
5387c478bd9Sstevel@tonic-gate 	au_kcontext_t	*kctx;
5397c478bd9Sstevel@tonic-gate 
5407c478bd9Sstevel@tonic-gate 	tad = U2A(u);
5417c478bd9Sstevel@tonic-gate 
5427c478bd9Sstevel@tonic-gate 	ASSERT(tad != (t_audit_data_t *)0);
5437c478bd9Sstevel@tonic-gate 
5447c478bd9Sstevel@tonic-gate 	ASSERT(tad->tad_scid == 0);
5457c478bd9Sstevel@tonic-gate 	ASSERT(tad->tad_event == 0);
5467c478bd9Sstevel@tonic-gate 	ASSERT(tad->tad_evmod == 0);
5477c478bd9Sstevel@tonic-gate 	ASSERT(tad->tad_ctrl == 0);
5487c478bd9Sstevel@tonic-gate 	ASSERT(tad->tad_flag == 0);
5497c478bd9Sstevel@tonic-gate 	ASSERT(tad->tad_aupath == NULL);
5507c478bd9Sstevel@tonic-gate 
5519e9e6ab8Spaulson 	kctx = GET_KCTX_PZ;
5527c478bd9Sstevel@tonic-gate 
5537c478bd9Sstevel@tonic-gate 	/* get basic event for system call */
5547c478bd9Sstevel@tonic-gate 	event = AUE_CORE;
5557c478bd9Sstevel@tonic-gate 	estate = kctx->auk_ets[event];
5567c478bd9Sstevel@tonic-gate 
5577c478bd9Sstevel@tonic-gate 	if ((tad->tad_flag = auditme(kctx, tad, estate)) == 0)
5587c478bd9Sstevel@tonic-gate 		return;
5597c478bd9Sstevel@tonic-gate 
5607c478bd9Sstevel@tonic-gate 	/* reset the flags for non-user attributable events */
5614a0fa546SMarek Pospisil 	tad->tad_ctrl   = TAD_CORE;
5627c478bd9Sstevel@tonic-gate 	tad->tad_scid   = 0;
5637c478bd9Sstevel@tonic-gate 
5647c478bd9Sstevel@tonic-gate 	/* if auditing not enabled, then don't generate an audit record */
5657c478bd9Sstevel@tonic-gate 
5667c478bd9Sstevel@tonic-gate 	if (!((kctx->auk_auditstate == AUC_AUDITING ||
5677c478bd9Sstevel@tonic-gate 	    kctx->auk_auditstate == AUC_INIT_AUDIT) ||
5687c478bd9Sstevel@tonic-gate 	    kctx->auk_auditstate == AUC_NOSPACE)) {
5697c478bd9Sstevel@tonic-gate 		tad->tad_flag = 0;
5707c478bd9Sstevel@tonic-gate 		tad->tad_ctrl = 0;
5717c478bd9Sstevel@tonic-gate 		return;
5727c478bd9Sstevel@tonic-gate 	}
5737c478bd9Sstevel@tonic-gate 
5747c478bd9Sstevel@tonic-gate 	tad->tad_event  = event;
5757c478bd9Sstevel@tonic-gate 	tad->tad_evmod  = 0;
5767c478bd9Sstevel@tonic-gate 
5777c478bd9Sstevel@tonic-gate 	ASSERT(tad->tad_ad == NULL);
5787c478bd9Sstevel@tonic-gate 
5797c478bd9Sstevel@tonic-gate 	au_write(&(u_ad), au_to_arg32(1, "signal", (uint32_t)sig));
5807c478bd9Sstevel@tonic-gate }
5817c478bd9Sstevel@tonic-gate 
5827c478bd9Sstevel@tonic-gate /*
5837c478bd9Sstevel@tonic-gate  * ROUTINE:	AUDIT_CORE_FINISH
5847c478bd9Sstevel@tonic-gate  * PURPOSE:
5857c478bd9Sstevel@tonic-gate  * CALLBY:	PSIG
5867c478bd9Sstevel@tonic-gate  * NOTE:
5877c478bd9Sstevel@tonic-gate  * TODO:
5887c478bd9Sstevel@tonic-gate  * QUESTION:
5897c478bd9Sstevel@tonic-gate  */
5907c478bd9Sstevel@tonic-gate 
5917c478bd9Sstevel@tonic-gate /*ARGSUSED*/
5927c478bd9Sstevel@tonic-gate void
audit_core_finish(int code)5937c478bd9Sstevel@tonic-gate audit_core_finish(int code)
5947c478bd9Sstevel@tonic-gate {
5957c478bd9Sstevel@tonic-gate 	int flag;
5967c478bd9Sstevel@tonic-gate 	t_audit_data_t *tad;
5977c478bd9Sstevel@tonic-gate 	au_kcontext_t	*kctx;
5987c478bd9Sstevel@tonic-gate 
5997c478bd9Sstevel@tonic-gate 	tad = U2A(u);
6007c478bd9Sstevel@tonic-gate 
6017c478bd9Sstevel@tonic-gate 	ASSERT(tad != (t_audit_data_t *)0);
6027c478bd9Sstevel@tonic-gate 
6037c478bd9Sstevel@tonic-gate 	if ((flag = tad->tad_flag) == 0) {
6047c478bd9Sstevel@tonic-gate 		tad->tad_event = 0;
6057c478bd9Sstevel@tonic-gate 		tad->tad_evmod = 0;
6067c478bd9Sstevel@tonic-gate 		tad->tad_ctrl  = 0;
6077c478bd9Sstevel@tonic-gate 		ASSERT(tad->tad_aupath == NULL);
6087c478bd9Sstevel@tonic-gate 		return;
6097c478bd9Sstevel@tonic-gate 	}
6107c478bd9Sstevel@tonic-gate 	tad->tad_flag = 0;
6117c478bd9Sstevel@tonic-gate 
6129e9e6ab8Spaulson 	kctx = GET_KCTX_PZ;
6137c478bd9Sstevel@tonic-gate 
6147c478bd9Sstevel@tonic-gate 	/* kludge for error 0, should use `code==CLD_DUMPED' instead */
615799bd290Spwernau 	if (flag = audit_success(kctx, tad, 0, NULL)) {
6167c478bd9Sstevel@tonic-gate 		cred_t *cr = CRED();
6177c478bd9Sstevel@tonic-gate 		const auditinfo_addr_t *ainfo = crgetauinfo(cr);
6187c478bd9Sstevel@tonic-gate 
6197c478bd9Sstevel@tonic-gate 		ASSERT(ainfo != NULL);
6207c478bd9Sstevel@tonic-gate 
6217c478bd9Sstevel@tonic-gate 		/*
62281490fd2Sgww 		 * Add subject information (no locks since our private copy of
6237c478bd9Sstevel@tonic-gate 		 * credential
6247c478bd9Sstevel@tonic-gate 		 */
62581490fd2Sgww 		AUDIT_SETSUBJ(&(u_ad), cr, ainfo, kctx);
62645916cd2Sjpk 
6277c478bd9Sstevel@tonic-gate 		/* Add a return token (should use f argument) */
6287c478bd9Sstevel@tonic-gate 		add_return_token((caddr_t *)&(u_ad), tad->tad_scid, 0, 0);
6297c478bd9Sstevel@tonic-gate 
6307c478bd9Sstevel@tonic-gate 		AS_INC(as_generated, 1, kctx);
6317c478bd9Sstevel@tonic-gate 		AS_INC(as_kernel, 1, kctx);
6327c478bd9Sstevel@tonic-gate 	}
6337c478bd9Sstevel@tonic-gate 
6347c478bd9Sstevel@tonic-gate 	/* Close up everything */
635005d3febSMarek Pospisil 	au_close(kctx, &(u_ad), flag, tad->tad_event, tad->tad_evmod, NULL);
6367c478bd9Sstevel@tonic-gate 
6377c478bd9Sstevel@tonic-gate 	/* free up any space remaining with the path's */
6387c478bd9Sstevel@tonic-gate 	if (tad->tad_aupath != NULL) {
6397c478bd9Sstevel@tonic-gate 		au_pathrele(tad->tad_aupath);
6407c478bd9Sstevel@tonic-gate 		tad->tad_aupath = NULL;
6417c478bd9Sstevel@tonic-gate 	}
6427c478bd9Sstevel@tonic-gate 	tad->tad_event = 0;
6437c478bd9Sstevel@tonic-gate 	tad->tad_evmod = 0;
6447c478bd9Sstevel@tonic-gate 	tad->tad_ctrl  = 0;
6457c478bd9Sstevel@tonic-gate }
6467c478bd9Sstevel@tonic-gate 
6477c478bd9Sstevel@tonic-gate 
6487c478bd9Sstevel@tonic-gate /*ARGSUSED*/
6497c478bd9Sstevel@tonic-gate void
audit_strgetmsg(struct vnode * vp,struct strbuf * mctl,struct strbuf * mdata,unsigned char * pri,int * flag,int fmode)6507c478bd9Sstevel@tonic-gate audit_strgetmsg(struct vnode *vp, struct strbuf *mctl, struct strbuf *mdata,
6517c478bd9Sstevel@tonic-gate     unsigned char *pri, int *flag, int fmode)
6527c478bd9Sstevel@tonic-gate {
6537c478bd9Sstevel@tonic-gate 	struct stdata *stp;
6547c478bd9Sstevel@tonic-gate 	t_audit_data_t *tad = U2A(u);
6557c478bd9Sstevel@tonic-gate 
6567c478bd9Sstevel@tonic-gate 	ASSERT(tad != (t_audit_data_t *)0);
6577c478bd9Sstevel@tonic-gate 
6587c478bd9Sstevel@tonic-gate 	stp = vp->v_stream;
6597c478bd9Sstevel@tonic-gate 
6607c478bd9Sstevel@tonic-gate 	/* lock stdata from audit_sock */
6617c478bd9Sstevel@tonic-gate 	mutex_enter(&stp->sd_lock);
6627c478bd9Sstevel@tonic-gate 
6637c478bd9Sstevel@tonic-gate 	/* proceed ONLY if user is being audited */
6647c478bd9Sstevel@tonic-gate 	if (!tad->tad_flag) {
6657c478bd9Sstevel@tonic-gate 		/*
6667c478bd9Sstevel@tonic-gate 		 * this is so we will not add audit data onto
6677c478bd9Sstevel@tonic-gate 		 * a thread that is not being audited.
6687c478bd9Sstevel@tonic-gate 		 */
6697c478bd9Sstevel@tonic-gate 		stp->sd_t_audit_data = NULL;
6707c478bd9Sstevel@tonic-gate 		mutex_exit(&stp->sd_lock);
6717c478bd9Sstevel@tonic-gate 		return;
6727c478bd9Sstevel@tonic-gate 	}
6737c478bd9Sstevel@tonic-gate 
6747c478bd9Sstevel@tonic-gate 	stp->sd_t_audit_data = (caddr_t)curthread;
6757c478bd9Sstevel@tonic-gate 	mutex_exit(&stp->sd_lock);
6767c478bd9Sstevel@tonic-gate }
6777c478bd9Sstevel@tonic-gate 
6787c478bd9Sstevel@tonic-gate /*ARGSUSED*/
6797c478bd9Sstevel@tonic-gate void
audit_strputmsg(struct vnode * vp,struct strbuf * mctl,struct strbuf * mdata,unsigned char pri,int flag,int fmode)6807c478bd9Sstevel@tonic-gate audit_strputmsg(struct vnode *vp, struct strbuf *mctl, struct strbuf *mdata,
6817c478bd9Sstevel@tonic-gate     unsigned char pri, int flag, int fmode)
6827c478bd9Sstevel@tonic-gate {
6837c478bd9Sstevel@tonic-gate 	struct stdata *stp;
6847c478bd9Sstevel@tonic-gate 	t_audit_data_t *tad = U2A(u);
6857c478bd9Sstevel@tonic-gate 
6867c478bd9Sstevel@tonic-gate 	ASSERT(tad != (t_audit_data_t *)0);
6877c478bd9Sstevel@tonic-gate 
6887c478bd9Sstevel@tonic-gate 	stp = vp->v_stream;
6897c478bd9Sstevel@tonic-gate 
6907c478bd9Sstevel@tonic-gate 	/* lock stdata from audit_sock */
6917c478bd9Sstevel@tonic-gate 	mutex_enter(&stp->sd_lock);
6927c478bd9Sstevel@tonic-gate 
6937c478bd9Sstevel@tonic-gate 	/* proceed ONLY if user is being audited */
6947c478bd9Sstevel@tonic-gate 	if (!tad->tad_flag) {
6957c478bd9Sstevel@tonic-gate 		/*
6967c478bd9Sstevel@tonic-gate 		 * this is so we will not add audit data onto
6977c478bd9Sstevel@tonic-gate 		 * a thread that is not being audited.
6987c478bd9Sstevel@tonic-gate 		 */
6997c478bd9Sstevel@tonic-gate 		stp->sd_t_audit_data = NULL;
7007c478bd9Sstevel@tonic-gate 		mutex_exit(&stp->sd_lock);
7017c478bd9Sstevel@tonic-gate 		return;
7027c478bd9Sstevel@tonic-gate 	}
7037c478bd9Sstevel@tonic-gate 
7047c478bd9Sstevel@tonic-gate 	stp->sd_t_audit_data = (caddr_t)curthread;
7057c478bd9Sstevel@tonic-gate 	mutex_exit(&stp->sd_lock);
7067c478bd9Sstevel@tonic-gate }
7077c478bd9Sstevel@tonic-gate 
7087c478bd9Sstevel@tonic-gate /*
7097c478bd9Sstevel@tonic-gate  * ROUTINE:	AUDIT_CLOSEF
7107c478bd9Sstevel@tonic-gate  * PURPOSE:
7117c478bd9Sstevel@tonic-gate  * CALLBY:	CLOSEF
7127c478bd9Sstevel@tonic-gate  * NOTE:
7137c478bd9Sstevel@tonic-gate  * release per file audit resources when file structure is being released.
7147c478bd9Sstevel@tonic-gate  *
7157c478bd9Sstevel@tonic-gate  * IMPORTANT NOTE: Since we generate an audit record here, we may sleep
7167c478bd9Sstevel@tonic-gate  *	on the audit queue if it becomes full. This means
7177c478bd9Sstevel@tonic-gate  *	audit_closef can not be called when f_count == 0. Since
7187c478bd9Sstevel@tonic-gate  *	f_count == 0 indicates the file structure is free, another
7197c478bd9Sstevel@tonic-gate  *	process could attempt to use the file while we were still
7207c478bd9Sstevel@tonic-gate  *	asleep waiting on the audit queue. This would cause the
7217c478bd9Sstevel@tonic-gate  *	per file audit data to be corrupted when we finally do
7227c478bd9Sstevel@tonic-gate  *	wakeup.
7237c478bd9Sstevel@tonic-gate  * TODO:
7247c478bd9Sstevel@tonic-gate  * QUESTION:
7257c478bd9Sstevel@tonic-gate  */
7267c478bd9Sstevel@tonic-gate 
7277c478bd9Sstevel@tonic-gate void
audit_closef(struct file * fp)7287c478bd9Sstevel@tonic-gate audit_closef(struct file *fp)
729d2a70789SRichard Lowe {
7307c478bd9Sstevel@tonic-gate 	f_audit_data_t *fad;
7317c478bd9Sstevel@tonic-gate 	t_audit_data_t *tad;
7327c478bd9Sstevel@tonic-gate 	int success;
7337c478bd9Sstevel@tonic-gate 	au_state_t estate;
7347c478bd9Sstevel@tonic-gate 	struct vnode *vp;
7357c478bd9Sstevel@tonic-gate 	token_t *ad = NULL;
7367c478bd9Sstevel@tonic-gate 	struct vattr attr;
737d0fa49b7STony Nguyen 	au_emod_t evmod = 0;
7387c478bd9Sstevel@tonic-gate 	const auditinfo_addr_t *ainfo;
7397c478bd9Sstevel@tonic-gate 	cred_t *cr;
7409e9e6ab8Spaulson 	au_kcontext_t	*kctx = GET_KCTX_PZ;
741005d3febSMarek Pospisil 	uint32_t auditing;
742224626ecSMarek Pospisil 	boolean_t audit_attr = B_FALSE;
7437c478bd9Sstevel@tonic-gate 
7447c478bd9Sstevel@tonic-gate 	fad = F2A(fp);
7457c478bd9Sstevel@tonic-gate 	estate = kctx->auk_ets[AUE_CLOSE];
7467c478bd9Sstevel@tonic-gate 	tad = U2A(u);
7477c478bd9Sstevel@tonic-gate 	cr = CRED();
7487c478bd9Sstevel@tonic-gate 
7497c478bd9Sstevel@tonic-gate 	/* audit record already generated by system call envelope */
7507c478bd9Sstevel@tonic-gate 	if (tad->tad_event == AUE_CLOSE) {
7517c478bd9Sstevel@tonic-gate 		/* so close audit event will have bits set */
752d0fa49b7STony Nguyen 		tad->tad_evmod |= (au_emod_t)fad->fad_flags;
7537c478bd9Sstevel@tonic-gate 		return;
7547c478bd9Sstevel@tonic-gate 	}
7557c478bd9Sstevel@tonic-gate 
7567c478bd9Sstevel@tonic-gate 	/* if auditing not enabled, then don't generate an audit record */
757005d3febSMarek Pospisil 	auditing = (tad->tad_audit == AUC_UNSET) ?
758005d3febSMarek Pospisil 	    kctx->auk_auditstate : tad->tad_audit;
759005d3febSMarek Pospisil 	if (auditing & ~(AUC_AUDITING | AUC_INIT_AUDIT | AUC_NOSPACE))
7607c478bd9Sstevel@tonic-gate 		return;
7617c478bd9Sstevel@tonic-gate 
7627c478bd9Sstevel@tonic-gate 	ainfo = crgetauinfo(cr);
7637c478bd9Sstevel@tonic-gate 	if (ainfo == NULL)
7647c478bd9Sstevel@tonic-gate 		return;
7657c478bd9Sstevel@tonic-gate 
7667c478bd9Sstevel@tonic-gate 	success = ainfo->ai_mask.as_success & estate;
7677c478bd9Sstevel@tonic-gate 
7687c478bd9Sstevel@tonic-gate 	/* not selected for this event */
7697c478bd9Sstevel@tonic-gate 	if (success == 0)
7707c478bd9Sstevel@tonic-gate 		return;
7717c478bd9Sstevel@tonic-gate 
7727c478bd9Sstevel@tonic-gate 	/*
7737c478bd9Sstevel@tonic-gate 	 * can't use audit_attributes here since we use a private audit area
7747c478bd9Sstevel@tonic-gate 	 * to build the audit record instead of the one off the thread.
7757c478bd9Sstevel@tonic-gate 	 */
7767c478bd9Sstevel@tonic-gate 	if ((vp = fp->f_vnode) != NULL) {
7777c478bd9Sstevel@tonic-gate 		attr.va_mask = AT_ALL;
778224626ecSMarek Pospisil 		if (VOP_GETATTR(vp, &attr, 0, CRED(), NULL) == 0) {
779224626ecSMarek Pospisil 			if ((fp->f_flag & FWRITE) == 0 &&
780224626ecSMarek Pospisil 			    object_is_public(&attr)) {
781224626ecSMarek Pospisil 				/*
782224626ecSMarek Pospisil 				 * When write was not used and the file can be
783224626ecSMarek Pospisil 				 * considered public, then skip the audit.
784224626ecSMarek Pospisil 				 */
785224626ecSMarek Pospisil 				return;
786224626ecSMarek Pospisil 			}
787224626ecSMarek Pospisil 			audit_attr = B_TRUE;
7887c478bd9Sstevel@tonic-gate 		}
7897c478bd9Sstevel@tonic-gate 	}
7907c478bd9Sstevel@tonic-gate 
791d0fa49b7STony Nguyen 	evmod = (au_emod_t)fad->fad_flags;
7927c478bd9Sstevel@tonic-gate 	if (fad->fad_aupath != NULL) {
7937c478bd9Sstevel@tonic-gate 		au_write((caddr_t *)&(ad), au_to_path(fad->fad_aupath));
7947c478bd9Sstevel@tonic-gate 	} else {
7957c478bd9Sstevel@tonic-gate #ifdef _LP64
7967c478bd9Sstevel@tonic-gate 		au_write((caddr_t *)&(ad), au_to_arg64(
797d2a70789SRichard Lowe 		    1, "no path: fp", (uint64_t)fp));
7987c478bd9Sstevel@tonic-gate #else
7997c478bd9Sstevel@tonic-gate 		au_write((caddr_t *)&(ad), au_to_arg32(
800d2a70789SRichard Lowe 		    1, "no path: fp", (uint32_t)fp));
8017c478bd9Sstevel@tonic-gate #endif
8027c478bd9Sstevel@tonic-gate 	}
8037c478bd9Sstevel@tonic-gate 
804224626ecSMarek Pospisil 	if (audit_attr) {
8057c478bd9Sstevel@tonic-gate 		au_write((caddr_t *)&(ad), au_to_attr(&attr));
80645916cd2Sjpk 		audit_sec_attributes((caddr_t *)&(ad), vp);
8077c478bd9Sstevel@tonic-gate 	}
8087c478bd9Sstevel@tonic-gate 
80981490fd2Sgww 	/* Add subject information */
81081490fd2Sgww 	AUDIT_SETSUBJ((caddr_t *)&(ad), cr, ainfo, kctx);
81145916cd2Sjpk 
8127c478bd9Sstevel@tonic-gate 	/* add a return token */
8137c478bd9Sstevel@tonic-gate 	add_return_token((caddr_t *)&(ad), tad->tad_scid, 0, 0);
8147c478bd9Sstevel@tonic-gate 
8157c478bd9Sstevel@tonic-gate 	AS_INC(as_generated, 1, kctx);
8167c478bd9Sstevel@tonic-gate 	AS_INC(as_kernel, 1, kctx);
8177c478bd9Sstevel@tonic-gate 
8187c478bd9Sstevel@tonic-gate 	/*
8197c478bd9Sstevel@tonic-gate 	 * Close up everything
8207c478bd9Sstevel@tonic-gate 	 * Note: path space recovery handled by normal system
8217c478bd9Sstevel@tonic-gate 	 * call envelope if not at last close.
8227c478bd9Sstevel@tonic-gate 	 * Note there is no failure at this point since
8237c478bd9Sstevel@tonic-gate 	 *   this represents closes due to exit of process,
8247c478bd9Sstevel@tonic-gate 	 *   thus we always indicate successful closes.
8257c478bd9Sstevel@tonic-gate 	 */
8267c478bd9Sstevel@tonic-gate 	au_close(kctx, (caddr_t *)&(ad), AU_OK | AU_DEFER,
827005d3febSMarek Pospisil 	    AUE_CLOSE, evmod, NULL);
8287c478bd9Sstevel@tonic-gate }
8297c478bd9Sstevel@tonic-gate 
8307c478bd9Sstevel@tonic-gate /*
8317c478bd9Sstevel@tonic-gate  * ROUTINE:	AUDIT_SET
8327c478bd9Sstevel@tonic-gate  * PURPOSE:	Audit the file path and file attributes.
8337c478bd9Sstevel@tonic-gate  * CALLBY:	SETF
8347c478bd9Sstevel@tonic-gate  * NOTE:	SETF associate a file pointer with user area's open files.
8357c478bd9Sstevel@tonic-gate  * TODO:
8367c478bd9Sstevel@tonic-gate  * call audit_finish directly ???
8377c478bd9Sstevel@tonic-gate  * QUESTION:
8387c478bd9Sstevel@tonic-gate  */
8397c478bd9Sstevel@tonic-gate 
8407c478bd9Sstevel@tonic-gate /*ARGSUSED*/
8417c478bd9Sstevel@tonic-gate void
audit_setf(file_t * fp,int fd)8427c478bd9Sstevel@tonic-gate audit_setf(file_t *fp, int fd)
8437c478bd9Sstevel@tonic-gate {
8447c478bd9Sstevel@tonic-gate 	f_audit_data_t *fad;
8457c478bd9Sstevel@tonic-gate 	t_audit_data_t *tad;
8467c478bd9Sstevel@tonic-gate 
8477c478bd9Sstevel@tonic-gate 	if (fp == NULL)
8487c478bd9Sstevel@tonic-gate 		return;
8497c478bd9Sstevel@tonic-gate 
8507c478bd9Sstevel@tonic-gate 	tad = T2A(curthread);
8517c478bd9Sstevel@tonic-gate 	fad = F2A(fp);
8527c478bd9Sstevel@tonic-gate 
8538fd04b83SRoger A. Faulkner 	if (!(tad->tad_scid == SYS_open ||
8548fd04b83SRoger A. Faulkner 	    tad->tad_scid == SYS_open64 ||
8558fd04b83SRoger A. Faulkner 	    tad->tad_scid == SYS_openat ||
8568fd04b83SRoger A. Faulkner 	    tad->tad_scid == SYS_openat64))
8577c478bd9Sstevel@tonic-gate 		return;
8587c478bd9Sstevel@tonic-gate 
8597c478bd9Sstevel@tonic-gate 	/* no path */
8607c478bd9Sstevel@tonic-gate 	if (tad->tad_aupath == 0)
8617c478bd9Sstevel@tonic-gate 		return;
8627c478bd9Sstevel@tonic-gate 
8637c478bd9Sstevel@tonic-gate 	/*
8647c478bd9Sstevel@tonic-gate 	 * assign path information associated with file audit data
8657c478bd9Sstevel@tonic-gate 	 * use tad hold
8667c478bd9Sstevel@tonic-gate 	 */
8677c478bd9Sstevel@tonic-gate 	fad->fad_aupath = tad->tad_aupath;
8687c478bd9Sstevel@tonic-gate 	tad->tad_aupath = NULL;
8697c478bd9Sstevel@tonic-gate 
8704a0fa546SMarek Pospisil 	if (!(tad->tad_ctrl & TAD_TRUE_CREATE)) {
8718fd04b83SRoger A. Faulkner 		/* adjust event type by dropping the 'creat' part */
8727c478bd9Sstevel@tonic-gate 		switch (tad->tad_event) {
8737c478bd9Sstevel@tonic-gate 		case AUE_OPEN_RC:
8747c478bd9Sstevel@tonic-gate 			tad->tad_event = AUE_OPEN_R;
8754a0fa546SMarek Pospisil 			tad->tad_ctrl |= TAD_PUBLIC_EV;
8767c478bd9Sstevel@tonic-gate 			break;
8777c478bd9Sstevel@tonic-gate 		case AUE_OPEN_RTC:
8787c478bd9Sstevel@tonic-gate 			tad->tad_event = AUE_OPEN_RT;
8797c478bd9Sstevel@tonic-gate 			break;
8807c478bd9Sstevel@tonic-gate 		case AUE_OPEN_WC:
8817c478bd9Sstevel@tonic-gate 			tad->tad_event = AUE_OPEN_W;
8827c478bd9Sstevel@tonic-gate 			break;
8837c478bd9Sstevel@tonic-gate 		case AUE_OPEN_WTC:
8847c478bd9Sstevel@tonic-gate 			tad->tad_event = AUE_OPEN_WT;
8857c478bd9Sstevel@tonic-gate 			break;
8867c478bd9Sstevel@tonic-gate 		case AUE_OPEN_RWC:
8877c478bd9Sstevel@tonic-gate 			tad->tad_event = AUE_OPEN_RW;
8887c478bd9Sstevel@tonic-gate 			break;
8897c478bd9Sstevel@tonic-gate 		case AUE_OPEN_RWTC:
8907c478bd9Sstevel@tonic-gate 			tad->tad_event = AUE_OPEN_RWT;
8917c478bd9Sstevel@tonic-gate 			break;
8927c478bd9Sstevel@tonic-gate 		default:
8937c478bd9Sstevel@tonic-gate 			break;
8947c478bd9Sstevel@tonic-gate 		}
8957c478bd9Sstevel@tonic-gate 	}
8967c478bd9Sstevel@tonic-gate }
8977c478bd9Sstevel@tonic-gate 
8987c478bd9Sstevel@tonic-gate 
8997c478bd9Sstevel@tonic-gate void
audit_ipc(int type,int id,void * vp)9007c478bd9Sstevel@tonic-gate audit_ipc(int type, int id, void *vp)
9017c478bd9Sstevel@tonic-gate {
9027c478bd9Sstevel@tonic-gate 	/* if not auditing this event, then do nothing */
9037c478bd9Sstevel@tonic-gate 	if (ad_flag == 0)
9047c478bd9Sstevel@tonic-gate 		return;
9057c478bd9Sstevel@tonic-gate 
9067c478bd9Sstevel@tonic-gate 	switch (type) {
9077c478bd9Sstevel@tonic-gate 	case AT_IPC_MSG:
9087c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_ipc(AT_IPC_MSG, id));
9097c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_ipc_perm(&(((kmsqid_t *)vp)->msg_perm)));
9107c478bd9Sstevel@tonic-gate 		break;
9117c478bd9Sstevel@tonic-gate 	case AT_IPC_SEM:
9127c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_ipc(AT_IPC_SEM, id));
9137c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_ipc_perm(&(((ksemid_t *)vp)->sem_perm)));
9147c478bd9Sstevel@tonic-gate 		break;
9157c478bd9Sstevel@tonic-gate 	case AT_IPC_SHM:
9167c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_ipc(AT_IPC_SHM, id));
9177c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_ipc_perm(&(((kshmid_t *)vp)->shm_perm)));
9187c478bd9Sstevel@tonic-gate 		break;
9197c478bd9Sstevel@tonic-gate 	}
9207c478bd9Sstevel@tonic-gate }
9217c478bd9Sstevel@tonic-gate 
9227c478bd9Sstevel@tonic-gate void
audit_ipcget(int type,void * vp)9237c478bd9Sstevel@tonic-gate audit_ipcget(int type, void *vp)
9247c478bd9Sstevel@tonic-gate {
9257c478bd9Sstevel@tonic-gate 	/* if not auditing this event, then do nothing */
9267c478bd9Sstevel@tonic-gate 	if (ad_flag == 0)
9277c478bd9Sstevel@tonic-gate 		return;
9287c478bd9Sstevel@tonic-gate 
9297c478bd9Sstevel@tonic-gate 	switch (type) {
930*0f48f68dSToomas Soome 	case 0:
9317c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_ipc_perm((struct kipc_perm *)vp));
9327c478bd9Sstevel@tonic-gate 		break;
9337c478bd9Sstevel@tonic-gate 	case AT_IPC_MSG:
9347c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_ipc_perm(&(((kmsqid_t *)vp)->msg_perm)));
9357c478bd9Sstevel@tonic-gate 		break;
9367c478bd9Sstevel@tonic-gate 	case AT_IPC_SEM:
9377c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_ipc_perm(&(((ksemid_t *)vp)->sem_perm)));
9387c478bd9Sstevel@tonic-gate 		break;
9397c478bd9Sstevel@tonic-gate 	case AT_IPC_SHM:
9407c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_ipc_perm(&(((kshmid_t *)vp)->shm_perm)));
9417c478bd9Sstevel@tonic-gate 		break;
9427c478bd9Sstevel@tonic-gate 	}
9437c478bd9Sstevel@tonic-gate }
9447c478bd9Sstevel@tonic-gate 
9457c478bd9Sstevel@tonic-gate /*
9467c478bd9Sstevel@tonic-gate  * ROUTINE:	AUDIT_REBOOT
9477c478bd9Sstevel@tonic-gate  * PURPOSE:
9487c478bd9Sstevel@tonic-gate  * CALLBY:
9497c478bd9Sstevel@tonic-gate  * NOTE:
9507c478bd9Sstevel@tonic-gate  * At this point we know that the system call reboot will not return. We thus
9517c478bd9Sstevel@tonic-gate  * have to complete the audit record generation and put it onto the queue.
9527c478bd9Sstevel@tonic-gate  * This might be fairly useless if the auditing daemon is already dead....
9537c478bd9Sstevel@tonic-gate  * TODO:
9547c478bd9Sstevel@tonic-gate  * QUESTION:	who calls audit_reboot
9557c478bd9Sstevel@tonic-gate  */
9567c478bd9Sstevel@tonic-gate 
9577c478bd9Sstevel@tonic-gate void
audit_reboot(void)9587c478bd9Sstevel@tonic-gate audit_reboot(void)
9597c478bd9Sstevel@tonic-gate {
9607c478bd9Sstevel@tonic-gate 	int flag;
9617c478bd9Sstevel@tonic-gate 	t_audit_data_t *tad;
9629e9e6ab8Spaulson 	au_kcontext_t	*kctx = GET_KCTX_PZ;
9637c478bd9Sstevel@tonic-gate 
9647c478bd9Sstevel@tonic-gate 	tad = U2A(u);
9657c478bd9Sstevel@tonic-gate 
9667c478bd9Sstevel@tonic-gate 	/* if not auditing this event, then do nothing */
9677c478bd9Sstevel@tonic-gate 	if (tad->tad_flag == 0)
9687c478bd9Sstevel@tonic-gate 		return;
9697c478bd9Sstevel@tonic-gate 
9707c478bd9Sstevel@tonic-gate 	/* do preselection on success/failure */
971799bd290Spwernau 	if (flag = audit_success(kctx, tad, 0, NULL)) {
9727c478bd9Sstevel@tonic-gate 		/* add a process token */
9737c478bd9Sstevel@tonic-gate 
9747c478bd9Sstevel@tonic-gate 		cred_t *cr = CRED();
9757c478bd9Sstevel@tonic-gate 		const auditinfo_addr_t *ainfo = crgetauinfo(cr);
9767c478bd9Sstevel@tonic-gate 
9777c478bd9Sstevel@tonic-gate 		if (ainfo == NULL)
9787c478bd9Sstevel@tonic-gate 			return;
9797c478bd9Sstevel@tonic-gate 
98081490fd2Sgww 		/* Add subject information */
98181490fd2Sgww 		AUDIT_SETSUBJ(&(u_ad), cr, ainfo, kctx);
98245916cd2Sjpk 
9837c478bd9Sstevel@tonic-gate 		/* add a return token */
9847c478bd9Sstevel@tonic-gate 		add_return_token((caddr_t *)&(u_ad), tad->tad_scid, 0, 0);
9857c478bd9Sstevel@tonic-gate 
9867c478bd9Sstevel@tonic-gate 		AS_INC(as_generated, 1, kctx);
9877c478bd9Sstevel@tonic-gate 		AS_INC(as_kernel, 1, kctx);
9887c478bd9Sstevel@tonic-gate 	}
9897c478bd9Sstevel@tonic-gate 
9907c478bd9Sstevel@tonic-gate 	/*
9917c478bd9Sstevel@tonic-gate 	 * Flow control useless here since we're going
9927c478bd9Sstevel@tonic-gate 	 * to drop everything in the queue anyway. Why
9937c478bd9Sstevel@tonic-gate 	 * block and wait. There aint anyone left alive to
9947c478bd9Sstevel@tonic-gate 	 * read the records remaining anyway.
9957c478bd9Sstevel@tonic-gate 	 */
9967c478bd9Sstevel@tonic-gate 
9977c478bd9Sstevel@tonic-gate 	/* Close up everything */
9987c478bd9Sstevel@tonic-gate 	au_close(kctx, &(u_ad), flag | AU_DONTBLOCK,
999005d3febSMarek Pospisil 	    tad->tad_event, tad->tad_evmod, NULL);
10007c478bd9Sstevel@tonic-gate }
10017c478bd9Sstevel@tonic-gate 
10027c478bd9Sstevel@tonic-gate void
audit_setfsat_path(int argnum)10037c478bd9Sstevel@tonic-gate audit_setfsat_path(int argnum)
10047c478bd9Sstevel@tonic-gate {
10057c478bd9Sstevel@tonic-gate 	klwp_id_t clwp = ttolwp(curthread);
10067c478bd9Sstevel@tonic-gate 	struct file  *fp;
10077c478bd9Sstevel@tonic-gate 	uint32_t fd;
10087c478bd9Sstevel@tonic-gate 	t_audit_data_t *tad;
10097c478bd9Sstevel@tonic-gate 	struct f_audit_data *fad;
10107c478bd9Sstevel@tonic-gate 	p_audit_data_t *pad;	/* current process */
1011c4d3e299SBrent Paulson 	uint_t fm;
1012da6c28aaSamw 	struct a {
1013da6c28aaSamw 		long arg1;
1014da6c28aaSamw 		long arg2;
1015da6c28aaSamw 		long arg3;
1016da6c28aaSamw 		long arg4;
1017da6c28aaSamw 		long arg5;
1018da6c28aaSamw 	} *uap;
10197c478bd9Sstevel@tonic-gate 
10207c478bd9Sstevel@tonic-gate 	if (clwp == NULL)
10217c478bd9Sstevel@tonic-gate 		return;
1022da6c28aaSamw 	uap = (struct a *)clwp->lwp_ap;
10237c478bd9Sstevel@tonic-gate 
10247c478bd9Sstevel@tonic-gate 	tad = U2A(u);
10257c478bd9Sstevel@tonic-gate 	ASSERT(tad != NULL);
10267c478bd9Sstevel@tonic-gate 
10278fd04b83SRoger A. Faulkner 	switch (tad->tad_scid) {
10288fd04b83SRoger A. Faulkner 	case SYS_faccessat:
1029794f0adbSRoger A. Faulkner 	case SYS_fchmodat:
10308fd04b83SRoger A. Faulkner 	case SYS_fchownat:
10318fd04b83SRoger A. Faulkner 	case SYS_fstatat:
10328fd04b83SRoger A. Faulkner 	case SYS_fstatat64:
1033794f0adbSRoger A. Faulkner 	case SYS_mkdirat:
1034794f0adbSRoger A. Faulkner 	case SYS_mknodat:
10358fd04b83SRoger A. Faulkner 	case SYS_openat:
10368fd04b83SRoger A. Faulkner 	case SYS_openat64:
1037794f0adbSRoger A. Faulkner 	case SYS_readlinkat:
10388fd04b83SRoger A. Faulkner 	case SYS_unlinkat:
10398fd04b83SRoger A. Faulkner 		fd = uap->arg1;
10407c478bd9Sstevel@tonic-gate 		break;
1041794f0adbSRoger A. Faulkner 	case SYS_linkat:
10428fd04b83SRoger A. Faulkner 	case SYS_renameat:
10438fd04b83SRoger A. Faulkner 		if (argnum == 3)
10448fd04b83SRoger A. Faulkner 			fd = uap->arg3;
10458fd04b83SRoger A. Faulkner 		else
10468fd04b83SRoger A. Faulkner 			fd = uap->arg1;
10477c478bd9Sstevel@tonic-gate 		break;
1048794f0adbSRoger A. Faulkner 	case SYS_symlinkat:
10498fd04b83SRoger A. Faulkner 	case SYS_utimesys:
10508fd04b83SRoger A. Faulkner 		fd = uap->arg2;
10517c478bd9Sstevel@tonic-gate 		break;
1052c4d3e299SBrent Paulson 	case SYS_open:
1053c4d3e299SBrent Paulson 	case SYS_open64:
1054c4d3e299SBrent Paulson 		fd = AT_FDCWD;
1055c4d3e299SBrent Paulson 		break;
10567c478bd9Sstevel@tonic-gate 	default:
10577c478bd9Sstevel@tonic-gate 		return;
10587c478bd9Sstevel@tonic-gate 	}
10597c478bd9Sstevel@tonic-gate 
10607c478bd9Sstevel@tonic-gate 	if (tad->tad_atpath != NULL) {
10617c478bd9Sstevel@tonic-gate 		au_pathrele(tad->tad_atpath);
10627c478bd9Sstevel@tonic-gate 		tad->tad_atpath = NULL;
10637c478bd9Sstevel@tonic-gate 	}
1064c4d3e299SBrent Paulson 
10657c478bd9Sstevel@tonic-gate 	if (fd != AT_FDCWD) {
1066c4d3e299SBrent Paulson 		tad->tad_ctrl |= TAD_ATCALL;
1067c4d3e299SBrent Paulson 
1068c4d3e299SBrent Paulson 		if (tad->tad_scid == SYS_openat ||
1069c4d3e299SBrent Paulson 		    tad->tad_scid == SYS_openat64) {
1070c4d3e299SBrent Paulson 			fm = (uint_t)uap->arg3;
1071c4d3e299SBrent Paulson 			if (fm & (FXATTR | FXATTRDIROPEN)) {
1072c4d3e299SBrent Paulson 				tad->tad_ctrl |= TAD_ATTPATH;
1073c4d3e299SBrent Paulson 			}
1074c4d3e299SBrent Paulson 		}
1075c4d3e299SBrent Paulson 
1076fc960aa7SBrent Paulson 		if ((fp = getf(fd)) == NULL) {
10774a0fa546SMarek Pospisil 			tad->tad_ctrl |= TAD_NOPATH;
10787c478bd9Sstevel@tonic-gate 			return;
1079fc960aa7SBrent Paulson 		}
10807c478bd9Sstevel@tonic-gate 		fad = F2A(fp);
10817c478bd9Sstevel@tonic-gate 		ASSERT(fad);
1082fc960aa7SBrent Paulson 		if (fad->fad_aupath == NULL) {
10834a0fa546SMarek Pospisil 			tad->tad_ctrl |= TAD_NOPATH;
1084fc960aa7SBrent Paulson 			releasef(fd);
1085fc960aa7SBrent Paulson 			return;
1086fc960aa7SBrent Paulson 		}
10877c478bd9Sstevel@tonic-gate 		au_pathhold(fad->fad_aupath);
10887c478bd9Sstevel@tonic-gate 		tad->tad_atpath = fad->fad_aupath;
10897c478bd9Sstevel@tonic-gate 		releasef(fd);
10907c478bd9Sstevel@tonic-gate 	} else {
1091c4d3e299SBrent Paulson 		if (tad->tad_scid == SYS_open ||
1092c4d3e299SBrent Paulson 		    tad->tad_scid == SYS_open64) {
1093c4d3e299SBrent Paulson 			fm = (uint_t)uap->arg2;
1094c4d3e299SBrent Paulson 			if (fm & FXATTR) {
1095c4d3e299SBrent Paulson 				tad->tad_ctrl |= TAD_ATTPATH;
1096c4d3e299SBrent Paulson 			}
1097c4d3e299SBrent Paulson 			return;
1098c4d3e299SBrent Paulson 		}
10997c478bd9Sstevel@tonic-gate 		pad = P2A(curproc);
11007c478bd9Sstevel@tonic-gate 		mutex_enter(&pad->pad_lock);
11017c478bd9Sstevel@tonic-gate 		au_pathhold(pad->pad_cwd);
11027c478bd9Sstevel@tonic-gate 		tad->tad_atpath = pad->pad_cwd;
11037c478bd9Sstevel@tonic-gate 		mutex_exit(&pad->pad_lock);
11047c478bd9Sstevel@tonic-gate 	}
11057c478bd9Sstevel@tonic-gate }
11067c478bd9Sstevel@tonic-gate 
11077c478bd9Sstevel@tonic-gate void
audit_symlink_create(vnode_t * dvp,char * sname,char * target,int error)11087c478bd9Sstevel@tonic-gate audit_symlink_create(vnode_t *dvp, char *sname, char *target, int error)
11097c478bd9Sstevel@tonic-gate {
11107c478bd9Sstevel@tonic-gate 	t_audit_data_t *tad;
11117c478bd9Sstevel@tonic-gate 	vnode_t	*vp;
11127c478bd9Sstevel@tonic-gate 
11137c478bd9Sstevel@tonic-gate 	tad = U2A(u);
11147c478bd9Sstevel@tonic-gate 
11157c478bd9Sstevel@tonic-gate 	/* if not auditing this event, then do nothing */
11167c478bd9Sstevel@tonic-gate 	if (tad->tad_flag == 0)
11177c478bd9Sstevel@tonic-gate 		return;
11187c478bd9Sstevel@tonic-gate 
11197c478bd9Sstevel@tonic-gate 	au_uwrite(au_to_text(target));
11207c478bd9Sstevel@tonic-gate 
11217c478bd9Sstevel@tonic-gate 	if (error)
11227c478bd9Sstevel@tonic-gate 		return;
11237c478bd9Sstevel@tonic-gate 
1124da6c28aaSamw 	error = VOP_LOOKUP(dvp, sname, &vp, NULL, 0, NULL, CRED(),
112551d48dedSMarek Pospisil 	    NULL, NULL, NULL);
11267c478bd9Sstevel@tonic-gate 	if (error == 0) {
11277c478bd9Sstevel@tonic-gate 		audit_attributes(vp);
11287c478bd9Sstevel@tonic-gate 		VN_RELE(vp);
11297c478bd9Sstevel@tonic-gate 	}
11307c478bd9Sstevel@tonic-gate }
11317c478bd9Sstevel@tonic-gate 
11327c478bd9Sstevel@tonic-gate /*
11337c478bd9Sstevel@tonic-gate  * ROUTINE:	AUDIT_VNCREATE_START
11347c478bd9Sstevel@tonic-gate  * PURPOSE:	set flag so path name lookup in create will not add attribute
11357c478bd9Sstevel@tonic-gate  * CALLBY:	VN_CREATE
11367c478bd9Sstevel@tonic-gate  * NOTE:
11377c478bd9Sstevel@tonic-gate  * TODO:
11387c478bd9Sstevel@tonic-gate  * QUESTION:
11397c478bd9Sstevel@tonic-gate  */
11407c478bd9Sstevel@tonic-gate 
11417c478bd9Sstevel@tonic-gate void
audit_vncreate_start()11427c478bd9Sstevel@tonic-gate audit_vncreate_start()
11437c478bd9Sstevel@tonic-gate {
11447c478bd9Sstevel@tonic-gate 	t_audit_data_t *tad;
11457c478bd9Sstevel@tonic-gate 
11467c478bd9Sstevel@tonic-gate 	tad = U2A(u);
11474a0fa546SMarek Pospisil 	tad->tad_ctrl |= TAD_NOATTRB;
11487c478bd9Sstevel@tonic-gate }
11497c478bd9Sstevel@tonic-gate 
11507c478bd9Sstevel@tonic-gate /*
11517c478bd9Sstevel@tonic-gate  * ROUTINE:	AUDIT_VNCREATE_FINISH
11527c478bd9Sstevel@tonic-gate  * PURPOSE:
11537c478bd9Sstevel@tonic-gate  * CALLBY:	VN_CREATE
11547c478bd9Sstevel@tonic-gate  * NOTE:
11557c478bd9Sstevel@tonic-gate  * TODO:
11567c478bd9Sstevel@tonic-gate  * QUESTION:
11577c478bd9Sstevel@tonic-gate  */
11587c478bd9Sstevel@tonic-gate void
audit_vncreate_finish(struct vnode * vp,int error)11597c478bd9Sstevel@tonic-gate audit_vncreate_finish(struct vnode *vp, int error)
11607c478bd9Sstevel@tonic-gate {
11617c478bd9Sstevel@tonic-gate 	t_audit_data_t *tad;
11627c478bd9Sstevel@tonic-gate 
11637c478bd9Sstevel@tonic-gate 	if (error)
11647c478bd9Sstevel@tonic-gate 		return;
11657c478bd9Sstevel@tonic-gate 
11667c478bd9Sstevel@tonic-gate 	tad = U2A(u);
11677c478bd9Sstevel@tonic-gate 
11687c478bd9Sstevel@tonic-gate 	/* if not auditing this event, then do nothing */
11697c478bd9Sstevel@tonic-gate 	if (tad->tad_flag == 0)
11707c478bd9Sstevel@tonic-gate 		return;
11717c478bd9Sstevel@tonic-gate 
11724a0fa546SMarek Pospisil 	if (tad->tad_ctrl & TAD_TRUE_CREATE) {
11737c478bd9Sstevel@tonic-gate 		audit_attributes(vp);
11747c478bd9Sstevel@tonic-gate 	}
11757c478bd9Sstevel@tonic-gate 
11764a0fa546SMarek Pospisil 	if (tad->tad_ctrl & TAD_CORE) {
11777c478bd9Sstevel@tonic-gate 		audit_attributes(vp);
11784a0fa546SMarek Pospisil 		tad->tad_ctrl &= ~TAD_CORE;
11797c478bd9Sstevel@tonic-gate 	}
11807c478bd9Sstevel@tonic-gate 
11817c478bd9Sstevel@tonic-gate 	if (!error && ((tad->tad_event == AUE_MKNOD) ||
118251d48dedSMarek Pospisil 	    (tad->tad_event == AUE_MKDIR))) {
11837c478bd9Sstevel@tonic-gate 		audit_attributes(vp);
11847c478bd9Sstevel@tonic-gate 	}
11857c478bd9Sstevel@tonic-gate 
11867c478bd9Sstevel@tonic-gate 	/* for case where multiple lookups in one syscall (rename) */
11874a0fa546SMarek Pospisil 	tad->tad_ctrl &= ~TAD_NOATTRB;
11887c478bd9Sstevel@tonic-gate }
11897c478bd9Sstevel@tonic-gate 
11907c478bd9Sstevel@tonic-gate 
11917c478bd9Sstevel@tonic-gate 
11927c478bd9Sstevel@tonic-gate 
11937c478bd9Sstevel@tonic-gate 
11947c478bd9Sstevel@tonic-gate 
11957c478bd9Sstevel@tonic-gate 
11967c478bd9Sstevel@tonic-gate 
11977c478bd9Sstevel@tonic-gate /*
11987c478bd9Sstevel@tonic-gate  * ROUTINE:	AUDIT_EXEC
11997c478bd9Sstevel@tonic-gate  * PURPOSE:	Records the function arguments and environment variables
12007c478bd9Sstevel@tonic-gate  * CALLBY:	EXEC_ARGS
12017c478bd9Sstevel@tonic-gate  * NOTE:
12027c478bd9Sstevel@tonic-gate  * TODO:
12037c478bd9Sstevel@tonic-gate  * QUESTION:
12047c478bd9Sstevel@tonic-gate  */
12057c478bd9Sstevel@tonic-gate 
12067c478bd9Sstevel@tonic-gate void
audit_exec(const char * argstr,const char * envstr,ssize_t argc,ssize_t envc,cred_t * pfcred)12077c478bd9Sstevel@tonic-gate audit_exec(
12087c478bd9Sstevel@tonic-gate 	const char *argstr,	/* argument strings */
12097c478bd9Sstevel@tonic-gate 	const char *envstr,	/* environment strings */
12107c478bd9Sstevel@tonic-gate 	ssize_t argc,		/* total # arguments */
1211134a1f4eSCasper H.S. Dik 	ssize_t envc,		/* total # environment variables */
1212134a1f4eSCasper H.S. Dik 	cred_t *pfcred)		/* the additional privileges in a profile */
12137c478bd9Sstevel@tonic-gate {
12147c478bd9Sstevel@tonic-gate 	t_audit_data_t *tad;
12159e9e6ab8Spaulson 	au_kcontext_t	*kctx = GET_KCTX_PZ;
12167c478bd9Sstevel@tonic-gate 
12177c478bd9Sstevel@tonic-gate 	tad = U2A(u);
12187c478bd9Sstevel@tonic-gate 
12197c478bd9Sstevel@tonic-gate 	/* if not auditing this event, then do nothing */
12207c478bd9Sstevel@tonic-gate 	if (!tad->tad_flag)
12217c478bd9Sstevel@tonic-gate 		return;
12227c478bd9Sstevel@tonic-gate 
1223134a1f4eSCasper H.S. Dik 	if (pfcred != NULL) {
1224134a1f4eSCasper H.S. Dik 		p_audit_data_t *pad;
1225134a1f4eSCasper H.S. Dik 		cred_t *cr = CRED();
1226134a1f4eSCasper H.S. Dik 		priv_set_t pset = CR_IPRIV(cr);
12277c478bd9Sstevel@tonic-gate 
1228134a1f4eSCasper H.S. Dik 		pad = P2A(curproc);
1229134a1f4eSCasper H.S. Dik 
1230134a1f4eSCasper H.S. Dik 		/* It's a different event. */
1231134a1f4eSCasper H.S. Dik 		tad->tad_event = AUE_PFEXEC;
1232134a1f4eSCasper H.S. Dik 
1233134a1f4eSCasper H.S. Dik 		/* Add the current working directory to the audit trail. */
1234134a1f4eSCasper H.S. Dik 		if (pad->pad_cwd != NULL)
1235134a1f4eSCasper H.S. Dik 			au_uwrite(au_to_path(pad->pad_cwd));
1236134a1f4eSCasper H.S. Dik 
1237134a1f4eSCasper H.S. Dik 		/*
1238134a1f4eSCasper H.S. Dik 		 * The new credential is not yet in place when audit_exec
1239134a1f4eSCasper H.S. Dik 		 * is called.
1240134a1f4eSCasper H.S. Dik 		 * Compute the additional bits available in the new credential
1241134a1f4eSCasper H.S. Dik 		 * and the limit set.
1242134a1f4eSCasper H.S. Dik 		 */
1243134a1f4eSCasper H.S. Dik 		priv_inverse(&pset);
1244134a1f4eSCasper H.S. Dik 		priv_intersect(&CR_IPRIV(pfcred), &pset);
1245134a1f4eSCasper H.S. Dik 		if (!priv_isemptyset(&pset) ||
1246134a1f4eSCasper H.S. Dik 		    !priv_isequalset(&CR_LPRIV(pfcred), &CR_LPRIV(cr))) {
1247134a1f4eSCasper H.S. Dik 			au_uwrite(au_to_privset(
1248134a1f4eSCasper H.S. Dik 			    priv_getsetbynum(PRIV_INHERITABLE), &pset, AUT_PRIV,
1249134a1f4eSCasper H.S. Dik 			    0));
1250134a1f4eSCasper H.S. Dik 			au_uwrite(au_to_privset(priv_getsetbynum(PRIV_LIMIT),
1251134a1f4eSCasper H.S. Dik 			    &CR_LPRIV(pfcred), AUT_PRIV, 0));
1252134a1f4eSCasper H.S. Dik 		}
1253134a1f4eSCasper H.S. Dik 		/*
1254134a1f4eSCasper H.S. Dik 		 * Compare the uids & gids: create a process token if changed.
1255134a1f4eSCasper H.S. Dik 		 */
1256134a1f4eSCasper H.S. Dik 		if (crgetuid(cr) != crgetuid(pfcred) ||
1257134a1f4eSCasper H.S. Dik 		    crgetruid(cr) != crgetruid(pfcred) ||
1258134a1f4eSCasper H.S. Dik 		    crgetgid(cr) != crgetgid(pfcred) ||
1259134a1f4eSCasper H.S. Dik 		    crgetrgid(cr) != crgetrgid(pfcred)) {
1260134a1f4eSCasper H.S. Dik 			AUDIT_SETPROC(&(u_ad), cr, crgetauinfo(cr));
1261134a1f4eSCasper H.S. Dik 		}
12627c478bd9Sstevel@tonic-gate 	}
12637c478bd9Sstevel@tonic-gate 
1264134a1f4eSCasper H.S. Dik 	if (pfcred != NULL || (kctx->auk_policy & AUDIT_ARGV) != 0)
1265134a1f4eSCasper H.S. Dik 		au_uwrite(au_to_exec_args(argstr, argc));
1266134a1f4eSCasper H.S. Dik 
1267134a1f4eSCasper H.S. Dik 	if (kctx->auk_policy & AUDIT_ARGE)
12687c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_exec_env(envstr, envc));
12697c478bd9Sstevel@tonic-gate }
12707c478bd9Sstevel@tonic-gate 
12717c478bd9Sstevel@tonic-gate /*
12727c478bd9Sstevel@tonic-gate  * ROUTINE:	AUDIT_ENTERPROM
12737c478bd9Sstevel@tonic-gate  * PURPOSE:
12747c478bd9Sstevel@tonic-gate  * CALLBY:	KBDINPUT
12757c478bd9Sstevel@tonic-gate  *		ZSA_XSINT
12767c478bd9Sstevel@tonic-gate  * NOTE:
12777c478bd9Sstevel@tonic-gate  * TODO:
12787c478bd9Sstevel@tonic-gate  * QUESTION:
12797c478bd9Sstevel@tonic-gate  */
12807c478bd9Sstevel@tonic-gate void
audit_enterprom(int flg)12817c478bd9Sstevel@tonic-gate audit_enterprom(int flg)
12827c478bd9Sstevel@tonic-gate {
12837c478bd9Sstevel@tonic-gate 	token_t *rp = NULL;
12847c478bd9Sstevel@tonic-gate 	int sorf;
12857c478bd9Sstevel@tonic-gate 
12867c478bd9Sstevel@tonic-gate 	if (flg)
12877c478bd9Sstevel@tonic-gate 		sorf = AUM_SUCC;
12887c478bd9Sstevel@tonic-gate 	else
12897c478bd9Sstevel@tonic-gate 		sorf = AUM_FAIL;
12907c478bd9Sstevel@tonic-gate 
12917c478bd9Sstevel@tonic-gate 	AUDIT_ASYNC_START(rp, AUE_ENTERPROM, sorf);
12927c478bd9Sstevel@tonic-gate 
12937c478bd9Sstevel@tonic-gate 	au_write((caddr_t *)&(rp), au_to_text("kmdb"));
12947c478bd9Sstevel@tonic-gate 
12957c478bd9Sstevel@tonic-gate 	if (flg)
12967c478bd9Sstevel@tonic-gate 		au_write((caddr_t *)&(rp), au_to_return32(0, 0));
12977c478bd9Sstevel@tonic-gate 	else
12987c478bd9Sstevel@tonic-gate 		au_write((caddr_t *)&(rp), au_to_return32(ECANCELED, 0));
12997c478bd9Sstevel@tonic-gate 
1300*0f48f68dSToomas Soome 	AUDIT_ASYNC_FINISH(rp, AUE_ENTERPROM, 0, NULL);
13017c478bd9Sstevel@tonic-gate }
13027c478bd9Sstevel@tonic-gate 
13037c478bd9Sstevel@tonic-gate 
13047c478bd9Sstevel@tonic-gate /*
13057c478bd9Sstevel@tonic-gate  * ROUTINE:	AUDIT_EXITPROM
13067c478bd9Sstevel@tonic-gate  * PURPOSE:
13077c478bd9Sstevel@tonic-gate  * CALLBY:	KBDINPUT
13087c478bd9Sstevel@tonic-gate  *		ZSA_XSINT
13097c478bd9Sstevel@tonic-gate  * NOTE:
13107c478bd9Sstevel@tonic-gate  * TODO:
13117c478bd9Sstevel@tonic-gate  * QUESTION:
13127c478bd9Sstevel@tonic-gate  */
13137c478bd9Sstevel@tonic-gate void
audit_exitprom(int flg)13147c478bd9Sstevel@tonic-gate audit_exitprom(int flg)
13157c478bd9Sstevel@tonic-gate {
13167c478bd9Sstevel@tonic-gate 	int sorf;
13177c478bd9Sstevel@tonic-gate 	token_t *rp = NULL;
13187c478bd9Sstevel@tonic-gate 
13197c478bd9Sstevel@tonic-gate 	if (flg)
13207c478bd9Sstevel@tonic-gate 		sorf = AUM_SUCC;
13217c478bd9Sstevel@tonic-gate 	else
13227c478bd9Sstevel@tonic-gate 		sorf = AUM_FAIL;
13237c478bd9Sstevel@tonic-gate 
13247c478bd9Sstevel@tonic-gate 	AUDIT_ASYNC_START(rp, AUE_EXITPROM, sorf);
13257c478bd9Sstevel@tonic-gate 
13267c478bd9Sstevel@tonic-gate 	au_write((caddr_t *)&(rp), au_to_text("kmdb"));
13277c478bd9Sstevel@tonic-gate 
13287c478bd9Sstevel@tonic-gate 	if (flg)
13297c478bd9Sstevel@tonic-gate 		au_write((caddr_t *)&(rp), au_to_return32(0, 0));
13307c478bd9Sstevel@tonic-gate 	else
13317c478bd9Sstevel@tonic-gate 		au_write((caddr_t *)&(rp), au_to_return32(ECANCELED, 0));
13327c478bd9Sstevel@tonic-gate 
1333*0f48f68dSToomas Soome 	AUDIT_ASYNC_FINISH(rp, AUE_EXITPROM, 0, NULL);
13347c478bd9Sstevel@tonic-gate }
13357c478bd9Sstevel@tonic-gate 
13367c478bd9Sstevel@tonic-gate struct fcntla {
13377c478bd9Sstevel@tonic-gate 	int fdes;
13387c478bd9Sstevel@tonic-gate 	int cmd;
13397c478bd9Sstevel@tonic-gate 	intptr_t arg;
13407c478bd9Sstevel@tonic-gate };
13417c478bd9Sstevel@tonic-gate 
13427c478bd9Sstevel@tonic-gate 
13437c478bd9Sstevel@tonic-gate /*
13447c478bd9Sstevel@tonic-gate  * ROUTINE:	AUDIT_CHDIREC
13457c478bd9Sstevel@tonic-gate  * PURPOSE:
13467c478bd9Sstevel@tonic-gate  * CALLBY:	CHDIREC
13477c478bd9Sstevel@tonic-gate  * NOTE:	The main function of CHDIREC
13487c478bd9Sstevel@tonic-gate  * TODO:	Move the audit_chdirec hook above the VN_RELE in vncalls.c
13497c478bd9Sstevel@tonic-gate  * QUESTION:
13507c478bd9Sstevel@tonic-gate  */
13517c478bd9Sstevel@tonic-gate 
13527c478bd9Sstevel@tonic-gate /*ARGSUSED*/
13537c478bd9Sstevel@tonic-gate void
audit_chdirec(vnode_t * vp,vnode_t ** vpp)13547c478bd9Sstevel@tonic-gate audit_chdirec(vnode_t *vp, vnode_t **vpp)
13557c478bd9Sstevel@tonic-gate {
13567c478bd9Sstevel@tonic-gate 	int		chdir;
13577c478bd9Sstevel@tonic-gate 	int		fchdir;
13587c478bd9Sstevel@tonic-gate 	struct audit_path	**appp;
13597c478bd9Sstevel@tonic-gate 	struct file	*fp;
13607c478bd9Sstevel@tonic-gate 	f_audit_data_t *fad;
13617c478bd9Sstevel@tonic-gate 	p_audit_data_t *pad = P2A(curproc);
13627c478bd9Sstevel@tonic-gate 	t_audit_data_t *tad = T2A(curthread);
13637c478bd9Sstevel@tonic-gate 
13647c478bd9Sstevel@tonic-gate 	struct a {
13657c478bd9Sstevel@tonic-gate 		long fd;
13667c478bd9Sstevel@tonic-gate 	} *uap = (struct a *)ttolwp(curthread)->lwp_ap;
13677c478bd9Sstevel@tonic-gate 
13687c478bd9Sstevel@tonic-gate 	if ((tad->tad_scid == SYS_chdir) || (tad->tad_scid == SYS_chroot)) {
13697c478bd9Sstevel@tonic-gate 		chdir = tad->tad_scid == SYS_chdir;
13707c478bd9Sstevel@tonic-gate 		if (tad->tad_aupath) {
13717c478bd9Sstevel@tonic-gate 			mutex_enter(&pad->pad_lock);
13727c478bd9Sstevel@tonic-gate 			if (chdir)
13737c478bd9Sstevel@tonic-gate 				appp = &(pad->pad_cwd);
13747c478bd9Sstevel@tonic-gate 			else
13757c478bd9Sstevel@tonic-gate 				appp = &(pad->pad_root);
13767c478bd9Sstevel@tonic-gate 			au_pathrele(*appp);
13777c478bd9Sstevel@tonic-gate 			/* use tad hold */
13787c478bd9Sstevel@tonic-gate 			*appp = tad->tad_aupath;
13797c478bd9Sstevel@tonic-gate 			tad->tad_aupath = NULL;
13807c478bd9Sstevel@tonic-gate 			mutex_exit(&pad->pad_lock);
13817c478bd9Sstevel@tonic-gate 		}
13827c478bd9Sstevel@tonic-gate 	} else if ((tad->tad_scid == SYS_fchdir) ||
13837c478bd9Sstevel@tonic-gate 	    (tad->tad_scid == SYS_fchroot)) {
13847c478bd9Sstevel@tonic-gate 		fchdir = tad->tad_scid == SYS_fchdir;
13857c478bd9Sstevel@tonic-gate 		if ((fp = getf(uap->fd)) == NULL)
13867c478bd9Sstevel@tonic-gate 			return;
13877c478bd9Sstevel@tonic-gate 		fad = F2A(fp);
13887c478bd9Sstevel@tonic-gate 		if (fad->fad_aupath) {
13897c478bd9Sstevel@tonic-gate 			au_pathhold(fad->fad_aupath);
13907c478bd9Sstevel@tonic-gate 			mutex_enter(&pad->pad_lock);
13917c478bd9Sstevel@tonic-gate 			if (fchdir)
13927c478bd9Sstevel@tonic-gate 				appp = &(pad->pad_cwd);
13937c478bd9Sstevel@tonic-gate 			else
13947c478bd9Sstevel@tonic-gate 				appp = &(pad->pad_root);
13957c478bd9Sstevel@tonic-gate 			au_pathrele(*appp);
13967c478bd9Sstevel@tonic-gate 			*appp = fad->fad_aupath;
13977c478bd9Sstevel@tonic-gate 			mutex_exit(&pad->pad_lock);
13987c478bd9Sstevel@tonic-gate 			if (tad->tad_flag) {
13997c478bd9Sstevel@tonic-gate 				au_uwrite(au_to_path(fad->fad_aupath));
14007c478bd9Sstevel@tonic-gate 				audit_attributes(fp->f_vnode);
14017c478bd9Sstevel@tonic-gate 			}
14027c478bd9Sstevel@tonic-gate 		}
14037c478bd9Sstevel@tonic-gate 		releasef(uap->fd);
14047c478bd9Sstevel@tonic-gate 	}
14057c478bd9Sstevel@tonic-gate }
14067c478bd9Sstevel@tonic-gate 
14077c478bd9Sstevel@tonic-gate 
14087c478bd9Sstevel@tonic-gate /*
14097c478bd9Sstevel@tonic-gate  *	Audit hook for stream based socket and tli request.
14107c478bd9Sstevel@tonic-gate  *	Note that we do not have user context while executing
14117c478bd9Sstevel@tonic-gate  *	this code so we had to record them earlier during the
14127c478bd9Sstevel@tonic-gate  *	putmsg/getmsg to figure out which user we are dealing with.
14137c478bd9Sstevel@tonic-gate  */
14147c478bd9Sstevel@tonic-gate 
14157c478bd9Sstevel@tonic-gate /*ARGSUSED*/
14167c478bd9Sstevel@tonic-gate void
audit_sock(int type,queue_t * q,mblk_t * mp,int from)14177c478bd9Sstevel@tonic-gate audit_sock(
14187c478bd9Sstevel@tonic-gate 	int type,	/* type of tihdr.h header requests */
14197c478bd9Sstevel@tonic-gate 	queue_t *q,	/* contains the process and thread audit data */
14207c478bd9Sstevel@tonic-gate 	mblk_t *mp,	/* contains the tihdr.h header structures */
14217c478bd9Sstevel@tonic-gate 	int from)	/* timod or sockmod request */
14227c478bd9Sstevel@tonic-gate {
14237c478bd9Sstevel@tonic-gate 	int32_t    len;
14247c478bd9Sstevel@tonic-gate 	int32_t    offset;
14257c478bd9Sstevel@tonic-gate 	struct sockaddr_in *sock_data;
14267c478bd9Sstevel@tonic-gate 	struct T_conn_req *conn_req;
14277c478bd9Sstevel@tonic-gate 	struct T_conn_ind *conn_ind;
14287c478bd9Sstevel@tonic-gate 	struct T_unitdata_req *unitdata_req;
14297c478bd9Sstevel@tonic-gate 	struct T_unitdata_ind *unitdata_ind;
14307c478bd9Sstevel@tonic-gate 	au_state_t estate;
14317c478bd9Sstevel@tonic-gate 	t_audit_data_t *tad;
14327c478bd9Sstevel@tonic-gate 	caddr_t saved_thread_ptr;
14337c478bd9Sstevel@tonic-gate 	au_mask_t amask;
14347c478bd9Sstevel@tonic-gate 	const auditinfo_addr_t *ainfo;
14357c478bd9Sstevel@tonic-gate 	au_kcontext_t	*kctx;
14367c478bd9Sstevel@tonic-gate 
14377c478bd9Sstevel@tonic-gate 	if (q->q_stream == NULL)
14387c478bd9Sstevel@tonic-gate 		return;
14397c478bd9Sstevel@tonic-gate 	mutex_enter(&q->q_stream->sd_lock);
14407c478bd9Sstevel@tonic-gate 	/* are we being audited */
14417c478bd9Sstevel@tonic-gate 	saved_thread_ptr = q->q_stream->sd_t_audit_data;
14427c478bd9Sstevel@tonic-gate 	/* no pointer to thread, nothing to do */
14437c478bd9Sstevel@tonic-gate 	if (saved_thread_ptr == NULL) {
14447c478bd9Sstevel@tonic-gate 		mutex_exit(&q->q_stream->sd_lock);
14457c478bd9Sstevel@tonic-gate 		return;
14467c478bd9Sstevel@tonic-gate 	}
14477c478bd9Sstevel@tonic-gate 	/* only allow one addition of a record token */
14487c478bd9Sstevel@tonic-gate 	q->q_stream->sd_t_audit_data = NULL;
14497c478bd9Sstevel@tonic-gate 	/*
14507c478bd9Sstevel@tonic-gate 	 * thread is not the one being audited, then nothing to do
14517c478bd9Sstevel@tonic-gate 	 * This could be the stream thread handling the module
14527c478bd9Sstevel@tonic-gate 	 * service routine. In this case, the context for the audit
14537c478bd9Sstevel@tonic-gate 	 * record can no longer be assumed. Simplest to just drop
14547c478bd9Sstevel@tonic-gate 	 * the operation.
14557c478bd9Sstevel@tonic-gate 	 */
14567c478bd9Sstevel@tonic-gate 	if (curthread != (kthread_id_t)saved_thread_ptr) {
14577c478bd9Sstevel@tonic-gate 		mutex_exit(&q->q_stream->sd_lock);
14587c478bd9Sstevel@tonic-gate 		return;
14597c478bd9Sstevel@tonic-gate 	}
14607c478bd9Sstevel@tonic-gate 	if (curthread->t_sysnum >= SYS_so_socket &&
14617c478bd9Sstevel@tonic-gate 	    curthread->t_sysnum <= SYS_sockconfig) {
14627c478bd9Sstevel@tonic-gate 		mutex_exit(&q->q_stream->sd_lock);
14637c478bd9Sstevel@tonic-gate 		return;
14647c478bd9Sstevel@tonic-gate 	}
14657c478bd9Sstevel@tonic-gate 	mutex_exit(&q->q_stream->sd_lock);
14667c478bd9Sstevel@tonic-gate 	/*
14677c478bd9Sstevel@tonic-gate 	 * we know that the thread that did the put/getmsg is the
14687c478bd9Sstevel@tonic-gate 	 * one running. Now we can get the TAD and see if we should
14697c478bd9Sstevel@tonic-gate 	 * add an audit token.
14707c478bd9Sstevel@tonic-gate 	 */
14717c478bd9Sstevel@tonic-gate 	tad = U2A(u);
14727c478bd9Sstevel@tonic-gate 
14739e9e6ab8Spaulson 	kctx = GET_KCTX_PZ;
14747c478bd9Sstevel@tonic-gate 
14757c478bd9Sstevel@tonic-gate 	/* proceed ONLY if user is being audited */
14767c478bd9Sstevel@tonic-gate 	if (!tad->tad_flag)
14777c478bd9Sstevel@tonic-gate 		return;
14787c478bd9Sstevel@tonic-gate 
14797c478bd9Sstevel@tonic-gate 	ainfo = crgetauinfo(CRED());
14807c478bd9Sstevel@tonic-gate 	if (ainfo == NULL)
14817c478bd9Sstevel@tonic-gate 		return;
14827c478bd9Sstevel@tonic-gate 	amask = ainfo->ai_mask;
14837c478bd9Sstevel@tonic-gate 
14847c478bd9Sstevel@tonic-gate 	/*
14857c478bd9Sstevel@tonic-gate 	 * Figure out the type of stream networking request here.
14867c478bd9Sstevel@tonic-gate 	 * Note that getmsg and putmsg are always preselected
14877c478bd9Sstevel@tonic-gate 	 * because during the beginning of the system call we have
14887c478bd9Sstevel@tonic-gate 	 * not yet figure out which of the socket or tli request
14897c478bd9Sstevel@tonic-gate 	 * we are looking at until we are here. So we need to check
14907c478bd9Sstevel@tonic-gate 	 * against that specific request and reset the type of event.
14917c478bd9Sstevel@tonic-gate 	 */
14927c478bd9Sstevel@tonic-gate 	switch (type) {
14937c478bd9Sstevel@tonic-gate 	case T_CONN_REQ:	/* connection request */
14947c478bd9Sstevel@tonic-gate 		conn_req = (struct T_conn_req *)mp->b_rptr;
14957c478bd9Sstevel@tonic-gate 		if (conn_req->DEST_offset < sizeof (struct T_conn_req))
14967c478bd9Sstevel@tonic-gate 			return;
14977c478bd9Sstevel@tonic-gate 		offset = conn_req->DEST_offset;
14987c478bd9Sstevel@tonic-gate 		len = conn_req->DEST_length;
14997c478bd9Sstevel@tonic-gate 		estate = kctx->auk_ets[AUE_SOCKCONNECT];
15007c478bd9Sstevel@tonic-gate 		if (amask.as_success & estate || amask.as_failure & estate) {
15017c478bd9Sstevel@tonic-gate 			tad->tad_event = AUE_SOCKCONNECT;
15027c478bd9Sstevel@tonic-gate 			break;
15037c478bd9Sstevel@tonic-gate 		} else {
15047c478bd9Sstevel@tonic-gate 			return;
15057c478bd9Sstevel@tonic-gate 		}
15067c478bd9Sstevel@tonic-gate 	case T_CONN_IND:	 /* connectionless receive request */
15077c478bd9Sstevel@tonic-gate 		conn_ind = (struct T_conn_ind *)mp->b_rptr;
15087c478bd9Sstevel@tonic-gate 		if (conn_ind->SRC_offset < sizeof (struct T_conn_ind))
15097c478bd9Sstevel@tonic-gate 			return;
15107c478bd9Sstevel@tonic-gate 		offset = conn_ind->SRC_offset;
15117c478bd9Sstevel@tonic-gate 		len = conn_ind->SRC_length;
15127c478bd9Sstevel@tonic-gate 		estate = kctx->auk_ets[AUE_SOCKACCEPT];
15137c478bd9Sstevel@tonic-gate 		if (amask.as_success & estate || amask.as_failure & estate) {
15147c478bd9Sstevel@tonic-gate 			tad->tad_event = AUE_SOCKACCEPT;
15157c478bd9Sstevel@tonic-gate 			break;
15167c478bd9Sstevel@tonic-gate 		} else {
15177c478bd9Sstevel@tonic-gate 			return;
15187c478bd9Sstevel@tonic-gate 		}
15197c478bd9Sstevel@tonic-gate 	case T_UNITDATA_REQ:	 /* connectionless send request */
15207c478bd9Sstevel@tonic-gate 		unitdata_req = (struct T_unitdata_req *)mp->b_rptr;
15217c478bd9Sstevel@tonic-gate 		if (unitdata_req->DEST_offset < sizeof (struct T_unitdata_req))
15227c478bd9Sstevel@tonic-gate 			return;
15237c478bd9Sstevel@tonic-gate 		offset = unitdata_req->DEST_offset;
15247c478bd9Sstevel@tonic-gate 		len = unitdata_req->DEST_length;
15257c478bd9Sstevel@tonic-gate 		estate = kctx->auk_ets[AUE_SOCKSEND];
15267c478bd9Sstevel@tonic-gate 		if (amask.as_success & estate || amask.as_failure & estate) {
15277c478bd9Sstevel@tonic-gate 			tad->tad_event = AUE_SOCKSEND;
15287c478bd9Sstevel@tonic-gate 			break;
15297c478bd9Sstevel@tonic-gate 		} else {
15307c478bd9Sstevel@tonic-gate 			return;
15317c478bd9Sstevel@tonic-gate 		}
15327c478bd9Sstevel@tonic-gate 	case T_UNITDATA_IND:	 /* connectionless receive request */
15337c478bd9Sstevel@tonic-gate 		unitdata_ind = (struct T_unitdata_ind *)mp->b_rptr;
15347c478bd9Sstevel@tonic-gate 		if (unitdata_ind->SRC_offset < sizeof (struct T_unitdata_ind))
15357c478bd9Sstevel@tonic-gate 			return;
15367c478bd9Sstevel@tonic-gate 		offset = unitdata_ind->SRC_offset;
15377c478bd9Sstevel@tonic-gate 		len = unitdata_ind->SRC_length;
15387c478bd9Sstevel@tonic-gate 		estate = kctx->auk_ets[AUE_SOCKRECEIVE];
15397c478bd9Sstevel@tonic-gate 		if (amask.as_success & estate || amask.as_failure & estate) {
15407c478bd9Sstevel@tonic-gate 			tad->tad_event = AUE_SOCKRECEIVE;
15417c478bd9Sstevel@tonic-gate 			break;
15427c478bd9Sstevel@tonic-gate 		} else {
15437c478bd9Sstevel@tonic-gate 			return;
15447c478bd9Sstevel@tonic-gate 		}
15457c478bd9Sstevel@tonic-gate 	default:
15467c478bd9Sstevel@tonic-gate 		return;
15477c478bd9Sstevel@tonic-gate 	}
15487c478bd9Sstevel@tonic-gate 
15497c478bd9Sstevel@tonic-gate 	/*
15507c478bd9Sstevel@tonic-gate 	 * we are only interested in tcp stream connections,
15517c478bd9Sstevel@tonic-gate 	 * not unix domain stuff
15527c478bd9Sstevel@tonic-gate 	 */
15537c478bd9Sstevel@tonic-gate 	if ((len < 0) || (len > sizeof (struct sockaddr_in))) {
15547c478bd9Sstevel@tonic-gate 		tad->tad_event = AUE_GETMSG;
15557c478bd9Sstevel@tonic-gate 		return;
15567c478bd9Sstevel@tonic-gate 	}
15577c478bd9Sstevel@tonic-gate 	/* skip over TPI header and point to the ip address */
15587c478bd9Sstevel@tonic-gate 	sock_data = (struct sockaddr_in *)((char *)mp->b_rptr + offset);
15597c478bd9Sstevel@tonic-gate 
15607c478bd9Sstevel@tonic-gate 	switch (sock_data->sin_family) {
15617c478bd9Sstevel@tonic-gate 	case AF_INET:
15627c478bd9Sstevel@tonic-gate 		au_write(&(tad->tad_ad), au_to_sock_inet(sock_data));
15637c478bd9Sstevel@tonic-gate 		break;
15647c478bd9Sstevel@tonic-gate 	default:	/* reset to AUE_PUTMSG if not a inet request */
15657c478bd9Sstevel@tonic-gate 		tad->tad_event = AUE_GETMSG;
15667c478bd9Sstevel@tonic-gate 		break;
15677c478bd9Sstevel@tonic-gate 	}
15687c478bd9Sstevel@tonic-gate }
15697c478bd9Sstevel@tonic-gate 
15707c478bd9Sstevel@tonic-gate 
15717c478bd9Sstevel@tonic-gate static void
add_return_token(caddr_t * ad,unsigned int scid,int err,int rval)15727c478bd9Sstevel@tonic-gate add_return_token(caddr_t *ad, unsigned int scid, int err, int rval)
15737c478bd9Sstevel@tonic-gate {
15747c478bd9Sstevel@tonic-gate 	unsigned int sy_flags;
15757c478bd9Sstevel@tonic-gate 
15767c478bd9Sstevel@tonic-gate #ifdef _SYSCALL32_IMPL
1577950d6705SPaul Wernau 	/*
1578950d6705SPaul Wernau 	 * Guard against t_lwp being NULL when this function is called
1579950d6705SPaul Wernau 	 * from a kernel queue instead of from a direct system call.
1580950d6705SPaul Wernau 	 * In that case, assume the running kernel data model.
1581950d6705SPaul Wernau 	 */
1582950d6705SPaul Wernau 	if ((curthread->t_lwp == NULL) || (lwp_getdatamodel(
1583950d6705SPaul Wernau 	    ttolwp(curthread)) == DATAMODEL_NATIVE))
15847c478bd9Sstevel@tonic-gate 		sy_flags = sysent[scid].sy_flags & SE_RVAL_MASK;
15857c478bd9Sstevel@tonic-gate 	else
15867c478bd9Sstevel@tonic-gate 		sy_flags = sysent32[scid].sy_flags & SE_RVAL_MASK;
15877c478bd9Sstevel@tonic-gate #else
15887c478bd9Sstevel@tonic-gate 		sy_flags = sysent[scid].sy_flags & SE_RVAL_MASK;
15897c478bd9Sstevel@tonic-gate #endif
15907c478bd9Sstevel@tonic-gate 
15917c478bd9Sstevel@tonic-gate 	if (sy_flags == SE_64RVAL)
15927c478bd9Sstevel@tonic-gate 		au_write(ad, au_to_return64(err, rval));
15937c478bd9Sstevel@tonic-gate 	else
15947c478bd9Sstevel@tonic-gate 		au_write(ad, au_to_return32(err, rval));
15957c478bd9Sstevel@tonic-gate 
15967c478bd9Sstevel@tonic-gate }
15977c478bd9Sstevel@tonic-gate 
15987c478bd9Sstevel@tonic-gate /*ARGSUSED*/
15997c478bd9Sstevel@tonic-gate void
audit_fdsend(int fd,struct file * fp,int error)1600d2a70789SRichard Lowe audit_fdsend(int fd, struct file *fp, int error)
16017c478bd9Sstevel@tonic-gate {
16027c478bd9Sstevel@tonic-gate 	t_audit_data_t *tad;	/* current thread */
16037c478bd9Sstevel@tonic-gate 	f_audit_data_t *fad;	/* per file audit structure */
16047c478bd9Sstevel@tonic-gate 	struct vnode *vp;	/* for file attributes */
16057c478bd9Sstevel@tonic-gate 
16067c478bd9Sstevel@tonic-gate 	/* is this system call being audited */
16077c478bd9Sstevel@tonic-gate 	tad = U2A(u);
16087c478bd9Sstevel@tonic-gate 	ASSERT(tad != (t_audit_data_t *)0);
16097c478bd9Sstevel@tonic-gate 	if (!tad->tad_flag)
16107c478bd9Sstevel@tonic-gate 		return;
16117c478bd9Sstevel@tonic-gate 
16127c478bd9Sstevel@tonic-gate 	fad = F2A(fp);
16137c478bd9Sstevel@tonic-gate 
16147c478bd9Sstevel@tonic-gate 	/* add path and file attributes */
16157c478bd9Sstevel@tonic-gate 	if (fad != NULL && fad->fad_aupath != NULL) {
16167c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_arg32(0, "send fd", (uint32_t)fd));
16177c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_path(fad->fad_aupath));
16187c478bd9Sstevel@tonic-gate 	} else {
16197c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_arg32(0, "send fd", (uint32_t)fd));
16207c478bd9Sstevel@tonic-gate #ifdef _LP64
16217c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_arg64(0, "no path", (uint64_t)fp));
16227c478bd9Sstevel@tonic-gate #else
16237c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_arg32(0, "no path", (uint32_t)fp));
16247c478bd9Sstevel@tonic-gate #endif
16257c478bd9Sstevel@tonic-gate 	}
16267c478bd9Sstevel@tonic-gate 	vp = fp->f_vnode;	/* include vnode attributes */
16277c478bd9Sstevel@tonic-gate 	audit_attributes(vp);
16287c478bd9Sstevel@tonic-gate }
16297c478bd9Sstevel@tonic-gate 
16307c478bd9Sstevel@tonic-gate /*
1631da6c28aaSamw  * Record privileges successfully used and we attempted to use but
16327c478bd9Sstevel@tonic-gate  * didn't have.
16337c478bd9Sstevel@tonic-gate  */
16347c478bd9Sstevel@tonic-gate void
audit_priv(int priv,const priv_set_t * set,int flag)16357c478bd9Sstevel@tonic-gate audit_priv(int priv, const priv_set_t *set, int flag)
16367c478bd9Sstevel@tonic-gate {
16377c478bd9Sstevel@tonic-gate 	t_audit_data_t *tad;
16387c478bd9Sstevel@tonic-gate 	int sbit;
16397c478bd9Sstevel@tonic-gate 	priv_set_t *target;
16407c478bd9Sstevel@tonic-gate 
16417c478bd9Sstevel@tonic-gate 	/* Make sure this isn't being called in an interrupt context */
16427c478bd9Sstevel@tonic-gate 	ASSERT(servicing_interrupt() == 0);
16437c478bd9Sstevel@tonic-gate 
16447c478bd9Sstevel@tonic-gate 	tad = U2A(u);
16457c478bd9Sstevel@tonic-gate 
16467c478bd9Sstevel@tonic-gate 	if (tad->tad_flag == 0)
16477c478bd9Sstevel@tonic-gate 		return;
16487c478bd9Sstevel@tonic-gate 
16497c478bd9Sstevel@tonic-gate 	target = flag ? &tad->tad_sprivs : &tad->tad_fprivs;
16507c478bd9Sstevel@tonic-gate 	sbit = flag ? PAD_SPRIVUSE : PAD_FPRIVUSE;
16517c478bd9Sstevel@tonic-gate 
16527c478bd9Sstevel@tonic-gate 	/* Tell audit_success() and audit_finish() that we saw this case */
16537c478bd9Sstevel@tonic-gate 	if (!(tad->tad_evmod & sbit)) {
16547c478bd9Sstevel@tonic-gate 		/* Clear set first time around */
16557c478bd9Sstevel@tonic-gate 		priv_emptyset(target);
16567c478bd9Sstevel@tonic-gate 		tad->tad_evmod |= sbit;
16577c478bd9Sstevel@tonic-gate 	}
16587c478bd9Sstevel@tonic-gate 
16597c478bd9Sstevel@tonic-gate 	/* Save the privileges in the tad */
16607c478bd9Sstevel@tonic-gate 	if (priv == PRIV_ALL) {
16617c478bd9Sstevel@tonic-gate 		priv_fillset(target);
16627c478bd9Sstevel@tonic-gate 	} else {
16637c478bd9Sstevel@tonic-gate 		ASSERT(set != NULL || priv != PRIV_NONE);
16647c478bd9Sstevel@tonic-gate 		if (set != NULL)
16657c478bd9Sstevel@tonic-gate 			priv_union(set, target);
16667c478bd9Sstevel@tonic-gate 		if (priv != PRIV_NONE)
16677c478bd9Sstevel@tonic-gate 			priv_addset(target, priv);
16687c478bd9Sstevel@tonic-gate 	}
16697c478bd9Sstevel@tonic-gate }
16707c478bd9Sstevel@tonic-gate 
1671d2a70789SRichard Lowe /*
1672d2a70789SRichard Lowe  * Audit the psecflags() system call; the set name, current value, and delta
1673d2a70789SRichard Lowe  * are put in the audit trail.
1674d2a70789SRichard Lowe  */
1675d2a70789SRichard Lowe void
audit_psecflags(proc_t * p,psecflagwhich_t which,const secflagdelta_t * psd)1676d2a70789SRichard Lowe audit_psecflags(proc_t *p,
1677d2a70789SRichard Lowe     psecflagwhich_t which,
1678d2a70789SRichard Lowe     const secflagdelta_t *psd)
1679d2a70789SRichard Lowe {
1680d2a70789SRichard Lowe 	t_audit_data_t *tad;
1681d2a70789SRichard Lowe 	secflagset_t new;
1682d2a70789SRichard Lowe 	const secflagset_t *old;
1683d2a70789SRichard Lowe 	const char *s;
1684d2a70789SRichard Lowe 	cred_t *cr;
1685d2a70789SRichard Lowe 	pid_t pid;
1686d2a70789SRichard Lowe 	const auditinfo_addr_t	*ainfo;
1687d2a70789SRichard Lowe 	const psecflags_t *psec = &p->p_secflags;
1688d2a70789SRichard Lowe 
1689d2a70789SRichard Lowe 	tad = U2A(u);
1690d2a70789SRichard Lowe 
1691d2a70789SRichard Lowe 	if (tad->tad_flag == 0)
1692d2a70789SRichard Lowe 		return;
1693d2a70789SRichard Lowe 
1694d2a70789SRichard Lowe 	switch (which) {
1695d2a70789SRichard Lowe 	case PSF_EFFECTIVE:
1696d2a70789SRichard Lowe 		s = "effective";
1697d2a70789SRichard Lowe 		old = &psec->psf_effective;
1698d2a70789SRichard Lowe 		break;
1699d2a70789SRichard Lowe 	case PSF_INHERIT:
1700d2a70789SRichard Lowe 		s = "inherit";
1701d2a70789SRichard Lowe 		old = &psec->psf_inherit;
1702d2a70789SRichard Lowe 		break;
1703d2a70789SRichard Lowe 	case PSF_LOWER:
1704d2a70789SRichard Lowe 		s = "lower";
1705d2a70789SRichard Lowe 		old = &psec->psf_lower;
1706d2a70789SRichard Lowe 		break;
1707d2a70789SRichard Lowe 	case PSF_UPPER:
1708d2a70789SRichard Lowe 		s = "upper";
1709d2a70789SRichard Lowe 		old = &psec->psf_upper;
1710d2a70789SRichard Lowe 		break;
1711d2a70789SRichard Lowe 	}
1712d2a70789SRichard Lowe 
1713d2a70789SRichard Lowe 	secflags_copy(&new, old);
1714d2a70789SRichard Lowe 	secflags_apply_delta(&new, psd);
1715d2a70789SRichard Lowe 
1716d2a70789SRichard Lowe 	au_uwrite(au_to_secflags(s, *old));
1717d2a70789SRichard Lowe 	au_uwrite(au_to_secflags(s, new));
1718d2a70789SRichard Lowe 
1719d2a70789SRichard Lowe 	ASSERT(mutex_owned(&p->p_lock));
1720d2a70789SRichard Lowe 	mutex_enter(&p->p_crlock);
1721d2a70789SRichard Lowe 
1722d2a70789SRichard Lowe 	pid = p->p_pid;
1723d2a70789SRichard Lowe 	crhold(cr = p->p_cred);
1724d2a70789SRichard Lowe 	mutex_exit(&p->p_crlock);
1725d2a70789SRichard Lowe 
1726d2a70789SRichard Lowe 	if ((ainfo = crgetauinfo(cr)) == NULL) {
1727d2a70789SRichard Lowe 		crfree(cr);
1728d2a70789SRichard Lowe 		return;
1729d2a70789SRichard Lowe 	}
1730d2a70789SRichard Lowe 
1731d2a70789SRichard Lowe 	AUDIT_SETPROC_GENERIC(&(u_ad), cr, ainfo, pid);
1732d2a70789SRichard Lowe 
1733d2a70789SRichard Lowe 	crfree(cr);
1734d2a70789SRichard Lowe }
1735d2a70789SRichard Lowe 
17367c478bd9Sstevel@tonic-gate /*
17377c478bd9Sstevel@tonic-gate  * Audit the setpriv() system call; the operation, the set name and
17387c478bd9Sstevel@tonic-gate  * the current value as well as the set argument are put in the
17397c478bd9Sstevel@tonic-gate  * audit trail.
17407c478bd9Sstevel@tonic-gate  */
17417c478bd9Sstevel@tonic-gate void
audit_setppriv(int op,int set,const priv_set_t * newpriv,const cred_t * ocr)17427c478bd9Sstevel@tonic-gate audit_setppriv(int op, int set, const priv_set_t *newpriv, const cred_t *ocr)
17437c478bd9Sstevel@tonic-gate {
17447c478bd9Sstevel@tonic-gate 	t_audit_data_t *tad;
17457c478bd9Sstevel@tonic-gate 	const priv_set_t *oldpriv;
17467c478bd9Sstevel@tonic-gate 	priv_set_t report;
17477c478bd9Sstevel@tonic-gate 	const char *setname;
17487c478bd9Sstevel@tonic-gate 
17497c478bd9Sstevel@tonic-gate 	tad = U2A(u);
17507c478bd9Sstevel@tonic-gate 
17517c478bd9Sstevel@tonic-gate 	if (tad->tad_flag == 0)
17527c478bd9Sstevel@tonic-gate 		return;
17537c478bd9Sstevel@tonic-gate 
17547c478bd9Sstevel@tonic-gate 	oldpriv = priv_getset(ocr, set);
17557c478bd9Sstevel@tonic-gate 
17567c478bd9Sstevel@tonic-gate 	/* Generate the actual record, include the before and after */
17577c478bd9Sstevel@tonic-gate 	au_uwrite(au_to_arg32(2, "op", op));
17587c478bd9Sstevel@tonic-gate 	setname = priv_getsetbynum(set);
17597c478bd9Sstevel@tonic-gate 
17607c478bd9Sstevel@tonic-gate 	switch (op) {
17617c478bd9Sstevel@tonic-gate 	case PRIV_OFF:
17627c478bd9Sstevel@tonic-gate 		/* Report privileges actually switched off */
17637c478bd9Sstevel@tonic-gate 		report = *oldpriv;
17647c478bd9Sstevel@tonic-gate 		priv_intersect(newpriv, &report);
17657c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_privset(setname, &report, AUT_PRIV, 0));
17667c478bd9Sstevel@tonic-gate 		break;
17677c478bd9Sstevel@tonic-gate 	case PRIV_ON:
17687c478bd9Sstevel@tonic-gate 		/* Report privileges actually switched on */
17697c478bd9Sstevel@tonic-gate 		report = *oldpriv;
17707c478bd9Sstevel@tonic-gate 		priv_inverse(&report);
17717c478bd9Sstevel@tonic-gate 		priv_intersect(newpriv, &report);
17727c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_privset(setname, &report, AUT_PRIV, 0));
17737c478bd9Sstevel@tonic-gate 		break;
17747c478bd9Sstevel@tonic-gate 	case PRIV_SET:
17757c478bd9Sstevel@tonic-gate 		/* Report before and after */
17767c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_privset(setname, oldpriv, AUT_PRIV, 0));
17777c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_privset(setname, newpriv, AUT_PRIV, 0));
17787c478bd9Sstevel@tonic-gate 		break;
17797c478bd9Sstevel@tonic-gate 	}
17807c478bd9Sstevel@tonic-gate }
17817c478bd9Sstevel@tonic-gate 
17827c478bd9Sstevel@tonic-gate /*
17837c478bd9Sstevel@tonic-gate  * Dump the full device policy setting in the audit trail.
17847c478bd9Sstevel@tonic-gate  */
17857c478bd9Sstevel@tonic-gate void
audit_devpolicy(int nitems,const devplcysys_t * items)17867c478bd9Sstevel@tonic-gate audit_devpolicy(int nitems, const devplcysys_t *items)
17877c478bd9Sstevel@tonic-gate {
17887c478bd9Sstevel@tonic-gate 	t_audit_data_t *tad;
17897c478bd9Sstevel@tonic-gate 	int i;
17907c478bd9Sstevel@tonic-gate 
17917c478bd9Sstevel@tonic-gate 	tad = U2A(u);
17927c478bd9Sstevel@tonic-gate 
17937c478bd9Sstevel@tonic-gate 	if (tad->tad_flag == 0)
17947c478bd9Sstevel@tonic-gate 		return;
17957c478bd9Sstevel@tonic-gate 
17967c478bd9Sstevel@tonic-gate 	for (i = 0; i < nitems; i++) {
17977c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_arg32(2, "major", items[i].dps_maj));
17987c478bd9Sstevel@tonic-gate 		if (items[i].dps_minornm[0] == '\0') {
17997c478bd9Sstevel@tonic-gate 			au_uwrite(au_to_arg32(2, "lomin", items[i].dps_lomin));
18007c478bd9Sstevel@tonic-gate 			au_uwrite(au_to_arg32(2, "himin", items[i].dps_himin));
18017c478bd9Sstevel@tonic-gate 		} else
18027c478bd9Sstevel@tonic-gate 			au_uwrite(au_to_text(items[i].dps_minornm));
18037c478bd9Sstevel@tonic-gate 
18047c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_privset("read", &items[i].dps_rdp,
18057c478bd9Sstevel@tonic-gate 		    AUT_PRIV, 0));
18067c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_privset("write", &items[i].dps_wrp,
18077c478bd9Sstevel@tonic-gate 		    AUT_PRIV, 0));
18087c478bd9Sstevel@tonic-gate 	}
18097c478bd9Sstevel@tonic-gate }
18107c478bd9Sstevel@tonic-gate 
18117c478bd9Sstevel@tonic-gate /*ARGSUSED*/
18127c478bd9Sstevel@tonic-gate void
audit_fdrecv(int fd,struct file * fp)1813d2a70789SRichard Lowe audit_fdrecv(int fd, struct file *fp)
18147c478bd9Sstevel@tonic-gate {
18157c478bd9Sstevel@tonic-gate 	t_audit_data_t *tad;	/* current thread */
18167c478bd9Sstevel@tonic-gate 	f_audit_data_t *fad;	/* per file audit structure */
18177c478bd9Sstevel@tonic-gate 	struct vnode *vp;	/* for file attributes */
18187c478bd9Sstevel@tonic-gate 
18197c478bd9Sstevel@tonic-gate 	/* is this system call being audited */
18207c478bd9Sstevel@tonic-gate 	tad = U2A(u);
18217c478bd9Sstevel@tonic-gate 	ASSERT(tad != (t_audit_data_t *)0);
18227c478bd9Sstevel@tonic-gate 	if (!tad->tad_flag)
18237c478bd9Sstevel@tonic-gate 		return;
18247c478bd9Sstevel@tonic-gate 
18257c478bd9Sstevel@tonic-gate 	fad = F2A(fp);
18267c478bd9Sstevel@tonic-gate 
18277c478bd9Sstevel@tonic-gate 	/* add path and file attributes */
18287c478bd9Sstevel@tonic-gate 	if (fad != NULL && fad->fad_aupath != NULL) {
18297c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_arg32(0, "recv fd", (uint32_t)fd));
18307c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_path(fad->fad_aupath));
18317c478bd9Sstevel@tonic-gate 	} else {
18327c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_arg32(0, "recv fd", (uint32_t)fd));
18337c478bd9Sstevel@tonic-gate #ifdef _LP64
18347c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_arg64(0, "no path", (uint64_t)fp));
18357c478bd9Sstevel@tonic-gate #else
18367c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_arg32(0, "no path", (uint32_t)fp));
18377c478bd9Sstevel@tonic-gate #endif
18387c478bd9Sstevel@tonic-gate 	}
18397c478bd9Sstevel@tonic-gate 	vp = fp->f_vnode;	/* include vnode attributes */
18407c478bd9Sstevel@tonic-gate 	audit_attributes(vp);
18417c478bd9Sstevel@tonic-gate }
18427c478bd9Sstevel@tonic-gate 
18437c478bd9Sstevel@tonic-gate /*
18447c478bd9Sstevel@tonic-gate  * ROUTINE:	AUDIT_CRYPTOADM
18457c478bd9Sstevel@tonic-gate  * PURPOSE:	Records arguments to administrative ioctls on /dev/cryptoadm
18467c478bd9Sstevel@tonic-gate  * CALLBY:	CRYPTO_LOAD_DEV_DISABLED, CRYPTO_LOAD_SOFT_DISABLED,
18477c478bd9Sstevel@tonic-gate  *		CRYPTO_UNLOAD_SOFT_MODULE, CRYPTO_LOAD_SOFT_CONFIG,
18487c478bd9Sstevel@tonic-gate  *		CRYPTO_POOL_CREATE, CRYPTO_POOL_WAIT, CRYPTO_POOL_RUN,
18497c478bd9Sstevel@tonic-gate  *		CRYPTO_LOAD_DOOR
18507c478bd9Sstevel@tonic-gate  * NOTE:
18517c478bd9Sstevel@tonic-gate  * TODO:
18527c478bd9Sstevel@tonic-gate  * QUESTION:
18537c478bd9Sstevel@tonic-gate  */
18547c478bd9Sstevel@tonic-gate 
18557c478bd9Sstevel@tonic-gate void
audit_cryptoadm(int cmd,char * module_name,crypto_mech_name_t * mech_names,uint_t mech_count,uint_t device_instance,uint32_t rv,int error)18567c478bd9Sstevel@tonic-gate audit_cryptoadm(int cmd, char *module_name, crypto_mech_name_t *mech_names,
18577c478bd9Sstevel@tonic-gate     uint_t mech_count, uint_t device_instance, uint32_t rv, int error)
18587c478bd9Sstevel@tonic-gate {
18597c478bd9Sstevel@tonic-gate 	boolean_t		mech_list_required = B_FALSE;
18607c478bd9Sstevel@tonic-gate 	cred_t			*cr = CRED();
18617c478bd9Sstevel@tonic-gate 	t_audit_data_t		*tad;
18627c478bd9Sstevel@tonic-gate 	token_t			*ad = NULL;
18637c478bd9Sstevel@tonic-gate 	const auditinfo_addr_t	*ainfo = crgetauinfo(cr);
18647c478bd9Sstevel@tonic-gate 	char			buffer[MAXNAMELEN * 2];
18659e9e6ab8Spaulson 	au_kcontext_t		*kctx = GET_KCTX_PZ;
18667c478bd9Sstevel@tonic-gate 
18677c478bd9Sstevel@tonic-gate 	tad = U2A(u);
18687c478bd9Sstevel@tonic-gate 	if (tad == NULL)
18697c478bd9Sstevel@tonic-gate 		return;
18707c478bd9Sstevel@tonic-gate 
18717c478bd9Sstevel@tonic-gate 	if (ainfo == NULL)
18727c478bd9Sstevel@tonic-gate 		return;
18737c478bd9Sstevel@tonic-gate 
18747c478bd9Sstevel@tonic-gate 	tad->tad_event = AUE_CRYPTOADM;
18757c478bd9Sstevel@tonic-gate 
1876799bd290Spwernau 	if (audit_success(kctx, tad, error, NULL) != AU_OK)
18777c478bd9Sstevel@tonic-gate 		return;
18787c478bd9Sstevel@tonic-gate 
187981490fd2Sgww 	/* Add subject information */
188081490fd2Sgww 	AUDIT_SETSUBJ((caddr_t *)&(ad), cr, ainfo, kctx);
188145916cd2Sjpk 
18827c478bd9Sstevel@tonic-gate 	switch (cmd) {
18837c478bd9Sstevel@tonic-gate 	case CRYPTO_LOAD_DEV_DISABLED:
18847c478bd9Sstevel@tonic-gate 		if (error == 0 && rv == CRYPTO_SUCCESS) {
18857c478bd9Sstevel@tonic-gate 			(void) snprintf(buffer, sizeof (buffer),
18867c478bd9Sstevel@tonic-gate 			    "op=CRYPTO_LOAD_DEV_DISABLED, module=%s,"
18877c478bd9Sstevel@tonic-gate 			    " dev_instance=%d",
18887c478bd9Sstevel@tonic-gate 			    module_name, device_instance);
18897c478bd9Sstevel@tonic-gate 			mech_list_required = B_TRUE;
18907c478bd9Sstevel@tonic-gate 		} else {
18917c478bd9Sstevel@tonic-gate 			(void) snprintf(buffer, sizeof (buffer),
18927c478bd9Sstevel@tonic-gate 			    "op=CRYPTO_LOAD_DEV_DISABLED, return_val=%d", rv);
18937c478bd9Sstevel@tonic-gate 		}
18947c478bd9Sstevel@tonic-gate 		break;
18957c478bd9Sstevel@tonic-gate 
18967c478bd9Sstevel@tonic-gate 	case CRYPTO_LOAD_SOFT_DISABLED:
18977c478bd9Sstevel@tonic-gate 		if (error == 0 && rv == CRYPTO_SUCCESS) {
18987c478bd9Sstevel@tonic-gate 			(void) snprintf(buffer, sizeof (buffer),
18997c478bd9Sstevel@tonic-gate 			    "op=CRYPTO_LOAD_SOFT_DISABLED, module=%s",
19007c478bd9Sstevel@tonic-gate 			    module_name);
19017c478bd9Sstevel@tonic-gate 			mech_list_required = B_TRUE;
19027c478bd9Sstevel@tonic-gate 		} else {
19037c478bd9Sstevel@tonic-gate 			(void) snprintf(buffer, sizeof (buffer),
19047c478bd9Sstevel@tonic-gate 			    "op=CRYPTO_LOAD_SOFT_DISABLED, return_val=%d", rv);
19057c478bd9Sstevel@tonic-gate 		}
19067c478bd9Sstevel@tonic-gate 		break;
19077c478bd9Sstevel@tonic-gate 
19087c478bd9Sstevel@tonic-gate 	case CRYPTO_UNLOAD_SOFT_MODULE:
19097c478bd9Sstevel@tonic-gate 		if (error == 0 && rv == CRYPTO_SUCCESS) {
19107c478bd9Sstevel@tonic-gate 			(void) snprintf(buffer, sizeof (buffer),
19117c478bd9Sstevel@tonic-gate 			    "op=CRYPTO_UNLOAD_SOFT_MODULE, module=%s",
19127c478bd9Sstevel@tonic-gate 			    module_name);
19137c478bd9Sstevel@tonic-gate 		} else {
19147c478bd9Sstevel@tonic-gate 			(void) snprintf(buffer, sizeof (buffer),
19157c478bd9Sstevel@tonic-gate 			    "op=CRYPTO_UNLOAD_SOFT_MODULE, return_val=%d", rv);
19167c478bd9Sstevel@tonic-gate 		}
19177c478bd9Sstevel@tonic-gate 		break;
19187c478bd9Sstevel@tonic-gate 
19197c478bd9Sstevel@tonic-gate 	case CRYPTO_LOAD_SOFT_CONFIG:
19207c478bd9Sstevel@tonic-gate 		if (error == 0 && rv == CRYPTO_SUCCESS) {
19217c478bd9Sstevel@tonic-gate 			(void) snprintf(buffer, sizeof (buffer),
19227c478bd9Sstevel@tonic-gate 			    "op=CRYPTO_LOAD_SOFT_CONFIG, module=%s",
19237c478bd9Sstevel@tonic-gate 			    module_name);
19247c478bd9Sstevel@tonic-gate 			mech_list_required = B_TRUE;
19257c478bd9Sstevel@tonic-gate 		} else {
19267c478bd9Sstevel@tonic-gate 			(void) snprintf(buffer, sizeof (buffer),
19277c478bd9Sstevel@tonic-gate 			    "op=CRYPTO_LOAD_SOFT_CONFIG, return_val=%d", rv);
19287c478bd9Sstevel@tonic-gate 		}
19297c478bd9Sstevel@tonic-gate 		break;
19307c478bd9Sstevel@tonic-gate 
19317c478bd9Sstevel@tonic-gate 	case CRYPTO_POOL_CREATE:
19327c478bd9Sstevel@tonic-gate 		(void) snprintf(buffer, sizeof (buffer),
19337c478bd9Sstevel@tonic-gate 		    "op=CRYPTO_POOL_CREATE");
19347c478bd9Sstevel@tonic-gate 		break;
19357c478bd9Sstevel@tonic-gate 
19367c478bd9Sstevel@tonic-gate 	case CRYPTO_POOL_WAIT:
19377c478bd9Sstevel@tonic-gate 		(void) snprintf(buffer, sizeof (buffer), "op=CRYPTO_POOL_WAIT");
19387c478bd9Sstevel@tonic-gate 		break;
19397c478bd9Sstevel@tonic-gate 
19407c478bd9Sstevel@tonic-gate 	case CRYPTO_POOL_RUN:
19417c478bd9Sstevel@tonic-gate 		(void) snprintf(buffer, sizeof (buffer), "op=CRYPTO_POOL_RUN");
19427c478bd9Sstevel@tonic-gate 		break;
19437c478bd9Sstevel@tonic-gate 
19447c478bd9Sstevel@tonic-gate 	case CRYPTO_LOAD_DOOR:
19457c478bd9Sstevel@tonic-gate 		if (error == 0 && rv == CRYPTO_SUCCESS)
19467c478bd9Sstevel@tonic-gate 			(void) snprintf(buffer, sizeof (buffer),
19477c478bd9Sstevel@tonic-gate 			    "op=CRYPTO_LOAD_DOOR");
19487c478bd9Sstevel@tonic-gate 		else
19497c478bd9Sstevel@tonic-gate 			(void) snprintf(buffer, sizeof (buffer),
19507c478bd9Sstevel@tonic-gate 			    "op=CRYPTO_LOAD_DOOR, return_val=%d", rv);
19517c478bd9Sstevel@tonic-gate 		break;
19527c478bd9Sstevel@tonic-gate 
195373556491SAnthony Scarpino 	case CRYPTO_FIPS140_SET:
195473556491SAnthony Scarpino 		(void) snprintf(buffer, sizeof (buffer),
195573556491SAnthony Scarpino 		    "op=CRYPTO_FIPS140_SET, fips_state=%d", rv);
195673556491SAnthony Scarpino 		break;
195773556491SAnthony Scarpino 
19587c478bd9Sstevel@tonic-gate 	default:
19597c478bd9Sstevel@tonic-gate 		return;
19607c478bd9Sstevel@tonic-gate 	}
19617c478bd9Sstevel@tonic-gate 
19627c478bd9Sstevel@tonic-gate 	au_write((caddr_t *)&ad, au_to_text(buffer));
19637c478bd9Sstevel@tonic-gate 
19647c478bd9Sstevel@tonic-gate 	if (mech_list_required) {
19657c478bd9Sstevel@tonic-gate 		int i;
19667c478bd9Sstevel@tonic-gate 
19677c478bd9Sstevel@tonic-gate 		if (mech_count == 0) {
19687c478bd9Sstevel@tonic-gate 			au_write((caddr_t *)&ad, au_to_text("mech=list empty"));
19697c478bd9Sstevel@tonic-gate 		} else {
19707c478bd9Sstevel@tonic-gate 			char	*pb = buffer;
19717c478bd9Sstevel@tonic-gate 			size_t	l = sizeof (buffer);
19727c478bd9Sstevel@tonic-gate 			size_t	n;
19737c478bd9Sstevel@tonic-gate 			char	space[2] = ":";
19747c478bd9Sstevel@tonic-gate 
19757c478bd9Sstevel@tonic-gate 			n = snprintf(pb, l, "mech=");
19767c478bd9Sstevel@tonic-gate 
19777c478bd9Sstevel@tonic-gate 			for (i = 0; i < mech_count; i++) {
19787c478bd9Sstevel@tonic-gate 				pb += n;
19795c93ad81SMarek Pospisil 				l = (n >= l) ? 0 : l - n;
19807c478bd9Sstevel@tonic-gate 
19817c478bd9Sstevel@tonic-gate 				if (i == mech_count - 1)
19827c478bd9Sstevel@tonic-gate 					(void) strcpy(space, "");
19837c478bd9Sstevel@tonic-gate 
19847c478bd9Sstevel@tonic-gate 				n = snprintf(pb, l, "%s%s", mech_names[i],
19857c478bd9Sstevel@tonic-gate 				    space);
19867c478bd9Sstevel@tonic-gate 			}
19877c478bd9Sstevel@tonic-gate 			au_write((caddr_t *)&ad, au_to_text(buffer));
19887c478bd9Sstevel@tonic-gate 		}
19897c478bd9Sstevel@tonic-gate 	}
19907c478bd9Sstevel@tonic-gate 
19917c478bd9Sstevel@tonic-gate 	/* add a return token */
19927c478bd9Sstevel@tonic-gate 	if (error || (rv != CRYPTO_SUCCESS))
19937c478bd9Sstevel@tonic-gate 		add_return_token((caddr_t *)&ad, tad->tad_scid, -1, error);
19947c478bd9Sstevel@tonic-gate 	else
19957c478bd9Sstevel@tonic-gate 		add_return_token((caddr_t *)&ad, tad->tad_scid, 0, rv);
19967c478bd9Sstevel@tonic-gate 
19977c478bd9Sstevel@tonic-gate 	AS_INC(as_generated, 1, kctx);
19987c478bd9Sstevel@tonic-gate 	AS_INC(as_kernel, 1, kctx);
19997c478bd9Sstevel@tonic-gate 
2000005d3febSMarek Pospisil 	au_close(kctx, (caddr_t *)&ad, AU_OK, AUE_CRYPTOADM, tad->tad_evmod,
2001005d3febSMarek Pospisil 	    NULL);
20027c478bd9Sstevel@tonic-gate }
2003c28749e9Skais 
2004799bd290Spwernau /*
2005799bd290Spwernau  * Audit the kernel PF_POLICY administration commands.  Record command,
2006799bd290Spwernau  * zone, policy type (global or tunnel, active or inactive)
2007799bd290Spwernau  */
2008799bd290Spwernau /*
2009799bd290Spwernau  * ROUTINE:	AUDIT_PF_POLICY
2010799bd290Spwernau  * PURPOSE:	Records arguments to administrative ioctls on PF_POLICY socket
2011799bd290Spwernau  * CALLBY:	SPD_ADDRULE, SPD_DELETERULE, SPD_FLUSH, SPD_UPDATEALGS,
2012799bd290Spwernau  *		SPD_CLONE, SPD_FLIP
2013799bd290Spwernau  * NOTE:
2014799bd290Spwernau  * TODO:
2015799bd290Spwernau  * QUESTION:
2016799bd290Spwernau  */
2017799bd290Spwernau 
2018799bd290Spwernau void
audit_pf_policy(int cmd,cred_t * cred,netstack_t * ns,char * tun,boolean_t active,int error,pid_t pid)2019799bd290Spwernau audit_pf_policy(int cmd, cred_t *cred, netstack_t *ns, char *tun,
2020799bd290Spwernau     boolean_t active, int error, pid_t pid)
2021799bd290Spwernau {
2022799bd290Spwernau 	const auditinfo_addr_t	*ainfo;
2023799bd290Spwernau 	t_audit_data_t		*tad;
2024799bd290Spwernau 	token_t			*ad = NULL;
2025799bd290Spwernau 	au_kcontext_t		*kctx = GET_KCTX_PZ;
2026799bd290Spwernau 	char			buf[80];
2027799bd290Spwernau 	int			flag;
2028799bd290Spwernau 
2029799bd290Spwernau 	tad = U2A(u);
2030799bd290Spwernau 	if (tad == NULL)
2031799bd290Spwernau 		return;
2032799bd290Spwernau 
2033799bd290Spwernau 	ainfo = crgetauinfo((cred != NULL) ? cred : CRED());
2034799bd290Spwernau 	if (ainfo == NULL)
2035799bd290Spwernau 		return;
2036799bd290Spwernau 
2037799bd290Spwernau 	/*
2038799bd290Spwernau 	 * Initialize some variables since these are only set
2039799bd290Spwernau 	 * with system calls.
2040799bd290Spwernau 	 */
2041799bd290Spwernau 
2042799bd290Spwernau 	switch (cmd) {
2043799bd290Spwernau 	case SPD_ADDRULE: {
2044799bd290Spwernau 		tad->tad_event = AUE_PF_POLICY_ADDRULE;
2045799bd290Spwernau 		break;
2046799bd290Spwernau 	}
2047799bd290Spwernau 
2048799bd290Spwernau 	case SPD_DELETERULE: {
2049799bd290Spwernau 		tad->tad_event = AUE_PF_POLICY_DELRULE;
2050799bd290Spwernau 		break;
2051799bd290Spwernau 	}
2052799bd290Spwernau 
2053799bd290Spwernau 	case SPD_FLUSH: {
2054799bd290Spwernau 		tad->tad_event = AUE_PF_POLICY_FLUSH;
2055799bd290Spwernau 		break;
2056799bd290Spwernau 	}
2057799bd290Spwernau 
2058799bd290Spwernau 	case SPD_UPDATEALGS: {
2059799bd290Spwernau 		tad->tad_event = AUE_PF_POLICY_ALGS;
2060799bd290Spwernau 		break;
2061799bd290Spwernau 	}
2062799bd290Spwernau 
2063799bd290Spwernau 	case SPD_CLONE: {
2064799bd290Spwernau 		tad->tad_event = AUE_PF_POLICY_CLONE;
2065799bd290Spwernau 		break;
2066799bd290Spwernau 	}
2067799bd290Spwernau 
2068799bd290Spwernau 	case SPD_FLIP: {
2069799bd290Spwernau 		tad->tad_event = AUE_PF_POLICY_FLIP;
2070799bd290Spwernau 		break;
2071799bd290Spwernau 	}
2072799bd290Spwernau 
2073799bd290Spwernau 	default:
2074799bd290Spwernau 		tad->tad_event = AUE_NULL;
2075799bd290Spwernau 	}
2076799bd290Spwernau 
2077799bd290Spwernau 	tad->tad_evmod = 0;
2078799bd290Spwernau 
2079799bd290Spwernau 	if (flag = audit_success(kctx, tad, error, cred)) {
2080799bd290Spwernau 		zone_t *nszone;
2081799bd290Spwernau 
2082799bd290Spwernau 		/*
2083799bd290Spwernau 		 * For now, just audit that an event happened,
2084799bd290Spwernau 		 * along with the error code.
2085799bd290Spwernau 		 */
2086799bd290Spwernau 		au_write((caddr_t *)&ad,
2087799bd290Spwernau 		    au_to_arg32(1, "Policy Active?", (uint32_t)active));
2088799bd290Spwernau 		au_write((caddr_t *)&ad,
2089799bd290Spwernau 		    au_to_arg32(2, "Policy Global?", (uint32_t)(tun == NULL)));
2090799bd290Spwernau 
2091799bd290Spwernau 		/* Supplemental data */
2092799bd290Spwernau 
2093799bd290Spwernau 		/*
2094799bd290Spwernau 		 * Generate this zone token if the target zone differs
2095799bd290Spwernau 		 * from the administrative zone.  If netstacks are expanded
2096799bd290Spwernau 		 * to something other than a 1-1 relationship with zones,
2097799bd290Spwernau 		 * the auditing framework should create a new token type
2098799bd290Spwernau 		 * and audit it as a netstack instead.
2099799bd290Spwernau 		 * Turn on general zone auditing to get the administrative zone.
2100799bd290Spwernau 		 */
2101799bd290Spwernau 
2102799bd290Spwernau 		nszone = zone_find_by_id(netstackid_to_zoneid(
2103799bd290Spwernau 		    ns->netstack_stackid));
2104875a4abcSPaul Wernau 		if (nszone != NULL) {
210567dbe2beSCasper H.S. Dik 			if (strncmp(crgetzone(cred)->zone_name,
210667dbe2beSCasper H.S. Dik 			    nszone->zone_name, ZONENAME_MAX) != 0) {
2107875a4abcSPaul Wernau 				token_t *ztoken;
2108799bd290Spwernau 
2109875a4abcSPaul Wernau 				ztoken = au_to_zonename(0, nszone);
2110875a4abcSPaul Wernau 				au_write((caddr_t *)&ad, ztoken);
2111875a4abcSPaul Wernau 			}
2112875a4abcSPaul Wernau 			zone_rele(nszone);
2113799bd290Spwernau 		}
2114799bd290Spwernau 
2115799bd290Spwernau 		if (tun != NULL) {
2116799bd290Spwernau 			/* write tunnel name - tun is bounded */
2117799bd290Spwernau 			(void) snprintf(buf, sizeof (buf), "tunnel_name:%s",
2118799bd290Spwernau 			    tun);
2119799bd290Spwernau 			au_write((caddr_t *)&ad, au_to_text(buf));
2120799bd290Spwernau 		}
2121799bd290Spwernau 
2122799bd290Spwernau 		/* Add subject information */
2123799bd290Spwernau 		AUDIT_SETSUBJ_GENERIC((caddr_t *)&ad,
2124799bd290Spwernau 		    ((cred != NULL) ? cred : CRED()), ainfo, kctx, pid);
2125799bd290Spwernau 
2126799bd290Spwernau 		/* add a return token */
2127799bd290Spwernau 		add_return_token((caddr_t *)&ad, 0, error, 0);
2128799bd290Spwernau 
2129799bd290Spwernau 		AS_INC(as_generated, 1, kctx);
2130799bd290Spwernau 		AS_INC(as_kernel, 1, kctx);
2131799bd290Spwernau 
2132799bd290Spwernau 	}
2133005d3febSMarek Pospisil 	au_close(kctx, (caddr_t *)&ad, flag, tad->tad_event, tad->tad_evmod,
2134005d3febSMarek Pospisil 	    NULL);
2135799bd290Spwernau 
2136799bd290Spwernau 	/*
2137799bd290Spwernau 	 * clear the ctrl flag so that we don't have spurious collection of
2138799bd290Spwernau 	 * audit information.
2139799bd290Spwernau 	 */
2140799bd290Spwernau 	tad->tad_scid  = 0;
2141799bd290Spwernau 	tad->tad_event = 0;
2142799bd290Spwernau 	tad->tad_evmod = 0;
2143799bd290Spwernau 	tad->tad_ctrl  = 0;
2144799bd290Spwernau }
2145799bd290Spwernau 
214645916cd2Sjpk /*
214745916cd2Sjpk  * ROUTINE:	AUDIT_SEC_ATTRIBUTES
214845916cd2Sjpk  * PURPOSE:	Add security attributes
214945916cd2Sjpk  * CALLBY:	AUDIT_ATTRIBUTES
215045916cd2Sjpk  *		AUDIT_CLOSEF
215145916cd2Sjpk  *		AUS_CLOSE
215245916cd2Sjpk  * NOTE:
215345916cd2Sjpk  * TODO:
215445916cd2Sjpk  * QUESTION:
215545916cd2Sjpk  */
215645916cd2Sjpk 
215745916cd2Sjpk void
audit_sec_attributes(caddr_t * ad,struct vnode * vp)215845916cd2Sjpk audit_sec_attributes(caddr_t *ad, struct vnode *vp)
215945916cd2Sjpk {
216045916cd2Sjpk 	/* Dump the SL */
216145916cd2Sjpk 	if (is_system_labeled()) {
216245916cd2Sjpk 		ts_label_t	*tsl;
216345916cd2Sjpk 		bslabel_t	*bsl;
216445916cd2Sjpk 
216545916cd2Sjpk 		tsl = getflabel(vp);
216645916cd2Sjpk 		if (tsl == NULL)
216745916cd2Sjpk 			return;			/* nothing else to do */
216845916cd2Sjpk 
216945916cd2Sjpk 		bsl = label2bslabel(tsl);
217045916cd2Sjpk 		if (bsl == NULL)
217145916cd2Sjpk 			return;			/* nothing else to do */
217245916cd2Sjpk 		au_write(ad, au_to_label(bsl));
217345916cd2Sjpk 		label_rele(tsl);
217445916cd2Sjpk 	}
217545916cd2Sjpk 
217645916cd2Sjpk }	/* AUDIT_SEC_ATTRIBUTES */
2177