xref: /titanic_50/usr/src/uts/common/c2/audit.c (revision da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0)
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  */
217c478bd9Sstevel@tonic-gate /*
22405e5d68Stz204579  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
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 #pragma ident	"%Z%%M%	%I%	%E% SMI"
317c478bd9Sstevel@tonic-gate 
327c478bd9Sstevel@tonic-gate #include <sys/types.h>
337c478bd9Sstevel@tonic-gate #include <sys/proc.h>
347c478bd9Sstevel@tonic-gate #include <sys/vnode.h>
357c478bd9Sstevel@tonic-gate #include <sys/vfs.h>
367c478bd9Sstevel@tonic-gate #include <sys/file.h>
377c478bd9Sstevel@tonic-gate #include <sys/user.h>
387c478bd9Sstevel@tonic-gate #include <sys/stropts.h>
397c478bd9Sstevel@tonic-gate #include <sys/systm.h>
407c478bd9Sstevel@tonic-gate #include <sys/pathname.h>
417c478bd9Sstevel@tonic-gate #include <sys/syscall.h>
427c478bd9Sstevel@tonic-gate #include <sys/fcntl.h>
437c478bd9Sstevel@tonic-gate #include <sys/ipc_impl.h>
447c478bd9Sstevel@tonic-gate #include <sys/msg_impl.h>
457c478bd9Sstevel@tonic-gate #include <sys/sem_impl.h>
467c478bd9Sstevel@tonic-gate #include <sys/shm_impl.h>
477c478bd9Sstevel@tonic-gate #include <sys/kmem.h>		/* for KM_SLEEP */
487c478bd9Sstevel@tonic-gate #include <sys/socket.h>
497c478bd9Sstevel@tonic-gate #include <sys/cmn_err.h>	/* snprintf... */
507c478bd9Sstevel@tonic-gate #include <sys/debug.h>
517c478bd9Sstevel@tonic-gate #include <sys/thread.h>
527c478bd9Sstevel@tonic-gate #include <netinet/in.h>
537c478bd9Sstevel@tonic-gate #include <c2/audit.h>		/* needs to be included before user.h */
547c478bd9Sstevel@tonic-gate #include <c2/audit_kernel.h>	/* for M_DONTWAIT */
557c478bd9Sstevel@tonic-gate #include <c2/audit_kevents.h>
567c478bd9Sstevel@tonic-gate #include <c2/audit_record.h>
577c478bd9Sstevel@tonic-gate #include <sys/strsubr.h>
587c478bd9Sstevel@tonic-gate #include <sys/tihdr.h>
597c478bd9Sstevel@tonic-gate #include <sys/tiuser.h>
607c478bd9Sstevel@tonic-gate #include <sys/timod.h>
617c478bd9Sstevel@tonic-gate #include <sys/model.h>		/* for model_t */
627c478bd9Sstevel@tonic-gate #include <sys/disp.h>		/* for servicing_interrupt() */
637c478bd9Sstevel@tonic-gate #include <sys/devpolicy.h>
647c478bd9Sstevel@tonic-gate #include <sys/crypto/ioctladmin.h>
65799bd290Spwernau #include <sys/cred_impl.h>
66c28749e9Skais #include <inet/kssl/kssl.h>
67799bd290Spwernau #include <net/pfpolicy.h>
687c478bd9Sstevel@tonic-gate 
697c478bd9Sstevel@tonic-gate static void add_return_token(caddr_t *, unsigned int scid, int err, int rval);
707c478bd9Sstevel@tonic-gate 
717c478bd9Sstevel@tonic-gate static void audit_pathbuild(struct pathname *pnp);
727c478bd9Sstevel@tonic-gate 
737c478bd9Sstevel@tonic-gate /*
747c478bd9Sstevel@tonic-gate  * ROUTINE:	AUDIT_NEWPROC
757c478bd9Sstevel@tonic-gate  * PURPOSE:	initialize the child p_audit_data structure
767c478bd9Sstevel@tonic-gate  * CALLBY:	GETPROC
777c478bd9Sstevel@tonic-gate  * NOTE:	All threads for the parent process are locked at this point.
787c478bd9Sstevel@tonic-gate  *		We are essentially running singled threaded for this reason.
797c478bd9Sstevel@tonic-gate  *		GETPROC is called when system creates a new process.
807c478bd9Sstevel@tonic-gate  *		By the time AUDIT_NEWPROC is called, the child proc
817c478bd9Sstevel@tonic-gate  *		structure has already been initialized. What we need
827c478bd9Sstevel@tonic-gate  *		to do is to allocate the child p_audit_data and
837c478bd9Sstevel@tonic-gate  *		initialize it with the content of current parent process.
847c478bd9Sstevel@tonic-gate  */
857c478bd9Sstevel@tonic-gate 
867c478bd9Sstevel@tonic-gate void
877c478bd9Sstevel@tonic-gate audit_newproc(struct proc *cp)	/* initialized child proc structure */
887c478bd9Sstevel@tonic-gate {
897c478bd9Sstevel@tonic-gate 	p_audit_data_t *pad;	/* child process audit data */
907c478bd9Sstevel@tonic-gate 	p_audit_data_t *opad;	/* parent process audit data */
917c478bd9Sstevel@tonic-gate 
927c478bd9Sstevel@tonic-gate 	pad = kmem_cache_alloc(au_pad_cache, KM_SLEEP);
937c478bd9Sstevel@tonic-gate 
947c478bd9Sstevel@tonic-gate 	P2A(cp) = pad;
957c478bd9Sstevel@tonic-gate 
967c478bd9Sstevel@tonic-gate 	opad = P2A(curproc);
977c478bd9Sstevel@tonic-gate 
987c478bd9Sstevel@tonic-gate 	/*
997c478bd9Sstevel@tonic-gate 	 * copy the audit data. Note that all threads of current
1007c478bd9Sstevel@tonic-gate 	 *   process have been "held". Thus there is no race condition
1017c478bd9Sstevel@tonic-gate 	 *   here with mutiple threads trying to alter the cwrd
1027c478bd9Sstevel@tonic-gate 	 *   structure (such as releasing it).
1037c478bd9Sstevel@tonic-gate 	 *
1047c478bd9Sstevel@tonic-gate 	 *   The audit context in the cred is "duplicated" for the new
1057c478bd9Sstevel@tonic-gate 	 *   proc by elsewhere crhold'ing the parent's cred which it shares.
1067c478bd9Sstevel@tonic-gate 	 *
1077c478bd9Sstevel@tonic-gate 	 *   We still want to hold things since auditon() [A_SETUMASK,
1087c478bd9Sstevel@tonic-gate 	 *   A_SETSMASK] could be walking through the processes to
1097c478bd9Sstevel@tonic-gate 	 *   update things.
1107c478bd9Sstevel@tonic-gate 	 */
1117c478bd9Sstevel@tonic-gate 	mutex_enter(&opad->pad_lock);	/* lock opad structure during copy */
1127c478bd9Sstevel@tonic-gate 	pad->pad_data = opad->pad_data;	/* copy parent's process audit data */
1137c478bd9Sstevel@tonic-gate 	au_pathhold(pad->pad_root);
1147c478bd9Sstevel@tonic-gate 	au_pathhold(pad->pad_cwd);
1157c478bd9Sstevel@tonic-gate 	mutex_exit(&opad->pad_lock);	/* current proc will keep cwrd open */
1167c478bd9Sstevel@tonic-gate 
1177c478bd9Sstevel@tonic-gate 	/*
1187c478bd9Sstevel@tonic-gate 	 * finish auditing of parent here so that it will be done
1197c478bd9Sstevel@tonic-gate 	 * before child has a chance to run. We include the child
1207c478bd9Sstevel@tonic-gate 	 * pid since the return value in the return token is a dummy
1217c478bd9Sstevel@tonic-gate 	 * one and contains no useful information (it is included to
1227c478bd9Sstevel@tonic-gate 	 * make the audit record structure consistant).
1237c478bd9Sstevel@tonic-gate 	 *
1247c478bd9Sstevel@tonic-gate 	 * tad_flag is set if auditing is on
1257c478bd9Sstevel@tonic-gate 	 */
1267c478bd9Sstevel@tonic-gate 	if (((t_audit_data_t *)T2A(curthread))->tad_flag)
1277c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_arg32(0, "child PID", (uint32_t)cp->p_pid));
1287c478bd9Sstevel@tonic-gate 
1297c478bd9Sstevel@tonic-gate 	/*
1307c478bd9Sstevel@tonic-gate 	 * finish up audit record generation here because child process
1317c478bd9Sstevel@tonic-gate 	 * is set to run before parent process. We distinguish here
1327c478bd9Sstevel@tonic-gate 	 * between FORK, FORK1, or VFORK by the saved system call ID.
1337c478bd9Sstevel@tonic-gate 	 */
1347c478bd9Sstevel@tonic-gate 	audit_finish(0, ((t_audit_data_t *)T2A(curthread))->tad_scid, 0, 0);
1357c478bd9Sstevel@tonic-gate }
1367c478bd9Sstevel@tonic-gate 
1377c478bd9Sstevel@tonic-gate /*
1387c478bd9Sstevel@tonic-gate  * ROUTINE:	AUDIT_PFREE
1397c478bd9Sstevel@tonic-gate  * PURPOSE:	deallocate the per-process udit data structure
1407c478bd9Sstevel@tonic-gate  * CALLBY:	EXIT
1417c478bd9Sstevel@tonic-gate  *		FORK_FAIL
1427c478bd9Sstevel@tonic-gate  * NOTE:	all lwp except current one have stopped in SEXITLWPS
1437c478bd9Sstevel@tonic-gate  * 		why we are single threaded?
1447c478bd9Sstevel@tonic-gate  *		. all lwp except current one have stopped in SEXITLWPS.
1457c478bd9Sstevel@tonic-gate  */
1467c478bd9Sstevel@tonic-gate void
1477c478bd9Sstevel@tonic-gate audit_pfree(struct proc *p)		/* proc structure to be freed */
1487c478bd9Sstevel@tonic-gate 
1497c478bd9Sstevel@tonic-gate {	/* AUDIT_PFREE */
1507c478bd9Sstevel@tonic-gate 
1517c478bd9Sstevel@tonic-gate 	p_audit_data_t *pad;
1527c478bd9Sstevel@tonic-gate 
1537c478bd9Sstevel@tonic-gate 	pad = P2A(p);
1547c478bd9Sstevel@tonic-gate 
1557c478bd9Sstevel@tonic-gate 	/* better be a per process audit data structure */
1567c478bd9Sstevel@tonic-gate 	ASSERT(pad != (p_audit_data_t *)0);
1577c478bd9Sstevel@tonic-gate 
1587c478bd9Sstevel@tonic-gate 	if (pad == pad0) {
1597c478bd9Sstevel@tonic-gate 		return;
1607c478bd9Sstevel@tonic-gate 	}
1617c478bd9Sstevel@tonic-gate 
1627c478bd9Sstevel@tonic-gate 	/* deallocate all auditing resources for this process */
1637c478bd9Sstevel@tonic-gate 	au_pathrele(pad->pad_root);
1647c478bd9Sstevel@tonic-gate 	au_pathrele(pad->pad_cwd);
1657c478bd9Sstevel@tonic-gate 
1667c478bd9Sstevel@tonic-gate 	/*
1677c478bd9Sstevel@tonic-gate 	 * Since the pad structure is completely overwritten after alloc,
1687c478bd9Sstevel@tonic-gate 	 * we don't bother to clear it.
1697c478bd9Sstevel@tonic-gate 	 */
1707c478bd9Sstevel@tonic-gate 
1717c478bd9Sstevel@tonic-gate 	kmem_cache_free(au_pad_cache, pad);
1727c478bd9Sstevel@tonic-gate }
1737c478bd9Sstevel@tonic-gate 
1747c478bd9Sstevel@tonic-gate /*
1757c478bd9Sstevel@tonic-gate  * ROUTINE:	AUDIT_THREAD_CREATE
1767c478bd9Sstevel@tonic-gate  * PURPOSE:	allocate per-process thread audit data structure
1777c478bd9Sstevel@tonic-gate  * CALLBY:	THREAD_CREATE
1787c478bd9Sstevel@tonic-gate  * NOTE:	This is called just after *t was bzero'd.
1797c478bd9Sstevel@tonic-gate  *		We are single threaded in this routine.
1807c478bd9Sstevel@tonic-gate  * TODO:
1817c478bd9Sstevel@tonic-gate  * QUESTION:
1827c478bd9Sstevel@tonic-gate  */
1837c478bd9Sstevel@tonic-gate 
1847c478bd9Sstevel@tonic-gate void
1857c478bd9Sstevel@tonic-gate audit_thread_create(kthread_id_t t)
1867c478bd9Sstevel@tonic-gate {
1877c478bd9Sstevel@tonic-gate 	t_audit_data_t *tad;	/* per-thread audit data */
1887c478bd9Sstevel@tonic-gate 
1897c478bd9Sstevel@tonic-gate 	tad = kmem_zalloc(sizeof (struct t_audit_data), KM_SLEEP);
1907c478bd9Sstevel@tonic-gate 
1917c478bd9Sstevel@tonic-gate 	T2A(t) = tad;		/* set up thread audit data ptr */
1927c478bd9Sstevel@tonic-gate 	tad->tad_thread = t;	/* back ptr to thread: DEBUG */
1937c478bd9Sstevel@tonic-gate }
1947c478bd9Sstevel@tonic-gate 
1957c478bd9Sstevel@tonic-gate /*
1967c478bd9Sstevel@tonic-gate  * ROUTINE:	AUDIT_THREAD_FREE
1977c478bd9Sstevel@tonic-gate  * PURPOSE:	free the per-thread audit data structure
1987c478bd9Sstevel@tonic-gate  * CALLBY:	THREAD_FREE
1997c478bd9Sstevel@tonic-gate  * NOTE:	most thread data is clear after return
2007c478bd9Sstevel@tonic-gate  */
2017c478bd9Sstevel@tonic-gate void
2027c478bd9Sstevel@tonic-gate audit_thread_free(kthread_t *t)
2037c478bd9Sstevel@tonic-gate {
2047c478bd9Sstevel@tonic-gate 	t_audit_data_t *tad;
2057c478bd9Sstevel@tonic-gate 	au_defer_info_t	*attr;
2067c478bd9Sstevel@tonic-gate 
2077c478bd9Sstevel@tonic-gate 	tad = T2A(t);
2087c478bd9Sstevel@tonic-gate 
2097c478bd9Sstevel@tonic-gate 	/* thread audit data must still be set */
2107c478bd9Sstevel@tonic-gate 
2117c478bd9Sstevel@tonic-gate 	if (tad == tad0) {
2127c478bd9Sstevel@tonic-gate 		return;
2137c478bd9Sstevel@tonic-gate 	}
2147c478bd9Sstevel@tonic-gate 
2157c478bd9Sstevel@tonic-gate 	if (tad == NULL) {
2167c478bd9Sstevel@tonic-gate 		return;
2177c478bd9Sstevel@tonic-gate 	}
2187c478bd9Sstevel@tonic-gate 
2197c478bd9Sstevel@tonic-gate 	t->t_audit_data = 0;
2207c478bd9Sstevel@tonic-gate 
2217c478bd9Sstevel@tonic-gate 	/* must not have any audit record residual */
2227c478bd9Sstevel@tonic-gate 	ASSERT(tad->tad_ad == NULL);
2237c478bd9Sstevel@tonic-gate 
2247c478bd9Sstevel@tonic-gate 	/* saved path must be empty */
2257c478bd9Sstevel@tonic-gate 	ASSERT(tad->tad_aupath == NULL);
2267c478bd9Sstevel@tonic-gate 
2277c478bd9Sstevel@tonic-gate 	if (tad->tad_atpath)
2287c478bd9Sstevel@tonic-gate 		au_pathrele(tad->tad_atpath);
2297c478bd9Sstevel@tonic-gate 
2307c478bd9Sstevel@tonic-gate 	attr = tad->tad_defer_head;
2317c478bd9Sstevel@tonic-gate 	while (attr != NULL) {
2327c478bd9Sstevel@tonic-gate 		au_defer_info_t	*tmp_attr = attr;
2337c478bd9Sstevel@tonic-gate 
2347c478bd9Sstevel@tonic-gate 		au_free_rec(attr->audi_ad);
2357c478bd9Sstevel@tonic-gate 
2367c478bd9Sstevel@tonic-gate 		attr = attr->audi_next;
2377c478bd9Sstevel@tonic-gate 		kmem_free(tmp_attr, sizeof (au_defer_info_t));
2387c478bd9Sstevel@tonic-gate 	}
2397c478bd9Sstevel@tonic-gate 
2407c478bd9Sstevel@tonic-gate 	kmem_free(tad, sizeof (*tad));
2417c478bd9Sstevel@tonic-gate }
2427c478bd9Sstevel@tonic-gate 
2437c478bd9Sstevel@tonic-gate /*
2447c478bd9Sstevel@tonic-gate  * ROUTINE:	AUDIT_SAVEPATH
2457c478bd9Sstevel@tonic-gate  * PURPOSE:
2467c478bd9Sstevel@tonic-gate  * CALLBY:	LOOKUPPN
2477c478bd9Sstevel@tonic-gate  *
2487c478bd9Sstevel@tonic-gate  * NOTE:	We have reached the end of a path in fs/lookup.c.
2497c478bd9Sstevel@tonic-gate  *		We get two pieces of information here:
2507c478bd9Sstevel@tonic-gate  *		the vnode of the last component (vp) and
2517c478bd9Sstevel@tonic-gate  *		the status of the last access (flag).
2527c478bd9Sstevel@tonic-gate  * TODO:
2537c478bd9Sstevel@tonic-gate  * QUESTION:
2547c478bd9Sstevel@tonic-gate  */
2557c478bd9Sstevel@tonic-gate 
2567c478bd9Sstevel@tonic-gate /*ARGSUSED*/
2577c478bd9Sstevel@tonic-gate int
2587c478bd9Sstevel@tonic-gate audit_savepath(
2597c478bd9Sstevel@tonic-gate 	struct pathname *pnp,		/* pathname to lookup */
2607c478bd9Sstevel@tonic-gate 	struct vnode *vp,		/* vnode of the last component */
2617c478bd9Sstevel@tonic-gate 	int    flag,			/* status of the last access */
2627c478bd9Sstevel@tonic-gate 	cred_t *cr)			/* cred of requestor */
2637c478bd9Sstevel@tonic-gate {
2647c478bd9Sstevel@tonic-gate 
2657c478bd9Sstevel@tonic-gate 	t_audit_data_t *tad;	/* current thread */
2669e9e6ab8Spaulson 	au_kcontext_t	*kctx = GET_KCTX_PZ;
2677c478bd9Sstevel@tonic-gate 
2687c478bd9Sstevel@tonic-gate 	tad = U2A(u);
2697c478bd9Sstevel@tonic-gate 
2707c478bd9Sstevel@tonic-gate 	/*
2717c478bd9Sstevel@tonic-gate 	 * this event being audited or do we need path information
2727c478bd9Sstevel@tonic-gate 	 * later? This might be for a chdir/chroot or open (add path
2737c478bd9Sstevel@tonic-gate 	 * to file pointer. If the path has already been found for an
2747c478bd9Sstevel@tonic-gate 	 * open/creat then we don't need to process the path.
2757c478bd9Sstevel@tonic-gate 	 *
2767c478bd9Sstevel@tonic-gate 	 * S2E_SP (PAD_SAVPATH) flag comes from audit_s2e[].au_ctrl. Used with
2777c478bd9Sstevel@tonic-gate 	 *	chroot, chdir, open, creat system call processing. It determines
2787c478bd9Sstevel@tonic-gate 	 *	if audit_savepath() will discard the path or we need it later.
2797c478bd9Sstevel@tonic-gate 	 * PAD_PATHFND means path already included in this audit record. It
2807c478bd9Sstevel@tonic-gate 	 *	is used in cases where multiple path lookups are done per
2817c478bd9Sstevel@tonic-gate 	 *	system call. The policy flag, AUDIT_PATH, controls if multiple
2827c478bd9Sstevel@tonic-gate 	 *	paths are allowed.
2837c478bd9Sstevel@tonic-gate 	 * S2E_NPT (PAD_NOPATH) flag comes from audit_s2e[].au_ctrl. Used with
2847c478bd9Sstevel@tonic-gate 	 *	exit processing to inhibit any paths that may be added due to
2857c478bd9Sstevel@tonic-gate 	 *	closes.
2867c478bd9Sstevel@tonic-gate 	 */
2877c478bd9Sstevel@tonic-gate 	if ((tad->tad_flag == 0 && !(tad->tad_ctrl & PAD_SAVPATH)) ||
2887c478bd9Sstevel@tonic-gate 		((tad->tad_ctrl & PAD_PATHFND) &&
2897c478bd9Sstevel@tonic-gate 		!(kctx->auk_policy & AUDIT_PATH)) ||
2907c478bd9Sstevel@tonic-gate 		(tad->tad_ctrl & PAD_NOPATH)) {
2917c478bd9Sstevel@tonic-gate 			return (0);
2927c478bd9Sstevel@tonic-gate 	}
2937c478bd9Sstevel@tonic-gate 
29445916cd2Sjpk 	tad->tad_ctrl |= PAD_NOPATH;		/* prevent possible reentry */
29545916cd2Sjpk 
2967c478bd9Sstevel@tonic-gate 	audit_pathbuild(pnp);
2977c478bd9Sstevel@tonic-gate 	tad->tad_vn = vp;
2987c478bd9Sstevel@tonic-gate 
2997c478bd9Sstevel@tonic-gate 	/*
3007c478bd9Sstevel@tonic-gate 	 * are we auditing only if error, or if it is not open or create
3017c478bd9Sstevel@tonic-gate 	 * otherwise audit_setf will do it
3027c478bd9Sstevel@tonic-gate 	 */
3037c478bd9Sstevel@tonic-gate 
3047c478bd9Sstevel@tonic-gate 	if (tad->tad_flag) {
3057c478bd9Sstevel@tonic-gate 		if (flag && (tad->tad_scid == SYS_open ||
3067c478bd9Sstevel@tonic-gate 		    tad->tad_scid == SYS_open64 ||
3077c478bd9Sstevel@tonic-gate 		    tad->tad_scid == SYS_creat ||
3087c478bd9Sstevel@tonic-gate 		    tad->tad_scid == SYS_creat64 ||
3097c478bd9Sstevel@tonic-gate 		    tad->tad_scid == SYS_fsat)) {
3107c478bd9Sstevel@tonic-gate 			tad->tad_ctrl |= PAD_TRUE_CREATE;
3117c478bd9Sstevel@tonic-gate 		}
3127c478bd9Sstevel@tonic-gate 
3137c478bd9Sstevel@tonic-gate 		/* add token to audit record for this name */
3147c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_path(tad->tad_aupath));
3157c478bd9Sstevel@tonic-gate 
3167c478bd9Sstevel@tonic-gate 		/* add the attributes of the object */
3177c478bd9Sstevel@tonic-gate 		if (vp) {
3187c478bd9Sstevel@tonic-gate 			/*
3197c478bd9Sstevel@tonic-gate 			 * only capture attributes when there is no error
3207c478bd9Sstevel@tonic-gate 			 * lookup will not return the vnode of the failing
3217c478bd9Sstevel@tonic-gate 			 * component.
3227c478bd9Sstevel@tonic-gate 			 *
3237c478bd9Sstevel@tonic-gate 			 * if there was a lookup error, then don't add
3247c478bd9Sstevel@tonic-gate 			 * attribute. if lookup in vn_create(),
3257c478bd9Sstevel@tonic-gate 			 * then don't add attribute,
3267c478bd9Sstevel@tonic-gate 			 * it will be added at end of vn_create().
3277c478bd9Sstevel@tonic-gate 			 */
3287c478bd9Sstevel@tonic-gate 			if (!flag && !(tad->tad_ctrl & PAD_NOATTRB))
3297c478bd9Sstevel@tonic-gate 				audit_attributes(vp);
3307c478bd9Sstevel@tonic-gate 		}
3317c478bd9Sstevel@tonic-gate 	}
3327c478bd9Sstevel@tonic-gate 
3337c478bd9Sstevel@tonic-gate 	/* free up space if we're not going to save path (open, crate) */
3347c478bd9Sstevel@tonic-gate 	if ((tad->tad_ctrl & PAD_SAVPATH) == 0) {
3357c478bd9Sstevel@tonic-gate 		if (tad->tad_aupath != NULL) {
3367c478bd9Sstevel@tonic-gate 			au_pathrele(tad->tad_aupath);
3377c478bd9Sstevel@tonic-gate 			tad->tad_aupath = NULL;
3387c478bd9Sstevel@tonic-gate 			tad->tad_vn = NULL;
3397c478bd9Sstevel@tonic-gate 		}
3407c478bd9Sstevel@tonic-gate 	}
3417c478bd9Sstevel@tonic-gate 	if (tad->tad_ctrl & PAD_MLD)
3427c478bd9Sstevel@tonic-gate 		tad->tad_ctrl |= PAD_PATHFND;
3437c478bd9Sstevel@tonic-gate 
34445916cd2Sjpk 	tad->tad_ctrl &= ~PAD_NOPATH;		/* restore */
3457c478bd9Sstevel@tonic-gate 	return (0);
3467c478bd9Sstevel@tonic-gate }
3477c478bd9Sstevel@tonic-gate 
3487c478bd9Sstevel@tonic-gate static void
3497c478bd9Sstevel@tonic-gate audit_pathbuild(struct pathname *pnp)
3507c478bd9Sstevel@tonic-gate {
3517c478bd9Sstevel@tonic-gate 	char *pp;	/* pointer to path */
3527c478bd9Sstevel@tonic-gate 	int len;	/* length of incoming segment */
3537c478bd9Sstevel@tonic-gate 	int newsect;	/* path requires a new section */
3547c478bd9Sstevel@tonic-gate 	struct audit_path	*pfxapp;	/* prefix for path */
3557c478bd9Sstevel@tonic-gate 	struct audit_path	*newapp;	/* new audit_path */
3567c478bd9Sstevel@tonic-gate 	t_audit_data_t *tad;	/* current thread */
3577c478bd9Sstevel@tonic-gate 	p_audit_data_t *pad;	/* current process */
3587c478bd9Sstevel@tonic-gate 
3597c478bd9Sstevel@tonic-gate 	tad = U2A(u);
3607c478bd9Sstevel@tonic-gate 	ASSERT(tad != NULL);
3617c478bd9Sstevel@tonic-gate 	pad = P2A(curproc);
3627c478bd9Sstevel@tonic-gate 	ASSERT(pad != NULL);
3637c478bd9Sstevel@tonic-gate 
3647c478bd9Sstevel@tonic-gate 	len = (pnp->pn_path - pnp->pn_buf) + 1;		/* +1 for terminator */
3657c478bd9Sstevel@tonic-gate 	ASSERT(len > 0);
3667c478bd9Sstevel@tonic-gate 
3677c478bd9Sstevel@tonic-gate 	/* adjust for path prefix: tad_aupath, ATPATH, CRD, or CWD */
3687c478bd9Sstevel@tonic-gate 	mutex_enter(&pad->pad_lock);
3697c478bd9Sstevel@tonic-gate 	if (tad->tad_aupath != NULL) {
3707c478bd9Sstevel@tonic-gate 		pfxapp = tad->tad_aupath;
3717c478bd9Sstevel@tonic-gate 	} else if (tad->tad_scid == SYS_fsat && pnp->pn_buf[0] != '/') {
3727c478bd9Sstevel@tonic-gate 		ASSERT(tad->tad_atpath != NULL);
3737c478bd9Sstevel@tonic-gate 		pfxapp = tad->tad_atpath;
3747c478bd9Sstevel@tonic-gate 	} else if (tad->tad_ctrl & PAD_ABSPATH) {
3757c478bd9Sstevel@tonic-gate 		pfxapp = pad->pad_root;
3767c478bd9Sstevel@tonic-gate 	} else {
3777c478bd9Sstevel@tonic-gate 		pfxapp = pad->pad_cwd;
3787c478bd9Sstevel@tonic-gate 	}
3797c478bd9Sstevel@tonic-gate 	au_pathhold(pfxapp);
3807c478bd9Sstevel@tonic-gate 	mutex_exit(&pad->pad_lock);
3817c478bd9Sstevel@tonic-gate 
3827c478bd9Sstevel@tonic-gate 	/* get an expanded buffer to hold the anchored path */
3837c478bd9Sstevel@tonic-gate 	newsect = tad->tad_ctrl & PAD_ATPATH;
3847c478bd9Sstevel@tonic-gate 	newapp = au_pathdup(pfxapp, newsect, len);
3857c478bd9Sstevel@tonic-gate 	au_pathrele(pfxapp);
3867c478bd9Sstevel@tonic-gate 
3877c478bd9Sstevel@tonic-gate 	pp = newapp->audp_sect[newapp->audp_cnt] - len;
3887c478bd9Sstevel@tonic-gate 	if (!newsect) {
3897c478bd9Sstevel@tonic-gate 		/* overlay previous NUL terminator */
3907c478bd9Sstevel@tonic-gate 		*(pp - 1) = '/';
3917c478bd9Sstevel@tonic-gate 	}
3927c478bd9Sstevel@tonic-gate 
3937c478bd9Sstevel@tonic-gate 	/* now add string of processed path */
3947c478bd9Sstevel@tonic-gate 	bcopy(pnp->pn_buf, pp, len);
3957c478bd9Sstevel@tonic-gate 	pp[len - 1] = '\0';
3967c478bd9Sstevel@tonic-gate 
3977c478bd9Sstevel@tonic-gate 	/* perform path simplification as necessary */
3987c478bd9Sstevel@tonic-gate 	audit_fixpath(newapp, len);
3997c478bd9Sstevel@tonic-gate 
4007c478bd9Sstevel@tonic-gate 	if (tad->tad_aupath)
4017c478bd9Sstevel@tonic-gate 		au_pathrele(tad->tad_aupath);
4027c478bd9Sstevel@tonic-gate 	tad->tad_aupath = newapp;
4037c478bd9Sstevel@tonic-gate 
4047c478bd9Sstevel@tonic-gate 	/* for case where multiple lookups in one syscall (rename) */
4057c478bd9Sstevel@tonic-gate 	tad->tad_ctrl &= ~(PAD_ABSPATH | PAD_ATPATH);
4067c478bd9Sstevel@tonic-gate }
4077c478bd9Sstevel@tonic-gate 
4087c478bd9Sstevel@tonic-gate 
4097c478bd9Sstevel@tonic-gate 
4107c478bd9Sstevel@tonic-gate /*ARGSUSED*/
4117c478bd9Sstevel@tonic-gate 
4127c478bd9Sstevel@tonic-gate /*
4137c478bd9Sstevel@tonic-gate  * ROUTINE:	AUDIT_ADDCOMPONENT
4147c478bd9Sstevel@tonic-gate  * PURPOSE:	extend the path by the component accepted
4157c478bd9Sstevel@tonic-gate  * CALLBY:	LOOKUPPN
4167c478bd9Sstevel@tonic-gate  * NOTE:	This function is called only when there is an error in
4177c478bd9Sstevel@tonic-gate  *		parsing a path component
4187c478bd9Sstevel@tonic-gate  * TODO:	Add the error component to audit record
4197c478bd9Sstevel@tonic-gate  * QUESTION:	what is this for
4207c478bd9Sstevel@tonic-gate  */
4217c478bd9Sstevel@tonic-gate 
4227c478bd9Sstevel@tonic-gate void
4237c478bd9Sstevel@tonic-gate audit_addcomponent(struct pathname *pnp)
4247c478bd9Sstevel@tonic-gate {
4259e9e6ab8Spaulson 	au_kcontext_t	*kctx = GET_KCTX_PZ;
4267c478bd9Sstevel@tonic-gate 	t_audit_data_t *tad;
4277c478bd9Sstevel@tonic-gate 
4287c478bd9Sstevel@tonic-gate 	tad = U2A(u);
4297c478bd9Sstevel@tonic-gate 	/*
4307c478bd9Sstevel@tonic-gate 	 * S2E_SP (PAD_SAVPATH) flag comes from audit_s2e[].au_ctrl. Used with
4317c478bd9Sstevel@tonic-gate 	 *	chroot, chdir, open, creat system call processing. It determines
4327c478bd9Sstevel@tonic-gate 	 *	if audit_savepath() will discard the path or we need it later.
4337c478bd9Sstevel@tonic-gate 	 * PAD_PATHFND means path already included in this audit record. It
4347c478bd9Sstevel@tonic-gate 	 *	is used in cases where multiple path lookups are done per
4357c478bd9Sstevel@tonic-gate 	 *	system call. The policy flag, AUDIT_PATH, controls if multiple
4367c478bd9Sstevel@tonic-gate 	 *	paths are allowed.
4377c478bd9Sstevel@tonic-gate 	 * S2E_NPT (PAD_NOPATH) flag comes from audit_s2e[].au_ctrl. Used with
4387c478bd9Sstevel@tonic-gate 	 *	exit processing to inhibit any paths that may be added due to
4397c478bd9Sstevel@tonic-gate 	 *	closes.
4407c478bd9Sstevel@tonic-gate 	 */
4417c478bd9Sstevel@tonic-gate 	if ((tad->tad_flag == 0 && !(tad->tad_ctrl & PAD_SAVPATH)) ||
4427c478bd9Sstevel@tonic-gate 		((tad->tad_ctrl & PAD_PATHFND) &&
4437c478bd9Sstevel@tonic-gate 		!(kctx->auk_policy & AUDIT_PATH)) ||
4447c478bd9Sstevel@tonic-gate 		(tad->tad_ctrl & PAD_NOPATH)) {
4457c478bd9Sstevel@tonic-gate 			return;
4467c478bd9Sstevel@tonic-gate 	}
4477c478bd9Sstevel@tonic-gate 
4487c478bd9Sstevel@tonic-gate 	return;
4497c478bd9Sstevel@tonic-gate 
4507c478bd9Sstevel@tonic-gate }	/* AUDIT_ADDCOMPONENT */
4517c478bd9Sstevel@tonic-gate 
4527c478bd9Sstevel@tonic-gate 
4537c478bd9Sstevel@tonic-gate 
4547c478bd9Sstevel@tonic-gate 
4557c478bd9Sstevel@tonic-gate 
4567c478bd9Sstevel@tonic-gate 
4577c478bd9Sstevel@tonic-gate 
4587c478bd9Sstevel@tonic-gate 
4597c478bd9Sstevel@tonic-gate /*
4607c478bd9Sstevel@tonic-gate  * ROUTINE:	AUDIT_ANCHORPATH
4617c478bd9Sstevel@tonic-gate  * PURPOSE:
4627c478bd9Sstevel@tonic-gate  * CALLBY:	LOOKUPPN
4637c478bd9Sstevel@tonic-gate  * NOTE:
4647c478bd9Sstevel@tonic-gate  * anchor path at "/". We have seen a symbolic link or entering for the
4657c478bd9Sstevel@tonic-gate  * first time we will throw away any saved path if path is anchored.
4667c478bd9Sstevel@tonic-gate  *
4677c478bd9Sstevel@tonic-gate  * flag = 0, path is relative.
4687c478bd9Sstevel@tonic-gate  * flag = 1, path is absolute. Free any saved path and set flag to PAD_ABSPATH.
4697c478bd9Sstevel@tonic-gate  *
4707c478bd9Sstevel@tonic-gate  * If the (new) path is absolute, then we have to throw away whatever we have
471*da6c28aaSamw  * already accumulated since it is being superseded by new path which is
4727c478bd9Sstevel@tonic-gate  * anchored at the root.
4737c478bd9Sstevel@tonic-gate  *		Note that if the path is relative, this function does nothing
4747c478bd9Sstevel@tonic-gate  * TODO:
4757c478bd9Sstevel@tonic-gate  * QUESTION:
4767c478bd9Sstevel@tonic-gate  */
4777c478bd9Sstevel@tonic-gate /*ARGSUSED*/
4787c478bd9Sstevel@tonic-gate void
4797c478bd9Sstevel@tonic-gate audit_anchorpath(struct pathname *pnp, int flag)
4807c478bd9Sstevel@tonic-gate {
4819e9e6ab8Spaulson 	au_kcontext_t	*kctx = GET_KCTX_PZ;
4827c478bd9Sstevel@tonic-gate 	t_audit_data_t *tad;
4837c478bd9Sstevel@tonic-gate 
4847c478bd9Sstevel@tonic-gate 	tad = U2A(u);
4857c478bd9Sstevel@tonic-gate 
4867c478bd9Sstevel@tonic-gate 	/*
4877c478bd9Sstevel@tonic-gate 	 * this event being audited or do we need path information
4887c478bd9Sstevel@tonic-gate 	 * later? This might be for a chdir/chroot or open (add path
4897c478bd9Sstevel@tonic-gate 	 * to file pointer. If the path has already been found for an
4907c478bd9Sstevel@tonic-gate 	 * open/creat then we don't need to process the path.
4917c478bd9Sstevel@tonic-gate 	 *
4927c478bd9Sstevel@tonic-gate 	 * S2E_SP (PAD_SAVPATH) flag comes from audit_s2e[].au_ctrl. Used with
4937c478bd9Sstevel@tonic-gate 	 *	chroot, chdir, open, creat system call processing. It determines
4947c478bd9Sstevel@tonic-gate 	 *	if audit_savepath() will discard the path or we need it later.
4957c478bd9Sstevel@tonic-gate 	 * PAD_PATHFND means path already included in this audit record. It
4967c478bd9Sstevel@tonic-gate 	 *	is used in cases where multiple path lookups are done per
4977c478bd9Sstevel@tonic-gate 	 *	system call. The policy flag, AUDIT_PATH, controls if multiple
4987c478bd9Sstevel@tonic-gate 	 *	paths are allowed.
4997c478bd9Sstevel@tonic-gate 	 * S2E_NPT (PAD_NOPATH) flag comes from audit_s2e[].au_ctrl. Used with
5007c478bd9Sstevel@tonic-gate 	 *	exit processing to inhibit any paths that may be added due to
5017c478bd9Sstevel@tonic-gate 	 *	closes.
5027c478bd9Sstevel@tonic-gate 	 */
5037c478bd9Sstevel@tonic-gate 	if ((tad->tad_flag == 0 && !(tad->tad_ctrl & PAD_SAVPATH)) ||
5047c478bd9Sstevel@tonic-gate 		((tad->tad_ctrl & PAD_PATHFND) &&
5057c478bd9Sstevel@tonic-gate 		!(kctx->auk_policy & AUDIT_PATH)) ||
5067c478bd9Sstevel@tonic-gate 		(tad->tad_ctrl & PAD_NOPATH)) {
5077c478bd9Sstevel@tonic-gate 			return;
5087c478bd9Sstevel@tonic-gate 	}
5097c478bd9Sstevel@tonic-gate 
5107c478bd9Sstevel@tonic-gate 	if (flag) {
5117c478bd9Sstevel@tonic-gate 		tad->tad_ctrl |= PAD_ABSPATH;
5127c478bd9Sstevel@tonic-gate 		if (tad->tad_aupath != NULL) {
5137c478bd9Sstevel@tonic-gate 			au_pathrele(tad->tad_aupath);
5147c478bd9Sstevel@tonic-gate 			tad->tad_aupath = NULL;
5157c478bd9Sstevel@tonic-gate 			tad->tad_vn = NULL;
5167c478bd9Sstevel@tonic-gate 		}
5177c478bd9Sstevel@tonic-gate 	}
5187c478bd9Sstevel@tonic-gate }
5197c478bd9Sstevel@tonic-gate 
5207c478bd9Sstevel@tonic-gate 
5217c478bd9Sstevel@tonic-gate /*
5227c478bd9Sstevel@tonic-gate  * symbolic link. Save previous components.
5237c478bd9Sstevel@tonic-gate  *
5247c478bd9Sstevel@tonic-gate  * the path seen so far looks like this
5257c478bd9Sstevel@tonic-gate  *
5267c478bd9Sstevel@tonic-gate  *  +-----------------------+----------------+
5277c478bd9Sstevel@tonic-gate  *  | path processed so far | remaining path |
5287c478bd9Sstevel@tonic-gate  *  +-----------------------+----------------+
5297c478bd9Sstevel@tonic-gate  *  \-----------------------/
5307c478bd9Sstevel@tonic-gate  *	save this string if
5317c478bd9Sstevel@tonic-gate  *	symbolic link relative
5327c478bd9Sstevel@tonic-gate  *	(but don't include  symlink component)
5337c478bd9Sstevel@tonic-gate  */
5347c478bd9Sstevel@tonic-gate 
5357c478bd9Sstevel@tonic-gate /*ARGSUSED*/
5367c478bd9Sstevel@tonic-gate 
5377c478bd9Sstevel@tonic-gate 
5387c478bd9Sstevel@tonic-gate /*
5397c478bd9Sstevel@tonic-gate  * ROUTINE:	AUDIT_SYMLINK
5407c478bd9Sstevel@tonic-gate  * PURPOSE:
5417c478bd9Sstevel@tonic-gate  * CALLBY:	LOOKUPPN
5427c478bd9Sstevel@tonic-gate  * NOTE:
5437c478bd9Sstevel@tonic-gate  * TODO:
5447c478bd9Sstevel@tonic-gate  * QUESTION:
5457c478bd9Sstevel@tonic-gate  */
5467c478bd9Sstevel@tonic-gate void
5477c478bd9Sstevel@tonic-gate audit_symlink(struct pathname *pnp, struct pathname *sympath)
5487c478bd9Sstevel@tonic-gate {
5497c478bd9Sstevel@tonic-gate 	char *sp;	/* saved initial pp */
5507c478bd9Sstevel@tonic-gate 	char *cp;	/* start of symlink path */
5517c478bd9Sstevel@tonic-gate 	uint_t len_path;	/* processed path before symlink */
5527c478bd9Sstevel@tonic-gate 	t_audit_data_t *tad;
5539e9e6ab8Spaulson 	au_kcontext_t	*kctx = GET_KCTX_PZ;
5547c478bd9Sstevel@tonic-gate 
5557c478bd9Sstevel@tonic-gate 	tad = U2A(u);
5567c478bd9Sstevel@tonic-gate 
5577c478bd9Sstevel@tonic-gate 	/*
5587c478bd9Sstevel@tonic-gate 	 * this event being audited or do we need path information
5597c478bd9Sstevel@tonic-gate 	 * later? This might be for a chdir/chroot or open (add path
5607c478bd9Sstevel@tonic-gate 	 * to file pointer. If the path has already been found for an
5617c478bd9Sstevel@tonic-gate 	 * open/creat then we don't need to process the path.
5627c478bd9Sstevel@tonic-gate 	 *
5637c478bd9Sstevel@tonic-gate 	 * S2E_SP (PAD_SAVPATH) flag comes from audit_s2e[].au_ctrl. Used with
5647c478bd9Sstevel@tonic-gate 	 *	chroot, chdir, open, creat system call processing. It determines
5657c478bd9Sstevel@tonic-gate 	 *	if audit_savepath() will discard the path or we need it later.
5667c478bd9Sstevel@tonic-gate 	 * PAD_PATHFND means path already included in this audit record. It
5677c478bd9Sstevel@tonic-gate 	 *	is used in cases where multiple path lookups are done per
5687c478bd9Sstevel@tonic-gate 	 *	system call. The policy flag, AUDIT_PATH, controls if multiple
5697c478bd9Sstevel@tonic-gate 	 *	paths are allowed.
5707c478bd9Sstevel@tonic-gate 	 * S2E_NPT (PAD_NOPATH) flag comes from audit_s2e[].au_ctrl. Used with
5717c478bd9Sstevel@tonic-gate 	 *	exit processing to inhibit any paths that may be added due to
5727c478bd9Sstevel@tonic-gate 	 *	closes.
5737c478bd9Sstevel@tonic-gate 	 */
5747c478bd9Sstevel@tonic-gate 	if ((tad->tad_flag == 0 &&
5757c478bd9Sstevel@tonic-gate 		!(tad->tad_ctrl & PAD_SAVPATH)) ||
5767c478bd9Sstevel@tonic-gate 		((tad->tad_ctrl & PAD_PATHFND) &&
5777c478bd9Sstevel@tonic-gate 		!(kctx->auk_policy & AUDIT_PATH)) ||
5787c478bd9Sstevel@tonic-gate 		(tad->tad_ctrl & PAD_NOPATH)) {
5797c478bd9Sstevel@tonic-gate 			return;
5807c478bd9Sstevel@tonic-gate 	}
5817c478bd9Sstevel@tonic-gate 
5827c478bd9Sstevel@tonic-gate 	/*
5837c478bd9Sstevel@tonic-gate 	 * if symbolic link is anchored at / then do nothing.
5847c478bd9Sstevel@tonic-gate 	 * When we cycle back to begin: in lookuppn() we will
5857c478bd9Sstevel@tonic-gate 	 * call audit_anchorpath() with a flag indicating if the
5867c478bd9Sstevel@tonic-gate 	 * path is anchored at / or is relative. We will release
5877c478bd9Sstevel@tonic-gate 	 * any saved path at that point.
5887c478bd9Sstevel@tonic-gate 	 *
5897c478bd9Sstevel@tonic-gate 	 * Note In the event that an error occurs in pn_combine then
5907c478bd9Sstevel@tonic-gate 	 * we want to remain pointing at the component that caused the
5917c478bd9Sstevel@tonic-gate 	 * path to overflow the pnp structure.
5927c478bd9Sstevel@tonic-gate 	 */
5937c478bd9Sstevel@tonic-gate 	if (sympath->pn_buf[0] == '/')
5947c478bd9Sstevel@tonic-gate 		return;
5957c478bd9Sstevel@tonic-gate 
5967c478bd9Sstevel@tonic-gate 	/* backup over last component */
5977c478bd9Sstevel@tonic-gate 	sp = cp = pnp->pn_path;
5987c478bd9Sstevel@tonic-gate 	while (*--cp != '/' && cp > pnp->pn_buf)
5997c478bd9Sstevel@tonic-gate 		;
6007c478bd9Sstevel@tonic-gate 
6017c478bd9Sstevel@tonic-gate 	len_path = cp - pnp->pn_buf;
6027c478bd9Sstevel@tonic-gate 
6037c478bd9Sstevel@tonic-gate 	/* is there anything to save? */
6047c478bd9Sstevel@tonic-gate 	if (len_path) {
605405e5d68Stz204579 		pnp->pn_path = pnp->pn_buf;
6067c478bd9Sstevel@tonic-gate 		audit_pathbuild(pnp);
6077c478bd9Sstevel@tonic-gate 		pnp->pn_path = sp;
6087c478bd9Sstevel@tonic-gate 	}
6097c478bd9Sstevel@tonic-gate }
6107c478bd9Sstevel@tonic-gate 
6117c478bd9Sstevel@tonic-gate /*
6127c478bd9Sstevel@tonic-gate  * file_is_public : determine whether events for the file (corresponding to
6137c478bd9Sstevel@tonic-gate  * 			the specified file attr) should be audited or ignored.
6147c478bd9Sstevel@tonic-gate  *
6157c478bd9Sstevel@tonic-gate  * returns: 	1 - if audit policy and file attributes indicate that
6167c478bd9Sstevel@tonic-gate  *			file is effectively public. read events for
6177c478bd9Sstevel@tonic-gate  *			the file should not be audited.
6187c478bd9Sstevel@tonic-gate  *		0 - otherwise
6197c478bd9Sstevel@tonic-gate  *
6207c478bd9Sstevel@tonic-gate  * The required attributes to be considered a public object are:
6217c478bd9Sstevel@tonic-gate  * - owned by root, AND
6227c478bd9Sstevel@tonic-gate  * - world-readable (permissions for other include read), AND
6237c478bd9Sstevel@tonic-gate  * - NOT world-writeable (permissions for other don't
6247c478bd9Sstevel@tonic-gate  *	include write)
6257c478bd9Sstevel@tonic-gate  *   (mode doesn't need to be checked for symlinks)
6267c478bd9Sstevel@tonic-gate  */
6277c478bd9Sstevel@tonic-gate int
6287c478bd9Sstevel@tonic-gate file_is_public(struct vattr *attr)
6297c478bd9Sstevel@tonic-gate {
6309e9e6ab8Spaulson 	au_kcontext_t	*kctx = GET_KCTX_PZ;
6317c478bd9Sstevel@tonic-gate 
6327c478bd9Sstevel@tonic-gate 	if (!(kctx->auk_policy & AUDIT_PUBLIC) && (attr->va_uid == 0) &&
6337c478bd9Sstevel@tonic-gate 	    ((attr->va_type == VLNK) ||
6347c478bd9Sstevel@tonic-gate 	    ((attr->va_mode & (VREAD>>6)) != 0) &&
6357c478bd9Sstevel@tonic-gate 	    ((attr->va_mode & (VWRITE>>6)) == 0))) {
6367c478bd9Sstevel@tonic-gate 		return (1);
6377c478bd9Sstevel@tonic-gate 	}
6387c478bd9Sstevel@tonic-gate 	return (0);
6397c478bd9Sstevel@tonic-gate }
6407c478bd9Sstevel@tonic-gate 
6417c478bd9Sstevel@tonic-gate 
6427c478bd9Sstevel@tonic-gate /*
6437c478bd9Sstevel@tonic-gate  * ROUTINE:	AUDIT_ATTRIBUTES
644*da6c28aaSamw  * PURPOSE:	Audit the attributes so we can tell why the error occurred
6457c478bd9Sstevel@tonic-gate  * CALLBY:	AUDIT_SAVEPATH
6467c478bd9Sstevel@tonic-gate  *		AUDIT_VNCREATE_FINISH
6477c478bd9Sstevel@tonic-gate  *		AUS_FCHOWN...audit_event.c...audit_path.c
6487c478bd9Sstevel@tonic-gate  * NOTE:
6497c478bd9Sstevel@tonic-gate  * TODO:
6507c478bd9Sstevel@tonic-gate  * QUESTION:
6517c478bd9Sstevel@tonic-gate  */
6527c478bd9Sstevel@tonic-gate void
6537c478bd9Sstevel@tonic-gate audit_attributes(struct vnode *vp)
6547c478bd9Sstevel@tonic-gate {
6557c478bd9Sstevel@tonic-gate 	struct vattr attr;
6567c478bd9Sstevel@tonic-gate 	struct t_audit_data *tad;
6577c478bd9Sstevel@tonic-gate 
6587c478bd9Sstevel@tonic-gate 	tad = U2A(u);
6597c478bd9Sstevel@tonic-gate 
6607c478bd9Sstevel@tonic-gate 	if (vp) {
6617c478bd9Sstevel@tonic-gate 		attr.va_mask = AT_ALL;
662*da6c28aaSamw 		if (VOP_GETATTR(vp, &attr, 0, CRED(), NULL) != 0)
6637c478bd9Sstevel@tonic-gate 			return;
6647c478bd9Sstevel@tonic-gate 
6657c478bd9Sstevel@tonic-gate 		if (file_is_public(&attr) && (tad->tad_ctrl & PAD_PUBLIC_EV)) {
6667c478bd9Sstevel@tonic-gate 			/*
6677c478bd9Sstevel@tonic-gate 			 * This is a public object and a "public" event
6687c478bd9Sstevel@tonic-gate 			 * (i.e., read only) -- either by definition
6697c478bd9Sstevel@tonic-gate 			 * (e.g., stat, access...) or by virtue of write access
6707c478bd9Sstevel@tonic-gate 			 * not being requested (e.g. mmap).
6717c478bd9Sstevel@tonic-gate 			 * Flag it in the tad to prevent this audit at the end.
6727c478bd9Sstevel@tonic-gate 			 */
6737c478bd9Sstevel@tonic-gate 			tad->tad_ctrl |= PAD_NOAUDIT;
6747c478bd9Sstevel@tonic-gate 		} else {
6757c478bd9Sstevel@tonic-gate 			au_uwrite(au_to_attr(&attr));
67645916cd2Sjpk 			audit_sec_attributes(&(u_ad), vp);
6777c478bd9Sstevel@tonic-gate 		}
6787c478bd9Sstevel@tonic-gate 	}
6797c478bd9Sstevel@tonic-gate }
6807c478bd9Sstevel@tonic-gate 
6817c478bd9Sstevel@tonic-gate 
6827c478bd9Sstevel@tonic-gate /*
6837c478bd9Sstevel@tonic-gate  * ROUTINE:	AUDIT_FALLOC
6847c478bd9Sstevel@tonic-gate  * PURPOSE:	allocating a new file structure
6857c478bd9Sstevel@tonic-gate  * CALLBY:	FALLOC
6867c478bd9Sstevel@tonic-gate  * NOTE:	file structure already initialized
6877c478bd9Sstevel@tonic-gate  * TODO:
6887c478bd9Sstevel@tonic-gate  * QUESTION:
6897c478bd9Sstevel@tonic-gate  */
6907c478bd9Sstevel@tonic-gate 
6917c478bd9Sstevel@tonic-gate void
6927c478bd9Sstevel@tonic-gate audit_falloc(struct file *fp)
6937c478bd9Sstevel@tonic-gate {	/* AUDIT_FALLOC */
6947c478bd9Sstevel@tonic-gate 
6957c478bd9Sstevel@tonic-gate 	f_audit_data_t *fad;
6967c478bd9Sstevel@tonic-gate 
6977c478bd9Sstevel@tonic-gate 	/* allocate per file audit structure if there a'int any */
6987c478bd9Sstevel@tonic-gate 	ASSERT(F2A(fp) == NULL);
6997c478bd9Sstevel@tonic-gate 
7007c478bd9Sstevel@tonic-gate 	fad = kmem_zalloc(sizeof (struct f_audit_data), KM_SLEEP);
7017c478bd9Sstevel@tonic-gate 
7027c478bd9Sstevel@tonic-gate 	F2A(fp) = fad;
7037c478bd9Sstevel@tonic-gate 
7047c478bd9Sstevel@tonic-gate 	fad->fad_thread = curthread; 	/* file audit data back ptr; DEBUG */
7057c478bd9Sstevel@tonic-gate }
7067c478bd9Sstevel@tonic-gate 
7077c478bd9Sstevel@tonic-gate /*
7087c478bd9Sstevel@tonic-gate  * ROUTINE:	AUDIT_UNFALLOC
7097c478bd9Sstevel@tonic-gate  * PURPOSE:	deallocate file audit data structure
7107c478bd9Sstevel@tonic-gate  * CALLBY:	CLOSEF
7117c478bd9Sstevel@tonic-gate  *		UNFALLOC
7127c478bd9Sstevel@tonic-gate  * NOTE:
7137c478bd9Sstevel@tonic-gate  * TODO:
7147c478bd9Sstevel@tonic-gate  * QUESTION:
7157c478bd9Sstevel@tonic-gate  */
7167c478bd9Sstevel@tonic-gate 
7177c478bd9Sstevel@tonic-gate void
7187c478bd9Sstevel@tonic-gate audit_unfalloc(struct file *fp)
7197c478bd9Sstevel@tonic-gate {
7207c478bd9Sstevel@tonic-gate 	f_audit_data_t *fad;
7217c478bd9Sstevel@tonic-gate 
7227c478bd9Sstevel@tonic-gate 	fad = F2A(fp);
7237c478bd9Sstevel@tonic-gate 
7247c478bd9Sstevel@tonic-gate 	if (!fad) {
7257c478bd9Sstevel@tonic-gate 		return;
7267c478bd9Sstevel@tonic-gate 	}
7277c478bd9Sstevel@tonic-gate 	if (fad->fad_aupath != NULL) {
7287c478bd9Sstevel@tonic-gate 		au_pathrele(fad->fad_aupath);
7297c478bd9Sstevel@tonic-gate 	}
7307c478bd9Sstevel@tonic-gate 	fp->f_audit_data = 0;
7317c478bd9Sstevel@tonic-gate 	kmem_free(fad, sizeof (struct f_audit_data));
7327c478bd9Sstevel@tonic-gate }
7337c478bd9Sstevel@tonic-gate 
7347c478bd9Sstevel@tonic-gate /*
7357c478bd9Sstevel@tonic-gate  * ROUTINE:	AUDIT_EXIT
7367c478bd9Sstevel@tonic-gate  * PURPOSE:
7377c478bd9Sstevel@tonic-gate  * CALLBY:	EXIT
7387c478bd9Sstevel@tonic-gate  * NOTE:
7397c478bd9Sstevel@tonic-gate  * TODO:
7407c478bd9Sstevel@tonic-gate  * QUESTION:	why cmw code as offset by 2 but not here
7417c478bd9Sstevel@tonic-gate  */
7427c478bd9Sstevel@tonic-gate /* ARGSUSED */
7437c478bd9Sstevel@tonic-gate void
7447c478bd9Sstevel@tonic-gate audit_exit(int code, int what)
7457c478bd9Sstevel@tonic-gate {
7467c478bd9Sstevel@tonic-gate 	struct t_audit_data *tad;
7477c478bd9Sstevel@tonic-gate 	tad = U2A(u);
7487c478bd9Sstevel@tonic-gate 
7497c478bd9Sstevel@tonic-gate 	/*
7507c478bd9Sstevel@tonic-gate 	 * tad_scid will be set by audit_start even if we are not auditing
7517c478bd9Sstevel@tonic-gate 	 * the event.
7527c478bd9Sstevel@tonic-gate 	 */
7537c478bd9Sstevel@tonic-gate 	if (tad->tad_scid == SYS_exit) {
7547c478bd9Sstevel@tonic-gate 		/*
7557c478bd9Sstevel@tonic-gate 		 * if we are auditing the exit system call, then complete
7567c478bd9Sstevel@tonic-gate 		 * audit record generation (no return from system call).
7577c478bd9Sstevel@tonic-gate 		 */
7587c478bd9Sstevel@tonic-gate 		if (tad->tad_flag && tad->tad_event == AUE_EXIT)
7597c478bd9Sstevel@tonic-gate 			audit_finish(0, SYS_exit, 0, 0);
7607c478bd9Sstevel@tonic-gate 		return;
7617c478bd9Sstevel@tonic-gate 	}
7627c478bd9Sstevel@tonic-gate 
7637c478bd9Sstevel@tonic-gate 	/*
7647c478bd9Sstevel@tonic-gate 	 * Anyone auditing the system call that was aborted?
7657c478bd9Sstevel@tonic-gate 	 */
7667c478bd9Sstevel@tonic-gate 	if (tad->tad_flag) {
7677c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_text("event aborted"));
7687c478bd9Sstevel@tonic-gate 		audit_finish(0, tad->tad_scid, 0, 0);
7697c478bd9Sstevel@tonic-gate 	}
7707c478bd9Sstevel@tonic-gate 
7717c478bd9Sstevel@tonic-gate 	/*
7727c478bd9Sstevel@tonic-gate 	 * Generate an audit record for process exit if preselected.
7737c478bd9Sstevel@tonic-gate 	 */
7747c478bd9Sstevel@tonic-gate 	(void) audit_start(0, SYS_exit, 0, 0);
7757c478bd9Sstevel@tonic-gate 	audit_finish(0, SYS_exit, 0, 0);
7767c478bd9Sstevel@tonic-gate }
7777c478bd9Sstevel@tonic-gate 
7787c478bd9Sstevel@tonic-gate /*
7797c478bd9Sstevel@tonic-gate  * ROUTINE:	AUDIT_CORE_START
7807c478bd9Sstevel@tonic-gate  * PURPOSE:
7817c478bd9Sstevel@tonic-gate  * CALLBY: 	PSIG
7827c478bd9Sstevel@tonic-gate  * NOTE:
7837c478bd9Sstevel@tonic-gate  * TODO:
7847c478bd9Sstevel@tonic-gate  */
7857c478bd9Sstevel@tonic-gate void
7867c478bd9Sstevel@tonic-gate audit_core_start(int sig)
7877c478bd9Sstevel@tonic-gate {
7887c478bd9Sstevel@tonic-gate 	au_event_t event;
7897c478bd9Sstevel@tonic-gate 	au_state_t estate;
7907c478bd9Sstevel@tonic-gate 	t_audit_data_t *tad;
7917c478bd9Sstevel@tonic-gate 	au_kcontext_t	*kctx;
7927c478bd9Sstevel@tonic-gate 
7937c478bd9Sstevel@tonic-gate 	tad = U2A(u);
7947c478bd9Sstevel@tonic-gate 
7957c478bd9Sstevel@tonic-gate 	ASSERT(tad != (t_audit_data_t *)0);
7967c478bd9Sstevel@tonic-gate 
7977c478bd9Sstevel@tonic-gate 	ASSERT(tad->tad_scid == 0);
7987c478bd9Sstevel@tonic-gate 	ASSERT(tad->tad_event == 0);
7997c478bd9Sstevel@tonic-gate 	ASSERT(tad->tad_evmod == 0);
8007c478bd9Sstevel@tonic-gate 	ASSERT(tad->tad_ctrl == 0);
8017c478bd9Sstevel@tonic-gate 	ASSERT(tad->tad_flag == 0);
8027c478bd9Sstevel@tonic-gate 	ASSERT(tad->tad_aupath == NULL);
8037c478bd9Sstevel@tonic-gate 
8049e9e6ab8Spaulson 	kctx = GET_KCTX_PZ;
8057c478bd9Sstevel@tonic-gate 
8067c478bd9Sstevel@tonic-gate 	/* get basic event for system call */
8077c478bd9Sstevel@tonic-gate 	event = AUE_CORE;
8087c478bd9Sstevel@tonic-gate 	estate = kctx->auk_ets[event];
8097c478bd9Sstevel@tonic-gate 
8107c478bd9Sstevel@tonic-gate 	if ((tad->tad_flag = auditme(kctx, tad, estate)) == 0)
8117c478bd9Sstevel@tonic-gate 		return;
8127c478bd9Sstevel@tonic-gate 
8137c478bd9Sstevel@tonic-gate 	/* reset the flags for non-user attributable events */
8147c478bd9Sstevel@tonic-gate 	tad->tad_ctrl   = PAD_CORE;
8157c478bd9Sstevel@tonic-gate 	tad->tad_scid   = 0;
8167c478bd9Sstevel@tonic-gate 
8177c478bd9Sstevel@tonic-gate 	/* if auditing not enabled, then don't generate an audit record */
8187c478bd9Sstevel@tonic-gate 
8197c478bd9Sstevel@tonic-gate 	if (!((kctx->auk_auditstate == AUC_AUDITING ||
8207c478bd9Sstevel@tonic-gate 	    kctx->auk_auditstate == AUC_INIT_AUDIT) ||
8217c478bd9Sstevel@tonic-gate 	    kctx->auk_auditstate == AUC_NOSPACE)) {
8227c478bd9Sstevel@tonic-gate 		tad->tad_flag = 0;
8237c478bd9Sstevel@tonic-gate 		tad->tad_ctrl = 0;
8247c478bd9Sstevel@tonic-gate 		return;
8257c478bd9Sstevel@tonic-gate 	}
8267c478bd9Sstevel@tonic-gate 
8277c478bd9Sstevel@tonic-gate 	tad->tad_event  = event;
8287c478bd9Sstevel@tonic-gate 	tad->tad_evmod  = 0;
8297c478bd9Sstevel@tonic-gate 
8307c478bd9Sstevel@tonic-gate 	ASSERT(tad->tad_ad == NULL);
8317c478bd9Sstevel@tonic-gate 
8327c478bd9Sstevel@tonic-gate 	au_write(&(u_ad), au_to_arg32(1, "signal", (uint32_t)sig));
8337c478bd9Sstevel@tonic-gate }
8347c478bd9Sstevel@tonic-gate 
8357c478bd9Sstevel@tonic-gate /*
8367c478bd9Sstevel@tonic-gate  * ROUTINE:	AUDIT_CORE_FINISH
8377c478bd9Sstevel@tonic-gate  * PURPOSE:
8387c478bd9Sstevel@tonic-gate  * CALLBY:	PSIG
8397c478bd9Sstevel@tonic-gate  * NOTE:
8407c478bd9Sstevel@tonic-gate  * TODO:
8417c478bd9Sstevel@tonic-gate  * QUESTION:
8427c478bd9Sstevel@tonic-gate  */
8437c478bd9Sstevel@tonic-gate 
8447c478bd9Sstevel@tonic-gate /*ARGSUSED*/
8457c478bd9Sstevel@tonic-gate void
8467c478bd9Sstevel@tonic-gate audit_core_finish(int code)
8477c478bd9Sstevel@tonic-gate {
8487c478bd9Sstevel@tonic-gate 	int flag;
8497c478bd9Sstevel@tonic-gate 	t_audit_data_t *tad;
8507c478bd9Sstevel@tonic-gate 	au_kcontext_t	*kctx;
8517c478bd9Sstevel@tonic-gate 
8527c478bd9Sstevel@tonic-gate 	tad = U2A(u);
8537c478bd9Sstevel@tonic-gate 
8547c478bd9Sstevel@tonic-gate 	ASSERT(tad != (t_audit_data_t *)0);
8557c478bd9Sstevel@tonic-gate 
8567c478bd9Sstevel@tonic-gate 	if ((flag = tad->tad_flag) == 0) {
8577c478bd9Sstevel@tonic-gate 		tad->tad_event = 0;
8587c478bd9Sstevel@tonic-gate 		tad->tad_evmod = 0;
8597c478bd9Sstevel@tonic-gate 		tad->tad_ctrl  = 0;
8607c478bd9Sstevel@tonic-gate 		ASSERT(tad->tad_aupath == NULL);
8617c478bd9Sstevel@tonic-gate 		return;
8627c478bd9Sstevel@tonic-gate 	}
8637c478bd9Sstevel@tonic-gate 	tad->tad_flag = 0;
8647c478bd9Sstevel@tonic-gate 
8659e9e6ab8Spaulson 	kctx = GET_KCTX_PZ;
8667c478bd9Sstevel@tonic-gate 
8677c478bd9Sstevel@tonic-gate 	/* kludge for error 0, should use `code==CLD_DUMPED' instead */
868799bd290Spwernau 	if (flag = audit_success(kctx, tad, 0, NULL)) {
8697c478bd9Sstevel@tonic-gate 		cred_t *cr = CRED();
8707c478bd9Sstevel@tonic-gate 		const auditinfo_addr_t *ainfo = crgetauinfo(cr);
8717c478bd9Sstevel@tonic-gate 
8727c478bd9Sstevel@tonic-gate 		ASSERT(ainfo != NULL);
8737c478bd9Sstevel@tonic-gate 
8747c478bd9Sstevel@tonic-gate 		/*
87581490fd2Sgww 		 * Add subject information (no locks since our private copy of
8767c478bd9Sstevel@tonic-gate 		 * credential
8777c478bd9Sstevel@tonic-gate 		 */
87881490fd2Sgww 		AUDIT_SETSUBJ(&(u_ad), cr, ainfo, kctx);
87945916cd2Sjpk 
8807c478bd9Sstevel@tonic-gate 		/* Add a return token (should use f argument) */
8817c478bd9Sstevel@tonic-gate 		add_return_token((caddr_t *)&(u_ad), tad->tad_scid, 0, 0);
8827c478bd9Sstevel@tonic-gate 
8837c478bd9Sstevel@tonic-gate 		AS_INC(as_generated, 1, kctx);
8847c478bd9Sstevel@tonic-gate 		AS_INC(as_kernel, 1, kctx);
8857c478bd9Sstevel@tonic-gate 	}
8867c478bd9Sstevel@tonic-gate 
8877c478bd9Sstevel@tonic-gate 	/* Close up everything */
8887c478bd9Sstevel@tonic-gate 	au_close(kctx, &(u_ad), flag, tad->tad_event, tad->tad_evmod);
8897c478bd9Sstevel@tonic-gate 
8907c478bd9Sstevel@tonic-gate 	/* free up any space remaining with the path's */
8917c478bd9Sstevel@tonic-gate 	if (tad->tad_aupath != NULL) {
8927c478bd9Sstevel@tonic-gate 		au_pathrele(tad->tad_aupath);
8937c478bd9Sstevel@tonic-gate 		tad->tad_aupath = NULL;
8947c478bd9Sstevel@tonic-gate 		tad->tad_vn = NULL;
8957c478bd9Sstevel@tonic-gate 	}
8967c478bd9Sstevel@tonic-gate 	tad->tad_event = 0;
8977c478bd9Sstevel@tonic-gate 	tad->tad_evmod = 0;
8987c478bd9Sstevel@tonic-gate 	tad->tad_ctrl  = 0;
8997c478bd9Sstevel@tonic-gate }
9007c478bd9Sstevel@tonic-gate 
9017c478bd9Sstevel@tonic-gate /*ARGSUSED*/
9027c478bd9Sstevel@tonic-gate void
9037c478bd9Sstevel@tonic-gate audit_stropen(struct vnode *vp, dev_t *devp, int flag, cred_t *crp)
9047c478bd9Sstevel@tonic-gate {
9057c478bd9Sstevel@tonic-gate }
9067c478bd9Sstevel@tonic-gate 
9077c478bd9Sstevel@tonic-gate /*ARGSUSED*/
9087c478bd9Sstevel@tonic-gate void
9097c478bd9Sstevel@tonic-gate audit_strclose(struct vnode *vp, int flag, cred_t *crp)
9107c478bd9Sstevel@tonic-gate {
9117c478bd9Sstevel@tonic-gate }
9127c478bd9Sstevel@tonic-gate 
9137c478bd9Sstevel@tonic-gate /*ARGSUSED*/
9147c478bd9Sstevel@tonic-gate void
9157c478bd9Sstevel@tonic-gate audit_strioctl(struct vnode *vp, int cmd, intptr_t arg, int flag,
9167c478bd9Sstevel@tonic-gate     int copyflag, cred_t *crp, int *rvalp)
9177c478bd9Sstevel@tonic-gate {
9187c478bd9Sstevel@tonic-gate }
9197c478bd9Sstevel@tonic-gate 
9207c478bd9Sstevel@tonic-gate 
9217c478bd9Sstevel@tonic-gate /*ARGSUSED*/
9227c478bd9Sstevel@tonic-gate void
9237c478bd9Sstevel@tonic-gate audit_strgetmsg(struct vnode *vp, struct strbuf *mctl, struct strbuf *mdata,
9247c478bd9Sstevel@tonic-gate     unsigned char *pri, int *flag, int fmode)
9257c478bd9Sstevel@tonic-gate {
9267c478bd9Sstevel@tonic-gate 	struct stdata *stp;
9277c478bd9Sstevel@tonic-gate 	t_audit_data_t *tad = U2A(u);
9287c478bd9Sstevel@tonic-gate 
9297c478bd9Sstevel@tonic-gate 	ASSERT(tad != (t_audit_data_t *)0);
9307c478bd9Sstevel@tonic-gate 
9317c478bd9Sstevel@tonic-gate 	stp = vp->v_stream;
9327c478bd9Sstevel@tonic-gate 
9337c478bd9Sstevel@tonic-gate 	/* lock stdata from audit_sock */
9347c478bd9Sstevel@tonic-gate 	mutex_enter(&stp->sd_lock);
9357c478bd9Sstevel@tonic-gate 
9367c478bd9Sstevel@tonic-gate 	/* proceed ONLY if user is being audited */
9377c478bd9Sstevel@tonic-gate 	if (!tad->tad_flag) {
9387c478bd9Sstevel@tonic-gate 		/*
9397c478bd9Sstevel@tonic-gate 		 * this is so we will not add audit data onto
9407c478bd9Sstevel@tonic-gate 		 * a thread that is not being audited.
9417c478bd9Sstevel@tonic-gate 		 */
9427c478bd9Sstevel@tonic-gate 		stp->sd_t_audit_data = NULL;
9437c478bd9Sstevel@tonic-gate 		mutex_exit(&stp->sd_lock);
9447c478bd9Sstevel@tonic-gate 		return;
9457c478bd9Sstevel@tonic-gate 	}
9467c478bd9Sstevel@tonic-gate 
9477c478bd9Sstevel@tonic-gate 	stp->sd_t_audit_data = (caddr_t)curthread;
9487c478bd9Sstevel@tonic-gate 	mutex_exit(&stp->sd_lock);
9497c478bd9Sstevel@tonic-gate }
9507c478bd9Sstevel@tonic-gate 
9517c478bd9Sstevel@tonic-gate /*ARGSUSED*/
9527c478bd9Sstevel@tonic-gate void
9537c478bd9Sstevel@tonic-gate audit_strputmsg(struct vnode *vp, struct strbuf *mctl, struct strbuf *mdata,
9547c478bd9Sstevel@tonic-gate     unsigned char pri, int flag, int fmode)
9557c478bd9Sstevel@tonic-gate {
9567c478bd9Sstevel@tonic-gate 	struct stdata *stp;
9577c478bd9Sstevel@tonic-gate 	t_audit_data_t *tad = U2A(u);
9587c478bd9Sstevel@tonic-gate 
9597c478bd9Sstevel@tonic-gate 	ASSERT(tad != (t_audit_data_t *)0);
9607c478bd9Sstevel@tonic-gate 
9617c478bd9Sstevel@tonic-gate 	stp = vp->v_stream;
9627c478bd9Sstevel@tonic-gate 
9637c478bd9Sstevel@tonic-gate 	/* lock stdata from audit_sock */
9647c478bd9Sstevel@tonic-gate 	mutex_enter(&stp->sd_lock);
9657c478bd9Sstevel@tonic-gate 
9667c478bd9Sstevel@tonic-gate 	/* proceed ONLY if user is being audited */
9677c478bd9Sstevel@tonic-gate 	if (!tad->tad_flag) {
9687c478bd9Sstevel@tonic-gate 		/*
9697c478bd9Sstevel@tonic-gate 		 * this is so we will not add audit data onto
9707c478bd9Sstevel@tonic-gate 		 * a thread that is not being audited.
9717c478bd9Sstevel@tonic-gate 		 */
9727c478bd9Sstevel@tonic-gate 		stp->sd_t_audit_data = NULL;
9737c478bd9Sstevel@tonic-gate 		mutex_exit(&stp->sd_lock);
9747c478bd9Sstevel@tonic-gate 		return;
9757c478bd9Sstevel@tonic-gate 	}
9767c478bd9Sstevel@tonic-gate 
9777c478bd9Sstevel@tonic-gate 	stp->sd_t_audit_data = (caddr_t)curthread;
9787c478bd9Sstevel@tonic-gate 	mutex_exit(&stp->sd_lock);
9797c478bd9Sstevel@tonic-gate }
9807c478bd9Sstevel@tonic-gate 
9817c478bd9Sstevel@tonic-gate /*
9827c478bd9Sstevel@tonic-gate  * ROUTINE:	AUDIT_CLOSEF
9837c478bd9Sstevel@tonic-gate  * PURPOSE:
9847c478bd9Sstevel@tonic-gate  * CALLBY:	CLOSEF
9857c478bd9Sstevel@tonic-gate  * NOTE:
9867c478bd9Sstevel@tonic-gate  * release per file audit resources when file structure is being released.
9877c478bd9Sstevel@tonic-gate  *
9887c478bd9Sstevel@tonic-gate  * IMPORTANT NOTE: Since we generate an audit record here, we may sleep
9897c478bd9Sstevel@tonic-gate  *	on the audit queue if it becomes full. This means
9907c478bd9Sstevel@tonic-gate  *	audit_closef can not be called when f_count == 0. Since
9917c478bd9Sstevel@tonic-gate  *	f_count == 0 indicates the file structure is free, another
9927c478bd9Sstevel@tonic-gate  *	process could attempt to use the file while we were still
9937c478bd9Sstevel@tonic-gate  *	asleep waiting on the audit queue. This would cause the
9947c478bd9Sstevel@tonic-gate  *	per file audit data to be corrupted when we finally do
9957c478bd9Sstevel@tonic-gate  *	wakeup.
9967c478bd9Sstevel@tonic-gate  * TODO:
9977c478bd9Sstevel@tonic-gate  * QUESTION:
9987c478bd9Sstevel@tonic-gate  */
9997c478bd9Sstevel@tonic-gate 
10007c478bd9Sstevel@tonic-gate void
10017c478bd9Sstevel@tonic-gate audit_closef(struct file *fp)
10027c478bd9Sstevel@tonic-gate {	/* AUDIT_CLOSEF */
10037c478bd9Sstevel@tonic-gate 	f_audit_data_t *fad;
10047c478bd9Sstevel@tonic-gate 	t_audit_data_t *tad;
10057c478bd9Sstevel@tonic-gate 	int success;
10067c478bd9Sstevel@tonic-gate 	au_state_t estate;
10077c478bd9Sstevel@tonic-gate 	struct vnode *vp;
10087c478bd9Sstevel@tonic-gate 	token_t *ad = NULL;
10097c478bd9Sstevel@tonic-gate 	struct vattr attr;
10107c478bd9Sstevel@tonic-gate 	short evmod = 0;
10117c478bd9Sstevel@tonic-gate 	const auditinfo_addr_t *ainfo;
10127c478bd9Sstevel@tonic-gate 	int getattr_ret;
10137c478bd9Sstevel@tonic-gate 	cred_t *cr;
10149e9e6ab8Spaulson 	au_kcontext_t	*kctx = GET_KCTX_PZ;
10157c478bd9Sstevel@tonic-gate 
10167c478bd9Sstevel@tonic-gate 	fad = F2A(fp);
10177c478bd9Sstevel@tonic-gate 	estate = kctx->auk_ets[AUE_CLOSE];
10187c478bd9Sstevel@tonic-gate 	tad = U2A(u);
10197c478bd9Sstevel@tonic-gate 	cr = CRED();
10207c478bd9Sstevel@tonic-gate 
10217c478bd9Sstevel@tonic-gate 	/* audit record already generated by system call envelope */
10227c478bd9Sstevel@tonic-gate 	if (tad->tad_event == AUE_CLOSE) {
10237c478bd9Sstevel@tonic-gate 		/* so close audit event will have bits set */
10247c478bd9Sstevel@tonic-gate 		tad->tad_evmod |= (short)fad->fad_flags;
10257c478bd9Sstevel@tonic-gate 		return;
10267c478bd9Sstevel@tonic-gate 	}
10277c478bd9Sstevel@tonic-gate 
10287c478bd9Sstevel@tonic-gate 	/* if auditing not enabled, then don't generate an audit record */
10297c478bd9Sstevel@tonic-gate 	if (!((kctx->auk_auditstate == AUC_AUDITING ||
10307c478bd9Sstevel@tonic-gate 	    kctx->auk_auditstate == AUC_INIT_AUDIT) ||
10317c478bd9Sstevel@tonic-gate 	    kctx->auk_auditstate == AUC_NOSPACE))
10327c478bd9Sstevel@tonic-gate 		return;
10337c478bd9Sstevel@tonic-gate 
10347c478bd9Sstevel@tonic-gate 	ainfo = crgetauinfo(cr);
10357c478bd9Sstevel@tonic-gate 	if (ainfo == NULL)
10367c478bd9Sstevel@tonic-gate 		return;
10377c478bd9Sstevel@tonic-gate 
10387c478bd9Sstevel@tonic-gate 	success = ainfo->ai_mask.as_success & estate;
10397c478bd9Sstevel@tonic-gate 
10407c478bd9Sstevel@tonic-gate 	/* not selected for this event */
10417c478bd9Sstevel@tonic-gate 	if (success == 0)
10427c478bd9Sstevel@tonic-gate 		return;
10437c478bd9Sstevel@tonic-gate 
10447c478bd9Sstevel@tonic-gate 	/*
10457c478bd9Sstevel@tonic-gate 	 * can't use audit_attributes here since we use a private audit area
10467c478bd9Sstevel@tonic-gate 	 * to build the audit record instead of the one off the thread.
10477c478bd9Sstevel@tonic-gate 	 */
10487c478bd9Sstevel@tonic-gate 	if ((vp = fp->f_vnode) != NULL) {
10497c478bd9Sstevel@tonic-gate 		attr.va_mask = AT_ALL;
1050*da6c28aaSamw 		getattr_ret = VOP_GETATTR(vp, &attr, 0, CRED(), NULL);
10517c478bd9Sstevel@tonic-gate 	}
10527c478bd9Sstevel@tonic-gate 
10537c478bd9Sstevel@tonic-gate 	/*
10547c478bd9Sstevel@tonic-gate 	 * When write was not used and the file can be considered public,
10557c478bd9Sstevel@tonic-gate 	 * then skip the audit.
10567c478bd9Sstevel@tonic-gate 	 */
10577c478bd9Sstevel@tonic-gate 	if ((getattr_ret == 0) && ((fp->f_flag & FWRITE) == 0)) {
10587c478bd9Sstevel@tonic-gate 		if (file_is_public(&attr)) {
10597c478bd9Sstevel@tonic-gate 			return;
10607c478bd9Sstevel@tonic-gate 		}
10617c478bd9Sstevel@tonic-gate 	}
10627c478bd9Sstevel@tonic-gate 
10637c478bd9Sstevel@tonic-gate 	evmod = (short)fad->fad_flags;
10647c478bd9Sstevel@tonic-gate 	if (fad->fad_aupath != NULL) {
10657c478bd9Sstevel@tonic-gate 		au_write((caddr_t *)&(ad), au_to_path(fad->fad_aupath));
10667c478bd9Sstevel@tonic-gate 	} else {
10677c478bd9Sstevel@tonic-gate #ifdef _LP64
10687c478bd9Sstevel@tonic-gate 		au_write((caddr_t *)&(ad), au_to_arg64(
10697c478bd9Sstevel@tonic-gate 			1, "no path: fp", (uint64_t)fp));
10707c478bd9Sstevel@tonic-gate #else
10717c478bd9Sstevel@tonic-gate 		au_write((caddr_t *)&(ad), au_to_arg32(
10727c478bd9Sstevel@tonic-gate 			1, "no path: fp", (uint32_t)fp));
10737c478bd9Sstevel@tonic-gate #endif
10747c478bd9Sstevel@tonic-gate 	}
10757c478bd9Sstevel@tonic-gate 
10767c478bd9Sstevel@tonic-gate 	if (getattr_ret == 0) {
10777c478bd9Sstevel@tonic-gate 		au_write((caddr_t *)&(ad), au_to_attr(&attr));
107845916cd2Sjpk 		audit_sec_attributes((caddr_t *)&(ad), vp);
10797c478bd9Sstevel@tonic-gate 	}
10807c478bd9Sstevel@tonic-gate 
108181490fd2Sgww 	/* Add subject information */
108281490fd2Sgww 	AUDIT_SETSUBJ((caddr_t *)&(ad), cr, ainfo, kctx);
108345916cd2Sjpk 
10847c478bd9Sstevel@tonic-gate 	/* add a return token */
10857c478bd9Sstevel@tonic-gate 	add_return_token((caddr_t *)&(ad), tad->tad_scid, 0, 0);
10867c478bd9Sstevel@tonic-gate 
10877c478bd9Sstevel@tonic-gate 	AS_INC(as_generated, 1, kctx);
10887c478bd9Sstevel@tonic-gate 	AS_INC(as_kernel, 1, kctx);
10897c478bd9Sstevel@tonic-gate 
10907c478bd9Sstevel@tonic-gate 	/*
10917c478bd9Sstevel@tonic-gate 	 * Close up everything
10927c478bd9Sstevel@tonic-gate 	 * Note: path space recovery handled by normal system
10937c478bd9Sstevel@tonic-gate 	 * call envelope if not at last close.
10947c478bd9Sstevel@tonic-gate 	 * Note there is no failure at this point since
10957c478bd9Sstevel@tonic-gate 	 *   this represents closes due to exit of process,
10967c478bd9Sstevel@tonic-gate 	 *   thus we always indicate successful closes.
10977c478bd9Sstevel@tonic-gate 	 */
10987c478bd9Sstevel@tonic-gate 	au_close(kctx, (caddr_t *)&(ad), AU_OK | AU_DEFER,
10997c478bd9Sstevel@tonic-gate 	    AUE_CLOSE, evmod);
11007c478bd9Sstevel@tonic-gate }
11017c478bd9Sstevel@tonic-gate 
11027c478bd9Sstevel@tonic-gate /*
11037c478bd9Sstevel@tonic-gate  * ROUTINE:	AUDIT_SET
11047c478bd9Sstevel@tonic-gate  * PURPOSE:	Audit the file path and file attributes.
11057c478bd9Sstevel@tonic-gate  * CALLBY:	SETF
11067c478bd9Sstevel@tonic-gate  * NOTE:	SETF associate a file pointer with user area's open files.
11077c478bd9Sstevel@tonic-gate  * TODO:
11087c478bd9Sstevel@tonic-gate  * call audit_finish directly ???
11097c478bd9Sstevel@tonic-gate  * QUESTION:
11107c478bd9Sstevel@tonic-gate  */
11117c478bd9Sstevel@tonic-gate 
11127c478bd9Sstevel@tonic-gate /*ARGSUSED*/
11137c478bd9Sstevel@tonic-gate void
11147c478bd9Sstevel@tonic-gate audit_setf(file_t *fp, int fd)
11157c478bd9Sstevel@tonic-gate {
11167c478bd9Sstevel@tonic-gate 	f_audit_data_t *fad;
11177c478bd9Sstevel@tonic-gate 	t_audit_data_t *tad;
11187c478bd9Sstevel@tonic-gate 
11197c478bd9Sstevel@tonic-gate 	if (fp == NULL)
11207c478bd9Sstevel@tonic-gate 		return;
11217c478bd9Sstevel@tonic-gate 
11227c478bd9Sstevel@tonic-gate 	tad = T2A(curthread);
11237c478bd9Sstevel@tonic-gate 	fad = F2A(fp);
11247c478bd9Sstevel@tonic-gate 
11257c478bd9Sstevel@tonic-gate 	if (!(tad->tad_scid == SYS_open || tad->tad_scid == SYS_creat ||
11267c478bd9Sstevel@tonic-gate 	    tad->tad_scid == SYS_open64 || tad->tad_scid == SYS_creat64 ||
11277c478bd9Sstevel@tonic-gate 	    tad->tad_scid == SYS_fsat))
11287c478bd9Sstevel@tonic-gate 		return;
11297c478bd9Sstevel@tonic-gate 
11307c478bd9Sstevel@tonic-gate 	/* no path */
11317c478bd9Sstevel@tonic-gate 	if (tad->tad_aupath == 0)
11327c478bd9Sstevel@tonic-gate 		return;
11337c478bd9Sstevel@tonic-gate 
11347c478bd9Sstevel@tonic-gate 	/*
11357c478bd9Sstevel@tonic-gate 	 * assign path information associated with file audit data
11367c478bd9Sstevel@tonic-gate 	 * use tad hold
11377c478bd9Sstevel@tonic-gate 	 */
11387c478bd9Sstevel@tonic-gate 	fad->fad_aupath = tad->tad_aupath;
11397c478bd9Sstevel@tonic-gate 	tad->tad_aupath = NULL;
11407c478bd9Sstevel@tonic-gate 	tad->tad_vn = NULL;
11417c478bd9Sstevel@tonic-gate 
11427c478bd9Sstevel@tonic-gate 	if (!(tad->tad_ctrl & PAD_TRUE_CREATE)) {
11437c478bd9Sstevel@tonic-gate 	/* adjust event type */
11447c478bd9Sstevel@tonic-gate 		switch (tad->tad_event) {
11457c478bd9Sstevel@tonic-gate 		case AUE_OPEN_RC:
11467c478bd9Sstevel@tonic-gate 			tad->tad_event = AUE_OPEN_R;
11477c478bd9Sstevel@tonic-gate 			tad->tad_ctrl |= PAD_PUBLIC_EV;
11487c478bd9Sstevel@tonic-gate 			break;
11497c478bd9Sstevel@tonic-gate 		case AUE_OPEN_RTC:
11507c478bd9Sstevel@tonic-gate 			tad->tad_event = AUE_OPEN_RT;
11517c478bd9Sstevel@tonic-gate 			break;
11527c478bd9Sstevel@tonic-gate 		case AUE_OPEN_WC:
11537c478bd9Sstevel@tonic-gate 			tad->tad_event = AUE_OPEN_W;
11547c478bd9Sstevel@tonic-gate 			break;
11557c478bd9Sstevel@tonic-gate 		case AUE_OPEN_WTC:
11567c478bd9Sstevel@tonic-gate 			tad->tad_event = AUE_OPEN_WT;
11577c478bd9Sstevel@tonic-gate 			break;
11587c478bd9Sstevel@tonic-gate 		case AUE_OPEN_RWC:
11597c478bd9Sstevel@tonic-gate 			tad->tad_event = AUE_OPEN_RW;
11607c478bd9Sstevel@tonic-gate 			break;
11617c478bd9Sstevel@tonic-gate 		case AUE_OPEN_RWTC:
11627c478bd9Sstevel@tonic-gate 			tad->tad_event = AUE_OPEN_RWT;
11637c478bd9Sstevel@tonic-gate 			break;
11647c478bd9Sstevel@tonic-gate 		default:
11657c478bd9Sstevel@tonic-gate 			break;
11667c478bd9Sstevel@tonic-gate 		}
11677c478bd9Sstevel@tonic-gate 	}
11687c478bd9Sstevel@tonic-gate }
11697c478bd9Sstevel@tonic-gate 
11707c478bd9Sstevel@tonic-gate 
11717c478bd9Sstevel@tonic-gate /*
11727c478bd9Sstevel@tonic-gate  * ROUTINE:	AUDIT_COPEN
11737c478bd9Sstevel@tonic-gate  * PURPOSE:
11747c478bd9Sstevel@tonic-gate  * CALLBY:	COPEN
11757c478bd9Sstevel@tonic-gate  * NOTE:
11767c478bd9Sstevel@tonic-gate  * TODO:
11777c478bd9Sstevel@tonic-gate  * QUESTION:
11787c478bd9Sstevel@tonic-gate  */
11797c478bd9Sstevel@tonic-gate /*ARGSUSED*/
11807c478bd9Sstevel@tonic-gate void
11817c478bd9Sstevel@tonic-gate audit_copen(int fd, file_t *fp, vnode_t *vp)
11827c478bd9Sstevel@tonic-gate {
11837c478bd9Sstevel@tonic-gate }
11847c478bd9Sstevel@tonic-gate 
11857c478bd9Sstevel@tonic-gate void
11867c478bd9Sstevel@tonic-gate audit_ipc(int type, int id, void *vp)
11877c478bd9Sstevel@tonic-gate {
11887c478bd9Sstevel@tonic-gate 	/* if not auditing this event, then do nothing */
11897c478bd9Sstevel@tonic-gate 	if (ad_flag == 0)
11907c478bd9Sstevel@tonic-gate 		return;
11917c478bd9Sstevel@tonic-gate 
11927c478bd9Sstevel@tonic-gate 	switch (type) {
11937c478bd9Sstevel@tonic-gate 	case AT_IPC_MSG:
11947c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_ipc(AT_IPC_MSG, id));
11957c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_ipc_perm(&(((kmsqid_t *)vp)->msg_perm)));
11967c478bd9Sstevel@tonic-gate 		break;
11977c478bd9Sstevel@tonic-gate 	case AT_IPC_SEM:
11987c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_ipc(AT_IPC_SEM, id));
11997c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_ipc_perm(&(((ksemid_t *)vp)->sem_perm)));
12007c478bd9Sstevel@tonic-gate 		break;
12017c478bd9Sstevel@tonic-gate 	case AT_IPC_SHM:
12027c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_ipc(AT_IPC_SHM, id));
12037c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_ipc_perm(&(((kshmid_t *)vp)->shm_perm)));
12047c478bd9Sstevel@tonic-gate 		break;
12057c478bd9Sstevel@tonic-gate 	}
12067c478bd9Sstevel@tonic-gate }
12077c478bd9Sstevel@tonic-gate 
12087c478bd9Sstevel@tonic-gate void
12097c478bd9Sstevel@tonic-gate audit_ipcget(int type, void *vp)
12107c478bd9Sstevel@tonic-gate {
12117c478bd9Sstevel@tonic-gate 	/* if not auditing this event, then do nothing */
12127c478bd9Sstevel@tonic-gate 	if (ad_flag == 0)
12137c478bd9Sstevel@tonic-gate 		return;
12147c478bd9Sstevel@tonic-gate 
12157c478bd9Sstevel@tonic-gate 	switch (type) {
12167c478bd9Sstevel@tonic-gate 	case NULL:
12177c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_ipc_perm((struct kipc_perm *)vp));
12187c478bd9Sstevel@tonic-gate 		break;
12197c478bd9Sstevel@tonic-gate 	case AT_IPC_MSG:
12207c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_ipc_perm(&(((kmsqid_t *)vp)->msg_perm)));
12217c478bd9Sstevel@tonic-gate 		break;
12227c478bd9Sstevel@tonic-gate 	case AT_IPC_SEM:
12237c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_ipc_perm(&(((ksemid_t *)vp)->sem_perm)));
12247c478bd9Sstevel@tonic-gate 		break;
12257c478bd9Sstevel@tonic-gate 	case AT_IPC_SHM:
12267c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_ipc_perm(&(((kshmid_t *)vp)->shm_perm)));
12277c478bd9Sstevel@tonic-gate 		break;
12287c478bd9Sstevel@tonic-gate 	}
12297c478bd9Sstevel@tonic-gate }
12307c478bd9Sstevel@tonic-gate 
12317c478bd9Sstevel@tonic-gate /*
12327c478bd9Sstevel@tonic-gate  * ROUTINE:	AUDIT_REBOOT
12337c478bd9Sstevel@tonic-gate  * PURPOSE:
12347c478bd9Sstevel@tonic-gate  * CALLBY:
12357c478bd9Sstevel@tonic-gate  * NOTE:
12367c478bd9Sstevel@tonic-gate  * At this point we know that the system call reboot will not return. We thus
12377c478bd9Sstevel@tonic-gate  * have to complete the audit record generation and put it onto the queue.
12387c478bd9Sstevel@tonic-gate  * This might be fairly useless if the auditing daemon is already dead....
12397c478bd9Sstevel@tonic-gate  * TODO:
12407c478bd9Sstevel@tonic-gate  * QUESTION:	who calls audit_reboot
12417c478bd9Sstevel@tonic-gate  */
12427c478bd9Sstevel@tonic-gate 
12437c478bd9Sstevel@tonic-gate void
12447c478bd9Sstevel@tonic-gate audit_reboot(void)
12457c478bd9Sstevel@tonic-gate {
12467c478bd9Sstevel@tonic-gate 	int flag;
12477c478bd9Sstevel@tonic-gate 	t_audit_data_t *tad;
12489e9e6ab8Spaulson 	au_kcontext_t	*kctx = GET_KCTX_PZ;
12497c478bd9Sstevel@tonic-gate 
12507c478bd9Sstevel@tonic-gate 	tad = U2A(u);
12517c478bd9Sstevel@tonic-gate 
12527c478bd9Sstevel@tonic-gate 	/* if not auditing this event, then do nothing */
12537c478bd9Sstevel@tonic-gate 	if (tad->tad_flag == 0)
12547c478bd9Sstevel@tonic-gate 		return;
12557c478bd9Sstevel@tonic-gate 
12567c478bd9Sstevel@tonic-gate 	/* do preselection on success/failure */
1257799bd290Spwernau 	if (flag = audit_success(kctx, tad, 0, NULL)) {
12587c478bd9Sstevel@tonic-gate 		/* add a process token */
12597c478bd9Sstevel@tonic-gate 
12607c478bd9Sstevel@tonic-gate 		cred_t *cr = CRED();
12617c478bd9Sstevel@tonic-gate 		const auditinfo_addr_t *ainfo = crgetauinfo(cr);
12627c478bd9Sstevel@tonic-gate 
12637c478bd9Sstevel@tonic-gate 		if (ainfo == NULL)
12647c478bd9Sstevel@tonic-gate 			return;
12657c478bd9Sstevel@tonic-gate 
126681490fd2Sgww 		/* Add subject information */
126781490fd2Sgww 		AUDIT_SETSUBJ(&(u_ad), cr, ainfo, kctx);
126845916cd2Sjpk 
12697c478bd9Sstevel@tonic-gate 		/* add a return token */
12707c478bd9Sstevel@tonic-gate 		add_return_token((caddr_t *)&(u_ad), tad->tad_scid, 0, 0);
12717c478bd9Sstevel@tonic-gate 
12727c478bd9Sstevel@tonic-gate 		AS_INC(as_generated, 1, kctx);
12737c478bd9Sstevel@tonic-gate 		AS_INC(as_kernel, 1, kctx);
12747c478bd9Sstevel@tonic-gate 	}
12757c478bd9Sstevel@tonic-gate 
12767c478bd9Sstevel@tonic-gate 	/*
12777c478bd9Sstevel@tonic-gate 	 * Flow control useless here since we're going
12787c478bd9Sstevel@tonic-gate 	 * to drop everything in the queue anyway. Why
12797c478bd9Sstevel@tonic-gate 	 * block and wait. There aint anyone left alive to
12807c478bd9Sstevel@tonic-gate 	 * read the records remaining anyway.
12817c478bd9Sstevel@tonic-gate 	 */
12827c478bd9Sstevel@tonic-gate 
12837c478bd9Sstevel@tonic-gate 	/* Close up everything */
12847c478bd9Sstevel@tonic-gate 	au_close(kctx, &(u_ad), flag | AU_DONTBLOCK,
12857c478bd9Sstevel@tonic-gate 	    tad->tad_event, tad->tad_evmod);
12867c478bd9Sstevel@tonic-gate }
12877c478bd9Sstevel@tonic-gate 
12887c478bd9Sstevel@tonic-gate void
12897c478bd9Sstevel@tonic-gate audit_setfsat_path(int argnum)
12907c478bd9Sstevel@tonic-gate {
12917c478bd9Sstevel@tonic-gate 	klwp_id_t clwp = ttolwp(curthread);
12927c478bd9Sstevel@tonic-gate 	struct file  *fp;
12937c478bd9Sstevel@tonic-gate 	uint32_t fd;
12947c478bd9Sstevel@tonic-gate 	t_audit_data_t *tad;
12957c478bd9Sstevel@tonic-gate 	struct f_audit_data *fad;
12967c478bd9Sstevel@tonic-gate 	p_audit_data_t *pad;	/* current process */
1297*da6c28aaSamw 	struct a {
1298*da6c28aaSamw 		long id;
1299*da6c28aaSamw 		long arg1;
1300*da6c28aaSamw 		long arg2;
1301*da6c28aaSamw 		long arg3;
1302*da6c28aaSamw 		long arg4;
1303*da6c28aaSamw 		long arg5;
1304*da6c28aaSamw 	} *uap;
13057c478bd9Sstevel@tonic-gate 	struct b {
13067c478bd9Sstevel@tonic-gate 		long arg1;
13077c478bd9Sstevel@tonic-gate 		long arg2;
13087c478bd9Sstevel@tonic-gate 		long arg3;
13097c478bd9Sstevel@tonic-gate 		long arg4;
13107c478bd9Sstevel@tonic-gate 		long arg5;
13117c478bd9Sstevel@tonic-gate 	} *uap1;
13127c478bd9Sstevel@tonic-gate 
13137c478bd9Sstevel@tonic-gate 	if (clwp == NULL)
13147c478bd9Sstevel@tonic-gate 		return;
13157c478bd9Sstevel@tonic-gate 	uap1 = (struct b *)&clwp->lwp_ap[1];
1316*da6c28aaSamw 	uap = (struct a *)clwp->lwp_ap;
13177c478bd9Sstevel@tonic-gate 
13187c478bd9Sstevel@tonic-gate 	tad = U2A(u);
13197c478bd9Sstevel@tonic-gate 
13207c478bd9Sstevel@tonic-gate 	ASSERT(tad != NULL);
13217c478bd9Sstevel@tonic-gate 
13227c478bd9Sstevel@tonic-gate 	if (tad->tad_scid != SYS_fsat)
13237c478bd9Sstevel@tonic-gate 		return;
13247c478bd9Sstevel@tonic-gate 
13257c478bd9Sstevel@tonic-gate 	switch (argnum) {
13267c478bd9Sstevel@tonic-gate 	case 1:
13277c478bd9Sstevel@tonic-gate 		fd = (uint32_t)uap1->arg1;
13287c478bd9Sstevel@tonic-gate 		break;
13297c478bd9Sstevel@tonic-gate 	case 2:
13307c478bd9Sstevel@tonic-gate 		fd = (uint32_t)uap1->arg2;
13317c478bd9Sstevel@tonic-gate 		break;
13327c478bd9Sstevel@tonic-gate 	case 3:
13337c478bd9Sstevel@tonic-gate 		fd = (uint32_t)uap1->arg3;
13347c478bd9Sstevel@tonic-gate 		break;
13357c478bd9Sstevel@tonic-gate 	case 4:
13367c478bd9Sstevel@tonic-gate 		fd = (uint32_t)uap1->arg4;
13377c478bd9Sstevel@tonic-gate 		break;
13387c478bd9Sstevel@tonic-gate 	case 5:
13397c478bd9Sstevel@tonic-gate 		fd = (uint32_t)uap1->arg5;
13407c478bd9Sstevel@tonic-gate 		break;
13417c478bd9Sstevel@tonic-gate 	default:
13427c478bd9Sstevel@tonic-gate 		return;
13437c478bd9Sstevel@tonic-gate 	}
13447c478bd9Sstevel@tonic-gate 
1345*da6c28aaSamw 	if (uap->id == 9 && tad->tad_atpath != NULL) { /* openattrdir */
1346*da6c28aaSamw 		tad->tad_ctrl |= PAD_ATPATH;
1347*da6c28aaSamw 		return;
1348*da6c28aaSamw 	}
13497c478bd9Sstevel@tonic-gate 	if (tad->tad_atpath != NULL) {
13507c478bd9Sstevel@tonic-gate 		au_pathrele(tad->tad_atpath);
13517c478bd9Sstevel@tonic-gate 		tad->tad_atpath = NULL;
13527c478bd9Sstevel@tonic-gate 	}
13537c478bd9Sstevel@tonic-gate 	if (fd != AT_FDCWD) {
13547c478bd9Sstevel@tonic-gate 		if ((fp = getf(fd)) == NULL)
13557c478bd9Sstevel@tonic-gate 			return;
13567c478bd9Sstevel@tonic-gate 
13577c478bd9Sstevel@tonic-gate 		fad = F2A(fp);
13587c478bd9Sstevel@tonic-gate 		ASSERT(fad);
13597c478bd9Sstevel@tonic-gate 		au_pathhold(fad->fad_aupath);
13607c478bd9Sstevel@tonic-gate 		tad->tad_atpath = fad->fad_aupath;
13617c478bd9Sstevel@tonic-gate 		releasef(fd);
13627c478bd9Sstevel@tonic-gate 	} else {
13637c478bd9Sstevel@tonic-gate 		pad = P2A(curproc);
13647c478bd9Sstevel@tonic-gate 		mutex_enter(&pad->pad_lock);
13657c478bd9Sstevel@tonic-gate 		au_pathhold(pad->pad_cwd);
13667c478bd9Sstevel@tonic-gate 		tad->tad_atpath = pad->pad_cwd;
13677c478bd9Sstevel@tonic-gate 		mutex_exit(&pad->pad_lock);
13687c478bd9Sstevel@tonic-gate 	}
13697c478bd9Sstevel@tonic-gate }
13707c478bd9Sstevel@tonic-gate 
13717c478bd9Sstevel@tonic-gate void
13727c478bd9Sstevel@tonic-gate audit_symlink_create(vnode_t *dvp, char *sname, char *target, int error)
13737c478bd9Sstevel@tonic-gate {
13747c478bd9Sstevel@tonic-gate 	t_audit_data_t *tad;
13757c478bd9Sstevel@tonic-gate 	vnode_t	*vp;
13767c478bd9Sstevel@tonic-gate 
13777c478bd9Sstevel@tonic-gate 	tad = U2A(u);
13787c478bd9Sstevel@tonic-gate 
13797c478bd9Sstevel@tonic-gate 	/* if not auditing this event, then do nothing */
13807c478bd9Sstevel@tonic-gate 	if (tad->tad_flag == 0)
13817c478bd9Sstevel@tonic-gate 		return;
13827c478bd9Sstevel@tonic-gate 
13837c478bd9Sstevel@tonic-gate 	au_uwrite(au_to_text(target));
13847c478bd9Sstevel@tonic-gate 
13857c478bd9Sstevel@tonic-gate 	if (error)
13867c478bd9Sstevel@tonic-gate 		return;
13877c478bd9Sstevel@tonic-gate 
1388*da6c28aaSamw 	error = VOP_LOOKUP(dvp, sname, &vp, NULL, 0, NULL, CRED(),
1389*da6c28aaSamw 			NULL, NULL, NULL);
13907c478bd9Sstevel@tonic-gate 	if (error == 0) {
13917c478bd9Sstevel@tonic-gate 		audit_attributes(vp);
13927c478bd9Sstevel@tonic-gate 		VN_RELE(vp);
13937c478bd9Sstevel@tonic-gate 	}
13947c478bd9Sstevel@tonic-gate }
13957c478bd9Sstevel@tonic-gate 
13967c478bd9Sstevel@tonic-gate /*
13977c478bd9Sstevel@tonic-gate  * ROUTINE:	AUDIT_VNCREATE_START
13987c478bd9Sstevel@tonic-gate  * PURPOSE:	set flag so path name lookup in create will not add attribute
13997c478bd9Sstevel@tonic-gate  * CALLBY:	VN_CREATE
14007c478bd9Sstevel@tonic-gate  * NOTE:
14017c478bd9Sstevel@tonic-gate  * TODO:
14027c478bd9Sstevel@tonic-gate  * QUESTION:
14037c478bd9Sstevel@tonic-gate  */
14047c478bd9Sstevel@tonic-gate 
14057c478bd9Sstevel@tonic-gate void
14067c478bd9Sstevel@tonic-gate audit_vncreate_start()
14077c478bd9Sstevel@tonic-gate {
14087c478bd9Sstevel@tonic-gate 	t_audit_data_t *tad;
14097c478bd9Sstevel@tonic-gate 
14107c478bd9Sstevel@tonic-gate 	tad = U2A(u);
14117c478bd9Sstevel@tonic-gate 	tad->tad_ctrl |= PAD_NOATTRB;
14127c478bd9Sstevel@tonic-gate }
14137c478bd9Sstevel@tonic-gate 
14147c478bd9Sstevel@tonic-gate /*
14157c478bd9Sstevel@tonic-gate  * ROUTINE:	AUDIT_VNCREATE_FINISH
14167c478bd9Sstevel@tonic-gate  * PURPOSE:
14177c478bd9Sstevel@tonic-gate  * CALLBY:	VN_CREATE
14187c478bd9Sstevel@tonic-gate  * NOTE:
14197c478bd9Sstevel@tonic-gate  * TODO:
14207c478bd9Sstevel@tonic-gate  * QUESTION:
14217c478bd9Sstevel@tonic-gate  */
14227c478bd9Sstevel@tonic-gate void
14237c478bd9Sstevel@tonic-gate audit_vncreate_finish(struct vnode *vp, int error)
14247c478bd9Sstevel@tonic-gate {
14257c478bd9Sstevel@tonic-gate 	t_audit_data_t *tad;
14267c478bd9Sstevel@tonic-gate 
14277c478bd9Sstevel@tonic-gate 	if (error)
14287c478bd9Sstevel@tonic-gate 		return;
14297c478bd9Sstevel@tonic-gate 
14307c478bd9Sstevel@tonic-gate 	tad = U2A(u);
14317c478bd9Sstevel@tonic-gate 
14327c478bd9Sstevel@tonic-gate 	/* if not auditing this event, then do nothing */
14337c478bd9Sstevel@tonic-gate 	if (tad->tad_flag == 0)
14347c478bd9Sstevel@tonic-gate 		return;
14357c478bd9Sstevel@tonic-gate 
14367c478bd9Sstevel@tonic-gate 	if (tad->tad_ctrl & PAD_TRUE_CREATE) {
14377c478bd9Sstevel@tonic-gate 		audit_attributes(vp);
14387c478bd9Sstevel@tonic-gate 	}
14397c478bd9Sstevel@tonic-gate 
14407c478bd9Sstevel@tonic-gate 	if (tad->tad_ctrl & PAD_CORE) {
14417c478bd9Sstevel@tonic-gate 		audit_attributes(vp);
14427c478bd9Sstevel@tonic-gate 		tad->tad_ctrl &= ~PAD_CORE;
14437c478bd9Sstevel@tonic-gate 	}
14447c478bd9Sstevel@tonic-gate 
14457c478bd9Sstevel@tonic-gate 	if (!error && ((tad->tad_event == AUE_MKNOD) ||
14467c478bd9Sstevel@tonic-gate 			(tad->tad_event == AUE_MKDIR))) {
14477c478bd9Sstevel@tonic-gate 		audit_attributes(vp);
14487c478bd9Sstevel@tonic-gate 	}
14497c478bd9Sstevel@tonic-gate 
14507c478bd9Sstevel@tonic-gate 	/* for case where multiple lookups in one syscall (rename) */
14517c478bd9Sstevel@tonic-gate 	tad->tad_ctrl &= ~PAD_NOATTRB;
14527c478bd9Sstevel@tonic-gate }
14537c478bd9Sstevel@tonic-gate 
14547c478bd9Sstevel@tonic-gate 
14557c478bd9Sstevel@tonic-gate 
14567c478bd9Sstevel@tonic-gate 
14577c478bd9Sstevel@tonic-gate 
14587c478bd9Sstevel@tonic-gate 
14597c478bd9Sstevel@tonic-gate 
14607c478bd9Sstevel@tonic-gate 
14617c478bd9Sstevel@tonic-gate /*
14627c478bd9Sstevel@tonic-gate  * ROUTINE:	AUDIT_EXEC
14637c478bd9Sstevel@tonic-gate  * PURPOSE:	Records the function arguments and environment variables
14647c478bd9Sstevel@tonic-gate  * CALLBY:	EXEC_ARGS
14657c478bd9Sstevel@tonic-gate  * NOTE:
14667c478bd9Sstevel@tonic-gate  * TODO:
14677c478bd9Sstevel@tonic-gate  * QUESTION:
14687c478bd9Sstevel@tonic-gate  */
14697c478bd9Sstevel@tonic-gate 
14707c478bd9Sstevel@tonic-gate /*ARGSUSED*/
14717c478bd9Sstevel@tonic-gate void
14727c478bd9Sstevel@tonic-gate audit_exec(
14737c478bd9Sstevel@tonic-gate 	const char *argstr,	/* argument strings */
14747c478bd9Sstevel@tonic-gate 	const char *envstr,	/* environment strings */
14757c478bd9Sstevel@tonic-gate 	ssize_t argc,		/* total # arguments */
14767c478bd9Sstevel@tonic-gate 	ssize_t envc)		/* total # environment variables */
14777c478bd9Sstevel@tonic-gate {
14787c478bd9Sstevel@tonic-gate 	t_audit_data_t *tad;
14799e9e6ab8Spaulson 	au_kcontext_t	*kctx = GET_KCTX_PZ;
14807c478bd9Sstevel@tonic-gate 
14817c478bd9Sstevel@tonic-gate 	tad = U2A(u);
14827c478bd9Sstevel@tonic-gate 
14837c478bd9Sstevel@tonic-gate 	/* if not auditing this event, then do nothing */
14847c478bd9Sstevel@tonic-gate 	if (!tad->tad_flag)
14857c478bd9Sstevel@tonic-gate 		return;
14867c478bd9Sstevel@tonic-gate 
14877c478bd9Sstevel@tonic-gate 	/* return if not interested in argv or environment variables */
14887c478bd9Sstevel@tonic-gate 	if (!(kctx->auk_policy & (AUDIT_ARGV|AUDIT_ARGE)))
14897c478bd9Sstevel@tonic-gate 		return;
14907c478bd9Sstevel@tonic-gate 
14917c478bd9Sstevel@tonic-gate 	if (kctx->auk_policy & AUDIT_ARGV) {
14927c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_exec_args(argstr, argc));
14937c478bd9Sstevel@tonic-gate 	}
14947c478bd9Sstevel@tonic-gate 
14957c478bd9Sstevel@tonic-gate 	if (kctx->auk_policy & AUDIT_ARGE) {
14967c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_exec_env(envstr, envc));
14977c478bd9Sstevel@tonic-gate 	}
14987c478bd9Sstevel@tonic-gate }
14997c478bd9Sstevel@tonic-gate 
15007c478bd9Sstevel@tonic-gate /*
15017c478bd9Sstevel@tonic-gate  * ROUTINE:	AUDIT_ENTERPROM
15027c478bd9Sstevel@tonic-gate  * PURPOSE:
15037c478bd9Sstevel@tonic-gate  * CALLBY:	KBDINPUT
15047c478bd9Sstevel@tonic-gate  *		ZSA_XSINT
15057c478bd9Sstevel@tonic-gate  * NOTE:
15067c478bd9Sstevel@tonic-gate  * TODO:
15077c478bd9Sstevel@tonic-gate  * QUESTION:
15087c478bd9Sstevel@tonic-gate  */
15097c478bd9Sstevel@tonic-gate void
15107c478bd9Sstevel@tonic-gate audit_enterprom(int flg)
15117c478bd9Sstevel@tonic-gate {
15127c478bd9Sstevel@tonic-gate 	token_t *rp = NULL;
15137c478bd9Sstevel@tonic-gate 	int sorf;
15147c478bd9Sstevel@tonic-gate 
15157c478bd9Sstevel@tonic-gate 	if (flg)
15167c478bd9Sstevel@tonic-gate 		sorf = AUM_SUCC;
15177c478bd9Sstevel@tonic-gate 	else
15187c478bd9Sstevel@tonic-gate 		sorf = AUM_FAIL;
15197c478bd9Sstevel@tonic-gate 
15207c478bd9Sstevel@tonic-gate 	AUDIT_ASYNC_START(rp, AUE_ENTERPROM, sorf);
15217c478bd9Sstevel@tonic-gate 
15227c478bd9Sstevel@tonic-gate 	au_write((caddr_t *)&(rp), au_to_text("kmdb"));
15237c478bd9Sstevel@tonic-gate 
15247c478bd9Sstevel@tonic-gate 	if (flg)
15257c478bd9Sstevel@tonic-gate 		au_write((caddr_t *)&(rp), au_to_return32(0, 0));
15267c478bd9Sstevel@tonic-gate 	else
15277c478bd9Sstevel@tonic-gate 		au_write((caddr_t *)&(rp), au_to_return32(ECANCELED, 0));
15287c478bd9Sstevel@tonic-gate 
15297c478bd9Sstevel@tonic-gate 	AUDIT_ASYNC_FINISH(rp, AUE_ENTERPROM, NULL);
15307c478bd9Sstevel@tonic-gate }
15317c478bd9Sstevel@tonic-gate 
15327c478bd9Sstevel@tonic-gate 
15337c478bd9Sstevel@tonic-gate /*
15347c478bd9Sstevel@tonic-gate  * ROUTINE:	AUDIT_EXITPROM
15357c478bd9Sstevel@tonic-gate  * PURPOSE:
15367c478bd9Sstevel@tonic-gate  * CALLBY:	KBDINPUT
15377c478bd9Sstevel@tonic-gate  *		ZSA_XSINT
15387c478bd9Sstevel@tonic-gate  * NOTE:
15397c478bd9Sstevel@tonic-gate  * TODO:
15407c478bd9Sstevel@tonic-gate  * QUESTION:
15417c478bd9Sstevel@tonic-gate  */
15427c478bd9Sstevel@tonic-gate void
15437c478bd9Sstevel@tonic-gate audit_exitprom(int flg)
15447c478bd9Sstevel@tonic-gate {
15457c478bd9Sstevel@tonic-gate 	int sorf;
15467c478bd9Sstevel@tonic-gate 	token_t *rp = NULL;
15477c478bd9Sstevel@tonic-gate 
15487c478bd9Sstevel@tonic-gate 	if (flg)
15497c478bd9Sstevel@tonic-gate 		sorf = AUM_SUCC;
15507c478bd9Sstevel@tonic-gate 	else
15517c478bd9Sstevel@tonic-gate 		sorf = AUM_FAIL;
15527c478bd9Sstevel@tonic-gate 
15537c478bd9Sstevel@tonic-gate 	AUDIT_ASYNC_START(rp, AUE_EXITPROM, sorf);
15547c478bd9Sstevel@tonic-gate 
15557c478bd9Sstevel@tonic-gate 	au_write((caddr_t *)&(rp), au_to_text("kmdb"));
15567c478bd9Sstevel@tonic-gate 
15577c478bd9Sstevel@tonic-gate 	if (flg)
15587c478bd9Sstevel@tonic-gate 		au_write((caddr_t *)&(rp), au_to_return32(0, 0));
15597c478bd9Sstevel@tonic-gate 	else
15607c478bd9Sstevel@tonic-gate 		au_write((caddr_t *)&(rp), au_to_return32(ECANCELED, 0));
15617c478bd9Sstevel@tonic-gate 
15627c478bd9Sstevel@tonic-gate 	AUDIT_ASYNC_FINISH(rp, AUE_EXITPROM, NULL);
15637c478bd9Sstevel@tonic-gate }
15647c478bd9Sstevel@tonic-gate 
15657c478bd9Sstevel@tonic-gate struct fcntla {
15667c478bd9Sstevel@tonic-gate 	int fdes;
15677c478bd9Sstevel@tonic-gate 	int cmd;
15687c478bd9Sstevel@tonic-gate 	intptr_t arg;
15697c478bd9Sstevel@tonic-gate };
15707c478bd9Sstevel@tonic-gate 
15717c478bd9Sstevel@tonic-gate /*
15727c478bd9Sstevel@tonic-gate  * ROUTINE:	AUDIT_C2_REVOKE
15737c478bd9Sstevel@tonic-gate  * PURPOSE:
15747c478bd9Sstevel@tonic-gate  * CALLBY:	FCNTL
15757c478bd9Sstevel@tonic-gate  * NOTE:
15767c478bd9Sstevel@tonic-gate  * TODO:
15777c478bd9Sstevel@tonic-gate  * QUESTION:	are we keeping this func
15787c478bd9Sstevel@tonic-gate  */
15797c478bd9Sstevel@tonic-gate 
15807c478bd9Sstevel@tonic-gate /*ARGSUSED*/
15817c478bd9Sstevel@tonic-gate int
15827c478bd9Sstevel@tonic-gate audit_c2_revoke(struct fcntla *uap, rval_t *rvp)
15837c478bd9Sstevel@tonic-gate {
15847c478bd9Sstevel@tonic-gate 	return (0);
15857c478bd9Sstevel@tonic-gate }
15867c478bd9Sstevel@tonic-gate 
15877c478bd9Sstevel@tonic-gate 
15887c478bd9Sstevel@tonic-gate /*
15897c478bd9Sstevel@tonic-gate  * ROUTINE:	AUDIT_CHDIREC
15907c478bd9Sstevel@tonic-gate  * PURPOSE:
15917c478bd9Sstevel@tonic-gate  * CALLBY:	CHDIREC
15927c478bd9Sstevel@tonic-gate  * NOTE:	The main function of CHDIREC
15937c478bd9Sstevel@tonic-gate  * TODO:	Move the audit_chdirec hook above the VN_RELE in vncalls.c
15947c478bd9Sstevel@tonic-gate  * QUESTION:
15957c478bd9Sstevel@tonic-gate  */
15967c478bd9Sstevel@tonic-gate 
15977c478bd9Sstevel@tonic-gate /*ARGSUSED*/
15987c478bd9Sstevel@tonic-gate void
15997c478bd9Sstevel@tonic-gate audit_chdirec(vnode_t *vp, vnode_t **vpp)
16007c478bd9Sstevel@tonic-gate {
16017c478bd9Sstevel@tonic-gate 	int		chdir;
16027c478bd9Sstevel@tonic-gate 	int		fchdir;
16037c478bd9Sstevel@tonic-gate 	struct audit_path	**appp;
16047c478bd9Sstevel@tonic-gate 	struct file	*fp;
16057c478bd9Sstevel@tonic-gate 	f_audit_data_t *fad;
16067c478bd9Sstevel@tonic-gate 	p_audit_data_t *pad = P2A(curproc);
16077c478bd9Sstevel@tonic-gate 	t_audit_data_t *tad = T2A(curthread);
16087c478bd9Sstevel@tonic-gate 
16097c478bd9Sstevel@tonic-gate 	struct a {
16107c478bd9Sstevel@tonic-gate 		long fd;
16117c478bd9Sstevel@tonic-gate 	} *uap = (struct a *)ttolwp(curthread)->lwp_ap;
16127c478bd9Sstevel@tonic-gate 
16137c478bd9Sstevel@tonic-gate 	if ((tad->tad_scid == SYS_chdir) || (tad->tad_scid == SYS_chroot)) {
16147c478bd9Sstevel@tonic-gate 		chdir = tad->tad_scid == SYS_chdir;
16157c478bd9Sstevel@tonic-gate 		if (tad->tad_aupath) {
16167c478bd9Sstevel@tonic-gate 			mutex_enter(&pad->pad_lock);
16177c478bd9Sstevel@tonic-gate 			if (chdir)
16187c478bd9Sstevel@tonic-gate 				appp = &(pad->pad_cwd);
16197c478bd9Sstevel@tonic-gate 			else
16207c478bd9Sstevel@tonic-gate 				appp = &(pad->pad_root);
16217c478bd9Sstevel@tonic-gate 			au_pathrele(*appp);
16227c478bd9Sstevel@tonic-gate 			/* use tad hold */
16237c478bd9Sstevel@tonic-gate 			*appp = tad->tad_aupath;
16247c478bd9Sstevel@tonic-gate 			tad->tad_aupath = NULL;
16257c478bd9Sstevel@tonic-gate 			mutex_exit(&pad->pad_lock);
16267c478bd9Sstevel@tonic-gate 		}
16277c478bd9Sstevel@tonic-gate 	} else if ((tad->tad_scid == SYS_fchdir) ||
16287c478bd9Sstevel@tonic-gate 	    (tad->tad_scid == SYS_fchroot)) {
16297c478bd9Sstevel@tonic-gate 		fchdir = tad->tad_scid == SYS_fchdir;
16307c478bd9Sstevel@tonic-gate 		if ((fp = getf(uap->fd)) == NULL)
16317c478bd9Sstevel@tonic-gate 			return;
16327c478bd9Sstevel@tonic-gate 		fad = F2A(fp);
16337c478bd9Sstevel@tonic-gate 		if (fad->fad_aupath) {
16347c478bd9Sstevel@tonic-gate 			au_pathhold(fad->fad_aupath);
16357c478bd9Sstevel@tonic-gate 			mutex_enter(&pad->pad_lock);
16367c478bd9Sstevel@tonic-gate 			if (fchdir)
16377c478bd9Sstevel@tonic-gate 				appp = &(pad->pad_cwd);
16387c478bd9Sstevel@tonic-gate 			else
16397c478bd9Sstevel@tonic-gate 				appp = &(pad->pad_root);
16407c478bd9Sstevel@tonic-gate 			au_pathrele(*appp);
16417c478bd9Sstevel@tonic-gate 			*appp = fad->fad_aupath;
16427c478bd9Sstevel@tonic-gate 			mutex_exit(&pad->pad_lock);
16437c478bd9Sstevel@tonic-gate 			if (tad->tad_flag) {
16447c478bd9Sstevel@tonic-gate 				au_uwrite(au_to_path(fad->fad_aupath));
16457c478bd9Sstevel@tonic-gate 				audit_attributes(fp->f_vnode);
16467c478bd9Sstevel@tonic-gate 			}
16477c478bd9Sstevel@tonic-gate 		}
16487c478bd9Sstevel@tonic-gate 		releasef(uap->fd);
16497c478bd9Sstevel@tonic-gate 	}
16507c478bd9Sstevel@tonic-gate }
16517c478bd9Sstevel@tonic-gate 
16527c478bd9Sstevel@tonic-gate /*
16537c478bd9Sstevel@tonic-gate  * ROUTINE:	AUDIT_GETF
16547c478bd9Sstevel@tonic-gate  * PURPOSE:
16557c478bd9Sstevel@tonic-gate  * CALLBY:	GETF_INTERNAL
16567c478bd9Sstevel@tonic-gate  * NOTE:	The main function of GETF_INTERNAL is to associate a given
16577c478bd9Sstevel@tonic-gate  *		file descriptor with a file structure and increment the
16587c478bd9Sstevel@tonic-gate  *		file pointer reference count.
16597c478bd9Sstevel@tonic-gate  * TODO:	remove pass in of fpp.
16607c478bd9Sstevel@tonic-gate  * increment a reference count so that even if a thread with same process delete
16617c478bd9Sstevel@tonic-gate  * the same object, it will not panic our system
16627c478bd9Sstevel@tonic-gate  * QUESTION:
16637c478bd9Sstevel@tonic-gate  * where to decrement the f_count?????????????????
1664*da6c28aaSamw  * seems like I need to set a flag if f_count incremented through audit_getf
16657c478bd9Sstevel@tonic-gate  */
16667c478bd9Sstevel@tonic-gate 
16677c478bd9Sstevel@tonic-gate /*ARGSUSED*/
16687c478bd9Sstevel@tonic-gate int
16697c478bd9Sstevel@tonic-gate audit_getf(int fd)
16707c478bd9Sstevel@tonic-gate {
16717c478bd9Sstevel@tonic-gate #ifdef NOTYET
16727c478bd9Sstevel@tonic-gate 	t_audit_data_t *tad;
16737c478bd9Sstevel@tonic-gate 
16747c478bd9Sstevel@tonic-gate 	tad = T2A(curthread);
16757c478bd9Sstevel@tonic-gate 
16767c478bd9Sstevel@tonic-gate 	if (!(tad->tad_scid == SYS_open || tad->tad_scid == SYS_creat))
16777c478bd9Sstevel@tonic-gate 		return;
16787c478bd9Sstevel@tonic-gate #endif
16797c478bd9Sstevel@tonic-gate 	return (0);
16807c478bd9Sstevel@tonic-gate }
16817c478bd9Sstevel@tonic-gate 
16827c478bd9Sstevel@tonic-gate /*
16837c478bd9Sstevel@tonic-gate  *	Audit hook for stream based socket and tli request.
16847c478bd9Sstevel@tonic-gate  *	Note that we do not have user context while executing
16857c478bd9Sstevel@tonic-gate  *	this code so we had to record them earlier during the
16867c478bd9Sstevel@tonic-gate  *	putmsg/getmsg to figure out which user we are dealing with.
16877c478bd9Sstevel@tonic-gate  */
16887c478bd9Sstevel@tonic-gate 
16897c478bd9Sstevel@tonic-gate /*ARGSUSED*/
16907c478bd9Sstevel@tonic-gate void
16917c478bd9Sstevel@tonic-gate audit_sock(
16927c478bd9Sstevel@tonic-gate 	int type,	/* type of tihdr.h header requests */
16937c478bd9Sstevel@tonic-gate 	queue_t *q,	/* contains the process and thread audit data */
16947c478bd9Sstevel@tonic-gate 	mblk_t *mp,	/* contains the tihdr.h header structures */
16957c478bd9Sstevel@tonic-gate 	int from)	/* timod or sockmod request */
16967c478bd9Sstevel@tonic-gate {
16977c478bd9Sstevel@tonic-gate 	int32_t    len;
16987c478bd9Sstevel@tonic-gate 	int32_t    offset;
16997c478bd9Sstevel@tonic-gate 	struct sockaddr_in *sock_data;
17007c478bd9Sstevel@tonic-gate 	struct T_conn_req *conn_req;
17017c478bd9Sstevel@tonic-gate 	struct T_conn_ind *conn_ind;
17027c478bd9Sstevel@tonic-gate 	struct T_unitdata_req *unitdata_req;
17037c478bd9Sstevel@tonic-gate 	struct T_unitdata_ind *unitdata_ind;
17047c478bd9Sstevel@tonic-gate 	au_state_t estate;
17057c478bd9Sstevel@tonic-gate 	t_audit_data_t *tad;
17067c478bd9Sstevel@tonic-gate 	caddr_t saved_thread_ptr;
17077c478bd9Sstevel@tonic-gate 	au_mask_t amask;
17087c478bd9Sstevel@tonic-gate 	const auditinfo_addr_t *ainfo;
17097c478bd9Sstevel@tonic-gate 	au_kcontext_t	*kctx;
17107c478bd9Sstevel@tonic-gate 
17117c478bd9Sstevel@tonic-gate 	if (q->q_stream == NULL)
17127c478bd9Sstevel@tonic-gate 		return;
17137c478bd9Sstevel@tonic-gate 	mutex_enter(&q->q_stream->sd_lock);
17147c478bd9Sstevel@tonic-gate 	/* are we being audited */
17157c478bd9Sstevel@tonic-gate 	saved_thread_ptr = q->q_stream->sd_t_audit_data;
17167c478bd9Sstevel@tonic-gate 	/* no pointer to thread, nothing to do */
17177c478bd9Sstevel@tonic-gate 	if (saved_thread_ptr == NULL) {
17187c478bd9Sstevel@tonic-gate 		mutex_exit(&q->q_stream->sd_lock);
17197c478bd9Sstevel@tonic-gate 		return;
17207c478bd9Sstevel@tonic-gate 	}
17217c478bd9Sstevel@tonic-gate 	/* only allow one addition of a record token */
17227c478bd9Sstevel@tonic-gate 	q->q_stream->sd_t_audit_data = NULL;
17237c478bd9Sstevel@tonic-gate 	/*
17247c478bd9Sstevel@tonic-gate 	 * thread is not the one being audited, then nothing to do
17257c478bd9Sstevel@tonic-gate 	 * This could be the stream thread handling the module
17267c478bd9Sstevel@tonic-gate 	 * service routine. In this case, the context for the audit
17277c478bd9Sstevel@tonic-gate 	 * record can no longer be assumed. Simplest to just drop
17287c478bd9Sstevel@tonic-gate 	 * the operation.
17297c478bd9Sstevel@tonic-gate 	 */
17307c478bd9Sstevel@tonic-gate 	if (curthread != (kthread_id_t)saved_thread_ptr) {
17317c478bd9Sstevel@tonic-gate 		mutex_exit(&q->q_stream->sd_lock);
17327c478bd9Sstevel@tonic-gate 		return;
17337c478bd9Sstevel@tonic-gate 	}
17347c478bd9Sstevel@tonic-gate 	if (curthread->t_sysnum >= SYS_so_socket &&
17357c478bd9Sstevel@tonic-gate 	    curthread->t_sysnum <= SYS_sockconfig) {
17367c478bd9Sstevel@tonic-gate 		mutex_exit(&q->q_stream->sd_lock);
17377c478bd9Sstevel@tonic-gate 		return;
17387c478bd9Sstevel@tonic-gate 	}
17397c478bd9Sstevel@tonic-gate 	mutex_exit(&q->q_stream->sd_lock);
17407c478bd9Sstevel@tonic-gate 	/*
17417c478bd9Sstevel@tonic-gate 	 * we know that the thread that did the put/getmsg is the
17427c478bd9Sstevel@tonic-gate 	 * one running. Now we can get the TAD and see if we should
17437c478bd9Sstevel@tonic-gate 	 * add an audit token.
17447c478bd9Sstevel@tonic-gate 	 */
17457c478bd9Sstevel@tonic-gate 	tad = U2A(u);
17467c478bd9Sstevel@tonic-gate 
17479e9e6ab8Spaulson 	kctx = GET_KCTX_PZ;
17487c478bd9Sstevel@tonic-gate 
17497c478bd9Sstevel@tonic-gate 	/* proceed ONLY if user is being audited */
17507c478bd9Sstevel@tonic-gate 	if (!tad->tad_flag)
17517c478bd9Sstevel@tonic-gate 		return;
17527c478bd9Sstevel@tonic-gate 
17537c478bd9Sstevel@tonic-gate 	ainfo = crgetauinfo(CRED());
17547c478bd9Sstevel@tonic-gate 	if (ainfo == NULL)
17557c478bd9Sstevel@tonic-gate 		return;
17567c478bd9Sstevel@tonic-gate 	amask = ainfo->ai_mask;
17577c478bd9Sstevel@tonic-gate 
17587c478bd9Sstevel@tonic-gate 	/*
17597c478bd9Sstevel@tonic-gate 	 * Figure out the type of stream networking request here.
17607c478bd9Sstevel@tonic-gate 	 * Note that getmsg and putmsg are always preselected
17617c478bd9Sstevel@tonic-gate 	 * because during the beginning of the system call we have
17627c478bd9Sstevel@tonic-gate 	 * not yet figure out which of the socket or tli request
17637c478bd9Sstevel@tonic-gate 	 * we are looking at until we are here. So we need to check
17647c478bd9Sstevel@tonic-gate 	 * against that specific request and reset the type of event.
17657c478bd9Sstevel@tonic-gate 	 */
17667c478bd9Sstevel@tonic-gate 	switch (type) {
17677c478bd9Sstevel@tonic-gate 	case T_CONN_REQ:	/* connection request */
17687c478bd9Sstevel@tonic-gate 		conn_req = (struct T_conn_req *)mp->b_rptr;
17697c478bd9Sstevel@tonic-gate 		if (conn_req->DEST_offset < sizeof (struct T_conn_req))
17707c478bd9Sstevel@tonic-gate 			return;
17717c478bd9Sstevel@tonic-gate 		offset = conn_req->DEST_offset;
17727c478bd9Sstevel@tonic-gate 		len = conn_req->DEST_length;
17737c478bd9Sstevel@tonic-gate 		estate = kctx->auk_ets[AUE_SOCKCONNECT];
17747c478bd9Sstevel@tonic-gate 		if (amask.as_success & estate || amask.as_failure & estate) {
17757c478bd9Sstevel@tonic-gate 			tad->tad_event = AUE_SOCKCONNECT;
17767c478bd9Sstevel@tonic-gate 			break;
17777c478bd9Sstevel@tonic-gate 		} else {
17787c478bd9Sstevel@tonic-gate 			return;
17797c478bd9Sstevel@tonic-gate 		}
17807c478bd9Sstevel@tonic-gate 	case T_CONN_IND:	 /* connectionless receive request */
17817c478bd9Sstevel@tonic-gate 		conn_ind = (struct T_conn_ind *)mp->b_rptr;
17827c478bd9Sstevel@tonic-gate 		if (conn_ind->SRC_offset < sizeof (struct T_conn_ind))
17837c478bd9Sstevel@tonic-gate 			return;
17847c478bd9Sstevel@tonic-gate 		offset = conn_ind->SRC_offset;
17857c478bd9Sstevel@tonic-gate 		len = conn_ind->SRC_length;
17867c478bd9Sstevel@tonic-gate 		estate = kctx->auk_ets[AUE_SOCKACCEPT];
17877c478bd9Sstevel@tonic-gate 		if (amask.as_success & estate || amask.as_failure & estate) {
17887c478bd9Sstevel@tonic-gate 			tad->tad_event = AUE_SOCKACCEPT;
17897c478bd9Sstevel@tonic-gate 			break;
17907c478bd9Sstevel@tonic-gate 		} else {
17917c478bd9Sstevel@tonic-gate 			return;
17927c478bd9Sstevel@tonic-gate 		}
17937c478bd9Sstevel@tonic-gate 	case T_UNITDATA_REQ:	 /* connectionless send request */
17947c478bd9Sstevel@tonic-gate 		unitdata_req = (struct T_unitdata_req *)mp->b_rptr;
17957c478bd9Sstevel@tonic-gate 		if (unitdata_req->DEST_offset < sizeof (struct T_unitdata_req))
17967c478bd9Sstevel@tonic-gate 			return;
17977c478bd9Sstevel@tonic-gate 		offset = unitdata_req->DEST_offset;
17987c478bd9Sstevel@tonic-gate 		len = unitdata_req->DEST_length;
17997c478bd9Sstevel@tonic-gate 		estate = kctx->auk_ets[AUE_SOCKSEND];
18007c478bd9Sstevel@tonic-gate 		if (amask.as_success & estate || amask.as_failure & estate) {
18017c478bd9Sstevel@tonic-gate 			tad->tad_event = AUE_SOCKSEND;
18027c478bd9Sstevel@tonic-gate 			break;
18037c478bd9Sstevel@tonic-gate 		} else {
18047c478bd9Sstevel@tonic-gate 			return;
18057c478bd9Sstevel@tonic-gate 		}
18067c478bd9Sstevel@tonic-gate 	case T_UNITDATA_IND:	 /* connectionless receive request */
18077c478bd9Sstevel@tonic-gate 		unitdata_ind = (struct T_unitdata_ind *)mp->b_rptr;
18087c478bd9Sstevel@tonic-gate 		if (unitdata_ind->SRC_offset < sizeof (struct T_unitdata_ind))
18097c478bd9Sstevel@tonic-gate 			return;
18107c478bd9Sstevel@tonic-gate 		offset = unitdata_ind->SRC_offset;
18117c478bd9Sstevel@tonic-gate 		len = unitdata_ind->SRC_length;
18127c478bd9Sstevel@tonic-gate 		estate = kctx->auk_ets[AUE_SOCKRECEIVE];
18137c478bd9Sstevel@tonic-gate 		if (amask.as_success & estate || amask.as_failure & estate) {
18147c478bd9Sstevel@tonic-gate 			tad->tad_event = AUE_SOCKRECEIVE;
18157c478bd9Sstevel@tonic-gate 			break;
18167c478bd9Sstevel@tonic-gate 		} else {
18177c478bd9Sstevel@tonic-gate 			return;
18187c478bd9Sstevel@tonic-gate 		}
18197c478bd9Sstevel@tonic-gate 	default:
18207c478bd9Sstevel@tonic-gate 		return;
18217c478bd9Sstevel@tonic-gate 	}
18227c478bd9Sstevel@tonic-gate 
18237c478bd9Sstevel@tonic-gate 	/*
18247c478bd9Sstevel@tonic-gate 	 * we are only interested in tcp stream connections,
18257c478bd9Sstevel@tonic-gate 	 * not unix domain stuff
18267c478bd9Sstevel@tonic-gate 	 */
18277c478bd9Sstevel@tonic-gate 	if ((len < 0) || (len > sizeof (struct sockaddr_in))) {
18287c478bd9Sstevel@tonic-gate 		tad->tad_event = AUE_GETMSG;
18297c478bd9Sstevel@tonic-gate 		return;
18307c478bd9Sstevel@tonic-gate 	}
18317c478bd9Sstevel@tonic-gate 	/* skip over TPI header and point to the ip address */
18327c478bd9Sstevel@tonic-gate 	sock_data = (struct sockaddr_in *)((char *)mp->b_rptr + offset);
18337c478bd9Sstevel@tonic-gate 
18347c478bd9Sstevel@tonic-gate 	switch (sock_data->sin_family) {
18357c478bd9Sstevel@tonic-gate 	case AF_INET:
18367c478bd9Sstevel@tonic-gate 		au_write(&(tad->tad_ad), au_to_sock_inet(sock_data));
18377c478bd9Sstevel@tonic-gate 		break;
18387c478bd9Sstevel@tonic-gate 	default:	/* reset to AUE_PUTMSG if not a inet request */
18397c478bd9Sstevel@tonic-gate 		tad->tad_event = AUE_GETMSG;
18407c478bd9Sstevel@tonic-gate 		break;
18417c478bd9Sstevel@tonic-gate 	}
18427c478bd9Sstevel@tonic-gate }
18437c478bd9Sstevel@tonic-gate 
18447c478bd9Sstevel@tonic-gate void
18457c478bd9Sstevel@tonic-gate audit_lookupname()
18467c478bd9Sstevel@tonic-gate {
18477c478bd9Sstevel@tonic-gate }
18487c478bd9Sstevel@tonic-gate 
18497c478bd9Sstevel@tonic-gate /*ARGSUSED*/
18507c478bd9Sstevel@tonic-gate int
18517c478bd9Sstevel@tonic-gate audit_pathcomp(struct pathname *pnp, vnode_t *cvp, cred_t *cr)
18527c478bd9Sstevel@tonic-gate {
18537c478bd9Sstevel@tonic-gate 	return (0);
18547c478bd9Sstevel@tonic-gate }
18557c478bd9Sstevel@tonic-gate 
18567c478bd9Sstevel@tonic-gate static void
18577c478bd9Sstevel@tonic-gate add_return_token(caddr_t *ad, unsigned int scid, int err, int rval)
18587c478bd9Sstevel@tonic-gate {
18597c478bd9Sstevel@tonic-gate 	unsigned int sy_flags;
18607c478bd9Sstevel@tonic-gate 
18617c478bd9Sstevel@tonic-gate #ifdef _SYSCALL32_IMPL
18627c478bd9Sstevel@tonic-gate 	if (lwp_getdatamodel(
18637c478bd9Sstevel@tonic-gate 		ttolwp(curthread)) == DATAMODEL_NATIVE)
18647c478bd9Sstevel@tonic-gate 		sy_flags = sysent[scid].sy_flags & SE_RVAL_MASK;
18657c478bd9Sstevel@tonic-gate 	else
18667c478bd9Sstevel@tonic-gate 		sy_flags = sysent32[scid].sy_flags & SE_RVAL_MASK;
18677c478bd9Sstevel@tonic-gate #else
18687c478bd9Sstevel@tonic-gate 		sy_flags = sysent[scid].sy_flags & SE_RVAL_MASK;
18697c478bd9Sstevel@tonic-gate #endif
18707c478bd9Sstevel@tonic-gate 
18717c478bd9Sstevel@tonic-gate 	if (sy_flags == SE_64RVAL)
18727c478bd9Sstevel@tonic-gate 		au_write(ad, au_to_return64(err, rval));
18737c478bd9Sstevel@tonic-gate 	else
18747c478bd9Sstevel@tonic-gate 		au_write(ad, au_to_return32(err, rval));
18757c478bd9Sstevel@tonic-gate 
18767c478bd9Sstevel@tonic-gate }
18777c478bd9Sstevel@tonic-gate 
18787c478bd9Sstevel@tonic-gate /*ARGSUSED*/
18797c478bd9Sstevel@tonic-gate void
18807c478bd9Sstevel@tonic-gate audit_fdsend(fd, fp, error)
18817c478bd9Sstevel@tonic-gate 	int fd;
18827c478bd9Sstevel@tonic-gate 	struct file *fp;
18837c478bd9Sstevel@tonic-gate 	int error;		/* ignore for now */
18847c478bd9Sstevel@tonic-gate {
18857c478bd9Sstevel@tonic-gate 	t_audit_data_t *tad;	/* current thread */
18867c478bd9Sstevel@tonic-gate 	f_audit_data_t *fad;	/* per file audit structure */
18877c478bd9Sstevel@tonic-gate 	struct vnode *vp;	/* for file attributes */
18887c478bd9Sstevel@tonic-gate 
18897c478bd9Sstevel@tonic-gate 	/* is this system call being audited */
18907c478bd9Sstevel@tonic-gate 	tad = U2A(u);
18917c478bd9Sstevel@tonic-gate 	ASSERT(tad != (t_audit_data_t *)0);
18927c478bd9Sstevel@tonic-gate 	if (!tad->tad_flag)
18937c478bd9Sstevel@tonic-gate 		return;
18947c478bd9Sstevel@tonic-gate 
18957c478bd9Sstevel@tonic-gate 	fad = F2A(fp);
18967c478bd9Sstevel@tonic-gate 
18977c478bd9Sstevel@tonic-gate 	/* add path and file attributes */
18987c478bd9Sstevel@tonic-gate 	if (fad != NULL && fad->fad_aupath != NULL) {
18997c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_arg32(0, "send fd", (uint32_t)fd));
19007c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_path(fad->fad_aupath));
19017c478bd9Sstevel@tonic-gate 	} else {
19027c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_arg32(0, "send fd", (uint32_t)fd));
19037c478bd9Sstevel@tonic-gate #ifdef _LP64
19047c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_arg64(0, "no path", (uint64_t)fp));
19057c478bd9Sstevel@tonic-gate #else
19067c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_arg32(0, "no path", (uint32_t)fp));
19077c478bd9Sstevel@tonic-gate #endif
19087c478bd9Sstevel@tonic-gate 	}
19097c478bd9Sstevel@tonic-gate 	vp = fp->f_vnode;	/* include vnode attributes */
19107c478bd9Sstevel@tonic-gate 	audit_attributes(vp);
19117c478bd9Sstevel@tonic-gate }
19127c478bd9Sstevel@tonic-gate 
19137c478bd9Sstevel@tonic-gate /*
1914*da6c28aaSamw  * Record privileges successfully used and we attempted to use but
19157c478bd9Sstevel@tonic-gate  * didn't have.
19167c478bd9Sstevel@tonic-gate  */
19177c478bd9Sstevel@tonic-gate void
19187c478bd9Sstevel@tonic-gate audit_priv(int priv, const priv_set_t *set, int flag)
19197c478bd9Sstevel@tonic-gate {
19207c478bd9Sstevel@tonic-gate 	t_audit_data_t *tad;
19217c478bd9Sstevel@tonic-gate 	int sbit;
19227c478bd9Sstevel@tonic-gate 	priv_set_t *target;
19237c478bd9Sstevel@tonic-gate 
19247c478bd9Sstevel@tonic-gate 	/* Make sure this isn't being called in an interrupt context */
19257c478bd9Sstevel@tonic-gate 	ASSERT(servicing_interrupt() == 0);
19267c478bd9Sstevel@tonic-gate 
19277c478bd9Sstevel@tonic-gate 	tad = U2A(u);
19287c478bd9Sstevel@tonic-gate 
19297c478bd9Sstevel@tonic-gate 	if (tad->tad_flag == 0)
19307c478bd9Sstevel@tonic-gate 		return;
19317c478bd9Sstevel@tonic-gate 
19327c478bd9Sstevel@tonic-gate 	target = flag ? &tad->tad_sprivs : &tad->tad_fprivs;
19337c478bd9Sstevel@tonic-gate 	sbit = flag ? PAD_SPRIVUSE : PAD_FPRIVUSE;
19347c478bd9Sstevel@tonic-gate 
19357c478bd9Sstevel@tonic-gate 	/* Tell audit_success() and audit_finish() that we saw this case */
19367c478bd9Sstevel@tonic-gate 	if (!(tad->tad_evmod & sbit)) {
19377c478bd9Sstevel@tonic-gate 		/* Clear set first time around */
19387c478bd9Sstevel@tonic-gate 		priv_emptyset(target);
19397c478bd9Sstevel@tonic-gate 		tad->tad_evmod |= sbit;
19407c478bd9Sstevel@tonic-gate 	}
19417c478bd9Sstevel@tonic-gate 
19427c478bd9Sstevel@tonic-gate 	/* Save the privileges in the tad */
19437c478bd9Sstevel@tonic-gate 	if (priv == PRIV_ALL) {
19447c478bd9Sstevel@tonic-gate 		priv_fillset(target);
19457c478bd9Sstevel@tonic-gate 	} else {
19467c478bd9Sstevel@tonic-gate 		ASSERT(set != NULL || priv != PRIV_NONE);
19477c478bd9Sstevel@tonic-gate 		if (set != NULL)
19487c478bd9Sstevel@tonic-gate 			priv_union(set, target);
19497c478bd9Sstevel@tonic-gate 		if (priv != PRIV_NONE)
19507c478bd9Sstevel@tonic-gate 			priv_addset(target, priv);
19517c478bd9Sstevel@tonic-gate 	}
19527c478bd9Sstevel@tonic-gate }
19537c478bd9Sstevel@tonic-gate 
19547c478bd9Sstevel@tonic-gate /*
19557c478bd9Sstevel@tonic-gate  * Audit the setpriv() system call; the operation, the set name and
19567c478bd9Sstevel@tonic-gate  * the current value as well as the set argument are put in the
19577c478bd9Sstevel@tonic-gate  * audit trail.
19587c478bd9Sstevel@tonic-gate  */
19597c478bd9Sstevel@tonic-gate void
19607c478bd9Sstevel@tonic-gate audit_setppriv(int op, int set, const priv_set_t *newpriv, const cred_t *ocr)
19617c478bd9Sstevel@tonic-gate {
19627c478bd9Sstevel@tonic-gate 	t_audit_data_t *tad;
19637c478bd9Sstevel@tonic-gate 	const priv_set_t *oldpriv;
19647c478bd9Sstevel@tonic-gate 	priv_set_t report;
19657c478bd9Sstevel@tonic-gate 	const char *setname;
19667c478bd9Sstevel@tonic-gate 
19677c478bd9Sstevel@tonic-gate 	tad = U2A(u);
19687c478bd9Sstevel@tonic-gate 
19697c478bd9Sstevel@tonic-gate 	if (tad->tad_flag == 0)
19707c478bd9Sstevel@tonic-gate 		return;
19717c478bd9Sstevel@tonic-gate 
19727c478bd9Sstevel@tonic-gate 	oldpriv = priv_getset(ocr, set);
19737c478bd9Sstevel@tonic-gate 
19747c478bd9Sstevel@tonic-gate 	/* Generate the actual record, include the before and after */
19757c478bd9Sstevel@tonic-gate 	au_uwrite(au_to_arg32(2, "op", op));
19767c478bd9Sstevel@tonic-gate 	setname = priv_getsetbynum(set);
19777c478bd9Sstevel@tonic-gate 
19787c478bd9Sstevel@tonic-gate 	switch (op) {
19797c478bd9Sstevel@tonic-gate 	case PRIV_OFF:
19807c478bd9Sstevel@tonic-gate 		/* Report privileges actually switched off */
19817c478bd9Sstevel@tonic-gate 		report = *oldpriv;
19827c478bd9Sstevel@tonic-gate 		priv_intersect(newpriv, &report);
19837c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_privset(setname, &report, AUT_PRIV, 0));
19847c478bd9Sstevel@tonic-gate 		break;
19857c478bd9Sstevel@tonic-gate 	case PRIV_ON:
19867c478bd9Sstevel@tonic-gate 		/* Report privileges actually switched on */
19877c478bd9Sstevel@tonic-gate 		report = *oldpriv;
19887c478bd9Sstevel@tonic-gate 		priv_inverse(&report);
19897c478bd9Sstevel@tonic-gate 		priv_intersect(newpriv, &report);
19907c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_privset(setname, &report, AUT_PRIV, 0));
19917c478bd9Sstevel@tonic-gate 		break;
19927c478bd9Sstevel@tonic-gate 	case PRIV_SET:
19937c478bd9Sstevel@tonic-gate 		/* Report before and after */
19947c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_privset(setname, oldpriv, AUT_PRIV, 0));
19957c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_privset(setname, newpriv, AUT_PRIV, 0));
19967c478bd9Sstevel@tonic-gate 		break;
19977c478bd9Sstevel@tonic-gate 	}
19987c478bd9Sstevel@tonic-gate }
19997c478bd9Sstevel@tonic-gate 
20007c478bd9Sstevel@tonic-gate /*
20017c478bd9Sstevel@tonic-gate  * Dump the full device policy setting in the audit trail.
20027c478bd9Sstevel@tonic-gate  */
20037c478bd9Sstevel@tonic-gate void
20047c478bd9Sstevel@tonic-gate audit_devpolicy(int nitems, const devplcysys_t *items)
20057c478bd9Sstevel@tonic-gate {
20067c478bd9Sstevel@tonic-gate 	t_audit_data_t *tad;
20077c478bd9Sstevel@tonic-gate 	int i;
20087c478bd9Sstevel@tonic-gate 
20097c478bd9Sstevel@tonic-gate 	tad = U2A(u);
20107c478bd9Sstevel@tonic-gate 
20117c478bd9Sstevel@tonic-gate 	if (tad->tad_flag == 0)
20127c478bd9Sstevel@tonic-gate 		return;
20137c478bd9Sstevel@tonic-gate 
20147c478bd9Sstevel@tonic-gate 	for (i = 0; i < nitems; i++) {
20157c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_arg32(2, "major", items[i].dps_maj));
20167c478bd9Sstevel@tonic-gate 		if (items[i].dps_minornm[0] == '\0') {
20177c478bd9Sstevel@tonic-gate 			au_uwrite(au_to_arg32(2, "lomin", items[i].dps_lomin));
20187c478bd9Sstevel@tonic-gate 			au_uwrite(au_to_arg32(2, "himin", items[i].dps_himin));
20197c478bd9Sstevel@tonic-gate 		} else
20207c478bd9Sstevel@tonic-gate 			au_uwrite(au_to_text(items[i].dps_minornm));
20217c478bd9Sstevel@tonic-gate 
20227c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_privset("read", &items[i].dps_rdp,
20237c478bd9Sstevel@tonic-gate 		    AUT_PRIV, 0));
20247c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_privset("write", &items[i].dps_wrp,
20257c478bd9Sstevel@tonic-gate 		    AUT_PRIV, 0));
20267c478bd9Sstevel@tonic-gate 	}
20277c478bd9Sstevel@tonic-gate }
20287c478bd9Sstevel@tonic-gate 
20297c478bd9Sstevel@tonic-gate /*ARGSUSED*/
20307c478bd9Sstevel@tonic-gate void
20317c478bd9Sstevel@tonic-gate audit_fdrecv(fd, fp)
20327c478bd9Sstevel@tonic-gate 	int fd;
20337c478bd9Sstevel@tonic-gate 	struct file *fp;
20347c478bd9Sstevel@tonic-gate {
20357c478bd9Sstevel@tonic-gate 	t_audit_data_t *tad;	/* current thread */
20367c478bd9Sstevel@tonic-gate 	f_audit_data_t *fad;	/* per file audit structure */
20377c478bd9Sstevel@tonic-gate 	struct vnode *vp;	/* for file attributes */
20387c478bd9Sstevel@tonic-gate 
20397c478bd9Sstevel@tonic-gate 	/* is this system call being audited */
20407c478bd9Sstevel@tonic-gate 	tad = U2A(u);
20417c478bd9Sstevel@tonic-gate 	ASSERT(tad != (t_audit_data_t *)0);
20427c478bd9Sstevel@tonic-gate 	if (!tad->tad_flag)
20437c478bd9Sstevel@tonic-gate 		return;
20447c478bd9Sstevel@tonic-gate 
20457c478bd9Sstevel@tonic-gate 	fad = F2A(fp);
20467c478bd9Sstevel@tonic-gate 
20477c478bd9Sstevel@tonic-gate 	/* add path and file attributes */
20487c478bd9Sstevel@tonic-gate 	if (fad != NULL && fad->fad_aupath != NULL) {
20497c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_arg32(0, "recv fd", (uint32_t)fd));
20507c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_path(fad->fad_aupath));
20517c478bd9Sstevel@tonic-gate 	} else {
20527c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_arg32(0, "recv fd", (uint32_t)fd));
20537c478bd9Sstevel@tonic-gate #ifdef _LP64
20547c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_arg64(0, "no path", (uint64_t)fp));
20557c478bd9Sstevel@tonic-gate #else
20567c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_arg32(0, "no path", (uint32_t)fp));
20577c478bd9Sstevel@tonic-gate #endif
20587c478bd9Sstevel@tonic-gate 	}
20597c478bd9Sstevel@tonic-gate 	vp = fp->f_vnode;	/* include vnode attributes */
20607c478bd9Sstevel@tonic-gate 	audit_attributes(vp);
20617c478bd9Sstevel@tonic-gate }
20627c478bd9Sstevel@tonic-gate 
20637c478bd9Sstevel@tonic-gate /*
20647c478bd9Sstevel@tonic-gate  * ROUTINE:	AUDIT_CRYPTOADM
20657c478bd9Sstevel@tonic-gate  * PURPOSE:	Records arguments to administrative ioctls on /dev/cryptoadm
20667c478bd9Sstevel@tonic-gate  * CALLBY:	CRYPTO_LOAD_DEV_DISABLED, CRYPTO_LOAD_SOFT_DISABLED,
20677c478bd9Sstevel@tonic-gate  *		CRYPTO_UNLOAD_SOFT_MODULE, CRYPTO_LOAD_SOFT_CONFIG,
20687c478bd9Sstevel@tonic-gate  *		CRYPTO_POOL_CREATE, CRYPTO_POOL_WAIT, CRYPTO_POOL_RUN,
20697c478bd9Sstevel@tonic-gate  *		CRYPTO_LOAD_DOOR
20707c478bd9Sstevel@tonic-gate  * NOTE:
20717c478bd9Sstevel@tonic-gate  * TODO:
20727c478bd9Sstevel@tonic-gate  * QUESTION:
20737c478bd9Sstevel@tonic-gate  */
20747c478bd9Sstevel@tonic-gate 
20757c478bd9Sstevel@tonic-gate void
20767c478bd9Sstevel@tonic-gate audit_cryptoadm(int cmd, char *module_name, crypto_mech_name_t *mech_names,
20777c478bd9Sstevel@tonic-gate     uint_t mech_count, uint_t device_instance, uint32_t rv, int error)
20787c478bd9Sstevel@tonic-gate {
20797c478bd9Sstevel@tonic-gate 	boolean_t		mech_list_required = B_FALSE;
20807c478bd9Sstevel@tonic-gate 	cred_t			*cr = CRED();
20817c478bd9Sstevel@tonic-gate 	t_audit_data_t		*tad;
20827c478bd9Sstevel@tonic-gate 	token_t			*ad = NULL;
20837c478bd9Sstevel@tonic-gate 	const auditinfo_addr_t	*ainfo = crgetauinfo(cr);
20847c478bd9Sstevel@tonic-gate 	char			buffer[MAXNAMELEN * 2];
20859e9e6ab8Spaulson 	au_kcontext_t		*kctx = GET_KCTX_PZ;
20867c478bd9Sstevel@tonic-gate 
20877c478bd9Sstevel@tonic-gate 	tad = U2A(u);
20887c478bd9Sstevel@tonic-gate 	if (tad == NULL)
20897c478bd9Sstevel@tonic-gate 		return;
20907c478bd9Sstevel@tonic-gate 
20917c478bd9Sstevel@tonic-gate 	if (ainfo == NULL)
20927c478bd9Sstevel@tonic-gate 		return;
20937c478bd9Sstevel@tonic-gate 
20947c478bd9Sstevel@tonic-gate 	tad->tad_event = AUE_CRYPTOADM;
20957c478bd9Sstevel@tonic-gate 
2096799bd290Spwernau 	if (audit_success(kctx, tad, error, NULL) != AU_OK)
20977c478bd9Sstevel@tonic-gate 		return;
20987c478bd9Sstevel@tonic-gate 
209981490fd2Sgww 	/* Add subject information */
210081490fd2Sgww 	AUDIT_SETSUBJ((caddr_t *)&(ad), cr, ainfo, kctx);
210145916cd2Sjpk 
21027c478bd9Sstevel@tonic-gate 	switch (cmd) {
21037c478bd9Sstevel@tonic-gate 	case CRYPTO_LOAD_DEV_DISABLED:
21047c478bd9Sstevel@tonic-gate 		if (error == 0 && rv == CRYPTO_SUCCESS) {
21057c478bd9Sstevel@tonic-gate 			(void) snprintf(buffer, sizeof (buffer),
21067c478bd9Sstevel@tonic-gate 			    "op=CRYPTO_LOAD_DEV_DISABLED, module=%s,"
21077c478bd9Sstevel@tonic-gate 			    " dev_instance=%d",
21087c478bd9Sstevel@tonic-gate 			    module_name, device_instance);
21097c478bd9Sstevel@tonic-gate 			mech_list_required = B_TRUE;
21107c478bd9Sstevel@tonic-gate 		} else {
21117c478bd9Sstevel@tonic-gate 			(void) snprintf(buffer, sizeof (buffer),
21127c478bd9Sstevel@tonic-gate 			    "op=CRYPTO_LOAD_DEV_DISABLED, return_val=%d", rv);
21137c478bd9Sstevel@tonic-gate 		}
21147c478bd9Sstevel@tonic-gate 		break;
21157c478bd9Sstevel@tonic-gate 
21167c478bd9Sstevel@tonic-gate 	case CRYPTO_LOAD_SOFT_DISABLED:
21177c478bd9Sstevel@tonic-gate 		if (error == 0 && rv == CRYPTO_SUCCESS) {
21187c478bd9Sstevel@tonic-gate 			(void) snprintf(buffer, sizeof (buffer),
21197c478bd9Sstevel@tonic-gate 			    "op=CRYPTO_LOAD_SOFT_DISABLED, module=%s",
21207c478bd9Sstevel@tonic-gate 			    module_name);
21217c478bd9Sstevel@tonic-gate 			mech_list_required = B_TRUE;
21227c478bd9Sstevel@tonic-gate 		} else {
21237c478bd9Sstevel@tonic-gate 			(void) snprintf(buffer, sizeof (buffer),
21247c478bd9Sstevel@tonic-gate 			    "op=CRYPTO_LOAD_SOFT_DISABLED, return_val=%d", rv);
21257c478bd9Sstevel@tonic-gate 		}
21267c478bd9Sstevel@tonic-gate 		break;
21277c478bd9Sstevel@tonic-gate 
21287c478bd9Sstevel@tonic-gate 	case CRYPTO_UNLOAD_SOFT_MODULE:
21297c478bd9Sstevel@tonic-gate 		if (error == 0 && rv == CRYPTO_SUCCESS) {
21307c478bd9Sstevel@tonic-gate 			(void) snprintf(buffer, sizeof (buffer),
21317c478bd9Sstevel@tonic-gate 			    "op=CRYPTO_UNLOAD_SOFT_MODULE, module=%s",
21327c478bd9Sstevel@tonic-gate 			    module_name);
21337c478bd9Sstevel@tonic-gate 		} else {
21347c478bd9Sstevel@tonic-gate 			(void) snprintf(buffer, sizeof (buffer),
21357c478bd9Sstevel@tonic-gate 			    "op=CRYPTO_UNLOAD_SOFT_MODULE, return_val=%d", rv);
21367c478bd9Sstevel@tonic-gate 		}
21377c478bd9Sstevel@tonic-gate 		break;
21387c478bd9Sstevel@tonic-gate 
21397c478bd9Sstevel@tonic-gate 	case CRYPTO_LOAD_SOFT_CONFIG:
21407c478bd9Sstevel@tonic-gate 		if (error == 0 && rv == CRYPTO_SUCCESS) {
21417c478bd9Sstevel@tonic-gate 			(void) snprintf(buffer, sizeof (buffer),
21427c478bd9Sstevel@tonic-gate 			    "op=CRYPTO_LOAD_SOFT_CONFIG, module=%s",
21437c478bd9Sstevel@tonic-gate 			    module_name);
21447c478bd9Sstevel@tonic-gate 			mech_list_required = B_TRUE;
21457c478bd9Sstevel@tonic-gate 		} else {
21467c478bd9Sstevel@tonic-gate 			(void) snprintf(buffer, sizeof (buffer),
21477c478bd9Sstevel@tonic-gate 			    "op=CRYPTO_LOAD_SOFT_CONFIG, return_val=%d", rv);
21487c478bd9Sstevel@tonic-gate 		}
21497c478bd9Sstevel@tonic-gate 		break;
21507c478bd9Sstevel@tonic-gate 
21517c478bd9Sstevel@tonic-gate 	case CRYPTO_POOL_CREATE:
21527c478bd9Sstevel@tonic-gate 		(void) snprintf(buffer, sizeof (buffer),
21537c478bd9Sstevel@tonic-gate 		    "op=CRYPTO_POOL_CREATE");
21547c478bd9Sstevel@tonic-gate 		break;
21557c478bd9Sstevel@tonic-gate 
21567c478bd9Sstevel@tonic-gate 	case CRYPTO_POOL_WAIT:
21577c478bd9Sstevel@tonic-gate 		(void) snprintf(buffer, sizeof (buffer), "op=CRYPTO_POOL_WAIT");
21587c478bd9Sstevel@tonic-gate 		break;
21597c478bd9Sstevel@tonic-gate 
21607c478bd9Sstevel@tonic-gate 	case CRYPTO_POOL_RUN:
21617c478bd9Sstevel@tonic-gate 		(void) snprintf(buffer, sizeof (buffer), "op=CRYPTO_POOL_RUN");
21627c478bd9Sstevel@tonic-gate 		break;
21637c478bd9Sstevel@tonic-gate 
21647c478bd9Sstevel@tonic-gate 	case CRYPTO_LOAD_DOOR:
21657c478bd9Sstevel@tonic-gate 		if (error == 0 && rv == CRYPTO_SUCCESS)
21667c478bd9Sstevel@tonic-gate 			(void) snprintf(buffer, sizeof (buffer),
21677c478bd9Sstevel@tonic-gate 			    "op=CRYPTO_LOAD_DOOR");
21687c478bd9Sstevel@tonic-gate 		else
21697c478bd9Sstevel@tonic-gate 			(void) snprintf(buffer, sizeof (buffer),
21707c478bd9Sstevel@tonic-gate 			    "op=CRYPTO_LOAD_DOOR, return_val=%d", rv);
21717c478bd9Sstevel@tonic-gate 		break;
21727c478bd9Sstevel@tonic-gate 
21737c478bd9Sstevel@tonic-gate 	default:
21747c478bd9Sstevel@tonic-gate 		return;
21757c478bd9Sstevel@tonic-gate 	}
21767c478bd9Sstevel@tonic-gate 
21777c478bd9Sstevel@tonic-gate 	au_write((caddr_t *)&ad, au_to_text(buffer));
21787c478bd9Sstevel@tonic-gate 
21797c478bd9Sstevel@tonic-gate 	if (mech_list_required) {
21807c478bd9Sstevel@tonic-gate 		int i;
21817c478bd9Sstevel@tonic-gate 
21827c478bd9Sstevel@tonic-gate 		if (mech_count == 0) {
21837c478bd9Sstevel@tonic-gate 			au_write((caddr_t *)&ad, au_to_text("mech=list empty"));
21847c478bd9Sstevel@tonic-gate 		} else {
21857c478bd9Sstevel@tonic-gate 			char	*pb = buffer;
21867c478bd9Sstevel@tonic-gate 			size_t	l = sizeof (buffer);
21877c478bd9Sstevel@tonic-gate 			size_t	n;
21887c478bd9Sstevel@tonic-gate 			char	space[2] = ":";
21897c478bd9Sstevel@tonic-gate 
21907c478bd9Sstevel@tonic-gate 			n = snprintf(pb, l, "mech=");
21917c478bd9Sstevel@tonic-gate 
21927c478bd9Sstevel@tonic-gate 			for (i = 0; i < mech_count; i++) {
21937c478bd9Sstevel@tonic-gate 				pb += n;
21947c478bd9Sstevel@tonic-gate 				l -= n;
21957c478bd9Sstevel@tonic-gate 				if (l < 0)
21967c478bd9Sstevel@tonic-gate 					l = 0;
21977c478bd9Sstevel@tonic-gate 
21987c478bd9Sstevel@tonic-gate 				if (i == mech_count - 1)
21997c478bd9Sstevel@tonic-gate 					(void) strcpy(space, "");
22007c478bd9Sstevel@tonic-gate 
22017c478bd9Sstevel@tonic-gate 				n = snprintf(pb, l, "%s%s", mech_names[i],
22027c478bd9Sstevel@tonic-gate 				    space);
22037c478bd9Sstevel@tonic-gate 			}
22047c478bd9Sstevel@tonic-gate 			au_write((caddr_t *)&ad, au_to_text(buffer));
22057c478bd9Sstevel@tonic-gate 		}
22067c478bd9Sstevel@tonic-gate 	}
22077c478bd9Sstevel@tonic-gate 
22087c478bd9Sstevel@tonic-gate 	/* add a return token */
22097c478bd9Sstevel@tonic-gate 	if (error || (rv != CRYPTO_SUCCESS))
22107c478bd9Sstevel@tonic-gate 		add_return_token((caddr_t *)&ad, tad->tad_scid, -1, error);
22117c478bd9Sstevel@tonic-gate 	else
22127c478bd9Sstevel@tonic-gate 		add_return_token((caddr_t *)&ad, tad->tad_scid, 0, rv);
22137c478bd9Sstevel@tonic-gate 
22147c478bd9Sstevel@tonic-gate 	AS_INC(as_generated, 1, kctx);
22157c478bd9Sstevel@tonic-gate 	AS_INC(as_kernel, 1, kctx);
22167c478bd9Sstevel@tonic-gate 
22177c478bd9Sstevel@tonic-gate 	au_close(kctx, (caddr_t *)&ad, AU_OK, AUE_CRYPTOADM, 0);
22187c478bd9Sstevel@tonic-gate }
2219c28749e9Skais 
2220c28749e9Skais /*
2221c28749e9Skais  * Audit the kernel SSL administration command. The address and the
2222c28749e9Skais  * port number for the SSL instance, and the proxy port are put in the
2223c28749e9Skais  * audit trail.
2224c28749e9Skais  */
2225c28749e9Skais void
2226c28749e9Skais audit_kssl(int cmd, void *params, int error)
2227c28749e9Skais {
2228c28749e9Skais 	cred_t			*cr = CRED();
2229c28749e9Skais 	t_audit_data_t		*tad;
2230c28749e9Skais 	token_t			*ad = NULL;
2231c28749e9Skais 	const auditinfo_addr_t	*ainfo = crgetauinfo(cr);
22329e9e6ab8Spaulson 	au_kcontext_t		*kctx = GET_KCTX_PZ;
2233c28749e9Skais 
2234c28749e9Skais 	tad = U2A(u);
2235c28749e9Skais 
2236c28749e9Skais 	if (ainfo == NULL)
2237c28749e9Skais 		return;
2238c28749e9Skais 
2239c28749e9Skais 	tad->tad_event = AUE_CONFIGKSSL;
2240c28749e9Skais 
2241799bd290Spwernau 	if (audit_success(kctx, tad, error, NULL) != AU_OK)
2242c28749e9Skais 		return;
2243c28749e9Skais 
224481490fd2Sgww 	/* Add subject information */
224581490fd2Sgww 	AUDIT_SETSUBJ((caddr_t *)&ad, cr, ainfo, kctx);
224645916cd2Sjpk 
2247c28749e9Skais 	switch (cmd) {
2248c28749e9Skais 	case KSSL_ADD_ENTRY: {
2249c28749e9Skais 		char buf[32];
2250c28749e9Skais 		kssl_params_t *kp = (kssl_params_t *)params;
2251c28749e9Skais 		struct sockaddr_in *saddr = &(kp->kssl_addr);
2252c28749e9Skais 
2253c28749e9Skais 		au_write((caddr_t *)&ad, au_to_text("op=KSSL_ADD_ENTRY"));
2254c28749e9Skais 		au_write((caddr_t *)&ad, au_to_in_addr(&(saddr->sin_addr)));
2255c28749e9Skais 		(void) snprintf(buf, sizeof (buf), "SSL port=%d",
2256c28749e9Skais 		    saddr->sin_port);
2257c28749e9Skais 		au_write((caddr_t *)&ad, au_to_text(buf));
2258c28749e9Skais 
2259c28749e9Skais 		(void) snprintf(buf, sizeof (buf), "proxy port=%d",
2260c28749e9Skais 		    kp->kssl_proxy_port);
2261c28749e9Skais 		au_write((caddr_t *)&ad, au_to_text(buf));
2262c28749e9Skais 		break;
2263c28749e9Skais 	}
2264c28749e9Skais 
2265c28749e9Skais 	case KSSL_DELETE_ENTRY: {
2266c28749e9Skais 		char buf[32];
2267c28749e9Skais 		struct sockaddr_in *saddr = (struct sockaddr_in *)params;
2268c28749e9Skais 
2269c28749e9Skais 		au_write((caddr_t *)&ad, au_to_text("op=KSSL_DELETE_ENTRY"));
2270c28749e9Skais 		au_write((caddr_t *)&ad, au_to_in_addr(&(saddr->sin_addr)));
2271c28749e9Skais 		(void) snprintf(buf, sizeof (buf), "SSL port=%d",
2272c28749e9Skais 		    saddr->sin_port);
2273c28749e9Skais 		au_write((caddr_t *)&ad, au_to_text(buf));
2274c28749e9Skais 		break;
2275c28749e9Skais 	}
2276c28749e9Skais 
2277c28749e9Skais 	default:
2278c28749e9Skais 		return;
2279c28749e9Skais 	}
2280c28749e9Skais 
2281c28749e9Skais 	/* add a return token */
2282c28749e9Skais 	add_return_token((caddr_t *)&ad, tad->tad_scid, error, 0);
2283c28749e9Skais 
2284c28749e9Skais 	AS_INC(as_generated, 1, kctx);
2285c28749e9Skais 	AS_INC(as_kernel, 1, kctx);
2286c28749e9Skais 
2287c28749e9Skais 	au_close(kctx, (caddr_t *)&ad, AU_OK, AUE_CONFIGKSSL, 0);
2288c28749e9Skais }
228945916cd2Sjpk 
229045916cd2Sjpk /*
2291799bd290Spwernau  * Audit the kernel PF_POLICY administration commands.  Record command,
2292799bd290Spwernau  * zone, policy type (global or tunnel, active or inactive)
2293799bd290Spwernau  */
2294799bd290Spwernau /*
2295799bd290Spwernau  * ROUTINE:	AUDIT_PF_POLICY
2296799bd290Spwernau  * PURPOSE:	Records arguments to administrative ioctls on PF_POLICY socket
2297799bd290Spwernau  * CALLBY:	SPD_ADDRULE, SPD_DELETERULE, SPD_FLUSH, SPD_UPDATEALGS,
2298799bd290Spwernau  *		SPD_CLONE, SPD_FLIP
2299799bd290Spwernau  * NOTE:
2300799bd290Spwernau  * TODO:
2301799bd290Spwernau  * QUESTION:
2302799bd290Spwernau  */
2303799bd290Spwernau 
2304799bd290Spwernau void
2305799bd290Spwernau audit_pf_policy(int cmd, cred_t *cred, netstack_t *ns, char *tun,
2306799bd290Spwernau     boolean_t active, int error, pid_t pid)
2307799bd290Spwernau {
2308799bd290Spwernau 	const auditinfo_addr_t	*ainfo;
2309799bd290Spwernau 	t_audit_data_t		*tad;
2310799bd290Spwernau 	token_t			*ad = NULL;
2311799bd290Spwernau 	au_kcontext_t		*kctx = GET_KCTX_PZ;
2312799bd290Spwernau 	char			buf[80];
2313799bd290Spwernau 	int			flag;
2314799bd290Spwernau 
2315799bd290Spwernau 	tad = U2A(u);
2316799bd290Spwernau 	if (tad == NULL)
2317799bd290Spwernau 		return;
2318799bd290Spwernau 
2319799bd290Spwernau 	ainfo = crgetauinfo((cred != NULL) ? cred : CRED());
2320799bd290Spwernau 	if (ainfo == NULL)
2321799bd290Spwernau 		return;
2322799bd290Spwernau 
2323799bd290Spwernau 	/*
2324799bd290Spwernau 	 * Initialize some variables since these are only set
2325799bd290Spwernau 	 * with system calls.
2326799bd290Spwernau 	 */
2327799bd290Spwernau 
2328799bd290Spwernau 	switch (cmd) {
2329799bd290Spwernau 	case SPD_ADDRULE: {
2330799bd290Spwernau 		tad->tad_event = AUE_PF_POLICY_ADDRULE;
2331799bd290Spwernau 		break;
2332799bd290Spwernau 	}
2333799bd290Spwernau 
2334799bd290Spwernau 	case SPD_DELETERULE: {
2335799bd290Spwernau 		tad->tad_event = AUE_PF_POLICY_DELRULE;
2336799bd290Spwernau 		break;
2337799bd290Spwernau 	}
2338799bd290Spwernau 
2339799bd290Spwernau 	case SPD_FLUSH: {
2340799bd290Spwernau 		tad->tad_event = AUE_PF_POLICY_FLUSH;
2341799bd290Spwernau 		break;
2342799bd290Spwernau 	}
2343799bd290Spwernau 
2344799bd290Spwernau 	case SPD_UPDATEALGS: {
2345799bd290Spwernau 		tad->tad_event = AUE_PF_POLICY_ALGS;
2346799bd290Spwernau 		break;
2347799bd290Spwernau 	}
2348799bd290Spwernau 
2349799bd290Spwernau 	case SPD_CLONE: {
2350799bd290Spwernau 		tad->tad_event = AUE_PF_POLICY_CLONE;
2351799bd290Spwernau 		break;
2352799bd290Spwernau 	}
2353799bd290Spwernau 
2354799bd290Spwernau 	case SPD_FLIP: {
2355799bd290Spwernau 		tad->tad_event = AUE_PF_POLICY_FLIP;
2356799bd290Spwernau 		break;
2357799bd290Spwernau 	}
2358799bd290Spwernau 
2359799bd290Spwernau 	default:
2360799bd290Spwernau 		tad->tad_event = AUE_NULL;
2361799bd290Spwernau 	}
2362799bd290Spwernau 
2363799bd290Spwernau 	tad->tad_evmod = 0;
2364799bd290Spwernau 
2365799bd290Spwernau 	if (flag = audit_success(kctx, tad, error, cred)) {
2366799bd290Spwernau 		zone_t *nszone;
2367799bd290Spwernau 
2368799bd290Spwernau 		/*
2369799bd290Spwernau 		 * For now, just audit that an event happened,
2370799bd290Spwernau 		 * along with the error code.
2371799bd290Spwernau 		 */
2372799bd290Spwernau 		au_write((caddr_t *)&ad,
2373799bd290Spwernau 		    au_to_arg32(1, "Policy Active?", (uint32_t)active));
2374799bd290Spwernau 		au_write((caddr_t *)&ad,
2375799bd290Spwernau 		    au_to_arg32(2, "Policy Global?", (uint32_t)(tun == NULL)));
2376799bd290Spwernau 
2377799bd290Spwernau 		/* Supplemental data */
2378799bd290Spwernau 
2379799bd290Spwernau 		/*
2380799bd290Spwernau 		 * Generate this zone token if the target zone differs
2381799bd290Spwernau 		 * from the administrative zone.  If netstacks are expanded
2382799bd290Spwernau 		 * to something other than a 1-1 relationship with zones,
2383799bd290Spwernau 		 * the auditing framework should create a new token type
2384799bd290Spwernau 		 * and audit it as a netstack instead.
2385799bd290Spwernau 		 * Turn on general zone auditing to get the administrative zone.
2386799bd290Spwernau 		 */
2387799bd290Spwernau 
2388799bd290Spwernau 		nszone = zone_find_by_id(netstackid_to_zoneid(
2389799bd290Spwernau 		    ns->netstack_stackid));
2390799bd290Spwernau 		if (strncmp(cred->cr_zone->zone_name, nszone->zone_name,
2391799bd290Spwernau 		    ZONENAME_MAX) != 0) {
2392799bd290Spwernau 			token_t *ztoken;
2393799bd290Spwernau 
2394799bd290Spwernau 			ztoken = au_to_zonename(0, nszone);
2395799bd290Spwernau 			au_write((caddr_t *)&ad, ztoken);
2396799bd290Spwernau 		}
2397799bd290Spwernau 
2398799bd290Spwernau 		if (tun != NULL) {
2399799bd290Spwernau 			/* write tunnel name - tun is bounded */
2400799bd290Spwernau 			(void) snprintf(buf, sizeof (buf), "tunnel_name:%s",
2401799bd290Spwernau 			    tun);
2402799bd290Spwernau 			au_write((caddr_t *)&ad, au_to_text(buf));
2403799bd290Spwernau 		}
2404799bd290Spwernau 
2405799bd290Spwernau 		/* Add subject information */
2406799bd290Spwernau 		AUDIT_SETSUBJ_GENERIC((caddr_t *)&ad,
2407799bd290Spwernau 		    ((cred != NULL) ? cred : CRED()), ainfo, kctx, pid);
2408799bd290Spwernau 
2409799bd290Spwernau 		/* add a return token */
2410799bd290Spwernau 		add_return_token((caddr_t *)&ad, 0, error, 0);
2411799bd290Spwernau 
2412799bd290Spwernau 		AS_INC(as_generated, 1, kctx);
2413799bd290Spwernau 		AS_INC(as_kernel, 1, kctx);
2414799bd290Spwernau 
2415799bd290Spwernau 	}
2416799bd290Spwernau 	au_close(kctx, (caddr_t *)&ad, flag, tad->tad_event, 0);
2417799bd290Spwernau 
2418799bd290Spwernau 	/*
2419799bd290Spwernau 	 * clear the ctrl flag so that we don't have spurious collection of
2420799bd290Spwernau 	 * audit information.
2421799bd290Spwernau 	 */
2422799bd290Spwernau 	tad->tad_scid  = 0;
2423799bd290Spwernau 	tad->tad_event = 0;
2424799bd290Spwernau 	tad->tad_evmod = 0;
2425799bd290Spwernau 	tad->tad_ctrl  = 0;
2426799bd290Spwernau }
2427799bd290Spwernau 
2428799bd290Spwernau /*
242945916cd2Sjpk  * ROUTINE:	AUDIT_SEC_ATTRIBUTES
243045916cd2Sjpk  * PURPOSE:	Add security attributes
243145916cd2Sjpk  * CALLBY:	AUDIT_ATTRIBUTES
243245916cd2Sjpk  *		AUDIT_CLOSEF
243345916cd2Sjpk  *		AUS_CLOSE
243445916cd2Sjpk  * NOTE:
243545916cd2Sjpk  * TODO:
243645916cd2Sjpk  * QUESTION:
243745916cd2Sjpk  */
243845916cd2Sjpk 
243945916cd2Sjpk void
244045916cd2Sjpk audit_sec_attributes(caddr_t *ad, struct vnode *vp)
244145916cd2Sjpk {
244245916cd2Sjpk 	/* Dump the SL */
244345916cd2Sjpk 	if (is_system_labeled()) {
244445916cd2Sjpk 		ts_label_t	*tsl;
244545916cd2Sjpk 		bslabel_t	*bsl;
244645916cd2Sjpk 
244745916cd2Sjpk 		tsl = getflabel(vp);
244845916cd2Sjpk 		if (tsl == NULL)
244945916cd2Sjpk 			return;			/* nothing else to do */
245045916cd2Sjpk 
245145916cd2Sjpk 		bsl = label2bslabel(tsl);
245245916cd2Sjpk 		if (bsl == NULL)
245345916cd2Sjpk 			return;			/* nothing else to do */
245445916cd2Sjpk 		au_write(ad, au_to_label(bsl));
245545916cd2Sjpk 		label_rele(tsl);
245645916cd2Sjpk 	}
245745916cd2Sjpk 
245845916cd2Sjpk }	/* AUDIT_SEC_ATTRIBUTES */
2459