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