17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 545916cd2Sjpk * Common Development and Distribution License (the "License"). 645916cd2Sjpk * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 21794f0adbSRoger A. Faulkner 227c478bd9Sstevel@tonic-gate /* 23134a1f4eSCasper H.S. Dik * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved. 247c478bd9Sstevel@tonic-gate */ 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate /* 277c478bd9Sstevel@tonic-gate * This file contains the audit hook support code for auditing. 287c478bd9Sstevel@tonic-gate */ 297c478bd9Sstevel@tonic-gate 307c478bd9Sstevel@tonic-gate #include <sys/types.h> 317c478bd9Sstevel@tonic-gate #include <sys/proc.h> 327c478bd9Sstevel@tonic-gate #include <sys/vnode.h> 337c478bd9Sstevel@tonic-gate #include <sys/vfs.h> 347c478bd9Sstevel@tonic-gate #include <sys/file.h> 357c478bd9Sstevel@tonic-gate #include <sys/user.h> 367c478bd9Sstevel@tonic-gate #include <sys/stropts.h> 377c478bd9Sstevel@tonic-gate #include <sys/systm.h> 387c478bd9Sstevel@tonic-gate #include <sys/pathname.h> 397c478bd9Sstevel@tonic-gate #include <sys/syscall.h> 407c478bd9Sstevel@tonic-gate #include <sys/fcntl.h> 417c478bd9Sstevel@tonic-gate #include <sys/ipc_impl.h> 427c478bd9Sstevel@tonic-gate #include <sys/msg_impl.h> 437c478bd9Sstevel@tonic-gate #include <sys/sem_impl.h> 447c478bd9Sstevel@tonic-gate #include <sys/shm_impl.h> 457c478bd9Sstevel@tonic-gate #include <sys/kmem.h> /* for KM_SLEEP */ 467c478bd9Sstevel@tonic-gate #include <sys/socket.h> 477c478bd9Sstevel@tonic-gate #include <sys/cmn_err.h> /* snprintf... */ 487c478bd9Sstevel@tonic-gate #include <sys/debug.h> 497c478bd9Sstevel@tonic-gate #include <sys/thread.h> 507c478bd9Sstevel@tonic-gate #include <netinet/in.h> 517c478bd9Sstevel@tonic-gate #include <c2/audit.h> /* needs to be included before user.h */ 527c478bd9Sstevel@tonic-gate #include <c2/audit_kernel.h> /* for M_DONTWAIT */ 537c478bd9Sstevel@tonic-gate #include <c2/audit_kevents.h> 547c478bd9Sstevel@tonic-gate #include <c2/audit_record.h> 557c478bd9Sstevel@tonic-gate #include <sys/strsubr.h> 567c478bd9Sstevel@tonic-gate #include <sys/tihdr.h> 577c478bd9Sstevel@tonic-gate #include <sys/tiuser.h> 587c478bd9Sstevel@tonic-gate #include <sys/timod.h> 597c478bd9Sstevel@tonic-gate #include <sys/model.h> /* for model_t */ 607c478bd9Sstevel@tonic-gate #include <sys/disp.h> /* for servicing_interrupt() */ 617c478bd9Sstevel@tonic-gate #include <sys/devpolicy.h> 627c478bd9Sstevel@tonic-gate #include <sys/crypto/ioctladmin.h> 63134a1f4eSCasper H.S. Dik #include <sys/cred_impl.h> 64c28749e9Skais #include <inet/kssl/kssl.h> 65799bd290Spwernau #include <net/pfpolicy.h> 667c478bd9Sstevel@tonic-gate 677c478bd9Sstevel@tonic-gate static void add_return_token(caddr_t *, unsigned int scid, int err, int rval); 687c478bd9Sstevel@tonic-gate 697c478bd9Sstevel@tonic-gate static void audit_pathbuild(struct pathname *pnp); 707c478bd9Sstevel@tonic-gate 717c478bd9Sstevel@tonic-gate 727c478bd9Sstevel@tonic-gate /* 737c478bd9Sstevel@tonic-gate * ROUTINE: AUDIT_SAVEPATH 747c478bd9Sstevel@tonic-gate * PURPOSE: 757c478bd9Sstevel@tonic-gate * CALLBY: LOOKUPPN 767c478bd9Sstevel@tonic-gate * 777c478bd9Sstevel@tonic-gate * NOTE: We have reached the end of a path in fs/lookup.c. 787c478bd9Sstevel@tonic-gate * We get two pieces of information here: 797c478bd9Sstevel@tonic-gate * the vnode of the last component (vp) and 807c478bd9Sstevel@tonic-gate * the status of the last access (flag). 817c478bd9Sstevel@tonic-gate * TODO: 827c478bd9Sstevel@tonic-gate * QUESTION: 837c478bd9Sstevel@tonic-gate */ 847c478bd9Sstevel@tonic-gate 857c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 867c478bd9Sstevel@tonic-gate int 877c478bd9Sstevel@tonic-gate audit_savepath( 887c478bd9Sstevel@tonic-gate struct pathname *pnp, /* pathname to lookup */ 897c478bd9Sstevel@tonic-gate struct vnode *vp, /* vnode of the last component */ 904a0fa546SMarek Pospisil struct vnode *pvp, /* vnode of the last parent component */ 917c478bd9Sstevel@tonic-gate int flag, /* status of the last access */ 927c478bd9Sstevel@tonic-gate cred_t *cr) /* cred of requestor */ 937c478bd9Sstevel@tonic-gate { 947c478bd9Sstevel@tonic-gate 957c478bd9Sstevel@tonic-gate t_audit_data_t *tad; /* current thread */ 969e9e6ab8Spaulson au_kcontext_t *kctx = GET_KCTX_PZ; 977c478bd9Sstevel@tonic-gate 987c478bd9Sstevel@tonic-gate tad = U2A(u); 997c478bd9Sstevel@tonic-gate 1007c478bd9Sstevel@tonic-gate /* 1014a0fa546SMarek Pospisil * Noise elimination in audit trails - this event will be discarded if: 1024a0fa546SMarek Pospisil * - the public policy is not active AND 1034a0fa546SMarek Pospisil * - the system call is a public operation AND 1044a0fa546SMarek Pospisil * - the file was not found: VFS lookup failed with ENOENT error AND 1054a0fa546SMarek Pospisil * - the missing file would have been located in the public directory 1064a0fa546SMarek Pospisil * owned by root if it had existed 1074a0fa546SMarek Pospisil */ 1084a0fa546SMarek Pospisil if (tad->tad_flag != 0 && flag == ENOENT && pvp != NULL && 1094a0fa546SMarek Pospisil (tad->tad_ctrl & TAD_PUBLIC_EV) && 1104a0fa546SMarek Pospisil !(kctx->auk_policy & AUDIT_PUBLIC)) { 1114a0fa546SMarek Pospisil struct vattr attr; 1124a0fa546SMarek Pospisil 1134a0fa546SMarek Pospisil attr.va_mask = AT_ALL; 1144a0fa546SMarek Pospisil if (VOP_GETATTR(pvp, &attr, 0, CRED(), NULL) == 0) { 1154a0fa546SMarek Pospisil if (object_is_public(&attr)) { 1164a0fa546SMarek Pospisil tad->tad_ctrl |= TAD_NOAUDIT; 1174a0fa546SMarek Pospisil } 1184a0fa546SMarek Pospisil } 1194a0fa546SMarek Pospisil } 1204a0fa546SMarek Pospisil 1214a0fa546SMarek Pospisil /* 1227c478bd9Sstevel@tonic-gate * this event being audited or do we need path information 1237c478bd9Sstevel@tonic-gate * later? This might be for a chdir/chroot or open (add path 1247c478bd9Sstevel@tonic-gate * to file pointer. If the path has already been found for an 1257c478bd9Sstevel@tonic-gate * open/creat then we don't need to process the path. 1267c478bd9Sstevel@tonic-gate * 1274a0fa546SMarek Pospisil * S2E_SP (TAD_SAVPATH) flag comes from audit_s2e[].au_ctrl. Used with 1287c478bd9Sstevel@tonic-gate * chroot, chdir, open, creat system call processing. It determines 1297c478bd9Sstevel@tonic-gate * if audit_savepath() will discard the path or we need it later. 1304a0fa546SMarek Pospisil * TAD_PATHFND means path already included in this audit record. It 1317c478bd9Sstevel@tonic-gate * is used in cases where multiple path lookups are done per 1327c478bd9Sstevel@tonic-gate * system call. The policy flag, AUDIT_PATH, controls if multiple 1337c478bd9Sstevel@tonic-gate * paths are allowed. 1344a0fa546SMarek Pospisil * S2E_NPT (TAD_NOPATH) flag comes from audit_s2e[].au_ctrl. Used with 1357c478bd9Sstevel@tonic-gate * exit processing to inhibit any paths that may be added due to 1367c478bd9Sstevel@tonic-gate * closes. 1377c478bd9Sstevel@tonic-gate */ 1384a0fa546SMarek Pospisil if ((tad->tad_flag == 0 && !(tad->tad_ctrl & TAD_SAVPATH)) || 1394a0fa546SMarek Pospisil ((tad->tad_ctrl & TAD_PATHFND) && 1407c478bd9Sstevel@tonic-gate !(kctx->auk_policy & AUDIT_PATH)) || 1414a0fa546SMarek Pospisil (tad->tad_ctrl & TAD_NOPATH)) { 1427c478bd9Sstevel@tonic-gate return (0); 1437c478bd9Sstevel@tonic-gate } 1447c478bd9Sstevel@tonic-gate 1454a0fa546SMarek Pospisil tad->tad_ctrl |= TAD_NOPATH; /* prevent possible reentry */ 14645916cd2Sjpk 1477c478bd9Sstevel@tonic-gate audit_pathbuild(pnp); 1487c478bd9Sstevel@tonic-gate 1497c478bd9Sstevel@tonic-gate /* 1507c478bd9Sstevel@tonic-gate * are we auditing only if error, or if it is not open or create 1517c478bd9Sstevel@tonic-gate * otherwise audit_setf will do it 1527c478bd9Sstevel@tonic-gate */ 1537c478bd9Sstevel@tonic-gate 1547c478bd9Sstevel@tonic-gate if (tad->tad_flag) { 1558fd04b83SRoger A. Faulkner if (flag && 1568fd04b83SRoger A. Faulkner (tad->tad_scid == SYS_open || 1577c478bd9Sstevel@tonic-gate tad->tad_scid == SYS_open64 || 1588fd04b83SRoger A. Faulkner tad->tad_scid == SYS_openat || 1598fd04b83SRoger A. Faulkner tad->tad_scid == SYS_openat64)) { 1604a0fa546SMarek Pospisil tad->tad_ctrl |= TAD_TRUE_CREATE; 1617c478bd9Sstevel@tonic-gate } 1627c478bd9Sstevel@tonic-gate 1637c478bd9Sstevel@tonic-gate /* add token to audit record for this name */ 1647c478bd9Sstevel@tonic-gate au_uwrite(au_to_path(tad->tad_aupath)); 1657c478bd9Sstevel@tonic-gate 1667c478bd9Sstevel@tonic-gate /* add the attributes of the object */ 1677c478bd9Sstevel@tonic-gate if (vp) { 1687c478bd9Sstevel@tonic-gate /* 1697c478bd9Sstevel@tonic-gate * only capture attributes when there is no error 1707c478bd9Sstevel@tonic-gate * lookup will not return the vnode of the failing 1717c478bd9Sstevel@tonic-gate * component. 1727c478bd9Sstevel@tonic-gate * 1737c478bd9Sstevel@tonic-gate * if there was a lookup error, then don't add 1747c478bd9Sstevel@tonic-gate * attribute. if lookup in vn_create(), 1757c478bd9Sstevel@tonic-gate * then don't add attribute, 1767c478bd9Sstevel@tonic-gate * it will be added at end of vn_create(). 1777c478bd9Sstevel@tonic-gate */ 1784a0fa546SMarek Pospisil if (!flag && !(tad->tad_ctrl & TAD_NOATTRB)) 1797c478bd9Sstevel@tonic-gate audit_attributes(vp); 1807c478bd9Sstevel@tonic-gate } 1817c478bd9Sstevel@tonic-gate } 1827c478bd9Sstevel@tonic-gate 1838fd04b83SRoger A. Faulkner /* free up space if we're not going to save path (open, creat) */ 1844a0fa546SMarek Pospisil if ((tad->tad_ctrl & TAD_SAVPATH) == 0) { 1857c478bd9Sstevel@tonic-gate if (tad->tad_aupath != NULL) { 1867c478bd9Sstevel@tonic-gate au_pathrele(tad->tad_aupath); 1877c478bd9Sstevel@tonic-gate tad->tad_aupath = NULL; 1887c478bd9Sstevel@tonic-gate } 1897c478bd9Sstevel@tonic-gate } 1904a0fa546SMarek Pospisil if (tad->tad_ctrl & TAD_MLD) 1914a0fa546SMarek Pospisil tad->tad_ctrl |= TAD_PATHFND; 1927c478bd9Sstevel@tonic-gate 1934a0fa546SMarek Pospisil tad->tad_ctrl &= ~TAD_NOPATH; /* restore */ 1947c478bd9Sstevel@tonic-gate return (0); 1957c478bd9Sstevel@tonic-gate } 1967c478bd9Sstevel@tonic-gate 1977c478bd9Sstevel@tonic-gate static void 1987c478bd9Sstevel@tonic-gate audit_pathbuild(struct pathname *pnp) 1997c478bd9Sstevel@tonic-gate { 2007c478bd9Sstevel@tonic-gate char *pp; /* pointer to path */ 2017c478bd9Sstevel@tonic-gate int len; /* length of incoming segment */ 2027c478bd9Sstevel@tonic-gate int newsect; /* path requires a new section */ 2037c478bd9Sstevel@tonic-gate struct audit_path *pfxapp; /* prefix for path */ 2047c478bd9Sstevel@tonic-gate struct audit_path *newapp; /* new audit_path */ 2057c478bd9Sstevel@tonic-gate t_audit_data_t *tad; /* current thread */ 2067c478bd9Sstevel@tonic-gate p_audit_data_t *pad; /* current process */ 2077c478bd9Sstevel@tonic-gate 2087c478bd9Sstevel@tonic-gate tad = U2A(u); 2097c478bd9Sstevel@tonic-gate ASSERT(tad != NULL); 2107c478bd9Sstevel@tonic-gate pad = P2A(curproc); 2117c478bd9Sstevel@tonic-gate ASSERT(pad != NULL); 2127c478bd9Sstevel@tonic-gate 2137c478bd9Sstevel@tonic-gate len = (pnp->pn_path - pnp->pn_buf) + 1; /* +1 for terminator */ 2147c478bd9Sstevel@tonic-gate ASSERT(len > 0); 2157c478bd9Sstevel@tonic-gate 2167c478bd9Sstevel@tonic-gate /* adjust for path prefix: tad_aupath, ATPATH, CRD, or CWD */ 2177c478bd9Sstevel@tonic-gate mutex_enter(&pad->pad_lock); 2187c478bd9Sstevel@tonic-gate if (tad->tad_aupath != NULL) { 2197c478bd9Sstevel@tonic-gate pfxapp = tad->tad_aupath; 2204a0fa546SMarek Pospisil } else if ((tad->tad_ctrl & TAD_ATCALL) && pnp->pn_buf[0] != '/') { 2217c478bd9Sstevel@tonic-gate ASSERT(tad->tad_atpath != NULL); 2227c478bd9Sstevel@tonic-gate pfxapp = tad->tad_atpath; 2234a0fa546SMarek Pospisil } else if (tad->tad_ctrl & TAD_ABSPATH) { 2247c478bd9Sstevel@tonic-gate pfxapp = pad->pad_root; 2257c478bd9Sstevel@tonic-gate } else { 2267c478bd9Sstevel@tonic-gate pfxapp = pad->pad_cwd; 2277c478bd9Sstevel@tonic-gate } 2287c478bd9Sstevel@tonic-gate au_pathhold(pfxapp); 2297c478bd9Sstevel@tonic-gate mutex_exit(&pad->pad_lock); 2307c478bd9Sstevel@tonic-gate 2317c478bd9Sstevel@tonic-gate /* get an expanded buffer to hold the anchored path */ 2324a0fa546SMarek Pospisil newsect = tad->tad_ctrl & TAD_ATTPATH; 2337c478bd9Sstevel@tonic-gate newapp = au_pathdup(pfxapp, newsect, len); 2347c478bd9Sstevel@tonic-gate au_pathrele(pfxapp); 2357c478bd9Sstevel@tonic-gate 2367c478bd9Sstevel@tonic-gate pp = newapp->audp_sect[newapp->audp_cnt] - len; 2377c478bd9Sstevel@tonic-gate if (!newsect) { 2387c478bd9Sstevel@tonic-gate /* overlay previous NUL terminator */ 2397c478bd9Sstevel@tonic-gate *(pp - 1) = '/'; 2407c478bd9Sstevel@tonic-gate } 2417c478bd9Sstevel@tonic-gate 2427c478bd9Sstevel@tonic-gate /* now add string of processed path */ 2437c478bd9Sstevel@tonic-gate bcopy(pnp->pn_buf, pp, len); 2447c478bd9Sstevel@tonic-gate pp[len - 1] = '\0'; 2457c478bd9Sstevel@tonic-gate 2467c478bd9Sstevel@tonic-gate /* perform path simplification as necessary */ 2477c478bd9Sstevel@tonic-gate audit_fixpath(newapp, len); 2487c478bd9Sstevel@tonic-gate 2497c478bd9Sstevel@tonic-gate if (tad->tad_aupath) 2507c478bd9Sstevel@tonic-gate au_pathrele(tad->tad_aupath); 2517c478bd9Sstevel@tonic-gate tad->tad_aupath = newapp; 2527c478bd9Sstevel@tonic-gate 2537c478bd9Sstevel@tonic-gate /* for case where multiple lookups in one syscall (rename) */ 2544a0fa546SMarek Pospisil tad->tad_ctrl &= ~(TAD_ABSPATH | TAD_ATTPATH); 2557c478bd9Sstevel@tonic-gate } 2567c478bd9Sstevel@tonic-gate 2577c478bd9Sstevel@tonic-gate 2587c478bd9Sstevel@tonic-gate /* 2597c478bd9Sstevel@tonic-gate * ROUTINE: AUDIT_ANCHORPATH 2607c478bd9Sstevel@tonic-gate * PURPOSE: 2617c478bd9Sstevel@tonic-gate * CALLBY: LOOKUPPN 2627c478bd9Sstevel@tonic-gate * NOTE: 2637c478bd9Sstevel@tonic-gate * anchor path at "/". We have seen a symbolic link or entering for the 2647c478bd9Sstevel@tonic-gate * first time we will throw away any saved path if path is anchored. 2657c478bd9Sstevel@tonic-gate * 2667c478bd9Sstevel@tonic-gate * flag = 0, path is relative. 2674a0fa546SMarek Pospisil * flag = 1, path is absolute. Free any saved path and set flag to TAD_ABSPATH. 2687c478bd9Sstevel@tonic-gate * 2697c478bd9Sstevel@tonic-gate * If the (new) path is absolute, then we have to throw away whatever we have 270da6c28aaSamw * already accumulated since it is being superseded by new path which is 2717c478bd9Sstevel@tonic-gate * anchored at the root. 2727c478bd9Sstevel@tonic-gate * Note that if the path is relative, this function does nothing 2737c478bd9Sstevel@tonic-gate * TODO: 2747c478bd9Sstevel@tonic-gate * QUESTION: 2757c478bd9Sstevel@tonic-gate */ 2767c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 2777c478bd9Sstevel@tonic-gate void 2787c478bd9Sstevel@tonic-gate audit_anchorpath(struct pathname *pnp, int flag) 2797c478bd9Sstevel@tonic-gate { 2809e9e6ab8Spaulson au_kcontext_t *kctx = GET_KCTX_PZ; 2817c478bd9Sstevel@tonic-gate t_audit_data_t *tad; 2827c478bd9Sstevel@tonic-gate 2837c478bd9Sstevel@tonic-gate tad = U2A(u); 2847c478bd9Sstevel@tonic-gate 2857c478bd9Sstevel@tonic-gate /* 2867c478bd9Sstevel@tonic-gate * this event being audited or do we need path information 2877c478bd9Sstevel@tonic-gate * later? This might be for a chdir/chroot or open (add path 2887c478bd9Sstevel@tonic-gate * to file pointer. If the path has already been found for an 2897c478bd9Sstevel@tonic-gate * open/creat then we don't need to process the path. 2907c478bd9Sstevel@tonic-gate * 2914a0fa546SMarek Pospisil * S2E_SP (TAD_SAVPATH) flag comes from audit_s2e[].au_ctrl. Used with 2927c478bd9Sstevel@tonic-gate * chroot, chdir, open, creat system call processing. It determines 2937c478bd9Sstevel@tonic-gate * if audit_savepath() will discard the path or we need it later. 2944a0fa546SMarek Pospisil * TAD_PATHFND means path already included in this audit record. It 2957c478bd9Sstevel@tonic-gate * is used in cases where multiple path lookups are done per 2967c478bd9Sstevel@tonic-gate * system call. The policy flag, AUDIT_PATH, controls if multiple 2977c478bd9Sstevel@tonic-gate * paths are allowed. 2984a0fa546SMarek Pospisil * S2E_NPT (TAD_NOPATH) flag comes from audit_s2e[].au_ctrl. Used with 2997c478bd9Sstevel@tonic-gate * exit processing to inhibit any paths that may be added due to 3007c478bd9Sstevel@tonic-gate * closes. 3017c478bd9Sstevel@tonic-gate */ 3024a0fa546SMarek Pospisil if ((tad->tad_flag == 0 && !(tad->tad_ctrl & TAD_SAVPATH)) || 3034a0fa546SMarek Pospisil ((tad->tad_ctrl & TAD_PATHFND) && 3047c478bd9Sstevel@tonic-gate !(kctx->auk_policy & AUDIT_PATH)) || 3054a0fa546SMarek Pospisil (tad->tad_ctrl & TAD_NOPATH)) { 3067c478bd9Sstevel@tonic-gate return; 3077c478bd9Sstevel@tonic-gate } 3087c478bd9Sstevel@tonic-gate 3097c478bd9Sstevel@tonic-gate if (flag) { 3104a0fa546SMarek Pospisil tad->tad_ctrl |= TAD_ABSPATH; 3117c478bd9Sstevel@tonic-gate if (tad->tad_aupath != NULL) { 3127c478bd9Sstevel@tonic-gate au_pathrele(tad->tad_aupath); 3137c478bd9Sstevel@tonic-gate tad->tad_aupath = NULL; 3147c478bd9Sstevel@tonic-gate } 3157c478bd9Sstevel@tonic-gate } 3167c478bd9Sstevel@tonic-gate } 3177c478bd9Sstevel@tonic-gate 3187c478bd9Sstevel@tonic-gate 3197c478bd9Sstevel@tonic-gate /* 3207c478bd9Sstevel@tonic-gate * symbolic link. Save previous components. 3217c478bd9Sstevel@tonic-gate * 3227c478bd9Sstevel@tonic-gate * the path seen so far looks like this 3237c478bd9Sstevel@tonic-gate * 3247c478bd9Sstevel@tonic-gate * +-----------------------+----------------+ 3257c478bd9Sstevel@tonic-gate * | path processed so far | remaining path | 3267c478bd9Sstevel@tonic-gate * +-----------------------+----------------+ 3277c478bd9Sstevel@tonic-gate * \-----------------------/ 3287c478bd9Sstevel@tonic-gate * save this string if 3297c478bd9Sstevel@tonic-gate * symbolic link relative 3307c478bd9Sstevel@tonic-gate * (but don't include symlink component) 3317c478bd9Sstevel@tonic-gate */ 3327c478bd9Sstevel@tonic-gate 3337c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 3347c478bd9Sstevel@tonic-gate 3357c478bd9Sstevel@tonic-gate 3367c478bd9Sstevel@tonic-gate /* 3377c478bd9Sstevel@tonic-gate * ROUTINE: AUDIT_SYMLINK 3387c478bd9Sstevel@tonic-gate * PURPOSE: 3397c478bd9Sstevel@tonic-gate * CALLBY: LOOKUPPN 3407c478bd9Sstevel@tonic-gate * NOTE: 3417c478bd9Sstevel@tonic-gate * TODO: 3427c478bd9Sstevel@tonic-gate * QUESTION: 3437c478bd9Sstevel@tonic-gate */ 3447c478bd9Sstevel@tonic-gate void 3457c478bd9Sstevel@tonic-gate audit_symlink(struct pathname *pnp, struct pathname *sympath) 3467c478bd9Sstevel@tonic-gate { 3477c478bd9Sstevel@tonic-gate char *sp; /* saved initial pp */ 3487c478bd9Sstevel@tonic-gate char *cp; /* start of symlink path */ 3497c478bd9Sstevel@tonic-gate uint_t len_path; /* processed path before symlink */ 3507c478bd9Sstevel@tonic-gate t_audit_data_t *tad; 3519e9e6ab8Spaulson au_kcontext_t *kctx = GET_KCTX_PZ; 3527c478bd9Sstevel@tonic-gate 3537c478bd9Sstevel@tonic-gate tad = U2A(u); 3547c478bd9Sstevel@tonic-gate 3557c478bd9Sstevel@tonic-gate /* 3567c478bd9Sstevel@tonic-gate * this event being audited or do we need path information 3577c478bd9Sstevel@tonic-gate * later? This might be for a chdir/chroot or open (add path 3587c478bd9Sstevel@tonic-gate * to file pointer. If the path has already been found for an 3597c478bd9Sstevel@tonic-gate * open/creat then we don't need to process the path. 3607c478bd9Sstevel@tonic-gate * 3614a0fa546SMarek Pospisil * S2E_SP (TAD_SAVPATH) flag comes from audit_s2e[].au_ctrl. Used with 3627c478bd9Sstevel@tonic-gate * chroot, chdir, open, creat system call processing. It determines 3637c478bd9Sstevel@tonic-gate * if audit_savepath() will discard the path or we need it later. 3644a0fa546SMarek Pospisil * TAD_PATHFND means path already included in this audit record. It 3657c478bd9Sstevel@tonic-gate * is used in cases where multiple path lookups are done per 3667c478bd9Sstevel@tonic-gate * system call. The policy flag, AUDIT_PATH, controls if multiple 3677c478bd9Sstevel@tonic-gate * paths are allowed. 3684a0fa546SMarek Pospisil * S2E_NPT (TAD_NOPATH) flag comes from audit_s2e[].au_ctrl. Used with 3697c478bd9Sstevel@tonic-gate * exit processing to inhibit any paths that may be added due to 3707c478bd9Sstevel@tonic-gate * closes. 3717c478bd9Sstevel@tonic-gate */ 3727c478bd9Sstevel@tonic-gate if ((tad->tad_flag == 0 && 3734a0fa546SMarek Pospisil !(tad->tad_ctrl & TAD_SAVPATH)) || 3744a0fa546SMarek Pospisil ((tad->tad_ctrl & TAD_PATHFND) && 3757c478bd9Sstevel@tonic-gate !(kctx->auk_policy & AUDIT_PATH)) || 3764a0fa546SMarek Pospisil (tad->tad_ctrl & TAD_NOPATH)) { 3777c478bd9Sstevel@tonic-gate return; 3787c478bd9Sstevel@tonic-gate } 3797c478bd9Sstevel@tonic-gate 3807c478bd9Sstevel@tonic-gate /* 3817c478bd9Sstevel@tonic-gate * if symbolic link is anchored at / then do nothing. 3827c478bd9Sstevel@tonic-gate * When we cycle back to begin: in lookuppn() we will 3837c478bd9Sstevel@tonic-gate * call audit_anchorpath() with a flag indicating if the 3847c478bd9Sstevel@tonic-gate * path is anchored at / or is relative. We will release 3857c478bd9Sstevel@tonic-gate * any saved path at that point. 3867c478bd9Sstevel@tonic-gate * 3877c478bd9Sstevel@tonic-gate * Note In the event that an error occurs in pn_combine then 3887c478bd9Sstevel@tonic-gate * we want to remain pointing at the component that caused the 3897c478bd9Sstevel@tonic-gate * path to overflow the pnp structure. 3907c478bd9Sstevel@tonic-gate */ 3917c478bd9Sstevel@tonic-gate if (sympath->pn_buf[0] == '/') 3927c478bd9Sstevel@tonic-gate return; 3937c478bd9Sstevel@tonic-gate 3947c478bd9Sstevel@tonic-gate /* backup over last component */ 3957c478bd9Sstevel@tonic-gate sp = cp = pnp->pn_path; 3967c478bd9Sstevel@tonic-gate while (*--cp != '/' && cp > pnp->pn_buf) 3977c478bd9Sstevel@tonic-gate ; 3987c478bd9Sstevel@tonic-gate 3997c478bd9Sstevel@tonic-gate len_path = cp - pnp->pn_buf; 4007c478bd9Sstevel@tonic-gate 4017c478bd9Sstevel@tonic-gate /* is there anything to save? */ 4027c478bd9Sstevel@tonic-gate if (len_path) { 403405e5d68Stz204579 pnp->pn_path = pnp->pn_buf; 4047c478bd9Sstevel@tonic-gate audit_pathbuild(pnp); 4057c478bd9Sstevel@tonic-gate pnp->pn_path = sp; 4067c478bd9Sstevel@tonic-gate } 4077c478bd9Sstevel@tonic-gate } 4087c478bd9Sstevel@tonic-gate 4097c478bd9Sstevel@tonic-gate /* 4104a0fa546SMarek Pospisil * object_is_public : determine whether events for the object (corresponding to 4114a0fa546SMarek Pospisil * the specified file/directory attr) should be audited or 4124a0fa546SMarek Pospisil * ignored. 4137c478bd9Sstevel@tonic-gate * 4144a0fa546SMarek Pospisil * returns: 1 - if audit policy and object attributes indicate that 4154a0fa546SMarek Pospisil * file/directory is effectively public. read events for 4167c478bd9Sstevel@tonic-gate * the file should not be audited. 4177c478bd9Sstevel@tonic-gate * 0 - otherwise 4187c478bd9Sstevel@tonic-gate * 4197c478bd9Sstevel@tonic-gate * The required attributes to be considered a public object are: 4207c478bd9Sstevel@tonic-gate * - owned by root, AND 4217c478bd9Sstevel@tonic-gate * - world-readable (permissions for other include read), AND 4227c478bd9Sstevel@tonic-gate * - NOT world-writeable (permissions for other don't 4237c478bd9Sstevel@tonic-gate * include write) 4247c478bd9Sstevel@tonic-gate * (mode doesn't need to be checked for symlinks) 4257c478bd9Sstevel@tonic-gate */ 4267c478bd9Sstevel@tonic-gate int 4274a0fa546SMarek Pospisil object_is_public(struct vattr *attr) 4287c478bd9Sstevel@tonic-gate { 4299e9e6ab8Spaulson au_kcontext_t *kctx = GET_KCTX_PZ; 4307c478bd9Sstevel@tonic-gate 4317c478bd9Sstevel@tonic-gate if (!(kctx->auk_policy & AUDIT_PUBLIC) && (attr->va_uid == 0) && 4327c478bd9Sstevel@tonic-gate ((attr->va_type == VLNK) || 4337c478bd9Sstevel@tonic-gate ((attr->va_mode & (VREAD>>6)) != 0) && 4347c478bd9Sstevel@tonic-gate ((attr->va_mode & (VWRITE>>6)) == 0))) { 4357c478bd9Sstevel@tonic-gate return (1); 4367c478bd9Sstevel@tonic-gate } 4377c478bd9Sstevel@tonic-gate return (0); 4387c478bd9Sstevel@tonic-gate } 4397c478bd9Sstevel@tonic-gate 4407c478bd9Sstevel@tonic-gate 4417c478bd9Sstevel@tonic-gate /* 4427c478bd9Sstevel@tonic-gate * ROUTINE: AUDIT_ATTRIBUTES 443da6c28aaSamw * PURPOSE: Audit the attributes so we can tell why the error occurred 4447c478bd9Sstevel@tonic-gate * CALLBY: AUDIT_SAVEPATH 4457c478bd9Sstevel@tonic-gate * AUDIT_VNCREATE_FINISH 4467c478bd9Sstevel@tonic-gate * AUS_FCHOWN...audit_event.c...audit_path.c 4477c478bd9Sstevel@tonic-gate * NOTE: 4487c478bd9Sstevel@tonic-gate * TODO: 4497c478bd9Sstevel@tonic-gate * QUESTION: 4507c478bd9Sstevel@tonic-gate */ 4517c478bd9Sstevel@tonic-gate void 4527c478bd9Sstevel@tonic-gate audit_attributes(struct vnode *vp) 4537c478bd9Sstevel@tonic-gate { 4547c478bd9Sstevel@tonic-gate struct vattr attr; 4557c478bd9Sstevel@tonic-gate struct t_audit_data *tad; 4567c478bd9Sstevel@tonic-gate 4577c478bd9Sstevel@tonic-gate tad = U2A(u); 4587c478bd9Sstevel@tonic-gate 4597c478bd9Sstevel@tonic-gate if (vp) { 4607c478bd9Sstevel@tonic-gate attr.va_mask = AT_ALL; 461da6c28aaSamw if (VOP_GETATTR(vp, &attr, 0, CRED(), NULL) != 0) 4627c478bd9Sstevel@tonic-gate return; 4637c478bd9Sstevel@tonic-gate 4644a0fa546SMarek Pospisil if (object_is_public(&attr) && 4654a0fa546SMarek Pospisil (tad->tad_ctrl & TAD_PUBLIC_EV)) { 4667c478bd9Sstevel@tonic-gate /* 4677c478bd9Sstevel@tonic-gate * This is a public object and a "public" event 4687c478bd9Sstevel@tonic-gate * (i.e., read only) -- either by definition 4697c478bd9Sstevel@tonic-gate * (e.g., stat, access...) or by virtue of write access 4707c478bd9Sstevel@tonic-gate * not being requested (e.g. mmap). 4717c478bd9Sstevel@tonic-gate * Flag it in the tad to prevent this audit at the end. 4727c478bd9Sstevel@tonic-gate */ 4734a0fa546SMarek Pospisil tad->tad_ctrl |= TAD_NOAUDIT; 4747c478bd9Sstevel@tonic-gate } else { 4757c478bd9Sstevel@tonic-gate au_uwrite(au_to_attr(&attr)); 47645916cd2Sjpk audit_sec_attributes(&(u_ad), vp); 4777c478bd9Sstevel@tonic-gate } 4787c478bd9Sstevel@tonic-gate } 4797c478bd9Sstevel@tonic-gate } 4807c478bd9Sstevel@tonic-gate 4817c478bd9Sstevel@tonic-gate 4827c478bd9Sstevel@tonic-gate /* 4837c478bd9Sstevel@tonic-gate * ROUTINE: AUDIT_EXIT 4847c478bd9Sstevel@tonic-gate * PURPOSE: 4857c478bd9Sstevel@tonic-gate * CALLBY: EXIT 4867c478bd9Sstevel@tonic-gate * NOTE: 4877c478bd9Sstevel@tonic-gate * TODO: 4887c478bd9Sstevel@tonic-gate * QUESTION: why cmw code as offset by 2 but not here 4897c478bd9Sstevel@tonic-gate */ 4907c478bd9Sstevel@tonic-gate /* ARGSUSED */ 4917c478bd9Sstevel@tonic-gate void 4927c478bd9Sstevel@tonic-gate audit_exit(int code, int what) 4937c478bd9Sstevel@tonic-gate { 4947c478bd9Sstevel@tonic-gate struct t_audit_data *tad; 4957c478bd9Sstevel@tonic-gate tad = U2A(u); 4967c478bd9Sstevel@tonic-gate 4977c478bd9Sstevel@tonic-gate /* 4987c478bd9Sstevel@tonic-gate * tad_scid will be set by audit_start even if we are not auditing 4997c478bd9Sstevel@tonic-gate * the event. 5007c478bd9Sstevel@tonic-gate */ 5017c478bd9Sstevel@tonic-gate if (tad->tad_scid == SYS_exit) { 5027c478bd9Sstevel@tonic-gate /* 5037c478bd9Sstevel@tonic-gate * if we are auditing the exit system call, then complete 5047c478bd9Sstevel@tonic-gate * audit record generation (no return from system call). 5057c478bd9Sstevel@tonic-gate */ 5067c478bd9Sstevel@tonic-gate if (tad->tad_flag && tad->tad_event == AUE_EXIT) 5077c478bd9Sstevel@tonic-gate audit_finish(0, SYS_exit, 0, 0); 5087c478bd9Sstevel@tonic-gate return; 5097c478bd9Sstevel@tonic-gate } 5107c478bd9Sstevel@tonic-gate 5117c478bd9Sstevel@tonic-gate /* 5127c478bd9Sstevel@tonic-gate * Anyone auditing the system call that was aborted? 5137c478bd9Sstevel@tonic-gate */ 5147c478bd9Sstevel@tonic-gate if (tad->tad_flag) { 5157c478bd9Sstevel@tonic-gate au_uwrite(au_to_text("event aborted")); 5167c478bd9Sstevel@tonic-gate audit_finish(0, tad->tad_scid, 0, 0); 5177c478bd9Sstevel@tonic-gate } 5187c478bd9Sstevel@tonic-gate 5197c478bd9Sstevel@tonic-gate /* 5207c478bd9Sstevel@tonic-gate * Generate an audit record for process exit if preselected. 5217c478bd9Sstevel@tonic-gate */ 522005d3febSMarek Pospisil (void) audit_start(0, SYS_exit, AUC_UNSET, 0, 0); 5237c478bd9Sstevel@tonic-gate audit_finish(0, SYS_exit, 0, 0); 5247c478bd9Sstevel@tonic-gate } 5257c478bd9Sstevel@tonic-gate 5267c478bd9Sstevel@tonic-gate /* 5277c478bd9Sstevel@tonic-gate * ROUTINE: AUDIT_CORE_START 5287c478bd9Sstevel@tonic-gate * PURPOSE: 5297c478bd9Sstevel@tonic-gate * CALLBY: PSIG 5307c478bd9Sstevel@tonic-gate * NOTE: 5317c478bd9Sstevel@tonic-gate * TODO: 5327c478bd9Sstevel@tonic-gate */ 5337c478bd9Sstevel@tonic-gate void 5347c478bd9Sstevel@tonic-gate audit_core_start(int sig) 5357c478bd9Sstevel@tonic-gate { 5367c478bd9Sstevel@tonic-gate au_event_t event; 5377c478bd9Sstevel@tonic-gate au_state_t estate; 5387c478bd9Sstevel@tonic-gate t_audit_data_t *tad; 5397c478bd9Sstevel@tonic-gate au_kcontext_t *kctx; 5407c478bd9Sstevel@tonic-gate 5417c478bd9Sstevel@tonic-gate tad = U2A(u); 5427c478bd9Sstevel@tonic-gate 5437c478bd9Sstevel@tonic-gate ASSERT(tad != (t_audit_data_t *)0); 5447c478bd9Sstevel@tonic-gate 5457c478bd9Sstevel@tonic-gate ASSERT(tad->tad_scid == 0); 5467c478bd9Sstevel@tonic-gate ASSERT(tad->tad_event == 0); 5477c478bd9Sstevel@tonic-gate ASSERT(tad->tad_evmod == 0); 5487c478bd9Sstevel@tonic-gate ASSERT(tad->tad_ctrl == 0); 5497c478bd9Sstevel@tonic-gate ASSERT(tad->tad_flag == 0); 5507c478bd9Sstevel@tonic-gate ASSERT(tad->tad_aupath == NULL); 5517c478bd9Sstevel@tonic-gate 5529e9e6ab8Spaulson kctx = GET_KCTX_PZ; 5537c478bd9Sstevel@tonic-gate 5547c478bd9Sstevel@tonic-gate /* get basic event for system call */ 5557c478bd9Sstevel@tonic-gate event = AUE_CORE; 5567c478bd9Sstevel@tonic-gate estate = kctx->auk_ets[event]; 5577c478bd9Sstevel@tonic-gate 5587c478bd9Sstevel@tonic-gate if ((tad->tad_flag = auditme(kctx, tad, estate)) == 0) 5597c478bd9Sstevel@tonic-gate return; 5607c478bd9Sstevel@tonic-gate 5617c478bd9Sstevel@tonic-gate /* reset the flags for non-user attributable events */ 5624a0fa546SMarek Pospisil tad->tad_ctrl = TAD_CORE; 5637c478bd9Sstevel@tonic-gate tad->tad_scid = 0; 5647c478bd9Sstevel@tonic-gate 5657c478bd9Sstevel@tonic-gate /* if auditing not enabled, then don't generate an audit record */ 5667c478bd9Sstevel@tonic-gate 5677c478bd9Sstevel@tonic-gate if (!((kctx->auk_auditstate == AUC_AUDITING || 5687c478bd9Sstevel@tonic-gate kctx->auk_auditstate == AUC_INIT_AUDIT) || 5697c478bd9Sstevel@tonic-gate kctx->auk_auditstate == AUC_NOSPACE)) { 5707c478bd9Sstevel@tonic-gate tad->tad_flag = 0; 5717c478bd9Sstevel@tonic-gate tad->tad_ctrl = 0; 5727c478bd9Sstevel@tonic-gate return; 5737c478bd9Sstevel@tonic-gate } 5747c478bd9Sstevel@tonic-gate 5757c478bd9Sstevel@tonic-gate tad->tad_event = event; 5767c478bd9Sstevel@tonic-gate tad->tad_evmod = 0; 5777c478bd9Sstevel@tonic-gate 5787c478bd9Sstevel@tonic-gate ASSERT(tad->tad_ad == NULL); 5797c478bd9Sstevel@tonic-gate 5807c478bd9Sstevel@tonic-gate au_write(&(u_ad), au_to_arg32(1, "signal", (uint32_t)sig)); 5817c478bd9Sstevel@tonic-gate } 5827c478bd9Sstevel@tonic-gate 5837c478bd9Sstevel@tonic-gate /* 5847c478bd9Sstevel@tonic-gate * ROUTINE: AUDIT_CORE_FINISH 5857c478bd9Sstevel@tonic-gate * PURPOSE: 5867c478bd9Sstevel@tonic-gate * CALLBY: PSIG 5877c478bd9Sstevel@tonic-gate * NOTE: 5887c478bd9Sstevel@tonic-gate * TODO: 5897c478bd9Sstevel@tonic-gate * QUESTION: 5907c478bd9Sstevel@tonic-gate */ 5917c478bd9Sstevel@tonic-gate 5927c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 5937c478bd9Sstevel@tonic-gate void 5947c478bd9Sstevel@tonic-gate audit_core_finish(int code) 5957c478bd9Sstevel@tonic-gate { 5967c478bd9Sstevel@tonic-gate int flag; 5977c478bd9Sstevel@tonic-gate t_audit_data_t *tad; 5987c478bd9Sstevel@tonic-gate au_kcontext_t *kctx; 5997c478bd9Sstevel@tonic-gate 6007c478bd9Sstevel@tonic-gate tad = U2A(u); 6017c478bd9Sstevel@tonic-gate 6027c478bd9Sstevel@tonic-gate ASSERT(tad != (t_audit_data_t *)0); 6037c478bd9Sstevel@tonic-gate 6047c478bd9Sstevel@tonic-gate if ((flag = tad->tad_flag) == 0) { 6057c478bd9Sstevel@tonic-gate tad->tad_event = 0; 6067c478bd9Sstevel@tonic-gate tad->tad_evmod = 0; 6077c478bd9Sstevel@tonic-gate tad->tad_ctrl = 0; 6087c478bd9Sstevel@tonic-gate ASSERT(tad->tad_aupath == NULL); 6097c478bd9Sstevel@tonic-gate return; 6107c478bd9Sstevel@tonic-gate } 6117c478bd9Sstevel@tonic-gate tad->tad_flag = 0; 6127c478bd9Sstevel@tonic-gate 6139e9e6ab8Spaulson kctx = GET_KCTX_PZ; 6147c478bd9Sstevel@tonic-gate 6157c478bd9Sstevel@tonic-gate /* kludge for error 0, should use `code==CLD_DUMPED' instead */ 616799bd290Spwernau if (flag = audit_success(kctx, tad, 0, NULL)) { 6177c478bd9Sstevel@tonic-gate cred_t *cr = CRED(); 6187c478bd9Sstevel@tonic-gate const auditinfo_addr_t *ainfo = crgetauinfo(cr); 6197c478bd9Sstevel@tonic-gate 6207c478bd9Sstevel@tonic-gate ASSERT(ainfo != NULL); 6217c478bd9Sstevel@tonic-gate 6227c478bd9Sstevel@tonic-gate /* 62381490fd2Sgww * Add subject information (no locks since our private copy of 6247c478bd9Sstevel@tonic-gate * credential 6257c478bd9Sstevel@tonic-gate */ 62681490fd2Sgww AUDIT_SETSUBJ(&(u_ad), cr, ainfo, kctx); 62745916cd2Sjpk 6287c478bd9Sstevel@tonic-gate /* Add a return token (should use f argument) */ 6297c478bd9Sstevel@tonic-gate add_return_token((caddr_t *)&(u_ad), tad->tad_scid, 0, 0); 6307c478bd9Sstevel@tonic-gate 6317c478bd9Sstevel@tonic-gate AS_INC(as_generated, 1, kctx); 6327c478bd9Sstevel@tonic-gate AS_INC(as_kernel, 1, kctx); 6337c478bd9Sstevel@tonic-gate } 6347c478bd9Sstevel@tonic-gate 6357c478bd9Sstevel@tonic-gate /* Close up everything */ 636005d3febSMarek Pospisil au_close(kctx, &(u_ad), flag, tad->tad_event, tad->tad_evmod, NULL); 6377c478bd9Sstevel@tonic-gate 6387c478bd9Sstevel@tonic-gate /* free up any space remaining with the path's */ 6397c478bd9Sstevel@tonic-gate if (tad->tad_aupath != NULL) { 6407c478bd9Sstevel@tonic-gate au_pathrele(tad->tad_aupath); 6417c478bd9Sstevel@tonic-gate tad->tad_aupath = NULL; 6427c478bd9Sstevel@tonic-gate } 6437c478bd9Sstevel@tonic-gate tad->tad_event = 0; 6447c478bd9Sstevel@tonic-gate tad->tad_evmod = 0; 6457c478bd9Sstevel@tonic-gate tad->tad_ctrl = 0; 6467c478bd9Sstevel@tonic-gate } 6477c478bd9Sstevel@tonic-gate 6487c478bd9Sstevel@tonic-gate 6497c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 6507c478bd9Sstevel@tonic-gate void 6517c478bd9Sstevel@tonic-gate audit_strgetmsg(struct vnode *vp, struct strbuf *mctl, struct strbuf *mdata, 6527c478bd9Sstevel@tonic-gate unsigned char *pri, int *flag, int fmode) 6537c478bd9Sstevel@tonic-gate { 6547c478bd9Sstevel@tonic-gate struct stdata *stp; 6557c478bd9Sstevel@tonic-gate t_audit_data_t *tad = U2A(u); 6567c478bd9Sstevel@tonic-gate 6577c478bd9Sstevel@tonic-gate ASSERT(tad != (t_audit_data_t *)0); 6587c478bd9Sstevel@tonic-gate 6597c478bd9Sstevel@tonic-gate stp = vp->v_stream; 6607c478bd9Sstevel@tonic-gate 6617c478bd9Sstevel@tonic-gate /* lock stdata from audit_sock */ 6627c478bd9Sstevel@tonic-gate mutex_enter(&stp->sd_lock); 6637c478bd9Sstevel@tonic-gate 6647c478bd9Sstevel@tonic-gate /* proceed ONLY if user is being audited */ 6657c478bd9Sstevel@tonic-gate if (!tad->tad_flag) { 6667c478bd9Sstevel@tonic-gate /* 6677c478bd9Sstevel@tonic-gate * this is so we will not add audit data onto 6687c478bd9Sstevel@tonic-gate * a thread that is not being audited. 6697c478bd9Sstevel@tonic-gate */ 6707c478bd9Sstevel@tonic-gate stp->sd_t_audit_data = NULL; 6717c478bd9Sstevel@tonic-gate mutex_exit(&stp->sd_lock); 6727c478bd9Sstevel@tonic-gate return; 6737c478bd9Sstevel@tonic-gate } 6747c478bd9Sstevel@tonic-gate 6757c478bd9Sstevel@tonic-gate stp->sd_t_audit_data = (caddr_t)curthread; 6767c478bd9Sstevel@tonic-gate mutex_exit(&stp->sd_lock); 6777c478bd9Sstevel@tonic-gate } 6787c478bd9Sstevel@tonic-gate 6797c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 6807c478bd9Sstevel@tonic-gate void 6817c478bd9Sstevel@tonic-gate audit_strputmsg(struct vnode *vp, struct strbuf *mctl, struct strbuf *mdata, 6827c478bd9Sstevel@tonic-gate unsigned char pri, int flag, int fmode) 6837c478bd9Sstevel@tonic-gate { 6847c478bd9Sstevel@tonic-gate struct stdata *stp; 6857c478bd9Sstevel@tonic-gate t_audit_data_t *tad = U2A(u); 6867c478bd9Sstevel@tonic-gate 6877c478bd9Sstevel@tonic-gate ASSERT(tad != (t_audit_data_t *)0); 6887c478bd9Sstevel@tonic-gate 6897c478bd9Sstevel@tonic-gate stp = vp->v_stream; 6907c478bd9Sstevel@tonic-gate 6917c478bd9Sstevel@tonic-gate /* lock stdata from audit_sock */ 6927c478bd9Sstevel@tonic-gate mutex_enter(&stp->sd_lock); 6937c478bd9Sstevel@tonic-gate 6947c478bd9Sstevel@tonic-gate /* proceed ONLY if user is being audited */ 6957c478bd9Sstevel@tonic-gate if (!tad->tad_flag) { 6967c478bd9Sstevel@tonic-gate /* 6977c478bd9Sstevel@tonic-gate * this is so we will not add audit data onto 6987c478bd9Sstevel@tonic-gate * a thread that is not being audited. 6997c478bd9Sstevel@tonic-gate */ 7007c478bd9Sstevel@tonic-gate stp->sd_t_audit_data = NULL; 7017c478bd9Sstevel@tonic-gate mutex_exit(&stp->sd_lock); 7027c478bd9Sstevel@tonic-gate return; 7037c478bd9Sstevel@tonic-gate } 7047c478bd9Sstevel@tonic-gate 7057c478bd9Sstevel@tonic-gate stp->sd_t_audit_data = (caddr_t)curthread; 7067c478bd9Sstevel@tonic-gate mutex_exit(&stp->sd_lock); 7077c478bd9Sstevel@tonic-gate } 7087c478bd9Sstevel@tonic-gate 7097c478bd9Sstevel@tonic-gate /* 7107c478bd9Sstevel@tonic-gate * ROUTINE: AUDIT_CLOSEF 7117c478bd9Sstevel@tonic-gate * PURPOSE: 7127c478bd9Sstevel@tonic-gate * CALLBY: CLOSEF 7137c478bd9Sstevel@tonic-gate * NOTE: 7147c478bd9Sstevel@tonic-gate * release per file audit resources when file structure is being released. 7157c478bd9Sstevel@tonic-gate * 7167c478bd9Sstevel@tonic-gate * IMPORTANT NOTE: Since we generate an audit record here, we may sleep 7177c478bd9Sstevel@tonic-gate * on the audit queue if it becomes full. This means 7187c478bd9Sstevel@tonic-gate * audit_closef can not be called when f_count == 0. Since 7197c478bd9Sstevel@tonic-gate * f_count == 0 indicates the file structure is free, another 7207c478bd9Sstevel@tonic-gate * process could attempt to use the file while we were still 7217c478bd9Sstevel@tonic-gate * asleep waiting on the audit queue. This would cause the 7227c478bd9Sstevel@tonic-gate * per file audit data to be corrupted when we finally do 7237c478bd9Sstevel@tonic-gate * wakeup. 7247c478bd9Sstevel@tonic-gate * TODO: 7257c478bd9Sstevel@tonic-gate * QUESTION: 7267c478bd9Sstevel@tonic-gate */ 7277c478bd9Sstevel@tonic-gate 7287c478bd9Sstevel@tonic-gate void 7297c478bd9Sstevel@tonic-gate audit_closef(struct file *fp) 7307c478bd9Sstevel@tonic-gate { /* AUDIT_CLOSEF */ 7317c478bd9Sstevel@tonic-gate f_audit_data_t *fad; 7327c478bd9Sstevel@tonic-gate t_audit_data_t *tad; 7337c478bd9Sstevel@tonic-gate int success; 7347c478bd9Sstevel@tonic-gate au_state_t estate; 7357c478bd9Sstevel@tonic-gate struct vnode *vp; 7367c478bd9Sstevel@tonic-gate token_t *ad = NULL; 7377c478bd9Sstevel@tonic-gate struct vattr attr; 738d0fa49b7STony Nguyen au_emod_t evmod = 0; 7397c478bd9Sstevel@tonic-gate const auditinfo_addr_t *ainfo; 7407c478bd9Sstevel@tonic-gate cred_t *cr; 7419e9e6ab8Spaulson au_kcontext_t *kctx = GET_KCTX_PZ; 742005d3febSMarek Pospisil uint32_t auditing; 743*224626ecSMarek Pospisil boolean_t audit_attr = B_FALSE; 7447c478bd9Sstevel@tonic-gate 7457c478bd9Sstevel@tonic-gate fad = F2A(fp); 7467c478bd9Sstevel@tonic-gate estate = kctx->auk_ets[AUE_CLOSE]; 7477c478bd9Sstevel@tonic-gate tad = U2A(u); 7487c478bd9Sstevel@tonic-gate cr = CRED(); 7497c478bd9Sstevel@tonic-gate 7507c478bd9Sstevel@tonic-gate /* audit record already generated by system call envelope */ 7517c478bd9Sstevel@tonic-gate if (tad->tad_event == AUE_CLOSE) { 7527c478bd9Sstevel@tonic-gate /* so close audit event will have bits set */ 753d0fa49b7STony Nguyen tad->tad_evmod |= (au_emod_t)fad->fad_flags; 7547c478bd9Sstevel@tonic-gate return; 7557c478bd9Sstevel@tonic-gate } 7567c478bd9Sstevel@tonic-gate 7577c478bd9Sstevel@tonic-gate /* if auditing not enabled, then don't generate an audit record */ 758005d3febSMarek Pospisil auditing = (tad->tad_audit == AUC_UNSET) ? 759005d3febSMarek Pospisil kctx->auk_auditstate : tad->tad_audit; 760005d3febSMarek Pospisil if (auditing & ~(AUC_AUDITING | AUC_INIT_AUDIT | AUC_NOSPACE)) 7617c478bd9Sstevel@tonic-gate return; 7627c478bd9Sstevel@tonic-gate 7637c478bd9Sstevel@tonic-gate ainfo = crgetauinfo(cr); 7647c478bd9Sstevel@tonic-gate if (ainfo == NULL) 7657c478bd9Sstevel@tonic-gate return; 7667c478bd9Sstevel@tonic-gate 7677c478bd9Sstevel@tonic-gate success = ainfo->ai_mask.as_success & estate; 7687c478bd9Sstevel@tonic-gate 7697c478bd9Sstevel@tonic-gate /* not selected for this event */ 7707c478bd9Sstevel@tonic-gate if (success == 0) 7717c478bd9Sstevel@tonic-gate return; 7727c478bd9Sstevel@tonic-gate 7737c478bd9Sstevel@tonic-gate /* 7747c478bd9Sstevel@tonic-gate * can't use audit_attributes here since we use a private audit area 7757c478bd9Sstevel@tonic-gate * to build the audit record instead of the one off the thread. 7767c478bd9Sstevel@tonic-gate */ 7777c478bd9Sstevel@tonic-gate if ((vp = fp->f_vnode) != NULL) { 7787c478bd9Sstevel@tonic-gate attr.va_mask = AT_ALL; 779*224626ecSMarek Pospisil if (VOP_GETATTR(vp, &attr, 0, CRED(), NULL) == 0) { 780*224626ecSMarek Pospisil if ((fp->f_flag & FWRITE) == 0 && 781*224626ecSMarek Pospisil object_is_public(&attr)) { 7827c478bd9Sstevel@tonic-gate /* 783*224626ecSMarek Pospisil * When write was not used and the file can be 784*224626ecSMarek Pospisil * considered public, then skip the audit. 7857c478bd9Sstevel@tonic-gate */ 7867c478bd9Sstevel@tonic-gate return; 7877c478bd9Sstevel@tonic-gate } 788*224626ecSMarek Pospisil audit_attr = B_TRUE; 789*224626ecSMarek Pospisil } 7907c478bd9Sstevel@tonic-gate } 7917c478bd9Sstevel@tonic-gate 792d0fa49b7STony Nguyen evmod = (au_emod_t)fad->fad_flags; 7937c478bd9Sstevel@tonic-gate if (fad->fad_aupath != NULL) { 7947c478bd9Sstevel@tonic-gate au_write((caddr_t *)&(ad), au_to_path(fad->fad_aupath)); 7957c478bd9Sstevel@tonic-gate } else { 7967c478bd9Sstevel@tonic-gate #ifdef _LP64 7977c478bd9Sstevel@tonic-gate au_write((caddr_t *)&(ad), au_to_arg64( 7987c478bd9Sstevel@tonic-gate 1, "no path: fp", (uint64_t)fp)); 7997c478bd9Sstevel@tonic-gate #else 8007c478bd9Sstevel@tonic-gate au_write((caddr_t *)&(ad), au_to_arg32( 8017c478bd9Sstevel@tonic-gate 1, "no path: fp", (uint32_t)fp)); 8027c478bd9Sstevel@tonic-gate #endif 8037c478bd9Sstevel@tonic-gate } 8047c478bd9Sstevel@tonic-gate 805*224626ecSMarek Pospisil if (audit_attr) { 8067c478bd9Sstevel@tonic-gate au_write((caddr_t *)&(ad), au_to_attr(&attr)); 80745916cd2Sjpk audit_sec_attributes((caddr_t *)&(ad), vp); 8087c478bd9Sstevel@tonic-gate } 8097c478bd9Sstevel@tonic-gate 81081490fd2Sgww /* Add subject information */ 81181490fd2Sgww AUDIT_SETSUBJ((caddr_t *)&(ad), cr, ainfo, kctx); 81245916cd2Sjpk 8137c478bd9Sstevel@tonic-gate /* add a return token */ 8147c478bd9Sstevel@tonic-gate add_return_token((caddr_t *)&(ad), tad->tad_scid, 0, 0); 8157c478bd9Sstevel@tonic-gate 8167c478bd9Sstevel@tonic-gate AS_INC(as_generated, 1, kctx); 8177c478bd9Sstevel@tonic-gate AS_INC(as_kernel, 1, kctx); 8187c478bd9Sstevel@tonic-gate 8197c478bd9Sstevel@tonic-gate /* 8207c478bd9Sstevel@tonic-gate * Close up everything 8217c478bd9Sstevel@tonic-gate * Note: path space recovery handled by normal system 8227c478bd9Sstevel@tonic-gate * call envelope if not at last close. 8237c478bd9Sstevel@tonic-gate * Note there is no failure at this point since 8247c478bd9Sstevel@tonic-gate * this represents closes due to exit of process, 8257c478bd9Sstevel@tonic-gate * thus we always indicate successful closes. 8267c478bd9Sstevel@tonic-gate */ 8277c478bd9Sstevel@tonic-gate au_close(kctx, (caddr_t *)&(ad), AU_OK | AU_DEFER, 828005d3febSMarek Pospisil AUE_CLOSE, evmod, NULL); 8297c478bd9Sstevel@tonic-gate } 8307c478bd9Sstevel@tonic-gate 8317c478bd9Sstevel@tonic-gate /* 8327c478bd9Sstevel@tonic-gate * ROUTINE: AUDIT_SET 8337c478bd9Sstevel@tonic-gate * PURPOSE: Audit the file path and file attributes. 8347c478bd9Sstevel@tonic-gate * CALLBY: SETF 8357c478bd9Sstevel@tonic-gate * NOTE: SETF associate a file pointer with user area's open files. 8367c478bd9Sstevel@tonic-gate * TODO: 8377c478bd9Sstevel@tonic-gate * call audit_finish directly ??? 8387c478bd9Sstevel@tonic-gate * QUESTION: 8397c478bd9Sstevel@tonic-gate */ 8407c478bd9Sstevel@tonic-gate 8417c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 8427c478bd9Sstevel@tonic-gate void 8437c478bd9Sstevel@tonic-gate audit_setf(file_t *fp, int fd) 8447c478bd9Sstevel@tonic-gate { 8457c478bd9Sstevel@tonic-gate f_audit_data_t *fad; 8467c478bd9Sstevel@tonic-gate t_audit_data_t *tad; 8477c478bd9Sstevel@tonic-gate 8487c478bd9Sstevel@tonic-gate if (fp == NULL) 8497c478bd9Sstevel@tonic-gate return; 8507c478bd9Sstevel@tonic-gate 8517c478bd9Sstevel@tonic-gate tad = T2A(curthread); 8527c478bd9Sstevel@tonic-gate fad = F2A(fp); 8537c478bd9Sstevel@tonic-gate 8548fd04b83SRoger A. Faulkner if (!(tad->tad_scid == SYS_open || 8558fd04b83SRoger A. Faulkner tad->tad_scid == SYS_open64 || 8568fd04b83SRoger A. Faulkner tad->tad_scid == SYS_openat || 8578fd04b83SRoger A. Faulkner tad->tad_scid == SYS_openat64)) 8587c478bd9Sstevel@tonic-gate return; 8597c478bd9Sstevel@tonic-gate 8607c478bd9Sstevel@tonic-gate /* no path */ 8617c478bd9Sstevel@tonic-gate if (tad->tad_aupath == 0) 8627c478bd9Sstevel@tonic-gate return; 8637c478bd9Sstevel@tonic-gate 8647c478bd9Sstevel@tonic-gate /* 8657c478bd9Sstevel@tonic-gate * assign path information associated with file audit data 8667c478bd9Sstevel@tonic-gate * use tad hold 8677c478bd9Sstevel@tonic-gate */ 8687c478bd9Sstevel@tonic-gate fad->fad_aupath = tad->tad_aupath; 8697c478bd9Sstevel@tonic-gate tad->tad_aupath = NULL; 8707c478bd9Sstevel@tonic-gate 8714a0fa546SMarek Pospisil if (!(tad->tad_ctrl & TAD_TRUE_CREATE)) { 8728fd04b83SRoger A. Faulkner /* adjust event type by dropping the 'creat' part */ 8737c478bd9Sstevel@tonic-gate switch (tad->tad_event) { 8747c478bd9Sstevel@tonic-gate case AUE_OPEN_RC: 8757c478bd9Sstevel@tonic-gate tad->tad_event = AUE_OPEN_R; 8764a0fa546SMarek Pospisil tad->tad_ctrl |= TAD_PUBLIC_EV; 8777c478bd9Sstevel@tonic-gate break; 8787c478bd9Sstevel@tonic-gate case AUE_OPEN_RTC: 8797c478bd9Sstevel@tonic-gate tad->tad_event = AUE_OPEN_RT; 8807c478bd9Sstevel@tonic-gate break; 8817c478bd9Sstevel@tonic-gate case AUE_OPEN_WC: 8827c478bd9Sstevel@tonic-gate tad->tad_event = AUE_OPEN_W; 8837c478bd9Sstevel@tonic-gate break; 8847c478bd9Sstevel@tonic-gate case AUE_OPEN_WTC: 8857c478bd9Sstevel@tonic-gate tad->tad_event = AUE_OPEN_WT; 8867c478bd9Sstevel@tonic-gate break; 8877c478bd9Sstevel@tonic-gate case AUE_OPEN_RWC: 8887c478bd9Sstevel@tonic-gate tad->tad_event = AUE_OPEN_RW; 8897c478bd9Sstevel@tonic-gate break; 8907c478bd9Sstevel@tonic-gate case AUE_OPEN_RWTC: 8917c478bd9Sstevel@tonic-gate tad->tad_event = AUE_OPEN_RWT; 8927c478bd9Sstevel@tonic-gate break; 8937c478bd9Sstevel@tonic-gate default: 8947c478bd9Sstevel@tonic-gate break; 8957c478bd9Sstevel@tonic-gate } 8967c478bd9Sstevel@tonic-gate } 8977c478bd9Sstevel@tonic-gate } 8987c478bd9Sstevel@tonic-gate 8997c478bd9Sstevel@tonic-gate 9007c478bd9Sstevel@tonic-gate void 9017c478bd9Sstevel@tonic-gate audit_ipc(int type, int id, void *vp) 9027c478bd9Sstevel@tonic-gate { 9037c478bd9Sstevel@tonic-gate /* if not auditing this event, then do nothing */ 9047c478bd9Sstevel@tonic-gate if (ad_flag == 0) 9057c478bd9Sstevel@tonic-gate return; 9067c478bd9Sstevel@tonic-gate 9077c478bd9Sstevel@tonic-gate switch (type) { 9087c478bd9Sstevel@tonic-gate case AT_IPC_MSG: 9097c478bd9Sstevel@tonic-gate au_uwrite(au_to_ipc(AT_IPC_MSG, id)); 9107c478bd9Sstevel@tonic-gate au_uwrite(au_to_ipc_perm(&(((kmsqid_t *)vp)->msg_perm))); 9117c478bd9Sstevel@tonic-gate break; 9127c478bd9Sstevel@tonic-gate case AT_IPC_SEM: 9137c478bd9Sstevel@tonic-gate au_uwrite(au_to_ipc(AT_IPC_SEM, id)); 9147c478bd9Sstevel@tonic-gate au_uwrite(au_to_ipc_perm(&(((ksemid_t *)vp)->sem_perm))); 9157c478bd9Sstevel@tonic-gate break; 9167c478bd9Sstevel@tonic-gate case AT_IPC_SHM: 9177c478bd9Sstevel@tonic-gate au_uwrite(au_to_ipc(AT_IPC_SHM, id)); 9187c478bd9Sstevel@tonic-gate au_uwrite(au_to_ipc_perm(&(((kshmid_t *)vp)->shm_perm))); 9197c478bd9Sstevel@tonic-gate break; 9207c478bd9Sstevel@tonic-gate } 9217c478bd9Sstevel@tonic-gate } 9227c478bd9Sstevel@tonic-gate 9237c478bd9Sstevel@tonic-gate void 9247c478bd9Sstevel@tonic-gate audit_ipcget(int type, void *vp) 9257c478bd9Sstevel@tonic-gate { 9267c478bd9Sstevel@tonic-gate /* if not auditing this event, then do nothing */ 9277c478bd9Sstevel@tonic-gate if (ad_flag == 0) 9287c478bd9Sstevel@tonic-gate return; 9297c478bd9Sstevel@tonic-gate 9307c478bd9Sstevel@tonic-gate switch (type) { 9317c478bd9Sstevel@tonic-gate case NULL: 9327c478bd9Sstevel@tonic-gate au_uwrite(au_to_ipc_perm((struct kipc_perm *)vp)); 9337c478bd9Sstevel@tonic-gate break; 9347c478bd9Sstevel@tonic-gate case AT_IPC_MSG: 9357c478bd9Sstevel@tonic-gate au_uwrite(au_to_ipc_perm(&(((kmsqid_t *)vp)->msg_perm))); 9367c478bd9Sstevel@tonic-gate break; 9377c478bd9Sstevel@tonic-gate case AT_IPC_SEM: 9387c478bd9Sstevel@tonic-gate au_uwrite(au_to_ipc_perm(&(((ksemid_t *)vp)->sem_perm))); 9397c478bd9Sstevel@tonic-gate break; 9407c478bd9Sstevel@tonic-gate case AT_IPC_SHM: 9417c478bd9Sstevel@tonic-gate au_uwrite(au_to_ipc_perm(&(((kshmid_t *)vp)->shm_perm))); 9427c478bd9Sstevel@tonic-gate break; 9437c478bd9Sstevel@tonic-gate } 9447c478bd9Sstevel@tonic-gate } 9457c478bd9Sstevel@tonic-gate 9467c478bd9Sstevel@tonic-gate /* 9477c478bd9Sstevel@tonic-gate * ROUTINE: AUDIT_REBOOT 9487c478bd9Sstevel@tonic-gate * PURPOSE: 9497c478bd9Sstevel@tonic-gate * CALLBY: 9507c478bd9Sstevel@tonic-gate * NOTE: 9517c478bd9Sstevel@tonic-gate * At this point we know that the system call reboot will not return. We thus 9527c478bd9Sstevel@tonic-gate * have to complete the audit record generation and put it onto the queue. 9537c478bd9Sstevel@tonic-gate * This might be fairly useless if the auditing daemon is already dead.... 9547c478bd9Sstevel@tonic-gate * TODO: 9557c478bd9Sstevel@tonic-gate * QUESTION: who calls audit_reboot 9567c478bd9Sstevel@tonic-gate */ 9577c478bd9Sstevel@tonic-gate 9587c478bd9Sstevel@tonic-gate void 9597c478bd9Sstevel@tonic-gate audit_reboot(void) 9607c478bd9Sstevel@tonic-gate { 9617c478bd9Sstevel@tonic-gate int flag; 9627c478bd9Sstevel@tonic-gate t_audit_data_t *tad; 9639e9e6ab8Spaulson au_kcontext_t *kctx = GET_KCTX_PZ; 9647c478bd9Sstevel@tonic-gate 9657c478bd9Sstevel@tonic-gate tad = U2A(u); 9667c478bd9Sstevel@tonic-gate 9677c478bd9Sstevel@tonic-gate /* if not auditing this event, then do nothing */ 9687c478bd9Sstevel@tonic-gate if (tad->tad_flag == 0) 9697c478bd9Sstevel@tonic-gate return; 9707c478bd9Sstevel@tonic-gate 9717c478bd9Sstevel@tonic-gate /* do preselection on success/failure */ 972799bd290Spwernau if (flag = audit_success(kctx, tad, 0, NULL)) { 9737c478bd9Sstevel@tonic-gate /* add a process token */ 9747c478bd9Sstevel@tonic-gate 9757c478bd9Sstevel@tonic-gate cred_t *cr = CRED(); 9767c478bd9Sstevel@tonic-gate const auditinfo_addr_t *ainfo = crgetauinfo(cr); 9777c478bd9Sstevel@tonic-gate 9787c478bd9Sstevel@tonic-gate if (ainfo == NULL) 9797c478bd9Sstevel@tonic-gate return; 9807c478bd9Sstevel@tonic-gate 98181490fd2Sgww /* Add subject information */ 98281490fd2Sgww AUDIT_SETSUBJ(&(u_ad), cr, ainfo, kctx); 98345916cd2Sjpk 9847c478bd9Sstevel@tonic-gate /* add a return token */ 9857c478bd9Sstevel@tonic-gate add_return_token((caddr_t *)&(u_ad), tad->tad_scid, 0, 0); 9867c478bd9Sstevel@tonic-gate 9877c478bd9Sstevel@tonic-gate AS_INC(as_generated, 1, kctx); 9887c478bd9Sstevel@tonic-gate AS_INC(as_kernel, 1, kctx); 9897c478bd9Sstevel@tonic-gate } 9907c478bd9Sstevel@tonic-gate 9917c478bd9Sstevel@tonic-gate /* 9927c478bd9Sstevel@tonic-gate * Flow control useless here since we're going 9937c478bd9Sstevel@tonic-gate * to drop everything in the queue anyway. Why 9947c478bd9Sstevel@tonic-gate * block and wait. There aint anyone left alive to 9957c478bd9Sstevel@tonic-gate * read the records remaining anyway. 9967c478bd9Sstevel@tonic-gate */ 9977c478bd9Sstevel@tonic-gate 9987c478bd9Sstevel@tonic-gate /* Close up everything */ 9997c478bd9Sstevel@tonic-gate au_close(kctx, &(u_ad), flag | AU_DONTBLOCK, 1000005d3febSMarek Pospisil tad->tad_event, tad->tad_evmod, NULL); 10017c478bd9Sstevel@tonic-gate } 10027c478bd9Sstevel@tonic-gate 10037c478bd9Sstevel@tonic-gate void 10047c478bd9Sstevel@tonic-gate audit_setfsat_path(int argnum) 10057c478bd9Sstevel@tonic-gate { 10067c478bd9Sstevel@tonic-gate klwp_id_t clwp = ttolwp(curthread); 10077c478bd9Sstevel@tonic-gate struct file *fp; 10087c478bd9Sstevel@tonic-gate uint32_t fd; 10097c478bd9Sstevel@tonic-gate t_audit_data_t *tad; 10107c478bd9Sstevel@tonic-gate struct f_audit_data *fad; 10117c478bd9Sstevel@tonic-gate p_audit_data_t *pad; /* current process */ 1012c4d3e299SBrent Paulson uint_t fm; 1013da6c28aaSamw struct a { 1014da6c28aaSamw long arg1; 1015da6c28aaSamw long arg2; 1016da6c28aaSamw long arg3; 1017da6c28aaSamw long arg4; 1018da6c28aaSamw long arg5; 1019da6c28aaSamw } *uap; 10207c478bd9Sstevel@tonic-gate 10217c478bd9Sstevel@tonic-gate if (clwp == NULL) 10227c478bd9Sstevel@tonic-gate return; 1023da6c28aaSamw uap = (struct a *)clwp->lwp_ap; 10247c478bd9Sstevel@tonic-gate 10257c478bd9Sstevel@tonic-gate tad = U2A(u); 10267c478bd9Sstevel@tonic-gate ASSERT(tad != NULL); 10277c478bd9Sstevel@tonic-gate 10288fd04b83SRoger A. Faulkner switch (tad->tad_scid) { 10298fd04b83SRoger A. Faulkner case SYS_faccessat: 1030794f0adbSRoger A. Faulkner case SYS_fchmodat: 10318fd04b83SRoger A. Faulkner case SYS_fchownat: 10328fd04b83SRoger A. Faulkner case SYS_fstatat: 10338fd04b83SRoger A. Faulkner case SYS_fstatat64: 1034794f0adbSRoger A. Faulkner case SYS_mkdirat: 1035794f0adbSRoger A. Faulkner case SYS_mknodat: 10368fd04b83SRoger A. Faulkner case SYS_openat: 10378fd04b83SRoger A. Faulkner case SYS_openat64: 1038794f0adbSRoger A. Faulkner case SYS_readlinkat: 10398fd04b83SRoger A. Faulkner case SYS_unlinkat: 10408fd04b83SRoger A. Faulkner fd = uap->arg1; 10417c478bd9Sstevel@tonic-gate break; 1042794f0adbSRoger A. Faulkner case SYS_linkat: 10438fd04b83SRoger A. Faulkner case SYS_renameat: 10448fd04b83SRoger A. Faulkner if (argnum == 3) 10458fd04b83SRoger A. Faulkner fd = uap->arg3; 10468fd04b83SRoger A. Faulkner else 10478fd04b83SRoger A. Faulkner fd = uap->arg1; 10487c478bd9Sstevel@tonic-gate break; 1049794f0adbSRoger A. Faulkner case SYS_symlinkat: 10508fd04b83SRoger A. Faulkner case SYS_utimesys: 10518fd04b83SRoger A. Faulkner fd = uap->arg2; 10527c478bd9Sstevel@tonic-gate break; 1053c4d3e299SBrent Paulson case SYS_open: 1054c4d3e299SBrent Paulson case SYS_open64: 1055c4d3e299SBrent Paulson fd = AT_FDCWD; 1056c4d3e299SBrent Paulson break; 10577c478bd9Sstevel@tonic-gate default: 10587c478bd9Sstevel@tonic-gate return; 10597c478bd9Sstevel@tonic-gate } 10607c478bd9Sstevel@tonic-gate 10617c478bd9Sstevel@tonic-gate if (tad->tad_atpath != NULL) { 10627c478bd9Sstevel@tonic-gate au_pathrele(tad->tad_atpath); 10637c478bd9Sstevel@tonic-gate tad->tad_atpath = NULL; 10647c478bd9Sstevel@tonic-gate } 1065c4d3e299SBrent Paulson 10667c478bd9Sstevel@tonic-gate if (fd != AT_FDCWD) { 1067c4d3e299SBrent Paulson tad->tad_ctrl |= TAD_ATCALL; 1068c4d3e299SBrent Paulson 1069c4d3e299SBrent Paulson if (tad->tad_scid == SYS_openat || 1070c4d3e299SBrent Paulson tad->tad_scid == SYS_openat64) { 1071c4d3e299SBrent Paulson fm = (uint_t)uap->arg3; 1072c4d3e299SBrent Paulson if (fm & (FXATTR | FXATTRDIROPEN)) { 1073c4d3e299SBrent Paulson tad->tad_ctrl |= TAD_ATTPATH; 1074c4d3e299SBrent Paulson } 1075c4d3e299SBrent Paulson } 1076c4d3e299SBrent Paulson 1077fc960aa7SBrent Paulson if ((fp = getf(fd)) == NULL) { 10784a0fa546SMarek Pospisil tad->tad_ctrl |= TAD_NOPATH; 10797c478bd9Sstevel@tonic-gate return; 1080fc960aa7SBrent Paulson } 10817c478bd9Sstevel@tonic-gate fad = F2A(fp); 10827c478bd9Sstevel@tonic-gate ASSERT(fad); 1083fc960aa7SBrent Paulson if (fad->fad_aupath == NULL) { 10844a0fa546SMarek Pospisil tad->tad_ctrl |= TAD_NOPATH; 1085fc960aa7SBrent Paulson releasef(fd); 1086fc960aa7SBrent Paulson return; 1087fc960aa7SBrent Paulson } 10887c478bd9Sstevel@tonic-gate au_pathhold(fad->fad_aupath); 10897c478bd9Sstevel@tonic-gate tad->tad_atpath = fad->fad_aupath; 10907c478bd9Sstevel@tonic-gate releasef(fd); 10917c478bd9Sstevel@tonic-gate } else { 1092c4d3e299SBrent Paulson if (tad->tad_scid == SYS_open || 1093c4d3e299SBrent Paulson tad->tad_scid == SYS_open64) { 1094c4d3e299SBrent Paulson fm = (uint_t)uap->arg2; 1095c4d3e299SBrent Paulson if (fm & FXATTR) { 1096c4d3e299SBrent Paulson tad->tad_ctrl |= TAD_ATTPATH; 1097c4d3e299SBrent Paulson } 1098c4d3e299SBrent Paulson return; 1099c4d3e299SBrent Paulson } 11007c478bd9Sstevel@tonic-gate pad = P2A(curproc); 11017c478bd9Sstevel@tonic-gate mutex_enter(&pad->pad_lock); 11027c478bd9Sstevel@tonic-gate au_pathhold(pad->pad_cwd); 11037c478bd9Sstevel@tonic-gate tad->tad_atpath = pad->pad_cwd; 11047c478bd9Sstevel@tonic-gate mutex_exit(&pad->pad_lock); 11057c478bd9Sstevel@tonic-gate } 11067c478bd9Sstevel@tonic-gate } 11077c478bd9Sstevel@tonic-gate 11087c478bd9Sstevel@tonic-gate void 11097c478bd9Sstevel@tonic-gate audit_symlink_create(vnode_t *dvp, char *sname, char *target, int error) 11107c478bd9Sstevel@tonic-gate { 11117c478bd9Sstevel@tonic-gate t_audit_data_t *tad; 11127c478bd9Sstevel@tonic-gate vnode_t *vp; 11137c478bd9Sstevel@tonic-gate 11147c478bd9Sstevel@tonic-gate tad = U2A(u); 11157c478bd9Sstevel@tonic-gate 11167c478bd9Sstevel@tonic-gate /* if not auditing this event, then do nothing */ 11177c478bd9Sstevel@tonic-gate if (tad->tad_flag == 0) 11187c478bd9Sstevel@tonic-gate return; 11197c478bd9Sstevel@tonic-gate 11207c478bd9Sstevel@tonic-gate au_uwrite(au_to_text(target)); 11217c478bd9Sstevel@tonic-gate 11227c478bd9Sstevel@tonic-gate if (error) 11237c478bd9Sstevel@tonic-gate return; 11247c478bd9Sstevel@tonic-gate 1125da6c28aaSamw error = VOP_LOOKUP(dvp, sname, &vp, NULL, 0, NULL, CRED(), 1126da6c28aaSamw NULL, NULL, NULL); 11277c478bd9Sstevel@tonic-gate if (error == 0) { 11287c478bd9Sstevel@tonic-gate audit_attributes(vp); 11297c478bd9Sstevel@tonic-gate VN_RELE(vp); 11307c478bd9Sstevel@tonic-gate } 11317c478bd9Sstevel@tonic-gate } 11327c478bd9Sstevel@tonic-gate 11337c478bd9Sstevel@tonic-gate /* 11347c478bd9Sstevel@tonic-gate * ROUTINE: AUDIT_VNCREATE_START 11357c478bd9Sstevel@tonic-gate * PURPOSE: set flag so path name lookup in create will not add attribute 11367c478bd9Sstevel@tonic-gate * CALLBY: VN_CREATE 11377c478bd9Sstevel@tonic-gate * NOTE: 11387c478bd9Sstevel@tonic-gate * TODO: 11397c478bd9Sstevel@tonic-gate * QUESTION: 11407c478bd9Sstevel@tonic-gate */ 11417c478bd9Sstevel@tonic-gate 11427c478bd9Sstevel@tonic-gate void 11437c478bd9Sstevel@tonic-gate audit_vncreate_start() 11447c478bd9Sstevel@tonic-gate { 11457c478bd9Sstevel@tonic-gate t_audit_data_t *tad; 11467c478bd9Sstevel@tonic-gate 11477c478bd9Sstevel@tonic-gate tad = U2A(u); 11484a0fa546SMarek Pospisil tad->tad_ctrl |= TAD_NOATTRB; 11497c478bd9Sstevel@tonic-gate } 11507c478bd9Sstevel@tonic-gate 11517c478bd9Sstevel@tonic-gate /* 11527c478bd9Sstevel@tonic-gate * ROUTINE: AUDIT_VNCREATE_FINISH 11537c478bd9Sstevel@tonic-gate * PURPOSE: 11547c478bd9Sstevel@tonic-gate * CALLBY: VN_CREATE 11557c478bd9Sstevel@tonic-gate * NOTE: 11567c478bd9Sstevel@tonic-gate * TODO: 11577c478bd9Sstevel@tonic-gate * QUESTION: 11587c478bd9Sstevel@tonic-gate */ 11597c478bd9Sstevel@tonic-gate void 11607c478bd9Sstevel@tonic-gate audit_vncreate_finish(struct vnode *vp, int error) 11617c478bd9Sstevel@tonic-gate { 11627c478bd9Sstevel@tonic-gate t_audit_data_t *tad; 11637c478bd9Sstevel@tonic-gate 11647c478bd9Sstevel@tonic-gate if (error) 11657c478bd9Sstevel@tonic-gate return; 11667c478bd9Sstevel@tonic-gate 11677c478bd9Sstevel@tonic-gate tad = U2A(u); 11687c478bd9Sstevel@tonic-gate 11697c478bd9Sstevel@tonic-gate /* if not auditing this event, then do nothing */ 11707c478bd9Sstevel@tonic-gate if (tad->tad_flag == 0) 11717c478bd9Sstevel@tonic-gate return; 11727c478bd9Sstevel@tonic-gate 11734a0fa546SMarek Pospisil if (tad->tad_ctrl & TAD_TRUE_CREATE) { 11747c478bd9Sstevel@tonic-gate audit_attributes(vp); 11757c478bd9Sstevel@tonic-gate } 11767c478bd9Sstevel@tonic-gate 11774a0fa546SMarek Pospisil if (tad->tad_ctrl & TAD_CORE) { 11787c478bd9Sstevel@tonic-gate audit_attributes(vp); 11794a0fa546SMarek Pospisil tad->tad_ctrl &= ~TAD_CORE; 11807c478bd9Sstevel@tonic-gate } 11817c478bd9Sstevel@tonic-gate 11827c478bd9Sstevel@tonic-gate if (!error && ((tad->tad_event == AUE_MKNOD) || 11837c478bd9Sstevel@tonic-gate (tad->tad_event == AUE_MKDIR))) { 11847c478bd9Sstevel@tonic-gate audit_attributes(vp); 11857c478bd9Sstevel@tonic-gate } 11867c478bd9Sstevel@tonic-gate 11877c478bd9Sstevel@tonic-gate /* for case where multiple lookups in one syscall (rename) */ 11884a0fa546SMarek Pospisil tad->tad_ctrl &= ~TAD_NOATTRB; 11897c478bd9Sstevel@tonic-gate } 11907c478bd9Sstevel@tonic-gate 11917c478bd9Sstevel@tonic-gate 11927c478bd9Sstevel@tonic-gate 11937c478bd9Sstevel@tonic-gate 11947c478bd9Sstevel@tonic-gate 11957c478bd9Sstevel@tonic-gate 11967c478bd9Sstevel@tonic-gate 11977c478bd9Sstevel@tonic-gate 11987c478bd9Sstevel@tonic-gate /* 11997c478bd9Sstevel@tonic-gate * ROUTINE: AUDIT_EXEC 12007c478bd9Sstevel@tonic-gate * PURPOSE: Records the function arguments and environment variables 12017c478bd9Sstevel@tonic-gate * CALLBY: EXEC_ARGS 12027c478bd9Sstevel@tonic-gate * NOTE: 12037c478bd9Sstevel@tonic-gate * TODO: 12047c478bd9Sstevel@tonic-gate * QUESTION: 12057c478bd9Sstevel@tonic-gate */ 12067c478bd9Sstevel@tonic-gate 12077c478bd9Sstevel@tonic-gate void 12087c478bd9Sstevel@tonic-gate audit_exec( 12097c478bd9Sstevel@tonic-gate const char *argstr, /* argument strings */ 12107c478bd9Sstevel@tonic-gate const char *envstr, /* environment strings */ 12117c478bd9Sstevel@tonic-gate ssize_t argc, /* total # arguments */ 1212134a1f4eSCasper H.S. Dik ssize_t envc, /* total # environment variables */ 1213134a1f4eSCasper H.S. Dik cred_t *pfcred) /* the additional privileges in a profile */ 12147c478bd9Sstevel@tonic-gate { 12157c478bd9Sstevel@tonic-gate t_audit_data_t *tad; 12169e9e6ab8Spaulson au_kcontext_t *kctx = GET_KCTX_PZ; 12177c478bd9Sstevel@tonic-gate 12187c478bd9Sstevel@tonic-gate tad = U2A(u); 12197c478bd9Sstevel@tonic-gate 12207c478bd9Sstevel@tonic-gate /* if not auditing this event, then do nothing */ 12217c478bd9Sstevel@tonic-gate if (!tad->tad_flag) 12227c478bd9Sstevel@tonic-gate return; 12237c478bd9Sstevel@tonic-gate 1224134a1f4eSCasper H.S. Dik if (pfcred != NULL) { 1225134a1f4eSCasper H.S. Dik p_audit_data_t *pad; 1226134a1f4eSCasper H.S. Dik cred_t *cr = CRED(); 1227134a1f4eSCasper H.S. Dik priv_set_t pset = CR_IPRIV(cr); 12287c478bd9Sstevel@tonic-gate 1229134a1f4eSCasper H.S. Dik pad = P2A(curproc); 1230134a1f4eSCasper H.S. Dik 1231134a1f4eSCasper H.S. Dik /* It's a different event. */ 1232134a1f4eSCasper H.S. Dik tad->tad_event = AUE_PFEXEC; 1233134a1f4eSCasper H.S. Dik 1234134a1f4eSCasper H.S. Dik /* Add the current working directory to the audit trail. */ 1235134a1f4eSCasper H.S. Dik if (pad->pad_cwd != NULL) 1236134a1f4eSCasper H.S. Dik au_uwrite(au_to_path(pad->pad_cwd)); 1237134a1f4eSCasper H.S. Dik 1238134a1f4eSCasper H.S. Dik /* 1239134a1f4eSCasper H.S. Dik * The new credential is not yet in place when audit_exec 1240134a1f4eSCasper H.S. Dik * is called. 1241134a1f4eSCasper H.S. Dik * Compute the additional bits available in the new credential 1242134a1f4eSCasper H.S. Dik * and the limit set. 1243134a1f4eSCasper H.S. Dik */ 1244134a1f4eSCasper H.S. Dik priv_inverse(&pset); 1245134a1f4eSCasper H.S. Dik priv_intersect(&CR_IPRIV(pfcred), &pset); 1246134a1f4eSCasper H.S. Dik if (!priv_isemptyset(&pset) || 1247134a1f4eSCasper H.S. Dik !priv_isequalset(&CR_LPRIV(pfcred), &CR_LPRIV(cr))) { 1248134a1f4eSCasper H.S. Dik au_uwrite(au_to_privset( 1249134a1f4eSCasper H.S. Dik priv_getsetbynum(PRIV_INHERITABLE), &pset, AUT_PRIV, 1250134a1f4eSCasper H.S. Dik 0)); 1251134a1f4eSCasper H.S. Dik au_uwrite(au_to_privset(priv_getsetbynum(PRIV_LIMIT), 1252134a1f4eSCasper H.S. Dik &CR_LPRIV(pfcred), AUT_PRIV, 0)); 1253134a1f4eSCasper H.S. Dik } 1254134a1f4eSCasper H.S. Dik /* 1255134a1f4eSCasper H.S. Dik * Compare the uids & gids: create a process token if changed. 1256134a1f4eSCasper H.S. Dik */ 1257134a1f4eSCasper H.S. Dik if (crgetuid(cr) != crgetuid(pfcred) || 1258134a1f4eSCasper H.S. Dik crgetruid(cr) != crgetruid(pfcred) || 1259134a1f4eSCasper H.S. Dik crgetgid(cr) != crgetgid(pfcred) || 1260134a1f4eSCasper H.S. Dik crgetrgid(cr) != crgetrgid(pfcred)) { 1261134a1f4eSCasper H.S. Dik AUDIT_SETPROC(&(u_ad), cr, crgetauinfo(cr)); 1262134a1f4eSCasper H.S. Dik } 1263134a1f4eSCasper H.S. Dik } 1264134a1f4eSCasper H.S. Dik 1265134a1f4eSCasper H.S. Dik if (pfcred != NULL || (kctx->auk_policy & AUDIT_ARGV) != 0) 12667c478bd9Sstevel@tonic-gate au_uwrite(au_to_exec_args(argstr, argc)); 12677c478bd9Sstevel@tonic-gate 1268134a1f4eSCasper H.S. Dik if (kctx->auk_policy & AUDIT_ARGE) 12697c478bd9Sstevel@tonic-gate au_uwrite(au_to_exec_env(envstr, envc)); 12707c478bd9Sstevel@tonic-gate } 12717c478bd9Sstevel@tonic-gate 12727c478bd9Sstevel@tonic-gate /* 12737c478bd9Sstevel@tonic-gate * ROUTINE: AUDIT_ENTERPROM 12747c478bd9Sstevel@tonic-gate * PURPOSE: 12757c478bd9Sstevel@tonic-gate * CALLBY: KBDINPUT 12767c478bd9Sstevel@tonic-gate * ZSA_XSINT 12777c478bd9Sstevel@tonic-gate * NOTE: 12787c478bd9Sstevel@tonic-gate * TODO: 12797c478bd9Sstevel@tonic-gate * QUESTION: 12807c478bd9Sstevel@tonic-gate */ 12817c478bd9Sstevel@tonic-gate void 12827c478bd9Sstevel@tonic-gate audit_enterprom(int flg) 12837c478bd9Sstevel@tonic-gate { 12847c478bd9Sstevel@tonic-gate token_t *rp = NULL; 12857c478bd9Sstevel@tonic-gate int sorf; 12867c478bd9Sstevel@tonic-gate 12877c478bd9Sstevel@tonic-gate if (flg) 12887c478bd9Sstevel@tonic-gate sorf = AUM_SUCC; 12897c478bd9Sstevel@tonic-gate else 12907c478bd9Sstevel@tonic-gate sorf = AUM_FAIL; 12917c478bd9Sstevel@tonic-gate 12927c478bd9Sstevel@tonic-gate AUDIT_ASYNC_START(rp, AUE_ENTERPROM, sorf); 12937c478bd9Sstevel@tonic-gate 12947c478bd9Sstevel@tonic-gate au_write((caddr_t *)&(rp), au_to_text("kmdb")); 12957c478bd9Sstevel@tonic-gate 12967c478bd9Sstevel@tonic-gate if (flg) 12977c478bd9Sstevel@tonic-gate au_write((caddr_t *)&(rp), au_to_return32(0, 0)); 12987c478bd9Sstevel@tonic-gate else 12997c478bd9Sstevel@tonic-gate au_write((caddr_t *)&(rp), au_to_return32(ECANCELED, 0)); 13007c478bd9Sstevel@tonic-gate 1301005d3febSMarek Pospisil AUDIT_ASYNC_FINISH(rp, AUE_ENTERPROM, NULL, NULL); 13027c478bd9Sstevel@tonic-gate } 13037c478bd9Sstevel@tonic-gate 13047c478bd9Sstevel@tonic-gate 13057c478bd9Sstevel@tonic-gate /* 13067c478bd9Sstevel@tonic-gate * ROUTINE: AUDIT_EXITPROM 13077c478bd9Sstevel@tonic-gate * PURPOSE: 13087c478bd9Sstevel@tonic-gate * CALLBY: KBDINPUT 13097c478bd9Sstevel@tonic-gate * ZSA_XSINT 13107c478bd9Sstevel@tonic-gate * NOTE: 13117c478bd9Sstevel@tonic-gate * TODO: 13127c478bd9Sstevel@tonic-gate * QUESTION: 13137c478bd9Sstevel@tonic-gate */ 13147c478bd9Sstevel@tonic-gate void 13157c478bd9Sstevel@tonic-gate audit_exitprom(int flg) 13167c478bd9Sstevel@tonic-gate { 13177c478bd9Sstevel@tonic-gate int sorf; 13187c478bd9Sstevel@tonic-gate token_t *rp = NULL; 13197c478bd9Sstevel@tonic-gate 13207c478bd9Sstevel@tonic-gate if (flg) 13217c478bd9Sstevel@tonic-gate sorf = AUM_SUCC; 13227c478bd9Sstevel@tonic-gate else 13237c478bd9Sstevel@tonic-gate sorf = AUM_FAIL; 13247c478bd9Sstevel@tonic-gate 13257c478bd9Sstevel@tonic-gate AUDIT_ASYNC_START(rp, AUE_EXITPROM, sorf); 13267c478bd9Sstevel@tonic-gate 13277c478bd9Sstevel@tonic-gate au_write((caddr_t *)&(rp), au_to_text("kmdb")); 13287c478bd9Sstevel@tonic-gate 13297c478bd9Sstevel@tonic-gate if (flg) 13307c478bd9Sstevel@tonic-gate au_write((caddr_t *)&(rp), au_to_return32(0, 0)); 13317c478bd9Sstevel@tonic-gate else 13327c478bd9Sstevel@tonic-gate au_write((caddr_t *)&(rp), au_to_return32(ECANCELED, 0)); 13337c478bd9Sstevel@tonic-gate 1334005d3febSMarek Pospisil AUDIT_ASYNC_FINISH(rp, AUE_EXITPROM, NULL, NULL); 13357c478bd9Sstevel@tonic-gate } 13367c478bd9Sstevel@tonic-gate 13377c478bd9Sstevel@tonic-gate struct fcntla { 13387c478bd9Sstevel@tonic-gate int fdes; 13397c478bd9Sstevel@tonic-gate int cmd; 13407c478bd9Sstevel@tonic-gate intptr_t arg; 13417c478bd9Sstevel@tonic-gate }; 13427c478bd9Sstevel@tonic-gate 13437c478bd9Sstevel@tonic-gate 13447c478bd9Sstevel@tonic-gate /* 13457c478bd9Sstevel@tonic-gate * ROUTINE: AUDIT_CHDIREC 13467c478bd9Sstevel@tonic-gate * PURPOSE: 13477c478bd9Sstevel@tonic-gate * CALLBY: CHDIREC 13487c478bd9Sstevel@tonic-gate * NOTE: The main function of CHDIREC 13497c478bd9Sstevel@tonic-gate * TODO: Move the audit_chdirec hook above the VN_RELE in vncalls.c 13507c478bd9Sstevel@tonic-gate * QUESTION: 13517c478bd9Sstevel@tonic-gate */ 13527c478bd9Sstevel@tonic-gate 13537c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 13547c478bd9Sstevel@tonic-gate void 13557c478bd9Sstevel@tonic-gate audit_chdirec(vnode_t *vp, vnode_t **vpp) 13567c478bd9Sstevel@tonic-gate { 13577c478bd9Sstevel@tonic-gate int chdir; 13587c478bd9Sstevel@tonic-gate int fchdir; 13597c478bd9Sstevel@tonic-gate struct audit_path **appp; 13607c478bd9Sstevel@tonic-gate struct file *fp; 13617c478bd9Sstevel@tonic-gate f_audit_data_t *fad; 13627c478bd9Sstevel@tonic-gate p_audit_data_t *pad = P2A(curproc); 13637c478bd9Sstevel@tonic-gate t_audit_data_t *tad = T2A(curthread); 13647c478bd9Sstevel@tonic-gate 13657c478bd9Sstevel@tonic-gate struct a { 13667c478bd9Sstevel@tonic-gate long fd; 13677c478bd9Sstevel@tonic-gate } *uap = (struct a *)ttolwp(curthread)->lwp_ap; 13687c478bd9Sstevel@tonic-gate 13697c478bd9Sstevel@tonic-gate if ((tad->tad_scid == SYS_chdir) || (tad->tad_scid == SYS_chroot)) { 13707c478bd9Sstevel@tonic-gate chdir = tad->tad_scid == SYS_chdir; 13717c478bd9Sstevel@tonic-gate if (tad->tad_aupath) { 13727c478bd9Sstevel@tonic-gate mutex_enter(&pad->pad_lock); 13737c478bd9Sstevel@tonic-gate if (chdir) 13747c478bd9Sstevel@tonic-gate appp = &(pad->pad_cwd); 13757c478bd9Sstevel@tonic-gate else 13767c478bd9Sstevel@tonic-gate appp = &(pad->pad_root); 13777c478bd9Sstevel@tonic-gate au_pathrele(*appp); 13787c478bd9Sstevel@tonic-gate /* use tad hold */ 13797c478bd9Sstevel@tonic-gate *appp = tad->tad_aupath; 13807c478bd9Sstevel@tonic-gate tad->tad_aupath = NULL; 13817c478bd9Sstevel@tonic-gate mutex_exit(&pad->pad_lock); 13827c478bd9Sstevel@tonic-gate } 13837c478bd9Sstevel@tonic-gate } else if ((tad->tad_scid == SYS_fchdir) || 13847c478bd9Sstevel@tonic-gate (tad->tad_scid == SYS_fchroot)) { 13857c478bd9Sstevel@tonic-gate fchdir = tad->tad_scid == SYS_fchdir; 13867c478bd9Sstevel@tonic-gate if ((fp = getf(uap->fd)) == NULL) 13877c478bd9Sstevel@tonic-gate return; 13887c478bd9Sstevel@tonic-gate fad = F2A(fp); 13897c478bd9Sstevel@tonic-gate if (fad->fad_aupath) { 13907c478bd9Sstevel@tonic-gate au_pathhold(fad->fad_aupath); 13917c478bd9Sstevel@tonic-gate mutex_enter(&pad->pad_lock); 13927c478bd9Sstevel@tonic-gate if (fchdir) 13937c478bd9Sstevel@tonic-gate appp = &(pad->pad_cwd); 13947c478bd9Sstevel@tonic-gate else 13957c478bd9Sstevel@tonic-gate appp = &(pad->pad_root); 13967c478bd9Sstevel@tonic-gate au_pathrele(*appp); 13977c478bd9Sstevel@tonic-gate *appp = fad->fad_aupath; 13987c478bd9Sstevel@tonic-gate mutex_exit(&pad->pad_lock); 13997c478bd9Sstevel@tonic-gate if (tad->tad_flag) { 14007c478bd9Sstevel@tonic-gate au_uwrite(au_to_path(fad->fad_aupath)); 14017c478bd9Sstevel@tonic-gate audit_attributes(fp->f_vnode); 14027c478bd9Sstevel@tonic-gate } 14037c478bd9Sstevel@tonic-gate } 14047c478bd9Sstevel@tonic-gate releasef(uap->fd); 14057c478bd9Sstevel@tonic-gate } 14067c478bd9Sstevel@tonic-gate } 14077c478bd9Sstevel@tonic-gate 14087c478bd9Sstevel@tonic-gate 14097c478bd9Sstevel@tonic-gate /* 14107c478bd9Sstevel@tonic-gate * Audit hook for stream based socket and tli request. 14117c478bd9Sstevel@tonic-gate * Note that we do not have user context while executing 14127c478bd9Sstevel@tonic-gate * this code so we had to record them earlier during the 14137c478bd9Sstevel@tonic-gate * putmsg/getmsg to figure out which user we are dealing with. 14147c478bd9Sstevel@tonic-gate */ 14157c478bd9Sstevel@tonic-gate 14167c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 14177c478bd9Sstevel@tonic-gate void 14187c478bd9Sstevel@tonic-gate audit_sock( 14197c478bd9Sstevel@tonic-gate int type, /* type of tihdr.h header requests */ 14207c478bd9Sstevel@tonic-gate queue_t *q, /* contains the process and thread audit data */ 14217c478bd9Sstevel@tonic-gate mblk_t *mp, /* contains the tihdr.h header structures */ 14227c478bd9Sstevel@tonic-gate int from) /* timod or sockmod request */ 14237c478bd9Sstevel@tonic-gate { 14247c478bd9Sstevel@tonic-gate int32_t len; 14257c478bd9Sstevel@tonic-gate int32_t offset; 14267c478bd9Sstevel@tonic-gate struct sockaddr_in *sock_data; 14277c478bd9Sstevel@tonic-gate struct T_conn_req *conn_req; 14287c478bd9Sstevel@tonic-gate struct T_conn_ind *conn_ind; 14297c478bd9Sstevel@tonic-gate struct T_unitdata_req *unitdata_req; 14307c478bd9Sstevel@tonic-gate struct T_unitdata_ind *unitdata_ind; 14317c478bd9Sstevel@tonic-gate au_state_t estate; 14327c478bd9Sstevel@tonic-gate t_audit_data_t *tad; 14337c478bd9Sstevel@tonic-gate caddr_t saved_thread_ptr; 14347c478bd9Sstevel@tonic-gate au_mask_t amask; 14357c478bd9Sstevel@tonic-gate const auditinfo_addr_t *ainfo; 14367c478bd9Sstevel@tonic-gate au_kcontext_t *kctx; 14377c478bd9Sstevel@tonic-gate 14387c478bd9Sstevel@tonic-gate if (q->q_stream == NULL) 14397c478bd9Sstevel@tonic-gate return; 14407c478bd9Sstevel@tonic-gate mutex_enter(&q->q_stream->sd_lock); 14417c478bd9Sstevel@tonic-gate /* are we being audited */ 14427c478bd9Sstevel@tonic-gate saved_thread_ptr = q->q_stream->sd_t_audit_data; 14437c478bd9Sstevel@tonic-gate /* no pointer to thread, nothing to do */ 14447c478bd9Sstevel@tonic-gate if (saved_thread_ptr == NULL) { 14457c478bd9Sstevel@tonic-gate mutex_exit(&q->q_stream->sd_lock); 14467c478bd9Sstevel@tonic-gate return; 14477c478bd9Sstevel@tonic-gate } 14487c478bd9Sstevel@tonic-gate /* only allow one addition of a record token */ 14497c478bd9Sstevel@tonic-gate q->q_stream->sd_t_audit_data = NULL; 14507c478bd9Sstevel@tonic-gate /* 14517c478bd9Sstevel@tonic-gate * thread is not the one being audited, then nothing to do 14527c478bd9Sstevel@tonic-gate * This could be the stream thread handling the module 14537c478bd9Sstevel@tonic-gate * service routine. In this case, the context for the audit 14547c478bd9Sstevel@tonic-gate * record can no longer be assumed. Simplest to just drop 14557c478bd9Sstevel@tonic-gate * the operation. 14567c478bd9Sstevel@tonic-gate */ 14577c478bd9Sstevel@tonic-gate if (curthread != (kthread_id_t)saved_thread_ptr) { 14587c478bd9Sstevel@tonic-gate mutex_exit(&q->q_stream->sd_lock); 14597c478bd9Sstevel@tonic-gate return; 14607c478bd9Sstevel@tonic-gate } 14617c478bd9Sstevel@tonic-gate if (curthread->t_sysnum >= SYS_so_socket && 14627c478bd9Sstevel@tonic-gate curthread->t_sysnum <= SYS_sockconfig) { 14637c478bd9Sstevel@tonic-gate mutex_exit(&q->q_stream->sd_lock); 14647c478bd9Sstevel@tonic-gate return; 14657c478bd9Sstevel@tonic-gate } 14667c478bd9Sstevel@tonic-gate mutex_exit(&q->q_stream->sd_lock); 14677c478bd9Sstevel@tonic-gate /* 14687c478bd9Sstevel@tonic-gate * we know that the thread that did the put/getmsg is the 14697c478bd9Sstevel@tonic-gate * one running. Now we can get the TAD and see if we should 14707c478bd9Sstevel@tonic-gate * add an audit token. 14717c478bd9Sstevel@tonic-gate */ 14727c478bd9Sstevel@tonic-gate tad = U2A(u); 14737c478bd9Sstevel@tonic-gate 14749e9e6ab8Spaulson kctx = GET_KCTX_PZ; 14757c478bd9Sstevel@tonic-gate 14767c478bd9Sstevel@tonic-gate /* proceed ONLY if user is being audited */ 14777c478bd9Sstevel@tonic-gate if (!tad->tad_flag) 14787c478bd9Sstevel@tonic-gate return; 14797c478bd9Sstevel@tonic-gate 14807c478bd9Sstevel@tonic-gate ainfo = crgetauinfo(CRED()); 14817c478bd9Sstevel@tonic-gate if (ainfo == NULL) 14827c478bd9Sstevel@tonic-gate return; 14837c478bd9Sstevel@tonic-gate amask = ainfo->ai_mask; 14847c478bd9Sstevel@tonic-gate 14857c478bd9Sstevel@tonic-gate /* 14867c478bd9Sstevel@tonic-gate * Figure out the type of stream networking request here. 14877c478bd9Sstevel@tonic-gate * Note that getmsg and putmsg are always preselected 14887c478bd9Sstevel@tonic-gate * because during the beginning of the system call we have 14897c478bd9Sstevel@tonic-gate * not yet figure out which of the socket or tli request 14907c478bd9Sstevel@tonic-gate * we are looking at until we are here. So we need to check 14917c478bd9Sstevel@tonic-gate * against that specific request and reset the type of event. 14927c478bd9Sstevel@tonic-gate */ 14937c478bd9Sstevel@tonic-gate switch (type) { 14947c478bd9Sstevel@tonic-gate case T_CONN_REQ: /* connection request */ 14957c478bd9Sstevel@tonic-gate conn_req = (struct T_conn_req *)mp->b_rptr; 14967c478bd9Sstevel@tonic-gate if (conn_req->DEST_offset < sizeof (struct T_conn_req)) 14977c478bd9Sstevel@tonic-gate return; 14987c478bd9Sstevel@tonic-gate offset = conn_req->DEST_offset; 14997c478bd9Sstevel@tonic-gate len = conn_req->DEST_length; 15007c478bd9Sstevel@tonic-gate estate = kctx->auk_ets[AUE_SOCKCONNECT]; 15017c478bd9Sstevel@tonic-gate if (amask.as_success & estate || amask.as_failure & estate) { 15027c478bd9Sstevel@tonic-gate tad->tad_event = AUE_SOCKCONNECT; 15037c478bd9Sstevel@tonic-gate break; 15047c478bd9Sstevel@tonic-gate } else { 15057c478bd9Sstevel@tonic-gate return; 15067c478bd9Sstevel@tonic-gate } 15077c478bd9Sstevel@tonic-gate case T_CONN_IND: /* connectionless receive request */ 15087c478bd9Sstevel@tonic-gate conn_ind = (struct T_conn_ind *)mp->b_rptr; 15097c478bd9Sstevel@tonic-gate if (conn_ind->SRC_offset < sizeof (struct T_conn_ind)) 15107c478bd9Sstevel@tonic-gate return; 15117c478bd9Sstevel@tonic-gate offset = conn_ind->SRC_offset; 15127c478bd9Sstevel@tonic-gate len = conn_ind->SRC_length; 15137c478bd9Sstevel@tonic-gate estate = kctx->auk_ets[AUE_SOCKACCEPT]; 15147c478bd9Sstevel@tonic-gate if (amask.as_success & estate || amask.as_failure & estate) { 15157c478bd9Sstevel@tonic-gate tad->tad_event = AUE_SOCKACCEPT; 15167c478bd9Sstevel@tonic-gate break; 15177c478bd9Sstevel@tonic-gate } else { 15187c478bd9Sstevel@tonic-gate return; 15197c478bd9Sstevel@tonic-gate } 15207c478bd9Sstevel@tonic-gate case T_UNITDATA_REQ: /* connectionless send request */ 15217c478bd9Sstevel@tonic-gate unitdata_req = (struct T_unitdata_req *)mp->b_rptr; 15227c478bd9Sstevel@tonic-gate if (unitdata_req->DEST_offset < sizeof (struct T_unitdata_req)) 15237c478bd9Sstevel@tonic-gate return; 15247c478bd9Sstevel@tonic-gate offset = unitdata_req->DEST_offset; 15257c478bd9Sstevel@tonic-gate len = unitdata_req->DEST_length; 15267c478bd9Sstevel@tonic-gate estate = kctx->auk_ets[AUE_SOCKSEND]; 15277c478bd9Sstevel@tonic-gate if (amask.as_success & estate || amask.as_failure & estate) { 15287c478bd9Sstevel@tonic-gate tad->tad_event = AUE_SOCKSEND; 15297c478bd9Sstevel@tonic-gate break; 15307c478bd9Sstevel@tonic-gate } else { 15317c478bd9Sstevel@tonic-gate return; 15327c478bd9Sstevel@tonic-gate } 15337c478bd9Sstevel@tonic-gate case T_UNITDATA_IND: /* connectionless receive request */ 15347c478bd9Sstevel@tonic-gate unitdata_ind = (struct T_unitdata_ind *)mp->b_rptr; 15357c478bd9Sstevel@tonic-gate if (unitdata_ind->SRC_offset < sizeof (struct T_unitdata_ind)) 15367c478bd9Sstevel@tonic-gate return; 15377c478bd9Sstevel@tonic-gate offset = unitdata_ind->SRC_offset; 15387c478bd9Sstevel@tonic-gate len = unitdata_ind->SRC_length; 15397c478bd9Sstevel@tonic-gate estate = kctx->auk_ets[AUE_SOCKRECEIVE]; 15407c478bd9Sstevel@tonic-gate if (amask.as_success & estate || amask.as_failure & estate) { 15417c478bd9Sstevel@tonic-gate tad->tad_event = AUE_SOCKRECEIVE; 15427c478bd9Sstevel@tonic-gate break; 15437c478bd9Sstevel@tonic-gate } else { 15447c478bd9Sstevel@tonic-gate return; 15457c478bd9Sstevel@tonic-gate } 15467c478bd9Sstevel@tonic-gate default: 15477c478bd9Sstevel@tonic-gate return; 15487c478bd9Sstevel@tonic-gate } 15497c478bd9Sstevel@tonic-gate 15507c478bd9Sstevel@tonic-gate /* 15517c478bd9Sstevel@tonic-gate * we are only interested in tcp stream connections, 15527c478bd9Sstevel@tonic-gate * not unix domain stuff 15537c478bd9Sstevel@tonic-gate */ 15547c478bd9Sstevel@tonic-gate if ((len < 0) || (len > sizeof (struct sockaddr_in))) { 15557c478bd9Sstevel@tonic-gate tad->tad_event = AUE_GETMSG; 15567c478bd9Sstevel@tonic-gate return; 15577c478bd9Sstevel@tonic-gate } 15587c478bd9Sstevel@tonic-gate /* skip over TPI header and point to the ip address */ 15597c478bd9Sstevel@tonic-gate sock_data = (struct sockaddr_in *)((char *)mp->b_rptr + offset); 15607c478bd9Sstevel@tonic-gate 15617c478bd9Sstevel@tonic-gate switch (sock_data->sin_family) { 15627c478bd9Sstevel@tonic-gate case AF_INET: 15637c478bd9Sstevel@tonic-gate au_write(&(tad->tad_ad), au_to_sock_inet(sock_data)); 15647c478bd9Sstevel@tonic-gate break; 15657c478bd9Sstevel@tonic-gate default: /* reset to AUE_PUTMSG if not a inet request */ 15667c478bd9Sstevel@tonic-gate tad->tad_event = AUE_GETMSG; 15677c478bd9Sstevel@tonic-gate break; 15687c478bd9Sstevel@tonic-gate } 15697c478bd9Sstevel@tonic-gate } 15707c478bd9Sstevel@tonic-gate 15717c478bd9Sstevel@tonic-gate 15727c478bd9Sstevel@tonic-gate static void 15737c478bd9Sstevel@tonic-gate add_return_token(caddr_t *ad, unsigned int scid, int err, int rval) 15747c478bd9Sstevel@tonic-gate { 15757c478bd9Sstevel@tonic-gate unsigned int sy_flags; 15767c478bd9Sstevel@tonic-gate 15777c478bd9Sstevel@tonic-gate #ifdef _SYSCALL32_IMPL 1578950d6705SPaul Wernau /* 1579950d6705SPaul Wernau * Guard against t_lwp being NULL when this function is called 1580950d6705SPaul Wernau * from a kernel queue instead of from a direct system call. 1581950d6705SPaul Wernau * In that case, assume the running kernel data model. 1582950d6705SPaul Wernau */ 1583950d6705SPaul Wernau if ((curthread->t_lwp == NULL) || (lwp_getdatamodel( 1584950d6705SPaul Wernau ttolwp(curthread)) == DATAMODEL_NATIVE)) 15857c478bd9Sstevel@tonic-gate sy_flags = sysent[scid].sy_flags & SE_RVAL_MASK; 15867c478bd9Sstevel@tonic-gate else 15877c478bd9Sstevel@tonic-gate sy_flags = sysent32[scid].sy_flags & SE_RVAL_MASK; 15887c478bd9Sstevel@tonic-gate #else 15897c478bd9Sstevel@tonic-gate sy_flags = sysent[scid].sy_flags & SE_RVAL_MASK; 15907c478bd9Sstevel@tonic-gate #endif 15917c478bd9Sstevel@tonic-gate 15927c478bd9Sstevel@tonic-gate if (sy_flags == SE_64RVAL) 15937c478bd9Sstevel@tonic-gate au_write(ad, au_to_return64(err, rval)); 15947c478bd9Sstevel@tonic-gate else 15957c478bd9Sstevel@tonic-gate au_write(ad, au_to_return32(err, rval)); 15967c478bd9Sstevel@tonic-gate 15977c478bd9Sstevel@tonic-gate } 15987c478bd9Sstevel@tonic-gate 15997c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 16007c478bd9Sstevel@tonic-gate void 16017c478bd9Sstevel@tonic-gate audit_fdsend(fd, fp, error) 16027c478bd9Sstevel@tonic-gate int fd; 16037c478bd9Sstevel@tonic-gate struct file *fp; 16047c478bd9Sstevel@tonic-gate int error; /* ignore for now */ 16057c478bd9Sstevel@tonic-gate { 16067c478bd9Sstevel@tonic-gate t_audit_data_t *tad; /* current thread */ 16077c478bd9Sstevel@tonic-gate f_audit_data_t *fad; /* per file audit structure */ 16087c478bd9Sstevel@tonic-gate struct vnode *vp; /* for file attributes */ 16097c478bd9Sstevel@tonic-gate 16107c478bd9Sstevel@tonic-gate /* is this system call being audited */ 16117c478bd9Sstevel@tonic-gate tad = U2A(u); 16127c478bd9Sstevel@tonic-gate ASSERT(tad != (t_audit_data_t *)0); 16137c478bd9Sstevel@tonic-gate if (!tad->tad_flag) 16147c478bd9Sstevel@tonic-gate return; 16157c478bd9Sstevel@tonic-gate 16167c478bd9Sstevel@tonic-gate fad = F2A(fp); 16177c478bd9Sstevel@tonic-gate 16187c478bd9Sstevel@tonic-gate /* add path and file attributes */ 16197c478bd9Sstevel@tonic-gate if (fad != NULL && fad->fad_aupath != NULL) { 16207c478bd9Sstevel@tonic-gate au_uwrite(au_to_arg32(0, "send fd", (uint32_t)fd)); 16217c478bd9Sstevel@tonic-gate au_uwrite(au_to_path(fad->fad_aupath)); 16227c478bd9Sstevel@tonic-gate } else { 16237c478bd9Sstevel@tonic-gate au_uwrite(au_to_arg32(0, "send fd", (uint32_t)fd)); 16247c478bd9Sstevel@tonic-gate #ifdef _LP64 16257c478bd9Sstevel@tonic-gate au_uwrite(au_to_arg64(0, "no path", (uint64_t)fp)); 16267c478bd9Sstevel@tonic-gate #else 16277c478bd9Sstevel@tonic-gate au_uwrite(au_to_arg32(0, "no path", (uint32_t)fp)); 16287c478bd9Sstevel@tonic-gate #endif 16297c478bd9Sstevel@tonic-gate } 16307c478bd9Sstevel@tonic-gate vp = fp->f_vnode; /* include vnode attributes */ 16317c478bd9Sstevel@tonic-gate audit_attributes(vp); 16327c478bd9Sstevel@tonic-gate } 16337c478bd9Sstevel@tonic-gate 16347c478bd9Sstevel@tonic-gate /* 1635da6c28aaSamw * Record privileges successfully used and we attempted to use but 16367c478bd9Sstevel@tonic-gate * didn't have. 16377c478bd9Sstevel@tonic-gate */ 16387c478bd9Sstevel@tonic-gate void 16397c478bd9Sstevel@tonic-gate audit_priv(int priv, const priv_set_t *set, int flag) 16407c478bd9Sstevel@tonic-gate { 16417c478bd9Sstevel@tonic-gate t_audit_data_t *tad; 16427c478bd9Sstevel@tonic-gate int sbit; 16437c478bd9Sstevel@tonic-gate priv_set_t *target; 16447c478bd9Sstevel@tonic-gate 16457c478bd9Sstevel@tonic-gate /* Make sure this isn't being called in an interrupt context */ 16467c478bd9Sstevel@tonic-gate ASSERT(servicing_interrupt() == 0); 16477c478bd9Sstevel@tonic-gate 16487c478bd9Sstevel@tonic-gate tad = U2A(u); 16497c478bd9Sstevel@tonic-gate 16507c478bd9Sstevel@tonic-gate if (tad->tad_flag == 0) 16517c478bd9Sstevel@tonic-gate return; 16527c478bd9Sstevel@tonic-gate 16537c478bd9Sstevel@tonic-gate target = flag ? &tad->tad_sprivs : &tad->tad_fprivs; 16547c478bd9Sstevel@tonic-gate sbit = flag ? PAD_SPRIVUSE : PAD_FPRIVUSE; 16557c478bd9Sstevel@tonic-gate 16567c478bd9Sstevel@tonic-gate /* Tell audit_success() and audit_finish() that we saw this case */ 16577c478bd9Sstevel@tonic-gate if (!(tad->tad_evmod & sbit)) { 16587c478bd9Sstevel@tonic-gate /* Clear set first time around */ 16597c478bd9Sstevel@tonic-gate priv_emptyset(target); 16607c478bd9Sstevel@tonic-gate tad->tad_evmod |= sbit; 16617c478bd9Sstevel@tonic-gate } 16627c478bd9Sstevel@tonic-gate 16637c478bd9Sstevel@tonic-gate /* Save the privileges in the tad */ 16647c478bd9Sstevel@tonic-gate if (priv == PRIV_ALL) { 16657c478bd9Sstevel@tonic-gate priv_fillset(target); 16667c478bd9Sstevel@tonic-gate } else { 16677c478bd9Sstevel@tonic-gate ASSERT(set != NULL || priv != PRIV_NONE); 16687c478bd9Sstevel@tonic-gate if (set != NULL) 16697c478bd9Sstevel@tonic-gate priv_union(set, target); 16707c478bd9Sstevel@tonic-gate if (priv != PRIV_NONE) 16717c478bd9Sstevel@tonic-gate priv_addset(target, priv); 16727c478bd9Sstevel@tonic-gate } 16737c478bd9Sstevel@tonic-gate } 16747c478bd9Sstevel@tonic-gate 16757c478bd9Sstevel@tonic-gate /* 16767c478bd9Sstevel@tonic-gate * Audit the setpriv() system call; the operation, the set name and 16777c478bd9Sstevel@tonic-gate * the current value as well as the set argument are put in the 16787c478bd9Sstevel@tonic-gate * audit trail. 16797c478bd9Sstevel@tonic-gate */ 16807c478bd9Sstevel@tonic-gate void 16817c478bd9Sstevel@tonic-gate audit_setppriv(int op, int set, const priv_set_t *newpriv, const cred_t *ocr) 16827c478bd9Sstevel@tonic-gate { 16837c478bd9Sstevel@tonic-gate t_audit_data_t *tad; 16847c478bd9Sstevel@tonic-gate const priv_set_t *oldpriv; 16857c478bd9Sstevel@tonic-gate priv_set_t report; 16867c478bd9Sstevel@tonic-gate const char *setname; 16877c478bd9Sstevel@tonic-gate 16887c478bd9Sstevel@tonic-gate tad = U2A(u); 16897c478bd9Sstevel@tonic-gate 16907c478bd9Sstevel@tonic-gate if (tad->tad_flag == 0) 16917c478bd9Sstevel@tonic-gate return; 16927c478bd9Sstevel@tonic-gate 16937c478bd9Sstevel@tonic-gate oldpriv = priv_getset(ocr, set); 16947c478bd9Sstevel@tonic-gate 16957c478bd9Sstevel@tonic-gate /* Generate the actual record, include the before and after */ 16967c478bd9Sstevel@tonic-gate au_uwrite(au_to_arg32(2, "op", op)); 16977c478bd9Sstevel@tonic-gate setname = priv_getsetbynum(set); 16987c478bd9Sstevel@tonic-gate 16997c478bd9Sstevel@tonic-gate switch (op) { 17007c478bd9Sstevel@tonic-gate case PRIV_OFF: 17017c478bd9Sstevel@tonic-gate /* Report privileges actually switched off */ 17027c478bd9Sstevel@tonic-gate report = *oldpriv; 17037c478bd9Sstevel@tonic-gate priv_intersect(newpriv, &report); 17047c478bd9Sstevel@tonic-gate au_uwrite(au_to_privset(setname, &report, AUT_PRIV, 0)); 17057c478bd9Sstevel@tonic-gate break; 17067c478bd9Sstevel@tonic-gate case PRIV_ON: 17077c478bd9Sstevel@tonic-gate /* Report privileges actually switched on */ 17087c478bd9Sstevel@tonic-gate report = *oldpriv; 17097c478bd9Sstevel@tonic-gate priv_inverse(&report); 17107c478bd9Sstevel@tonic-gate priv_intersect(newpriv, &report); 17117c478bd9Sstevel@tonic-gate au_uwrite(au_to_privset(setname, &report, AUT_PRIV, 0)); 17127c478bd9Sstevel@tonic-gate break; 17137c478bd9Sstevel@tonic-gate case PRIV_SET: 17147c478bd9Sstevel@tonic-gate /* Report before and after */ 17157c478bd9Sstevel@tonic-gate au_uwrite(au_to_privset(setname, oldpriv, AUT_PRIV, 0)); 17167c478bd9Sstevel@tonic-gate au_uwrite(au_to_privset(setname, newpriv, AUT_PRIV, 0)); 17177c478bd9Sstevel@tonic-gate break; 17187c478bd9Sstevel@tonic-gate } 17197c478bd9Sstevel@tonic-gate } 17207c478bd9Sstevel@tonic-gate 17217c478bd9Sstevel@tonic-gate /* 17227c478bd9Sstevel@tonic-gate * Dump the full device policy setting in the audit trail. 17237c478bd9Sstevel@tonic-gate */ 17247c478bd9Sstevel@tonic-gate void 17257c478bd9Sstevel@tonic-gate audit_devpolicy(int nitems, const devplcysys_t *items) 17267c478bd9Sstevel@tonic-gate { 17277c478bd9Sstevel@tonic-gate t_audit_data_t *tad; 17287c478bd9Sstevel@tonic-gate int i; 17297c478bd9Sstevel@tonic-gate 17307c478bd9Sstevel@tonic-gate tad = U2A(u); 17317c478bd9Sstevel@tonic-gate 17327c478bd9Sstevel@tonic-gate if (tad->tad_flag == 0) 17337c478bd9Sstevel@tonic-gate return; 17347c478bd9Sstevel@tonic-gate 17357c478bd9Sstevel@tonic-gate for (i = 0; i < nitems; i++) { 17367c478bd9Sstevel@tonic-gate au_uwrite(au_to_arg32(2, "major", items[i].dps_maj)); 17377c478bd9Sstevel@tonic-gate if (items[i].dps_minornm[0] == '\0') { 17387c478bd9Sstevel@tonic-gate au_uwrite(au_to_arg32(2, "lomin", items[i].dps_lomin)); 17397c478bd9Sstevel@tonic-gate au_uwrite(au_to_arg32(2, "himin", items[i].dps_himin)); 17407c478bd9Sstevel@tonic-gate } else 17417c478bd9Sstevel@tonic-gate au_uwrite(au_to_text(items[i].dps_minornm)); 17427c478bd9Sstevel@tonic-gate 17437c478bd9Sstevel@tonic-gate au_uwrite(au_to_privset("read", &items[i].dps_rdp, 17447c478bd9Sstevel@tonic-gate AUT_PRIV, 0)); 17457c478bd9Sstevel@tonic-gate au_uwrite(au_to_privset("write", &items[i].dps_wrp, 17467c478bd9Sstevel@tonic-gate AUT_PRIV, 0)); 17477c478bd9Sstevel@tonic-gate } 17487c478bd9Sstevel@tonic-gate } 17497c478bd9Sstevel@tonic-gate 17507c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 17517c478bd9Sstevel@tonic-gate void 17527c478bd9Sstevel@tonic-gate audit_fdrecv(fd, fp) 17537c478bd9Sstevel@tonic-gate int fd; 17547c478bd9Sstevel@tonic-gate struct file *fp; 17557c478bd9Sstevel@tonic-gate { 17567c478bd9Sstevel@tonic-gate t_audit_data_t *tad; /* current thread */ 17577c478bd9Sstevel@tonic-gate f_audit_data_t *fad; /* per file audit structure */ 17587c478bd9Sstevel@tonic-gate struct vnode *vp; /* for file attributes */ 17597c478bd9Sstevel@tonic-gate 17607c478bd9Sstevel@tonic-gate /* is this system call being audited */ 17617c478bd9Sstevel@tonic-gate tad = U2A(u); 17627c478bd9Sstevel@tonic-gate ASSERT(tad != (t_audit_data_t *)0); 17637c478bd9Sstevel@tonic-gate if (!tad->tad_flag) 17647c478bd9Sstevel@tonic-gate return; 17657c478bd9Sstevel@tonic-gate 17667c478bd9Sstevel@tonic-gate fad = F2A(fp); 17677c478bd9Sstevel@tonic-gate 17687c478bd9Sstevel@tonic-gate /* add path and file attributes */ 17697c478bd9Sstevel@tonic-gate if (fad != NULL && fad->fad_aupath != NULL) { 17707c478bd9Sstevel@tonic-gate au_uwrite(au_to_arg32(0, "recv fd", (uint32_t)fd)); 17717c478bd9Sstevel@tonic-gate au_uwrite(au_to_path(fad->fad_aupath)); 17727c478bd9Sstevel@tonic-gate } else { 17737c478bd9Sstevel@tonic-gate au_uwrite(au_to_arg32(0, "recv fd", (uint32_t)fd)); 17747c478bd9Sstevel@tonic-gate #ifdef _LP64 17757c478bd9Sstevel@tonic-gate au_uwrite(au_to_arg64(0, "no path", (uint64_t)fp)); 17767c478bd9Sstevel@tonic-gate #else 17777c478bd9Sstevel@tonic-gate au_uwrite(au_to_arg32(0, "no path", (uint32_t)fp)); 17787c478bd9Sstevel@tonic-gate #endif 17797c478bd9Sstevel@tonic-gate } 17807c478bd9Sstevel@tonic-gate vp = fp->f_vnode; /* include vnode attributes */ 17817c478bd9Sstevel@tonic-gate audit_attributes(vp); 17827c478bd9Sstevel@tonic-gate } 17837c478bd9Sstevel@tonic-gate 17847c478bd9Sstevel@tonic-gate /* 17857c478bd9Sstevel@tonic-gate * ROUTINE: AUDIT_CRYPTOADM 17867c478bd9Sstevel@tonic-gate * PURPOSE: Records arguments to administrative ioctls on /dev/cryptoadm 17877c478bd9Sstevel@tonic-gate * CALLBY: CRYPTO_LOAD_DEV_DISABLED, CRYPTO_LOAD_SOFT_DISABLED, 17887c478bd9Sstevel@tonic-gate * CRYPTO_UNLOAD_SOFT_MODULE, CRYPTO_LOAD_SOFT_CONFIG, 17897c478bd9Sstevel@tonic-gate * CRYPTO_POOL_CREATE, CRYPTO_POOL_WAIT, CRYPTO_POOL_RUN, 17907c478bd9Sstevel@tonic-gate * CRYPTO_LOAD_DOOR 17917c478bd9Sstevel@tonic-gate * NOTE: 17927c478bd9Sstevel@tonic-gate * TODO: 17937c478bd9Sstevel@tonic-gate * QUESTION: 17947c478bd9Sstevel@tonic-gate */ 17957c478bd9Sstevel@tonic-gate 17967c478bd9Sstevel@tonic-gate void 17977c478bd9Sstevel@tonic-gate audit_cryptoadm(int cmd, char *module_name, crypto_mech_name_t *mech_names, 17987c478bd9Sstevel@tonic-gate uint_t mech_count, uint_t device_instance, uint32_t rv, int error) 17997c478bd9Sstevel@tonic-gate { 18007c478bd9Sstevel@tonic-gate boolean_t mech_list_required = B_FALSE; 18017c478bd9Sstevel@tonic-gate cred_t *cr = CRED(); 18027c478bd9Sstevel@tonic-gate t_audit_data_t *tad; 18037c478bd9Sstevel@tonic-gate token_t *ad = NULL; 18047c478bd9Sstevel@tonic-gate const auditinfo_addr_t *ainfo = crgetauinfo(cr); 18057c478bd9Sstevel@tonic-gate char buffer[MAXNAMELEN * 2]; 18069e9e6ab8Spaulson au_kcontext_t *kctx = GET_KCTX_PZ; 18077c478bd9Sstevel@tonic-gate 18087c478bd9Sstevel@tonic-gate tad = U2A(u); 18097c478bd9Sstevel@tonic-gate if (tad == NULL) 18107c478bd9Sstevel@tonic-gate return; 18117c478bd9Sstevel@tonic-gate 18127c478bd9Sstevel@tonic-gate if (ainfo == NULL) 18137c478bd9Sstevel@tonic-gate return; 18147c478bd9Sstevel@tonic-gate 18157c478bd9Sstevel@tonic-gate tad->tad_event = AUE_CRYPTOADM; 18167c478bd9Sstevel@tonic-gate 1817799bd290Spwernau if (audit_success(kctx, tad, error, NULL) != AU_OK) 18187c478bd9Sstevel@tonic-gate return; 18197c478bd9Sstevel@tonic-gate 182081490fd2Sgww /* Add subject information */ 182181490fd2Sgww AUDIT_SETSUBJ((caddr_t *)&(ad), cr, ainfo, kctx); 182245916cd2Sjpk 18237c478bd9Sstevel@tonic-gate switch (cmd) { 18247c478bd9Sstevel@tonic-gate case CRYPTO_LOAD_DEV_DISABLED: 18257c478bd9Sstevel@tonic-gate if (error == 0 && rv == CRYPTO_SUCCESS) { 18267c478bd9Sstevel@tonic-gate (void) snprintf(buffer, sizeof (buffer), 18277c478bd9Sstevel@tonic-gate "op=CRYPTO_LOAD_DEV_DISABLED, module=%s," 18287c478bd9Sstevel@tonic-gate " dev_instance=%d", 18297c478bd9Sstevel@tonic-gate module_name, device_instance); 18307c478bd9Sstevel@tonic-gate mech_list_required = B_TRUE; 18317c478bd9Sstevel@tonic-gate } else { 18327c478bd9Sstevel@tonic-gate (void) snprintf(buffer, sizeof (buffer), 18337c478bd9Sstevel@tonic-gate "op=CRYPTO_LOAD_DEV_DISABLED, return_val=%d", rv); 18347c478bd9Sstevel@tonic-gate } 18357c478bd9Sstevel@tonic-gate break; 18367c478bd9Sstevel@tonic-gate 18377c478bd9Sstevel@tonic-gate case CRYPTO_LOAD_SOFT_DISABLED: 18387c478bd9Sstevel@tonic-gate if (error == 0 && rv == CRYPTO_SUCCESS) { 18397c478bd9Sstevel@tonic-gate (void) snprintf(buffer, sizeof (buffer), 18407c478bd9Sstevel@tonic-gate "op=CRYPTO_LOAD_SOFT_DISABLED, module=%s", 18417c478bd9Sstevel@tonic-gate module_name); 18427c478bd9Sstevel@tonic-gate mech_list_required = B_TRUE; 18437c478bd9Sstevel@tonic-gate } else { 18447c478bd9Sstevel@tonic-gate (void) snprintf(buffer, sizeof (buffer), 18457c478bd9Sstevel@tonic-gate "op=CRYPTO_LOAD_SOFT_DISABLED, return_val=%d", rv); 18467c478bd9Sstevel@tonic-gate } 18477c478bd9Sstevel@tonic-gate break; 18487c478bd9Sstevel@tonic-gate 18497c478bd9Sstevel@tonic-gate case CRYPTO_UNLOAD_SOFT_MODULE: 18507c478bd9Sstevel@tonic-gate if (error == 0 && rv == CRYPTO_SUCCESS) { 18517c478bd9Sstevel@tonic-gate (void) snprintf(buffer, sizeof (buffer), 18527c478bd9Sstevel@tonic-gate "op=CRYPTO_UNLOAD_SOFT_MODULE, module=%s", 18537c478bd9Sstevel@tonic-gate module_name); 18547c478bd9Sstevel@tonic-gate } else { 18557c478bd9Sstevel@tonic-gate (void) snprintf(buffer, sizeof (buffer), 18567c478bd9Sstevel@tonic-gate "op=CRYPTO_UNLOAD_SOFT_MODULE, return_val=%d", rv); 18577c478bd9Sstevel@tonic-gate } 18587c478bd9Sstevel@tonic-gate break; 18597c478bd9Sstevel@tonic-gate 18607c478bd9Sstevel@tonic-gate case CRYPTO_LOAD_SOFT_CONFIG: 18617c478bd9Sstevel@tonic-gate if (error == 0 && rv == CRYPTO_SUCCESS) { 18627c478bd9Sstevel@tonic-gate (void) snprintf(buffer, sizeof (buffer), 18637c478bd9Sstevel@tonic-gate "op=CRYPTO_LOAD_SOFT_CONFIG, module=%s", 18647c478bd9Sstevel@tonic-gate module_name); 18657c478bd9Sstevel@tonic-gate mech_list_required = B_TRUE; 18667c478bd9Sstevel@tonic-gate } else { 18677c478bd9Sstevel@tonic-gate (void) snprintf(buffer, sizeof (buffer), 18687c478bd9Sstevel@tonic-gate "op=CRYPTO_LOAD_SOFT_CONFIG, return_val=%d", rv); 18697c478bd9Sstevel@tonic-gate } 18707c478bd9Sstevel@tonic-gate break; 18717c478bd9Sstevel@tonic-gate 18727c478bd9Sstevel@tonic-gate case CRYPTO_POOL_CREATE: 18737c478bd9Sstevel@tonic-gate (void) snprintf(buffer, sizeof (buffer), 18747c478bd9Sstevel@tonic-gate "op=CRYPTO_POOL_CREATE"); 18757c478bd9Sstevel@tonic-gate break; 18767c478bd9Sstevel@tonic-gate 18777c478bd9Sstevel@tonic-gate case CRYPTO_POOL_WAIT: 18787c478bd9Sstevel@tonic-gate (void) snprintf(buffer, sizeof (buffer), "op=CRYPTO_POOL_WAIT"); 18797c478bd9Sstevel@tonic-gate break; 18807c478bd9Sstevel@tonic-gate 18817c478bd9Sstevel@tonic-gate case CRYPTO_POOL_RUN: 18827c478bd9Sstevel@tonic-gate (void) snprintf(buffer, sizeof (buffer), "op=CRYPTO_POOL_RUN"); 18837c478bd9Sstevel@tonic-gate break; 18847c478bd9Sstevel@tonic-gate 18857c478bd9Sstevel@tonic-gate case CRYPTO_LOAD_DOOR: 18867c478bd9Sstevel@tonic-gate if (error == 0 && rv == CRYPTO_SUCCESS) 18877c478bd9Sstevel@tonic-gate (void) snprintf(buffer, sizeof (buffer), 18887c478bd9Sstevel@tonic-gate "op=CRYPTO_LOAD_DOOR"); 18897c478bd9Sstevel@tonic-gate else 18907c478bd9Sstevel@tonic-gate (void) snprintf(buffer, sizeof (buffer), 18917c478bd9Sstevel@tonic-gate "op=CRYPTO_LOAD_DOOR, return_val=%d", rv); 18927c478bd9Sstevel@tonic-gate break; 18937c478bd9Sstevel@tonic-gate 189473556491SAnthony Scarpino case CRYPTO_FIPS140_SET: 189573556491SAnthony Scarpino (void) snprintf(buffer, sizeof (buffer), 189673556491SAnthony Scarpino "op=CRYPTO_FIPS140_SET, fips_state=%d", rv); 189773556491SAnthony Scarpino break; 189873556491SAnthony Scarpino 18997c478bd9Sstevel@tonic-gate default: 19007c478bd9Sstevel@tonic-gate return; 19017c478bd9Sstevel@tonic-gate } 19027c478bd9Sstevel@tonic-gate 19037c478bd9Sstevel@tonic-gate au_write((caddr_t *)&ad, au_to_text(buffer)); 19047c478bd9Sstevel@tonic-gate 19057c478bd9Sstevel@tonic-gate if (mech_list_required) { 19067c478bd9Sstevel@tonic-gate int i; 19077c478bd9Sstevel@tonic-gate 19087c478bd9Sstevel@tonic-gate if (mech_count == 0) { 19097c478bd9Sstevel@tonic-gate au_write((caddr_t *)&ad, au_to_text("mech=list empty")); 19107c478bd9Sstevel@tonic-gate } else { 19117c478bd9Sstevel@tonic-gate char *pb = buffer; 19127c478bd9Sstevel@tonic-gate size_t l = sizeof (buffer); 19137c478bd9Sstevel@tonic-gate size_t n; 19147c478bd9Sstevel@tonic-gate char space[2] = ":"; 19157c478bd9Sstevel@tonic-gate 19167c478bd9Sstevel@tonic-gate n = snprintf(pb, l, "mech="); 19177c478bd9Sstevel@tonic-gate 19187c478bd9Sstevel@tonic-gate for (i = 0; i < mech_count; i++) { 19197c478bd9Sstevel@tonic-gate pb += n; 19205c93ad81SMarek Pospisil l = (n >= l) ? 0 : l - n; 19217c478bd9Sstevel@tonic-gate 19227c478bd9Sstevel@tonic-gate if (i == mech_count - 1) 19237c478bd9Sstevel@tonic-gate (void) strcpy(space, ""); 19247c478bd9Sstevel@tonic-gate 19257c478bd9Sstevel@tonic-gate n = snprintf(pb, l, "%s%s", mech_names[i], 19267c478bd9Sstevel@tonic-gate space); 19277c478bd9Sstevel@tonic-gate } 19287c478bd9Sstevel@tonic-gate au_write((caddr_t *)&ad, au_to_text(buffer)); 19297c478bd9Sstevel@tonic-gate } 19307c478bd9Sstevel@tonic-gate } 19317c478bd9Sstevel@tonic-gate 19327c478bd9Sstevel@tonic-gate /* add a return token */ 19337c478bd9Sstevel@tonic-gate if (error || (rv != CRYPTO_SUCCESS)) 19347c478bd9Sstevel@tonic-gate add_return_token((caddr_t *)&ad, tad->tad_scid, -1, error); 19357c478bd9Sstevel@tonic-gate else 19367c478bd9Sstevel@tonic-gate add_return_token((caddr_t *)&ad, tad->tad_scid, 0, rv); 19377c478bd9Sstevel@tonic-gate 19387c478bd9Sstevel@tonic-gate AS_INC(as_generated, 1, kctx); 19397c478bd9Sstevel@tonic-gate AS_INC(as_kernel, 1, kctx); 19407c478bd9Sstevel@tonic-gate 1941005d3febSMarek Pospisil au_close(kctx, (caddr_t *)&ad, AU_OK, AUE_CRYPTOADM, tad->tad_evmod, 1942005d3febSMarek Pospisil NULL); 19437c478bd9Sstevel@tonic-gate } 1944c28749e9Skais 1945c28749e9Skais /* 1946c28749e9Skais * Audit the kernel SSL administration command. The address and the 1947c28749e9Skais * port number for the SSL instance, and the proxy port are put in the 1948c28749e9Skais * audit trail. 1949c28749e9Skais */ 1950c28749e9Skais void 1951c28749e9Skais audit_kssl(int cmd, void *params, int error) 1952c28749e9Skais { 1953c28749e9Skais cred_t *cr = CRED(); 1954c28749e9Skais t_audit_data_t *tad; 1955c28749e9Skais token_t *ad = NULL; 1956c28749e9Skais const auditinfo_addr_t *ainfo = crgetauinfo(cr); 19579e9e6ab8Spaulson au_kcontext_t *kctx = GET_KCTX_PZ; 1958c28749e9Skais 1959c28749e9Skais tad = U2A(u); 1960c28749e9Skais 1961c28749e9Skais if (ainfo == NULL) 1962c28749e9Skais return; 1963c28749e9Skais 1964c28749e9Skais tad->tad_event = AUE_CONFIGKSSL; 1965c28749e9Skais 1966799bd290Spwernau if (audit_success(kctx, tad, error, NULL) != AU_OK) 1967c28749e9Skais return; 1968c28749e9Skais 196981490fd2Sgww /* Add subject information */ 197081490fd2Sgww AUDIT_SETSUBJ((caddr_t *)&ad, cr, ainfo, kctx); 197145916cd2Sjpk 1972c28749e9Skais switch (cmd) { 1973c28749e9Skais case KSSL_ADD_ENTRY: { 1974c28749e9Skais char buf[32]; 1975c28749e9Skais kssl_params_t *kp = (kssl_params_t *)params; 19762ec7cc7fSKrishna Yenduri struct sockaddr_in6 *saddr = &kp->kssl_addr; 1977c28749e9Skais 1978c28749e9Skais au_write((caddr_t *)&ad, au_to_text("op=KSSL_ADD_ENTRY")); 19792ec7cc7fSKrishna Yenduri au_write((caddr_t *)&ad, 19802ec7cc7fSKrishna Yenduri au_to_in_addr_ex((int32_t *)&saddr->sin6_addr)); 1981c28749e9Skais (void) snprintf(buf, sizeof (buf), "SSL port=%d", 19822ec7cc7fSKrishna Yenduri saddr->sin6_port); 1983c28749e9Skais au_write((caddr_t *)&ad, au_to_text(buf)); 1984c28749e9Skais 1985c28749e9Skais (void) snprintf(buf, sizeof (buf), "proxy port=%d", 1986c28749e9Skais kp->kssl_proxy_port); 1987c28749e9Skais au_write((caddr_t *)&ad, au_to_text(buf)); 1988c28749e9Skais break; 1989c28749e9Skais } 1990c28749e9Skais 1991c28749e9Skais case KSSL_DELETE_ENTRY: { 1992c28749e9Skais char buf[32]; 19932ec7cc7fSKrishna Yenduri struct sockaddr_in6 *saddr = (struct sockaddr_in6 *)params; 1994c28749e9Skais 1995c28749e9Skais au_write((caddr_t *)&ad, au_to_text("op=KSSL_DELETE_ENTRY")); 19962ec7cc7fSKrishna Yenduri au_write((caddr_t *)&ad, 19972ec7cc7fSKrishna Yenduri au_to_in_addr_ex((int32_t *)&saddr->sin6_addr)); 1998c28749e9Skais (void) snprintf(buf, sizeof (buf), "SSL port=%d", 19992ec7cc7fSKrishna Yenduri saddr->sin6_port); 2000c28749e9Skais au_write((caddr_t *)&ad, au_to_text(buf)); 2001c28749e9Skais break; 2002c28749e9Skais } 2003c28749e9Skais 2004c28749e9Skais default: 2005c28749e9Skais return; 2006c28749e9Skais } 2007c28749e9Skais 2008c28749e9Skais /* add a return token */ 2009c28749e9Skais add_return_token((caddr_t *)&ad, tad->tad_scid, error, 0); 2010c28749e9Skais 2011c28749e9Skais AS_INC(as_generated, 1, kctx); 2012c28749e9Skais AS_INC(as_kernel, 1, kctx); 2013c28749e9Skais 2014005d3febSMarek Pospisil au_close(kctx, (caddr_t *)&ad, AU_OK, AUE_CONFIGKSSL, tad->tad_evmod, 2015005d3febSMarek Pospisil NULL); 2016c28749e9Skais } 201745916cd2Sjpk 201845916cd2Sjpk /* 2019799bd290Spwernau * Audit the kernel PF_POLICY administration commands. Record command, 2020799bd290Spwernau * zone, policy type (global or tunnel, active or inactive) 2021799bd290Spwernau */ 2022799bd290Spwernau /* 2023799bd290Spwernau * ROUTINE: AUDIT_PF_POLICY 2024799bd290Spwernau * PURPOSE: Records arguments to administrative ioctls on PF_POLICY socket 2025799bd290Spwernau * CALLBY: SPD_ADDRULE, SPD_DELETERULE, SPD_FLUSH, SPD_UPDATEALGS, 2026799bd290Spwernau * SPD_CLONE, SPD_FLIP 2027799bd290Spwernau * NOTE: 2028799bd290Spwernau * TODO: 2029799bd290Spwernau * QUESTION: 2030799bd290Spwernau */ 2031799bd290Spwernau 2032799bd290Spwernau void 2033799bd290Spwernau audit_pf_policy(int cmd, cred_t *cred, netstack_t *ns, char *tun, 2034799bd290Spwernau boolean_t active, int error, pid_t pid) 2035799bd290Spwernau { 2036799bd290Spwernau const auditinfo_addr_t *ainfo; 2037799bd290Spwernau t_audit_data_t *tad; 2038799bd290Spwernau token_t *ad = NULL; 2039799bd290Spwernau au_kcontext_t *kctx = GET_KCTX_PZ; 2040799bd290Spwernau char buf[80]; 2041799bd290Spwernau int flag; 2042799bd290Spwernau 2043799bd290Spwernau tad = U2A(u); 2044799bd290Spwernau if (tad == NULL) 2045799bd290Spwernau return; 2046799bd290Spwernau 2047799bd290Spwernau ainfo = crgetauinfo((cred != NULL) ? cred : CRED()); 2048799bd290Spwernau if (ainfo == NULL) 2049799bd290Spwernau return; 2050799bd290Spwernau 2051799bd290Spwernau /* 2052799bd290Spwernau * Initialize some variables since these are only set 2053799bd290Spwernau * with system calls. 2054799bd290Spwernau */ 2055799bd290Spwernau 2056799bd290Spwernau switch (cmd) { 2057799bd290Spwernau case SPD_ADDRULE: { 2058799bd290Spwernau tad->tad_event = AUE_PF_POLICY_ADDRULE; 2059799bd290Spwernau break; 2060799bd290Spwernau } 2061799bd290Spwernau 2062799bd290Spwernau case SPD_DELETERULE: { 2063799bd290Spwernau tad->tad_event = AUE_PF_POLICY_DELRULE; 2064799bd290Spwernau break; 2065799bd290Spwernau } 2066799bd290Spwernau 2067799bd290Spwernau case SPD_FLUSH: { 2068799bd290Spwernau tad->tad_event = AUE_PF_POLICY_FLUSH; 2069799bd290Spwernau break; 2070799bd290Spwernau } 2071799bd290Spwernau 2072799bd290Spwernau case SPD_UPDATEALGS: { 2073799bd290Spwernau tad->tad_event = AUE_PF_POLICY_ALGS; 2074799bd290Spwernau break; 2075799bd290Spwernau } 2076799bd290Spwernau 2077799bd290Spwernau case SPD_CLONE: { 2078799bd290Spwernau tad->tad_event = AUE_PF_POLICY_CLONE; 2079799bd290Spwernau break; 2080799bd290Spwernau } 2081799bd290Spwernau 2082799bd290Spwernau case SPD_FLIP: { 2083799bd290Spwernau tad->tad_event = AUE_PF_POLICY_FLIP; 2084799bd290Spwernau break; 2085799bd290Spwernau } 2086799bd290Spwernau 2087799bd290Spwernau default: 2088799bd290Spwernau tad->tad_event = AUE_NULL; 2089799bd290Spwernau } 2090799bd290Spwernau 2091799bd290Spwernau tad->tad_evmod = 0; 2092799bd290Spwernau 2093799bd290Spwernau if (flag = audit_success(kctx, tad, error, cred)) { 2094799bd290Spwernau zone_t *nszone; 2095799bd290Spwernau 2096799bd290Spwernau /* 2097799bd290Spwernau * For now, just audit that an event happened, 2098799bd290Spwernau * along with the error code. 2099799bd290Spwernau */ 2100799bd290Spwernau au_write((caddr_t *)&ad, 2101799bd290Spwernau au_to_arg32(1, "Policy Active?", (uint32_t)active)); 2102799bd290Spwernau au_write((caddr_t *)&ad, 2103799bd290Spwernau au_to_arg32(2, "Policy Global?", (uint32_t)(tun == NULL))); 2104799bd290Spwernau 2105799bd290Spwernau /* Supplemental data */ 2106799bd290Spwernau 2107799bd290Spwernau /* 2108799bd290Spwernau * Generate this zone token if the target zone differs 2109799bd290Spwernau * from the administrative zone. If netstacks are expanded 2110799bd290Spwernau * to something other than a 1-1 relationship with zones, 2111799bd290Spwernau * the auditing framework should create a new token type 2112799bd290Spwernau * and audit it as a netstack instead. 2113799bd290Spwernau * Turn on general zone auditing to get the administrative zone. 2114799bd290Spwernau */ 2115799bd290Spwernau 2116799bd290Spwernau nszone = zone_find_by_id(netstackid_to_zoneid( 2117799bd290Spwernau ns->netstack_stackid)); 2118875a4abcSPaul Wernau if (nszone != NULL) { 211967dbe2beSCasper H.S. Dik if (strncmp(crgetzone(cred)->zone_name, 212067dbe2beSCasper H.S. Dik nszone->zone_name, ZONENAME_MAX) != 0) { 2121799bd290Spwernau token_t *ztoken; 2122799bd290Spwernau 2123799bd290Spwernau ztoken = au_to_zonename(0, nszone); 2124799bd290Spwernau au_write((caddr_t *)&ad, ztoken); 2125799bd290Spwernau } 2126875a4abcSPaul Wernau zone_rele(nszone); 2127875a4abcSPaul Wernau } 2128799bd290Spwernau 2129799bd290Spwernau if (tun != NULL) { 2130799bd290Spwernau /* write tunnel name - tun is bounded */ 2131799bd290Spwernau (void) snprintf(buf, sizeof (buf), "tunnel_name:%s", 2132799bd290Spwernau tun); 2133799bd290Spwernau au_write((caddr_t *)&ad, au_to_text(buf)); 2134799bd290Spwernau } 2135799bd290Spwernau 2136799bd290Spwernau /* Add subject information */ 2137799bd290Spwernau AUDIT_SETSUBJ_GENERIC((caddr_t *)&ad, 2138799bd290Spwernau ((cred != NULL) ? cred : CRED()), ainfo, kctx, pid); 2139799bd290Spwernau 2140799bd290Spwernau /* add a return token */ 2141799bd290Spwernau add_return_token((caddr_t *)&ad, 0, error, 0); 2142799bd290Spwernau 2143799bd290Spwernau AS_INC(as_generated, 1, kctx); 2144799bd290Spwernau AS_INC(as_kernel, 1, kctx); 2145799bd290Spwernau 2146799bd290Spwernau } 2147005d3febSMarek Pospisil au_close(kctx, (caddr_t *)&ad, flag, tad->tad_event, tad->tad_evmod, 2148005d3febSMarek Pospisil NULL); 2149799bd290Spwernau 2150799bd290Spwernau /* 2151799bd290Spwernau * clear the ctrl flag so that we don't have spurious collection of 2152799bd290Spwernau * audit information. 2153799bd290Spwernau */ 2154799bd290Spwernau tad->tad_scid = 0; 2155799bd290Spwernau tad->tad_event = 0; 2156799bd290Spwernau tad->tad_evmod = 0; 2157799bd290Spwernau tad->tad_ctrl = 0; 2158799bd290Spwernau } 2159799bd290Spwernau 2160799bd290Spwernau /* 216145916cd2Sjpk * ROUTINE: AUDIT_SEC_ATTRIBUTES 216245916cd2Sjpk * PURPOSE: Add security attributes 216345916cd2Sjpk * CALLBY: AUDIT_ATTRIBUTES 216445916cd2Sjpk * AUDIT_CLOSEF 216545916cd2Sjpk * AUS_CLOSE 216645916cd2Sjpk * NOTE: 216745916cd2Sjpk * TODO: 216845916cd2Sjpk * QUESTION: 216945916cd2Sjpk */ 217045916cd2Sjpk 217145916cd2Sjpk void 217245916cd2Sjpk audit_sec_attributes(caddr_t *ad, struct vnode *vp) 217345916cd2Sjpk { 217445916cd2Sjpk /* Dump the SL */ 217545916cd2Sjpk if (is_system_labeled()) { 217645916cd2Sjpk ts_label_t *tsl; 217745916cd2Sjpk bslabel_t *bsl; 217845916cd2Sjpk 217945916cd2Sjpk tsl = getflabel(vp); 218045916cd2Sjpk if (tsl == NULL) 218145916cd2Sjpk return; /* nothing else to do */ 218245916cd2Sjpk 218345916cd2Sjpk bsl = label2bslabel(tsl); 218445916cd2Sjpk if (bsl == NULL) 218545916cd2Sjpk return; /* nothing else to do */ 218645916cd2Sjpk au_write(ad, au_to_label(bsl)); 218745916cd2Sjpk label_rele(tsl); 218845916cd2Sjpk } 218945916cd2Sjpk 219045916cd2Sjpk } /* AUDIT_SEC_ATTRIBUTES */ 2191