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