xref: /titanic_51/usr/src/uts/common/c2/audit.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate  *
4*7c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate  * with the License.
8*7c478bd9Sstevel@tonic-gate  *
9*7c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate  * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate  *
14*7c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate  *
20*7c478bd9Sstevel@tonic-gate  * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate  */
22*7c478bd9Sstevel@tonic-gate /*
23*7c478bd9Sstevel@tonic-gate  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
24*7c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
25*7c478bd9Sstevel@tonic-gate  */
26*7c478bd9Sstevel@tonic-gate 
27*7c478bd9Sstevel@tonic-gate /*
28*7c478bd9Sstevel@tonic-gate  * This file contains the audit hook support code for auditing.
29*7c478bd9Sstevel@tonic-gate  */
30*7c478bd9Sstevel@tonic-gate 
31*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
32*7c478bd9Sstevel@tonic-gate 
33*7c478bd9Sstevel@tonic-gate #include <sys/types.h>
34*7c478bd9Sstevel@tonic-gate #include <sys/proc.h>
35*7c478bd9Sstevel@tonic-gate #include <sys/vnode.h>
36*7c478bd9Sstevel@tonic-gate #include <sys/vfs.h>
37*7c478bd9Sstevel@tonic-gate #include <sys/file.h>
38*7c478bd9Sstevel@tonic-gate #include <sys/user.h>
39*7c478bd9Sstevel@tonic-gate #include <sys/stropts.h>
40*7c478bd9Sstevel@tonic-gate #include <sys/systm.h>
41*7c478bd9Sstevel@tonic-gate #include <sys/pathname.h>
42*7c478bd9Sstevel@tonic-gate #include <sys/syscall.h>
43*7c478bd9Sstevel@tonic-gate #include <sys/fcntl.h>
44*7c478bd9Sstevel@tonic-gate #include <sys/ipc_impl.h>
45*7c478bd9Sstevel@tonic-gate #include <sys/msg_impl.h>
46*7c478bd9Sstevel@tonic-gate #include <sys/sem_impl.h>
47*7c478bd9Sstevel@tonic-gate #include <sys/shm_impl.h>
48*7c478bd9Sstevel@tonic-gate #include <sys/kmem.h>		/* for KM_SLEEP */
49*7c478bd9Sstevel@tonic-gate #include <sys/socket.h>
50*7c478bd9Sstevel@tonic-gate #include <sys/cmn_err.h>	/* snprintf... */
51*7c478bd9Sstevel@tonic-gate #include <sys/debug.h>
52*7c478bd9Sstevel@tonic-gate #include <sys/thread.h>
53*7c478bd9Sstevel@tonic-gate #include <netinet/in.h>
54*7c478bd9Sstevel@tonic-gate #include <c2/audit.h>		/* needs to be included before user.h */
55*7c478bd9Sstevel@tonic-gate #include <c2/audit_kernel.h>	/* for M_DONTWAIT */
56*7c478bd9Sstevel@tonic-gate #include <c2/audit_kevents.h>
57*7c478bd9Sstevel@tonic-gate #include <c2/audit_record.h>
58*7c478bd9Sstevel@tonic-gate #include <sys/strsubr.h>
59*7c478bd9Sstevel@tonic-gate #include <sys/tihdr.h>
60*7c478bd9Sstevel@tonic-gate #include <sys/tiuser.h>
61*7c478bd9Sstevel@tonic-gate #include <sys/timod.h>
62*7c478bd9Sstevel@tonic-gate #include <sys/model.h>		/* for model_t */
63*7c478bd9Sstevel@tonic-gate #include <sys/disp.h>		/* for servicing_interrupt() */
64*7c478bd9Sstevel@tonic-gate #include <sys/devpolicy.h>
65*7c478bd9Sstevel@tonic-gate #include <sys/crypto/ioctladmin.h>
66*7c478bd9Sstevel@tonic-gate 
67*7c478bd9Sstevel@tonic-gate static void add_return_token(caddr_t *, unsigned int scid, int err, int rval);
68*7c478bd9Sstevel@tonic-gate 
69*7c478bd9Sstevel@tonic-gate static void audit_pathbuild(struct pathname *pnp);
70*7c478bd9Sstevel@tonic-gate 
71*7c478bd9Sstevel@tonic-gate /*
72*7c478bd9Sstevel@tonic-gate  * ROUTINE:	AUDIT_NEWPROC
73*7c478bd9Sstevel@tonic-gate  * PURPOSE:	initialize the child p_audit_data structure
74*7c478bd9Sstevel@tonic-gate  * CALLBY:	GETPROC
75*7c478bd9Sstevel@tonic-gate  * NOTE:	All threads for the parent process are locked at this point.
76*7c478bd9Sstevel@tonic-gate  *		We are essentially running singled threaded for this reason.
77*7c478bd9Sstevel@tonic-gate  *		GETPROC is called when system creates a new process.
78*7c478bd9Sstevel@tonic-gate  *		By the time AUDIT_NEWPROC is called, the child proc
79*7c478bd9Sstevel@tonic-gate  *		structure has already been initialized. What we need
80*7c478bd9Sstevel@tonic-gate  *		to do is to allocate the child p_audit_data and
81*7c478bd9Sstevel@tonic-gate  *		initialize it with the content of current parent process.
82*7c478bd9Sstevel@tonic-gate  */
83*7c478bd9Sstevel@tonic-gate 
84*7c478bd9Sstevel@tonic-gate void
85*7c478bd9Sstevel@tonic-gate audit_newproc(struct proc *cp)	/* initialized child proc structure */
86*7c478bd9Sstevel@tonic-gate {
87*7c478bd9Sstevel@tonic-gate 	p_audit_data_t *pad;	/* child process audit data */
88*7c478bd9Sstevel@tonic-gate 	p_audit_data_t *opad;	/* parent process audit data */
89*7c478bd9Sstevel@tonic-gate 
90*7c478bd9Sstevel@tonic-gate 	pad = kmem_cache_alloc(au_pad_cache, KM_SLEEP);
91*7c478bd9Sstevel@tonic-gate 
92*7c478bd9Sstevel@tonic-gate 	P2A(cp) = pad;
93*7c478bd9Sstevel@tonic-gate 
94*7c478bd9Sstevel@tonic-gate 	opad = P2A(curproc);
95*7c478bd9Sstevel@tonic-gate 
96*7c478bd9Sstevel@tonic-gate 	/*
97*7c478bd9Sstevel@tonic-gate 	 * copy the audit data. Note that all threads of current
98*7c478bd9Sstevel@tonic-gate 	 *   process have been "held". Thus there is no race condition
99*7c478bd9Sstevel@tonic-gate 	 *   here with mutiple threads trying to alter the cwrd
100*7c478bd9Sstevel@tonic-gate 	 *   structure (such as releasing it).
101*7c478bd9Sstevel@tonic-gate 	 *
102*7c478bd9Sstevel@tonic-gate 	 *   The audit context in the cred is "duplicated" for the new
103*7c478bd9Sstevel@tonic-gate 	 *   proc by elsewhere crhold'ing the parent's cred which it shares.
104*7c478bd9Sstevel@tonic-gate 	 *
105*7c478bd9Sstevel@tonic-gate 	 *   We still want to hold things since auditon() [A_SETUMASK,
106*7c478bd9Sstevel@tonic-gate 	 *   A_SETSMASK] could be walking through the processes to
107*7c478bd9Sstevel@tonic-gate 	 *   update things.
108*7c478bd9Sstevel@tonic-gate 	 */
109*7c478bd9Sstevel@tonic-gate 	mutex_enter(&opad->pad_lock);	/* lock opad structure during copy */
110*7c478bd9Sstevel@tonic-gate 	pad->pad_data = opad->pad_data;	/* copy parent's process audit data */
111*7c478bd9Sstevel@tonic-gate 	au_pathhold(pad->pad_root);
112*7c478bd9Sstevel@tonic-gate 	au_pathhold(pad->pad_cwd);
113*7c478bd9Sstevel@tonic-gate 	mutex_exit(&opad->pad_lock);	/* current proc will keep cwrd open */
114*7c478bd9Sstevel@tonic-gate 
115*7c478bd9Sstevel@tonic-gate 	/*
116*7c478bd9Sstevel@tonic-gate 	 * finish auditing of parent here so that it will be done
117*7c478bd9Sstevel@tonic-gate 	 * before child has a chance to run. We include the child
118*7c478bd9Sstevel@tonic-gate 	 * pid since the return value in the return token is a dummy
119*7c478bd9Sstevel@tonic-gate 	 * one and contains no useful information (it is included to
120*7c478bd9Sstevel@tonic-gate 	 * make the audit record structure consistant).
121*7c478bd9Sstevel@tonic-gate 	 *
122*7c478bd9Sstevel@tonic-gate 	 * tad_flag is set if auditing is on
123*7c478bd9Sstevel@tonic-gate 	 */
124*7c478bd9Sstevel@tonic-gate 	if (((t_audit_data_t *)T2A(curthread))->tad_flag)
125*7c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_arg32(0, "child PID", (uint32_t)cp->p_pid));
126*7c478bd9Sstevel@tonic-gate 
127*7c478bd9Sstevel@tonic-gate 	/*
128*7c478bd9Sstevel@tonic-gate 	 * finish up audit record generation here because child process
129*7c478bd9Sstevel@tonic-gate 	 * is set to run before parent process. We distinguish here
130*7c478bd9Sstevel@tonic-gate 	 * between FORK, FORK1, or VFORK by the saved system call ID.
131*7c478bd9Sstevel@tonic-gate 	 */
132*7c478bd9Sstevel@tonic-gate 	audit_finish(0, ((t_audit_data_t *)T2A(curthread))->tad_scid, 0, 0);
133*7c478bd9Sstevel@tonic-gate }
134*7c478bd9Sstevel@tonic-gate 
135*7c478bd9Sstevel@tonic-gate /*
136*7c478bd9Sstevel@tonic-gate  * ROUTINE:	AUDIT_PFREE
137*7c478bd9Sstevel@tonic-gate  * PURPOSE:	deallocate the per-process udit data structure
138*7c478bd9Sstevel@tonic-gate  * CALLBY:	EXIT
139*7c478bd9Sstevel@tonic-gate  *		FORK_FAIL
140*7c478bd9Sstevel@tonic-gate  * NOTE:	all lwp except current one have stopped in SEXITLWPS
141*7c478bd9Sstevel@tonic-gate  * 		why we are single threaded?
142*7c478bd9Sstevel@tonic-gate  *		. all lwp except current one have stopped in SEXITLWPS.
143*7c478bd9Sstevel@tonic-gate  */
144*7c478bd9Sstevel@tonic-gate void
145*7c478bd9Sstevel@tonic-gate audit_pfree(struct proc *p)		/* proc structure to be freed */
146*7c478bd9Sstevel@tonic-gate 
147*7c478bd9Sstevel@tonic-gate {	/* AUDIT_PFREE */
148*7c478bd9Sstevel@tonic-gate 
149*7c478bd9Sstevel@tonic-gate 	p_audit_data_t *pad;
150*7c478bd9Sstevel@tonic-gate 
151*7c478bd9Sstevel@tonic-gate 	pad = P2A(p);
152*7c478bd9Sstevel@tonic-gate 
153*7c478bd9Sstevel@tonic-gate 	/* better be a per process audit data structure */
154*7c478bd9Sstevel@tonic-gate 	ASSERT(pad != (p_audit_data_t *)0);
155*7c478bd9Sstevel@tonic-gate 
156*7c478bd9Sstevel@tonic-gate 	if (pad == pad0) {
157*7c478bd9Sstevel@tonic-gate 		return;
158*7c478bd9Sstevel@tonic-gate 	}
159*7c478bd9Sstevel@tonic-gate 
160*7c478bd9Sstevel@tonic-gate 	/* deallocate all auditing resources for this process */
161*7c478bd9Sstevel@tonic-gate 	au_pathrele(pad->pad_root);
162*7c478bd9Sstevel@tonic-gate 	au_pathrele(pad->pad_cwd);
163*7c478bd9Sstevel@tonic-gate 
164*7c478bd9Sstevel@tonic-gate 	/*
165*7c478bd9Sstevel@tonic-gate 	 * Since the pad structure is completely overwritten after alloc,
166*7c478bd9Sstevel@tonic-gate 	 * we don't bother to clear it.
167*7c478bd9Sstevel@tonic-gate 	 */
168*7c478bd9Sstevel@tonic-gate 
169*7c478bd9Sstevel@tonic-gate 	kmem_cache_free(au_pad_cache, pad);
170*7c478bd9Sstevel@tonic-gate }
171*7c478bd9Sstevel@tonic-gate 
172*7c478bd9Sstevel@tonic-gate /*
173*7c478bd9Sstevel@tonic-gate  * ROUTINE:	AUDIT_THREAD_CREATE
174*7c478bd9Sstevel@tonic-gate  * PURPOSE:	allocate per-process thread audit data structure
175*7c478bd9Sstevel@tonic-gate  * CALLBY:	THREAD_CREATE
176*7c478bd9Sstevel@tonic-gate  * NOTE:	This is called just after *t was bzero'd.
177*7c478bd9Sstevel@tonic-gate  *		We are single threaded in this routine.
178*7c478bd9Sstevel@tonic-gate  * TODO:
179*7c478bd9Sstevel@tonic-gate  * QUESTION:
180*7c478bd9Sstevel@tonic-gate  */
181*7c478bd9Sstevel@tonic-gate 
182*7c478bd9Sstevel@tonic-gate void
183*7c478bd9Sstevel@tonic-gate audit_thread_create(kthread_id_t t)
184*7c478bd9Sstevel@tonic-gate {
185*7c478bd9Sstevel@tonic-gate 	t_audit_data_t *tad;	/* per-thread audit data */
186*7c478bd9Sstevel@tonic-gate 
187*7c478bd9Sstevel@tonic-gate 	tad = kmem_zalloc(sizeof (struct t_audit_data), KM_SLEEP);
188*7c478bd9Sstevel@tonic-gate 
189*7c478bd9Sstevel@tonic-gate 	T2A(t) = tad;		/* set up thread audit data ptr */
190*7c478bd9Sstevel@tonic-gate 	tad->tad_thread = t;	/* back ptr to thread: DEBUG */
191*7c478bd9Sstevel@tonic-gate }
192*7c478bd9Sstevel@tonic-gate 
193*7c478bd9Sstevel@tonic-gate /*
194*7c478bd9Sstevel@tonic-gate  * ROUTINE:	AUDIT_THREAD_FREE
195*7c478bd9Sstevel@tonic-gate  * PURPOSE:	free the per-thread audit data structure
196*7c478bd9Sstevel@tonic-gate  * CALLBY:	THREAD_FREE
197*7c478bd9Sstevel@tonic-gate  * NOTE:	most thread data is clear after return
198*7c478bd9Sstevel@tonic-gate  */
199*7c478bd9Sstevel@tonic-gate void
200*7c478bd9Sstevel@tonic-gate audit_thread_free(kthread_t *t)
201*7c478bd9Sstevel@tonic-gate {
202*7c478bd9Sstevel@tonic-gate 	t_audit_data_t *tad;
203*7c478bd9Sstevel@tonic-gate 	au_defer_info_t	*attr;
204*7c478bd9Sstevel@tonic-gate 
205*7c478bd9Sstevel@tonic-gate 	tad = T2A(t);
206*7c478bd9Sstevel@tonic-gate 
207*7c478bd9Sstevel@tonic-gate 	/* thread audit data must still be set */
208*7c478bd9Sstevel@tonic-gate 
209*7c478bd9Sstevel@tonic-gate 	if (tad == tad0) {
210*7c478bd9Sstevel@tonic-gate 		return;
211*7c478bd9Sstevel@tonic-gate 	}
212*7c478bd9Sstevel@tonic-gate 
213*7c478bd9Sstevel@tonic-gate 	if (tad == NULL) {
214*7c478bd9Sstevel@tonic-gate 		return;
215*7c478bd9Sstevel@tonic-gate 	}
216*7c478bd9Sstevel@tonic-gate 
217*7c478bd9Sstevel@tonic-gate 	t->t_audit_data = 0;
218*7c478bd9Sstevel@tonic-gate 
219*7c478bd9Sstevel@tonic-gate 	/* must not have any audit record residual */
220*7c478bd9Sstevel@tonic-gate 	ASSERT(tad->tad_ad == NULL);
221*7c478bd9Sstevel@tonic-gate 
222*7c478bd9Sstevel@tonic-gate 	/* saved path must be empty */
223*7c478bd9Sstevel@tonic-gate 	ASSERT(tad->tad_aupath == NULL);
224*7c478bd9Sstevel@tonic-gate 
225*7c478bd9Sstevel@tonic-gate 	if (tad->tad_atpath)
226*7c478bd9Sstevel@tonic-gate 		au_pathrele(tad->tad_atpath);
227*7c478bd9Sstevel@tonic-gate 
228*7c478bd9Sstevel@tonic-gate 	attr = tad->tad_defer_head;
229*7c478bd9Sstevel@tonic-gate 	while (attr != NULL) {
230*7c478bd9Sstevel@tonic-gate 		au_defer_info_t	*tmp_attr = attr;
231*7c478bd9Sstevel@tonic-gate 
232*7c478bd9Sstevel@tonic-gate 		au_free_rec(attr->audi_ad);
233*7c478bd9Sstevel@tonic-gate 
234*7c478bd9Sstevel@tonic-gate 		attr = attr->audi_next;
235*7c478bd9Sstevel@tonic-gate 		kmem_free(tmp_attr, sizeof (au_defer_info_t));
236*7c478bd9Sstevel@tonic-gate 	}
237*7c478bd9Sstevel@tonic-gate 
238*7c478bd9Sstevel@tonic-gate 	kmem_free(tad, sizeof (*tad));
239*7c478bd9Sstevel@tonic-gate }
240*7c478bd9Sstevel@tonic-gate 
241*7c478bd9Sstevel@tonic-gate /*
242*7c478bd9Sstevel@tonic-gate  * ROUTINE:	AUDIT_SAVEPATH
243*7c478bd9Sstevel@tonic-gate  * PURPOSE:
244*7c478bd9Sstevel@tonic-gate  * CALLBY:	LOOKUPPN
245*7c478bd9Sstevel@tonic-gate  *
246*7c478bd9Sstevel@tonic-gate  * NOTE:	We have reached the end of a path in fs/lookup.c.
247*7c478bd9Sstevel@tonic-gate  *		We get two pieces of information here:
248*7c478bd9Sstevel@tonic-gate  *		the vnode of the last component (vp) and
249*7c478bd9Sstevel@tonic-gate  *		the status of the last access (flag).
250*7c478bd9Sstevel@tonic-gate  * TODO:
251*7c478bd9Sstevel@tonic-gate  * QUESTION:
252*7c478bd9Sstevel@tonic-gate  */
253*7c478bd9Sstevel@tonic-gate 
254*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
255*7c478bd9Sstevel@tonic-gate int
256*7c478bd9Sstevel@tonic-gate audit_savepath(
257*7c478bd9Sstevel@tonic-gate 	struct pathname *pnp,		/* pathname to lookup */
258*7c478bd9Sstevel@tonic-gate 	struct vnode *vp,		/* vnode of the last component */
259*7c478bd9Sstevel@tonic-gate 	int    flag,			/* status of the last access */
260*7c478bd9Sstevel@tonic-gate 	cred_t *cr)			/* cred of requestor */
261*7c478bd9Sstevel@tonic-gate {
262*7c478bd9Sstevel@tonic-gate 
263*7c478bd9Sstevel@tonic-gate 	t_audit_data_t *tad;	/* current thread */
264*7c478bd9Sstevel@tonic-gate 	p_audit_data_t *pad;	/* current process */
265*7c478bd9Sstevel@tonic-gate 	au_kcontext_t	*kctx = SET_KCTX_PZ;
266*7c478bd9Sstevel@tonic-gate 
267*7c478bd9Sstevel@tonic-gate 	if (kctx == NULL) {
268*7c478bd9Sstevel@tonic-gate 		zone_status_t zstate = zone_status_get(curproc->p_zone);
269*7c478bd9Sstevel@tonic-gate 		ASSERT(zstate != ZONE_IS_READY);
270*7c478bd9Sstevel@tonic-gate 		return (0);
271*7c478bd9Sstevel@tonic-gate 	}
272*7c478bd9Sstevel@tonic-gate 
273*7c478bd9Sstevel@tonic-gate 	tad = U2A(u);
274*7c478bd9Sstevel@tonic-gate 	ASSERT(tad != (t_audit_data_t *)0);
275*7c478bd9Sstevel@tonic-gate 	pad = P2A(curproc);
276*7c478bd9Sstevel@tonic-gate 	ASSERT(pad != (p_audit_data_t *)0);
277*7c478bd9Sstevel@tonic-gate 
278*7c478bd9Sstevel@tonic-gate 	/*
279*7c478bd9Sstevel@tonic-gate 	 * this event being audited or do we need path information
280*7c478bd9Sstevel@tonic-gate 	 * later? This might be for a chdir/chroot or open (add path
281*7c478bd9Sstevel@tonic-gate 	 * to file pointer. If the path has already been found for an
282*7c478bd9Sstevel@tonic-gate 	 * open/creat then we don't need to process the path.
283*7c478bd9Sstevel@tonic-gate 	 *
284*7c478bd9Sstevel@tonic-gate 	 * S2E_SP (PAD_SAVPATH) flag comes from audit_s2e[].au_ctrl. Used with
285*7c478bd9Sstevel@tonic-gate 	 *	chroot, chdir, open, creat system call processing. It determines
286*7c478bd9Sstevel@tonic-gate 	 *	if audit_savepath() will discard the path or we need it later.
287*7c478bd9Sstevel@tonic-gate 	 * PAD_PATHFND means path already included in this audit record. It
288*7c478bd9Sstevel@tonic-gate 	 *	is used in cases where multiple path lookups are done per
289*7c478bd9Sstevel@tonic-gate 	 *	system call. The policy flag, AUDIT_PATH, controls if multiple
290*7c478bd9Sstevel@tonic-gate 	 *	paths are allowed.
291*7c478bd9Sstevel@tonic-gate 	 * S2E_NPT (PAD_NOPATH) flag comes from audit_s2e[].au_ctrl. Used with
292*7c478bd9Sstevel@tonic-gate 	 *	exit processing to inhibit any paths that may be added due to
293*7c478bd9Sstevel@tonic-gate 	 *	closes.
294*7c478bd9Sstevel@tonic-gate 	 */
295*7c478bd9Sstevel@tonic-gate 	if ((tad->tad_flag == 0 && !(tad->tad_ctrl & PAD_SAVPATH)) ||
296*7c478bd9Sstevel@tonic-gate 		((tad->tad_ctrl & PAD_PATHFND) &&
297*7c478bd9Sstevel@tonic-gate 		!(kctx->auk_policy & AUDIT_PATH)) ||
298*7c478bd9Sstevel@tonic-gate 		(tad->tad_ctrl & PAD_NOPATH)) {
299*7c478bd9Sstevel@tonic-gate 			return (0);
300*7c478bd9Sstevel@tonic-gate 	}
301*7c478bd9Sstevel@tonic-gate 
302*7c478bd9Sstevel@tonic-gate 	audit_pathbuild(pnp);
303*7c478bd9Sstevel@tonic-gate 	tad->tad_vn = vp;
304*7c478bd9Sstevel@tonic-gate 
305*7c478bd9Sstevel@tonic-gate 	/*
306*7c478bd9Sstevel@tonic-gate 	 * are we auditing only if error, or if it is not open or create
307*7c478bd9Sstevel@tonic-gate 	 * otherwise audit_setf will do it
308*7c478bd9Sstevel@tonic-gate 	 */
309*7c478bd9Sstevel@tonic-gate 
310*7c478bd9Sstevel@tonic-gate 	if (tad->tad_flag) {
311*7c478bd9Sstevel@tonic-gate 		if (flag && (tad->tad_scid == SYS_open ||
312*7c478bd9Sstevel@tonic-gate 		    tad->tad_scid == SYS_open64 ||
313*7c478bd9Sstevel@tonic-gate 		    tad->tad_scid == SYS_creat ||
314*7c478bd9Sstevel@tonic-gate 		    tad->tad_scid == SYS_creat64 ||
315*7c478bd9Sstevel@tonic-gate 		    tad->tad_scid == SYS_fsat)) {
316*7c478bd9Sstevel@tonic-gate 			tad->tad_ctrl |= PAD_TRUE_CREATE;
317*7c478bd9Sstevel@tonic-gate 		}
318*7c478bd9Sstevel@tonic-gate 
319*7c478bd9Sstevel@tonic-gate 		/* add token to audit record for this name */
320*7c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_path(tad->tad_aupath));
321*7c478bd9Sstevel@tonic-gate 
322*7c478bd9Sstevel@tonic-gate 		/* add the attributes of the object */
323*7c478bd9Sstevel@tonic-gate 		if (vp) {
324*7c478bd9Sstevel@tonic-gate 			/*
325*7c478bd9Sstevel@tonic-gate 			 * only capture attributes when there is no error
326*7c478bd9Sstevel@tonic-gate 			 * lookup will not return the vnode of the failing
327*7c478bd9Sstevel@tonic-gate 			 * component.
328*7c478bd9Sstevel@tonic-gate 			 *
329*7c478bd9Sstevel@tonic-gate 			 * if there was a lookup error, then don't add
330*7c478bd9Sstevel@tonic-gate 			 * attribute. if lookup in vn_create(),
331*7c478bd9Sstevel@tonic-gate 			 * then don't add attribute,
332*7c478bd9Sstevel@tonic-gate 			 * it will be added at end of vn_create().
333*7c478bd9Sstevel@tonic-gate 			 */
334*7c478bd9Sstevel@tonic-gate 			if (!flag && !(tad->tad_ctrl & PAD_NOATTRB))
335*7c478bd9Sstevel@tonic-gate 				audit_attributes(vp);
336*7c478bd9Sstevel@tonic-gate 		}
337*7c478bd9Sstevel@tonic-gate 	}
338*7c478bd9Sstevel@tonic-gate 
339*7c478bd9Sstevel@tonic-gate 	/* free up space if we're not going to save path (open, crate) */
340*7c478bd9Sstevel@tonic-gate 	if ((tad->tad_ctrl & PAD_SAVPATH) == 0) {
341*7c478bd9Sstevel@tonic-gate 		if (tad->tad_aupath != NULL) {
342*7c478bd9Sstevel@tonic-gate 			au_pathrele(tad->tad_aupath);
343*7c478bd9Sstevel@tonic-gate 			tad->tad_aupath = NULL;
344*7c478bd9Sstevel@tonic-gate 			tad->tad_vn = NULL;
345*7c478bd9Sstevel@tonic-gate 		}
346*7c478bd9Sstevel@tonic-gate 	}
347*7c478bd9Sstevel@tonic-gate 	if (tad->tad_ctrl & PAD_MLD)
348*7c478bd9Sstevel@tonic-gate 		tad->tad_ctrl |= PAD_PATHFND;
349*7c478bd9Sstevel@tonic-gate 
350*7c478bd9Sstevel@tonic-gate 	return (0);
351*7c478bd9Sstevel@tonic-gate }
352*7c478bd9Sstevel@tonic-gate 
353*7c478bd9Sstevel@tonic-gate static void
354*7c478bd9Sstevel@tonic-gate audit_pathbuild(struct pathname *pnp)
355*7c478bd9Sstevel@tonic-gate {
356*7c478bd9Sstevel@tonic-gate 	char *pp;	/* pointer to path */
357*7c478bd9Sstevel@tonic-gate 	int len;	/* length of incoming segment */
358*7c478bd9Sstevel@tonic-gate 	int newsect;	/* path requires a new section */
359*7c478bd9Sstevel@tonic-gate 	struct audit_path	*pfxapp;	/* prefix for path */
360*7c478bd9Sstevel@tonic-gate 	struct audit_path	*newapp;	/* new audit_path */
361*7c478bd9Sstevel@tonic-gate 	t_audit_data_t *tad;	/* current thread */
362*7c478bd9Sstevel@tonic-gate 	p_audit_data_t *pad;	/* current process */
363*7c478bd9Sstevel@tonic-gate 
364*7c478bd9Sstevel@tonic-gate 	tad = U2A(u);
365*7c478bd9Sstevel@tonic-gate 	ASSERT(tad != NULL);
366*7c478bd9Sstevel@tonic-gate 	pad = P2A(curproc);
367*7c478bd9Sstevel@tonic-gate 	ASSERT(pad != NULL);
368*7c478bd9Sstevel@tonic-gate 
369*7c478bd9Sstevel@tonic-gate 	len = (pnp->pn_path - pnp->pn_buf) + 1;		/* +1 for terminator */
370*7c478bd9Sstevel@tonic-gate 	ASSERT(len > 0);
371*7c478bd9Sstevel@tonic-gate 
372*7c478bd9Sstevel@tonic-gate 	/* adjust for path prefix: tad_aupath, ATPATH, CRD, or CWD */
373*7c478bd9Sstevel@tonic-gate 	mutex_enter(&pad->pad_lock);
374*7c478bd9Sstevel@tonic-gate 	if (tad->tad_aupath != NULL) {
375*7c478bd9Sstevel@tonic-gate 		pfxapp = tad->tad_aupath;
376*7c478bd9Sstevel@tonic-gate 	} else if (tad->tad_scid == SYS_fsat && pnp->pn_buf[0] != '/') {
377*7c478bd9Sstevel@tonic-gate 		ASSERT(tad->tad_atpath != NULL);
378*7c478bd9Sstevel@tonic-gate 		pfxapp = tad->tad_atpath;
379*7c478bd9Sstevel@tonic-gate 	} else if (tad->tad_ctrl & PAD_ABSPATH) {
380*7c478bd9Sstevel@tonic-gate 		pfxapp = pad->pad_root;
381*7c478bd9Sstevel@tonic-gate 	} else {
382*7c478bd9Sstevel@tonic-gate 		pfxapp = pad->pad_cwd;
383*7c478bd9Sstevel@tonic-gate 	}
384*7c478bd9Sstevel@tonic-gate 	au_pathhold(pfxapp);
385*7c478bd9Sstevel@tonic-gate 	mutex_exit(&pad->pad_lock);
386*7c478bd9Sstevel@tonic-gate 
387*7c478bd9Sstevel@tonic-gate 	/* get an expanded buffer to hold the anchored path */
388*7c478bd9Sstevel@tonic-gate 	newsect = tad->tad_ctrl & PAD_ATPATH;
389*7c478bd9Sstevel@tonic-gate 	newapp = au_pathdup(pfxapp, newsect, len);
390*7c478bd9Sstevel@tonic-gate 	au_pathrele(pfxapp);
391*7c478bd9Sstevel@tonic-gate 
392*7c478bd9Sstevel@tonic-gate 	pp = newapp->audp_sect[newapp->audp_cnt] - len;
393*7c478bd9Sstevel@tonic-gate 	if (!newsect) {
394*7c478bd9Sstevel@tonic-gate 		/* overlay previous NUL terminator */
395*7c478bd9Sstevel@tonic-gate 		*(pp - 1) = '/';
396*7c478bd9Sstevel@tonic-gate 	}
397*7c478bd9Sstevel@tonic-gate 
398*7c478bd9Sstevel@tonic-gate 	/* now add string of processed path */
399*7c478bd9Sstevel@tonic-gate 	bcopy(pnp->pn_buf, pp, len);
400*7c478bd9Sstevel@tonic-gate 	pp[len - 1] = '\0';
401*7c478bd9Sstevel@tonic-gate 
402*7c478bd9Sstevel@tonic-gate 	/* perform path simplification as necessary */
403*7c478bd9Sstevel@tonic-gate 	audit_fixpath(newapp, len);
404*7c478bd9Sstevel@tonic-gate 
405*7c478bd9Sstevel@tonic-gate 	if (tad->tad_aupath)
406*7c478bd9Sstevel@tonic-gate 		au_pathrele(tad->tad_aupath);
407*7c478bd9Sstevel@tonic-gate 	tad->tad_aupath = newapp;
408*7c478bd9Sstevel@tonic-gate 
409*7c478bd9Sstevel@tonic-gate 	/* for case where multiple lookups in one syscall (rename) */
410*7c478bd9Sstevel@tonic-gate 	tad->tad_ctrl &= ~(PAD_ABSPATH | PAD_ATPATH);
411*7c478bd9Sstevel@tonic-gate }
412*7c478bd9Sstevel@tonic-gate 
413*7c478bd9Sstevel@tonic-gate 
414*7c478bd9Sstevel@tonic-gate 
415*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
416*7c478bd9Sstevel@tonic-gate 
417*7c478bd9Sstevel@tonic-gate /*
418*7c478bd9Sstevel@tonic-gate  * ROUTINE:	AUDIT_ADDCOMPONENT
419*7c478bd9Sstevel@tonic-gate  * PURPOSE:	extend the path by the component accepted
420*7c478bd9Sstevel@tonic-gate  * CALLBY:	LOOKUPPN
421*7c478bd9Sstevel@tonic-gate  * NOTE:	This function is called only when there is an error in
422*7c478bd9Sstevel@tonic-gate  *		parsing a path component
423*7c478bd9Sstevel@tonic-gate  * TODO:	Add the error component to audit record
424*7c478bd9Sstevel@tonic-gate  * QUESTION:	what is this for
425*7c478bd9Sstevel@tonic-gate  */
426*7c478bd9Sstevel@tonic-gate 
427*7c478bd9Sstevel@tonic-gate void
428*7c478bd9Sstevel@tonic-gate audit_addcomponent(struct pathname *pnp)
429*7c478bd9Sstevel@tonic-gate {
430*7c478bd9Sstevel@tonic-gate 	au_kcontext_t	*kctx = SET_KCTX_PZ;
431*7c478bd9Sstevel@tonic-gate 	t_audit_data_t *tad;
432*7c478bd9Sstevel@tonic-gate 
433*7c478bd9Sstevel@tonic-gate 	if (kctx == NULL) {
434*7c478bd9Sstevel@tonic-gate 		zone_status_t zstate = zone_status_get(curproc->p_zone);
435*7c478bd9Sstevel@tonic-gate 		ASSERT(zstate != ZONE_IS_READY);
436*7c478bd9Sstevel@tonic-gate 		return;
437*7c478bd9Sstevel@tonic-gate 	}
438*7c478bd9Sstevel@tonic-gate 
439*7c478bd9Sstevel@tonic-gate 	tad = U2A(u);
440*7c478bd9Sstevel@tonic-gate 	/*
441*7c478bd9Sstevel@tonic-gate 	 * S2E_SP (PAD_SAVPATH) flag comes from audit_s2e[].au_ctrl. Used with
442*7c478bd9Sstevel@tonic-gate 	 *	chroot, chdir, open, creat system call processing. It determines
443*7c478bd9Sstevel@tonic-gate 	 *	if audit_savepath() will discard the path or we need it later.
444*7c478bd9Sstevel@tonic-gate 	 * PAD_PATHFND means path already included in this audit record. It
445*7c478bd9Sstevel@tonic-gate 	 *	is used in cases where multiple path lookups are done per
446*7c478bd9Sstevel@tonic-gate 	 *	system call. The policy flag, AUDIT_PATH, controls if multiple
447*7c478bd9Sstevel@tonic-gate 	 *	paths are allowed.
448*7c478bd9Sstevel@tonic-gate 	 * S2E_NPT (PAD_NOPATH) flag comes from audit_s2e[].au_ctrl. Used with
449*7c478bd9Sstevel@tonic-gate 	 *	exit processing to inhibit any paths that may be added due to
450*7c478bd9Sstevel@tonic-gate 	 *	closes.
451*7c478bd9Sstevel@tonic-gate 	 */
452*7c478bd9Sstevel@tonic-gate 	if ((tad->tad_flag == 0 && !(tad->tad_ctrl & PAD_SAVPATH)) ||
453*7c478bd9Sstevel@tonic-gate 		((tad->tad_ctrl & PAD_PATHFND) &&
454*7c478bd9Sstevel@tonic-gate 		!(kctx->auk_policy & AUDIT_PATH)) ||
455*7c478bd9Sstevel@tonic-gate 		(tad->tad_ctrl & PAD_NOPATH)) {
456*7c478bd9Sstevel@tonic-gate 			return;
457*7c478bd9Sstevel@tonic-gate 	}
458*7c478bd9Sstevel@tonic-gate 
459*7c478bd9Sstevel@tonic-gate 	return;
460*7c478bd9Sstevel@tonic-gate 
461*7c478bd9Sstevel@tonic-gate }	/* AUDIT_ADDCOMPONENT */
462*7c478bd9Sstevel@tonic-gate 
463*7c478bd9Sstevel@tonic-gate 
464*7c478bd9Sstevel@tonic-gate 
465*7c478bd9Sstevel@tonic-gate 
466*7c478bd9Sstevel@tonic-gate 
467*7c478bd9Sstevel@tonic-gate 
468*7c478bd9Sstevel@tonic-gate 
469*7c478bd9Sstevel@tonic-gate 
470*7c478bd9Sstevel@tonic-gate /*
471*7c478bd9Sstevel@tonic-gate  * ROUTINE:	AUDIT_ANCHORPATH
472*7c478bd9Sstevel@tonic-gate  * PURPOSE:
473*7c478bd9Sstevel@tonic-gate  * CALLBY:	LOOKUPPN
474*7c478bd9Sstevel@tonic-gate  * NOTE:
475*7c478bd9Sstevel@tonic-gate  * anchor path at "/". We have seen a symbolic link or entering for the
476*7c478bd9Sstevel@tonic-gate  * first time we will throw away any saved path if path is anchored.
477*7c478bd9Sstevel@tonic-gate  *
478*7c478bd9Sstevel@tonic-gate  * flag = 0, path is relative.
479*7c478bd9Sstevel@tonic-gate  * flag = 1, path is absolute. Free any saved path and set flag to PAD_ABSPATH.
480*7c478bd9Sstevel@tonic-gate  *
481*7c478bd9Sstevel@tonic-gate  * If the (new) path is absolute, then we have to throw away whatever we have
482*7c478bd9Sstevel@tonic-gate  * already accumulated since it is being superceeded by new path which is
483*7c478bd9Sstevel@tonic-gate  * anchored at the root.
484*7c478bd9Sstevel@tonic-gate  *		Note that if the path is relative, this function does nothing
485*7c478bd9Sstevel@tonic-gate  * TODO:
486*7c478bd9Sstevel@tonic-gate  * QUESTION:
487*7c478bd9Sstevel@tonic-gate  */
488*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
489*7c478bd9Sstevel@tonic-gate void
490*7c478bd9Sstevel@tonic-gate audit_anchorpath(struct pathname *pnp, int flag)
491*7c478bd9Sstevel@tonic-gate {
492*7c478bd9Sstevel@tonic-gate 	au_kcontext_t	*kctx = SET_KCTX_PZ;
493*7c478bd9Sstevel@tonic-gate 	t_audit_data_t *tad;
494*7c478bd9Sstevel@tonic-gate 
495*7c478bd9Sstevel@tonic-gate 	if (kctx == NULL) {
496*7c478bd9Sstevel@tonic-gate 		zone_status_t zstate = zone_status_get(curproc->p_zone);
497*7c478bd9Sstevel@tonic-gate 		ASSERT(zstate != ZONE_IS_READY);
498*7c478bd9Sstevel@tonic-gate 		return;
499*7c478bd9Sstevel@tonic-gate 	}
500*7c478bd9Sstevel@tonic-gate 
501*7c478bd9Sstevel@tonic-gate 	tad = U2A(u);
502*7c478bd9Sstevel@tonic-gate 
503*7c478bd9Sstevel@tonic-gate 	/*
504*7c478bd9Sstevel@tonic-gate 	 * this event being audited or do we need path information
505*7c478bd9Sstevel@tonic-gate 	 * later? This might be for a chdir/chroot or open (add path
506*7c478bd9Sstevel@tonic-gate 	 * to file pointer. If the path has already been found for an
507*7c478bd9Sstevel@tonic-gate 	 * open/creat then we don't need to process the path.
508*7c478bd9Sstevel@tonic-gate 	 *
509*7c478bd9Sstevel@tonic-gate 	 * S2E_SP (PAD_SAVPATH) flag comes from audit_s2e[].au_ctrl. Used with
510*7c478bd9Sstevel@tonic-gate 	 *	chroot, chdir, open, creat system call processing. It determines
511*7c478bd9Sstevel@tonic-gate 	 *	if audit_savepath() will discard the path or we need it later.
512*7c478bd9Sstevel@tonic-gate 	 * PAD_PATHFND means path already included in this audit record. It
513*7c478bd9Sstevel@tonic-gate 	 *	is used in cases where multiple path lookups are done per
514*7c478bd9Sstevel@tonic-gate 	 *	system call. The policy flag, AUDIT_PATH, controls if multiple
515*7c478bd9Sstevel@tonic-gate 	 *	paths are allowed.
516*7c478bd9Sstevel@tonic-gate 	 * S2E_NPT (PAD_NOPATH) flag comes from audit_s2e[].au_ctrl. Used with
517*7c478bd9Sstevel@tonic-gate 	 *	exit processing to inhibit any paths that may be added due to
518*7c478bd9Sstevel@tonic-gate 	 *	closes.
519*7c478bd9Sstevel@tonic-gate 	 */
520*7c478bd9Sstevel@tonic-gate 	if ((tad->tad_flag == 0 && !(tad->tad_ctrl & PAD_SAVPATH)) ||
521*7c478bd9Sstevel@tonic-gate 		((tad->tad_ctrl & PAD_PATHFND) &&
522*7c478bd9Sstevel@tonic-gate 		!(kctx->auk_policy & AUDIT_PATH)) ||
523*7c478bd9Sstevel@tonic-gate 		(tad->tad_ctrl & PAD_NOPATH)) {
524*7c478bd9Sstevel@tonic-gate 			return;
525*7c478bd9Sstevel@tonic-gate 	}
526*7c478bd9Sstevel@tonic-gate 
527*7c478bd9Sstevel@tonic-gate 	if (flag) {
528*7c478bd9Sstevel@tonic-gate 		tad->tad_ctrl |= PAD_ABSPATH;
529*7c478bd9Sstevel@tonic-gate 		if (tad->tad_aupath != NULL) {
530*7c478bd9Sstevel@tonic-gate 			au_pathrele(tad->tad_aupath);
531*7c478bd9Sstevel@tonic-gate 			tad->tad_aupath = NULL;
532*7c478bd9Sstevel@tonic-gate 			tad->tad_vn = NULL;
533*7c478bd9Sstevel@tonic-gate 		}
534*7c478bd9Sstevel@tonic-gate 	}
535*7c478bd9Sstevel@tonic-gate }
536*7c478bd9Sstevel@tonic-gate 
537*7c478bd9Sstevel@tonic-gate 
538*7c478bd9Sstevel@tonic-gate /*
539*7c478bd9Sstevel@tonic-gate  * symbolic link. Save previous components.
540*7c478bd9Sstevel@tonic-gate  *
541*7c478bd9Sstevel@tonic-gate  * the path seen so far looks like this
542*7c478bd9Sstevel@tonic-gate  *
543*7c478bd9Sstevel@tonic-gate  *  +-----------------------+----------------+
544*7c478bd9Sstevel@tonic-gate  *  | path processed so far | remaining path |
545*7c478bd9Sstevel@tonic-gate  *  +-----------------------+----------------+
546*7c478bd9Sstevel@tonic-gate  *  \-----------------------/
547*7c478bd9Sstevel@tonic-gate  *	save this string if
548*7c478bd9Sstevel@tonic-gate  *	symbolic link relative
549*7c478bd9Sstevel@tonic-gate  *	(but don't include  symlink component)
550*7c478bd9Sstevel@tonic-gate  */
551*7c478bd9Sstevel@tonic-gate 
552*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
553*7c478bd9Sstevel@tonic-gate 
554*7c478bd9Sstevel@tonic-gate 
555*7c478bd9Sstevel@tonic-gate /*
556*7c478bd9Sstevel@tonic-gate  * ROUTINE:	AUDIT_SYMLINK
557*7c478bd9Sstevel@tonic-gate  * PURPOSE:
558*7c478bd9Sstevel@tonic-gate  * CALLBY:	LOOKUPPN
559*7c478bd9Sstevel@tonic-gate  * NOTE:
560*7c478bd9Sstevel@tonic-gate  * TODO:
561*7c478bd9Sstevel@tonic-gate  * QUESTION:
562*7c478bd9Sstevel@tonic-gate  */
563*7c478bd9Sstevel@tonic-gate void
564*7c478bd9Sstevel@tonic-gate audit_symlink(struct pathname *pnp, struct pathname *sympath)
565*7c478bd9Sstevel@tonic-gate {
566*7c478bd9Sstevel@tonic-gate 	char *sp;	/* saved initial pp */
567*7c478bd9Sstevel@tonic-gate 	char *cp;	/* start of symlink path */
568*7c478bd9Sstevel@tonic-gate 	uint_t len_path;	/* processed path before symlink */
569*7c478bd9Sstevel@tonic-gate 	t_audit_data_t *tad;
570*7c478bd9Sstevel@tonic-gate 	au_kcontext_t	*kctx = SET_KCTX_PZ;
571*7c478bd9Sstevel@tonic-gate 
572*7c478bd9Sstevel@tonic-gate 	if (kctx == NULL) {
573*7c478bd9Sstevel@tonic-gate 		zone_status_t zstate = zone_status_get(curproc->p_zone);
574*7c478bd9Sstevel@tonic-gate 		ASSERT(zstate != ZONE_IS_READY);
575*7c478bd9Sstevel@tonic-gate 		return;
576*7c478bd9Sstevel@tonic-gate 	}
577*7c478bd9Sstevel@tonic-gate 
578*7c478bd9Sstevel@tonic-gate 	tad = U2A(u);
579*7c478bd9Sstevel@tonic-gate 
580*7c478bd9Sstevel@tonic-gate 	/*
581*7c478bd9Sstevel@tonic-gate 	 * this event being audited or do we need path information
582*7c478bd9Sstevel@tonic-gate 	 * later? This might be for a chdir/chroot or open (add path
583*7c478bd9Sstevel@tonic-gate 	 * to file pointer. If the path has already been found for an
584*7c478bd9Sstevel@tonic-gate 	 * open/creat then we don't need to process the path.
585*7c478bd9Sstevel@tonic-gate 	 *
586*7c478bd9Sstevel@tonic-gate 	 * S2E_SP (PAD_SAVPATH) flag comes from audit_s2e[].au_ctrl. Used with
587*7c478bd9Sstevel@tonic-gate 	 *	chroot, chdir, open, creat system call processing. It determines
588*7c478bd9Sstevel@tonic-gate 	 *	if audit_savepath() will discard the path or we need it later.
589*7c478bd9Sstevel@tonic-gate 	 * PAD_PATHFND means path already included in this audit record. It
590*7c478bd9Sstevel@tonic-gate 	 *	is used in cases where multiple path lookups are done per
591*7c478bd9Sstevel@tonic-gate 	 *	system call. The policy flag, AUDIT_PATH, controls if multiple
592*7c478bd9Sstevel@tonic-gate 	 *	paths are allowed.
593*7c478bd9Sstevel@tonic-gate 	 * S2E_NPT (PAD_NOPATH) flag comes from audit_s2e[].au_ctrl. Used with
594*7c478bd9Sstevel@tonic-gate 	 *	exit processing to inhibit any paths that may be added due to
595*7c478bd9Sstevel@tonic-gate 	 *	closes.
596*7c478bd9Sstevel@tonic-gate 	 */
597*7c478bd9Sstevel@tonic-gate 	if ((tad->tad_flag == 0 &&
598*7c478bd9Sstevel@tonic-gate 		!(tad->tad_ctrl & PAD_SAVPATH)) ||
599*7c478bd9Sstevel@tonic-gate 		((tad->tad_ctrl & PAD_PATHFND) &&
600*7c478bd9Sstevel@tonic-gate 		!(kctx->auk_policy & AUDIT_PATH)) ||
601*7c478bd9Sstevel@tonic-gate 		(tad->tad_ctrl & PAD_NOPATH)) {
602*7c478bd9Sstevel@tonic-gate 			return;
603*7c478bd9Sstevel@tonic-gate 	}
604*7c478bd9Sstevel@tonic-gate 
605*7c478bd9Sstevel@tonic-gate 	/*
606*7c478bd9Sstevel@tonic-gate 	 * if symbolic link is anchored at / then do nothing.
607*7c478bd9Sstevel@tonic-gate 	 * When we cycle back to begin: in lookuppn() we will
608*7c478bd9Sstevel@tonic-gate 	 * call audit_anchorpath() with a flag indicating if the
609*7c478bd9Sstevel@tonic-gate 	 * path is anchored at / or is relative. We will release
610*7c478bd9Sstevel@tonic-gate 	 * any saved path at that point.
611*7c478bd9Sstevel@tonic-gate 	 *
612*7c478bd9Sstevel@tonic-gate 	 * Note In the event that an error occurs in pn_combine then
613*7c478bd9Sstevel@tonic-gate 	 * we want to remain pointing at the component that caused the
614*7c478bd9Sstevel@tonic-gate 	 * path to overflow the pnp structure.
615*7c478bd9Sstevel@tonic-gate 	 */
616*7c478bd9Sstevel@tonic-gate 	if (sympath->pn_buf[0] == '/')
617*7c478bd9Sstevel@tonic-gate 		return;
618*7c478bd9Sstevel@tonic-gate 
619*7c478bd9Sstevel@tonic-gate 	/* backup over last component */
620*7c478bd9Sstevel@tonic-gate 	sp = cp = pnp->pn_path;
621*7c478bd9Sstevel@tonic-gate 	while (*--cp != '/' && cp > pnp->pn_buf)
622*7c478bd9Sstevel@tonic-gate 		;
623*7c478bd9Sstevel@tonic-gate 
624*7c478bd9Sstevel@tonic-gate 	len_path = cp - pnp->pn_buf;
625*7c478bd9Sstevel@tonic-gate 
626*7c478bd9Sstevel@tonic-gate 	/* is there anything to save? */
627*7c478bd9Sstevel@tonic-gate 	if (len_path) {
628*7c478bd9Sstevel@tonic-gate 		pnp->pn_path = cp;
629*7c478bd9Sstevel@tonic-gate 		audit_pathbuild(pnp);
630*7c478bd9Sstevel@tonic-gate 		pnp->pn_path = sp;
631*7c478bd9Sstevel@tonic-gate 	}
632*7c478bd9Sstevel@tonic-gate }
633*7c478bd9Sstevel@tonic-gate 
634*7c478bd9Sstevel@tonic-gate /*
635*7c478bd9Sstevel@tonic-gate  * file_is_public : determine whether events for the file (corresponding to
636*7c478bd9Sstevel@tonic-gate  * 			the specified file attr) should be audited or ignored.
637*7c478bd9Sstevel@tonic-gate  *
638*7c478bd9Sstevel@tonic-gate  * returns: 	1 - if audit policy and file attributes indicate that
639*7c478bd9Sstevel@tonic-gate  *			file is effectively public. read events for
640*7c478bd9Sstevel@tonic-gate  *			the file should not be audited.
641*7c478bd9Sstevel@tonic-gate  *		0 - otherwise
642*7c478bd9Sstevel@tonic-gate  *
643*7c478bd9Sstevel@tonic-gate  * The required attributes to be considered a public object are:
644*7c478bd9Sstevel@tonic-gate  * - owned by root, AND
645*7c478bd9Sstevel@tonic-gate  * - world-readable (permissions for other include read), AND
646*7c478bd9Sstevel@tonic-gate  * - NOT world-writeable (permissions for other don't
647*7c478bd9Sstevel@tonic-gate  *	include write)
648*7c478bd9Sstevel@tonic-gate  *   (mode doesn't need to be checked for symlinks)
649*7c478bd9Sstevel@tonic-gate  */
650*7c478bd9Sstevel@tonic-gate int
651*7c478bd9Sstevel@tonic-gate file_is_public(struct vattr *attr)
652*7c478bd9Sstevel@tonic-gate {
653*7c478bd9Sstevel@tonic-gate 	au_kcontext_t	*kctx = SET_KCTX_PZ;
654*7c478bd9Sstevel@tonic-gate 
655*7c478bd9Sstevel@tonic-gate 	if (kctx == NULL) {
656*7c478bd9Sstevel@tonic-gate 		zone_status_t zstate = zone_status_get(curproc->p_zone);
657*7c478bd9Sstevel@tonic-gate 		ASSERT(zstate != ZONE_IS_READY);
658*7c478bd9Sstevel@tonic-gate 		return (0);
659*7c478bd9Sstevel@tonic-gate 	}
660*7c478bd9Sstevel@tonic-gate 
661*7c478bd9Sstevel@tonic-gate 	if (!(kctx->auk_policy & AUDIT_PUBLIC) && (attr->va_uid == 0) &&
662*7c478bd9Sstevel@tonic-gate 	    ((attr->va_type == VLNK) ||
663*7c478bd9Sstevel@tonic-gate 	    ((attr->va_mode & (VREAD>>6)) != 0) &&
664*7c478bd9Sstevel@tonic-gate 	    ((attr->va_mode & (VWRITE>>6)) == 0))) {
665*7c478bd9Sstevel@tonic-gate 		return (1);
666*7c478bd9Sstevel@tonic-gate 	}
667*7c478bd9Sstevel@tonic-gate 	return (0);
668*7c478bd9Sstevel@tonic-gate }
669*7c478bd9Sstevel@tonic-gate 
670*7c478bd9Sstevel@tonic-gate 
671*7c478bd9Sstevel@tonic-gate /*
672*7c478bd9Sstevel@tonic-gate  * ROUTINE:	AUDIT_ATTRIBUTES
673*7c478bd9Sstevel@tonic-gate  * PURPOSE:	Audit the attributes so we can tell why the error occured
674*7c478bd9Sstevel@tonic-gate  * CALLBY:	AUDIT_SAVEPATH
675*7c478bd9Sstevel@tonic-gate  *		AUDIT_VNCREATE_FINISH
676*7c478bd9Sstevel@tonic-gate  *		AUS_FCHOWN...audit_event.c...audit_path.c
677*7c478bd9Sstevel@tonic-gate  * NOTE:
678*7c478bd9Sstevel@tonic-gate  * TODO:
679*7c478bd9Sstevel@tonic-gate  * QUESTION:
680*7c478bd9Sstevel@tonic-gate  */
681*7c478bd9Sstevel@tonic-gate void
682*7c478bd9Sstevel@tonic-gate audit_attributes(struct vnode *vp)
683*7c478bd9Sstevel@tonic-gate {
684*7c478bd9Sstevel@tonic-gate 	struct vattr attr;
685*7c478bd9Sstevel@tonic-gate 	struct t_audit_data *tad;
686*7c478bd9Sstevel@tonic-gate 
687*7c478bd9Sstevel@tonic-gate 	tad = U2A(u);
688*7c478bd9Sstevel@tonic-gate 
689*7c478bd9Sstevel@tonic-gate 	if (vp) {
690*7c478bd9Sstevel@tonic-gate 		attr.va_mask = AT_ALL;
691*7c478bd9Sstevel@tonic-gate 		if (VOP_GETATTR(vp, &attr, 0, CRED()) != 0)
692*7c478bd9Sstevel@tonic-gate 			return;
693*7c478bd9Sstevel@tonic-gate 
694*7c478bd9Sstevel@tonic-gate 		if (file_is_public(&attr) && (tad->tad_ctrl & PAD_PUBLIC_EV)) {
695*7c478bd9Sstevel@tonic-gate 			/*
696*7c478bd9Sstevel@tonic-gate 			 * This is a public object and a "public" event
697*7c478bd9Sstevel@tonic-gate 			 * (i.e., read only) -- either by definition
698*7c478bd9Sstevel@tonic-gate 			 * (e.g., stat, access...) or by virtue of write access
699*7c478bd9Sstevel@tonic-gate 			 * not being requested (e.g. mmap).
700*7c478bd9Sstevel@tonic-gate 			 * Flag it in the tad to prevent this audit at the end.
701*7c478bd9Sstevel@tonic-gate 			 */
702*7c478bd9Sstevel@tonic-gate 			tad->tad_ctrl |= PAD_NOAUDIT;
703*7c478bd9Sstevel@tonic-gate 		} else {
704*7c478bd9Sstevel@tonic-gate 			au_uwrite(au_to_attr(&attr));
705*7c478bd9Sstevel@tonic-gate 		}
706*7c478bd9Sstevel@tonic-gate 	}
707*7c478bd9Sstevel@tonic-gate }
708*7c478bd9Sstevel@tonic-gate 
709*7c478bd9Sstevel@tonic-gate 
710*7c478bd9Sstevel@tonic-gate /*
711*7c478bd9Sstevel@tonic-gate  * ROUTINE:	AUDIT_FALLOC
712*7c478bd9Sstevel@tonic-gate  * PURPOSE:	allocating a new file structure
713*7c478bd9Sstevel@tonic-gate  * CALLBY:	FALLOC
714*7c478bd9Sstevel@tonic-gate  * NOTE:	file structure already initialized
715*7c478bd9Sstevel@tonic-gate  * TODO:
716*7c478bd9Sstevel@tonic-gate  * QUESTION:
717*7c478bd9Sstevel@tonic-gate  */
718*7c478bd9Sstevel@tonic-gate 
719*7c478bd9Sstevel@tonic-gate void
720*7c478bd9Sstevel@tonic-gate audit_falloc(struct file *fp)
721*7c478bd9Sstevel@tonic-gate {	/* AUDIT_FALLOC */
722*7c478bd9Sstevel@tonic-gate 
723*7c478bd9Sstevel@tonic-gate 	f_audit_data_t *fad;
724*7c478bd9Sstevel@tonic-gate 
725*7c478bd9Sstevel@tonic-gate 	/* allocate per file audit structure if there a'int any */
726*7c478bd9Sstevel@tonic-gate 	ASSERT(F2A(fp) == NULL);
727*7c478bd9Sstevel@tonic-gate 
728*7c478bd9Sstevel@tonic-gate 	fad = kmem_zalloc(sizeof (struct f_audit_data), KM_SLEEP);
729*7c478bd9Sstevel@tonic-gate 
730*7c478bd9Sstevel@tonic-gate 	F2A(fp) = fad;
731*7c478bd9Sstevel@tonic-gate 
732*7c478bd9Sstevel@tonic-gate 	fad->fad_thread = curthread; 	/* file audit data back ptr; DEBUG */
733*7c478bd9Sstevel@tonic-gate }
734*7c478bd9Sstevel@tonic-gate 
735*7c478bd9Sstevel@tonic-gate /*
736*7c478bd9Sstevel@tonic-gate  * ROUTINE:	AUDIT_UNFALLOC
737*7c478bd9Sstevel@tonic-gate  * PURPOSE:	deallocate file audit data structure
738*7c478bd9Sstevel@tonic-gate  * CALLBY:	CLOSEF
739*7c478bd9Sstevel@tonic-gate  *		UNFALLOC
740*7c478bd9Sstevel@tonic-gate  * NOTE:
741*7c478bd9Sstevel@tonic-gate  * TODO:
742*7c478bd9Sstevel@tonic-gate  * QUESTION:
743*7c478bd9Sstevel@tonic-gate  */
744*7c478bd9Sstevel@tonic-gate 
745*7c478bd9Sstevel@tonic-gate void
746*7c478bd9Sstevel@tonic-gate audit_unfalloc(struct file *fp)
747*7c478bd9Sstevel@tonic-gate {
748*7c478bd9Sstevel@tonic-gate 	f_audit_data_t *fad;
749*7c478bd9Sstevel@tonic-gate 
750*7c478bd9Sstevel@tonic-gate 	fad = F2A(fp);
751*7c478bd9Sstevel@tonic-gate 
752*7c478bd9Sstevel@tonic-gate 	if (!fad) {
753*7c478bd9Sstevel@tonic-gate 		return;
754*7c478bd9Sstevel@tonic-gate 	}
755*7c478bd9Sstevel@tonic-gate 	if (fad->fad_aupath != NULL) {
756*7c478bd9Sstevel@tonic-gate 		au_pathrele(fad->fad_aupath);
757*7c478bd9Sstevel@tonic-gate 	}
758*7c478bd9Sstevel@tonic-gate 	fp->f_audit_data = 0;
759*7c478bd9Sstevel@tonic-gate 	kmem_free(fad, sizeof (struct f_audit_data));
760*7c478bd9Sstevel@tonic-gate }
761*7c478bd9Sstevel@tonic-gate 
762*7c478bd9Sstevel@tonic-gate /*
763*7c478bd9Sstevel@tonic-gate  * ROUTINE:	AUDIT_EXIT
764*7c478bd9Sstevel@tonic-gate  * PURPOSE:
765*7c478bd9Sstevel@tonic-gate  * CALLBY:	EXIT
766*7c478bd9Sstevel@tonic-gate  * NOTE:
767*7c478bd9Sstevel@tonic-gate  * TODO:
768*7c478bd9Sstevel@tonic-gate  * QUESTION:	why cmw code as offset by 2 but not here
769*7c478bd9Sstevel@tonic-gate  */
770*7c478bd9Sstevel@tonic-gate /* ARGSUSED */
771*7c478bd9Sstevel@tonic-gate void
772*7c478bd9Sstevel@tonic-gate audit_exit(int code, int what)
773*7c478bd9Sstevel@tonic-gate {
774*7c478bd9Sstevel@tonic-gate 	struct t_audit_data *tad;
775*7c478bd9Sstevel@tonic-gate 	tad = U2A(u);
776*7c478bd9Sstevel@tonic-gate 
777*7c478bd9Sstevel@tonic-gate 	/*
778*7c478bd9Sstevel@tonic-gate 	 * tad_scid will be set by audit_start even if we are not auditing
779*7c478bd9Sstevel@tonic-gate 	 * the event.
780*7c478bd9Sstevel@tonic-gate 	 */
781*7c478bd9Sstevel@tonic-gate 	if (tad->tad_scid == SYS_exit) {
782*7c478bd9Sstevel@tonic-gate 		/*
783*7c478bd9Sstevel@tonic-gate 		 * if we are auditing the exit system call, then complete
784*7c478bd9Sstevel@tonic-gate 		 * audit record generation (no return from system call).
785*7c478bd9Sstevel@tonic-gate 		 */
786*7c478bd9Sstevel@tonic-gate 		if (tad->tad_flag && tad->tad_event == AUE_EXIT)
787*7c478bd9Sstevel@tonic-gate 			audit_finish(0, SYS_exit, 0, 0);
788*7c478bd9Sstevel@tonic-gate 		return;
789*7c478bd9Sstevel@tonic-gate 	}
790*7c478bd9Sstevel@tonic-gate 
791*7c478bd9Sstevel@tonic-gate 	/*
792*7c478bd9Sstevel@tonic-gate 	 * Anyone auditing the system call that was aborted?
793*7c478bd9Sstevel@tonic-gate 	 */
794*7c478bd9Sstevel@tonic-gate 	if (tad->tad_flag) {
795*7c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_text("event aborted"));
796*7c478bd9Sstevel@tonic-gate 		audit_finish(0, tad->tad_scid, 0, 0);
797*7c478bd9Sstevel@tonic-gate 	}
798*7c478bd9Sstevel@tonic-gate 
799*7c478bd9Sstevel@tonic-gate 	/*
800*7c478bd9Sstevel@tonic-gate 	 * Generate an audit record for process exit if preselected.
801*7c478bd9Sstevel@tonic-gate 	 */
802*7c478bd9Sstevel@tonic-gate 	(void) audit_start(0, SYS_exit, 0, 0);
803*7c478bd9Sstevel@tonic-gate 	audit_finish(0, SYS_exit, 0, 0);
804*7c478bd9Sstevel@tonic-gate }
805*7c478bd9Sstevel@tonic-gate 
806*7c478bd9Sstevel@tonic-gate /*
807*7c478bd9Sstevel@tonic-gate  * ROUTINE:	AUDIT_CORE_START
808*7c478bd9Sstevel@tonic-gate  * PURPOSE:
809*7c478bd9Sstevel@tonic-gate  * CALLBY: 	PSIG
810*7c478bd9Sstevel@tonic-gate  * NOTE:
811*7c478bd9Sstevel@tonic-gate  * TODO:
812*7c478bd9Sstevel@tonic-gate  */
813*7c478bd9Sstevel@tonic-gate void
814*7c478bd9Sstevel@tonic-gate audit_core_start(int sig)
815*7c478bd9Sstevel@tonic-gate {
816*7c478bd9Sstevel@tonic-gate 	au_event_t event;
817*7c478bd9Sstevel@tonic-gate 	au_state_t estate;
818*7c478bd9Sstevel@tonic-gate 	t_audit_data_t *tad;
819*7c478bd9Sstevel@tonic-gate 	au_kcontext_t	*kctx;
820*7c478bd9Sstevel@tonic-gate 
821*7c478bd9Sstevel@tonic-gate 	tad = U2A(u);
822*7c478bd9Sstevel@tonic-gate 
823*7c478bd9Sstevel@tonic-gate 	ASSERT(tad != (t_audit_data_t *)0);
824*7c478bd9Sstevel@tonic-gate 
825*7c478bd9Sstevel@tonic-gate 	ASSERT(tad->tad_scid == 0);
826*7c478bd9Sstevel@tonic-gate 	ASSERT(tad->tad_event == 0);
827*7c478bd9Sstevel@tonic-gate 	ASSERT(tad->tad_evmod == 0);
828*7c478bd9Sstevel@tonic-gate 	ASSERT(tad->tad_ctrl == 0);
829*7c478bd9Sstevel@tonic-gate 	ASSERT(tad->tad_flag == 0);
830*7c478bd9Sstevel@tonic-gate 	ASSERT(tad->tad_aupath == NULL);
831*7c478bd9Sstevel@tonic-gate 
832*7c478bd9Sstevel@tonic-gate 	kctx = SET_KCTX_PZ;
833*7c478bd9Sstevel@tonic-gate 
834*7c478bd9Sstevel@tonic-gate 	if (kctx == NULL) {
835*7c478bd9Sstevel@tonic-gate 		zone_status_t zstate = zone_status_get(curproc->p_zone);
836*7c478bd9Sstevel@tonic-gate 		ASSERT(zstate != ZONE_IS_READY);
837*7c478bd9Sstevel@tonic-gate 		return;
838*7c478bd9Sstevel@tonic-gate 	}
839*7c478bd9Sstevel@tonic-gate 
840*7c478bd9Sstevel@tonic-gate 	/* get basic event for system call */
841*7c478bd9Sstevel@tonic-gate 	event = AUE_CORE;
842*7c478bd9Sstevel@tonic-gate 	estate = kctx->auk_ets[event];
843*7c478bd9Sstevel@tonic-gate 
844*7c478bd9Sstevel@tonic-gate 	if ((tad->tad_flag = auditme(kctx, tad, estate)) == 0)
845*7c478bd9Sstevel@tonic-gate 		return;
846*7c478bd9Sstevel@tonic-gate 
847*7c478bd9Sstevel@tonic-gate 	/* reset the flags for non-user attributable events */
848*7c478bd9Sstevel@tonic-gate 	tad->tad_ctrl   = PAD_CORE;
849*7c478bd9Sstevel@tonic-gate 	tad->tad_scid   = 0;
850*7c478bd9Sstevel@tonic-gate 
851*7c478bd9Sstevel@tonic-gate 	/* if auditing not enabled, then don't generate an audit record */
852*7c478bd9Sstevel@tonic-gate 
853*7c478bd9Sstevel@tonic-gate 	if (!((kctx->auk_auditstate == AUC_AUDITING ||
854*7c478bd9Sstevel@tonic-gate 	    kctx->auk_auditstate == AUC_INIT_AUDIT) ||
855*7c478bd9Sstevel@tonic-gate 	    kctx->auk_auditstate == AUC_NOSPACE)) {
856*7c478bd9Sstevel@tonic-gate 		tad->tad_flag = 0;
857*7c478bd9Sstevel@tonic-gate 		tad->tad_ctrl = 0;
858*7c478bd9Sstevel@tonic-gate 		return;
859*7c478bd9Sstevel@tonic-gate 	}
860*7c478bd9Sstevel@tonic-gate 
861*7c478bd9Sstevel@tonic-gate 	tad->tad_event  = event;
862*7c478bd9Sstevel@tonic-gate 	tad->tad_evmod  = 0;
863*7c478bd9Sstevel@tonic-gate 
864*7c478bd9Sstevel@tonic-gate 	ASSERT(tad->tad_ad == NULL);
865*7c478bd9Sstevel@tonic-gate 
866*7c478bd9Sstevel@tonic-gate 	au_write(&(u_ad), au_to_arg32(1, "signal", (uint32_t)sig));
867*7c478bd9Sstevel@tonic-gate }
868*7c478bd9Sstevel@tonic-gate 
869*7c478bd9Sstevel@tonic-gate /*
870*7c478bd9Sstevel@tonic-gate  * ROUTINE:	AUDIT_CORE_FINISH
871*7c478bd9Sstevel@tonic-gate  * PURPOSE:
872*7c478bd9Sstevel@tonic-gate  * CALLBY:	PSIG
873*7c478bd9Sstevel@tonic-gate  * NOTE:
874*7c478bd9Sstevel@tonic-gate  * TODO:
875*7c478bd9Sstevel@tonic-gate  * QUESTION:
876*7c478bd9Sstevel@tonic-gate  */
877*7c478bd9Sstevel@tonic-gate 
878*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
879*7c478bd9Sstevel@tonic-gate void
880*7c478bd9Sstevel@tonic-gate audit_core_finish(int code)
881*7c478bd9Sstevel@tonic-gate {
882*7c478bd9Sstevel@tonic-gate 	int flag;
883*7c478bd9Sstevel@tonic-gate 	t_audit_data_t *tad;
884*7c478bd9Sstevel@tonic-gate 	au_kcontext_t	*kctx;
885*7c478bd9Sstevel@tonic-gate 
886*7c478bd9Sstevel@tonic-gate 	tad = U2A(u);
887*7c478bd9Sstevel@tonic-gate 
888*7c478bd9Sstevel@tonic-gate 	ASSERT(tad != (t_audit_data_t *)0);
889*7c478bd9Sstevel@tonic-gate 
890*7c478bd9Sstevel@tonic-gate 	if ((flag = tad->tad_flag) == 0) {
891*7c478bd9Sstevel@tonic-gate 		tad->tad_event = 0;
892*7c478bd9Sstevel@tonic-gate 		tad->tad_evmod = 0;
893*7c478bd9Sstevel@tonic-gate 		tad->tad_ctrl  = 0;
894*7c478bd9Sstevel@tonic-gate 		ASSERT(tad->tad_aupath == NULL);
895*7c478bd9Sstevel@tonic-gate 		return;
896*7c478bd9Sstevel@tonic-gate 	}
897*7c478bd9Sstevel@tonic-gate 	tad->tad_flag = 0;
898*7c478bd9Sstevel@tonic-gate 
899*7c478bd9Sstevel@tonic-gate 	kctx = SET_KCTX_PZ;
900*7c478bd9Sstevel@tonic-gate 	if (kctx == NULL) {
901*7c478bd9Sstevel@tonic-gate 		zone_status_t zstate = zone_status_get(curproc->p_zone);
902*7c478bd9Sstevel@tonic-gate 		ASSERT(zstate != ZONE_IS_READY);
903*7c478bd9Sstevel@tonic-gate 		return;
904*7c478bd9Sstevel@tonic-gate 	}
905*7c478bd9Sstevel@tonic-gate 
906*7c478bd9Sstevel@tonic-gate 	/* kludge for error 0, should use `code==CLD_DUMPED' instead */
907*7c478bd9Sstevel@tonic-gate 	if (flag = audit_success(kctx, tad, 0)) {
908*7c478bd9Sstevel@tonic-gate 		cred_t *cr = CRED();
909*7c478bd9Sstevel@tonic-gate 		const auditinfo_addr_t *ainfo = crgetauinfo(cr);
910*7c478bd9Sstevel@tonic-gate 
911*7c478bd9Sstevel@tonic-gate 		ASSERT(ainfo != NULL);
912*7c478bd9Sstevel@tonic-gate 
913*7c478bd9Sstevel@tonic-gate 		/*
914*7c478bd9Sstevel@tonic-gate 		 * Add a subject token (no locks since our private copy of
915*7c478bd9Sstevel@tonic-gate 		 * credential
916*7c478bd9Sstevel@tonic-gate 		 */
917*7c478bd9Sstevel@tonic-gate 		AUDIT_SETSUBJ(&(u_ad), cr, ainfo);
918*7c478bd9Sstevel@tonic-gate 
919*7c478bd9Sstevel@tonic-gate 		/* Add an optional group token */
920*7c478bd9Sstevel@tonic-gate 		AUDIT_SETGROUP(&(u_ad), cr, kctx);
921*7c478bd9Sstevel@tonic-gate 
922*7c478bd9Sstevel@tonic-gate 		/* Add a return token (should use f argument) */
923*7c478bd9Sstevel@tonic-gate 		add_return_token((caddr_t *)&(u_ad), tad->tad_scid, 0, 0);
924*7c478bd9Sstevel@tonic-gate 
925*7c478bd9Sstevel@tonic-gate 		AS_INC(as_generated, 1, kctx);
926*7c478bd9Sstevel@tonic-gate 		AS_INC(as_kernel, 1, kctx);
927*7c478bd9Sstevel@tonic-gate 	}
928*7c478bd9Sstevel@tonic-gate 
929*7c478bd9Sstevel@tonic-gate 	/* Close up everything */
930*7c478bd9Sstevel@tonic-gate 	au_close(kctx, &(u_ad), flag, tad->tad_event, tad->tad_evmod);
931*7c478bd9Sstevel@tonic-gate 
932*7c478bd9Sstevel@tonic-gate 	/* free up any space remaining with the path's */
933*7c478bd9Sstevel@tonic-gate 	if (tad->tad_aupath != NULL) {
934*7c478bd9Sstevel@tonic-gate 		au_pathrele(tad->tad_aupath);
935*7c478bd9Sstevel@tonic-gate 		tad->tad_aupath = NULL;
936*7c478bd9Sstevel@tonic-gate 		tad->tad_vn = NULL;
937*7c478bd9Sstevel@tonic-gate 	}
938*7c478bd9Sstevel@tonic-gate 	tad->tad_event = 0;
939*7c478bd9Sstevel@tonic-gate 	tad->tad_evmod = 0;
940*7c478bd9Sstevel@tonic-gate 	tad->tad_ctrl  = 0;
941*7c478bd9Sstevel@tonic-gate }
942*7c478bd9Sstevel@tonic-gate 
943*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
944*7c478bd9Sstevel@tonic-gate void
945*7c478bd9Sstevel@tonic-gate audit_stropen(struct vnode *vp, dev_t *devp, int flag, cred_t *crp)
946*7c478bd9Sstevel@tonic-gate {
947*7c478bd9Sstevel@tonic-gate }
948*7c478bd9Sstevel@tonic-gate 
949*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
950*7c478bd9Sstevel@tonic-gate void
951*7c478bd9Sstevel@tonic-gate audit_strclose(struct vnode *vp, int flag, cred_t *crp)
952*7c478bd9Sstevel@tonic-gate {
953*7c478bd9Sstevel@tonic-gate }
954*7c478bd9Sstevel@tonic-gate 
955*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
956*7c478bd9Sstevel@tonic-gate void
957*7c478bd9Sstevel@tonic-gate audit_strioctl(struct vnode *vp, int cmd, intptr_t arg, int flag,
958*7c478bd9Sstevel@tonic-gate     int copyflag, cred_t *crp, int *rvalp)
959*7c478bd9Sstevel@tonic-gate {
960*7c478bd9Sstevel@tonic-gate }
961*7c478bd9Sstevel@tonic-gate 
962*7c478bd9Sstevel@tonic-gate 
963*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
964*7c478bd9Sstevel@tonic-gate void
965*7c478bd9Sstevel@tonic-gate audit_strgetmsg(struct vnode *vp, struct strbuf *mctl, struct strbuf *mdata,
966*7c478bd9Sstevel@tonic-gate     unsigned char *pri, int *flag, int fmode)
967*7c478bd9Sstevel@tonic-gate {
968*7c478bd9Sstevel@tonic-gate 	struct stdata *stp;
969*7c478bd9Sstevel@tonic-gate 	t_audit_data_t *tad = U2A(u);
970*7c478bd9Sstevel@tonic-gate 
971*7c478bd9Sstevel@tonic-gate 	ASSERT(tad != (t_audit_data_t *)0);
972*7c478bd9Sstevel@tonic-gate 
973*7c478bd9Sstevel@tonic-gate 	stp = vp->v_stream;
974*7c478bd9Sstevel@tonic-gate 
975*7c478bd9Sstevel@tonic-gate 	/* lock stdata from audit_sock */
976*7c478bd9Sstevel@tonic-gate 	mutex_enter(&stp->sd_lock);
977*7c478bd9Sstevel@tonic-gate 
978*7c478bd9Sstevel@tonic-gate 	/* proceed ONLY if user is being audited */
979*7c478bd9Sstevel@tonic-gate 	if (!tad->tad_flag) {
980*7c478bd9Sstevel@tonic-gate 		/*
981*7c478bd9Sstevel@tonic-gate 		 * this is so we will not add audit data onto
982*7c478bd9Sstevel@tonic-gate 		 * a thread that is not being audited.
983*7c478bd9Sstevel@tonic-gate 		 */
984*7c478bd9Sstevel@tonic-gate 		stp->sd_t_audit_data = NULL;
985*7c478bd9Sstevel@tonic-gate 		mutex_exit(&stp->sd_lock);
986*7c478bd9Sstevel@tonic-gate 		return;
987*7c478bd9Sstevel@tonic-gate 	}
988*7c478bd9Sstevel@tonic-gate 
989*7c478bd9Sstevel@tonic-gate 	stp->sd_t_audit_data = (caddr_t)curthread;
990*7c478bd9Sstevel@tonic-gate 	mutex_exit(&stp->sd_lock);
991*7c478bd9Sstevel@tonic-gate }
992*7c478bd9Sstevel@tonic-gate 
993*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
994*7c478bd9Sstevel@tonic-gate void
995*7c478bd9Sstevel@tonic-gate audit_strputmsg(struct vnode *vp, struct strbuf *mctl, struct strbuf *mdata,
996*7c478bd9Sstevel@tonic-gate     unsigned char pri, int flag, int fmode)
997*7c478bd9Sstevel@tonic-gate {
998*7c478bd9Sstevel@tonic-gate 	struct stdata *stp;
999*7c478bd9Sstevel@tonic-gate 	t_audit_data_t *tad = U2A(u);
1000*7c478bd9Sstevel@tonic-gate 
1001*7c478bd9Sstevel@tonic-gate 	ASSERT(tad != (t_audit_data_t *)0);
1002*7c478bd9Sstevel@tonic-gate 
1003*7c478bd9Sstevel@tonic-gate 	stp = vp->v_stream;
1004*7c478bd9Sstevel@tonic-gate 
1005*7c478bd9Sstevel@tonic-gate 	/* lock stdata from audit_sock */
1006*7c478bd9Sstevel@tonic-gate 	mutex_enter(&stp->sd_lock);
1007*7c478bd9Sstevel@tonic-gate 
1008*7c478bd9Sstevel@tonic-gate 	/* proceed ONLY if user is being audited */
1009*7c478bd9Sstevel@tonic-gate 	if (!tad->tad_flag) {
1010*7c478bd9Sstevel@tonic-gate 		/*
1011*7c478bd9Sstevel@tonic-gate 		 * this is so we will not add audit data onto
1012*7c478bd9Sstevel@tonic-gate 		 * a thread that is not being audited.
1013*7c478bd9Sstevel@tonic-gate 		 */
1014*7c478bd9Sstevel@tonic-gate 		stp->sd_t_audit_data = NULL;
1015*7c478bd9Sstevel@tonic-gate 		mutex_exit(&stp->sd_lock);
1016*7c478bd9Sstevel@tonic-gate 		return;
1017*7c478bd9Sstevel@tonic-gate 	}
1018*7c478bd9Sstevel@tonic-gate 
1019*7c478bd9Sstevel@tonic-gate 	stp->sd_t_audit_data = (caddr_t)curthread;
1020*7c478bd9Sstevel@tonic-gate 	mutex_exit(&stp->sd_lock);
1021*7c478bd9Sstevel@tonic-gate }
1022*7c478bd9Sstevel@tonic-gate 
1023*7c478bd9Sstevel@tonic-gate /*
1024*7c478bd9Sstevel@tonic-gate  * ROUTINE:	AUDIT_CLOSEF
1025*7c478bd9Sstevel@tonic-gate  * PURPOSE:
1026*7c478bd9Sstevel@tonic-gate  * CALLBY:	CLOSEF
1027*7c478bd9Sstevel@tonic-gate  * NOTE:
1028*7c478bd9Sstevel@tonic-gate  * release per file audit resources when file structure is being released.
1029*7c478bd9Sstevel@tonic-gate  *
1030*7c478bd9Sstevel@tonic-gate  * IMPORTANT NOTE: Since we generate an audit record here, we may sleep
1031*7c478bd9Sstevel@tonic-gate  *	on the audit queue if it becomes full. This means
1032*7c478bd9Sstevel@tonic-gate  *	audit_closef can not be called when f_count == 0. Since
1033*7c478bd9Sstevel@tonic-gate  *	f_count == 0 indicates the file structure is free, another
1034*7c478bd9Sstevel@tonic-gate  *	process could attempt to use the file while we were still
1035*7c478bd9Sstevel@tonic-gate  *	asleep waiting on the audit queue. This would cause the
1036*7c478bd9Sstevel@tonic-gate  *	per file audit data to be corrupted when we finally do
1037*7c478bd9Sstevel@tonic-gate  *	wakeup.
1038*7c478bd9Sstevel@tonic-gate  * TODO:
1039*7c478bd9Sstevel@tonic-gate  * QUESTION:
1040*7c478bd9Sstevel@tonic-gate  */
1041*7c478bd9Sstevel@tonic-gate 
1042*7c478bd9Sstevel@tonic-gate void
1043*7c478bd9Sstevel@tonic-gate audit_closef(struct file *fp)
1044*7c478bd9Sstevel@tonic-gate {	/* AUDIT_CLOSEF */
1045*7c478bd9Sstevel@tonic-gate 	f_audit_data_t *fad;
1046*7c478bd9Sstevel@tonic-gate 	t_audit_data_t *tad;
1047*7c478bd9Sstevel@tonic-gate 	int success;
1048*7c478bd9Sstevel@tonic-gate 	au_state_t estate;
1049*7c478bd9Sstevel@tonic-gate 	struct vnode *vp;
1050*7c478bd9Sstevel@tonic-gate 	token_t *ad = NULL;
1051*7c478bd9Sstevel@tonic-gate 	struct vattr attr;
1052*7c478bd9Sstevel@tonic-gate 	short evmod = 0;
1053*7c478bd9Sstevel@tonic-gate 	const auditinfo_addr_t *ainfo;
1054*7c478bd9Sstevel@tonic-gate 	int getattr_ret;
1055*7c478bd9Sstevel@tonic-gate 	cred_t *cr;
1056*7c478bd9Sstevel@tonic-gate 	au_kcontext_t	*kctx = SET_KCTX_PZ;
1057*7c478bd9Sstevel@tonic-gate 
1058*7c478bd9Sstevel@tonic-gate 	if (kctx == NULL) {
1059*7c478bd9Sstevel@tonic-gate 		zone_status_t zstate = zone_status_get(curproc->p_zone);
1060*7c478bd9Sstevel@tonic-gate 		ASSERT(zstate != ZONE_IS_READY);
1061*7c478bd9Sstevel@tonic-gate 		return;
1062*7c478bd9Sstevel@tonic-gate 	}
1063*7c478bd9Sstevel@tonic-gate 
1064*7c478bd9Sstevel@tonic-gate 	fad = F2A(fp);
1065*7c478bd9Sstevel@tonic-gate 	estate = kctx->auk_ets[AUE_CLOSE];
1066*7c478bd9Sstevel@tonic-gate 	tad = U2A(u);
1067*7c478bd9Sstevel@tonic-gate 	cr = CRED();
1068*7c478bd9Sstevel@tonic-gate 
1069*7c478bd9Sstevel@tonic-gate 	/* audit record already generated by system call envelope */
1070*7c478bd9Sstevel@tonic-gate 	if (tad->tad_event == AUE_CLOSE) {
1071*7c478bd9Sstevel@tonic-gate 		/* so close audit event will have bits set */
1072*7c478bd9Sstevel@tonic-gate 		tad->tad_evmod |= (short)fad->fad_flags;
1073*7c478bd9Sstevel@tonic-gate 		return;
1074*7c478bd9Sstevel@tonic-gate 	}
1075*7c478bd9Sstevel@tonic-gate 
1076*7c478bd9Sstevel@tonic-gate 	/* if auditing not enabled, then don't generate an audit record */
1077*7c478bd9Sstevel@tonic-gate 	if (!((kctx->auk_auditstate == AUC_AUDITING ||
1078*7c478bd9Sstevel@tonic-gate 	    kctx->auk_auditstate == AUC_INIT_AUDIT) ||
1079*7c478bd9Sstevel@tonic-gate 	    kctx->auk_auditstate == AUC_NOSPACE))
1080*7c478bd9Sstevel@tonic-gate 		return;
1081*7c478bd9Sstevel@tonic-gate 
1082*7c478bd9Sstevel@tonic-gate 	ainfo = crgetauinfo(cr);
1083*7c478bd9Sstevel@tonic-gate 	if (ainfo == NULL)
1084*7c478bd9Sstevel@tonic-gate 		return;
1085*7c478bd9Sstevel@tonic-gate 
1086*7c478bd9Sstevel@tonic-gate 	success = ainfo->ai_mask.as_success & estate;
1087*7c478bd9Sstevel@tonic-gate 
1088*7c478bd9Sstevel@tonic-gate 	/* not selected for this event */
1089*7c478bd9Sstevel@tonic-gate 	if (success == 0)
1090*7c478bd9Sstevel@tonic-gate 		return;
1091*7c478bd9Sstevel@tonic-gate 
1092*7c478bd9Sstevel@tonic-gate 	/*
1093*7c478bd9Sstevel@tonic-gate 	 * can't use audit_attributes here since we use a private audit area
1094*7c478bd9Sstevel@tonic-gate 	 * to build the audit record instead of the one off the thread.
1095*7c478bd9Sstevel@tonic-gate 	 */
1096*7c478bd9Sstevel@tonic-gate 	if ((vp = fp->f_vnode) != NULL) {
1097*7c478bd9Sstevel@tonic-gate 		attr.va_mask = AT_ALL;
1098*7c478bd9Sstevel@tonic-gate 		getattr_ret = VOP_GETATTR(vp, &attr, 0, CRED());
1099*7c478bd9Sstevel@tonic-gate 	}
1100*7c478bd9Sstevel@tonic-gate 
1101*7c478bd9Sstevel@tonic-gate 	/*
1102*7c478bd9Sstevel@tonic-gate 	 * When write was not used and the file can be considered public,
1103*7c478bd9Sstevel@tonic-gate 	 * then skip the audit.
1104*7c478bd9Sstevel@tonic-gate 	 */
1105*7c478bd9Sstevel@tonic-gate 	if ((getattr_ret == 0) && ((fp->f_flag & FWRITE) == 0)) {
1106*7c478bd9Sstevel@tonic-gate 		if (file_is_public(&attr)) {
1107*7c478bd9Sstevel@tonic-gate 			return;
1108*7c478bd9Sstevel@tonic-gate 		}
1109*7c478bd9Sstevel@tonic-gate 	}
1110*7c478bd9Sstevel@tonic-gate 
1111*7c478bd9Sstevel@tonic-gate 	evmod = (short)fad->fad_flags;
1112*7c478bd9Sstevel@tonic-gate 	if (fad->fad_aupath != NULL) {
1113*7c478bd9Sstevel@tonic-gate 		au_write((caddr_t *)&(ad), au_to_path(fad->fad_aupath));
1114*7c478bd9Sstevel@tonic-gate 	} else {
1115*7c478bd9Sstevel@tonic-gate #ifdef _LP64
1116*7c478bd9Sstevel@tonic-gate 		au_write((caddr_t *)&(ad), au_to_arg64(
1117*7c478bd9Sstevel@tonic-gate 			1, "no path: fp", (uint64_t)fp));
1118*7c478bd9Sstevel@tonic-gate #else
1119*7c478bd9Sstevel@tonic-gate 		au_write((caddr_t *)&(ad), au_to_arg32(
1120*7c478bd9Sstevel@tonic-gate 			1, "no path: fp", (uint32_t)fp));
1121*7c478bd9Sstevel@tonic-gate #endif
1122*7c478bd9Sstevel@tonic-gate 	}
1123*7c478bd9Sstevel@tonic-gate 
1124*7c478bd9Sstevel@tonic-gate 	if (getattr_ret == 0) {
1125*7c478bd9Sstevel@tonic-gate 		au_write((caddr_t *)&(ad), au_to_attr(&attr));
1126*7c478bd9Sstevel@tonic-gate 	}
1127*7c478bd9Sstevel@tonic-gate 
1128*7c478bd9Sstevel@tonic-gate 	/* Add a subject token */
1129*7c478bd9Sstevel@tonic-gate 	AUDIT_SETSUBJ((caddr_t *)&(ad), cr, ainfo);
1130*7c478bd9Sstevel@tonic-gate 
1131*7c478bd9Sstevel@tonic-gate 	/* add an optional group token */
1132*7c478bd9Sstevel@tonic-gate 	AUDIT_SETGROUP((caddr_t *)&(ad), cr, kctx);
1133*7c478bd9Sstevel@tonic-gate 
1134*7c478bd9Sstevel@tonic-gate 	/* add a return token */
1135*7c478bd9Sstevel@tonic-gate 	add_return_token((caddr_t *)&(ad), tad->tad_scid, 0, 0);
1136*7c478bd9Sstevel@tonic-gate 
1137*7c478bd9Sstevel@tonic-gate 	AS_INC(as_generated, 1, kctx);
1138*7c478bd9Sstevel@tonic-gate 	AS_INC(as_kernel, 1, kctx);
1139*7c478bd9Sstevel@tonic-gate 
1140*7c478bd9Sstevel@tonic-gate 	/*
1141*7c478bd9Sstevel@tonic-gate 	 * Close up everything
1142*7c478bd9Sstevel@tonic-gate 	 * Note: path space recovery handled by normal system
1143*7c478bd9Sstevel@tonic-gate 	 * call envelope if not at last close.
1144*7c478bd9Sstevel@tonic-gate 	 * Note there is no failure at this point since
1145*7c478bd9Sstevel@tonic-gate 	 *   this represents closes due to exit of process,
1146*7c478bd9Sstevel@tonic-gate 	 *   thus we always indicate successful closes.
1147*7c478bd9Sstevel@tonic-gate 	 */
1148*7c478bd9Sstevel@tonic-gate 	au_close(kctx, (caddr_t *)&(ad), AU_OK | AU_DEFER,
1149*7c478bd9Sstevel@tonic-gate 	    AUE_CLOSE, evmod);
1150*7c478bd9Sstevel@tonic-gate }
1151*7c478bd9Sstevel@tonic-gate 
1152*7c478bd9Sstevel@tonic-gate /*
1153*7c478bd9Sstevel@tonic-gate  * ROUTINE:	AUDIT_SET
1154*7c478bd9Sstevel@tonic-gate  * PURPOSE:	Audit the file path and file attributes.
1155*7c478bd9Sstevel@tonic-gate  * CALLBY:	SETF
1156*7c478bd9Sstevel@tonic-gate  * NOTE:	SETF associate a file pointer with user area's open files.
1157*7c478bd9Sstevel@tonic-gate  * TODO:
1158*7c478bd9Sstevel@tonic-gate  * call audit_finish directly ???
1159*7c478bd9Sstevel@tonic-gate  * QUESTION:
1160*7c478bd9Sstevel@tonic-gate  */
1161*7c478bd9Sstevel@tonic-gate 
1162*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
1163*7c478bd9Sstevel@tonic-gate void
1164*7c478bd9Sstevel@tonic-gate audit_setf(file_t *fp, int fd)
1165*7c478bd9Sstevel@tonic-gate {
1166*7c478bd9Sstevel@tonic-gate 	f_audit_data_t *fad;
1167*7c478bd9Sstevel@tonic-gate 	t_audit_data_t *tad;
1168*7c478bd9Sstevel@tonic-gate 
1169*7c478bd9Sstevel@tonic-gate 	if (fp == NULL)
1170*7c478bd9Sstevel@tonic-gate 		return;
1171*7c478bd9Sstevel@tonic-gate 
1172*7c478bd9Sstevel@tonic-gate 	tad = T2A(curthread);
1173*7c478bd9Sstevel@tonic-gate 	fad = F2A(fp);
1174*7c478bd9Sstevel@tonic-gate 
1175*7c478bd9Sstevel@tonic-gate 	if (!(tad->tad_scid == SYS_open || tad->tad_scid == SYS_creat ||
1176*7c478bd9Sstevel@tonic-gate 	    tad->tad_scid == SYS_open64 || tad->tad_scid == SYS_creat64 ||
1177*7c478bd9Sstevel@tonic-gate 	    tad->tad_scid == SYS_fsat))
1178*7c478bd9Sstevel@tonic-gate 		return;
1179*7c478bd9Sstevel@tonic-gate 
1180*7c478bd9Sstevel@tonic-gate 	/* no path */
1181*7c478bd9Sstevel@tonic-gate 	if (tad->tad_aupath == 0)
1182*7c478bd9Sstevel@tonic-gate 		return;
1183*7c478bd9Sstevel@tonic-gate 
1184*7c478bd9Sstevel@tonic-gate 	/*
1185*7c478bd9Sstevel@tonic-gate 	 * assign path information associated with file audit data
1186*7c478bd9Sstevel@tonic-gate 	 * use tad hold
1187*7c478bd9Sstevel@tonic-gate 	 */
1188*7c478bd9Sstevel@tonic-gate 	fad->fad_aupath = tad->tad_aupath;
1189*7c478bd9Sstevel@tonic-gate 	tad->tad_aupath = NULL;
1190*7c478bd9Sstevel@tonic-gate 	tad->tad_vn = NULL;
1191*7c478bd9Sstevel@tonic-gate 
1192*7c478bd9Sstevel@tonic-gate 	if (!(tad->tad_ctrl & PAD_TRUE_CREATE)) {
1193*7c478bd9Sstevel@tonic-gate 	/* adjust event type */
1194*7c478bd9Sstevel@tonic-gate 		switch (tad->tad_event) {
1195*7c478bd9Sstevel@tonic-gate 		case AUE_OPEN_RC:
1196*7c478bd9Sstevel@tonic-gate 			tad->tad_event = AUE_OPEN_R;
1197*7c478bd9Sstevel@tonic-gate 			tad->tad_ctrl |= PAD_PUBLIC_EV;
1198*7c478bd9Sstevel@tonic-gate 			break;
1199*7c478bd9Sstevel@tonic-gate 		case AUE_OPEN_RTC:
1200*7c478bd9Sstevel@tonic-gate 			tad->tad_event = AUE_OPEN_RT;
1201*7c478bd9Sstevel@tonic-gate 			break;
1202*7c478bd9Sstevel@tonic-gate 		case AUE_OPEN_WC:
1203*7c478bd9Sstevel@tonic-gate 			tad->tad_event = AUE_OPEN_W;
1204*7c478bd9Sstevel@tonic-gate 			break;
1205*7c478bd9Sstevel@tonic-gate 		case AUE_OPEN_WTC:
1206*7c478bd9Sstevel@tonic-gate 			tad->tad_event = AUE_OPEN_WT;
1207*7c478bd9Sstevel@tonic-gate 			break;
1208*7c478bd9Sstevel@tonic-gate 		case AUE_OPEN_RWC:
1209*7c478bd9Sstevel@tonic-gate 			tad->tad_event = AUE_OPEN_RW;
1210*7c478bd9Sstevel@tonic-gate 			break;
1211*7c478bd9Sstevel@tonic-gate 		case AUE_OPEN_RWTC:
1212*7c478bd9Sstevel@tonic-gate 			tad->tad_event = AUE_OPEN_RWT;
1213*7c478bd9Sstevel@tonic-gate 			break;
1214*7c478bd9Sstevel@tonic-gate 		default:
1215*7c478bd9Sstevel@tonic-gate 			break;
1216*7c478bd9Sstevel@tonic-gate 		}
1217*7c478bd9Sstevel@tonic-gate 	}
1218*7c478bd9Sstevel@tonic-gate }
1219*7c478bd9Sstevel@tonic-gate 
1220*7c478bd9Sstevel@tonic-gate 
1221*7c478bd9Sstevel@tonic-gate /*
1222*7c478bd9Sstevel@tonic-gate  * ROUTINE:	AUDIT_COPEN
1223*7c478bd9Sstevel@tonic-gate  * PURPOSE:
1224*7c478bd9Sstevel@tonic-gate  * CALLBY:	COPEN
1225*7c478bd9Sstevel@tonic-gate  * NOTE:
1226*7c478bd9Sstevel@tonic-gate  * TODO:
1227*7c478bd9Sstevel@tonic-gate  * QUESTION:
1228*7c478bd9Sstevel@tonic-gate  */
1229*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
1230*7c478bd9Sstevel@tonic-gate void
1231*7c478bd9Sstevel@tonic-gate audit_copen(int fd, file_t *fp, vnode_t *vp)
1232*7c478bd9Sstevel@tonic-gate {
1233*7c478bd9Sstevel@tonic-gate }
1234*7c478bd9Sstevel@tonic-gate 
1235*7c478bd9Sstevel@tonic-gate void
1236*7c478bd9Sstevel@tonic-gate audit_ipc(int type, int id, void *vp)
1237*7c478bd9Sstevel@tonic-gate {
1238*7c478bd9Sstevel@tonic-gate 	/* if not auditing this event, then do nothing */
1239*7c478bd9Sstevel@tonic-gate 	if (ad_flag == 0)
1240*7c478bd9Sstevel@tonic-gate 		return;
1241*7c478bd9Sstevel@tonic-gate 
1242*7c478bd9Sstevel@tonic-gate 	switch (type) {
1243*7c478bd9Sstevel@tonic-gate 	case AT_IPC_MSG:
1244*7c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_ipc(AT_IPC_MSG, id));
1245*7c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_ipc_perm(&(((kmsqid_t *)vp)->msg_perm)));
1246*7c478bd9Sstevel@tonic-gate 		break;
1247*7c478bd9Sstevel@tonic-gate 	case AT_IPC_SEM:
1248*7c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_ipc(AT_IPC_SEM, id));
1249*7c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_ipc_perm(&(((ksemid_t *)vp)->sem_perm)));
1250*7c478bd9Sstevel@tonic-gate 		break;
1251*7c478bd9Sstevel@tonic-gate 	case AT_IPC_SHM:
1252*7c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_ipc(AT_IPC_SHM, id));
1253*7c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_ipc_perm(&(((kshmid_t *)vp)->shm_perm)));
1254*7c478bd9Sstevel@tonic-gate 		break;
1255*7c478bd9Sstevel@tonic-gate 	}
1256*7c478bd9Sstevel@tonic-gate }
1257*7c478bd9Sstevel@tonic-gate 
1258*7c478bd9Sstevel@tonic-gate void
1259*7c478bd9Sstevel@tonic-gate audit_ipcget(int type, void *vp)
1260*7c478bd9Sstevel@tonic-gate {
1261*7c478bd9Sstevel@tonic-gate 	/* if not auditing this event, then do nothing */
1262*7c478bd9Sstevel@tonic-gate 	if (ad_flag == 0)
1263*7c478bd9Sstevel@tonic-gate 		return;
1264*7c478bd9Sstevel@tonic-gate 
1265*7c478bd9Sstevel@tonic-gate 	switch (type) {
1266*7c478bd9Sstevel@tonic-gate 	case NULL:
1267*7c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_ipc_perm((struct kipc_perm *)vp));
1268*7c478bd9Sstevel@tonic-gate 		break;
1269*7c478bd9Sstevel@tonic-gate 	case AT_IPC_MSG:
1270*7c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_ipc_perm(&(((kmsqid_t *)vp)->msg_perm)));
1271*7c478bd9Sstevel@tonic-gate 		break;
1272*7c478bd9Sstevel@tonic-gate 	case AT_IPC_SEM:
1273*7c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_ipc_perm(&(((ksemid_t *)vp)->sem_perm)));
1274*7c478bd9Sstevel@tonic-gate 		break;
1275*7c478bd9Sstevel@tonic-gate 	case AT_IPC_SHM:
1276*7c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_ipc_perm(&(((kshmid_t *)vp)->shm_perm)));
1277*7c478bd9Sstevel@tonic-gate 		break;
1278*7c478bd9Sstevel@tonic-gate 	}
1279*7c478bd9Sstevel@tonic-gate }
1280*7c478bd9Sstevel@tonic-gate 
1281*7c478bd9Sstevel@tonic-gate /*
1282*7c478bd9Sstevel@tonic-gate  * ROUTINE:	AUDIT_REBOOT
1283*7c478bd9Sstevel@tonic-gate  * PURPOSE:
1284*7c478bd9Sstevel@tonic-gate  * CALLBY:
1285*7c478bd9Sstevel@tonic-gate  * NOTE:
1286*7c478bd9Sstevel@tonic-gate  * At this point we know that the system call reboot will not return. We thus
1287*7c478bd9Sstevel@tonic-gate  * have to complete the audit record generation and put it onto the queue.
1288*7c478bd9Sstevel@tonic-gate  * This might be fairly useless if the auditing daemon is already dead....
1289*7c478bd9Sstevel@tonic-gate  * TODO:
1290*7c478bd9Sstevel@tonic-gate  * QUESTION:	who calls audit_reboot
1291*7c478bd9Sstevel@tonic-gate  */
1292*7c478bd9Sstevel@tonic-gate 
1293*7c478bd9Sstevel@tonic-gate void
1294*7c478bd9Sstevel@tonic-gate audit_reboot(void)
1295*7c478bd9Sstevel@tonic-gate {
1296*7c478bd9Sstevel@tonic-gate 	int flag;
1297*7c478bd9Sstevel@tonic-gate 	t_audit_data_t *tad;
1298*7c478bd9Sstevel@tonic-gate 	au_kcontext_t	*kctx = SET_KCTX_PZ;
1299*7c478bd9Sstevel@tonic-gate 
1300*7c478bd9Sstevel@tonic-gate 	if (kctx == NULL) {
1301*7c478bd9Sstevel@tonic-gate 		zone_status_t zstate = zone_status_get(curproc->p_zone);
1302*7c478bd9Sstevel@tonic-gate 		ASSERT(zstate != ZONE_IS_READY);
1303*7c478bd9Sstevel@tonic-gate 		return;
1304*7c478bd9Sstevel@tonic-gate 	}
1305*7c478bd9Sstevel@tonic-gate 
1306*7c478bd9Sstevel@tonic-gate 	tad = U2A(u);
1307*7c478bd9Sstevel@tonic-gate 
1308*7c478bd9Sstevel@tonic-gate 	/* if not auditing this event, then do nothing */
1309*7c478bd9Sstevel@tonic-gate 	if (tad->tad_flag == 0)
1310*7c478bd9Sstevel@tonic-gate 		return;
1311*7c478bd9Sstevel@tonic-gate 
1312*7c478bd9Sstevel@tonic-gate 	/* do preselection on success/failure */
1313*7c478bd9Sstevel@tonic-gate 	if (flag = audit_success(kctx, tad, 0)) {
1314*7c478bd9Sstevel@tonic-gate 		/* add a process token */
1315*7c478bd9Sstevel@tonic-gate 
1316*7c478bd9Sstevel@tonic-gate 		cred_t *cr = CRED();
1317*7c478bd9Sstevel@tonic-gate 		const auditinfo_addr_t *ainfo = crgetauinfo(cr);
1318*7c478bd9Sstevel@tonic-gate 
1319*7c478bd9Sstevel@tonic-gate 		if (ainfo == NULL)
1320*7c478bd9Sstevel@tonic-gate 			return;
1321*7c478bd9Sstevel@tonic-gate 
1322*7c478bd9Sstevel@tonic-gate 		AUDIT_SETSUBJ(&(u_ad), cr, ainfo);
1323*7c478bd9Sstevel@tonic-gate 
1324*7c478bd9Sstevel@tonic-gate 		/* add an optional group token */
1325*7c478bd9Sstevel@tonic-gate 		AUDIT_SETGROUP(&(u_ad), cr, kctx);
1326*7c478bd9Sstevel@tonic-gate 
1327*7c478bd9Sstevel@tonic-gate 		/* add a return token */
1328*7c478bd9Sstevel@tonic-gate 		add_return_token((caddr_t *)&(u_ad), tad->tad_scid, 0, 0);
1329*7c478bd9Sstevel@tonic-gate 
1330*7c478bd9Sstevel@tonic-gate 		AS_INC(as_generated, 1, kctx);
1331*7c478bd9Sstevel@tonic-gate 		AS_INC(as_kernel, 1, kctx);
1332*7c478bd9Sstevel@tonic-gate 	}
1333*7c478bd9Sstevel@tonic-gate 
1334*7c478bd9Sstevel@tonic-gate 	/*
1335*7c478bd9Sstevel@tonic-gate 	 * Flow control useless here since we're going
1336*7c478bd9Sstevel@tonic-gate 	 * to drop everything in the queue anyway. Why
1337*7c478bd9Sstevel@tonic-gate 	 * block and wait. There aint anyone left alive to
1338*7c478bd9Sstevel@tonic-gate 	 * read the records remaining anyway.
1339*7c478bd9Sstevel@tonic-gate 	 */
1340*7c478bd9Sstevel@tonic-gate 
1341*7c478bd9Sstevel@tonic-gate 	/* Close up everything */
1342*7c478bd9Sstevel@tonic-gate 	au_close(kctx, &(u_ad), flag | AU_DONTBLOCK,
1343*7c478bd9Sstevel@tonic-gate 	    tad->tad_event, tad->tad_evmod);
1344*7c478bd9Sstevel@tonic-gate }
1345*7c478bd9Sstevel@tonic-gate 
1346*7c478bd9Sstevel@tonic-gate void
1347*7c478bd9Sstevel@tonic-gate audit_setfsat_path(int argnum)
1348*7c478bd9Sstevel@tonic-gate {
1349*7c478bd9Sstevel@tonic-gate 	klwp_id_t clwp = ttolwp(curthread);
1350*7c478bd9Sstevel@tonic-gate 	struct file  *fp;
1351*7c478bd9Sstevel@tonic-gate 	uint32_t fd;
1352*7c478bd9Sstevel@tonic-gate 	t_audit_data_t *tad;
1353*7c478bd9Sstevel@tonic-gate 	struct f_audit_data *fad;
1354*7c478bd9Sstevel@tonic-gate 	p_audit_data_t *pad;	/* current process */
1355*7c478bd9Sstevel@tonic-gate 
1356*7c478bd9Sstevel@tonic-gate 	struct b {
1357*7c478bd9Sstevel@tonic-gate 		long arg1;
1358*7c478bd9Sstevel@tonic-gate 		long arg2;
1359*7c478bd9Sstevel@tonic-gate 		long arg3;
1360*7c478bd9Sstevel@tonic-gate 		long arg4;
1361*7c478bd9Sstevel@tonic-gate 		long arg5;
1362*7c478bd9Sstevel@tonic-gate 	} *uap1;
1363*7c478bd9Sstevel@tonic-gate 
1364*7c478bd9Sstevel@tonic-gate 	if (clwp == NULL)
1365*7c478bd9Sstevel@tonic-gate 		return;
1366*7c478bd9Sstevel@tonic-gate 	uap1 = (struct b *)&clwp->lwp_ap[1];
1367*7c478bd9Sstevel@tonic-gate 
1368*7c478bd9Sstevel@tonic-gate 	tad = U2A(u);
1369*7c478bd9Sstevel@tonic-gate 
1370*7c478bd9Sstevel@tonic-gate 	ASSERT(tad != NULL);
1371*7c478bd9Sstevel@tonic-gate 
1372*7c478bd9Sstevel@tonic-gate 	if (tad->tad_scid != SYS_fsat)
1373*7c478bd9Sstevel@tonic-gate 		return;
1374*7c478bd9Sstevel@tonic-gate 
1375*7c478bd9Sstevel@tonic-gate 	switch (argnum) {
1376*7c478bd9Sstevel@tonic-gate 	case 1:
1377*7c478bd9Sstevel@tonic-gate 		fd = (uint32_t)uap1->arg1;
1378*7c478bd9Sstevel@tonic-gate 		break;
1379*7c478bd9Sstevel@tonic-gate 	case 2:
1380*7c478bd9Sstevel@tonic-gate 		fd = (uint32_t)uap1->arg2;
1381*7c478bd9Sstevel@tonic-gate 		break;
1382*7c478bd9Sstevel@tonic-gate 	case 3:
1383*7c478bd9Sstevel@tonic-gate 		fd = (uint32_t)uap1->arg3;
1384*7c478bd9Sstevel@tonic-gate 		break;
1385*7c478bd9Sstevel@tonic-gate 	case 4:
1386*7c478bd9Sstevel@tonic-gate 		fd = (uint32_t)uap1->arg4;
1387*7c478bd9Sstevel@tonic-gate 		break;
1388*7c478bd9Sstevel@tonic-gate 	case 5:
1389*7c478bd9Sstevel@tonic-gate 		fd = (uint32_t)uap1->arg5;
1390*7c478bd9Sstevel@tonic-gate 		break;
1391*7c478bd9Sstevel@tonic-gate 	default:
1392*7c478bd9Sstevel@tonic-gate 		return;
1393*7c478bd9Sstevel@tonic-gate 	}
1394*7c478bd9Sstevel@tonic-gate 
1395*7c478bd9Sstevel@tonic-gate 	if (tad->tad_atpath != NULL) {
1396*7c478bd9Sstevel@tonic-gate 		au_pathrele(tad->tad_atpath);
1397*7c478bd9Sstevel@tonic-gate 		tad->tad_atpath = NULL;
1398*7c478bd9Sstevel@tonic-gate 	}
1399*7c478bd9Sstevel@tonic-gate 	if (fd != AT_FDCWD) {
1400*7c478bd9Sstevel@tonic-gate 		if ((fp = getf(fd)) == NULL)
1401*7c478bd9Sstevel@tonic-gate 			return;
1402*7c478bd9Sstevel@tonic-gate 
1403*7c478bd9Sstevel@tonic-gate 		fad = F2A(fp);
1404*7c478bd9Sstevel@tonic-gate 		ASSERT(fad);
1405*7c478bd9Sstevel@tonic-gate 		au_pathhold(fad->fad_aupath);
1406*7c478bd9Sstevel@tonic-gate 		tad->tad_atpath = fad->fad_aupath;
1407*7c478bd9Sstevel@tonic-gate 		releasef(fd);
1408*7c478bd9Sstevel@tonic-gate 	} else {
1409*7c478bd9Sstevel@tonic-gate 		pad = P2A(curproc);
1410*7c478bd9Sstevel@tonic-gate 		mutex_enter(&pad->pad_lock);
1411*7c478bd9Sstevel@tonic-gate 		au_pathhold(pad->pad_cwd);
1412*7c478bd9Sstevel@tonic-gate 		tad->tad_atpath = pad->pad_cwd;
1413*7c478bd9Sstevel@tonic-gate 		mutex_exit(&pad->pad_lock);
1414*7c478bd9Sstevel@tonic-gate 	}
1415*7c478bd9Sstevel@tonic-gate }
1416*7c478bd9Sstevel@tonic-gate 
1417*7c478bd9Sstevel@tonic-gate void
1418*7c478bd9Sstevel@tonic-gate audit_symlink_create(vnode_t *dvp, char *sname, char *target, int error)
1419*7c478bd9Sstevel@tonic-gate {
1420*7c478bd9Sstevel@tonic-gate 	t_audit_data_t *tad;
1421*7c478bd9Sstevel@tonic-gate 	vnode_t	*vp;
1422*7c478bd9Sstevel@tonic-gate 
1423*7c478bd9Sstevel@tonic-gate 	tad = U2A(u);
1424*7c478bd9Sstevel@tonic-gate 
1425*7c478bd9Sstevel@tonic-gate 	/* if not auditing this event, then do nothing */
1426*7c478bd9Sstevel@tonic-gate 	if (tad->tad_flag == 0)
1427*7c478bd9Sstevel@tonic-gate 		return;
1428*7c478bd9Sstevel@tonic-gate 
1429*7c478bd9Sstevel@tonic-gate 	au_uwrite(au_to_text(target));
1430*7c478bd9Sstevel@tonic-gate 
1431*7c478bd9Sstevel@tonic-gate 	if (error)
1432*7c478bd9Sstevel@tonic-gate 		return;
1433*7c478bd9Sstevel@tonic-gate 
1434*7c478bd9Sstevel@tonic-gate 	error = VOP_LOOKUP(dvp, sname, &vp, NULL, NO_FOLLOW, NULL, CRED());
1435*7c478bd9Sstevel@tonic-gate 	if (error == 0) {
1436*7c478bd9Sstevel@tonic-gate 		audit_attributes(vp);
1437*7c478bd9Sstevel@tonic-gate 		VN_RELE(vp);
1438*7c478bd9Sstevel@tonic-gate 	}
1439*7c478bd9Sstevel@tonic-gate }
1440*7c478bd9Sstevel@tonic-gate 
1441*7c478bd9Sstevel@tonic-gate /*
1442*7c478bd9Sstevel@tonic-gate  * ROUTINE:	AUDIT_VNCREATE_START
1443*7c478bd9Sstevel@tonic-gate  * PURPOSE:	set flag so path name lookup in create will not add attribute
1444*7c478bd9Sstevel@tonic-gate  * CALLBY:	VN_CREATE
1445*7c478bd9Sstevel@tonic-gate  * NOTE:
1446*7c478bd9Sstevel@tonic-gate  * TODO:
1447*7c478bd9Sstevel@tonic-gate  * QUESTION:
1448*7c478bd9Sstevel@tonic-gate  */
1449*7c478bd9Sstevel@tonic-gate 
1450*7c478bd9Sstevel@tonic-gate void
1451*7c478bd9Sstevel@tonic-gate audit_vncreate_start()
1452*7c478bd9Sstevel@tonic-gate {
1453*7c478bd9Sstevel@tonic-gate 	t_audit_data_t *tad;
1454*7c478bd9Sstevel@tonic-gate 
1455*7c478bd9Sstevel@tonic-gate 	tad = U2A(u);
1456*7c478bd9Sstevel@tonic-gate 	tad->tad_ctrl |= PAD_NOATTRB;
1457*7c478bd9Sstevel@tonic-gate }
1458*7c478bd9Sstevel@tonic-gate 
1459*7c478bd9Sstevel@tonic-gate /*
1460*7c478bd9Sstevel@tonic-gate  * ROUTINE:	AUDIT_VNCREATE_FINISH
1461*7c478bd9Sstevel@tonic-gate  * PURPOSE:
1462*7c478bd9Sstevel@tonic-gate  * CALLBY:	VN_CREATE
1463*7c478bd9Sstevel@tonic-gate  * NOTE:
1464*7c478bd9Sstevel@tonic-gate  * TODO:
1465*7c478bd9Sstevel@tonic-gate  * QUESTION:
1466*7c478bd9Sstevel@tonic-gate  */
1467*7c478bd9Sstevel@tonic-gate void
1468*7c478bd9Sstevel@tonic-gate audit_vncreate_finish(struct vnode *vp, int error)
1469*7c478bd9Sstevel@tonic-gate {
1470*7c478bd9Sstevel@tonic-gate 	t_audit_data_t *tad;
1471*7c478bd9Sstevel@tonic-gate 
1472*7c478bd9Sstevel@tonic-gate 	if (error)
1473*7c478bd9Sstevel@tonic-gate 		return;
1474*7c478bd9Sstevel@tonic-gate 
1475*7c478bd9Sstevel@tonic-gate 	tad = U2A(u);
1476*7c478bd9Sstevel@tonic-gate 
1477*7c478bd9Sstevel@tonic-gate 	/* if not auditing this event, then do nothing */
1478*7c478bd9Sstevel@tonic-gate 	if (tad->tad_flag == 0)
1479*7c478bd9Sstevel@tonic-gate 		return;
1480*7c478bd9Sstevel@tonic-gate 
1481*7c478bd9Sstevel@tonic-gate 	if (tad->tad_ctrl & PAD_TRUE_CREATE) {
1482*7c478bd9Sstevel@tonic-gate 		audit_attributes(vp);
1483*7c478bd9Sstevel@tonic-gate 	}
1484*7c478bd9Sstevel@tonic-gate 
1485*7c478bd9Sstevel@tonic-gate 	if (tad->tad_ctrl & PAD_CORE) {
1486*7c478bd9Sstevel@tonic-gate 		audit_attributes(vp);
1487*7c478bd9Sstevel@tonic-gate 		tad->tad_ctrl &= ~PAD_CORE;
1488*7c478bd9Sstevel@tonic-gate 	}
1489*7c478bd9Sstevel@tonic-gate 
1490*7c478bd9Sstevel@tonic-gate 	if (!error && ((tad->tad_event == AUE_MKNOD) ||
1491*7c478bd9Sstevel@tonic-gate 			(tad->tad_event == AUE_MKDIR))) {
1492*7c478bd9Sstevel@tonic-gate 		audit_attributes(vp);
1493*7c478bd9Sstevel@tonic-gate 	}
1494*7c478bd9Sstevel@tonic-gate 
1495*7c478bd9Sstevel@tonic-gate 	/* for case where multiple lookups in one syscall (rename) */
1496*7c478bd9Sstevel@tonic-gate 	tad->tad_ctrl &= ~PAD_NOATTRB;
1497*7c478bd9Sstevel@tonic-gate }
1498*7c478bd9Sstevel@tonic-gate 
1499*7c478bd9Sstevel@tonic-gate 
1500*7c478bd9Sstevel@tonic-gate 
1501*7c478bd9Sstevel@tonic-gate 
1502*7c478bd9Sstevel@tonic-gate 
1503*7c478bd9Sstevel@tonic-gate 
1504*7c478bd9Sstevel@tonic-gate 
1505*7c478bd9Sstevel@tonic-gate 
1506*7c478bd9Sstevel@tonic-gate /*
1507*7c478bd9Sstevel@tonic-gate  * ROUTINE:	AUDIT_EXEC
1508*7c478bd9Sstevel@tonic-gate  * PURPOSE:	Records the function arguments and environment variables
1509*7c478bd9Sstevel@tonic-gate  * CALLBY:	EXEC_ARGS
1510*7c478bd9Sstevel@tonic-gate  * NOTE:
1511*7c478bd9Sstevel@tonic-gate  * TODO:
1512*7c478bd9Sstevel@tonic-gate  * QUESTION:
1513*7c478bd9Sstevel@tonic-gate  */
1514*7c478bd9Sstevel@tonic-gate 
1515*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
1516*7c478bd9Sstevel@tonic-gate void
1517*7c478bd9Sstevel@tonic-gate audit_exec(
1518*7c478bd9Sstevel@tonic-gate 	const char *argstr,	/* argument strings */
1519*7c478bd9Sstevel@tonic-gate 	const char *envstr,	/* environment strings */
1520*7c478bd9Sstevel@tonic-gate 	ssize_t argc,		/* total # arguments */
1521*7c478bd9Sstevel@tonic-gate 	ssize_t envc)		/* total # environment variables */
1522*7c478bd9Sstevel@tonic-gate {
1523*7c478bd9Sstevel@tonic-gate 	t_audit_data_t *tad;
1524*7c478bd9Sstevel@tonic-gate 	au_kcontext_t	*kctx = SET_KCTX_PZ;
1525*7c478bd9Sstevel@tonic-gate 
1526*7c478bd9Sstevel@tonic-gate 	ASSERT(kctx != NULL);
1527*7c478bd9Sstevel@tonic-gate 
1528*7c478bd9Sstevel@tonic-gate 	tad = U2A(u);
1529*7c478bd9Sstevel@tonic-gate 
1530*7c478bd9Sstevel@tonic-gate 	/* if not auditing this event, then do nothing */
1531*7c478bd9Sstevel@tonic-gate 	if (!tad->tad_flag)
1532*7c478bd9Sstevel@tonic-gate 		return;
1533*7c478bd9Sstevel@tonic-gate 
1534*7c478bd9Sstevel@tonic-gate 	/* return if not interested in argv or environment variables */
1535*7c478bd9Sstevel@tonic-gate 	if (!(kctx->auk_policy & (AUDIT_ARGV|AUDIT_ARGE)))
1536*7c478bd9Sstevel@tonic-gate 		return;
1537*7c478bd9Sstevel@tonic-gate 
1538*7c478bd9Sstevel@tonic-gate 	if (kctx->auk_policy & AUDIT_ARGV) {
1539*7c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_exec_args(argstr, argc));
1540*7c478bd9Sstevel@tonic-gate 	}
1541*7c478bd9Sstevel@tonic-gate 
1542*7c478bd9Sstevel@tonic-gate 	if (kctx->auk_policy & AUDIT_ARGE) {
1543*7c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_exec_env(envstr, envc));
1544*7c478bd9Sstevel@tonic-gate 	}
1545*7c478bd9Sstevel@tonic-gate }
1546*7c478bd9Sstevel@tonic-gate 
1547*7c478bd9Sstevel@tonic-gate /*
1548*7c478bd9Sstevel@tonic-gate  * ROUTINE:	AUDIT_ENTERPROM
1549*7c478bd9Sstevel@tonic-gate  * PURPOSE:
1550*7c478bd9Sstevel@tonic-gate  * CALLBY:	KBDINPUT
1551*7c478bd9Sstevel@tonic-gate  *		ZSA_XSINT
1552*7c478bd9Sstevel@tonic-gate  * NOTE:
1553*7c478bd9Sstevel@tonic-gate  * TODO:
1554*7c478bd9Sstevel@tonic-gate  * QUESTION:
1555*7c478bd9Sstevel@tonic-gate  */
1556*7c478bd9Sstevel@tonic-gate void
1557*7c478bd9Sstevel@tonic-gate audit_enterprom(int flg)
1558*7c478bd9Sstevel@tonic-gate {
1559*7c478bd9Sstevel@tonic-gate 	token_t *rp = NULL;
1560*7c478bd9Sstevel@tonic-gate 	int sorf;
1561*7c478bd9Sstevel@tonic-gate 
1562*7c478bd9Sstevel@tonic-gate 	if (flg)
1563*7c478bd9Sstevel@tonic-gate 		sorf = AUM_SUCC;
1564*7c478bd9Sstevel@tonic-gate 	else
1565*7c478bd9Sstevel@tonic-gate 		sorf = AUM_FAIL;
1566*7c478bd9Sstevel@tonic-gate 
1567*7c478bd9Sstevel@tonic-gate 	AUDIT_ASYNC_START(rp, AUE_ENTERPROM, sorf);
1568*7c478bd9Sstevel@tonic-gate 
1569*7c478bd9Sstevel@tonic-gate 	au_write((caddr_t *)&(rp), au_to_text("kmdb"));
1570*7c478bd9Sstevel@tonic-gate 
1571*7c478bd9Sstevel@tonic-gate 	if (flg)
1572*7c478bd9Sstevel@tonic-gate 		au_write((caddr_t *)&(rp), au_to_return32(0, 0));
1573*7c478bd9Sstevel@tonic-gate 	else
1574*7c478bd9Sstevel@tonic-gate 		au_write((caddr_t *)&(rp), au_to_return32(ECANCELED, 0));
1575*7c478bd9Sstevel@tonic-gate 
1576*7c478bd9Sstevel@tonic-gate 	AUDIT_ASYNC_FINISH(rp, AUE_ENTERPROM, NULL);
1577*7c478bd9Sstevel@tonic-gate }
1578*7c478bd9Sstevel@tonic-gate 
1579*7c478bd9Sstevel@tonic-gate 
1580*7c478bd9Sstevel@tonic-gate /*
1581*7c478bd9Sstevel@tonic-gate  * ROUTINE:	AUDIT_EXITPROM
1582*7c478bd9Sstevel@tonic-gate  * PURPOSE:
1583*7c478bd9Sstevel@tonic-gate  * CALLBY:	KBDINPUT
1584*7c478bd9Sstevel@tonic-gate  *		ZSA_XSINT
1585*7c478bd9Sstevel@tonic-gate  * NOTE:
1586*7c478bd9Sstevel@tonic-gate  * TODO:
1587*7c478bd9Sstevel@tonic-gate  * QUESTION:
1588*7c478bd9Sstevel@tonic-gate  */
1589*7c478bd9Sstevel@tonic-gate void
1590*7c478bd9Sstevel@tonic-gate audit_exitprom(int flg)
1591*7c478bd9Sstevel@tonic-gate {
1592*7c478bd9Sstevel@tonic-gate 	int sorf;
1593*7c478bd9Sstevel@tonic-gate 	token_t *rp = NULL;
1594*7c478bd9Sstevel@tonic-gate 
1595*7c478bd9Sstevel@tonic-gate 	if (flg)
1596*7c478bd9Sstevel@tonic-gate 		sorf = AUM_SUCC;
1597*7c478bd9Sstevel@tonic-gate 	else
1598*7c478bd9Sstevel@tonic-gate 		sorf = AUM_FAIL;
1599*7c478bd9Sstevel@tonic-gate 
1600*7c478bd9Sstevel@tonic-gate 	AUDIT_ASYNC_START(rp, AUE_EXITPROM, sorf);
1601*7c478bd9Sstevel@tonic-gate 
1602*7c478bd9Sstevel@tonic-gate 	au_write((caddr_t *)&(rp), au_to_text("kmdb"));
1603*7c478bd9Sstevel@tonic-gate 
1604*7c478bd9Sstevel@tonic-gate 	if (flg)
1605*7c478bd9Sstevel@tonic-gate 		au_write((caddr_t *)&(rp), au_to_return32(0, 0));
1606*7c478bd9Sstevel@tonic-gate 	else
1607*7c478bd9Sstevel@tonic-gate 		au_write((caddr_t *)&(rp), au_to_return32(ECANCELED, 0));
1608*7c478bd9Sstevel@tonic-gate 
1609*7c478bd9Sstevel@tonic-gate 	AUDIT_ASYNC_FINISH(rp, AUE_EXITPROM, NULL);
1610*7c478bd9Sstevel@tonic-gate }
1611*7c478bd9Sstevel@tonic-gate 
1612*7c478bd9Sstevel@tonic-gate struct fcntla {
1613*7c478bd9Sstevel@tonic-gate 	int fdes;
1614*7c478bd9Sstevel@tonic-gate 	int cmd;
1615*7c478bd9Sstevel@tonic-gate 	intptr_t arg;
1616*7c478bd9Sstevel@tonic-gate };
1617*7c478bd9Sstevel@tonic-gate 
1618*7c478bd9Sstevel@tonic-gate /*
1619*7c478bd9Sstevel@tonic-gate  * ROUTINE:	AUDIT_C2_REVOKE
1620*7c478bd9Sstevel@tonic-gate  * PURPOSE:
1621*7c478bd9Sstevel@tonic-gate  * CALLBY:	FCNTL
1622*7c478bd9Sstevel@tonic-gate  * NOTE:
1623*7c478bd9Sstevel@tonic-gate  * TODO:
1624*7c478bd9Sstevel@tonic-gate  * QUESTION:	are we keeping this func
1625*7c478bd9Sstevel@tonic-gate  */
1626*7c478bd9Sstevel@tonic-gate 
1627*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
1628*7c478bd9Sstevel@tonic-gate int
1629*7c478bd9Sstevel@tonic-gate audit_c2_revoke(struct fcntla *uap, rval_t *rvp)
1630*7c478bd9Sstevel@tonic-gate {
1631*7c478bd9Sstevel@tonic-gate 	return (0);
1632*7c478bd9Sstevel@tonic-gate }
1633*7c478bd9Sstevel@tonic-gate 
1634*7c478bd9Sstevel@tonic-gate 
1635*7c478bd9Sstevel@tonic-gate /*
1636*7c478bd9Sstevel@tonic-gate  * ROUTINE:	AUDIT_CHDIREC
1637*7c478bd9Sstevel@tonic-gate  * PURPOSE:
1638*7c478bd9Sstevel@tonic-gate  * CALLBY:	CHDIREC
1639*7c478bd9Sstevel@tonic-gate  * NOTE:	The main function of CHDIREC
1640*7c478bd9Sstevel@tonic-gate  * TODO:	Move the audit_chdirec hook above the VN_RELE in vncalls.c
1641*7c478bd9Sstevel@tonic-gate  * QUESTION:
1642*7c478bd9Sstevel@tonic-gate  */
1643*7c478bd9Sstevel@tonic-gate 
1644*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
1645*7c478bd9Sstevel@tonic-gate void
1646*7c478bd9Sstevel@tonic-gate audit_chdirec(vnode_t *vp, vnode_t **vpp)
1647*7c478bd9Sstevel@tonic-gate {
1648*7c478bd9Sstevel@tonic-gate 	int		chdir;
1649*7c478bd9Sstevel@tonic-gate 	int		fchdir;
1650*7c478bd9Sstevel@tonic-gate 	struct audit_path	**appp;
1651*7c478bd9Sstevel@tonic-gate 	struct file	*fp;
1652*7c478bd9Sstevel@tonic-gate 	f_audit_data_t *fad;
1653*7c478bd9Sstevel@tonic-gate 	p_audit_data_t *pad = P2A(curproc);
1654*7c478bd9Sstevel@tonic-gate 	t_audit_data_t *tad = T2A(curthread);
1655*7c478bd9Sstevel@tonic-gate 
1656*7c478bd9Sstevel@tonic-gate 	struct a {
1657*7c478bd9Sstevel@tonic-gate 		long fd;
1658*7c478bd9Sstevel@tonic-gate 	} *uap = (struct a *)ttolwp(curthread)->lwp_ap;
1659*7c478bd9Sstevel@tonic-gate 
1660*7c478bd9Sstevel@tonic-gate 	if ((tad->tad_scid == SYS_chdir) || (tad->tad_scid == SYS_chroot)) {
1661*7c478bd9Sstevel@tonic-gate 		chdir = tad->tad_scid == SYS_chdir;
1662*7c478bd9Sstevel@tonic-gate 		if (tad->tad_aupath) {
1663*7c478bd9Sstevel@tonic-gate 			mutex_enter(&pad->pad_lock);
1664*7c478bd9Sstevel@tonic-gate 			if (chdir)
1665*7c478bd9Sstevel@tonic-gate 				appp = &(pad->pad_cwd);
1666*7c478bd9Sstevel@tonic-gate 			else
1667*7c478bd9Sstevel@tonic-gate 				appp = &(pad->pad_root);
1668*7c478bd9Sstevel@tonic-gate 			au_pathrele(*appp);
1669*7c478bd9Sstevel@tonic-gate 			/* use tad hold */
1670*7c478bd9Sstevel@tonic-gate 			*appp = tad->tad_aupath;
1671*7c478bd9Sstevel@tonic-gate 			tad->tad_aupath = NULL;
1672*7c478bd9Sstevel@tonic-gate 			mutex_exit(&pad->pad_lock);
1673*7c478bd9Sstevel@tonic-gate 		}
1674*7c478bd9Sstevel@tonic-gate 	} else if ((tad->tad_scid == SYS_fchdir) ||
1675*7c478bd9Sstevel@tonic-gate 	    (tad->tad_scid == SYS_fchroot)) {
1676*7c478bd9Sstevel@tonic-gate 		fchdir = tad->tad_scid == SYS_fchdir;
1677*7c478bd9Sstevel@tonic-gate 		if ((fp = getf(uap->fd)) == NULL)
1678*7c478bd9Sstevel@tonic-gate 			return;
1679*7c478bd9Sstevel@tonic-gate 		fad = F2A(fp);
1680*7c478bd9Sstevel@tonic-gate 		if (fad->fad_aupath) {
1681*7c478bd9Sstevel@tonic-gate 			au_pathhold(fad->fad_aupath);
1682*7c478bd9Sstevel@tonic-gate 			mutex_enter(&pad->pad_lock);
1683*7c478bd9Sstevel@tonic-gate 			if (fchdir)
1684*7c478bd9Sstevel@tonic-gate 				appp = &(pad->pad_cwd);
1685*7c478bd9Sstevel@tonic-gate 			else
1686*7c478bd9Sstevel@tonic-gate 				appp = &(pad->pad_root);
1687*7c478bd9Sstevel@tonic-gate 			au_pathrele(*appp);
1688*7c478bd9Sstevel@tonic-gate 			*appp = fad->fad_aupath;
1689*7c478bd9Sstevel@tonic-gate 			mutex_exit(&pad->pad_lock);
1690*7c478bd9Sstevel@tonic-gate 			if (tad->tad_flag) {
1691*7c478bd9Sstevel@tonic-gate 				au_uwrite(au_to_path(fad->fad_aupath));
1692*7c478bd9Sstevel@tonic-gate 				audit_attributes(fp->f_vnode);
1693*7c478bd9Sstevel@tonic-gate 			}
1694*7c478bd9Sstevel@tonic-gate 		}
1695*7c478bd9Sstevel@tonic-gate 		releasef(uap->fd);
1696*7c478bd9Sstevel@tonic-gate 	}
1697*7c478bd9Sstevel@tonic-gate }
1698*7c478bd9Sstevel@tonic-gate 
1699*7c478bd9Sstevel@tonic-gate /*
1700*7c478bd9Sstevel@tonic-gate  * ROUTINE:	AUDIT_GETF
1701*7c478bd9Sstevel@tonic-gate  * PURPOSE:
1702*7c478bd9Sstevel@tonic-gate  * CALLBY:	GETF_INTERNAL
1703*7c478bd9Sstevel@tonic-gate  * NOTE:	The main function of GETF_INTERNAL is to associate a given
1704*7c478bd9Sstevel@tonic-gate  *		file descriptor with a file structure and increment the
1705*7c478bd9Sstevel@tonic-gate  *		file pointer reference count.
1706*7c478bd9Sstevel@tonic-gate  * TODO:	remove pass in of fpp.
1707*7c478bd9Sstevel@tonic-gate  * increment a reference count so that even if a thread with same process delete
1708*7c478bd9Sstevel@tonic-gate  * the same object, it will not panic our system
1709*7c478bd9Sstevel@tonic-gate  * QUESTION:
1710*7c478bd9Sstevel@tonic-gate  * where to decrement the f_count?????????????????
1711*7c478bd9Sstevel@tonic-gate  * seems like I need to set a flag if f_count incrmented through audit_getf
1712*7c478bd9Sstevel@tonic-gate  */
1713*7c478bd9Sstevel@tonic-gate 
1714*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
1715*7c478bd9Sstevel@tonic-gate int
1716*7c478bd9Sstevel@tonic-gate audit_getf(int fd)
1717*7c478bd9Sstevel@tonic-gate {
1718*7c478bd9Sstevel@tonic-gate #ifdef NOTYET
1719*7c478bd9Sstevel@tonic-gate 	t_audit_data_t *tad;
1720*7c478bd9Sstevel@tonic-gate 
1721*7c478bd9Sstevel@tonic-gate 	tad = T2A(curthread);
1722*7c478bd9Sstevel@tonic-gate 
1723*7c478bd9Sstevel@tonic-gate 	if (!(tad->tad_scid == SYS_open || tad->tad_scid == SYS_creat))
1724*7c478bd9Sstevel@tonic-gate 		return;
1725*7c478bd9Sstevel@tonic-gate #endif
1726*7c478bd9Sstevel@tonic-gate 	return (0);
1727*7c478bd9Sstevel@tonic-gate }
1728*7c478bd9Sstevel@tonic-gate 
1729*7c478bd9Sstevel@tonic-gate /*
1730*7c478bd9Sstevel@tonic-gate  *	Audit hook for stream based socket and tli request.
1731*7c478bd9Sstevel@tonic-gate  *	Note that we do not have user context while executing
1732*7c478bd9Sstevel@tonic-gate  *	this code so we had to record them earlier during the
1733*7c478bd9Sstevel@tonic-gate  *	putmsg/getmsg to figure out which user we are dealing with.
1734*7c478bd9Sstevel@tonic-gate  */
1735*7c478bd9Sstevel@tonic-gate 
1736*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
1737*7c478bd9Sstevel@tonic-gate void
1738*7c478bd9Sstevel@tonic-gate audit_sock(
1739*7c478bd9Sstevel@tonic-gate 	int type,	/* type of tihdr.h header requests */
1740*7c478bd9Sstevel@tonic-gate 	queue_t *q,	/* contains the process and thread audit data */
1741*7c478bd9Sstevel@tonic-gate 	mblk_t *mp,	/* contains the tihdr.h header structures */
1742*7c478bd9Sstevel@tonic-gate 	int from)	/* timod or sockmod request */
1743*7c478bd9Sstevel@tonic-gate {
1744*7c478bd9Sstevel@tonic-gate 	int32_t    len;
1745*7c478bd9Sstevel@tonic-gate 	int32_t    offset;
1746*7c478bd9Sstevel@tonic-gate 	struct sockaddr_in *sock_data;
1747*7c478bd9Sstevel@tonic-gate 	struct T_conn_req *conn_req;
1748*7c478bd9Sstevel@tonic-gate 	struct T_conn_ind *conn_ind;
1749*7c478bd9Sstevel@tonic-gate 	struct T_unitdata_req *unitdata_req;
1750*7c478bd9Sstevel@tonic-gate 	struct T_unitdata_ind *unitdata_ind;
1751*7c478bd9Sstevel@tonic-gate 	au_state_t estate;
1752*7c478bd9Sstevel@tonic-gate 	t_audit_data_t *tad;
1753*7c478bd9Sstevel@tonic-gate 	caddr_t saved_thread_ptr;
1754*7c478bd9Sstevel@tonic-gate 	au_mask_t amask;
1755*7c478bd9Sstevel@tonic-gate 	const auditinfo_addr_t *ainfo;
1756*7c478bd9Sstevel@tonic-gate 	au_kcontext_t	*kctx;
1757*7c478bd9Sstevel@tonic-gate 	zone_status_t	zstate;
1758*7c478bd9Sstevel@tonic-gate 
1759*7c478bd9Sstevel@tonic-gate 	if (q->q_stream == NULL)
1760*7c478bd9Sstevel@tonic-gate 		return;
1761*7c478bd9Sstevel@tonic-gate 	mutex_enter(&q->q_stream->sd_lock);
1762*7c478bd9Sstevel@tonic-gate 	/* are we being audited */
1763*7c478bd9Sstevel@tonic-gate 	saved_thread_ptr = q->q_stream->sd_t_audit_data;
1764*7c478bd9Sstevel@tonic-gate 	/* no pointer to thread, nothing to do */
1765*7c478bd9Sstevel@tonic-gate 	if (saved_thread_ptr == NULL) {
1766*7c478bd9Sstevel@tonic-gate 		mutex_exit(&q->q_stream->sd_lock);
1767*7c478bd9Sstevel@tonic-gate 		return;
1768*7c478bd9Sstevel@tonic-gate 	}
1769*7c478bd9Sstevel@tonic-gate 	/* only allow one addition of a record token */
1770*7c478bd9Sstevel@tonic-gate 	q->q_stream->sd_t_audit_data = NULL;
1771*7c478bd9Sstevel@tonic-gate 	/*
1772*7c478bd9Sstevel@tonic-gate 	 * thread is not the one being audited, then nothing to do
1773*7c478bd9Sstevel@tonic-gate 	 * This could be the stream thread handling the module
1774*7c478bd9Sstevel@tonic-gate 	 * service routine. In this case, the context for the audit
1775*7c478bd9Sstevel@tonic-gate 	 * record can no longer be assumed. Simplest to just drop
1776*7c478bd9Sstevel@tonic-gate 	 * the operation.
1777*7c478bd9Sstevel@tonic-gate 	 */
1778*7c478bd9Sstevel@tonic-gate 	if (curthread != (kthread_id_t)saved_thread_ptr) {
1779*7c478bd9Sstevel@tonic-gate 		mutex_exit(&q->q_stream->sd_lock);
1780*7c478bd9Sstevel@tonic-gate 		return;
1781*7c478bd9Sstevel@tonic-gate 	}
1782*7c478bd9Sstevel@tonic-gate 	if (curthread->t_sysnum >= SYS_so_socket &&
1783*7c478bd9Sstevel@tonic-gate 	    curthread->t_sysnum <= SYS_sockconfig) {
1784*7c478bd9Sstevel@tonic-gate 		mutex_exit(&q->q_stream->sd_lock);
1785*7c478bd9Sstevel@tonic-gate 		return;
1786*7c478bd9Sstevel@tonic-gate 	}
1787*7c478bd9Sstevel@tonic-gate 	mutex_exit(&q->q_stream->sd_lock);
1788*7c478bd9Sstevel@tonic-gate 	/*
1789*7c478bd9Sstevel@tonic-gate 	 * we know that the thread that did the put/getmsg is the
1790*7c478bd9Sstevel@tonic-gate 	 * one running. Now we can get the TAD and see if we should
1791*7c478bd9Sstevel@tonic-gate 	 * add an audit token.
1792*7c478bd9Sstevel@tonic-gate 	 */
1793*7c478bd9Sstevel@tonic-gate 	tad = U2A(u);
1794*7c478bd9Sstevel@tonic-gate 
1795*7c478bd9Sstevel@tonic-gate 	kctx = SET_KCTX_PZ;
1796*7c478bd9Sstevel@tonic-gate 	if (kctx == NULL) {
1797*7c478bd9Sstevel@tonic-gate 		zstate = zone_status_get(curproc->p_zone);
1798*7c478bd9Sstevel@tonic-gate 		ASSERT(zstate != ZONE_IS_READY);
1799*7c478bd9Sstevel@tonic-gate 		return;
1800*7c478bd9Sstevel@tonic-gate 	}
1801*7c478bd9Sstevel@tonic-gate 
1802*7c478bd9Sstevel@tonic-gate 	/* proceed ONLY if user is being audited */
1803*7c478bd9Sstevel@tonic-gate 	if (!tad->tad_flag)
1804*7c478bd9Sstevel@tonic-gate 		return;
1805*7c478bd9Sstevel@tonic-gate 
1806*7c478bd9Sstevel@tonic-gate 	ainfo = crgetauinfo(CRED());
1807*7c478bd9Sstevel@tonic-gate 	if (ainfo == NULL)
1808*7c478bd9Sstevel@tonic-gate 		return;
1809*7c478bd9Sstevel@tonic-gate 	amask = ainfo->ai_mask;
1810*7c478bd9Sstevel@tonic-gate 
1811*7c478bd9Sstevel@tonic-gate 	/*
1812*7c478bd9Sstevel@tonic-gate 	 * Figure out the type of stream networking request here.
1813*7c478bd9Sstevel@tonic-gate 	 * Note that getmsg and putmsg are always preselected
1814*7c478bd9Sstevel@tonic-gate 	 * because during the beginning of the system call we have
1815*7c478bd9Sstevel@tonic-gate 	 * not yet figure out which of the socket or tli request
1816*7c478bd9Sstevel@tonic-gate 	 * we are looking at until we are here. So we need to check
1817*7c478bd9Sstevel@tonic-gate 	 * against that specific request and reset the type of event.
1818*7c478bd9Sstevel@tonic-gate 	 */
1819*7c478bd9Sstevel@tonic-gate 	switch (type) {
1820*7c478bd9Sstevel@tonic-gate 	case T_CONN_REQ:	/* connection request */
1821*7c478bd9Sstevel@tonic-gate 		conn_req = (struct T_conn_req *)mp->b_rptr;
1822*7c478bd9Sstevel@tonic-gate 		if (conn_req->DEST_offset < sizeof (struct T_conn_req))
1823*7c478bd9Sstevel@tonic-gate 			return;
1824*7c478bd9Sstevel@tonic-gate 		offset = conn_req->DEST_offset;
1825*7c478bd9Sstevel@tonic-gate 		len = conn_req->DEST_length;
1826*7c478bd9Sstevel@tonic-gate 		estate = kctx->auk_ets[AUE_SOCKCONNECT];
1827*7c478bd9Sstevel@tonic-gate 		if (amask.as_success & estate || amask.as_failure & estate) {
1828*7c478bd9Sstevel@tonic-gate 			tad->tad_event = AUE_SOCKCONNECT;
1829*7c478bd9Sstevel@tonic-gate 			break;
1830*7c478bd9Sstevel@tonic-gate 		} else {
1831*7c478bd9Sstevel@tonic-gate 			return;
1832*7c478bd9Sstevel@tonic-gate 		}
1833*7c478bd9Sstevel@tonic-gate 	case T_CONN_IND:	 /* connectionless receive request */
1834*7c478bd9Sstevel@tonic-gate 		conn_ind = (struct T_conn_ind *)mp->b_rptr;
1835*7c478bd9Sstevel@tonic-gate 		if (conn_ind->SRC_offset < sizeof (struct T_conn_ind))
1836*7c478bd9Sstevel@tonic-gate 			return;
1837*7c478bd9Sstevel@tonic-gate 		offset = conn_ind->SRC_offset;
1838*7c478bd9Sstevel@tonic-gate 		len = conn_ind->SRC_length;
1839*7c478bd9Sstevel@tonic-gate 		estate = kctx->auk_ets[AUE_SOCKACCEPT];
1840*7c478bd9Sstevel@tonic-gate 		if (amask.as_success & estate || amask.as_failure & estate) {
1841*7c478bd9Sstevel@tonic-gate 			tad->tad_event = AUE_SOCKACCEPT;
1842*7c478bd9Sstevel@tonic-gate 			break;
1843*7c478bd9Sstevel@tonic-gate 		} else {
1844*7c478bd9Sstevel@tonic-gate 			return;
1845*7c478bd9Sstevel@tonic-gate 		}
1846*7c478bd9Sstevel@tonic-gate 	case T_UNITDATA_REQ:	 /* connectionless send request */
1847*7c478bd9Sstevel@tonic-gate 		unitdata_req = (struct T_unitdata_req *)mp->b_rptr;
1848*7c478bd9Sstevel@tonic-gate 		if (unitdata_req->DEST_offset < sizeof (struct T_unitdata_req))
1849*7c478bd9Sstevel@tonic-gate 			return;
1850*7c478bd9Sstevel@tonic-gate 		offset = unitdata_req->DEST_offset;
1851*7c478bd9Sstevel@tonic-gate 		len = unitdata_req->DEST_length;
1852*7c478bd9Sstevel@tonic-gate 		estate = kctx->auk_ets[AUE_SOCKSEND];
1853*7c478bd9Sstevel@tonic-gate 		if (amask.as_success & estate || amask.as_failure & estate) {
1854*7c478bd9Sstevel@tonic-gate 			tad->tad_event = AUE_SOCKSEND;
1855*7c478bd9Sstevel@tonic-gate 			break;
1856*7c478bd9Sstevel@tonic-gate 		} else {
1857*7c478bd9Sstevel@tonic-gate 			return;
1858*7c478bd9Sstevel@tonic-gate 		}
1859*7c478bd9Sstevel@tonic-gate 	case T_UNITDATA_IND:	 /* connectionless receive request */
1860*7c478bd9Sstevel@tonic-gate 		unitdata_ind = (struct T_unitdata_ind *)mp->b_rptr;
1861*7c478bd9Sstevel@tonic-gate 		if (unitdata_ind->SRC_offset < sizeof (struct T_unitdata_ind))
1862*7c478bd9Sstevel@tonic-gate 			return;
1863*7c478bd9Sstevel@tonic-gate 		offset = unitdata_ind->SRC_offset;
1864*7c478bd9Sstevel@tonic-gate 		len = unitdata_ind->SRC_length;
1865*7c478bd9Sstevel@tonic-gate 		estate = kctx->auk_ets[AUE_SOCKRECEIVE];
1866*7c478bd9Sstevel@tonic-gate 		if (amask.as_success & estate || amask.as_failure & estate) {
1867*7c478bd9Sstevel@tonic-gate 			tad->tad_event = AUE_SOCKRECEIVE;
1868*7c478bd9Sstevel@tonic-gate 			break;
1869*7c478bd9Sstevel@tonic-gate 		} else {
1870*7c478bd9Sstevel@tonic-gate 			return;
1871*7c478bd9Sstevel@tonic-gate 		}
1872*7c478bd9Sstevel@tonic-gate 	default:
1873*7c478bd9Sstevel@tonic-gate 		return;
1874*7c478bd9Sstevel@tonic-gate 	}
1875*7c478bd9Sstevel@tonic-gate 
1876*7c478bd9Sstevel@tonic-gate 	/*
1877*7c478bd9Sstevel@tonic-gate 	 * we are only interested in tcp stream connections,
1878*7c478bd9Sstevel@tonic-gate 	 * not unix domain stuff
1879*7c478bd9Sstevel@tonic-gate 	 */
1880*7c478bd9Sstevel@tonic-gate 	if ((len < 0) || (len > sizeof (struct sockaddr_in))) {
1881*7c478bd9Sstevel@tonic-gate 		tad->tad_event = AUE_GETMSG;
1882*7c478bd9Sstevel@tonic-gate 		return;
1883*7c478bd9Sstevel@tonic-gate 	}
1884*7c478bd9Sstevel@tonic-gate 	/* skip over TPI header and point to the ip address */
1885*7c478bd9Sstevel@tonic-gate 	sock_data = (struct sockaddr_in *)((char *)mp->b_rptr + offset);
1886*7c478bd9Sstevel@tonic-gate 
1887*7c478bd9Sstevel@tonic-gate 	switch (sock_data->sin_family) {
1888*7c478bd9Sstevel@tonic-gate 	case AF_INET:
1889*7c478bd9Sstevel@tonic-gate 		au_write(&(tad->tad_ad), au_to_sock_inet(sock_data));
1890*7c478bd9Sstevel@tonic-gate 		break;
1891*7c478bd9Sstevel@tonic-gate 	default:	/* reset to AUE_PUTMSG if not a inet request */
1892*7c478bd9Sstevel@tonic-gate 		tad->tad_event = AUE_GETMSG;
1893*7c478bd9Sstevel@tonic-gate 		break;
1894*7c478bd9Sstevel@tonic-gate 	}
1895*7c478bd9Sstevel@tonic-gate }
1896*7c478bd9Sstevel@tonic-gate 
1897*7c478bd9Sstevel@tonic-gate void
1898*7c478bd9Sstevel@tonic-gate audit_lookupname()
1899*7c478bd9Sstevel@tonic-gate {
1900*7c478bd9Sstevel@tonic-gate }
1901*7c478bd9Sstevel@tonic-gate 
1902*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
1903*7c478bd9Sstevel@tonic-gate int
1904*7c478bd9Sstevel@tonic-gate audit_pathcomp(struct pathname *pnp, vnode_t *cvp, cred_t *cr)
1905*7c478bd9Sstevel@tonic-gate {
1906*7c478bd9Sstevel@tonic-gate 	return (0);
1907*7c478bd9Sstevel@tonic-gate }
1908*7c478bd9Sstevel@tonic-gate 
1909*7c478bd9Sstevel@tonic-gate static void
1910*7c478bd9Sstevel@tonic-gate add_return_token(caddr_t *ad, unsigned int scid, int err, int rval)
1911*7c478bd9Sstevel@tonic-gate {
1912*7c478bd9Sstevel@tonic-gate 	unsigned int sy_flags;
1913*7c478bd9Sstevel@tonic-gate 
1914*7c478bd9Sstevel@tonic-gate #ifdef _SYSCALL32_IMPL
1915*7c478bd9Sstevel@tonic-gate 	if (lwp_getdatamodel(
1916*7c478bd9Sstevel@tonic-gate 		ttolwp(curthread)) == DATAMODEL_NATIVE)
1917*7c478bd9Sstevel@tonic-gate 		sy_flags = sysent[scid].sy_flags & SE_RVAL_MASK;
1918*7c478bd9Sstevel@tonic-gate 	else
1919*7c478bd9Sstevel@tonic-gate 		sy_flags = sysent32[scid].sy_flags & SE_RVAL_MASK;
1920*7c478bd9Sstevel@tonic-gate #else
1921*7c478bd9Sstevel@tonic-gate 		sy_flags = sysent[scid].sy_flags & SE_RVAL_MASK;
1922*7c478bd9Sstevel@tonic-gate #endif
1923*7c478bd9Sstevel@tonic-gate 
1924*7c478bd9Sstevel@tonic-gate 	if (sy_flags == SE_64RVAL)
1925*7c478bd9Sstevel@tonic-gate 		au_write(ad, au_to_return64(err, rval));
1926*7c478bd9Sstevel@tonic-gate 	else
1927*7c478bd9Sstevel@tonic-gate 		au_write(ad, au_to_return32(err, rval));
1928*7c478bd9Sstevel@tonic-gate 
1929*7c478bd9Sstevel@tonic-gate }
1930*7c478bd9Sstevel@tonic-gate 
1931*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
1932*7c478bd9Sstevel@tonic-gate void
1933*7c478bd9Sstevel@tonic-gate audit_fdsend(fd, fp, error)
1934*7c478bd9Sstevel@tonic-gate 	int fd;
1935*7c478bd9Sstevel@tonic-gate 	struct file *fp;
1936*7c478bd9Sstevel@tonic-gate 	int error;		/* ignore for now */
1937*7c478bd9Sstevel@tonic-gate {
1938*7c478bd9Sstevel@tonic-gate 	t_audit_data_t *tad;	/* current thread */
1939*7c478bd9Sstevel@tonic-gate 	f_audit_data_t *fad;	/* per file audit structure */
1940*7c478bd9Sstevel@tonic-gate 	struct vnode *vp;	/* for file attributes */
1941*7c478bd9Sstevel@tonic-gate 
1942*7c478bd9Sstevel@tonic-gate 	/* is this system call being audited */
1943*7c478bd9Sstevel@tonic-gate 	tad = U2A(u);
1944*7c478bd9Sstevel@tonic-gate 	ASSERT(tad != (t_audit_data_t *)0);
1945*7c478bd9Sstevel@tonic-gate 	if (!tad->tad_flag)
1946*7c478bd9Sstevel@tonic-gate 		return;
1947*7c478bd9Sstevel@tonic-gate 
1948*7c478bd9Sstevel@tonic-gate 	fad = F2A(fp);
1949*7c478bd9Sstevel@tonic-gate 
1950*7c478bd9Sstevel@tonic-gate 	/* add path and file attributes */
1951*7c478bd9Sstevel@tonic-gate 	if (fad != NULL && fad->fad_aupath != NULL) {
1952*7c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_arg32(0, "send fd", (uint32_t)fd));
1953*7c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_path(fad->fad_aupath));
1954*7c478bd9Sstevel@tonic-gate 	} else {
1955*7c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_arg32(0, "send fd", (uint32_t)fd));
1956*7c478bd9Sstevel@tonic-gate #ifdef _LP64
1957*7c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_arg64(0, "no path", (uint64_t)fp));
1958*7c478bd9Sstevel@tonic-gate #else
1959*7c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_arg32(0, "no path", (uint32_t)fp));
1960*7c478bd9Sstevel@tonic-gate #endif
1961*7c478bd9Sstevel@tonic-gate 	}
1962*7c478bd9Sstevel@tonic-gate 	vp = fp->f_vnode;	/* include vnode attributes */
1963*7c478bd9Sstevel@tonic-gate 	audit_attributes(vp);
1964*7c478bd9Sstevel@tonic-gate }
1965*7c478bd9Sstevel@tonic-gate 
1966*7c478bd9Sstevel@tonic-gate /*
1967*7c478bd9Sstevel@tonic-gate  * Record privileges sucessfully used and we attempted to use but
1968*7c478bd9Sstevel@tonic-gate  * didn't have.
1969*7c478bd9Sstevel@tonic-gate  */
1970*7c478bd9Sstevel@tonic-gate void
1971*7c478bd9Sstevel@tonic-gate audit_priv(int priv, const priv_set_t *set, int flag)
1972*7c478bd9Sstevel@tonic-gate {
1973*7c478bd9Sstevel@tonic-gate 	t_audit_data_t *tad;
1974*7c478bd9Sstevel@tonic-gate 	int sbit;
1975*7c478bd9Sstevel@tonic-gate 	priv_set_t *target;
1976*7c478bd9Sstevel@tonic-gate 
1977*7c478bd9Sstevel@tonic-gate 	/* Make sure this isn't being called in an interrupt context */
1978*7c478bd9Sstevel@tonic-gate 	ASSERT(servicing_interrupt() == 0);
1979*7c478bd9Sstevel@tonic-gate 
1980*7c478bd9Sstevel@tonic-gate 	tad = U2A(u);
1981*7c478bd9Sstevel@tonic-gate 
1982*7c478bd9Sstevel@tonic-gate 	if (tad->tad_flag == 0)
1983*7c478bd9Sstevel@tonic-gate 		return;
1984*7c478bd9Sstevel@tonic-gate 
1985*7c478bd9Sstevel@tonic-gate 	target = flag ? &tad->tad_sprivs : &tad->tad_fprivs;
1986*7c478bd9Sstevel@tonic-gate 	sbit = flag ? PAD_SPRIVUSE : PAD_FPRIVUSE;
1987*7c478bd9Sstevel@tonic-gate 
1988*7c478bd9Sstevel@tonic-gate 	/* Tell audit_success() and audit_finish() that we saw this case */
1989*7c478bd9Sstevel@tonic-gate 	if (!(tad->tad_evmod & sbit)) {
1990*7c478bd9Sstevel@tonic-gate 		/* Clear set first time around */
1991*7c478bd9Sstevel@tonic-gate 		priv_emptyset(target);
1992*7c478bd9Sstevel@tonic-gate 		tad->tad_evmod |= sbit;
1993*7c478bd9Sstevel@tonic-gate 	}
1994*7c478bd9Sstevel@tonic-gate 
1995*7c478bd9Sstevel@tonic-gate 	/* Save the privileges in the tad */
1996*7c478bd9Sstevel@tonic-gate 	if (priv == PRIV_ALL) {
1997*7c478bd9Sstevel@tonic-gate 		priv_fillset(target);
1998*7c478bd9Sstevel@tonic-gate 	} else {
1999*7c478bd9Sstevel@tonic-gate 		ASSERT(set != NULL || priv != PRIV_NONE);
2000*7c478bd9Sstevel@tonic-gate 		if (set != NULL)
2001*7c478bd9Sstevel@tonic-gate 			priv_union(set, target);
2002*7c478bd9Sstevel@tonic-gate 		if (priv != PRIV_NONE)
2003*7c478bd9Sstevel@tonic-gate 			priv_addset(target, priv);
2004*7c478bd9Sstevel@tonic-gate 	}
2005*7c478bd9Sstevel@tonic-gate }
2006*7c478bd9Sstevel@tonic-gate 
2007*7c478bd9Sstevel@tonic-gate /*
2008*7c478bd9Sstevel@tonic-gate  * Audit the setpriv() system call; the operation, the set name and
2009*7c478bd9Sstevel@tonic-gate  * the current value as well as the set argument are put in the
2010*7c478bd9Sstevel@tonic-gate  * audit trail.
2011*7c478bd9Sstevel@tonic-gate  */
2012*7c478bd9Sstevel@tonic-gate void
2013*7c478bd9Sstevel@tonic-gate audit_setppriv(int op, int set, const priv_set_t *newpriv, const cred_t *ocr)
2014*7c478bd9Sstevel@tonic-gate {
2015*7c478bd9Sstevel@tonic-gate 	t_audit_data_t *tad;
2016*7c478bd9Sstevel@tonic-gate 	const priv_set_t *oldpriv;
2017*7c478bd9Sstevel@tonic-gate 	priv_set_t report;
2018*7c478bd9Sstevel@tonic-gate 	const char *setname;
2019*7c478bd9Sstevel@tonic-gate 
2020*7c478bd9Sstevel@tonic-gate 	tad = U2A(u);
2021*7c478bd9Sstevel@tonic-gate 
2022*7c478bd9Sstevel@tonic-gate 	if (tad->tad_flag == 0)
2023*7c478bd9Sstevel@tonic-gate 		return;
2024*7c478bd9Sstevel@tonic-gate 
2025*7c478bd9Sstevel@tonic-gate 	oldpriv = priv_getset(ocr, set);
2026*7c478bd9Sstevel@tonic-gate 
2027*7c478bd9Sstevel@tonic-gate 	/* Generate the actual record, include the before and after */
2028*7c478bd9Sstevel@tonic-gate 	au_uwrite(au_to_arg32(2, "op", op));
2029*7c478bd9Sstevel@tonic-gate 	setname = priv_getsetbynum(set);
2030*7c478bd9Sstevel@tonic-gate 
2031*7c478bd9Sstevel@tonic-gate 	switch (op) {
2032*7c478bd9Sstevel@tonic-gate 	case PRIV_OFF:
2033*7c478bd9Sstevel@tonic-gate 		/* Report privileges actually switched off */
2034*7c478bd9Sstevel@tonic-gate 		report = *oldpriv;
2035*7c478bd9Sstevel@tonic-gate 		priv_intersect(newpriv, &report);
2036*7c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_privset(setname, &report, AUT_PRIV, 0));
2037*7c478bd9Sstevel@tonic-gate 		break;
2038*7c478bd9Sstevel@tonic-gate 	case PRIV_ON:
2039*7c478bd9Sstevel@tonic-gate 		/* Report privileges actually switched on */
2040*7c478bd9Sstevel@tonic-gate 		report = *oldpriv;
2041*7c478bd9Sstevel@tonic-gate 		priv_inverse(&report);
2042*7c478bd9Sstevel@tonic-gate 		priv_intersect(newpriv, &report);
2043*7c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_privset(setname, &report, AUT_PRIV, 0));
2044*7c478bd9Sstevel@tonic-gate 		break;
2045*7c478bd9Sstevel@tonic-gate 	case PRIV_SET:
2046*7c478bd9Sstevel@tonic-gate 		/* Report before and after */
2047*7c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_privset(setname, oldpriv, AUT_PRIV, 0));
2048*7c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_privset(setname, newpriv, AUT_PRIV, 0));
2049*7c478bd9Sstevel@tonic-gate 		break;
2050*7c478bd9Sstevel@tonic-gate 	}
2051*7c478bd9Sstevel@tonic-gate }
2052*7c478bd9Sstevel@tonic-gate 
2053*7c478bd9Sstevel@tonic-gate /*
2054*7c478bd9Sstevel@tonic-gate  * Dump the full device policy setting in the audit trail.
2055*7c478bd9Sstevel@tonic-gate  */
2056*7c478bd9Sstevel@tonic-gate void
2057*7c478bd9Sstevel@tonic-gate audit_devpolicy(int nitems, const devplcysys_t *items)
2058*7c478bd9Sstevel@tonic-gate {
2059*7c478bd9Sstevel@tonic-gate 	t_audit_data_t *tad;
2060*7c478bd9Sstevel@tonic-gate 	int i;
2061*7c478bd9Sstevel@tonic-gate 
2062*7c478bd9Sstevel@tonic-gate 	tad = U2A(u);
2063*7c478bd9Sstevel@tonic-gate 
2064*7c478bd9Sstevel@tonic-gate 	if (tad->tad_flag == 0)
2065*7c478bd9Sstevel@tonic-gate 		return;
2066*7c478bd9Sstevel@tonic-gate 
2067*7c478bd9Sstevel@tonic-gate 	for (i = 0; i < nitems; i++) {
2068*7c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_arg32(2, "major", items[i].dps_maj));
2069*7c478bd9Sstevel@tonic-gate 		if (items[i].dps_minornm[0] == '\0') {
2070*7c478bd9Sstevel@tonic-gate 			au_uwrite(au_to_arg32(2, "lomin", items[i].dps_lomin));
2071*7c478bd9Sstevel@tonic-gate 			au_uwrite(au_to_arg32(2, "himin", items[i].dps_himin));
2072*7c478bd9Sstevel@tonic-gate 		} else
2073*7c478bd9Sstevel@tonic-gate 			au_uwrite(au_to_text(items[i].dps_minornm));
2074*7c478bd9Sstevel@tonic-gate 
2075*7c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_privset("read", &items[i].dps_rdp,
2076*7c478bd9Sstevel@tonic-gate 		    AUT_PRIV, 0));
2077*7c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_privset("write", &items[i].dps_wrp,
2078*7c478bd9Sstevel@tonic-gate 		    AUT_PRIV, 0));
2079*7c478bd9Sstevel@tonic-gate 	}
2080*7c478bd9Sstevel@tonic-gate }
2081*7c478bd9Sstevel@tonic-gate 
2082*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
2083*7c478bd9Sstevel@tonic-gate void
2084*7c478bd9Sstevel@tonic-gate audit_fdrecv(fd, fp)
2085*7c478bd9Sstevel@tonic-gate 	int fd;
2086*7c478bd9Sstevel@tonic-gate 	struct file *fp;
2087*7c478bd9Sstevel@tonic-gate {
2088*7c478bd9Sstevel@tonic-gate 	t_audit_data_t *tad;	/* current thread */
2089*7c478bd9Sstevel@tonic-gate 	f_audit_data_t *fad;	/* per file audit structure */
2090*7c478bd9Sstevel@tonic-gate 	struct vnode *vp;	/* for file attributes */
2091*7c478bd9Sstevel@tonic-gate 
2092*7c478bd9Sstevel@tonic-gate 	/* is this system call being audited */
2093*7c478bd9Sstevel@tonic-gate 	tad = U2A(u);
2094*7c478bd9Sstevel@tonic-gate 	ASSERT(tad != (t_audit_data_t *)0);
2095*7c478bd9Sstevel@tonic-gate 	if (!tad->tad_flag)
2096*7c478bd9Sstevel@tonic-gate 		return;
2097*7c478bd9Sstevel@tonic-gate 
2098*7c478bd9Sstevel@tonic-gate 	fad = F2A(fp);
2099*7c478bd9Sstevel@tonic-gate 
2100*7c478bd9Sstevel@tonic-gate 	/* add path and file attributes */
2101*7c478bd9Sstevel@tonic-gate 	if (fad != NULL && fad->fad_aupath != NULL) {
2102*7c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_arg32(0, "recv fd", (uint32_t)fd));
2103*7c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_path(fad->fad_aupath));
2104*7c478bd9Sstevel@tonic-gate 	} else {
2105*7c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_arg32(0, "recv fd", (uint32_t)fd));
2106*7c478bd9Sstevel@tonic-gate #ifdef _LP64
2107*7c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_arg64(0, "no path", (uint64_t)fp));
2108*7c478bd9Sstevel@tonic-gate #else
2109*7c478bd9Sstevel@tonic-gate 		au_uwrite(au_to_arg32(0, "no path", (uint32_t)fp));
2110*7c478bd9Sstevel@tonic-gate #endif
2111*7c478bd9Sstevel@tonic-gate 	}
2112*7c478bd9Sstevel@tonic-gate 	vp = fp->f_vnode;	/* include vnode attributes */
2113*7c478bd9Sstevel@tonic-gate 	audit_attributes(vp);
2114*7c478bd9Sstevel@tonic-gate }
2115*7c478bd9Sstevel@tonic-gate 
2116*7c478bd9Sstevel@tonic-gate /*
2117*7c478bd9Sstevel@tonic-gate  * ROUTINE:	AUDIT_CRYPTOADM
2118*7c478bd9Sstevel@tonic-gate  * PURPOSE:	Records arguments to administrative ioctls on /dev/cryptoadm
2119*7c478bd9Sstevel@tonic-gate  * CALLBY:	CRYPTO_LOAD_DEV_DISABLED, CRYPTO_LOAD_SOFT_DISABLED,
2120*7c478bd9Sstevel@tonic-gate  *		CRYPTO_UNLOAD_SOFT_MODULE, CRYPTO_LOAD_SOFT_CONFIG,
2121*7c478bd9Sstevel@tonic-gate  *		CRYPTO_POOL_CREATE, CRYPTO_POOL_WAIT, CRYPTO_POOL_RUN,
2122*7c478bd9Sstevel@tonic-gate  *		CRYPTO_LOAD_DOOR
2123*7c478bd9Sstevel@tonic-gate  * NOTE:
2124*7c478bd9Sstevel@tonic-gate  * TODO:
2125*7c478bd9Sstevel@tonic-gate  * QUESTION:
2126*7c478bd9Sstevel@tonic-gate  */
2127*7c478bd9Sstevel@tonic-gate 
2128*7c478bd9Sstevel@tonic-gate void
2129*7c478bd9Sstevel@tonic-gate audit_cryptoadm(int cmd, char *module_name, crypto_mech_name_t *mech_names,
2130*7c478bd9Sstevel@tonic-gate     uint_t mech_count, uint_t device_instance, uint32_t rv, int error)
2131*7c478bd9Sstevel@tonic-gate {
2132*7c478bd9Sstevel@tonic-gate 	boolean_t		mech_list_required = B_FALSE;
2133*7c478bd9Sstevel@tonic-gate 	cred_t			*cr = CRED();
2134*7c478bd9Sstevel@tonic-gate 	t_audit_data_t		*tad;
2135*7c478bd9Sstevel@tonic-gate 	token_t			*ad = NULL;
2136*7c478bd9Sstevel@tonic-gate 	const auditinfo_addr_t	*ainfo = crgetauinfo(cr);
2137*7c478bd9Sstevel@tonic-gate 	char			buffer[MAXNAMELEN * 2];
2138*7c478bd9Sstevel@tonic-gate 	au_kcontext_t		*kctx = SET_KCTX_PZ;
2139*7c478bd9Sstevel@tonic-gate 
2140*7c478bd9Sstevel@tonic-gate 	ASSERT(kctx != NULL);
2141*7c478bd9Sstevel@tonic-gate 
2142*7c478bd9Sstevel@tonic-gate 	tad = U2A(u);
2143*7c478bd9Sstevel@tonic-gate 	if (tad == NULL)
2144*7c478bd9Sstevel@tonic-gate 		return;
2145*7c478bd9Sstevel@tonic-gate 
2146*7c478bd9Sstevel@tonic-gate 	if (ainfo == NULL)
2147*7c478bd9Sstevel@tonic-gate 		return;
2148*7c478bd9Sstevel@tonic-gate 
2149*7c478bd9Sstevel@tonic-gate 	tad->tad_event = AUE_CRYPTOADM;
2150*7c478bd9Sstevel@tonic-gate 
2151*7c478bd9Sstevel@tonic-gate 	if (audit_success(kctx, tad, error) != AU_OK)
2152*7c478bd9Sstevel@tonic-gate 		return;
2153*7c478bd9Sstevel@tonic-gate 
2154*7c478bd9Sstevel@tonic-gate 	/* Add a subject token */
2155*7c478bd9Sstevel@tonic-gate 	AUDIT_SETSUBJ((caddr_t *)&(ad), cr, ainfo);
2156*7c478bd9Sstevel@tonic-gate 
2157*7c478bd9Sstevel@tonic-gate 	/* add an optional group token */
2158*7c478bd9Sstevel@tonic-gate 	AUDIT_SETGROUP((caddr_t *)&(ad), cr, kctx);
2159*7c478bd9Sstevel@tonic-gate 
2160*7c478bd9Sstevel@tonic-gate 	switch (cmd) {
2161*7c478bd9Sstevel@tonic-gate 	case CRYPTO_LOAD_DEV_DISABLED:
2162*7c478bd9Sstevel@tonic-gate 		if (error == 0 && rv == CRYPTO_SUCCESS) {
2163*7c478bd9Sstevel@tonic-gate 			(void) snprintf(buffer, sizeof (buffer),
2164*7c478bd9Sstevel@tonic-gate 			    "op=CRYPTO_LOAD_DEV_DISABLED, module=%s,"
2165*7c478bd9Sstevel@tonic-gate 			    " dev_instance=%d",
2166*7c478bd9Sstevel@tonic-gate 			    module_name, device_instance);
2167*7c478bd9Sstevel@tonic-gate 			mech_list_required = B_TRUE;
2168*7c478bd9Sstevel@tonic-gate 		} else {
2169*7c478bd9Sstevel@tonic-gate 			(void) snprintf(buffer, sizeof (buffer),
2170*7c478bd9Sstevel@tonic-gate 			    "op=CRYPTO_LOAD_DEV_DISABLED, return_val=%d", rv);
2171*7c478bd9Sstevel@tonic-gate 		}
2172*7c478bd9Sstevel@tonic-gate 		break;
2173*7c478bd9Sstevel@tonic-gate 
2174*7c478bd9Sstevel@tonic-gate 	case CRYPTO_LOAD_SOFT_DISABLED:
2175*7c478bd9Sstevel@tonic-gate 		if (error == 0 && rv == CRYPTO_SUCCESS) {
2176*7c478bd9Sstevel@tonic-gate 			(void) snprintf(buffer, sizeof (buffer),
2177*7c478bd9Sstevel@tonic-gate 			    "op=CRYPTO_LOAD_SOFT_DISABLED, module=%s",
2178*7c478bd9Sstevel@tonic-gate 			    module_name);
2179*7c478bd9Sstevel@tonic-gate 			mech_list_required = B_TRUE;
2180*7c478bd9Sstevel@tonic-gate 		} else {
2181*7c478bd9Sstevel@tonic-gate 			(void) snprintf(buffer, sizeof (buffer),
2182*7c478bd9Sstevel@tonic-gate 			    "op=CRYPTO_LOAD_SOFT_DISABLED, return_val=%d", rv);
2183*7c478bd9Sstevel@tonic-gate 		}
2184*7c478bd9Sstevel@tonic-gate 		break;
2185*7c478bd9Sstevel@tonic-gate 
2186*7c478bd9Sstevel@tonic-gate 	case CRYPTO_UNLOAD_SOFT_MODULE:
2187*7c478bd9Sstevel@tonic-gate 		if (error == 0 && rv == CRYPTO_SUCCESS) {
2188*7c478bd9Sstevel@tonic-gate 			(void) snprintf(buffer, sizeof (buffer),
2189*7c478bd9Sstevel@tonic-gate 			    "op=CRYPTO_UNLOAD_SOFT_MODULE, module=%s",
2190*7c478bd9Sstevel@tonic-gate 			    module_name);
2191*7c478bd9Sstevel@tonic-gate 		} else {
2192*7c478bd9Sstevel@tonic-gate 			(void) snprintf(buffer, sizeof (buffer),
2193*7c478bd9Sstevel@tonic-gate 			    "op=CRYPTO_UNLOAD_SOFT_MODULE, return_val=%d", rv);
2194*7c478bd9Sstevel@tonic-gate 		}
2195*7c478bd9Sstevel@tonic-gate 		break;
2196*7c478bd9Sstevel@tonic-gate 
2197*7c478bd9Sstevel@tonic-gate 	case CRYPTO_LOAD_SOFT_CONFIG:
2198*7c478bd9Sstevel@tonic-gate 		if (error == 0 && rv == CRYPTO_SUCCESS) {
2199*7c478bd9Sstevel@tonic-gate 			(void) snprintf(buffer, sizeof (buffer),
2200*7c478bd9Sstevel@tonic-gate 			    "op=CRYPTO_LOAD_SOFT_CONFIG, module=%s",
2201*7c478bd9Sstevel@tonic-gate 			    module_name);
2202*7c478bd9Sstevel@tonic-gate 			mech_list_required = B_TRUE;
2203*7c478bd9Sstevel@tonic-gate 		} else {
2204*7c478bd9Sstevel@tonic-gate 			(void) snprintf(buffer, sizeof (buffer),
2205*7c478bd9Sstevel@tonic-gate 			    "op=CRYPTO_LOAD_SOFT_CONFIG, return_val=%d", rv);
2206*7c478bd9Sstevel@tonic-gate 		}
2207*7c478bd9Sstevel@tonic-gate 		break;
2208*7c478bd9Sstevel@tonic-gate 
2209*7c478bd9Sstevel@tonic-gate 	case CRYPTO_POOL_CREATE:
2210*7c478bd9Sstevel@tonic-gate 		(void) snprintf(buffer, sizeof (buffer),
2211*7c478bd9Sstevel@tonic-gate 		    "op=CRYPTO_POOL_CREATE");
2212*7c478bd9Sstevel@tonic-gate 		break;
2213*7c478bd9Sstevel@tonic-gate 
2214*7c478bd9Sstevel@tonic-gate 	case CRYPTO_POOL_WAIT:
2215*7c478bd9Sstevel@tonic-gate 		(void) snprintf(buffer, sizeof (buffer), "op=CRYPTO_POOL_WAIT");
2216*7c478bd9Sstevel@tonic-gate 		break;
2217*7c478bd9Sstevel@tonic-gate 
2218*7c478bd9Sstevel@tonic-gate 	case CRYPTO_POOL_RUN:
2219*7c478bd9Sstevel@tonic-gate 		(void) snprintf(buffer, sizeof (buffer), "op=CRYPTO_POOL_RUN");
2220*7c478bd9Sstevel@tonic-gate 		break;
2221*7c478bd9Sstevel@tonic-gate 
2222*7c478bd9Sstevel@tonic-gate 	case CRYPTO_LOAD_DOOR:
2223*7c478bd9Sstevel@tonic-gate 		if (error == 0 && rv == CRYPTO_SUCCESS)
2224*7c478bd9Sstevel@tonic-gate 			(void) snprintf(buffer, sizeof (buffer),
2225*7c478bd9Sstevel@tonic-gate 			    "op=CRYPTO_LOAD_DOOR");
2226*7c478bd9Sstevel@tonic-gate 		else
2227*7c478bd9Sstevel@tonic-gate 			(void) snprintf(buffer, sizeof (buffer),
2228*7c478bd9Sstevel@tonic-gate 			    "op=CRYPTO_LOAD_DOOR, return_val=%d", rv);
2229*7c478bd9Sstevel@tonic-gate 		break;
2230*7c478bd9Sstevel@tonic-gate 
2231*7c478bd9Sstevel@tonic-gate 	default:
2232*7c478bd9Sstevel@tonic-gate 		return;
2233*7c478bd9Sstevel@tonic-gate 	}
2234*7c478bd9Sstevel@tonic-gate 
2235*7c478bd9Sstevel@tonic-gate 	au_write((caddr_t *)&ad, au_to_text(buffer));
2236*7c478bd9Sstevel@tonic-gate 
2237*7c478bd9Sstevel@tonic-gate 	if (mech_list_required) {
2238*7c478bd9Sstevel@tonic-gate 		int i;
2239*7c478bd9Sstevel@tonic-gate 
2240*7c478bd9Sstevel@tonic-gate 		if (mech_count == 0) {
2241*7c478bd9Sstevel@tonic-gate 			au_write((caddr_t *)&ad, au_to_text("mech=list empty"));
2242*7c478bd9Sstevel@tonic-gate 		} else {
2243*7c478bd9Sstevel@tonic-gate 			char	*pb = buffer;
2244*7c478bd9Sstevel@tonic-gate 			size_t	l = sizeof (buffer);
2245*7c478bd9Sstevel@tonic-gate 			size_t	n;
2246*7c478bd9Sstevel@tonic-gate 			char	space[2] = ":";
2247*7c478bd9Sstevel@tonic-gate 
2248*7c478bd9Sstevel@tonic-gate 			n = snprintf(pb, l, "mech=");
2249*7c478bd9Sstevel@tonic-gate 
2250*7c478bd9Sstevel@tonic-gate 			for (i = 0; i < mech_count; i++) {
2251*7c478bd9Sstevel@tonic-gate 				pb += n;
2252*7c478bd9Sstevel@tonic-gate 				l -= n;
2253*7c478bd9Sstevel@tonic-gate 				if (l < 0)
2254*7c478bd9Sstevel@tonic-gate 					l = 0;
2255*7c478bd9Sstevel@tonic-gate 
2256*7c478bd9Sstevel@tonic-gate 				if (i == mech_count - 1)
2257*7c478bd9Sstevel@tonic-gate 					(void) strcpy(space, "");
2258*7c478bd9Sstevel@tonic-gate 
2259*7c478bd9Sstevel@tonic-gate 				n = snprintf(pb, l, "%s%s", mech_names[i],
2260*7c478bd9Sstevel@tonic-gate 				    space);
2261*7c478bd9Sstevel@tonic-gate 			}
2262*7c478bd9Sstevel@tonic-gate 			au_write((caddr_t *)&ad, au_to_text(buffer));
2263*7c478bd9Sstevel@tonic-gate 		}
2264*7c478bd9Sstevel@tonic-gate 	}
2265*7c478bd9Sstevel@tonic-gate 
2266*7c478bd9Sstevel@tonic-gate 	/* add a return token */
2267*7c478bd9Sstevel@tonic-gate 	if (error || (rv != CRYPTO_SUCCESS))
2268*7c478bd9Sstevel@tonic-gate 		add_return_token((caddr_t *)&ad, tad->tad_scid, -1, error);
2269*7c478bd9Sstevel@tonic-gate 	else
2270*7c478bd9Sstevel@tonic-gate 		add_return_token((caddr_t *)&ad, tad->tad_scid, 0, rv);
2271*7c478bd9Sstevel@tonic-gate 
2272*7c478bd9Sstevel@tonic-gate 	AS_INC(as_generated, 1, kctx);
2273*7c478bd9Sstevel@tonic-gate 	AS_INC(as_kernel, 1, kctx);
2274*7c478bd9Sstevel@tonic-gate 
2275*7c478bd9Sstevel@tonic-gate 	au_close(kctx, (caddr_t *)&ad, AU_OK, AUE_CRYPTOADM, 0);
2276*7c478bd9Sstevel@tonic-gate }
2277