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
audit_savepath(struct pathname * pnp,struct vnode * vp,struct vnode * pvp,int flag,cred_t * cr)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
audit_pathbuild(struct pathname * pnp)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
audit_anchorpath(struct pathname * pnp,int flag)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
audit_symlink(struct pathname * pnp,struct pathname * sympath)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
object_is_public(struct vattr * attr)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
audit_attributes(struct vnode * vp)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
audit_exit(int code,int what)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
audit_core_start(int sig)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
audit_core_finish(int code)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
audit_strgetmsg(struct vnode * vp,struct strbuf * mctl,struct strbuf * mdata,unsigned char * pri,int * flag,int fmode)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
audit_strputmsg(struct vnode * vp,struct strbuf * mctl,struct strbuf * mdata,unsigned char pri,int flag,int fmode)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
audit_closef(struct file * fp)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
audit_setf(file_t * fp,int fd)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
audit_ipc(int type,int id,void * vp)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
audit_ipcget(int type,void * vp)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
audit_reboot(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
audit_setfsat_path(int argnum)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
audit_symlink_create(vnode_t * dvp,char * sname,char * target,int error)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
audit_vncreate_start()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
audit_vncreate_finish(struct vnode * vp,int error)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
audit_exec(const char * argstr,const char * envstr,ssize_t argc,ssize_t envc,cred_t * pfcred)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
audit_enterprom(int flg)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
audit_exitprom(int flg)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
audit_chdirec(vnode_t * vp,vnode_t ** vpp)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
audit_sock(int type,queue_t * q,mblk_t * mp,int from)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
add_return_token(caddr_t * ad,unsigned int scid,int err,int rval)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
audit_fdsend(fd,fp,error)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
audit_priv(int priv,const priv_set_t * set,int flag)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
audit_setppriv(int op,int set,const priv_set_t * newpriv,const cred_t * ocr)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
audit_devpolicy(int nitems,const devplcysys_t * items)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
audit_fdrecv(fd,fp)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
audit_cryptoadm(int cmd,char * module_name,crypto_mech_name_t * mech_names,uint_t mech_count,uint_t device_instance,uint32_t rv,int error)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
audit_kssl(int cmd,void * params,int error)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
audit_pf_policy(int cmd,cred_t * cred,netstack_t * ns,char * tun,boolean_t active,int error,pid_t pid)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
audit_sec_attributes(caddr_t * ad,struct vnode * vp)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