1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22/*
23 * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright (c) 2011 Bayard G. Bell. All rights reserved.
25 * Copyright (c) 2018, Joyent, Inc.
26 */
27
28/*
29 * This file contains the audit event table used to control the production
30 * of audit records for each system call.
31 */
32
33#include <sys/policy.h>
34#include <sys/cred.h>
35#include <sys/types.h>
36#include <sys/systm.h>
37#include <sys/systeminfo.h>	/* for sysinfo auditing */
38#include <sys/utsname.h>	/* for sysinfo auditing */
39#include <sys/proc.h>
40#include <sys/vnode.h>
41#include <sys/mman.h>		/* for mmap(2) auditing etc. */
42#include <sys/fcntl.h>
43#include <sys/modctl.h>		/* for modctl auditing */
44#include <sys/vnode.h>
45#include <sys/user.h>
46#include <sys/types.h>
47#include <sys/processor.h>
48#include <sys/procset.h>
49#include <sys/acl.h>
50#include <sys/ipc.h>
51#include <sys/door.h>
52#include <sys/sem.h>
53#include <sys/msg.h>
54#include <sys/shm.h>
55#include <sys/kmem.h>
56#include <sys/file.h>		/* for accept */
57#include <sys/utssys.h>		/* for fuser */
58#include <sys/tsol/label.h>
59#include <sys/tsol/tndb.h>
60#include <sys/tsol/tsyscall.h>
61#include <c2/audit.h>
62#include <c2/audit_kernel.h>
63#include <c2/audit_kevents.h>
64#include <c2/audit_record.h>
65#include <sys/procset.h>
66#include <nfs/mount.h>
67#include <sys/param.h>
68#include <sys/debug.h>
69#include <sys/sysmacros.h>
70#include <sys/stream.h>
71#include <sys/strsubr.h>
72#include <sys/stropts.h>
73#include <sys/tihdr.h>
74#include <sys/socket.h>
75#include <sys/socketvar.h>
76#include <sys/vfs_opreg.h>
77#include <fs/sockfs/sockcommon.h>
78#include <netinet/in.h>
79#include <sys/ddi.h>
80#include <sys/port_impl.h>
81#include <sys/secflags.h>
82
83static au_event_t	aui_fchownat(au_event_t);
84static au_event_t	aui_fchmodat(au_event_t);
85static au_event_t	aui_open(au_event_t);
86static au_event_t	aui_openat(au_event_t);
87static au_event_t	aui_unlinkat(au_event_t);
88static au_event_t	aui_fstatat(au_event_t);
89static au_event_t	aui_msgsys(au_event_t);
90static au_event_t	aui_shmsys(au_event_t);
91static au_event_t	aui_semsys(au_event_t);
92static au_event_t	aui_utssys(au_event_t);
93static au_event_t	aui_fcntl(au_event_t);
94static au_event_t	aui_execve(au_event_t);
95static au_event_t	aui_memcntl(au_event_t);
96static au_event_t	aui_sysinfo(au_event_t);
97static au_event_t	aui_portfs(au_event_t);
98static au_event_t	aui_auditsys(au_event_t);
99static au_event_t	aui_modctl(au_event_t);
100static au_event_t	aui_acl(au_event_t);
101static au_event_t	aui_doorfs(au_event_t);
102static au_event_t	aui_privsys(au_event_t);
103static au_event_t	aui_forksys(au_event_t);
104static au_event_t	aui_labelsys(au_event_t);
105static au_event_t	aui_setpgrp(au_event_t);
106
107
108static void	aus_exit(struct t_audit_data *);
109static void	aus_open(struct t_audit_data *);
110static void	aus_openat(struct t_audit_data *);
111static void	aus_acl(struct t_audit_data *);
112static void	aus_acct(struct t_audit_data *);
113static void	aus_chown(struct t_audit_data *);
114static void	aus_fchown(struct t_audit_data *);
115static void	aus_lchown(struct t_audit_data *);
116static void	aus_fchownat(struct t_audit_data *);
117static void	aus_chmod(struct t_audit_data *);
118static void	aus_facl(struct t_audit_data *);
119static void	aus_fchmod(struct t_audit_data *);
120static void	aus_fchmodat(struct t_audit_data *);
121static void	aus_fcntl(struct t_audit_data *);
122static void	aus_mkdir(struct t_audit_data *);
123static void	aus_mkdirat(struct t_audit_data *);
124static void	aus_mknod(struct t_audit_data *);
125static void	aus_mknodat(struct t_audit_data *);
126static void	aus_mount(struct t_audit_data *);
127static void	aus_umount2(struct t_audit_data *);
128static void	aus_msgsys(struct t_audit_data *);
129static void	aus_semsys(struct t_audit_data *);
130static void	aus_close(struct t_audit_data *);
131static void	aus_fstatfs(struct t_audit_data *);
132static void	aus_setgid(struct t_audit_data *);
133static void	aus_setpgrp(struct t_audit_data *);
134static void	aus_setuid(struct t_audit_data *);
135static void	aus_shmsys(struct t_audit_data *);
136static void	aus_doorfs(struct t_audit_data *);
137static void	aus_ioctl(struct t_audit_data *);
138static void	aus_memcntl(struct t_audit_data *);
139static void	aus_mmap(struct t_audit_data *);
140static void	aus_munmap(struct t_audit_data *);
141static void	aus_priocntlsys(struct t_audit_data *);
142static void	aus_setegid(struct t_audit_data *);
143static void	aus_setgroups(struct t_audit_data *);
144static void	aus_seteuid(struct t_audit_data *);
145static void	aus_putmsg(struct t_audit_data *);
146static void	aus_putpmsg(struct t_audit_data *);
147static void	aus_getmsg(struct t_audit_data *);
148static void	aus_getpmsg(struct t_audit_data *);
149static void	aus_auditsys(struct t_audit_data *);
150static void	aus_sysinfo(struct t_audit_data *);
151static void	aus_modctl(struct t_audit_data *);
152static void	aus_kill(struct t_audit_data *);
153static void	aus_setregid(struct t_audit_data *);
154static void	aus_setreuid(struct t_audit_data *);
155static void	aus_labelsys(struct t_audit_data *);
156
157static void	auf_mknod(struct t_audit_data *, int, rval_t *);
158static void	auf_mknodat(struct t_audit_data *, int, rval_t *);
159static void	auf_msgsys(struct t_audit_data *, int, rval_t *);
160static void	auf_semsys(struct t_audit_data *, int, rval_t *);
161static void	auf_shmsys(struct t_audit_data *, int, rval_t *);
162static void	auf_read(struct t_audit_data *, int, rval_t *);
163static void	auf_write(struct t_audit_data *, int, rval_t *);
164
165static void	aus_sigqueue(struct t_audit_data *);
166static void	aus_p_online(struct t_audit_data *);
167static void	aus_processor_bind(struct t_audit_data *);
168static void	aus_inst_sync(struct t_audit_data *);
169static void	aus_brandsys(struct t_audit_data *);
170
171static void	auf_accept(struct t_audit_data *, int, rval_t *);
172
173static void	auf_bind(struct t_audit_data *, int, rval_t *);
174static void	auf_connect(struct t_audit_data *, int, rval_t *);
175static void	aus_shutdown(struct t_audit_data *);
176static void	auf_setsockopt(struct t_audit_data *, int, rval_t *);
177static void	aus_sockconfig(struct t_audit_data *);
178static void	auf_recv(struct t_audit_data *, int, rval_t *);
179static void	auf_recvmsg(struct t_audit_data *, int, rval_t *);
180static void	auf_send(struct t_audit_data *, int, rval_t *);
181static void	auf_sendmsg(struct t_audit_data *, int, rval_t *);
182static void	auf_recvfrom(struct t_audit_data *, int, rval_t *);
183static void	auf_sendto(struct t_audit_data *, int, rval_t *);
184static void	aus_socket(struct t_audit_data *);
185/*
186 * This table contains mapping information for converting system call numbers
187 * to audit event IDs. In several cases it is necessary to map a single system
188 * call to several events.
189 */
190
191#define	aui_null	NULL	/* NULL initialize function */
192#define	aus_null	NULL	/* NULL start function */
193#define	auf_null	NULL	/* NULL finish function */
194
195struct audit_s2e audit_s2e[] =
196{
197/*
198 * ----------	----------	----------	----------
199 * INITIAL	AUDIT		START		SYSTEM
200 * PROCESSING	EVENT		PROCESSING	CALL
201 * ----------	----------	----------	-----------
202 *		FINISH		EVENT
203 *		PROCESSING	CONTROL
204 * ----------------------------------------------------------
205 */
206aui_null,	AUE_NULL,	aus_null,	/* 0 unused (indirect) */
207		auf_null,	0,
208aui_null,	AUE_EXIT,	aus_exit,	/* 1 exit */
209		auf_null,	S2E_NPT,
210aui_null,	AUE_PSECFLAGS,	aus_null,	/* 2 psecflags */
211		auf_null,	0,
212aui_null,	AUE_READ,	aus_null,	/* 3 read */
213		auf_read,	S2E_PUB,
214aui_null,	AUE_WRITE,	aus_null,	/* 4 write */
215		auf_write,	0,
216aui_open,	AUE_OPEN,	aus_open,	/* 5 open */
217		auf_null,	S2E_SP,
218aui_null,	AUE_CLOSE,	aus_close,	/* 6 close */
219		auf_null,	0,
220aui_null,	AUE_LINK,	aus_null,	/* 7 linkat */
221		auf_null,	0,
222aui_null,	AUE_NULL,	aus_null,	/* 8 (loadable) was creat */
223		auf_null,	0,
224aui_null,	AUE_LINK,	aus_null,	/* 9 link */
225		auf_null,	0,
226aui_null,	AUE_UNLINK,	aus_null,	/* 10 unlink */
227		auf_null,	0,
228aui_null,	AUE_SYMLINK,	aus_null,	/* 11 symlinkat */
229		auf_null,	0,
230aui_null,	AUE_CHDIR,	aus_null,	/* 12 chdir */
231		auf_null,	S2E_SP,
232aui_null,	AUE_NULL,	aus_null,	/* 13 time */
233		auf_null,	0,
234aui_null,	AUE_MKNOD,	aus_mknod,	/* 14 mknod */
235		auf_mknod,	S2E_MLD,
236aui_null,	AUE_CHMOD,	aus_chmod,	/* 15 chmod */
237		auf_null,	0,
238aui_null,	AUE_CHOWN,	aus_chown,	/* 16 chown */
239		auf_null,	0,
240aui_null,	AUE_NULL,	aus_null,	/* 17 brk */
241		auf_null,	0,
242aui_null,	AUE_STAT,	aus_null,	/* 18 stat */
243		auf_null,	S2E_PUB,
244aui_null,	AUE_NULL,	aus_null,	/* 19 lseek */
245		auf_null,	0,
246aui_null,	AUE_NULL,	aus_null,	/* 20 getpid */
247		auf_null,	0,
248aui_null,	AUE_MOUNT,	aus_mount,	/* 21 mount */
249		auf_null,	S2E_MLD,
250aui_null,	AUE_READLINK,	aus_null,	/* 22 readlinkat */
251		auf_null,	S2E_PUB,
252aui_null,	AUE_SETUID,	aus_setuid,	/* 23 setuid */
253		auf_null,	0,
254aui_null,	AUE_NULL,	aus_null,	/* 24 getuid */
255		auf_null,	0,
256aui_null,	AUE_STIME,	aus_null,	/* 25 stime */
257		auf_null,	0,
258aui_null,	AUE_NULL,	aus_null,	/* 26 pcsample */
259		auf_null,	0,
260aui_null,	AUE_NULL,	aus_null,	/* 27 alarm */
261		auf_null,	0,
262aui_null,	AUE_NULL,	aus_null,	/* 28 fstat */
263		auf_null,	0,
264aui_null,	AUE_NULL,	aus_null,	/* 29 pause */
265		auf_null,	0,
266aui_null,	AUE_NULL,	aus_null,	/* 30 (loadable) was utime */
267		auf_null,	0,
268aui_null,	AUE_NULL,	aus_null,	/* 31 stty (TIOCSETP-audit?) */
269		auf_null,	0,
270aui_null,	AUE_NULL,	aus_null,	/* 32 gtty */
271		auf_null,	0,
272aui_null,	AUE_ACCESS,	aus_null,	/* 33 access */
273		auf_null,	S2E_PUB,
274aui_null,	AUE_NICE,	aus_null,	/* 34 nice */
275		auf_null,	0,
276aui_null,	AUE_STATFS,	aus_null,	/* 35 statfs */
277		auf_null,	S2E_PUB,
278aui_null,	AUE_NULL,	aus_null,	/* 36 sync */
279		auf_null,	0,
280aui_null,	AUE_KILL,	aus_kill,	/* 37 kill */
281		auf_null,	0,
282aui_null,	AUE_FSTATFS,	aus_fstatfs,	/* 38 fstatfs */
283		auf_null,	S2E_PUB,
284aui_setpgrp,	AUE_SETPGRP,	aus_setpgrp,	/* 39 setpgrp */
285		auf_null,	0,
286aui_null,	AUE_NULL,	aus_null,	/* 40 uucopystr */
287		auf_null,	0,
288aui_null,	AUE_NULL,	aus_null,	/* 41 (loadable) was dup */
289		auf_null,	0,
290aui_null,	AUE_PIPE,	aus_null,	/* 42 (loadable) pipe */
291		auf_null,	0,
292aui_null,	AUE_NULL,	aus_null,	/* 43 times */
293		auf_null,	0,
294aui_null,	AUE_NULL,	aus_null,	/* 44 profil */
295		auf_null,	0,
296aui_null,	AUE_ACCESS,	aus_null,	/* 45 faccessat */
297		auf_null,	S2E_PUB,
298aui_null,	AUE_SETGID,	aus_setgid,	/* 46 setgid */
299		auf_null,	0,
300aui_null,	AUE_NULL,	aus_null,	/* 47 getgid */
301		auf_null,	0,
302aui_null,	AUE_MKNOD,	aus_mknodat,	/* 48 mknodat */
303		auf_mknodat,	S2E_MLD,
304aui_msgsys,	AUE_MSGSYS,	aus_msgsys,	/* 49 (loadable) msgsys */
305		auf_msgsys,	0,
306#if defined(__x86)
307aui_null,	AUE_NULL,	aus_null,	/* 50 sysi86 */
308		auf_null,	0,
309#else
310aui_null,	AUE_NULL,	aus_null,	/* 50 (loadable) was sys3b */
311		auf_null,	0,
312#endif /* __x86 */
313aui_null,	AUE_ACCT,	aus_acct,	/* 51 (loadable) sysacct */
314		auf_null,	0,
315aui_shmsys,	AUE_SHMSYS,	aus_shmsys,	/* 52 (loadable) shmsys */
316		auf_shmsys,	0,
317aui_semsys,	AUE_SEMSYS,	aus_semsys,	/* 53 (loadable) semsys */
318		auf_semsys,	0,
319aui_null,	AUE_IOCTL,	aus_ioctl,	/* 54 ioctl */
320		auf_null,	0,
321aui_null,	AUE_NULL,	aus_null,	/* 55 uadmin */
322		auf_null,	0,
323aui_fchownat,	AUE_NULL,	aus_fchownat,	/* 56 fchownat */
324		auf_null,	0,
325aui_utssys,	AUE_FUSERS,	aus_null,	/* 57 utssys */
326		auf_null,	0,
327aui_null,	AUE_NULL,	aus_null,	/* 58 fsync */
328		auf_null,	0,
329aui_execve,	AUE_EXECVE,	aus_null,	/* 59 exece */
330		auf_null,	S2E_MLD,
331aui_null,	AUE_NULL,	aus_null,	/* 60 umask */
332		auf_null,	0,
333aui_null,	AUE_CHROOT,	aus_null,	/* 61 chroot */
334		auf_null,	S2E_SP,
335aui_fcntl,	AUE_FCNTL,	aus_fcntl,	/* 62 fcntl */
336		auf_null,	0,
337aui_null,	AUE_NULL,	aus_null,	/* 63 ulimit */
338		auf_null,	0,
339aui_null,	AUE_RENAME,	aus_null,	/* 64 renameat */
340		auf_null,	0,
341aui_unlinkat,	AUE_NULL,	aus_null,	/* 65 unlinkat */
342		auf_null,	0,
343aui_fstatat,	AUE_NULL,	aus_null,	/* 66 fstatat */
344		auf_null,	S2E_PUB,
345aui_fstatat,	AUE_NULL,	aus_null,	/* 67 fstatat64 */
346		auf_null,	S2E_PUB,
347aui_openat,	AUE_OPEN,	aus_openat,	/* 68 openat */
348		auf_null,	S2E_SP,
349aui_openat,	AUE_OPEN,	aus_openat,	/* 69 openat64 */
350		auf_null,	S2E_SP,
351aui_null,	AUE_NULL,	aus_null,	/* 70 tasksys */
352		auf_null,	0,
353aui_null,	AUE_NULL,	aus_null,	/* 71 (loadable) acctctl */
354		auf_null,	0,
355aui_null,	AUE_NULL,	aus_null,	/* 72 (loadable) exacct */
356		auf_null,	0,
357aui_null,	AUE_NULL,	aus_null,	/* 73 getpagesizes */
358		auf_null,	0,
359aui_null,	AUE_NULL,	aus_null,	/* 74 rctlsys */
360		auf_null,	0,
361aui_null,	AUE_NULL,	aus_null,	/* 75 sidsys */
362		auf_null,	0,
363aui_null,	AUE_NULL,	aus_null,	/* 76 (loadable) was fsat */
364		auf_null,	0,
365aui_null,	AUE_NULL,	aus_null,	/* 77 syslwp_park */
366		auf_null,	0,
367aui_null,	AUE_NULL,	aus_null,	/* 78 sendfilev */
368		auf_null,	0,
369aui_null,	AUE_RMDIR,	aus_null,	/* 79 rmdir */
370		auf_null,	0,
371aui_null,	AUE_MKDIR,	aus_mkdir,	/* 80 mkdir */
372		auf_null,	0,
373aui_null,	AUE_NULL,	aus_null,	/* 81 getdents */
374		auf_null,	0,
375aui_privsys,	AUE_NULL,	aus_null,	/* 82 privsys */
376		auf_null,	0,
377aui_null,	AUE_NULL,	aus_null,	/* 83 ucredsys */
378		auf_null,	0,
379aui_null,	AUE_NULL,	aus_null,	/* 84 sysfs */
380		auf_null,	0,
381aui_null,	AUE_GETMSG,	aus_getmsg,	/* 85 getmsg */
382		auf_null,	0,
383aui_null,	AUE_PUTMSG,	aus_putmsg,	/* 86 putmsg */
384		auf_null,	0,
385aui_null,	AUE_NULL,	aus_null,	/* 87 (loadable) was poll */
386		auf_null,	0,
387aui_null,	AUE_LSTAT,	aus_null,	/* 88 lstat */
388		auf_null,	S2E_PUB,
389aui_null,	AUE_SYMLINK,	aus_null,	/* 89 symlink */
390		auf_null,	0,
391aui_null,	AUE_READLINK,	aus_null,	/* 90 readlink */
392		auf_null,	S2E_PUB,
393aui_null,	AUE_SETGROUPS,	aus_setgroups,	/* 91 setgroups */
394		auf_null,	0,
395aui_null,	AUE_NULL,	aus_null,	/* 92 getgroups */
396		auf_null,	0,
397aui_null,	AUE_FCHMOD,	aus_fchmod,	/* 93 fchmod */
398		auf_null,	0,
399aui_null,	AUE_FCHOWN,	aus_fchown,	/* 94 fchown */
400		auf_null,	0,
401aui_null,	AUE_NULL,	aus_null,	/* 95 sigprocmask */
402		auf_null,	0,
403aui_null,	AUE_NULL,	aus_null,	/* 96 sigsuspend */
404		auf_null,	0,
405aui_null,	AUE_NULL,	aus_null,	/* 97 sigaltstack */
406		auf_null,	0,
407aui_null,	AUE_NULL,	aus_null,	/* 98 sigaction */
408		auf_null,	0,
409aui_null,	AUE_NULL,	aus_null,	/* 99 sigpending */
410		auf_null,	0,
411aui_null,	AUE_NULL,	aus_null,	/* 100 setcontext */
412		auf_null,	0,
413aui_fchmodat,	AUE_NULL,	aus_fchmodat,	/* 101 fchmodat */
414		auf_null,	0,
415aui_null,	AUE_MKDIR,	aus_mkdirat,	/* 102 mkdirat */
416		auf_null,	0,
417aui_null,	AUE_STATVFS,	aus_null,	/* 103 statvfs */
418		auf_null,	S2E_PUB,
419aui_null,	AUE_NULL,	aus_null,	/* 104 fstatvfs */
420		auf_null,	0,
421aui_null,	AUE_NULL,	aus_null,	/* 105 getloadavg */
422		auf_null,	0,
423aui_null,	AUE_NULL,	aus_null,	/* 106 nfssys */
424		auf_null,	0,
425aui_null,	AUE_NULL,	aus_null,	/* 107 waitsys */
426		auf_null,	0,
427aui_null,	AUE_NULL,	aus_null,	/* 108 sigsendsys */
428		auf_null,	0,
429#if defined(__x86)
430aui_null,	AUE_NULL,	aus_null,	/* 109 hrtsys */
431		auf_null,	0,
432#else
433aui_null,	AUE_NULL,	aus_null,	/* 109 (loadable) */
434		auf_null,	0,
435#endif /* __x86 */
436aui_null,	AUE_UTIMES,	aus_null,	/* 110 utimesys */
437		auf_null,	0,
438aui_null,	AUE_NULL,	aus_null,	/* 111 sigresend */
439		auf_null,	0,
440aui_null,	AUE_PRIOCNTLSYS, aus_priocntlsys, /* 112 priocntlsys */
441		auf_null,	0,
442aui_null,	AUE_PATHCONF,	aus_null,	/* 113 pathconf */
443		auf_null,	S2E_PUB,
444aui_null,	AUE_NULL,	aus_null,	/* 114 mincore */
445		auf_null,	0,
446aui_null,	AUE_MMAP,	aus_mmap,	/* 115 mmap */
447		auf_null,	0,
448aui_null,	AUE_NULL,	aus_null,	/* 116 mprotect */
449		auf_null,	0,
450aui_null,	AUE_MUNMAP,	aus_munmap,	/* 117 munmap */
451		auf_null,	0,
452aui_null,	AUE_NULL,	aus_null,	/* 118 fpathconf */
453		auf_null,	0,
454aui_null,	AUE_VFORK,	aus_null,	/* 119 vfork */
455		auf_null,	0,
456aui_null,	AUE_FCHDIR,	aus_null,	/* 120 fchdir */
457		auf_null,	0,
458aui_null,	AUE_READ,	aus_null,	/* 121 readv */
459		auf_read,	S2E_PUB,
460aui_null,	AUE_WRITE,	aus_null,	/* 122 writev */
461		auf_write,	0,
462aui_null,	AUE_NULL,	aus_null,	/* 123 (loadable) was xstat */
463		auf_null,	0,
464aui_null,	AUE_NULL,	aus_null,	/* 124 (loadable) was lxstat */
465		auf_null,	0,
466aui_null,	AUE_NULL,	aus_null,	/* 125 (loadable) was fxstat */
467		auf_null,	0,
468aui_null,	AUE_NULL,	aus_null,	/* 126 (loadable) was xmknod */
469		auf_null,	0,
470aui_null,	AUE_NULL,	aus_null,	/* 127 mmapobj */
471		auf_null,	0,
472aui_null,	AUE_SETRLIMIT,	aus_null,	/* 128 setrlimit */
473		auf_null,	0,
474aui_null,	AUE_NULL,	aus_null,	/* 129 getrlimit */
475		auf_null,	0,
476aui_null,	AUE_LCHOWN,	aus_lchown,	/* 130 lchown */
477		auf_null,	0,
478aui_memcntl,	AUE_MEMCNTL,	aus_memcntl,	/* 131 memcntl */
479		auf_null,	0,
480aui_null,	AUE_GETPMSG,	aus_getpmsg,	/* 132 getpmsg */
481		auf_null,	0,
482aui_null,	AUE_PUTPMSG,	aus_putpmsg,	/* 133 putpmsg */
483		auf_null,	0,
484aui_null,	AUE_RENAME,	aus_null,	/* 134 rename */
485		auf_null,	0,
486aui_null,	AUE_NULL,	aus_null,	/* 135 uname */
487		auf_null,	0,
488aui_null,	AUE_SETEGID,	aus_setegid,	/* 136 setegid */
489		auf_null,	0,
490aui_null,	AUE_NULL,	aus_null,	/* 137 sysconfig */
491		auf_null,	0,
492aui_null,	AUE_ADJTIME,	aus_null,	/* 138 adjtime */
493		auf_null,	0,
494aui_sysinfo,	AUE_SYSINFO,	aus_sysinfo,	/* 139 systeminfo */
495		auf_null,	0,
496aui_null,	AUE_NULL,	aus_null,	/* 140 (loadable) sharefs */
497		auf_null,	0,
498aui_null,	AUE_SETEUID,	aus_seteuid,	/* 141 seteuid */
499		auf_null,	0,
500aui_forksys,	AUE_NULL,	aus_null,	/* 142 forksys */
501		auf_null,	0,
502aui_null,	AUE_NULL,	aus_null,	/* 143 (loadable) was fork1 */
503		auf_null,	0,
504aui_null,	AUE_NULL,	aus_null,	/* 144 sigwait */
505		auf_null,	0,
506aui_null,	AUE_NULL,	aus_null,	/* 145 lwp_info */
507		auf_null,	0,
508aui_null,	AUE_NULL,	aus_null,	/* 146 yield */
509		auf_null,	0,
510aui_null,	AUE_NULL,	aus_null,	/* 147 (loadable) */
511						/*	was lwp_sema_wait */
512		auf_null,	0,
513aui_null,	AUE_NULL,	aus_null,	/* 148 lwp_sema_post */
514		auf_null,	0,
515aui_null,	AUE_NULL,	aus_null,	/* 149 lwp_sema_trywait */
516		auf_null,	0,
517aui_null,	AUE_NULL,	aus_null,	/* 150 lwp_detach */
518		auf_null,	0,
519aui_null,	AUE_NULL,	aus_null,	/* 151 corectl */
520		auf_null,	0,
521aui_modctl,	AUE_MODCTL,	aus_modctl,	/* 152 modctl */
522		auf_null,	0,
523aui_null,	AUE_FCHROOT,	aus_null,	/* 153 fchroot */
524		auf_null,	0,
525aui_null,	AUE_NULL,	aus_null,	/* 154 (loadable) was utimes */
526		auf_null,	0,
527aui_null,	AUE_NULL,	aus_null,	/* 155 vhangup */
528		auf_null,	0,
529aui_null,	AUE_NULL,	aus_null,	/* 156 gettimeofday */
530		auf_null,	0,
531aui_null,	AUE_NULL,	aus_null,	/* 157 getitimer */
532		auf_null,	0,
533aui_null,	AUE_NULL,	aus_null,	/* 158 setitimer */
534		auf_null,	0,
535aui_null,	AUE_NULL,	aus_null,	/* 159 lwp_create */
536		auf_null,	0,
537aui_null,	AUE_NULL,	aus_null,	/* 160 lwp_exit */
538		auf_null,	0,
539aui_null,	AUE_NULL,	aus_null,	/* 161 lwp_suspend */
540		auf_null,	0,
541aui_null,	AUE_NULL,	aus_null,	/* 162 lwp_continue */
542		auf_null,	0,
543aui_null,	AUE_NULL,	aus_null,	/* 163 lwp_kill */
544		auf_null,	0,
545aui_null,	AUE_NULL,	aus_null,	/* 164 lwp_self */
546		auf_null,	0,
547aui_null,	AUE_NULL,	aus_null,	/* 165 lwp_sigmask */
548		auf_null,	0,
549aui_null,	AUE_NULL,	aus_null,	/* 166 lwp_private */
550		auf_null,	0,
551aui_null,	AUE_NULL,	aus_null,	/* 167 lwp_wait */
552		auf_null,	0,
553aui_null,	AUE_NULL,	aus_null,	/* 168 lwp_mutex_wakeup  */
554		auf_null,	0,
555aui_null,	AUE_NULL,	aus_null,	/* 169 (loadable) */
556						/*	was lwp_mutex_lock */
557		auf_null,	0,
558aui_null,	AUE_NULL,	aus_null,	/* 170 lwp_cond_wait */
559		auf_null,	0,
560aui_null,	AUE_NULL,	aus_null,	/* 171 lwp_cond_signal */
561		auf_null,	0,
562aui_null,	AUE_NULL,	aus_null,	/* 172 lwp_cond_broadcast */
563		auf_null,	0,
564aui_null,	AUE_READ,	aus_null,	/* 173 pread */
565		auf_read,	S2E_PUB,
566aui_null,	AUE_WRITE,	aus_null,	/* 174 pwrite */
567		auf_write,	0,
568aui_null,	AUE_NULL,	aus_null,	/* 175 llseek */
569		auf_null,	0,
570aui_null,	AUE_INST_SYNC,	aus_inst_sync,  /* 176 (loadable) inst_sync */
571		auf_null,	0,
572aui_null,	AUE_BRANDSYS,	aus_brandsys,	/* 177 brandsys */
573		auf_null,	0,
574aui_null,	AUE_NULL,	aus_null,	/* 178 (loadable) kaio */
575		auf_null,	0,
576aui_null,	AUE_NULL,	aus_null,	/* 179 (loadable) cpc */
577		auf_null,	0,
578aui_null,	AUE_NULL,	aus_null,	/* 180 lgrpsys */
579		auf_null,	0,
580aui_null,	AUE_NULL,	aus_null,	/* 181 rusagesys */
581		auf_null,	0,
582aui_portfs,	AUE_PORTFS,	aus_null,	/* 182 (loadable) portfs */
583		auf_null,	S2E_MLD,
584aui_null,	AUE_NULL,	aus_null,	/* 183 pollsys */
585		auf_null,	0,
586aui_labelsys,	AUE_NULL,	aus_labelsys,	/* 184 labelsys */
587		auf_null,	0,
588aui_acl,	AUE_ACLSET,	aus_acl,	/* 185 acl */
589		auf_null,	0,
590aui_auditsys,	AUE_AUDITSYS,	aus_auditsys,	/* 186 auditsys  */
591		auf_null,	0,
592aui_null,	AUE_PROCESSOR_BIND, aus_processor_bind, /* 187 processor_bind */
593		auf_null,	0,
594aui_null,	AUE_NULL,	aus_null,	/* 188 processor_info */
595		auf_null,	0,
596aui_null,	AUE_P_ONLINE,	aus_p_online,	/* 189 p_online */
597		auf_null,	0,
598aui_null,	AUE_NULL,	aus_sigqueue,	/* 190 sigqueue */
599		auf_null,	0,
600aui_null,	AUE_NULL,	aus_null,	/* 191 clock_gettime */
601		auf_null,	0,
602aui_null,	AUE_CLOCK_SETTIME,	aus_null,	/* 192 clock_settime */
603		auf_null,	0,
604aui_null,	AUE_NULL,	aus_null,	/* 193 clock_getres */
605		auf_null,	0,
606aui_null,	AUE_NULL,	aus_null,	/* 194 timer_create */
607		auf_null,	0,
608aui_null,	AUE_NULL,	aus_null,	/* 195 timer_delete */
609		auf_null,	0,
610aui_null,	AUE_NULL,	aus_null,	/* 196 timer_settime */
611		auf_null,	0,
612aui_null,	AUE_NULL,	aus_null,	/* 197 timer_gettime */
613		auf_null,	0,
614aui_null,	AUE_NULL,	aus_null,	/* 198 timer_getoverrun */
615		auf_null,	0,
616aui_null,	AUE_NULL,	aus_null,	/* 199 nanosleep */
617		auf_null,	0,
618aui_acl,	AUE_FACLSET,	aus_facl,	/* 200 facl */
619		auf_null,	0,
620aui_doorfs,	AUE_DOORFS,	aus_doorfs,	/* 201 (loadable) doorfs */
621		auf_null,	0,
622aui_null,	AUE_SETREUID,	aus_setreuid,	/* 202 setreuid */
623		auf_null,	0,
624aui_null,	AUE_SETREGID,	aus_setregid,	/* 203 setregid */
625		auf_null,	0,
626aui_null,	AUE_NULL,	aus_null,	/* 204 install_utrap */
627		auf_null,	0,
628aui_null,	AUE_NULL,	aus_null,	/* 205 signotify */
629		auf_null,	0,
630aui_null,	AUE_NULL,	aus_null,	/* 206 schedctl */
631		auf_null,	0,
632aui_null,	AUE_NULL,	aus_null,	/* 207 (loadable) pset */
633		auf_null,	0,
634aui_null,	AUE_NULL,	aus_null,	/* 208 sparc_utrap_install */
635		auf_null,	0,
636aui_null,	AUE_NULL,	aus_null,	/* 209 resolvepath */
637		auf_null,	0,
638aui_null,	AUE_NULL,	aus_null,	/* 210 lwp_mutex_timedlock */
639		auf_null,	0,
640aui_null,	AUE_NULL,	aus_null,	/* 211 lwp_sema_timedwait */
641		auf_null,	0,
642aui_null,	AUE_NULL,	aus_null,	/* 212 lwp_rwlock_sys */
643		auf_null,	0,
644aui_null,	AUE_NULL,	aus_null,	/* 213 getdents64 */
645		auf_null,	0,
646aui_null,	AUE_MMAP,	aus_mmap,	/* 214 mmap64 */
647		auf_null,	0,
648aui_null,	AUE_STAT,	aus_null,	/* 215 stat64 */
649		auf_null,	S2E_PUB,
650aui_null,	AUE_LSTAT,	aus_null,	/* 216 lstat64 */
651		auf_null,	S2E_PUB,
652aui_null,	AUE_NULL,	aus_null,	/* 217 fstat64 */
653		auf_null,	0,
654aui_null,	AUE_STATVFS,	aus_null,	/* 218 statvfs64 */
655		auf_null,	S2E_PUB,
656aui_null,	AUE_NULL,	aus_null,	/* 219 fstatvfs64 */
657		auf_null,	0,
658aui_null,	AUE_SETRLIMIT,	aus_null,	/* 220 setrlimit64 */
659		auf_null,	0,
660aui_null,	AUE_NULL,	aus_null,	/* 221 getrlimit64 */
661		auf_null,	0,
662aui_null,	AUE_READ,	aus_null,	/* 222 pread64  */
663		auf_read,	S2E_PUB,
664aui_null,	AUE_WRITE,	aus_null,	/* 223 pwrite64 */
665		auf_write,	0,
666aui_null,	AUE_NULL,	aus_null,	/* 224 (loadable) was creat64 */
667		auf_null,	0,
668aui_open,	AUE_OPEN,	aus_open,	/* 225 open64 */
669		auf_null,	S2E_SP,
670aui_null,	AUE_NULL,	aus_null,	/* 226 (loadable) rpcsys */
671		auf_null,	0,
672aui_null,	AUE_NULL,	aus_null,	/* 227 zone */
673		auf_null,	0,
674aui_null,	AUE_NULL,	aus_null,	/* 228 (loadable) autofssys */
675		auf_null,	0,
676aui_null,	AUE_NULL,	aus_null,	/* 229 getcwd */
677		auf_null,	0,
678aui_null,	AUE_SOCKET,	aus_socket,	/* 230 so_socket */
679		auf_null,	0,
680aui_null,	AUE_NULL,	aus_null,	/* 231 so_socketpair */
681		auf_null,	0,
682aui_null,	AUE_BIND,	aus_null,	/* 232 bind */
683		auf_bind,	0,
684aui_null,	AUE_NULL,	aus_null,	/* 233 listen */
685		auf_null,	0,
686aui_null,	AUE_ACCEPT,	aus_null,	/* 234 accept */
687		auf_accept,	0,
688aui_null,	AUE_CONNECT,	aus_null,	/* 235 connect */
689		auf_connect,	0,
690aui_null,	AUE_SHUTDOWN,	aus_shutdown,	/* 236 shutdown */
691		auf_null,	0,
692aui_null,	AUE_READ,	aus_null,	/* 237 recv */
693		auf_recv,	0,
694aui_null,	AUE_RECVFROM,	aus_null,	/* 238 recvfrom */
695		auf_recvfrom,	0,
696aui_null,	AUE_RECVMSG,	aus_null,	/* 239 recvmsg */
697		auf_recvmsg,	0,
698aui_null,	AUE_WRITE,	aus_null,	/* 240 send */
699		auf_send,	0,
700aui_null,	AUE_SENDMSG,	aus_null,	/* 241 sendmsg */
701		auf_sendmsg,	0,
702aui_null,	AUE_SENDTO,	aus_null,	/* 242 sendto */
703		auf_sendto,	0,
704aui_null,	AUE_NULL,	aus_null,	/* 243 getpeername */
705		auf_null,	0,
706aui_null,	AUE_NULL,	aus_null,	/* 244 getsockname */
707		auf_null,	0,
708aui_null,	AUE_NULL,	aus_null,	/* 245 getsockopt */
709		auf_null,	0,
710aui_null,	AUE_SETSOCKOPT,	aus_null,	/* 246 setsockopt */
711		auf_setsockopt,	0,
712aui_null,	AUE_SOCKCONFIG,	aus_sockconfig,	/* 247 sockconfig */
713		auf_null,	0,
714aui_null,	AUE_NULL,	aus_null,	/* 248 ntp_gettime */
715		auf_null,	0,
716aui_null,	AUE_NTP_ADJTIME, aus_null,	/* 249 ntp_adjtime */
717		auf_null,	0,
718aui_null,	AUE_NULL,	aus_null,	/* 250 lwp_mutex_unlock */
719		auf_null,	0,
720aui_null,	AUE_NULL,	aus_null,	/* 251 lwp_mutex_trylock */
721		auf_null,	0,
722aui_null,	AUE_NULL,	aus_null,	/* 252 lwp_mutex_register */
723		auf_null,	0,
724aui_null,	AUE_NULL,	aus_null,	/* 253 cladm */
725		auf_null,	0,
726aui_null,	AUE_NULL,	aus_null,	/* 254 uucopy */
727		auf_null,	0,
728aui_null,	AUE_UMOUNT2,	aus_umount2,	/* 255 umount2 */
729		auf_null,	0
730};
731
732uint_t num_syscall = sizeof (audit_s2e) / sizeof (struct audit_s2e);
733
734
735/* exit start function */
736/*ARGSUSED*/
737static void
738aus_exit(struct t_audit_data *tad)
739{
740	uint32_t rval;
741	struct a {
742		long rval;
743	} *uap = (struct a *)ttolwp(curthread)->lwp_ap;
744
745	rval = (uint32_t)uap->rval;
746	au_uwrite(au_to_arg32(1, "exit status", rval));
747}
748
749
750/* acct start function */
751/*ARGSUSED*/
752static void
753aus_acct(struct t_audit_data *tad)
754{
755	klwp_t *clwp = ttolwp(curthread);
756	uintptr_t fname;
757
758	struct a {
759		long	fname;		/* char * */
760	} *uap = (struct a *)clwp->lwp_ap;
761
762	fname = (uintptr_t)uap->fname;
763
764	if (fname == 0)
765		au_uwrite(au_to_arg32(1, "accounting off", (uint32_t)0));
766}
767
768/* chown start function */
769/*ARGSUSED*/
770static void
771aus_chown(struct t_audit_data *tad)
772{
773	klwp_t *clwp = ttolwp(curthread);
774	uint32_t uid, gid;
775
776	struct a {
777		long	fname;		/* char * */
778		long	uid;
779		long	gid;
780	} *uap = (struct a *)clwp->lwp_ap;
781
782	uid = (uint32_t)uap->uid;
783	gid = (uint32_t)uap->gid;
784
785	au_uwrite(au_to_arg32(2, "new file uid", uid));
786	au_uwrite(au_to_arg32(3, "new file gid", gid));
787}
788
789/* fchown start function */
790/*ARGSUSED*/
791static void
792aus_fchown(struct t_audit_data *tad)
793{
794	klwp_t *clwp = ttolwp(curthread);
795	uint32_t uid, gid, fd;
796	struct file  *fp;
797	struct vnode *vp;
798	struct f_audit_data *fad;
799
800	struct a {
801		long fd;
802		long uid;
803		long gid;
804	} *uap = (struct a *)clwp->lwp_ap;
805
806	fd  = (uint32_t)uap->fd;
807	uid = (uint32_t)uap->uid;
808	gid = (uint32_t)uap->gid;
809
810	au_uwrite(au_to_arg32(2, "new file uid", uid));
811	au_uwrite(au_to_arg32(3, "new file gid", gid));
812
813		/*
814		 * convert file pointer to file descriptor
815		 *   Note: fd ref count incremented here.
816		 */
817	if ((fp = getf(fd)) == NULL)
818		return;
819
820	/* get path from file struct here */
821	fad = F2A(fp);
822	if (fad->fad_aupath != NULL) {
823		au_uwrite(au_to_path(fad->fad_aupath));
824	} else {
825		au_uwrite(au_to_arg32(1, "no path: fd", fd));
826	}
827
828	vp = fp->f_vnode;
829	audit_attributes(vp);
830
831	/* decrement file descriptor reference count */
832	releasef(fd);
833}
834
835/*ARGSUSED*/
836static void
837aus_lchown(struct t_audit_data *tad)
838{
839	klwp_t *clwp = ttolwp(curthread);
840	uint32_t uid, gid;
841
842
843	struct a {
844		long	fname;		/* char	* */
845		long	uid;
846		long	gid;
847	} *uap = (struct a *)clwp->lwp_ap;
848
849	uid = (uint32_t)uap->uid;
850	gid = (uint32_t)uap->gid;
851
852	au_uwrite(au_to_arg32(2, "new file uid", uid));
853	au_uwrite(au_to_arg32(3, "new file gid", gid));
854}
855
856static au_event_t
857aui_fchownat(au_event_t e)
858{
859	klwp_t *clwp = ttolwp(curthread);
860
861	struct a {
862		long	fd;
863		long	fname;		/* char * */
864		long	uid;
865		long	gid;
866		long	flags;
867	} *uap = (struct a *)clwp->lwp_ap;
868
869	if (uap->fname == 0)
870		e = AUE_FCHOWN;
871	else if (uap->flags & AT_SYMLINK_NOFOLLOW)
872		e = AUE_LCHOWN;
873	else
874		e = AUE_CHOWN;
875
876	return (e);
877}
878
879/*ARGSUSED*/
880static void
881aus_fchownat(struct t_audit_data *tad)
882{
883	klwp_t *clwp = ttolwp(curthread);
884	uint32_t uid, gid;
885
886	struct a {
887		long	fd;
888		long	fname;		/* char * */
889		long	uid;
890		long	gid;
891		long	flags;
892	} *uap = (struct a *)clwp->lwp_ap;
893
894	uid = (uint32_t)uap->uid;
895	gid = (uint32_t)uap->gid;
896
897	au_uwrite(au_to_arg32(3, "new file uid", uid));
898	au_uwrite(au_to_arg32(4, "new file gid", gid));
899}
900
901/*ARGSUSED*/
902static void
903aus_chmod(struct t_audit_data *tad)
904{
905	klwp_t *clwp = ttolwp(curthread);
906	uint32_t fmode;
907
908	struct a {
909		long	fname;		/* char	* */
910		long	fmode;
911	} *uap = (struct a *)clwp->lwp_ap;
912
913	fmode = (uint32_t)uap->fmode;
914
915	au_uwrite(au_to_arg32(2, "new file mode", fmode&07777));
916}
917
918/*ARGSUSED*/
919static void
920aus_fchmod(struct t_audit_data *tad)
921{
922	klwp_t *clwp = ttolwp(curthread);
923	uint32_t fmode, fd;
924	struct file  *fp;
925	struct vnode *vp;
926	struct f_audit_data *fad;
927
928	struct a {
929		long	fd;
930		long	fmode;
931	} *uap = (struct a *)clwp->lwp_ap;
932
933	fd = (uint32_t)uap->fd;
934	fmode = (uint32_t)uap->fmode;
935
936	au_uwrite(au_to_arg32(2, "new file mode", fmode&07777));
937
938	/*
939	 * convert file pointer to file descriptor
940	 *   Note: fd ref count incremented here.
941	 */
942	if ((fp = getf(fd)) == NULL)
943		return;
944
945	/* get path from file struct here */
946	fad = F2A(fp);
947	if (fad->fad_aupath != NULL) {
948		au_uwrite(au_to_path(fad->fad_aupath));
949	} else {
950		au_uwrite(au_to_arg32(1, "no path: fd", fd));
951	}
952
953	vp = fp->f_vnode;
954	audit_attributes(vp);
955
956	/* decrement file descriptor reference count */
957	releasef(fd);
958}
959
960static au_event_t
961aui_fchmodat(au_event_t e)
962{
963	klwp_t *clwp = ttolwp(curthread);
964
965	struct a {
966		long	fd;
967		long	fname;		/* char	* */
968		long	fmode;
969		long	flag;
970	} *uap = (struct a *)clwp->lwp_ap;
971
972	if (uap->fname == 0)
973		e = AUE_FCHMOD;
974	else
975		e = AUE_CHMOD;
976
977	return (e);
978}
979
980/*ARGSUSED*/
981static void
982aus_fchmodat(struct t_audit_data *tad)
983{
984	klwp_t *clwp = ttolwp(curthread);
985	uint32_t fmode;
986	uint32_t fd;
987	struct file  *fp;
988	struct vnode *vp;
989	struct f_audit_data *fad;
990
991	struct a {
992		long	fd;
993		long	fname;		/* char	* */
994		long	fmode;
995		long	flag;
996	} *uap = (struct a *)clwp->lwp_ap;
997
998	fd = (uint32_t)uap->fd;
999	fmode = (uint32_t)uap->fmode;
1000
1001	au_uwrite(au_to_arg32(2, "new file mode", fmode&07777));
1002
1003	if (fd == AT_FDCWD || uap->fname != 0)	/* same as chmod() */
1004		return;
1005
1006	/*
1007	 * convert file pointer to file descriptor
1008	 *   Note: fd ref count incremented here.
1009	 */
1010	if ((fp = getf(fd)) == NULL)
1011		return;
1012
1013	/* get path from file struct here */
1014	fad = F2A(fp);
1015	if (fad->fad_aupath != NULL) {
1016		au_uwrite(au_to_path(fad->fad_aupath));
1017	} else {
1018		au_uwrite(au_to_arg32(1, "no path: fd", fd));
1019	}
1020
1021	vp = fp->f_vnode;
1022	audit_attributes(vp);
1023
1024	/* decrement file descriptor reference count */
1025	releasef(fd);
1026}
1027
1028/*
1029 * convert open mode to appropriate open event
1030 */
1031au_event_t
1032open_event(uint_t fm)
1033{
1034	au_event_t e;
1035
1036	switch (fm & (O_ACCMODE | O_CREAT | O_TRUNC)) {
1037	case O_RDONLY:
1038		e = AUE_OPEN_R;
1039		break;
1040	case O_RDONLY | O_CREAT:
1041		e = AUE_OPEN_RC;
1042		break;
1043	case O_RDONLY | O_TRUNC:
1044		e = AUE_OPEN_RT;
1045		break;
1046	case O_RDONLY | O_TRUNC | O_CREAT:
1047		e = AUE_OPEN_RTC;
1048		break;
1049	case O_WRONLY:
1050		e = AUE_OPEN_W;
1051		break;
1052	case O_WRONLY | O_CREAT:
1053		e = AUE_OPEN_WC;
1054		break;
1055	case O_WRONLY | O_TRUNC:
1056		e = AUE_OPEN_WT;
1057		break;
1058	case O_WRONLY | O_TRUNC | O_CREAT:
1059		e = AUE_OPEN_WTC;
1060		break;
1061	case O_RDWR:
1062		e = AUE_OPEN_RW;
1063		break;
1064	case O_RDWR | O_CREAT:
1065		e = AUE_OPEN_RWC;
1066		break;
1067	case O_RDWR | O_TRUNC:
1068		e = AUE_OPEN_RWT;
1069		break;
1070	case O_RDWR | O_TRUNC | O_CREAT:
1071		e = AUE_OPEN_RWTC;
1072		break;
1073	case O_SEARCH:
1074		e = AUE_OPEN_S;
1075		break;
1076	case O_EXEC:
1077		e = AUE_OPEN_E;
1078		break;
1079	default:
1080		e = AUE_NULL;
1081		break;
1082	}
1083
1084	return (e);
1085}
1086
1087/* ARGSUSED */
1088static au_event_t
1089aui_open(au_event_t e)
1090{
1091	klwp_t *clwp = ttolwp(curthread);
1092	uint_t fm;
1093
1094	struct a {
1095		long	fnamep;		/* char	* */
1096		long	fmode;
1097		long	cmode;
1098	} *uap = (struct a *)clwp->lwp_ap;
1099
1100	fm = (uint_t)uap->fmode;
1101
1102	return (open_event(fm));
1103}
1104
1105static void
1106aus_open(struct t_audit_data *tad)
1107{
1108	klwp_t *clwp = ttolwp(curthread);
1109	uint_t fm;
1110
1111	struct a {
1112		long	fnamep;		/* char	* */
1113		long	fmode;
1114		long	cmode;
1115	} *uap = (struct a *)clwp->lwp_ap;
1116
1117	fm = (uint_t)uap->fmode;
1118
1119	/* If no write, create, or trunc modes, mark as a public op */
1120	if ((fm & (O_RDONLY|O_WRONLY|O_RDWR|O_CREAT|O_TRUNC)) == O_RDONLY)
1121		tad->tad_ctrl |= TAD_PUBLIC_EV;
1122}
1123
1124/* ARGSUSED */
1125static au_event_t
1126aui_openat(au_event_t e)
1127{
1128	t_audit_data_t *tad = T2A(curthread);
1129	klwp_t *clwp = ttolwp(curthread);
1130	uint_t fm;
1131
1132	struct a {
1133		long	filedes;
1134		long	fnamep;		/* char	* */
1135		long	fmode;
1136		long	cmode;
1137	} *uap = (struct a *)clwp->lwp_ap;
1138
1139	fm = (uint_t)uap->fmode;
1140
1141	/*
1142	 * __openattrdirat() does an extra pathname lookup in order to
1143	 * enter the extended system attribute namespace of the referenced
1144	 * extended attribute filename.
1145	 */
1146	if (fm & FXATTRDIROPEN)
1147		tad->tad_ctrl |= TAD_MLD;
1148
1149	return (open_event(fm));
1150}
1151
1152static void
1153aus_openat(struct t_audit_data *tad)
1154{
1155	klwp_t *clwp = ttolwp(curthread);
1156	uint_t fm;
1157
1158	struct a {
1159		long	filedes;
1160		long	fnamep;		/* char	* */
1161		long	fmode;
1162		long	cmode;
1163	} *uap = (struct a *)clwp->lwp_ap;
1164
1165	fm = (uint_t)uap->fmode;
1166
1167	/* If no write, create, or trunc modes, mark as a public op */
1168	if ((fm & (O_RDONLY|O_WRONLY|O_RDWR|O_CREAT|O_TRUNC)) == O_RDONLY)
1169		tad->tad_ctrl |= TAD_PUBLIC_EV;
1170}
1171
1172static au_event_t
1173aui_unlinkat(au_event_t e)
1174{
1175	klwp_t *clwp = ttolwp(curthread);
1176
1177	struct a {
1178		long	filedes;
1179		long	fnamep;		/* char	* */
1180		long	flags;
1181	} *uap = (struct a *)clwp->lwp_ap;
1182
1183	if (uap->flags & AT_REMOVEDIR)
1184		e = AUE_RMDIR;
1185	else
1186		e = AUE_UNLINK;
1187
1188	return (e);
1189}
1190
1191static au_event_t
1192aui_fstatat(au_event_t e)
1193{
1194	klwp_t *clwp = ttolwp(curthread);
1195
1196	struct a {
1197		long	filedes;
1198		long	fnamep;		/* char	* */
1199		long	statb;
1200		long	flags;
1201	} *uap = (struct a *)clwp->lwp_ap;
1202
1203	if (uap->fnamep == 0)
1204		e = AUE_FSTAT;
1205	else if (uap->flags & AT_SYMLINK_NOFOLLOW)
1206		e = AUE_LSTAT;
1207	else
1208		e = AUE_STAT;
1209
1210	return (e);
1211}
1212
1213/* msgsys */
1214static au_event_t
1215aui_msgsys(au_event_t e)
1216{
1217	klwp_t *clwp = ttolwp(curthread);
1218	uint_t fm;
1219
1220	struct a {
1221		long	id;	/* function code id */
1222		long	ap;	/* arg pointer for recvmsg */
1223	} *uap = (struct a *)clwp->lwp_ap;
1224
1225	struct b {
1226		long	msgid;
1227		long	cmd;
1228		long	buf;	/* struct msqid_ds * */
1229	} *uap1 = (struct b *)&clwp->lwp_ap[1];
1230
1231	fm  = (uint_t)uap->id;
1232
1233	switch (fm) {
1234	case 0:		/* msgget */
1235		e = AUE_MSGGET;
1236		break;
1237	case 1:		/* msgctl */
1238		switch ((uint_t)uap1->cmd) {
1239		case IPC_RMID:
1240			e = AUE_MSGCTL_RMID;
1241			break;
1242		case IPC_SET:
1243			e = AUE_MSGCTL_SET;
1244			break;
1245		case IPC_STAT:
1246			e = AUE_MSGCTL_STAT;
1247			break;
1248		default:
1249			e = AUE_MSGCTL;
1250			break;
1251		}
1252		break;
1253	case 2:		/* msgrcv */
1254		e = AUE_MSGRCV;
1255		break;
1256	case 3:		/* msgsnd */
1257		e = AUE_MSGSND;
1258		break;
1259	default:	/* illegal system call */
1260		e = AUE_NULL;
1261		break;
1262	}
1263
1264	return (e);
1265}
1266
1267
1268/* shmsys */
1269static au_event_t
1270aui_shmsys(au_event_t e)
1271{
1272	klwp_t *clwp = ttolwp(curthread);
1273	int fm;
1274
1275	struct a {		/* shmsys */
1276		long	id;	/* function code id */
1277	} *uap = (struct a *)clwp->lwp_ap;
1278
1279	struct b {		/* ctrl */
1280		long	shmid;
1281		long	cmd;
1282		long	arg;		/* struct shmid_ds * */
1283	} *uap1 = (struct b *)&clwp->lwp_ap[1];
1284	fm  = (uint_t)uap->id;
1285
1286	switch (fm) {
1287	case 0:		/* shmat */
1288		e = AUE_SHMAT;
1289		break;
1290	case 1:		/* shmctl */
1291		switch ((uint_t)uap1->cmd) {
1292		case IPC_RMID:
1293			e = AUE_SHMCTL_RMID;
1294			break;
1295		case IPC_SET:
1296			e = AUE_SHMCTL_SET;
1297			break;
1298		case IPC_STAT:
1299			e = AUE_SHMCTL_STAT;
1300			break;
1301		default:
1302			e = AUE_SHMCTL;
1303			break;
1304		}
1305		break;
1306	case 2:		/* shmdt */
1307		e = AUE_SHMDT;
1308		break;
1309	case 3:		/* shmget */
1310		e = AUE_SHMGET;
1311		break;
1312	default:	/* illegal system call */
1313		e = AUE_NULL;
1314		break;
1315	}
1316
1317	return (e);
1318}
1319
1320
1321/* semsys */
1322static au_event_t
1323aui_semsys(au_event_t e)
1324{
1325	klwp_t *clwp = ttolwp(curthread);
1326	uint_t fm;
1327
1328	struct a {		/* semsys */
1329		long	id;
1330	} *uap = (struct a *)clwp->lwp_ap;
1331
1332	struct b {		/* ctrl */
1333		long	semid;
1334		long	semnum;
1335		long	cmd;
1336		long	arg;
1337	} *uap1 = (struct b *)&clwp->lwp_ap[1];
1338
1339	fm = (uint_t)uap->id;
1340
1341	switch (fm) {
1342	case 0:		/* semctl */
1343		switch ((uint_t)uap1->cmd) {
1344		case IPC_RMID:
1345			e = AUE_SEMCTL_RMID;
1346			break;
1347		case IPC_SET:
1348			e = AUE_SEMCTL_SET;
1349			break;
1350		case IPC_STAT:
1351			e = AUE_SEMCTL_STAT;
1352			break;
1353		case GETNCNT:
1354			e = AUE_SEMCTL_GETNCNT;
1355			break;
1356		case GETPID:
1357			e = AUE_SEMCTL_GETPID;
1358			break;
1359		case GETVAL:
1360			e = AUE_SEMCTL_GETVAL;
1361			break;
1362		case GETALL:
1363			e = AUE_SEMCTL_GETALL;
1364			break;
1365		case GETZCNT:
1366			e = AUE_SEMCTL_GETZCNT;
1367			break;
1368		case SETVAL:
1369			e = AUE_SEMCTL_SETVAL;
1370			break;
1371		case SETALL:
1372			e = AUE_SEMCTL_SETALL;
1373			break;
1374		default:
1375			e = AUE_SEMCTL;
1376			break;
1377		}
1378		break;
1379	case 1:		/* semget */
1380		e = AUE_SEMGET;
1381		break;
1382	case 2:		/* semop */
1383		e = AUE_SEMOP;
1384		break;
1385	default:	/* illegal system call */
1386		e = AUE_NULL;
1387		break;
1388	}
1389
1390	return (e);
1391}
1392
1393/* utssys - uname(2), ustat(2), fusers(2) */
1394static au_event_t
1395aui_utssys(au_event_t e)
1396{
1397	klwp_t *clwp = ttolwp(curthread);
1398	uint_t type;
1399
1400	struct a {
1401		union {
1402			long	cbuf;		/* char * */
1403			long	ubuf;		/* struct stat * */
1404		} ub;
1405		union {
1406			long	mv;	/* for USTAT */
1407			long	flags;	/* for FUSERS */
1408		} un;
1409		long	type;
1410		long	outbp;		/* char * for FUSERS */
1411	} *uap = (struct a *)clwp->lwp_ap;
1412
1413	type = (uint_t)uap->type;
1414
1415	if (type == UTS_FUSERS)
1416		return (e);
1417	else
1418		return ((au_event_t)AUE_NULL);
1419}
1420
1421static au_event_t
1422aui_fcntl(au_event_t e)
1423{
1424	klwp_t *clwp = ttolwp(curthread);
1425	uint_t cmd;
1426
1427	struct a {
1428		long	fdes;
1429		long	cmd;
1430		long	arg;
1431	} *uap = (struct a *)clwp->lwp_ap;
1432
1433	cmd = (uint_t)uap->cmd;
1434
1435	switch (cmd) {
1436	case F_GETLK:
1437	case F_SETLK:
1438	case F_SETLKW:
1439		break;
1440	case F_SETFL:
1441	case F_GETFL:
1442	case F_GETFD:
1443		break;
1444	default:
1445		e = (au_event_t)AUE_NULL;
1446		break;
1447	}
1448	return ((au_event_t)e);
1449}
1450
1451/* null function for now */
1452static au_event_t
1453aui_execve(au_event_t e)
1454{
1455	return (e);
1456}
1457
1458/*ARGSUSED*/
1459static void
1460aus_fcntl(struct t_audit_data *tad)
1461{
1462	klwp_t *clwp = ttolwp(curthread);
1463	uint32_t cmd, fd, flags;
1464	struct file  *fp;
1465	struct vnode *vp;
1466	struct f_audit_data *fad;
1467
1468	struct a {
1469		long	fd;
1470		long	cmd;
1471		long	arg;
1472	} *uap = (struct a *)clwp->lwp_ap;
1473
1474	cmd	= (uint32_t)uap->cmd;
1475	fd	= (uint32_t)uap->fd;
1476	flags	= (uint32_t)uap->arg;
1477
1478	au_uwrite(au_to_arg32(2, "cmd", cmd));
1479
1480	if (cmd == F_SETFL)
1481		au_uwrite(au_to_arg32(3, "flags", flags));
1482
1483		/*
1484		 * convert file pointer to file descriptor
1485		 *   Note: fd ref count incremented here.
1486		 */
1487	if ((fp = getf(fd)) == NULL)
1488		return;
1489
1490	/* get path from file struct here */
1491	fad = F2A(fp);
1492	if (fad->fad_aupath != NULL) {
1493		au_uwrite(au_to_path(fad->fad_aupath));
1494	} else {
1495		au_uwrite(au_to_arg32(1, "no path: fd", fd));
1496	}
1497
1498	vp = fp->f_vnode;
1499	audit_attributes(vp);
1500
1501	/* decrement file descriptor reference count */
1502	releasef(fd);
1503}
1504
1505/*ARGSUSED*/
1506static void
1507aus_kill(struct t_audit_data *tad)
1508{
1509	klwp_t *clwp = ttolwp(curthread);
1510	struct proc *p;
1511	uint32_t signo;
1512	uid_t uid, ruid;
1513	gid_t gid, rgid;
1514	pid_t pid;
1515	const auditinfo_addr_t *ainfo;
1516	cred_t *cr;
1517
1518	struct a {
1519		long	pid;
1520		long	signo;
1521	} *uap = (struct a *)clwp->lwp_ap;
1522
1523	pid   = (pid_t)uap->pid;
1524	signo = (uint32_t)uap->signo;
1525
1526	au_uwrite(au_to_arg32(2, "signal", signo));
1527	if (pid > 0) {
1528		mutex_enter(&pidlock);
1529		if (((p = prfind(pid)) == (struct proc *)0) ||
1530		    (p->p_stat == SIDL)) {
1531			mutex_exit(&pidlock);
1532			au_uwrite(au_to_arg32(1, "process", (uint32_t)pid));
1533			return;
1534		}
1535		mutex_enter(&p->p_lock); /* so process doesn't go away */
1536		mutex_exit(&pidlock);
1537
1538		mutex_enter(&p->p_crlock);
1539		crhold(cr = p->p_cred);
1540		mutex_exit(&p->p_crlock);
1541		mutex_exit(&p->p_lock);
1542
1543		ainfo = crgetauinfo(cr);
1544		if (ainfo == NULL) {
1545			crfree(cr);
1546			au_uwrite(au_to_arg32(1, "process", (uint32_t)pid));
1547			return;
1548		}
1549
1550		uid  = crgetuid(cr);
1551		gid  = crgetgid(cr);
1552		ruid = crgetruid(cr);
1553		rgid = crgetrgid(cr);
1554		au_uwrite(au_to_process(uid, gid, ruid, rgid, pid,
1555		    ainfo->ai_auid, ainfo->ai_asid, &ainfo->ai_termid));
1556
1557		if (is_system_labeled())
1558			au_uwrite(au_to_label(CR_SL(cr)));
1559
1560		crfree(cr);
1561	}
1562	else
1563		au_uwrite(au_to_arg32(1, "process", (uint32_t)pid));
1564}
1565
1566/*ARGSUSED*/
1567static void
1568aus_mkdir(struct t_audit_data *tad)
1569{
1570	klwp_t *clwp = ttolwp(curthread);
1571	uint32_t dmode;
1572
1573	struct a {
1574		long	dirnamep;		/* char * */
1575		long	dmode;
1576	} *uap = (struct a *)clwp->lwp_ap;
1577
1578	dmode = (uint32_t)uap->dmode;
1579
1580	au_uwrite(au_to_arg32(2, "mode", dmode));
1581}
1582
1583/*ARGSUSED*/
1584static void
1585aus_mkdirat(struct t_audit_data *tad)
1586{
1587	klwp_t *clwp = ttolwp(curthread);
1588	uint32_t dmode;
1589
1590	struct a {
1591		long	fd;
1592		long	dirnamep;		/* char * */
1593		long	dmode;
1594	} *uap = (struct a *)clwp->lwp_ap;
1595
1596	dmode = (uint32_t)uap->dmode;
1597
1598	au_uwrite(au_to_arg32(2, "mode", dmode));
1599}
1600
1601/*ARGSUSED*/
1602static void
1603aus_mknod(struct t_audit_data *tad)
1604{
1605	klwp_t *clwp = ttolwp(curthread);
1606	uint32_t fmode;
1607	dev_t dev;
1608
1609	struct a {
1610		long	pnamep;		/* char * */
1611		long	fmode;
1612		long	dev;
1613	} *uap = (struct a *)clwp->lwp_ap;
1614
1615	fmode = (uint32_t)uap->fmode;
1616	dev   = (dev_t)uap->dev;
1617
1618	au_uwrite(au_to_arg32(2, "mode", fmode));
1619#ifdef _LP64
1620	au_uwrite(au_to_arg64(3, "dev", dev));
1621#else
1622	au_uwrite(au_to_arg32(3, "dev", dev));
1623#endif
1624}
1625
1626/*ARGSUSED*/
1627static void
1628auf_mknod(struct t_audit_data *tad, int error, rval_t *rval)
1629{
1630	klwp_t *clwp = ttolwp(curthread);
1631	vnode_t	*dvp;
1632	caddr_t pnamep;
1633
1634	struct a {
1635		long	pnamep;		/* char * */
1636		long	fmode;
1637		long	dev;
1638	} *uap = (struct a *)clwp->lwp_ap;
1639
1640	/* no error, then already path token in audit record */
1641	if (error != EPERM && error != EINVAL)
1642		return;
1643
1644	/* do the lookup to force generation of path token */
1645	pnamep = (caddr_t)uap->pnamep;
1646	tad->tad_ctrl |= TAD_NOATTRB;
1647	error = lookupname(pnamep, UIO_USERSPACE, NO_FOLLOW, &dvp, NULLVPP);
1648	if (error == 0)
1649		VN_RELE(dvp);
1650}
1651
1652/*ARGSUSED*/
1653static void
1654aus_mknodat(struct t_audit_data *tad)
1655{
1656	klwp_t *clwp = ttolwp(curthread);
1657	uint32_t fmode;
1658	dev_t dev;
1659
1660	struct a {
1661		long	fd;
1662		long	pnamep;		/* char * */
1663		long	fmode;
1664		long	dev;
1665	} *uap = (struct a *)clwp->lwp_ap;
1666
1667	fmode = (uint32_t)uap->fmode;
1668	dev   = (dev_t)uap->dev;
1669
1670	au_uwrite(au_to_arg32(2, "mode", fmode));
1671#ifdef _LP64
1672	au_uwrite(au_to_arg64(3, "dev", dev));
1673#else
1674	au_uwrite(au_to_arg32(3, "dev", dev));
1675#endif
1676}
1677
1678/*ARGSUSED*/
1679static void
1680auf_mknodat(struct t_audit_data *tad, int error, rval_t *rval)
1681{
1682	klwp_t *clwp = ttolwp(curthread);
1683	vnode_t	*startvp;
1684	vnode_t	*dvp;
1685	caddr_t pnamep;
1686	int fd;
1687
1688	struct a {
1689		long	fd;
1690		long	pnamep;		/* char * */
1691		long	fmode;
1692		long	dev;
1693	} *uap = (struct a *)clwp->lwp_ap;
1694
1695	/* no error, then already path token in audit record */
1696	if (error != EPERM && error != EINVAL)
1697		return;
1698
1699	/* do the lookup to force generation of path token */
1700	fd = (int)uap->fd;
1701	pnamep = (caddr_t)uap->pnamep;
1702	if (pnamep == NULL ||
1703	    fgetstartvp(fd, pnamep, &startvp) != 0)
1704		return;
1705	tad->tad_ctrl |= TAD_NOATTRB;
1706	error = lookupnameat(pnamep, UIO_USERSPACE, NO_FOLLOW, &dvp, NULLVPP,
1707	    startvp);
1708	if (error == 0)
1709		VN_RELE(dvp);
1710	if (startvp != NULL)
1711		VN_RELE(startvp);
1712}
1713
1714/*ARGSUSED*/
1715static void
1716aus_mount(struct t_audit_data *tad)
1717{
1718	/* AUS_START */
1719	klwp_t *clwp = ttolwp(curthread);
1720	uint32_t flags;
1721	uintptr_t u_fstype, dataptr;
1722	STRUCT_DECL(nfs_args, nfsargs);
1723	size_t len;
1724	char *fstype, *hostname;
1725
1726	struct a {
1727		long	spec;		/* char    * */
1728		long	dir;		/* char    * */
1729		long	flags;
1730		long	fstype;		/* char    * */
1731		long	dataptr;	/* char    * */
1732		long	datalen;
1733	} *uap = (struct a *)clwp->lwp_ap;
1734
1735	u_fstype = (uintptr_t)uap->fstype;
1736	flags    = (uint32_t)uap->flags;
1737	dataptr  = (uintptr_t)uap->dataptr;
1738
1739	fstype = kmem_alloc(MAXNAMELEN, KM_SLEEP);
1740	if (copyinstr((caddr_t)u_fstype, (caddr_t)fstype, MAXNAMELEN, &len))
1741		goto mount_free_fstype;
1742
1743	au_uwrite(au_to_arg32(3, "flags", flags));
1744	au_uwrite(au_to_text(fstype));
1745
1746	if (strncmp(fstype, "nfs", 3) == 0) {
1747
1748		STRUCT_INIT(nfsargs, get_udatamodel());
1749		bzero(STRUCT_BUF(nfsargs), STRUCT_SIZE(nfsargs));
1750
1751		if (copyin((caddr_t)dataptr, STRUCT_BUF(nfsargs),
1752		    MIN(uap->datalen, STRUCT_SIZE(nfsargs)))) {
1753			/* DEBUG debug_enter((char *)NULL); */
1754			goto mount_free_fstype;
1755		}
1756		hostname = kmem_alloc(MAXNAMELEN, KM_SLEEP);
1757		if (copyinstr(STRUCT_FGETP(nfsargs, hostname),
1758		    (caddr_t)hostname, MAXNAMELEN, &len)) {
1759			goto mount_free_hostname;
1760		}
1761		au_uwrite(au_to_text(hostname));
1762		au_uwrite(au_to_arg32(3, "internal flags",
1763		    (uint_t)STRUCT_FGET(nfsargs, flags)));
1764
1765mount_free_hostname:
1766		kmem_free(hostname, MAXNAMELEN);
1767	}
1768
1769mount_free_fstype:
1770	kmem_free(fstype, MAXNAMELEN);
1771}	/* AUS_MOUNT */
1772
1773static void
1774aus_umount_path(caddr_t umount_dir)
1775{
1776	char			*dir_path;
1777	struct audit_path	*path;
1778	size_t			path_len, dir_len;
1779
1780	/* length alloc'd for two string pointers */
1781	path_len = sizeof (struct audit_path) + sizeof (char *);
1782	path = kmem_alloc(path_len, KM_SLEEP);
1783	dir_path = kmem_alloc(MAXPATHLEN, KM_SLEEP);
1784
1785	if (copyinstr(umount_dir, (caddr_t)dir_path,
1786	    MAXPATHLEN, &dir_len))
1787		goto umount2_free_dir;
1788
1789	/*
1790	 * the audit_path struct assumes that the buffer pointed to
1791	 * by audp_sect[n] contains string 0 immediatedly followed
1792	 * by string 1.
1793	 */
1794	path->audp_sect[0] = dir_path;
1795	path->audp_sect[1] = dir_path + strlen(dir_path) + 1;
1796	path->audp_size = path_len;
1797	path->audp_ref = 1;		/* not used */
1798	path->audp_cnt = 1;		/* one path string */
1799
1800	au_uwrite(au_to_path(path));
1801
1802umount2_free_dir:
1803	kmem_free(dir_path, MAXPATHLEN);
1804	kmem_free(path, path_len);
1805}
1806
1807/*ARGSUSED*/
1808static void
1809aus_umount2(struct t_audit_data *tad)
1810{
1811	klwp_t			*clwp = ttolwp(curthread);
1812	struct a {
1813		long	dir;		/* char    * */
1814		long	flags;
1815	} *uap = (struct a *)clwp->lwp_ap;
1816
1817	aus_umount_path((caddr_t)uap->dir);
1818
1819	au_uwrite(au_to_arg32(2, "flags", (uint32_t)uap->flags));
1820}
1821
1822static void
1823aus_msgsys(struct t_audit_data *tad)
1824{
1825	klwp_t *clwp = ttolwp(curthread);
1826	uint32_t msgid;
1827
1828	struct b {
1829		long	msgid;
1830		long	cmd;
1831		long	buf;		/* struct msqid_ds * */
1832	} *uap1 = (struct b *)&clwp->lwp_ap[1];
1833
1834	msgid = (uint32_t)uap1->msgid;
1835
1836
1837	switch (tad->tad_event) {
1838	case AUE_MSGGET:		/* msgget */
1839		au_uwrite(au_to_arg32(1, "msg key", msgid));
1840		break;
1841	case AUE_MSGCTL:		/* msgctl */
1842	case AUE_MSGCTL_RMID:		/* msgctl */
1843	case AUE_MSGCTL_SET:		/* msgctl */
1844	case AUE_MSGCTL_STAT:		/* msgctl */
1845	case AUE_MSGRCV:		/* msgrcv */
1846	case AUE_MSGSND:		/* msgsnd */
1847		au_uwrite(au_to_arg32(1, "msg ID", msgid));
1848		break;
1849	}
1850}
1851
1852/*ARGSUSED*/
1853static void
1854auf_msgsys(struct t_audit_data *tad, int error, rval_t *rval)
1855{
1856	int id;
1857
1858	if (error != 0)
1859		return;
1860	if (tad->tad_event == AUE_MSGGET) {
1861		uint32_t scid;
1862		uint32_t sy_flags;
1863
1864		/* need to determine type of executing binary */
1865		scid = tad->tad_scid;
1866#ifdef _SYSCALL32_IMPL
1867		if (lwp_getdatamodel(ttolwp(curthread)) == DATAMODEL_NATIVE)
1868			sy_flags = sysent[scid].sy_flags & SE_RVAL_MASK;
1869		else
1870			sy_flags = sysent32[scid].sy_flags & SE_RVAL_MASK;
1871#else
1872		sy_flags = sysent[scid].sy_flags & SE_RVAL_MASK;
1873#endif
1874		if (sy_flags == SE_32RVAL1)
1875			id = rval->r_val1;
1876		if (sy_flags == (SE_32RVAL2|SE_32RVAL1))
1877			id = rval->r_val1;
1878		if (sy_flags == SE_64RVAL)
1879			id = (int)rval->r_vals;
1880
1881		au_uwrite(au_to_ipc(AT_IPC_MSG, id));
1882	}
1883}
1884
1885static void
1886aus_semsys(struct t_audit_data *tad)
1887{
1888	klwp_t *clwp = ttolwp(curthread);
1889	uint32_t semid;
1890
1891	struct b {		/* ctrl */
1892		long	semid;
1893		long	semnum;
1894		long	cmd;
1895		long	arg;
1896	} *uap1 = (struct b *)&clwp->lwp_ap[1];
1897
1898	semid = (uint32_t)uap1->semid;
1899
1900	switch (tad->tad_event) {
1901	case AUE_SEMCTL_RMID:
1902	case AUE_SEMCTL_STAT:
1903	case AUE_SEMCTL_GETNCNT:
1904	case AUE_SEMCTL_GETPID:
1905	case AUE_SEMCTL_GETVAL:
1906	case AUE_SEMCTL_GETALL:
1907	case AUE_SEMCTL_GETZCNT:
1908	case AUE_SEMCTL_SET:
1909	case AUE_SEMCTL_SETVAL:
1910	case AUE_SEMCTL_SETALL:
1911	case AUE_SEMCTL:
1912	case AUE_SEMOP:
1913		au_uwrite(au_to_arg32(1, "sem ID", semid));
1914		break;
1915	case AUE_SEMGET:
1916		au_uwrite(au_to_arg32(1, "sem key", semid));
1917		break;
1918	}
1919}
1920
1921/*ARGSUSED*/
1922static void
1923auf_semsys(struct t_audit_data *tad, int error, rval_t *rval)
1924{
1925	int id;
1926
1927	if (error != 0)
1928		return;
1929	if (tad->tad_event == AUE_SEMGET) {
1930		uint32_t scid;
1931		uint32_t sy_flags;
1932
1933		/* need to determine type of executing binary */
1934		scid = tad->tad_scid;
1935#ifdef _SYSCALL32_IMPL
1936		if (lwp_getdatamodel(ttolwp(curthread)) == DATAMODEL_NATIVE)
1937			sy_flags = sysent[scid].sy_flags & SE_RVAL_MASK;
1938		else
1939			sy_flags = sysent32[scid].sy_flags & SE_RVAL_MASK;
1940#else
1941		sy_flags = sysent[scid].sy_flags & SE_RVAL_MASK;
1942#endif
1943		if (sy_flags == SE_32RVAL1)
1944			id = rval->r_val1;
1945		if (sy_flags == (SE_32RVAL2|SE_32RVAL1))
1946			id = rval->r_val1;
1947		if (sy_flags == SE_64RVAL)
1948			id = (int)rval->r_vals;
1949
1950		au_uwrite(au_to_ipc(AT_IPC_SEM, id));
1951	}
1952}
1953
1954/*ARGSUSED*/
1955static void
1956aus_close(struct t_audit_data *tad)
1957{
1958	klwp_t *clwp = ttolwp(curthread);
1959	uint32_t fd;
1960	struct file *fp;
1961	struct f_audit_data *fad;
1962	struct vnode *vp;
1963	struct vattr attr;
1964	au_kcontext_t	*kctx = GET_KCTX_PZ;
1965
1966	struct a {
1967		long	i;
1968	} *uap = (struct a *)clwp->lwp_ap;
1969
1970	fd = (uint32_t)uap->i;
1971
1972	attr.va_mask = 0;
1973	au_uwrite(au_to_arg32(1, "fd", fd));
1974
1975		/*
1976		 * convert file pointer to file descriptor
1977		 *   Note: fd ref count incremented here.
1978		 */
1979	if ((fp = getf(fd)) == NULL)
1980		return;
1981
1982	fad = F2A(fp);
1983	tad->tad_evmod = (au_emod_t)fad->fad_flags;
1984	if (fad->fad_aupath != NULL) {
1985		au_uwrite(au_to_path(fad->fad_aupath));
1986		if ((vp = fp->f_vnode) != NULL) {
1987			attr.va_mask = AT_ALL;
1988			if (VOP_GETATTR(vp, &attr, 0, CRED(), NULL) == 0) {
1989				/*
1990				 * When write was not used and the file can be
1991				 * considered public, skip the audit.
1992				 */
1993				if (((fp->f_flag & FWRITE) == 0) &&
1994				    object_is_public(&attr)) {
1995					tad->tad_flag = 0;
1996					tad->tad_evmod = 0;
1997					/* free any residual audit data */
1998					au_close(kctx, &(u_ad), 0, 0, 0, NULL);
1999					releasef(fd);
2000					return;
2001				}
2002				au_uwrite(au_to_attr(&attr));
2003				audit_sec_attributes(&(u_ad), vp);
2004			}
2005		}
2006	}
2007
2008	/* decrement file descriptor reference count */
2009	releasef(fd);
2010}
2011
2012/*ARGSUSED*/
2013static void
2014aus_fstatfs(struct t_audit_data *tad)
2015{
2016	klwp_t *clwp = ttolwp(curthread);
2017	uint32_t fd;
2018	struct file  *fp;
2019	struct vnode *vp;
2020	struct f_audit_data *fad;
2021
2022	struct a {
2023		long	fd;
2024		long	buf;		/* struct statfs * */
2025	} *uap = (struct a *)clwp->lwp_ap;
2026
2027	fd = (uint_t)uap->fd;
2028
2029		/*
2030		 * convert file pointer to file descriptor
2031		 *   Note: fd ref count incremented here.
2032		 */
2033	if ((fp = getf(fd)) == NULL)
2034		return;
2035
2036		/* get path from file struct here */
2037	fad = F2A(fp);
2038	if (fad->fad_aupath != NULL) {
2039		au_uwrite(au_to_path(fad->fad_aupath));
2040	} else {
2041		au_uwrite(au_to_arg32(1, "no path: fd", fd));
2042	}
2043
2044	vp = fp->f_vnode;
2045	audit_attributes(vp);
2046
2047	/* decrement file descriptor reference count */
2048	releasef(fd);
2049}
2050
2051static au_event_t
2052aui_setpgrp(au_event_t e)
2053{
2054	klwp_t *clwp = ttolwp(curthread);
2055	int flag;
2056
2057	struct a {
2058		long	flag;
2059		long	pid;
2060		long	pgid;
2061	} *uap = (struct a *)clwp->lwp_ap;
2062
2063	flag = (int)uap->flag;
2064
2065
2066	switch (flag) {
2067
2068	case 1:	/* setpgrp() */
2069		e = AUE_SETPGRP;
2070		break;
2071
2072	case 3: /* setsid() */
2073		e = AUE_SETSID;
2074		break;
2075
2076	case 5: /* setpgid() */
2077		e = AUE_SETPGID;
2078		break;
2079
2080	case 0: /* getpgrp()	- not security relevant */
2081	case 2: /* getsid()	- not security relevant */
2082	case 4: /* getpgid()	- not security relevant */
2083		e = AUE_NULL;
2084		break;
2085
2086	default:
2087		e = AUE_NULL;
2088		break;
2089	}
2090
2091	return (e);
2092}
2093
2094/*ARGSUSED*/
2095static void
2096aus_setpgrp(struct t_audit_data *tad)
2097{
2098	klwp_t		*clwp = ttolwp(curthread);
2099	pid_t		pgid;
2100	struct proc	*p;
2101	uid_t		uid, ruid;
2102	gid_t		gid, rgid;
2103	pid_t		pid;
2104	cred_t		*cr;
2105	int		flag;
2106	const auditinfo_addr_t	*ainfo;
2107
2108	struct a {
2109		long	flag;
2110		long	pid;
2111		long	pgid;
2112	} *uap = (struct a *)clwp->lwp_ap;
2113
2114	flag = (int)uap->flag;
2115	pid  = (pid_t)uap->pid;
2116	pgid = (pid_t)uap->pgid;
2117
2118
2119	switch (flag) {
2120
2121	case 0: /* getpgrp() */
2122	case 1: /* setpgrp() */
2123	case 2: /* getsid() */
2124	case 3: /* setsid() */
2125	case 4: /* getpgid() */
2126		break;
2127
2128	case 5: /* setpgid() */
2129
2130		/* current process? */
2131		if (pid == 0) {
2132			return;
2133		}
2134
2135		mutex_enter(&pidlock);
2136		p = prfind(pid);
2137		if (p == NULL || p->p_as == &kas ||
2138		    p->p_stat == SIDL || p->p_stat == SZOMB) {
2139			mutex_exit(&pidlock);
2140			return;
2141		}
2142		mutex_enter(&p->p_lock);	/* so process doesn't go away */
2143		mutex_exit(&pidlock);
2144
2145		mutex_enter(&p->p_crlock);
2146		crhold(cr = p->p_cred);
2147		mutex_exit(&p->p_crlock);
2148		mutex_exit(&p->p_lock);
2149
2150		ainfo = crgetauinfo(cr);
2151		if (ainfo == NULL) {
2152			crfree(cr);
2153			return;
2154		}
2155
2156		uid  = crgetuid(cr);
2157		gid  = crgetgid(cr);
2158		ruid = crgetruid(cr);
2159		rgid = crgetrgid(cr);
2160		au_uwrite(au_to_process(uid, gid, ruid, rgid, pid,
2161		    ainfo->ai_auid, ainfo->ai_asid, &ainfo->ai_termid));
2162		crfree(cr);
2163		au_uwrite(au_to_arg32(2, "pgid", pgid));
2164		break;
2165
2166	default:
2167		break;
2168	}
2169}
2170
2171
2172/*ARGSUSED*/
2173static void
2174aus_setregid(struct t_audit_data *tad)
2175{
2176	klwp_t *clwp = ttolwp(curthread);
2177	uint32_t rgid, egid;
2178
2179	struct a {
2180		long	 rgid;
2181		long	 egid;
2182	} *uap = (struct a *)clwp->lwp_ap;
2183
2184	rgid  = (uint32_t)uap->rgid;
2185	egid  = (uint32_t)uap->egid;
2186
2187	au_uwrite(au_to_arg32(1, "rgid", rgid));
2188	au_uwrite(au_to_arg32(2, "egid", egid));
2189}
2190
2191/*ARGSUSED*/
2192static void
2193aus_setgid(struct t_audit_data *tad)
2194{
2195	klwp_t *clwp = ttolwp(curthread);
2196	uint32_t gid;
2197
2198	struct a {
2199		long	gid;
2200	} *uap = (struct a *)clwp->lwp_ap;
2201
2202	gid = (uint32_t)uap->gid;
2203
2204	au_uwrite(au_to_arg32(1, "gid", gid));
2205}
2206
2207
2208/*ARGSUSED*/
2209static void
2210aus_setreuid(struct t_audit_data *tad)
2211{
2212	klwp_t *clwp = ttolwp(curthread);
2213	uint32_t ruid, euid;
2214
2215	struct a {
2216		long	ruid;
2217		long	euid;
2218	} *uap = (struct a *)clwp->lwp_ap;
2219
2220	ruid = (uint32_t)uap->ruid;
2221	euid  = (uint32_t)uap->euid;
2222
2223	au_uwrite(au_to_arg32(1, "ruid", ruid));
2224	au_uwrite(au_to_arg32(2, "euid", euid));
2225}
2226
2227
2228/*ARGSUSED*/
2229static void
2230aus_setuid(struct t_audit_data *tad)
2231{
2232	klwp_t *clwp = ttolwp(curthread);
2233	uint32_t uid;
2234
2235	struct a {
2236		long	uid;
2237	} *uap = (struct a *)clwp->lwp_ap;
2238
2239	uid = (uint32_t)uap->uid;
2240
2241	au_uwrite(au_to_arg32(1, "uid", uid));
2242}
2243
2244/*ARGSUSED*/
2245static void
2246aus_shmsys(struct t_audit_data *tad)
2247{
2248	klwp_t *clwp = ttolwp(curthread);
2249	uint32_t id, cmd;
2250
2251	struct b {
2252		long	id;
2253		long	cmd;
2254		long	buf;		/* struct shmid_ds * */
2255	} *uap1 = (struct b *)&clwp->lwp_ap[1];
2256
2257	id  = (uint32_t)uap1->id;
2258	cmd = (uint32_t)uap1->cmd;
2259
2260	switch (tad->tad_event) {
2261	case AUE_SHMGET:			/* shmget */
2262		au_uwrite(au_to_arg32(1, "shm key", id));
2263		break;
2264	case AUE_SHMCTL:			/* shmctl */
2265	case AUE_SHMCTL_RMID:			/* shmctl */
2266	case AUE_SHMCTL_STAT:			/* shmctl */
2267	case AUE_SHMCTL_SET:			/* shmctl */
2268		au_uwrite(au_to_arg32(1, "shm ID", id));
2269		break;
2270	case AUE_SHMDT:				/* shmdt */
2271		au_uwrite(au_to_arg32(1, "shm adr", id));
2272		break;
2273	case AUE_SHMAT:				/* shmat */
2274		au_uwrite(au_to_arg32(1, "shm ID", id));
2275		au_uwrite(au_to_arg32(2, "shm adr", cmd));
2276		break;
2277	}
2278}
2279
2280/*ARGSUSED*/
2281static void
2282auf_shmsys(struct t_audit_data *tad, int error, rval_t *rval)
2283{
2284	int id;
2285
2286	if (error != 0)
2287		return;
2288	if (tad->tad_event == AUE_SHMGET) {
2289		uint32_t scid;
2290		uint32_t sy_flags;
2291
2292		/* need to determine type of executing binary */
2293		scid = tad->tad_scid;
2294#ifdef _SYSCALL32_IMPL
2295		if (lwp_getdatamodel(ttolwp(curthread)) == DATAMODEL_NATIVE)
2296			sy_flags = sysent[scid].sy_flags & SE_RVAL_MASK;
2297		else
2298			sy_flags = sysent32[scid].sy_flags & SE_RVAL_MASK;
2299#else
2300		sy_flags = sysent[scid].sy_flags & SE_RVAL_MASK;
2301#endif
2302		if (sy_flags == SE_32RVAL1)
2303			id = rval->r_val1;
2304		if (sy_flags == (SE_32RVAL2|SE_32RVAL1))
2305			id = rval->r_val1;
2306		if (sy_flags == SE_64RVAL)
2307			id = (int)rval->r_vals;
2308		au_uwrite(au_to_ipc(AT_IPC_SHM, id));
2309	}
2310}
2311
2312
2313/*ARGSUSED*/
2314static void
2315aus_ioctl(struct t_audit_data *tad)
2316{
2317	klwp_t *clwp = ttolwp(curthread);
2318	struct file *fp;
2319	struct vnode *vp;
2320	struct f_audit_data *fad;
2321	uint32_t fd, cmd;
2322	uintptr_t cmarg;
2323
2324	/* XX64 */
2325	struct a {
2326		long	fd;
2327		long	cmd;
2328		long	cmarg;		/* caddr_t */
2329	} *uap = (struct a *)clwp->lwp_ap;
2330
2331	fd    = (uint32_t)uap->fd;
2332	cmd   = (uint32_t)uap->cmd;
2333	cmarg = (uintptr_t)uap->cmarg;
2334
2335		/*
2336		 * convert file pointer to file descriptor
2337		 *   Note: fd ref count incremented here.
2338		 */
2339	if ((fp = getf(fd)) == NULL) {
2340		au_uwrite(au_to_arg32(1, "fd", fd));
2341		au_uwrite(au_to_arg32(2, "cmd", cmd));
2342#ifndef _LP64
2343		au_uwrite(au_to_arg32(3, "arg", (uint32_t)cmarg));
2344#else
2345		au_uwrite(au_to_arg64(3, "arg", (uint64_t)cmarg));
2346#endif
2347		return;
2348	}
2349
2350	/* get path from file struct here */
2351	fad = F2A(fp);
2352	if (fad->fad_aupath != NULL) {
2353		au_uwrite(au_to_path(fad->fad_aupath));
2354	} else {
2355		au_uwrite(au_to_arg32(1, "no path: fd", fd));
2356	}
2357
2358	vp = fp->f_vnode;
2359	audit_attributes(vp);
2360
2361	/* decrement file descriptor reference count */
2362	releasef(fd);
2363
2364	au_uwrite(au_to_arg32(2, "cmd", cmd));
2365#ifndef _LP64
2366	au_uwrite(au_to_arg32(3, "arg", (uint32_t)cmarg));
2367#else
2368	au_uwrite(au_to_arg64(3, "arg", (uint64_t)cmarg));
2369#endif
2370}
2371
2372/*
2373 * null function for memcntl for now. We might want to limit memcntl()
2374 * auditing to commands: MC_LOCKAS, MC_LOCK, MC_UNLOCKAS, MC_UNLOCK which
2375 * require privileges.
2376 */
2377static au_event_t
2378aui_memcntl(au_event_t e)
2379{
2380	return (e);
2381}
2382
2383/*ARGSUSED*/
2384static au_event_t
2385aui_privsys(au_event_t e)
2386{
2387	klwp_t *clwp = ttolwp(curthread);
2388
2389	struct a {
2390		long	opcode;
2391	} *uap = (struct a *)clwp->lwp_ap;
2392
2393	switch (uap->opcode) {
2394	case PRIVSYS_SETPPRIV:
2395		return (AUE_SETPPRIV);
2396	default:
2397		return (AUE_NULL);
2398	}
2399}
2400
2401/*ARGSUSED*/
2402static void
2403aus_memcntl(struct t_audit_data *tad)
2404{
2405	klwp_t *clwp = ttolwp(curthread);
2406
2407	struct a {
2408		long	addr;
2409		long	len;
2410		long	cmd;
2411		long	arg;
2412		long	attr;
2413		long	mask;
2414	} *uap = (struct a *)clwp->lwp_ap;
2415
2416#ifdef _LP64
2417	au_uwrite(au_to_arg64(1, "base", (uint64_t)uap->addr));
2418	au_uwrite(au_to_arg64(2, "len", (uint64_t)uap->len));
2419#else
2420	au_uwrite(au_to_arg32(1, "base", (uint32_t)uap->addr));
2421	au_uwrite(au_to_arg32(2, "len", (uint32_t)uap->len));
2422#endif
2423	au_uwrite(au_to_arg32(3, "cmd", (uint_t)uap->cmd));
2424#ifdef _LP64
2425	au_uwrite(au_to_arg64(4, "arg", (uint64_t)uap->arg));
2426#else
2427	au_uwrite(au_to_arg32(4, "arg", (uint32_t)uap->arg));
2428#endif
2429	au_uwrite(au_to_arg32(5, "attr", (uint_t)uap->attr));
2430	au_uwrite(au_to_arg32(6, "mask", (uint_t)uap->mask));
2431}
2432
2433/*ARGSUSED*/
2434static void
2435aus_mmap(struct t_audit_data *tad)
2436{
2437	klwp_t *clwp = ttolwp(curthread);
2438	struct file *fp;
2439	struct f_audit_data *fad;
2440	struct vnode *vp;
2441	uint32_t fd;
2442
2443	struct a {
2444		long	addr;
2445		long	len;
2446		long	prot;
2447		long	flags;
2448		long	fd;
2449		long	pos;
2450	} *uap = (struct a *)clwp->lwp_ap;
2451
2452	fd = (uint32_t)uap->fd;
2453
2454#ifdef _LP64
2455	au_uwrite(au_to_arg64(1, "addr", (uint64_t)uap->addr));
2456	au_uwrite(au_to_arg64(2, "len", (uint64_t)uap->len));
2457#else
2458	au_uwrite(au_to_arg32(1, "addr", (uint32_t)uap->addr));
2459	au_uwrite(au_to_arg32(2, "len", (uint32_t)uap->len));
2460#endif
2461
2462	if ((fp = getf(fd)) == NULL) {
2463		au_uwrite(au_to_arg32(5, "fd", (uint32_t)uap->fd));
2464		return;
2465	}
2466
2467	/*
2468	 * Mark in the tad if write access is NOT requested... if
2469	 * this is later detected (in audit_attributes) to be a
2470	 * public object, the mmap event may be discarded.
2471	 */
2472	if (((uap->prot) & PROT_WRITE) == 0) {
2473		tad->tad_ctrl |= TAD_PUBLIC_EV;
2474	}
2475
2476	fad = F2A(fp);
2477	if (fad->fad_aupath != NULL) {
2478		au_uwrite(au_to_path(fad->fad_aupath));
2479	} else {
2480		au_uwrite(au_to_arg32(1, "no path: fd", fd));
2481	}
2482
2483	vp = (struct vnode *)fp->f_vnode;
2484	audit_attributes(vp);
2485
2486	/* mark READ/WRITE since we can't predict access */
2487	if (uap->prot & PROT_READ)
2488		fad->fad_flags |= FAD_READ;
2489	if (uap->prot & PROT_WRITE)
2490		fad->fad_flags |= FAD_WRITE;
2491
2492	/* decrement file descriptor reference count */
2493	releasef(fd);
2494
2495}	/* AUS_MMAP */
2496
2497
2498
2499
2500/*ARGSUSED*/
2501static void
2502aus_munmap(struct t_audit_data *tad)
2503{
2504	klwp_t *clwp = ttolwp(curthread);
2505
2506	struct a {
2507		long	addr;
2508		long	len;
2509	} *uap = (struct a *)clwp->lwp_ap;
2510
2511#ifdef _LP64
2512	au_uwrite(au_to_arg64(1, "addr", (uint64_t)uap->addr));
2513	au_uwrite(au_to_arg64(2, "len", (uint64_t)uap->len));
2514#else
2515	au_uwrite(au_to_arg32(1, "addr", (uint32_t)uap->addr));
2516	au_uwrite(au_to_arg32(2, "len", (uint32_t)uap->len));
2517#endif
2518
2519}	/* AUS_MUNMAP */
2520
2521
2522
2523
2524
2525
2526
2527/*ARGSUSED*/
2528static void
2529aus_priocntlsys(struct t_audit_data *tad)
2530{
2531	klwp_t *clwp = ttolwp(curthread);
2532
2533	struct a {
2534		long	pc_version;
2535		long	psp;		/* procset_t */
2536		long	cmd;
2537		long	arg;
2538	} *uap = (struct a *)clwp->lwp_ap;
2539
2540	au_uwrite(au_to_arg32(1, "pc_version", (uint32_t)uap->pc_version));
2541	au_uwrite(au_to_arg32(3, "cmd", (uint32_t)uap->cmd));
2542
2543}	/* AUS_PRIOCNTLSYS */
2544
2545
2546/*ARGSUSED*/
2547static void
2548aus_setegid(struct t_audit_data *tad)
2549{
2550	klwp_t *clwp = ttolwp(curthread);
2551	uint32_t gid;
2552
2553	struct a {
2554		long	gid;
2555	} *uap = (struct a *)clwp->lwp_ap;
2556
2557	gid = (uint32_t)uap->gid;
2558
2559	au_uwrite(au_to_arg32(1, "gid", gid));
2560}	/* AUS_SETEGID */
2561
2562
2563
2564
2565/*ARGSUSED*/
2566static void
2567aus_setgroups(struct t_audit_data *tad)
2568{
2569	klwp_t *clwp = ttolwp(curthread);
2570	int i;
2571	int gidsetsize;
2572	uintptr_t gidset;
2573	gid_t *gidlist;
2574
2575	struct a {
2576		long	gidsetsize;
2577		long	gidset;
2578	} *uap = (struct a *)clwp->lwp_ap;
2579
2580	gidsetsize = (uint_t)uap->gidsetsize;
2581	gidset = (uintptr_t)uap->gidset;
2582
2583	if ((gidsetsize > NGROUPS_MAX_DEFAULT) || (gidsetsize < 0))
2584		return;
2585	if (gidsetsize != 0) {
2586		gidlist = kmem_alloc(gidsetsize * sizeof (gid_t),
2587		    KM_SLEEP);
2588		if (copyin((caddr_t)gidset, gidlist,
2589		    gidsetsize * sizeof (gid_t)) == 0)
2590			for (i = 0; i < gidsetsize; i++)
2591				au_uwrite(au_to_arg32(1, "setgroups",
2592				    (uint32_t)gidlist[i]));
2593		kmem_free(gidlist, gidsetsize * sizeof (gid_t));
2594	} else
2595		au_uwrite(au_to_arg32(1, "setgroups", (uint32_t)0));
2596
2597}	/* AUS_SETGROUPS */
2598
2599
2600
2601
2602
2603/*ARGSUSED*/
2604static void
2605aus_seteuid(struct t_audit_data *tad)
2606{
2607	klwp_t *clwp = ttolwp(curthread);
2608	uint32_t uid;
2609
2610	struct a {
2611		long	uid;
2612	} *uap = (struct a *)clwp->lwp_ap;
2613
2614	uid = (uint32_t)uap->uid;
2615
2616	au_uwrite(au_to_arg32(1, "euid", uid));
2617
2618}	/* AUS_SETEUID */
2619
2620/*ARGSUSED*/
2621static void
2622aus_putmsg(struct t_audit_data *tad)
2623{
2624	klwp_t *clwp = ttolwp(curthread);
2625	uint32_t fd, pri;
2626	struct file *fp;
2627	struct f_audit_data *fad;
2628
2629	struct a {
2630		long	fdes;
2631		long	ctl;		/* struct strbuf * */
2632		long	data;		/* struct strbuf * */
2633		long	pri;
2634	} *uap = (struct a *)clwp->lwp_ap;
2635
2636	fd  = (uint32_t)uap->fdes;
2637	pri = (uint32_t)uap->pri;
2638
2639	au_uwrite(au_to_arg32(1, "fd", fd));
2640
2641	if ((fp = getf(fd)) != NULL) {
2642		fad = F2A(fp);
2643
2644		fad->fad_flags |= FAD_WRITE;
2645
2646		/* add path name to audit record */
2647		if (fad->fad_aupath != NULL) {
2648			au_uwrite(au_to_path(fad->fad_aupath));
2649		}
2650		audit_attributes(fp->f_vnode);
2651
2652		releasef(fd);
2653	}
2654
2655	au_uwrite(au_to_arg32(4, "pri", pri));
2656}
2657
2658/*ARGSUSED*/
2659static void
2660aus_putpmsg(struct t_audit_data *tad)
2661{
2662	klwp_t *clwp = ttolwp(curthread);
2663	uint32_t fd, pri, flags;
2664	struct file *fp;
2665	struct f_audit_data *fad;
2666
2667	struct a {
2668		long	fdes;
2669		long	ctl;		/* struct strbuf * */
2670		long	data;		/* struct strbuf * */
2671		long	pri;
2672		long	flags;
2673	} *uap = (struct a *)clwp->lwp_ap;
2674
2675	fd = (uint32_t)uap->fdes;
2676	pri  = (uint32_t)uap->pri;
2677	flags  = (uint32_t)uap->flags;
2678
2679	au_uwrite(au_to_arg32(1, "fd", fd));
2680
2681	if ((fp = getf(fd)) != NULL) {
2682		fad = F2A(fp);
2683
2684		fad->fad_flags |= FAD_WRITE;
2685
2686		/* add path name to audit record */
2687		if (fad->fad_aupath != NULL) {
2688			au_uwrite(au_to_path(fad->fad_aupath));
2689		}
2690		audit_attributes(fp->f_vnode);
2691
2692		releasef(fd);
2693	}
2694
2695
2696	au_uwrite(au_to_arg32(4, "pri", pri));
2697	au_uwrite(au_to_arg32(5, "flags", flags));
2698}
2699
2700/*ARGSUSED*/
2701static void
2702aus_getmsg(struct t_audit_data *tad)
2703{
2704	klwp_t *clwp = ttolwp(curthread);
2705	uint32_t fd, pri;
2706	struct file *fp;
2707	struct f_audit_data *fad;
2708
2709	struct a {
2710		long	fdes;
2711		long	ctl;		/* struct strbuf * */
2712		long	data;		/* struct strbuf * */
2713		long	pri;
2714	} *uap = (struct a *)clwp->lwp_ap;
2715
2716	fd  = (uint32_t)uap->fdes;
2717	pri = (uint32_t)uap->pri;
2718
2719	au_uwrite(au_to_arg32(1, "fd", fd));
2720
2721	if ((fp = getf(fd)) != NULL) {
2722		fad = F2A(fp);
2723
2724		/*
2725		 * read operation on this object
2726		 */
2727		fad->fad_flags |= FAD_READ;
2728
2729		/* add path name to audit record */
2730		if (fad->fad_aupath != NULL) {
2731			au_uwrite(au_to_path(fad->fad_aupath));
2732		}
2733		audit_attributes(fp->f_vnode);
2734
2735		releasef(fd);
2736	}
2737
2738	au_uwrite(au_to_arg32(4, "pri", pri));
2739}
2740
2741/*ARGSUSED*/
2742static void
2743aus_getpmsg(struct t_audit_data *tad)
2744{
2745	klwp_t *clwp = ttolwp(curthread);
2746	uint32_t fd;
2747	struct file *fp;
2748	struct f_audit_data *fad;
2749
2750	struct a {
2751		long	fdes;
2752		long	ctl;		/* struct strbuf * */
2753		long	data;		/* struct strbuf * */
2754		long	pri;
2755		long	flags;
2756	} *uap = (struct a *)clwp->lwp_ap;
2757
2758	fd = (uint32_t)uap->fdes;
2759
2760	au_uwrite(au_to_arg32(1, "fd", fd));
2761
2762	if ((fp = getf(fd)) != NULL) {
2763		fad = F2A(fp);
2764
2765		/*
2766		 * read operation on this object
2767		 */
2768		fad->fad_flags |= FAD_READ;
2769
2770		/* add path name to audit record */
2771		if (fad->fad_aupath != NULL) {
2772			au_uwrite(au_to_path(fad->fad_aupath));
2773		}
2774		audit_attributes(fp->f_vnode);
2775
2776		releasef(fd);
2777	}
2778}
2779
2780static au_event_t
2781aui_labelsys(au_event_t e)
2782{
2783	klwp_t *clwp = ttolwp(curthread);
2784	uint32_t code;
2785	uint32_t cmd;
2786
2787	struct a {
2788		long	code;
2789		long	cmd;
2790	} *uap = (struct a *)clwp->lwp_ap;
2791
2792	code = (uint32_t)uap->code;
2793	cmd = (uint32_t)uap->cmd;
2794
2795	/* not security relevant if not changing kernel cache */
2796	if (cmd == TNDB_GET)
2797		return (AUE_NULL);
2798
2799	switch (code) {
2800	case TSOL_TNRH:
2801		e = AUE_LABELSYS_TNRH;
2802		break;
2803	case TSOL_TNRHTP:
2804		e = AUE_LABELSYS_TNRHTP;
2805		break;
2806	case TSOL_TNMLP:
2807		e = AUE_LABELSYS_TNMLP;
2808		break;
2809	default:
2810		e = AUE_NULL;
2811		break;
2812	}
2813
2814	return (e);
2815
2816}
2817
2818static void
2819aus_labelsys(struct t_audit_data *tad)
2820{
2821	klwp_t *clwp = ttolwp(curthread);
2822	uint32_t cmd;
2823	uintptr_t a2;
2824
2825	struct a {
2826		long	code;
2827		long	cmd;
2828		long	a2;
2829	} *uap = (struct a *)clwp->lwp_ap;
2830
2831	cmd = (uint32_t)uap->cmd;
2832	a2 = (uintptr_t)uap->a2;
2833
2834	switch (tad->tad_event) {
2835	case AUE_LABELSYS_TNRH:
2836	{
2837		tsol_rhent_t	*rhent;
2838		tnaddr_t	*rh_addr;
2839
2840		au_uwrite(au_to_arg32(1, "cmd", cmd));
2841
2842		/* Remaining args don't apply for FLUSH, so skip */
2843		if (cmd == TNDB_FLUSH)
2844			break;
2845
2846		rhent = kmem_alloc(sizeof (tsol_rhent_t), KM_SLEEP);
2847		if (copyin((caddr_t)a2, rhent, sizeof (tsol_rhent_t))) {
2848			kmem_free(rhent, sizeof (tsol_rhent_t));
2849			return;
2850		}
2851
2852		rh_addr = &rhent->rh_address;
2853		if (rh_addr->ta_family == AF_INET) {
2854			struct in_addr	*ipaddr;
2855
2856			ipaddr = &(rh_addr->ta_addr_v4);
2857			au_uwrite(au_to_in_addr(ipaddr));
2858		} else if (rh_addr->ta_family == AF_INET6) {
2859			int32_t		*ipaddr;
2860
2861			ipaddr = (int32_t *)&(rh_addr->ta_addr_v6);
2862			au_uwrite(au_to_in_addr_ex(ipaddr));
2863		}
2864		au_uwrite(au_to_arg32(2, "prefix len", rhent->rh_prefix));
2865
2866		kmem_free(rhent, sizeof (tsol_rhent_t));
2867
2868		break;
2869	}
2870	case AUE_LABELSYS_TNRHTP:
2871	{
2872		tsol_tpent_t	*tpent;
2873
2874		au_uwrite(au_to_arg32(1, "cmd", cmd));
2875
2876		/* Remaining args don't apply for FLUSH, so skip */
2877		if (cmd == TNDB_FLUSH)
2878			break;
2879
2880		tpent = kmem_alloc(sizeof (tsol_tpent_t), KM_SLEEP);
2881		if (copyin((caddr_t)a2, tpent, sizeof (tsol_tpent_t))) {
2882			kmem_free(tpent, sizeof (tsol_tpent_t));
2883			return;
2884		}
2885
2886		/* Make sure that the template name is null-terminated. */
2887		*(tpent->name + TNTNAMSIZ - 1) = '\0';
2888
2889		au_uwrite(au_to_text(tpent->name));
2890		kmem_free(tpent, sizeof (tsol_tpent_t));
2891
2892		break;
2893	}
2894	case AUE_LABELSYS_TNMLP:
2895	{
2896		tsol_mlpent_t	*mlpent;
2897
2898		au_uwrite(au_to_arg32(1, "cmd", cmd));
2899
2900		mlpent = kmem_alloc(sizeof (tsol_mlpent_t), KM_SLEEP);
2901		if (copyin((caddr_t)a2, mlpent, sizeof (tsol_mlpent_t))) {
2902			kmem_free(mlpent, sizeof (tsol_mlpent_t));
2903			return;
2904		}
2905
2906		if (mlpent->tsme_flags & TSOL_MEF_SHARED) {
2907			au_uwrite(au_to_text("shared"));
2908		} else {
2909			zone_t	*zone;
2910
2911			zone = zone_find_by_id(mlpent->tsme_zoneid);
2912			if (zone != NULL) {
2913				au_uwrite(au_to_text(zone->zone_name));
2914				zone_rele(zone);
2915			}
2916		}
2917
2918		/* Remaining args don't apply for FLUSH, so skip */
2919		if (cmd == TNDB_FLUSH) {
2920			kmem_free(mlpent, sizeof (tsol_mlpent_t));
2921			break;
2922		}
2923
2924		au_uwrite(au_to_arg32(2, "proto num",
2925		    (uint32_t)mlpent->tsme_mlp.mlp_ipp));
2926		au_uwrite(au_to_arg32(2, "mlp_port",
2927		    (uint32_t)mlpent->tsme_mlp.mlp_port));
2928
2929		if (mlpent->tsme_mlp.mlp_port_upper != 0)
2930			au_uwrite(au_to_arg32(2, "mlp_port_upper",
2931			    (uint32_t)mlpent->tsme_mlp.mlp_port_upper));
2932
2933		kmem_free(mlpent, sizeof (tsol_mlpent_t));
2934
2935		break;
2936	}
2937	default:
2938		break;
2939	}
2940}
2941
2942
2943static au_event_t
2944aui_auditsys(au_event_t e)
2945{
2946	klwp_t *clwp = ttolwp(curthread);
2947	uint32_t code;
2948
2949	struct a {
2950		long	code;
2951		long	a1;
2952		long	a2;
2953		long	a3;
2954		long	a4;
2955		long	a5;
2956		long	a6;
2957		long	a7;
2958	} *uap = (struct a *)clwp->lwp_ap;
2959
2960	code = (uint32_t)uap->code;
2961
2962	switch (code) {
2963
2964	case BSM_GETAUID:
2965		e = AUE_GETAUID;
2966		break;
2967	case BSM_SETAUID:
2968		e = AUE_SETAUID;
2969		break;
2970	case BSM_GETAUDIT:
2971		e = AUE_GETAUDIT;
2972		break;
2973	case BSM_GETAUDIT_ADDR:
2974		e = AUE_GETAUDIT_ADDR;
2975		break;
2976	case BSM_SETAUDIT:
2977		e = AUE_SETAUDIT;
2978		break;
2979	case BSM_SETAUDIT_ADDR:
2980		e = AUE_SETAUDIT_ADDR;
2981		break;
2982	case BSM_AUDIT:
2983		e = AUE_AUDIT;
2984		break;
2985	case BSM_AUDITCTL:
2986		switch ((uint_t)uap->a1) {
2987
2988		case A_GETPOLICY:
2989			e = AUE_AUDITON_GPOLICY;
2990			break;
2991		case A_SETPOLICY:
2992			e = AUE_AUDITON_SPOLICY;
2993			break;
2994		case A_GETAMASK:
2995			e = AUE_AUDITON_GETAMASK;
2996			break;
2997		case A_SETAMASK:
2998			e = AUE_AUDITON_SETAMASK;
2999			break;
3000		case A_GETKMASK:
3001			e = AUE_AUDITON_GETKMASK;
3002			break;
3003		case A_SETKMASK:
3004			e = AUE_AUDITON_SETKMASK;
3005			break;
3006		case A_GETQCTRL:
3007			e = AUE_AUDITON_GQCTRL;
3008			break;
3009		case A_SETQCTRL:
3010			e = AUE_AUDITON_SQCTRL;
3011			break;
3012		case A_GETCWD:
3013			e = AUE_AUDITON_GETCWD;
3014			break;
3015		case A_GETCAR:
3016			e = AUE_AUDITON_GETCAR;
3017			break;
3018		case A_GETSTAT:
3019			e = AUE_AUDITON_GETSTAT;
3020			break;
3021		case A_SETSTAT:
3022			e = AUE_AUDITON_SETSTAT;
3023			break;
3024		case A_SETUMASK:
3025			e = AUE_AUDITON_SETUMASK;
3026			break;
3027		case A_SETSMASK:
3028			e = AUE_AUDITON_SETSMASK;
3029			break;
3030		case A_GETCOND:
3031			e = AUE_AUDITON_GETCOND;
3032			break;
3033		case A_SETCOND:
3034			e = AUE_AUDITON_SETCOND;
3035			break;
3036		case A_GETCLASS:
3037			e = AUE_AUDITON_GETCLASS;
3038			break;
3039		case A_SETCLASS:
3040			e = AUE_AUDITON_SETCLASS;
3041			break;
3042		case A_GETPINFO:
3043		case A_GETPINFO_ADDR:
3044			e = AUE_AUDITON_GETPINFO;
3045			break;
3046		case A_SETPMASK:
3047			e = AUE_AUDITON_SETPMASK;
3048			break;
3049		case A_GETKAUDIT:
3050			e = AUE_AUDITON_GETKAUDIT;
3051			break;
3052		case A_SETKAUDIT:
3053			e = AUE_AUDITON_SETKAUDIT;
3054			break;
3055		default:
3056			e = AUE_AUDITON_OTHER;
3057			break;
3058		}
3059		break;
3060	default:
3061		e = AUE_NULL;
3062		break;
3063	}
3064
3065	return (e);
3066
3067}	/* AUI_AUDITSYS */
3068
3069
3070static void
3071aus_auditsys(struct t_audit_data *tad)
3072{
3073	klwp_t *clwp = ttolwp(curthread);
3074	uintptr_t a1, a2;
3075	STRUCT_DECL(auditinfo, ainfo);
3076	STRUCT_DECL(auditinfo_addr, ainfo_addr);
3077	STRUCT_DECL(auditpinfo, apinfo);
3078	au_evclass_map_t event;
3079	au_mask_t mask;
3080	int auditstate, policy;
3081	au_id_t auid;
3082
3083
3084	struct a {
3085		long	code;
3086		long	a1;
3087		long	a2;
3088		long	a3;
3089		long	a4;
3090		long	a5;
3091		long	a6;
3092		long	a7;
3093	} *uap = (struct a *)clwp->lwp_ap;
3094
3095	a1   = (uintptr_t)uap->a1;
3096	a2   = (uintptr_t)uap->a2;
3097
3098	switch (tad->tad_event) {
3099	case AUE_SETAUID:
3100		if (copyin((caddr_t)a1, &auid, sizeof (au_id_t)))
3101				return;
3102		au_uwrite(au_to_arg32(2, "setauid", auid));
3103		break;
3104	case AUE_SETAUDIT:
3105		STRUCT_INIT(ainfo, get_udatamodel());
3106		if (copyin((caddr_t)a1, STRUCT_BUF(ainfo),
3107		    STRUCT_SIZE(ainfo))) {
3108				return;
3109		}
3110		au_uwrite(au_to_arg32((char)1, "setaudit:auid",
3111		    (uint32_t)STRUCT_FGET(ainfo, ai_auid)));
3112#ifdef _LP64
3113		au_uwrite(au_to_arg64((char)1, "setaudit:port",
3114		    (uint64_t)STRUCT_FGET(ainfo, ai_termid.port)));
3115#else
3116		au_uwrite(au_to_arg32((char)1, "setaudit:port",
3117		    (uint32_t)STRUCT_FGET(ainfo, ai_termid.port)));
3118#endif
3119		au_uwrite(au_to_arg32((char)1, "setaudit:machine",
3120		    (uint32_t)STRUCT_FGET(ainfo, ai_termid.machine)));
3121		au_uwrite(au_to_arg32((char)1, "setaudit:as_success",
3122		    (uint32_t)STRUCT_FGET(ainfo, ai_mask.as_success)));
3123		au_uwrite(au_to_arg32((char)1, "setaudit:as_failure",
3124		    (uint32_t)STRUCT_FGET(ainfo, ai_mask.as_failure)));
3125		au_uwrite(au_to_arg32((char)1, "setaudit:asid",
3126		    (uint32_t)STRUCT_FGET(ainfo, ai_asid)));
3127		break;
3128	case AUE_SETAUDIT_ADDR:
3129		STRUCT_INIT(ainfo_addr, get_udatamodel());
3130		if (copyin((caddr_t)a1, STRUCT_BUF(ainfo_addr),
3131		    STRUCT_SIZE(ainfo_addr))) {
3132				return;
3133		}
3134		au_uwrite(au_to_arg32((char)1, "auid",
3135		    (uint32_t)STRUCT_FGET(ainfo_addr, ai_auid)));
3136#ifdef _LP64
3137		au_uwrite(au_to_arg64((char)1, "port",
3138		    (uint64_t)STRUCT_FGET(ainfo_addr, ai_termid.at_port)));
3139#else
3140		au_uwrite(au_to_arg32((char)1, "port",
3141		    (uint32_t)STRUCT_FGET(ainfo_addr, ai_termid.at_port)));
3142#endif
3143		au_uwrite(au_to_arg32((char)1, "type",
3144		    (uint32_t)STRUCT_FGET(ainfo_addr, ai_termid.at_type)));
3145		if ((uint32_t)STRUCT_FGET(ainfo_addr, ai_termid.at_type) ==
3146		    AU_IPv4) {
3147			au_uwrite(au_to_in_addr(
3148			    (struct in_addr *)STRUCT_FGETP(ainfo_addr,
3149			    ai_termid.at_addr)));
3150		} else {
3151			au_uwrite(au_to_in_addr_ex(
3152			    (int32_t *)STRUCT_FGETP(ainfo_addr,
3153			    ai_termid.at_addr)));
3154		}
3155		au_uwrite(au_to_arg32((char)1, "as_success",
3156		    (uint32_t)STRUCT_FGET(ainfo_addr, ai_mask.as_success)));
3157		au_uwrite(au_to_arg32((char)1, "as_failure",
3158		    (uint32_t)STRUCT_FGET(ainfo_addr, ai_mask.as_failure)));
3159		au_uwrite(au_to_arg32((char)1, "asid",
3160		    (uint32_t)STRUCT_FGET(ainfo_addr, ai_asid)));
3161		break;
3162	case AUE_AUDITON_SETAMASK:
3163		if (copyin((caddr_t)a2, &mask, sizeof (au_mask_t)))
3164				return;
3165		au_uwrite(au_to_arg32(
3166		    2, "setamask:as_success", (uint32_t)mask.as_success));
3167		au_uwrite(au_to_arg32(
3168		    2, "setamask:as_failure", (uint32_t)mask.as_failure));
3169		break;
3170	case AUE_AUDITON_SETKMASK:
3171		if (copyin((caddr_t)a2, &mask, sizeof (au_mask_t)))
3172				return;
3173		au_uwrite(au_to_arg32(
3174		    2, "setkmask:as_success", (uint32_t)mask.as_success));
3175		au_uwrite(au_to_arg32(
3176		    2, "setkmask:as_failure", (uint32_t)mask.as_failure));
3177		break;
3178	case AUE_AUDITON_SPOLICY:
3179		if (copyin((caddr_t)a2, &policy, sizeof (int)))
3180			return;
3181		au_uwrite(au_to_arg32(3, "setpolicy", (uint32_t)policy));
3182		break;
3183	case AUE_AUDITON_SQCTRL: {
3184		STRUCT_DECL(au_qctrl, qctrl);
3185		model_t model;
3186
3187		model = get_udatamodel();
3188		STRUCT_INIT(qctrl, model);
3189		if (copyin((caddr_t)a2, STRUCT_BUF(qctrl), STRUCT_SIZE(qctrl)))
3190				return;
3191		if (model == DATAMODEL_ILP32) {
3192			au_uwrite(au_to_arg32(
3193			    3, "setqctrl:aq_hiwater",
3194			    (uint32_t)STRUCT_FGET(qctrl, aq_hiwater)));
3195			au_uwrite(au_to_arg32(
3196			    3, "setqctrl:aq_lowater",
3197			    (uint32_t)STRUCT_FGET(qctrl, aq_lowater)));
3198			au_uwrite(au_to_arg32(
3199			    3, "setqctrl:aq_bufsz",
3200			    (uint32_t)STRUCT_FGET(qctrl, aq_bufsz)));
3201			au_uwrite(au_to_arg32(
3202			    3, "setqctrl:aq_delay",
3203			    (uint32_t)STRUCT_FGET(qctrl, aq_delay)));
3204		} else {
3205			au_uwrite(au_to_arg64(
3206			    3, "setqctrl:aq_hiwater",
3207			    (uint64_t)STRUCT_FGET(qctrl, aq_hiwater)));
3208			au_uwrite(au_to_arg64(
3209			    3, "setqctrl:aq_lowater",
3210			    (uint64_t)STRUCT_FGET(qctrl, aq_lowater)));
3211			au_uwrite(au_to_arg64(
3212			    3, "setqctrl:aq_bufsz",
3213			    (uint64_t)STRUCT_FGET(qctrl, aq_bufsz)));
3214			au_uwrite(au_to_arg64(
3215			    3, "setqctrl:aq_delay",
3216			    (uint64_t)STRUCT_FGET(qctrl, aq_delay)));
3217		}
3218		break;
3219	}
3220	case AUE_AUDITON_SETUMASK:
3221		STRUCT_INIT(ainfo, get_udatamodel());
3222		if (copyin((caddr_t)uap->a2, STRUCT_BUF(ainfo),
3223		    STRUCT_SIZE(ainfo))) {
3224			return;
3225		}
3226		au_uwrite(au_to_arg32(3, "setumask:as_success",
3227		    (uint32_t)STRUCT_FGET(ainfo, ai_mask.as_success)));
3228		au_uwrite(au_to_arg32(3, "setumask:as_failure",
3229		    (uint32_t)STRUCT_FGET(ainfo, ai_mask.as_failure)));
3230		break;
3231	case AUE_AUDITON_SETSMASK:
3232		STRUCT_INIT(ainfo, get_udatamodel());
3233		if (copyin((caddr_t)uap->a2, STRUCT_BUF(ainfo),
3234		    STRUCT_SIZE(ainfo))) {
3235			return;
3236		}
3237		au_uwrite(au_to_arg32(3, "setsmask:as_success",
3238		    (uint32_t)STRUCT_FGET(ainfo, ai_mask.as_success)));
3239		au_uwrite(au_to_arg32(3, "setsmask:as_failure",
3240		    (uint32_t)STRUCT_FGET(ainfo, ai_mask.as_failure)));
3241		break;
3242	case AUE_AUDITON_SETCOND:
3243		if (copyin((caddr_t)a2, &auditstate, sizeof (int)))
3244			return;
3245		au_uwrite(au_to_arg32(3, "setcond", (uint32_t)auditstate));
3246		break;
3247	case AUE_AUDITON_SETCLASS:
3248		if (copyin((caddr_t)a2, &event, sizeof (au_evclass_map_t)))
3249			return;
3250		au_uwrite(au_to_arg32(
3251		    2, "setclass:ec_event", (uint32_t)event.ec_number));
3252		au_uwrite(au_to_arg32(
3253		    3, "setclass:ec_class", (uint32_t)event.ec_class));
3254		break;
3255	case AUE_AUDITON_SETPMASK:
3256		STRUCT_INIT(apinfo, get_udatamodel());
3257		if (copyin((caddr_t)uap->a2, STRUCT_BUF(apinfo),
3258		    STRUCT_SIZE(apinfo))) {
3259			return;
3260		}
3261		au_uwrite(au_to_arg32(3, "setpmask:pid",
3262		    (uint32_t)STRUCT_FGET(apinfo, ap_pid)));
3263		au_uwrite(au_to_arg32(3, "setpmask:as_success",
3264		    (uint32_t)STRUCT_FGET(apinfo, ap_mask.as_success)));
3265		au_uwrite(au_to_arg32(3, "setpmask:as_failure",
3266		    (uint32_t)STRUCT_FGET(apinfo, ap_mask.as_failure)));
3267		break;
3268	case AUE_AUDITON_SETKAUDIT:
3269		STRUCT_INIT(ainfo_addr, get_udatamodel());
3270		if (copyin((caddr_t)a1, STRUCT_BUF(ainfo_addr),
3271		    STRUCT_SIZE(ainfo_addr))) {
3272				return;
3273		}
3274		au_uwrite(au_to_arg32((char)1, "auid",
3275		    (uint32_t)STRUCT_FGET(ainfo_addr, ai_auid)));
3276#ifdef _LP64
3277		au_uwrite(au_to_arg64((char)1, "port",
3278		    (uint64_t)STRUCT_FGET(ainfo_addr, ai_termid.at_port)));
3279#else
3280		au_uwrite(au_to_arg32((char)1, "port",
3281		    (uint32_t)STRUCT_FGET(ainfo_addr, ai_termid.at_port)));
3282#endif
3283		au_uwrite(au_to_arg32((char)1, "type",
3284		    (uint32_t)STRUCT_FGET(ainfo_addr, ai_termid.at_type)));
3285		if ((uint32_t)STRUCT_FGET(ainfo_addr, ai_termid.at_type) ==
3286		    AU_IPv4) {
3287			au_uwrite(au_to_in_addr(
3288			    (struct in_addr *)STRUCT_FGETP(ainfo_addr,
3289			    ai_termid.at_addr)));
3290		} else {
3291			au_uwrite(au_to_in_addr_ex(
3292			    (int32_t *)STRUCT_FGETP(ainfo_addr,
3293			    ai_termid.at_addr)));
3294		}
3295		au_uwrite(au_to_arg32((char)1, "as_success",
3296		    (uint32_t)STRUCT_FGET(ainfo_addr, ai_mask.as_success)));
3297		au_uwrite(au_to_arg32((char)1, "as_failure",
3298		    (uint32_t)STRUCT_FGET(ainfo_addr, ai_mask.as_failure)));
3299		au_uwrite(au_to_arg32((char)1, "asid",
3300		    (uint32_t)STRUCT_FGET(ainfo_addr, ai_asid)));
3301		break;
3302	case AUE_GETAUID:
3303	case AUE_GETAUDIT:
3304	case AUE_GETAUDIT_ADDR:
3305	case AUE_AUDIT:
3306	case AUE_AUDITON_GPOLICY:
3307	case AUE_AUDITON_GQCTRL:
3308	case AUE_AUDITON_GETAMASK:
3309	case AUE_AUDITON_GETKMASK:
3310	case AUE_AUDITON_GETCWD:
3311	case AUE_AUDITON_GETCAR:
3312	case AUE_AUDITON_GETSTAT:
3313	case AUE_AUDITON_SETSTAT:
3314	case AUE_AUDITON_GETCOND:
3315	case AUE_AUDITON_GETCLASS:
3316	case AUE_AUDITON_GETPINFO:
3317	case AUE_AUDITON_GETKAUDIT:
3318	case AUE_AUDITON_OTHER:
3319		break;
3320	default:
3321		break;
3322	}
3323
3324}	/* AUS_AUDITSYS */
3325
3326
3327/* only audit privileged operations for systeminfo(2) system call */
3328static au_event_t
3329aui_sysinfo(au_event_t e)
3330{
3331	klwp_t *clwp = ttolwp(curthread);
3332	uint32_t command;
3333
3334	struct a {
3335		long	command;
3336		long	buf;		/* char * */
3337		long	count;
3338	} *uap = (struct a *)clwp->lwp_ap;
3339
3340	command = (uint32_t)uap->command;
3341
3342	switch (command) {
3343	case SI_SET_HOSTNAME:
3344	case SI_SET_SRPC_DOMAIN:
3345		e = (au_event_t)AUE_SYSINFO;
3346		break;
3347	default:
3348		e = (au_event_t)AUE_NULL;
3349		break;
3350	}
3351	return (e);
3352}
3353
3354/*ARGSUSED*/
3355static void
3356aus_sysinfo(struct t_audit_data *tad)
3357{
3358	klwp_t *clwp = ttolwp(curthread);
3359	uint32_t command;
3360	size_t len, maxlen;
3361	char *name;
3362	uintptr_t buf;
3363
3364	struct a {
3365		long	command;
3366		long	buf;		/* char * */
3367		long	count;
3368	} *uap = (struct a *)clwp->lwp_ap;
3369
3370	command = (uint32_t)uap->command;
3371	buf = (uintptr_t)uap->buf;
3372
3373	au_uwrite(au_to_arg32(1, "cmd", command));
3374
3375	switch (command) {
3376	case SI_SET_HOSTNAME:
3377	{
3378		if (secpolicy_sys_config(CRED(), B_TRUE) != 0)
3379			return;
3380
3381		maxlen = SYS_NMLN;
3382		name = kmem_alloc(maxlen, KM_SLEEP);
3383		if (copyinstr((caddr_t)buf, name, SYS_NMLN, &len))
3384			break;
3385
3386		/*
3387		 * Must be non-NULL string and string
3388		 * must be less than SYS_NMLN chars.
3389		 */
3390		if (len < 2 || (len == SYS_NMLN && name[SYS_NMLN - 1] != '\0'))
3391			break;
3392
3393		au_uwrite(au_to_text(name));
3394		break;
3395	}
3396
3397	case SI_SET_SRPC_DOMAIN:
3398	{
3399		if (secpolicy_sys_config(CRED(), B_TRUE) != 0)
3400			return;
3401
3402		maxlen = SYS_NMLN;
3403		name = kmem_alloc(maxlen, KM_SLEEP);
3404		if (copyinstr((caddr_t)buf, name, SYS_NMLN, &len))
3405			break;
3406
3407		/*
3408		 * If string passed in is longer than length
3409		 * allowed for domain name, fail.
3410		 */
3411		if (len == SYS_NMLN && name[SYS_NMLN - 1] != '\0')
3412			break;
3413
3414		au_uwrite(au_to_text(name));
3415		break;
3416	}
3417
3418	default:
3419		return;
3420	}
3421
3422	kmem_free(name, maxlen);
3423}
3424
3425static au_event_t
3426aui_modctl(au_event_t e)
3427{
3428	klwp_t *clwp = ttolwp(curthread);
3429	uint_t cmd;
3430
3431	struct a {
3432		long	cmd;
3433	} *uap = (struct a *)clwp->lwp_ap;
3434
3435	cmd = (uint_t)uap->cmd;
3436
3437	switch (cmd) {
3438	case MODLOAD:
3439		e = AUE_MODLOAD;
3440		break;
3441	case MODUNLOAD:
3442		e = AUE_MODUNLOAD;
3443		break;
3444	case MODADDMAJBIND:
3445		e = AUE_MODADDMAJ;
3446		break;
3447	case MODSETDEVPOLICY:
3448		e = AUE_MODDEVPLCY;
3449		break;
3450	case MODALLOCPRIV:
3451		e = AUE_MODADDPRIV;
3452		break;
3453	default:
3454		e = AUE_NULL;
3455		break;
3456	}
3457	return (e);
3458}
3459
3460
3461/*ARGSUSED*/
3462static void
3463aus_modctl(struct t_audit_data *tad)
3464{
3465	klwp_t *clwp = ttolwp(curthread);
3466	void *a	= clwp->lwp_ap;
3467	uint_t use_path;
3468
3469	switch (tad->tad_event) {
3470	case AUE_MODLOAD: {
3471		typedef struct {
3472			long	cmd;
3473			long	use_path;
3474			long	filename;		/* char * */
3475		} modloada_t;
3476
3477		char *filenamep;
3478		uintptr_t fname;
3479		extern char *default_path;
3480
3481		fname = (uintptr_t)((modloada_t *)a)->filename;
3482		use_path = (uint_t)((modloada_t *)a)->use_path;
3483
3484			/* space to hold path */
3485		filenamep = kmem_alloc(MOD_MAXPATH, KM_SLEEP);
3486			/* get string */
3487		if (copyinstr((caddr_t)fname, filenamep, MOD_MAXPATH, 0)) {
3488				/* free allocated path */
3489			kmem_free(filenamep, MOD_MAXPATH);
3490			return;
3491		}
3492			/* ensure it's null terminated */
3493		filenamep[MOD_MAXPATH - 1] = 0;
3494
3495		if (use_path)
3496			au_uwrite(au_to_text(default_path));
3497		au_uwrite(au_to_text(filenamep));
3498
3499			/* release temporary memory */
3500		kmem_free(filenamep, MOD_MAXPATH);
3501		break;
3502	}
3503	case AUE_MODUNLOAD: {
3504		typedef struct {
3505			long	cmd;
3506			long	id;
3507		} modunloada_t;
3508
3509		uint32_t id = (uint32_t)((modunloada_t *)a)->id;
3510
3511		au_uwrite(au_to_arg32(1, "id", id));
3512		break;
3513	}
3514	case AUE_MODADDMAJ: {
3515		STRUCT_DECL(modconfig, mc);
3516		typedef struct {
3517			long	cmd;
3518			long	subcmd;
3519			long	data;		/* int * */
3520		} modconfiga_t;
3521
3522		STRUCT_DECL(aliases, alias);
3523		caddr_t ap;
3524		int i, num_aliases;
3525		char *drvname, *mc_drvname;
3526		char *name;
3527		extern char *ddi_major_to_name(major_t);
3528		model_t model;
3529
3530		uintptr_t data = (uintptr_t)((modconfiga_t *)a)->data;
3531
3532		model = get_udatamodel();
3533		STRUCT_INIT(mc, model);
3534			/* sanitize buffer */
3535		bzero((caddr_t)STRUCT_BUF(mc), STRUCT_SIZE(mc));
3536			/* get user arguments */
3537		if (copyin((caddr_t)data, (caddr_t)STRUCT_BUF(mc),
3538		    STRUCT_SIZE(mc)) != 0)
3539			return;
3540
3541		mc_drvname = STRUCT_FGET(mc, drvname);
3542		if ((drvname = ddi_major_to_name(
3543		    (major_t)STRUCT_FGET(mc, major))) != NULL &&
3544		    strncmp(drvname, mc_drvname, MAXMODCONFNAME) != 0) {
3545				/* safety */
3546			if (mc_drvname[0] != '\0') {
3547				mc_drvname[MAXMODCONFNAME-1] = '\0';
3548				au_uwrite(au_to_text(mc_drvname));
3549			}
3550				/* drvname != NULL from test above */
3551			au_uwrite(au_to_text(drvname));
3552			return;
3553		}
3554
3555		if (mc_drvname[0] != '\0') {
3556				/* safety */
3557			mc_drvname[MAXMODCONFNAME-1] = '\0';
3558			au_uwrite(au_to_text(mc_drvname));
3559		} else
3560			au_uwrite(au_to_text("no drvname"));
3561
3562		num_aliases = STRUCT_FGET(mc, num_aliases);
3563		au_uwrite(au_to_arg32(5, "", (uint32_t)num_aliases));
3564		ap = (caddr_t)STRUCT_FGETP(mc, ap);
3565		name = kmem_alloc(MAXMODCONFNAME, KM_SLEEP);
3566		STRUCT_INIT(alias, model);
3567		for (i = 0; i < num_aliases; i++) {
3568			bzero((caddr_t)STRUCT_BUF(alias),
3569			    STRUCT_SIZE(alias));
3570			if (copyin((caddr_t)ap, (caddr_t)STRUCT_BUF(alias),
3571			    STRUCT_SIZE(alias)) != 0)
3572				break;
3573			if (copyinstr(STRUCT_FGETP(alias, a_name), name,
3574			    MAXMODCONFNAME, NULL) != 0) {
3575				break;
3576			}
3577
3578			au_uwrite(au_to_text(name));
3579			ap = (caddr_t)STRUCT_FGETP(alias, a_next);
3580		}
3581		kmem_free(name, MAXMODCONFNAME);
3582		break;
3583	}
3584	default:
3585		break;
3586	}
3587}
3588
3589
3590/*ARGSUSED*/
3591static void
3592auf_accept(
3593	struct t_audit_data *tad,
3594	int	error,
3595	rval_t	*rval)
3596{
3597	uint32_t scid;
3598	uint32_t sy_flags;
3599	int fd;
3600	struct sonode *so;
3601	char so_laddr[sizeof (struct sockaddr_in6)];
3602	char so_faddr[sizeof (struct sockaddr_in6)];
3603	int err;
3604	short so_family, so_type;
3605	int add_sock_token = 0;
3606
3607	/* need to determine type of executing binary */
3608	scid = tad->tad_scid;
3609#ifdef _SYSCALL32_IMPL
3610	if (lwp_getdatamodel(ttolwp(curthread)) == DATAMODEL_NATIVE)
3611		sy_flags = sysent[scid].sy_flags & SE_RVAL_MASK;
3612	else
3613		sy_flags = sysent32[scid].sy_flags & SE_RVAL_MASK;
3614#else
3615	sy_flags = sysent[scid].sy_flags & SE_RVAL_MASK;
3616#endif
3617	switch (sy_flags) {
3618	case SE_32RVAL1:
3619		/* FALLTHRU */
3620	case SE_32RVAL2|SE_32RVAL1:
3621		fd = rval->r_val1;
3622		break;
3623	case SE_64RVAL:
3624		fd = (int)rval->r_vals;
3625		break;
3626	default:
3627		/*
3628		 * should never happen, seems to be an internal error
3629		 * in sysent => no fd, nothing to audit here, returning
3630		 */
3631		return;
3632	}
3633
3634	if (error) {
3635		/* can't trust socket contents. Just return */
3636		au_uwrite(au_to_arg32(1, "so", (uint32_t)fd));
3637		return;
3638	}
3639
3640	if ((so = getsonode(fd, &err, NULL)) == NULL) {
3641		/*
3642		 * not security relevant if doing a accept from non socket
3643		 * so no extra tokens. Should probably turn off audit record
3644		 * generation here.
3645		 */
3646		return;
3647	}
3648
3649	so_family = so->so_family;
3650	so_type   = so->so_type;
3651
3652	switch (so_family) {
3653	case AF_INET:
3654	case AF_INET6:
3655		/*
3656		 * XXX - what about other socket types for AF_INET (e.g. DGRAM)
3657		 */
3658		if (so->so_type == SOCK_STREAM) {
3659			socklen_t len;
3660
3661			bzero((void *)so_laddr, sizeof (so_laddr));
3662			bzero((void *)so_faddr, sizeof (so_faddr));
3663
3664			len = sizeof (so_laddr);
3665			(void) socket_getsockname(so,
3666			    (struct sockaddr *)so_laddr, &len, CRED());
3667			len = sizeof (so_faddr);
3668			(void) socket_getpeername(so,
3669			    (struct sockaddr *)so_faddr, &len, B_FALSE, CRED());
3670
3671			add_sock_token = 1;
3672		}
3673		break;
3674
3675	default:
3676		/* AF_UNIX, AF_ROUTE, AF_KEY do not support accept */
3677		break;
3678	}
3679
3680	releasef(fd);
3681
3682	au_uwrite(au_to_arg32(1, "so", (uint32_t)fd));
3683
3684	if (add_sock_token == 0) {
3685		au_uwrite(au_to_arg32(0, "family", (uint32_t)(so_family)));
3686		au_uwrite(au_to_arg32(0, "type", (uint32_t)(so_type)));
3687		return;
3688	}
3689
3690	au_uwrite(au_to_socket_ex(so_family, so_type, so_laddr, so_faddr));
3691
3692}
3693
3694/*ARGSUSED*/
3695static void
3696auf_bind(struct t_audit_data *tad, int error, rval_t *rvp)
3697{
3698	struct a {
3699		long	fd;
3700		long	addr;
3701		long	len;
3702	} *uap = (struct a *)ttolwp(curthread)->lwp_ap;
3703
3704	struct sonode *so;
3705	char so_laddr[sizeof (struct sockaddr_in6)];
3706	char so_faddr[sizeof (struct sockaddr_in6)];
3707	int err, fd;
3708	socklen_t len;
3709	short so_family, so_type;
3710	int add_sock_token = 0;
3711
3712	fd = (int)uap->fd;
3713
3714	/*
3715	 * bind failed, then nothing extra to add to audit record.
3716	 */
3717	if (error) {
3718		au_uwrite(au_to_arg32(1, "so", (uint32_t)fd));
3719		/* XXX may want to add failed address some day */
3720		return;
3721	}
3722
3723	if ((so = getsonode(fd, &err, NULL)) == NULL) {
3724		/*
3725		 * not security relevant if doing a bind from non socket
3726		 * so no extra tokens. Should probably turn off audit record
3727		 * generation here.
3728		 */
3729		return;
3730	}
3731
3732	so_family = so->so_family;
3733	so_type   = so->so_type;
3734
3735	switch (so_family) {
3736	case AF_INET:
3737	case AF_INET6:
3738
3739		bzero(so_faddr, sizeof (so_faddr));
3740		len = sizeof (so_faddr);
3741
3742		(void) socket_getpeername(so,
3743		    (struct sockaddr *)so_faddr, &len, B_FALSE, CRED());
3744		add_sock_token = 1;
3745
3746		break;
3747
3748	case AF_UNIX:
3749		/* token added by lookup */
3750		break;
3751	default:
3752		/* AF_ROUTE, AF_KEY do not support accept */
3753		break;
3754	}
3755
3756	releasef(fd);
3757
3758	au_uwrite(au_to_arg32(1, "so", (uint32_t)fd));
3759
3760	if (add_sock_token == 0) {
3761		au_uwrite(au_to_arg32(1, "family", (uint32_t)(so_family)));
3762		au_uwrite(au_to_arg32(1, "type", (uint32_t)(so_type)));
3763		return;
3764	}
3765
3766	au_uwrite(au_to_socket_ex(so_family, so_type, so_laddr, so_faddr));
3767
3768}
3769
3770/*ARGSUSED*/
3771static void
3772auf_connect(struct t_audit_data *tad, int error, rval_t *rval)
3773{
3774	struct a {
3775		long	fd;
3776		long	addr;
3777		long	len;
3778	} *uap = (struct a *)ttolwp(curthread)->lwp_ap;
3779
3780	struct sonode *so;
3781	char so_laddr[sizeof (struct sockaddr_in6)];
3782	char so_faddr[sizeof (struct sockaddr_in6)];
3783	int err, fd;
3784	socklen_t len;
3785	short so_family, so_type;
3786	int add_sock_token = 0;
3787
3788	fd = (int)uap->fd;
3789
3790
3791	if ((so = getsonode(fd, &err, NULL)) == NULL) {
3792		/*
3793		 * not security relevant if doing a connect from non socket
3794		 * so no extra tokens. Should probably turn off audit record
3795		 * generation here.
3796		 */
3797		return;
3798	}
3799
3800	so_family = so->so_family;
3801	so_type   = so->so_type;
3802
3803	switch (so_family) {
3804	case AF_INET:
3805	case AF_INET6:
3806
3807		bzero(so_laddr, sizeof (so_laddr));
3808		bzero(so_faddr, sizeof (so_faddr));
3809
3810		len = sizeof (so_laddr);
3811		(void) socket_getsockname(so, (struct sockaddr *)so_laddr,
3812		    &len, CRED());
3813		if (error) {
3814			if (uap->addr == 0)
3815				break;
3816			if (uap->len <= 0)
3817				break;
3818			len = min(uap->len, sizeof (so_faddr));
3819			if (copyin((caddr_t)(uap->addr), so_faddr, len) != 0)
3820				break;
3821#ifdef NOTYET
3822			au_uwrite(au_to_data(AUP_HEX, AUR_CHAR, len, so_faddr));
3823#endif
3824		} else {
3825			/* sanity check on length */
3826			len = sizeof (so_faddr);
3827			(void) socket_getpeername(so,
3828			    (struct sockaddr *)so_faddr, &len, B_FALSE, CRED());
3829		}
3830
3831		add_sock_token = 1;
3832
3833		break;
3834
3835	case AF_UNIX:
3836		/* does a lookup on name */
3837		break;
3838
3839	default:
3840		/* AF_ROUTE, AF_KEY do not support accept */
3841		break;
3842	}
3843
3844	releasef(fd);
3845
3846	au_uwrite(au_to_arg32(1, "so", (uint32_t)fd));
3847
3848	if (add_sock_token == 0) {
3849		au_uwrite(au_to_arg32(1, "family", (uint32_t)(so_family)));
3850		au_uwrite(au_to_arg32(1, "type", (uint32_t)(so_type)));
3851		return;
3852	}
3853
3854	au_uwrite(au_to_socket_ex(so_family, so_type, so_laddr, so_faddr));
3855
3856}
3857
3858/*ARGSUSED*/
3859static void
3860aus_shutdown(struct t_audit_data *tad)
3861{
3862	struct a {
3863		long	fd;
3864		long	how;
3865	} *uap = (struct a *)ttolwp(curthread)->lwp_ap;
3866
3867	struct sonode *so;
3868	char so_laddr[sizeof (struct sockaddr_in6)];
3869	char so_faddr[sizeof (struct sockaddr_in6)];
3870	int err, fd;
3871	socklen_t len;
3872	short so_family, so_type;
3873	int add_sock_token = 0;
3874	file_t *fp;				/* unix domain sockets */
3875	struct f_audit_data *fad;		/* unix domain sockets */
3876
3877	fd = (int)uap->fd;
3878
3879	if ((so = getsonode(fd, &err, &fp)) == NULL) {
3880		/*
3881		 * not security relevant if doing a shutdown using non socket
3882		 * so no extra tokens. Should probably turn off audit record
3883		 * generation here.
3884		 */
3885		return;
3886	}
3887
3888	so_family = so->so_family;
3889	so_type   = so->so_type;
3890
3891	switch (so_family) {
3892	case AF_INET:
3893	case AF_INET6:
3894
3895		bzero(so_laddr, sizeof (so_laddr));
3896		bzero(so_faddr, sizeof (so_faddr));
3897
3898		len = sizeof (so_laddr);
3899		(void) socket_getsockname(so,
3900		    (struct sockaddr *)so_laddr, &len, CRED());
3901		len = sizeof (so_faddr);
3902		(void) socket_getpeername(so,
3903		    (struct sockaddr *)so_faddr, &len, B_FALSE, CRED());
3904
3905		add_sock_token = 1;
3906
3907		break;
3908
3909	case AF_UNIX:
3910
3911		/* get path from file struct here */
3912		fad = F2A(fp);
3913		ASSERT(fad);
3914
3915		if (fad->fad_aupath != NULL) {
3916			au_uwrite(au_to_path(fad->fad_aupath));
3917		} else {
3918			au_uwrite(au_to_arg32(1, "no path: fd", fd));
3919		}
3920
3921		audit_attributes(fp->f_vnode);
3922
3923		break;
3924
3925	default:
3926		/*
3927		 * AF_KEY and AF_ROUTE support shutdown. No socket token
3928		 * added.
3929		 */
3930		break;
3931	}
3932
3933	releasef(fd);
3934
3935	au_uwrite(au_to_arg32(1, "so", (uint32_t)fd));
3936
3937	if (add_sock_token == 0) {
3938		au_uwrite(au_to_arg32(1, "family", (uint32_t)(so_family)));
3939		au_uwrite(au_to_arg32(1, "type", (uint32_t)(so_type)));
3940		au_uwrite(au_to_arg32(2, "how", (uint32_t)(uap->how)));
3941		return;
3942	}
3943
3944	au_uwrite(au_to_arg32(2, "how", (uint32_t)(uap->how)));
3945
3946	au_uwrite(au_to_socket_ex(so_family, so_type, so_laddr, so_faddr));
3947
3948}
3949
3950/*ARGSUSED*/
3951static void
3952auf_setsockopt(struct t_audit_data *tad, int error, rval_t *rval)
3953{
3954	struct a {
3955		long	fd;
3956		long	level;
3957		long	optname;
3958		long	*optval;
3959		long	optlen;
3960	} *uap = (struct a *)ttolwp(curthread)->lwp_ap;
3961
3962	struct sonode	*so;
3963	char so_laddr[sizeof (struct sockaddr_in6)];
3964	char so_faddr[sizeof (struct sockaddr_in6)];
3965	char		val[AU_BUFSIZE];
3966	int		err, fd;
3967	socklen_t	len;
3968	short so_family, so_type;
3969	int		add_sock_token = 0;
3970	file_t *fp;				/* unix domain sockets */
3971	struct f_audit_data *fad;		/* unix domain sockets */
3972
3973	fd = (int)uap->fd;
3974
3975	if (error) {
3976		au_uwrite(au_to_arg32(1, "so", (uint32_t)fd));
3977		au_uwrite(au_to_arg32(2, "level", (uint32_t)uap->level));
3978		/* XXX may want to include other arguments */
3979		return;
3980	}
3981
3982	if ((so = getsonode(fd, &err, &fp)) == NULL) {
3983		/*
3984		 * not security relevant if doing a setsockopt from non socket
3985		 * so no extra tokens. Should probably turn off audit record
3986		 * generation here.
3987		 */
3988		return;
3989	}
3990
3991	so_family = so->so_family;
3992	so_type   = so->so_type;
3993
3994	switch (so_family) {
3995	case AF_INET:
3996	case AF_INET6:
3997		bzero((void *)so_laddr, sizeof (so_laddr));
3998		bzero((void *)so_faddr, sizeof (so_faddr));
3999
4000		/* get local and foreign addresses */
4001		len = sizeof (so_laddr);
4002		(void) socket_getsockname(so, (struct sockaddr *)so_laddr,
4003		    &len, CRED());
4004		len = sizeof (so_faddr);
4005		(void) socket_getpeername(so, (struct sockaddr *)so_faddr,
4006		    &len, B_FALSE, CRED());
4007
4008		add_sock_token = 1;
4009
4010		break;
4011
4012	case AF_UNIX:
4013
4014		/* get path from file struct here */
4015		fad = F2A(fp);
4016		ASSERT(fad);
4017
4018		if (fad->fad_aupath != NULL) {
4019			au_uwrite(au_to_path(fad->fad_aupath));
4020		} else {
4021			au_uwrite(au_to_arg32(1, "no path: fd", fd));
4022		}
4023
4024		audit_attributes(fp->f_vnode);
4025
4026		break;
4027
4028	default:
4029		/*
4030		 * AF_KEY and AF_ROUTE support setsockopt. No socket token
4031		 * added.
4032		 */
4033		break;
4034	}
4035
4036	releasef(fd);
4037
4038	au_uwrite(au_to_arg32(1, "so", (uint32_t)fd));
4039
4040	if (add_sock_token == 0) {
4041		au_uwrite(au_to_arg32(1, "family", (uint32_t)(so_family)));
4042		au_uwrite(au_to_arg32(1, "type", (uint32_t)(so_type)));
4043	}
4044	au_uwrite(au_to_arg32(2, "level", (uint32_t)(uap->level)));
4045	au_uwrite(au_to_arg32(3, "optname", (uint32_t)(uap->optname)));
4046
4047	bzero(val, sizeof (val));
4048	len = min(uap->optlen, sizeof (val));
4049	if ((len > 0) &&
4050	    (copyin((caddr_t)(uap->optval), (caddr_t)val, len) == 0)) {
4051		au_uwrite(au_to_arg32(5, "optlen", (uint32_t)(uap->optlen)));
4052		au_uwrite(au_to_data(AUP_HEX, AUR_BYTE, len, val));
4053	}
4054
4055	if (add_sock_token == 0)
4056		return;
4057
4058	au_uwrite(au_to_socket_ex(so_family, so_type, so_laddr, so_faddr));
4059
4060}
4061
4062/*ARGSUSED*/
4063static void
4064aus_sockconfig(struct t_audit_data *tad)
4065{
4066	struct a {
4067		long	cmd;
4068		long	arg1;
4069		long	arg2;
4070		long	arg3;
4071		long	arg4;
4072	} *uap = (struct a *)ttolwp(curthread)->lwp_ap;
4073
4074	char	*buf;
4075	int	buflen;
4076	size_t	size;
4077
4078	au_uwrite(au_to_arg32(1, "cmd", (uint_t)uap->cmd));
4079	switch (uap->cmd) {
4080	case SOCKCONFIG_ADD_SOCK:
4081	case SOCKCONFIG_REMOVE_SOCK:
4082		au_uwrite(au_to_arg32(2, "domain", (uint32_t)uap->arg1));
4083		au_uwrite(au_to_arg32(3, "type", (uint32_t)uap->arg2));
4084		au_uwrite(au_to_arg32(4, "protocol", (uint32_t)uap->arg3));
4085
4086		if (uap->arg4 == 0) {
4087			au_uwrite(au_to_arg32(5, "devpath", (uint32_t)0));
4088		} else {
4089			buflen = MAXPATHLEN + 1;
4090			buf = kmem_alloc(buflen, KM_SLEEP);
4091			if (copyinstr((caddr_t)uap->arg4, buf, buflen,
4092			    &size)) {
4093				kmem_free(buf, buflen);
4094				return;
4095			}
4096
4097			if (size > MAXPATHLEN) {
4098				kmem_free(buf, buflen);
4099				return;
4100			}
4101
4102			au_uwrite(au_to_text(buf));
4103			kmem_free(buf, buflen);
4104		}
4105		break;
4106	case SOCKCONFIG_ADD_FILTER:
4107	case SOCKCONFIG_REMOVE_FILTER:
4108		buflen = FILNAME_MAX;
4109		buf = kmem_alloc(buflen, KM_SLEEP);
4110
4111		if (copyinstr((caddr_t)uap->arg1, buf, buflen, &size)) {
4112			kmem_free(buf, buflen);
4113			return;
4114		}
4115
4116		au_uwrite(au_to_text(buf));
4117		kmem_free(buf, buflen);
4118		break;
4119	default:
4120		break;
4121	}
4122}
4123
4124/*
4125 * only audit recvmsg when the system call represents the creation of a new
4126 * circuit. This effectively occurs for all UDP packets and may occur for
4127 * special TCP situations where the local host has not set a local address
4128 * in the socket structure.
4129 */
4130/*ARGSUSED*/
4131static void
4132auf_recvmsg(
4133	struct t_audit_data *tad,
4134	int error,
4135	rval_t *rvp)
4136{
4137	struct a {
4138		long	fd;
4139		long	msg;	/* struct msghdr */
4140		long	flags;
4141	} *uap = (struct a *)ttolwp(curthread)->lwp_ap;
4142
4143	struct sonode	*so;
4144	STRUCT_DECL(msghdr, msg);
4145	caddr_t msg_name;
4146	socklen_t msg_namelen;
4147	int fd;
4148	int err;
4149	char so_laddr[sizeof (struct sockaddr_in6)];
4150	char so_faddr[sizeof (struct sockaddr_in6)];
4151	socklen_t len;
4152	file_t *fp;				/* unix domain sockets */
4153	struct f_audit_data *fad;		/* unix domain sockets */
4154	short so_family, so_type;
4155	int add_sock_token = 0;
4156	au_kcontext_t	*kctx = GET_KCTX_PZ;
4157
4158	fd = (int)uap->fd;
4159
4160	/* bail if an error */
4161	if (error) {
4162		au_uwrite(au_to_arg32(1, "so", (uint32_t)fd));
4163		au_uwrite(au_to_arg32(3, "flags", (uint32_t)(uap->flags)));
4164		return;
4165	}
4166
4167	if ((so = getsonode(fd, &err, &fp)) == NULL) {
4168		/*
4169		 * not security relevant if doing a recvmsg from non socket
4170		 * so no extra tokens. Should probably turn off audit record
4171		 * generation here.
4172		 */
4173		return;
4174	}
4175
4176	so_family = so->so_family;
4177	so_type   = so->so_type;
4178
4179	/*
4180	 * only putout SOCKET_EX token if INET/INET6 family.
4181	 * XXX - what do we do about other families?
4182	 */
4183
4184	switch (so_family) {
4185	case AF_INET:
4186	case AF_INET6:
4187
4188		/*
4189		 * if datagram type socket, then just use what is in
4190		 * socket structure for local address.
4191		 * XXX - what do we do for other types?
4192		 */
4193		if ((so->so_type == SOCK_DGRAM) ||
4194		    (so->so_type == SOCK_RAW)) {
4195			add_sock_token = 1;
4196
4197			bzero((void *)so_laddr, sizeof (so_laddr));
4198			bzero((void *)so_faddr, sizeof (so_faddr));
4199
4200			/* get local address */
4201			len = sizeof (so_laddr);
4202			(void) socket_getsockname(so,
4203			    (struct sockaddr *)so_laddr, &len, CRED());
4204
4205			/* get peer address */
4206			STRUCT_INIT(msg, get_udatamodel());
4207
4208			if (copyin((caddr_t)(uap->msg),
4209			    (caddr_t)STRUCT_BUF(msg), STRUCT_SIZE(msg)) != 0) {
4210				break;
4211			}
4212			msg_name = (caddr_t)STRUCT_FGETP(msg, msg_name);
4213			if (msg_name == NULL) {
4214				break;
4215			}
4216
4217			/* length is value from recvmsg - sanity check */
4218			msg_namelen = (socklen_t)STRUCT_FGET(msg, msg_namelen);
4219			if (msg_namelen == 0) {
4220				break;
4221			}
4222			if (copyin(msg_name, so_faddr,
4223			    sizeof (so_faddr)) != 0) {
4224				break;
4225			}
4226
4227		} else if (so->so_type == SOCK_STREAM) {
4228
4229			/* get path from file struct here */
4230			fad = F2A(fp);
4231			ASSERT(fad);
4232
4233			/*
4234			 * already processed this file for read attempt
4235			 */
4236			if (fad->fad_flags & FAD_READ) {
4237				/* don't want to audit every recvmsg attempt */
4238				tad->tad_flag = 0;
4239				/* free any residual audit data */
4240				au_close(kctx, &(u_ad), 0, 0, 0, NULL);
4241				releasef(fd);
4242				return;
4243			}
4244			/*
4245			 * mark things so we know what happened and don't
4246			 * repeat things
4247			 */
4248			fad->fad_flags |= FAD_READ;
4249
4250			bzero((void *)so_laddr, sizeof (so_laddr));
4251			bzero((void *)so_faddr, sizeof (so_faddr));
4252
4253			/* get local and foreign addresses */
4254			len = sizeof (so_laddr);
4255			(void) socket_getsockname(so,
4256			    (struct sockaddr *)so_laddr, &len, CRED());
4257			len = sizeof (so_faddr);
4258			(void) socket_getpeername(so,
4259			    (struct sockaddr *)so_faddr, &len, B_FALSE, CRED());
4260
4261			add_sock_token = 1;
4262		}
4263
4264		/* XXX - what about SOCK_RDM/SOCK_SEQPACKET ??? */
4265
4266		break;
4267
4268	case AF_UNIX:
4269		/*
4270		 * first check if this is first time through. Too much
4271		 * duplicate code to put this in an aui_ routine.
4272		 */
4273
4274		/* get path from file struct here */
4275		fad = F2A(fp);
4276		ASSERT(fad);
4277
4278		/*
4279		 * already processed this file for read attempt
4280		 */
4281		if (fad->fad_flags & FAD_READ) {
4282			releasef(fd);
4283			/* don't want to audit every recvmsg attempt */
4284			tad->tad_flag = 0;
4285			/* free any residual audit data */
4286			au_close(kctx, &(u_ad), 0, 0, 0, NULL);
4287			return;
4288		}
4289		/*
4290		 * mark things so we know what happened and don't
4291		 * repeat things
4292		 */
4293		fad->fad_flags |= FAD_READ;
4294
4295		if (fad->fad_aupath != NULL) {
4296			au_uwrite(au_to_path(fad->fad_aupath));
4297		} else {
4298			au_uwrite(au_to_arg32(1, "no path: fd", fd));
4299		}
4300
4301		audit_attributes(fp->f_vnode);
4302
4303		releasef(fd);
4304
4305		return;
4306
4307	default:
4308		break;
4309
4310	}
4311
4312	releasef(fd);
4313
4314	au_uwrite(au_to_arg32(1, "so", (uint32_t)fd));
4315
4316	if (add_sock_token == 0) {
4317		au_uwrite(au_to_arg32(1, "family", (uint32_t)so_family));
4318		au_uwrite(au_to_arg32(1, "type", (uint32_t)so_type));
4319		au_uwrite(au_to_arg32(3, "flags", (uint32_t)(uap->flags)));
4320		return;
4321	}
4322
4323	au_uwrite(au_to_arg32(3, "flags", (uint32_t)(uap->flags)));
4324
4325	au_uwrite(au_to_socket_ex(so_family, so_type, so_laddr, so_faddr));
4326
4327}
4328
4329/*ARGSUSED*/
4330static void
4331auf_recvfrom(
4332	struct t_audit_data *tad,
4333	int error,
4334	rval_t *rvp)
4335{
4336
4337	struct a {
4338		long	fd;
4339		long	msg;	/* char */
4340		long	len;
4341		long	flags;
4342		long	from;	/* struct sockaddr */
4343		long	fromlen;
4344	} *uap = (struct a *)ttolwp(curthread)->lwp_ap;
4345
4346	socklen_t	fromlen;
4347	struct sonode	*so;
4348	char so_laddr[sizeof (struct sockaddr_in6)];
4349	char so_faddr[sizeof (struct sockaddr_in6)];
4350	int		fd;
4351	short so_family, so_type;
4352	int add_sock_token = 0;
4353	socklen_t len;
4354	int err;
4355	struct file *fp;
4356	struct f_audit_data *fad;		/* unix domain sockets */
4357	au_kcontext_t	*kctx = GET_KCTX_PZ;
4358
4359	fd = (int)uap->fd;
4360
4361	/* bail if an error */
4362	if (error) {
4363		au_uwrite(au_to_arg32(1, "so", (uint32_t)fd));
4364		au_uwrite(au_to_arg32(3, "flags", (uint32_t)(uap->flags)));
4365		return;
4366	}
4367
4368	if ((so = getsonode(fd, &err, &fp)) == NULL) {
4369		/*
4370		 * not security relevant if doing a recvmsg from non socket
4371		 * so no extra tokens. Should probably turn off audit record
4372		 * generation here.
4373		 */
4374		return;
4375	}
4376
4377	so_family = so->so_family;
4378	so_type   = so->so_type;
4379
4380	/*
4381	 * only putout SOCKET_EX token if INET/INET6 family.
4382	 * XXX - what do we do about other families?
4383	 */
4384
4385	switch (so_family) {
4386	case AF_INET:
4387	case AF_INET6:
4388
4389		/*
4390		 * if datagram type socket, then just use what is in
4391		 * socket structure for local address.
4392		 * XXX - what do we do for other types?
4393		 */
4394		if ((so->so_type == SOCK_DGRAM) ||
4395		    (so->so_type == SOCK_RAW)) {
4396			add_sock_token = 1;
4397
4398			/* get local address */
4399			len = sizeof (so_laddr);
4400			(void) socket_getsockname(so,
4401			    (struct sockaddr *)so_laddr, &len, CRED());
4402
4403			/* get peer address */
4404			bzero((void *)so_faddr, sizeof (so_faddr));
4405
4406			/* sanity check */
4407			if (uap->from == 0)
4408				break;
4409
4410			/* sanity checks */
4411			if (uap->fromlen == 0)
4412				break;
4413
4414			if (copyin((caddr_t)(uap->fromlen), (caddr_t)&fromlen,
4415			    sizeof (fromlen)) != 0)
4416				break;
4417
4418			if (fromlen == 0)
4419				break;
4420
4421			/* enforce maximum size */
4422			if (fromlen > sizeof (so_faddr))
4423				fromlen = sizeof (so_faddr);
4424
4425			if (copyin((caddr_t)(uap->from), so_faddr,
4426			    fromlen) != 0)
4427				break;
4428
4429		} else if (so->so_type == SOCK_STREAM) {
4430
4431			/* get path from file struct here */
4432			fad = F2A(fp);
4433			ASSERT(fad);
4434
4435			/*
4436			 * already processed this file for read attempt
4437			 */
4438			if (fad->fad_flags & FAD_READ) {
4439				/* don't want to audit every recvfrom attempt */
4440				tad->tad_flag = 0;
4441				/* free any residual audit data */
4442				au_close(kctx, &(u_ad), 0, 0, 0, NULL);
4443				releasef(fd);
4444				return;
4445			}
4446			/*
4447			 * mark things so we know what happened and don't
4448			 * repeat things
4449			 */
4450			fad->fad_flags |= FAD_READ;
4451
4452			bzero((void *)so_laddr, sizeof (so_laddr));
4453			bzero((void *)so_faddr, sizeof (so_faddr));
4454
4455			/* get local and foreign addresses */
4456			len = sizeof (so_laddr);
4457			(void) socket_getsockname(so,
4458			    (struct sockaddr *)so_laddr, &len, CRED());
4459			len = sizeof (so_faddr);
4460			(void) socket_getpeername(so,
4461			    (struct sockaddr *)so_faddr, &len, B_FALSE, CRED());
4462
4463			add_sock_token = 1;
4464		}
4465
4466		/* XXX - what about SOCK_RDM/SOCK_SEQPACKET ??? */
4467
4468		break;
4469
4470	case AF_UNIX:
4471		/*
4472		 * first check if this is first time through. Too much
4473		 * duplicate code to put this in an aui_ routine.
4474		 */
4475
4476		/* get path from file struct here */
4477		fad = F2A(fp);
4478		ASSERT(fad);
4479
4480		/*
4481		 * already processed this file for read attempt
4482		 */
4483		if (fad->fad_flags & FAD_READ) {
4484			/* don't want to audit every recvfrom attempt */
4485			tad->tad_flag = 0;
4486			/* free any residual audit data */
4487			au_close(kctx, &(u_ad), 0, 0, 0, NULL);
4488			releasef(fd);
4489			return;
4490		}
4491		/*
4492		 * mark things so we know what happened and don't
4493		 * repeat things
4494		 */
4495		fad->fad_flags |= FAD_READ;
4496
4497		if (fad->fad_aupath != NULL) {
4498			au_uwrite(au_to_path(fad->fad_aupath));
4499		} else {
4500			au_uwrite(au_to_arg32(1, "no path: fd", fd));
4501		}
4502
4503		audit_attributes(fp->f_vnode);
4504
4505		releasef(fd);
4506
4507		return;
4508
4509	default:
4510		break;
4511
4512	}
4513
4514	releasef(fd);
4515
4516	au_uwrite(au_to_arg32(1, "so", (uint32_t)fd));
4517
4518	if (add_sock_token == 0) {
4519		au_uwrite(au_to_arg32(1, "family", (uint32_t)so_family));
4520		au_uwrite(au_to_arg32(1, "type", (uint32_t)so_type));
4521		au_uwrite(au_to_arg32(3, "flags", (uint32_t)(uap->flags)));
4522		return;
4523	}
4524
4525	au_uwrite(au_to_arg32(3, "flags", (uint32_t)(uap->flags)));
4526
4527	au_uwrite(au_to_socket_ex(so_family, so_type, so_laddr, so_faddr));
4528}
4529
4530/*ARGSUSED*/
4531static void
4532auf_sendmsg(struct t_audit_data *tad, int error, rval_t *rval)
4533{
4534	struct a {
4535		long	fd;
4536		long	msg;	/* struct msghdr */
4537		long	flags;
4538	} *uap = (struct a *)ttolwp(curthread)->lwp_ap;
4539
4540	struct sonode	*so;
4541	char so_laddr[sizeof (struct sockaddr_in6)];
4542	char so_faddr[sizeof (struct sockaddr_in6)];
4543	int		err;
4544	int		fd;
4545	short so_family, so_type;
4546	int		add_sock_token = 0;
4547	socklen_t	len;
4548	struct file	*fp;
4549	struct f_audit_data *fad;
4550	caddr_t		msg_name;
4551	socklen_t	msg_namelen;
4552	STRUCT_DECL(msghdr, msg);
4553	au_kcontext_t	*kctx = GET_KCTX_PZ;
4554
4555	fd = (int)uap->fd;
4556
4557	/* bail if an error */
4558	if (error) {
4559		/* XXX include destination address from system call arguments */
4560		au_uwrite(au_to_arg32(1, "so", (uint32_t)fd));
4561		au_uwrite(au_to_arg32(3, "flags", (uint32_t)(uap->flags)));
4562		return;
4563	}
4564
4565	if ((so = getsonode(fd, &err, &fp)) == NULL) {
4566		/*
4567		 * not security relevant if doing a sendmsg from non socket
4568		 * so no extra tokens. Should probably turn off audit record
4569		 * generation here.
4570		 */
4571		return;
4572	}
4573
4574	so_family = so->so_family;
4575	so_type   = so->so_type;
4576
4577	switch (so_family) {
4578	case AF_INET:
4579	case AF_INET6:
4580		/*
4581		 * if datagram type socket, then just use what is in
4582		 * socket structure for local address.
4583		 * XXX - what do we do for other types?
4584		 */
4585		if ((so->so_type == SOCK_DGRAM) ||
4586		    (so->so_type == SOCK_RAW)) {
4587
4588			bzero((void *)so_laddr, sizeof (so_laddr));
4589			bzero((void *)so_faddr, sizeof (so_faddr));
4590
4591			/* get local address */
4592			len = sizeof (so_laddr);
4593			(void) socket_getsockname(so,
4594			    (struct sockaddr *)so_laddr, &len, CRED());
4595
4596			/* get peer address */
4597			STRUCT_INIT(msg, get_udatamodel());
4598
4599			if (copyin((caddr_t)(uap->msg),
4600			    (caddr_t)STRUCT_BUF(msg), STRUCT_SIZE(msg)) != 0) {
4601				break;
4602			}
4603			msg_name = (caddr_t)STRUCT_FGETP(msg, msg_name);
4604			if (msg_name == NULL)
4605				break;
4606
4607			msg_namelen = (socklen_t)STRUCT_FGET(msg, msg_namelen);
4608			/* length is value from recvmsg - sanity check */
4609			if (msg_namelen == 0)
4610				break;
4611
4612			if (copyin(msg_name, so_faddr,
4613			    sizeof (so_faddr)) != 0)
4614				break;
4615
4616			add_sock_token = 1;
4617
4618		} else if (so->so_type == SOCK_STREAM) {
4619
4620			/* get path from file struct here */
4621			fad = F2A(fp);
4622			ASSERT(fad);
4623
4624			/*
4625			 * already processed this file for write attempt
4626			 */
4627			if (fad->fad_flags & FAD_WRITE) {
4628				releasef(fd);
4629				/* don't want to audit every sendmsg attempt */
4630				tad->tad_flag = 0;
4631				/* free any residual audit data */
4632				au_close(kctx, &(u_ad), 0, 0, 0, NULL);
4633				return;
4634			}
4635
4636			/*
4637			 * mark things so we know what happened and don't
4638			 * repeat things
4639			 */
4640			fad->fad_flags |= FAD_WRITE;
4641
4642			bzero((void *)so_laddr, sizeof (so_laddr));
4643			bzero((void *)so_faddr, sizeof (so_faddr));
4644
4645			/* get local and foreign addresses */
4646			len = sizeof (so_laddr);
4647			(void) socket_getsockname(so,
4648			    (struct sockaddr *)so_laddr, &len, CRED());
4649			len = sizeof (so_faddr);
4650			(void) socket_getpeername(so,
4651			    (struct sockaddr *)so_faddr, &len, B_FALSE, CRED());
4652
4653			add_sock_token = 1;
4654		}
4655
4656		/* XXX - what about SOCK_RAW/SOCK_RDM/SOCK_SEQPACKET ??? */
4657
4658		break;
4659
4660	case AF_UNIX:
4661		/*
4662		 * first check if this is first time through. Too much
4663		 * duplicate code to put this in an aui_ routine.
4664		 */
4665
4666		/* get path from file struct here */
4667		fad = F2A(fp);
4668		ASSERT(fad);
4669
4670		/*
4671		 * already processed this file for write attempt
4672		 */
4673		if (fad->fad_flags & FAD_WRITE) {
4674			releasef(fd);
4675			/* don't want to audit every sendmsg attempt */
4676			tad->tad_flag = 0;
4677			/* free any residual audit data */
4678			au_close(kctx, &(u_ad), 0, 0, 0, NULL);
4679			return;
4680		}
4681		/*
4682		 * mark things so we know what happened and don't
4683		 * repeat things
4684		 */
4685		fad->fad_flags |= FAD_WRITE;
4686
4687		if (fad->fad_aupath != NULL) {
4688			au_uwrite(au_to_path(fad->fad_aupath));
4689		} else {
4690			au_uwrite(au_to_arg32(1, "no path: fd", fd));
4691		}
4692
4693		audit_attributes(fp->f_vnode);
4694
4695		releasef(fd);
4696
4697		return;
4698
4699	default:
4700		break;
4701	}
4702
4703	releasef(fd);
4704
4705	au_uwrite(au_to_arg32(1, "so", (uint32_t)fd));
4706
4707	if (add_sock_token == 0) {
4708		au_uwrite(au_to_arg32(1, "family", (uint32_t)so_family));
4709		au_uwrite(au_to_arg32(1, "type", (uint32_t)so_type));
4710		au_uwrite(au_to_arg32(3, "flags", (uint32_t)(uap->flags)));
4711		return;
4712	}
4713
4714	au_uwrite(au_to_arg32(3, "flags", (uint32_t)(uap->flags)));
4715
4716	au_uwrite(au_to_socket_ex(so_family, so_type, so_laddr, so_faddr));
4717}
4718
4719/*ARGSUSED*/
4720static void
4721auf_sendto(struct t_audit_data *tad, int error, rval_t *rval)
4722{
4723	struct a {
4724		long	fd;
4725		long	msg;	/* char */
4726		long	len;
4727		long	flags;
4728		long	to;	/* struct sockaddr */
4729		long	tolen;
4730	} *uap = (struct a *)ttolwp(curthread)->lwp_ap;
4731
4732	struct sonode	*so;
4733	char so_laddr[sizeof (struct sockaddr_in6)];
4734	char so_faddr[sizeof (struct sockaddr_in6)];
4735	socklen_t	tolen;
4736	int		err;
4737	int		fd;
4738	socklen_t	len;
4739	short so_family, so_type;
4740	int		add_sock_token = 0;
4741	struct file	*fp;
4742	struct f_audit_data *fad;
4743	au_kcontext_t	*kctx = GET_KCTX_PZ;
4744
4745	fd = (int)uap->fd;
4746
4747	/* bail if an error */
4748	if (error) {
4749		au_uwrite(au_to_arg32(1, "so", (uint32_t)fd));
4750		au_uwrite(au_to_arg32(3, "flags", (uint32_t)(uap->flags)));
4751		/* XXX include destination address from system call arguments */
4752		return;
4753	}
4754
4755	if ((so = getsonode(fd, &err, &fp)) == NULL) {
4756		/*
4757		 * not security relevant if doing a sendto using non socket
4758		 * so no extra tokens. Should probably turn off audit record
4759		 * generation here.
4760		 */
4761		return;
4762	}
4763
4764	so_family = so->so_family;
4765	so_type   = so->so_type;
4766
4767	/*
4768	 * only putout SOCKET_EX token if INET/INET6 family.
4769	 * XXX - what do we do about other families?
4770	 */
4771
4772	switch (so_family) {
4773	case AF_INET:
4774	case AF_INET6:
4775
4776		/*
4777		 * if datagram type socket, then just use what is in
4778		 * socket structure for local address.
4779		 * XXX - what do we do for other types?
4780		 */
4781		if ((so->so_type == SOCK_DGRAM) ||
4782		    (so->so_type == SOCK_RAW)) {
4783
4784			bzero((void *)so_laddr, sizeof (so_laddr));
4785			bzero((void *)so_faddr, sizeof (so_faddr));
4786
4787			/* get local address */
4788			len = sizeof (so_laddr);
4789			(void) socket_getsockname(so,
4790			    (struct sockaddr *)so_laddr, &len, CRED());
4791
4792			/* get peer address */
4793
4794			/* sanity check */
4795			if (uap->to == 0)
4796				break;
4797
4798			/* sanity checks */
4799			if (uap->tolen == 0)
4800				break;
4801
4802			tolen = (socklen_t)uap->tolen;
4803
4804			/* enforce maximum size */
4805			if (tolen > sizeof (so_faddr))
4806				tolen = sizeof (so_faddr);
4807
4808			if (copyin((caddr_t)(uap->to), so_faddr, tolen) != 0)
4809				break;
4810
4811			add_sock_token = 1;
4812		} else {
4813			/*
4814			 * check if this is first time through.
4815			 */
4816
4817			/* get path from file struct here */
4818			fad = F2A(fp);
4819			ASSERT(fad);
4820
4821			/*
4822			 * already processed this file for write attempt
4823			 */
4824			if (fad->fad_flags & FAD_WRITE) {
4825				/* don't want to audit every sendto attempt */
4826				tad->tad_flag = 0;
4827				/* free any residual audit data */
4828				au_close(kctx, &(u_ad), 0, 0, 0, NULL);
4829				releasef(fd);
4830				return;
4831			}
4832			/*
4833			 * mark things so we know what happened and don't
4834			 * repeat things
4835			 */
4836			fad->fad_flags |= FAD_WRITE;
4837
4838			bzero((void *)so_laddr, sizeof (so_laddr));
4839			bzero((void *)so_faddr, sizeof (so_faddr));
4840
4841			/* get local and foreign addresses */
4842			len = sizeof (so_laddr);
4843			(void) socket_getsockname(so,
4844			    (struct sockaddr *)so_laddr, &len, CRED());
4845			len = sizeof (so_faddr);
4846			(void) socket_getpeername(so,
4847			    (struct sockaddr *)so_faddr, &len, B_FALSE, CRED());
4848
4849			add_sock_token = 1;
4850		}
4851
4852		/* XXX - what about SOCK_RDM/SOCK_SEQPACKET ??? */
4853
4854		break;
4855
4856	case AF_UNIX:
4857		/*
4858		 * first check if this is first time through. Too much
4859		 * duplicate code to put this in an aui_ routine.
4860		 */
4861
4862		/* get path from file struct here */
4863		fad = F2A(fp);
4864		ASSERT(fad);
4865
4866		/*
4867		 * already processed this file for write attempt
4868		 */
4869		if (fad->fad_flags & FAD_WRITE) {
4870			/* don't want to audit every sendto attempt */
4871			tad->tad_flag = 0;
4872			/* free any residual audit data */
4873			au_close(kctx, &(u_ad), 0, 0, 0, NULL);
4874			releasef(fd);
4875			return;
4876		}
4877		/*
4878		 * mark things so we know what happened and don't
4879		 * repeat things
4880		 */
4881		fad->fad_flags |= FAD_WRITE;
4882
4883		if (fad->fad_aupath != NULL) {
4884			au_uwrite(au_to_path(fad->fad_aupath));
4885		} else {
4886			au_uwrite(au_to_arg32(1, "no path: fd", fd));
4887		}
4888
4889		audit_attributes(fp->f_vnode);
4890
4891		releasef(fd);
4892
4893		return;
4894
4895	default:
4896		break;
4897
4898	}
4899
4900	releasef(fd);
4901
4902	au_uwrite(au_to_arg32(1, "so", (uint32_t)fd));
4903
4904	if (add_sock_token == 0) {
4905		au_uwrite(au_to_arg32(1, "family", (uint32_t)so_family));
4906		au_uwrite(au_to_arg32(1, "type", (uint32_t)so_type));
4907		au_uwrite(au_to_arg32(3, "flags", (uint32_t)(uap->flags)));
4908		return;
4909	}
4910
4911	au_uwrite(au_to_arg32(3, "flags", (uint32_t)(uap->flags)));
4912
4913	au_uwrite(au_to_socket_ex(so_family, so_type, so_laddr, so_faddr));
4914
4915}
4916
4917/*
4918 * XXX socket(2) may be equivalent to open(2) on a unix domain
4919 * socket. This needs investigation.
4920 */
4921
4922/*ARGSUSED*/
4923static void
4924aus_socket(struct t_audit_data *tad)
4925{
4926	struct a {
4927		long	domain;
4928		long	type;
4929		long	protocol;
4930	} *uap = (struct a *)ttolwp(curthread)->lwp_ap;
4931
4932	au_uwrite(au_to_arg32(1, "domain", (uint32_t)uap->domain));
4933	au_uwrite(au_to_arg32(2, "type", (uint32_t)uap->type));
4934	au_uwrite(au_to_arg32(3, "protocol", (uint32_t)uap->protocol));
4935}
4936
4937/*ARGSUSED*/
4938static void
4939aus_sigqueue(struct t_audit_data *tad)
4940{
4941	struct a {
4942		long	pid;
4943		long	signo;
4944		long	*val;
4945	} *uap = (struct a *)ttolwp(curthread)->lwp_ap;
4946	struct proc *p;
4947	uid_t uid, ruid;
4948	gid_t gid, rgid;
4949	pid_t pid;
4950	const auditinfo_addr_t *ainfo;
4951	cred_t *cr;
4952
4953	pid = (pid_t)uap->pid;
4954
4955	au_uwrite(au_to_arg32(2, "signal", (uint32_t)uap->signo));
4956	if (pid > 0) {
4957		mutex_enter(&pidlock);
4958		if ((p = prfind(pid)) == (struct proc *)0) {
4959			mutex_exit(&pidlock);
4960			return;
4961		}
4962		mutex_enter(&p->p_lock); /* so process doesn't go away */
4963		mutex_exit(&pidlock);
4964
4965		mutex_enter(&p->p_crlock);
4966		crhold(cr = p->p_cred);
4967		mutex_exit(&p->p_crlock);
4968		mutex_exit(&p->p_lock);
4969
4970		ainfo = crgetauinfo(cr);
4971		if (ainfo == NULL) {
4972			crfree(cr);
4973			return;
4974		}
4975
4976		uid  = crgetuid(cr);
4977		gid  = crgetgid(cr);
4978		ruid = crgetruid(cr);
4979		rgid = crgetrgid(cr);
4980		au_uwrite(au_to_process(uid, gid, ruid, rgid, pid,
4981		    ainfo->ai_auid, ainfo->ai_asid, &ainfo->ai_termid));
4982		crfree(cr);
4983	}
4984	else
4985		au_uwrite(au_to_arg32(1, "process ID", (uint32_t)pid));
4986}
4987
4988/*ARGSUSED*/
4989static void
4990aus_inst_sync(struct t_audit_data *tad)
4991{
4992	struct a {
4993		long	name;	/* char */
4994		long	flags;
4995	} *uap = (struct a *)ttolwp(curthread)->lwp_ap;
4996
4997	au_uwrite(au_to_arg32(2, "flags", (uint32_t)uap->flags));
4998}
4999
5000/*ARGSUSED*/
5001static void
5002aus_brandsys(struct t_audit_data *tad)
5003{
5004	klwp_t *clwp = ttolwp(curthread);
5005
5006	struct a {
5007		long	cmd;
5008		long	arg1;
5009		long	arg2;
5010		long	arg3;
5011		long	arg4;
5012		long	arg5;
5013		long	arg6;
5014	} *uap = (struct a *)clwp->lwp_ap;
5015
5016	au_uwrite(au_to_arg32(1, "cmd", (uint_t)uap->cmd));
5017#ifdef _LP64
5018	au_uwrite(au_to_arg64(2, "arg1", (uint64_t)uap->arg1));
5019	au_uwrite(au_to_arg64(3, "arg2", (uint64_t)uap->arg2));
5020	au_uwrite(au_to_arg64(4, "arg3", (uint64_t)uap->arg3));
5021	au_uwrite(au_to_arg64(5, "arg4", (uint64_t)uap->arg4));
5022	au_uwrite(au_to_arg64(6, "arg5", (uint64_t)uap->arg5));
5023	au_uwrite(au_to_arg64(7, "arg6", (uint64_t)uap->arg6));
5024#else
5025	au_uwrite(au_to_arg32(2, "arg1", (uint32_t)uap->arg1));
5026	au_uwrite(au_to_arg32(3, "arg2", (uint32_t)uap->arg2));
5027	au_uwrite(au_to_arg32(4, "arg3", (uint32_t)uap->arg3));
5028	au_uwrite(au_to_arg32(5, "arg4", (uint32_t)uap->arg4));
5029	au_uwrite(au_to_arg32(6, "arg5", (uint32_t)uap->arg5));
5030	au_uwrite(au_to_arg32(7, "arg6", (uint32_t)uap->arg6));
5031#endif
5032}
5033
5034/*ARGSUSED*/
5035static void
5036aus_p_online(struct t_audit_data *tad)
5037{
5038	struct a {
5039		long	processor_id;
5040		long	flag;
5041	} *uap = (struct a *)ttolwp(curthread)->lwp_ap;
5042
5043	struct flags {
5044			int	flag;
5045			char	*cflag;
5046	} aflags[6] = {
5047			{ P_ONLINE, "P_ONLINE"},
5048			{ P_OFFLINE, "P_OFFLINE"},
5049			{ P_NOINTR, "P_NOINTR"},
5050			{ P_SPARE, "P_SPARE"},
5051			{ P_FAULTED, "P_FAULTED"},
5052			{ P_STATUS, "P_STATUS"}
5053	};
5054	int i;
5055	char *cflag;
5056
5057	au_uwrite(au_to_arg32(1, "processor ID", (uint32_t)uap->processor_id));
5058	au_uwrite(au_to_arg32(2, "flag", (uint32_t)uap->flag));
5059
5060	for (i = 0; i < 6; i++) {
5061		if (aflags[i].flag == uap->flag)
5062			break;
5063	}
5064	cflag = (i == 6) ? "bad flag":aflags[i].cflag;
5065
5066	au_uwrite(au_to_text(cflag));
5067}
5068
5069/*ARGSUSED*/
5070static void
5071aus_processor_bind(struct t_audit_data *tad)
5072{
5073	struct a {
5074		long	id_type;
5075		long	id;
5076		long	processor_id;
5077		long	obind;
5078	} *uap = (struct a *)ttolwp(curthread)->lwp_ap;
5079
5080	struct proc *p;
5081	int lwpcnt;
5082	uid_t uid, ruid;
5083	gid_t gid, rgid;
5084	pid_t pid;
5085	const auditinfo_addr_t *ainfo;
5086	cred_t *cr;
5087
5088	au_uwrite(au_to_arg32(1, "ID type", (uint32_t)uap->id_type));
5089	au_uwrite(au_to_arg32(2, "ID", (uint32_t)uap->id));
5090	if (uap->processor_id == PBIND_NONE)
5091		au_uwrite(au_to_text("PBIND_NONE"));
5092	else
5093		au_uwrite(au_to_arg32(3, "processor_id",
5094		    (uint32_t)uap->processor_id));
5095
5096	switch (uap->id_type) {
5097	case P_MYID:
5098	case P_LWPID:
5099		mutex_enter(&pidlock);
5100		p = ttoproc(curthread);
5101		if (p == NULL || p->p_as == &kas) {
5102			mutex_exit(&pidlock);
5103			return;
5104		}
5105		mutex_enter(&p->p_lock);
5106		mutex_exit(&pidlock);
5107		lwpcnt = p->p_lwpcnt;
5108		pid  = p->p_pid;
5109
5110		mutex_enter(&p->p_crlock);
5111		crhold(cr = p->p_cred);
5112		mutex_exit(&p->p_crlock);
5113		mutex_exit(&p->p_lock);
5114
5115		ainfo = crgetauinfo(cr);
5116		if (ainfo == NULL) {
5117			crfree(cr);
5118			return;
5119		}
5120
5121		uid  = crgetuid(cr);
5122		gid  = crgetgid(cr);
5123		ruid = crgetruid(cr);
5124		rgid = crgetrgid(cr);
5125		au_uwrite(au_to_process(uid, gid, ruid, rgid, pid,
5126		    ainfo->ai_auid, ainfo->ai_asid, &ainfo->ai_termid));
5127		crfree(cr);
5128		break;
5129	case P_PID:
5130		mutex_enter(&pidlock);
5131		p = prfind(uap->id);
5132		if (p == NULL || p->p_as == &kas) {
5133			mutex_exit(&pidlock);
5134			return;
5135		}
5136		mutex_enter(&p->p_lock);
5137		mutex_exit(&pidlock);
5138		lwpcnt = p->p_lwpcnt;
5139		pid  = p->p_pid;
5140
5141		mutex_enter(&p->p_crlock);
5142		crhold(cr = p->p_cred);
5143		mutex_exit(&p->p_crlock);
5144		mutex_exit(&p->p_lock);
5145
5146		ainfo = crgetauinfo(cr);
5147		if (ainfo == NULL) {
5148			crfree(cr);
5149			return;
5150		}
5151
5152		uid  = crgetuid(cr);
5153		gid  = crgetgid(cr);
5154		ruid = crgetruid(cr);
5155		rgid = crgetrgid(cr);
5156		au_uwrite(au_to_process(uid, gid, ruid, rgid, pid,
5157		    ainfo->ai_auid, ainfo->ai_asid, &ainfo->ai_termid));
5158		crfree(cr);
5159
5160		break;
5161	default:
5162		return;
5163	}
5164
5165	if (uap->processor_id == PBIND_NONE &&
5166	    (!(uap->id_type == P_LWPID && lwpcnt > 1)))
5167		au_uwrite(au_to_text("PBIND_NONE for process"));
5168	else
5169		au_uwrite(au_to_arg32(3, "processor_id",
5170		    (uint32_t)uap->processor_id));
5171}
5172
5173/*ARGSUSED*/
5174static au_event_t
5175aui_doorfs(au_event_t e)
5176{
5177	uint32_t code;
5178
5179	struct a {		/* doorfs */
5180		long	a1;
5181		long	a2;
5182		long	a3;
5183		long	a4;
5184		long	a5;
5185		long	code;
5186	} *uap = (struct a *)ttolwp(curthread)->lwp_ap;
5187
5188	/*
5189	 *	audit formats for several of the
5190	 *	door calls have not yet been determined
5191	 */
5192	code = (uint32_t)uap->code;
5193	switch (code) {
5194	case DOOR_CALL:
5195		e = AUE_DOORFS_DOOR_CALL;
5196		break;
5197	case DOOR_RETURN:
5198		e = AUE_NULL;
5199		break;
5200	case DOOR_CREATE:
5201		e = AUE_DOORFS_DOOR_CREATE;
5202		break;
5203	case DOOR_REVOKE:
5204		e = AUE_DOORFS_DOOR_REVOKE;
5205		break;
5206	case DOOR_INFO:
5207		e = AUE_NULL;
5208		break;
5209	case DOOR_UCRED:
5210		e = AUE_NULL;
5211		break;
5212	case DOOR_BIND:
5213		e = AUE_NULL;
5214		break;
5215	case DOOR_UNBIND:
5216		e = AUE_NULL;
5217		break;
5218	case DOOR_GETPARAM:
5219		e = AUE_NULL;
5220		break;
5221	case DOOR_SETPARAM:
5222		e = AUE_NULL;
5223		break;
5224	default:	/* illegal system call */
5225		e = AUE_NULL;
5226		break;
5227	}
5228
5229	return (e);
5230}
5231
5232static door_node_t *
5233au_door_lookup(int did)
5234{
5235	vnode_t	*vp;
5236	file_t *fp;
5237
5238	if ((fp = getf(did)) == NULL)
5239		return (NULL);
5240	/*
5241	 * Use the underlying vnode (we may be namefs mounted)
5242	 */
5243	if (VOP_REALVP(fp->f_vnode, &vp, NULL))
5244		vp = fp->f_vnode;
5245
5246	if (vp == NULL || vp->v_type != VDOOR) {
5247		releasef(did);
5248		return (NULL);
5249	}
5250
5251	return (VTOD(vp));
5252}
5253
5254/*ARGSUSED*/
5255static void
5256aus_doorfs(struct t_audit_data *tad)
5257{
5258
5259	struct a {		/* doorfs */
5260		long	a1;
5261		long	a2;
5262		long	a3;
5263		long	a4;
5264		long	a5;
5265		long	code;
5266	} *uap = (struct a *)ttolwp(curthread)->lwp_ap;
5267
5268	door_node_t	*dp;
5269	struct proc	*p;
5270	uint32_t	did;
5271	uid_t uid, ruid;
5272	gid_t gid, rgid;
5273	pid_t pid;
5274	const auditinfo_addr_t *ainfo;
5275	cred_t *cr;
5276
5277	did = (uint32_t)uap->a1;
5278
5279	switch (tad->tad_event) {
5280	case AUE_DOORFS_DOOR_CALL:
5281		au_uwrite(au_to_arg32(1, "door ID", (uint32_t)did));
5282		if ((dp = au_door_lookup(did)) == NULL)
5283			break;
5284
5285		if (DOOR_INVALID(dp)) {
5286			releasef(did);
5287			break;
5288		}
5289
5290		if ((p = dp->door_target) == NULL) {
5291			releasef(did);
5292			break;
5293		}
5294		mutex_enter(&p->p_lock);
5295		releasef(did);
5296
5297		pid  = p->p_pid;
5298
5299		mutex_enter(&p->p_crlock);
5300		crhold(cr = p->p_cred);
5301		mutex_exit(&p->p_crlock);
5302		mutex_exit(&p->p_lock);
5303
5304		ainfo = crgetauinfo(cr);
5305		if (ainfo == NULL) {
5306			crfree(cr);
5307			return;
5308		}
5309		uid  = crgetuid(cr);
5310		gid  = crgetgid(cr);
5311		ruid = crgetruid(cr);
5312		rgid = crgetrgid(cr);
5313		au_uwrite(au_to_process(uid, gid, ruid, rgid, pid,
5314		    ainfo->ai_auid, ainfo->ai_asid, &ainfo->ai_termid));
5315		crfree(cr);
5316		break;
5317	case AUE_DOORFS_DOOR_RETURN:
5318		/*
5319		 * We may want to write information about
5320		 * all doors (if any) which will be copied
5321		 * by this call to the user space
5322		 */
5323		break;
5324	case AUE_DOORFS_DOOR_CREATE:
5325		au_uwrite(au_to_arg32(3, "door attr", (uint32_t)uap->a3));
5326		break;
5327	case AUE_DOORFS_DOOR_REVOKE:
5328		au_uwrite(au_to_arg32(1, "door ID", (uint32_t)did));
5329		break;
5330	case AUE_DOORFS_DOOR_INFO:
5331		break;
5332	case AUE_DOORFS_DOOR_CRED:
5333		break;
5334	case AUE_DOORFS_DOOR_BIND:
5335		break;
5336	case AUE_DOORFS_DOOR_UNBIND: {
5337		break;
5338	}
5339	default:	/* illegal system call */
5340		break;
5341	}
5342}
5343
5344/*ARGSUSED*/
5345static au_event_t
5346aui_acl(au_event_t e)
5347{
5348	struct a {
5349		union {
5350			long	name;	/* char */
5351			long	fd;
5352		}		obj;
5353
5354		long		cmd;
5355		long		nentries;
5356		long		arg;	/* aclent_t */
5357	} *uap = (struct a *)ttolwp(curthread)->lwp_ap;
5358
5359	switch (uap->cmd) {
5360	case SETACL:
5361	case ACE_SETACL:
5362		/*
5363		 * acl(SETACL/ACE_SETACL, ...) and facl(SETACL/ACE_SETACL, ...)
5364		 * are expected.
5365		 */
5366		break;
5367	case GETACL:
5368	case GETACLCNT:
5369	case ACE_GETACL:
5370	case ACE_GETACLCNT:
5371		/* do nothing for these four values. */
5372		e = AUE_NULL;
5373		break;
5374	default:
5375		/* illegal system call */
5376		break;
5377	}
5378
5379	return (e);
5380}
5381
5382static void
5383au_acl(int cmd, int nentries, caddr_t bufp)
5384{
5385	size_t		a_size;
5386	aclent_t	*aclbufp;
5387	ace_t		*acebufp;
5388	int		i;
5389
5390	switch (cmd) {
5391	case GETACL:
5392	case GETACLCNT:
5393		break;
5394	case SETACL:
5395		if (nentries < 3)
5396			break;
5397
5398		a_size = nentries * sizeof (aclent_t);
5399
5400		if ((aclbufp = kmem_alloc(a_size, KM_SLEEP)) == NULL)
5401			break;
5402		if (copyin(bufp, aclbufp, a_size)) {
5403			kmem_free(aclbufp, a_size);
5404			break;
5405		}
5406		for (i = 0; i < nentries; i++) {
5407			au_uwrite(au_to_acl(aclbufp + i));
5408		}
5409		kmem_free(aclbufp, a_size);
5410		break;
5411
5412	case ACE_SETACL:
5413		if (nentries < 1 || nentries > MAX_ACL_ENTRIES)
5414			break;
5415
5416		a_size = nentries * sizeof (ace_t);
5417		if ((acebufp = kmem_alloc(a_size, KM_SLEEP)) == NULL)
5418			break;
5419		if (copyin(bufp, acebufp, a_size)) {
5420			kmem_free(acebufp, a_size);
5421			break;
5422		}
5423		for (i = 0; i < nentries; i++) {
5424			au_uwrite(au_to_ace(acebufp + i));
5425		}
5426		kmem_free(acebufp, a_size);
5427		break;
5428	default:
5429		break;
5430	}
5431}
5432
5433/*ARGSUSED*/
5434static void
5435aus_acl(struct t_audit_data *tad)
5436{
5437	struct a {
5438		long	fname;
5439		long	cmd;
5440		long	nentries;
5441		long	aclbufp;
5442	} *uap = (struct a *)ttolwp(curthread)->lwp_ap;
5443
5444	au_uwrite(au_to_arg32(2, "cmd", (uint32_t)uap->cmd));
5445	au_uwrite(au_to_arg32(3, "nentries", (uint32_t)uap->nentries));
5446
5447	au_acl(uap->cmd, uap->nentries, (caddr_t)uap->aclbufp);
5448}
5449
5450/*ARGSUSED*/
5451static void
5452aus_facl(struct t_audit_data *tad)
5453{
5454	struct a {
5455		long	fd;
5456		long	cmd;
5457		long	nentries;
5458		long	aclbufp;
5459	} *uap = (struct a *)ttolwp(curthread)->lwp_ap;
5460	struct file  *fp;
5461	struct vnode *vp;
5462	struct f_audit_data *fad;
5463	int fd;
5464
5465	au_uwrite(au_to_arg32(2, "cmd", (uint32_t)uap->cmd));
5466	au_uwrite(au_to_arg32(3, "nentries", (uint32_t)uap->nentries));
5467
5468	fd = (int)uap->fd;
5469
5470	if ((fp = getf(fd)) == NULL)
5471		return;
5472
5473	/* get path from file struct here */
5474	fad = F2A(fp);
5475	if (fad->fad_aupath != NULL) {
5476		au_uwrite(au_to_path(fad->fad_aupath));
5477	} else {
5478		au_uwrite(au_to_arg32(1, "no path: fd", (uint32_t)fd));
5479	}
5480
5481	vp = fp->f_vnode;
5482	audit_attributes(vp);
5483
5484	/* decrement file descriptor reference count */
5485	releasef(fd);
5486
5487	au_acl(uap->cmd, uap->nentries, (caddr_t)uap->aclbufp);
5488}
5489
5490/*ARGSUSED*/
5491static void
5492auf_read(struct t_audit_data *tad, int error, rval_t *rval)
5493{
5494	struct file *fp;
5495	struct f_audit_data *fad;
5496	int fd;
5497	register struct a {
5498		long	fd;
5499	} *uap = (struct a *)ttolwp(curthread)->lwp_ap;
5500	au_kcontext_t	*kctx = GET_KCTX_PZ;
5501
5502	fd = (int)uap->fd;
5503
5504	/*
5505	 * convert file pointer to file descriptor
5506	 *   Note: fd ref count incremented here.
5507	 */
5508	if ((fp = getf(fd)) == NULL)
5509		return;
5510
5511	/* get path from file struct here */
5512	fad = F2A(fp);
5513	ASSERT(fad);
5514
5515	/*
5516	 * already processed this file for read attempt
5517	 *
5518	 * XXX might be better to turn off auditing in a aui_read() routine.
5519	 */
5520	if (fad->fad_flags & FAD_READ) {
5521		/* don't really want to audit every read attempt */
5522		tad->tad_flag = 0;
5523		/* free any residual audit data */
5524		au_close(kctx, &(u_ad), 0, 0, 0, NULL);
5525		releasef(fd);
5526		return;
5527	}
5528	/* mark things so we know what happened and don't repeat things */
5529	fad->fad_flags |= FAD_READ;
5530
5531	if (fad->fad_aupath != NULL) {
5532		au_uwrite(au_to_path(fad->fad_aupath));
5533	} else {
5534		au_uwrite(au_to_arg32(1, "no path: fd", (uint32_t)fd));
5535	}
5536
5537	/* include attributes */
5538	audit_attributes(fp->f_vnode);
5539
5540	/* decrement file descriptor reference count */
5541	releasef(fd);
5542}
5543
5544/*ARGSUSED*/
5545static void
5546auf_write(struct t_audit_data *tad, int error, rval_t *rval)
5547{
5548	struct file *fp;
5549	struct f_audit_data *fad;
5550	int fd;
5551	register struct a {
5552		long	fd;
5553	} *uap = (struct a *)ttolwp(curthread)->lwp_ap;
5554	au_kcontext_t	*kctx = GET_KCTX_PZ;
5555
5556	fd = (int)uap->fd;
5557
5558	/*
5559	 * convert file pointer to file descriptor
5560	 *   Note: fd ref count incremented here.
5561	 */
5562	if ((fp = getf(fd)) == NULL)
5563		return;
5564
5565	/* get path from file struct here */
5566	fad = F2A(fp);
5567	ASSERT(fad);
5568
5569	/*
5570	 * already processed this file for write attempt
5571	 *
5572	 * XXX might be better to turn off auditing in a aus_write() routine.
5573	 */
5574	if (fad->fad_flags & FAD_WRITE) {
5575		/* don't really want to audit every write attempt */
5576		tad->tad_flag = 0;
5577		/* free any residual audit data */
5578		au_close(kctx, &(u_ad), 0, 0, 0, NULL);
5579		releasef(fd);
5580		return;
5581	}
5582	/* mark things so we know what happened and don't repeat things */
5583	fad->fad_flags |= FAD_WRITE;
5584
5585	if (fad->fad_aupath != NULL) {
5586		au_uwrite(au_to_path(fad->fad_aupath));
5587	} else {
5588		au_uwrite(au_to_arg32(1, "no path: fd", (uint32_t)fd));
5589	}
5590
5591	/* include attributes */
5592	audit_attributes(fp->f_vnode);
5593
5594	/* decrement file descriptor reference count */
5595	releasef(fd);
5596}
5597
5598/*ARGSUSED*/
5599static void
5600auf_recv(struct t_audit_data *tad, int error, rval_t *rval)
5601{
5602	struct sonode *so;
5603	char so_laddr[sizeof (struct sockaddr_in6)];
5604	char so_faddr[sizeof (struct sockaddr_in6)];
5605	struct file *fp;
5606	struct f_audit_data *fad;
5607	int fd;
5608	int err;
5609	socklen_t len;
5610	short so_family, so_type;
5611	register struct a {
5612		long	fd;
5613	} *uap = (struct a *)ttolwp(curthread)->lwp_ap;
5614	au_kcontext_t	*kctx = GET_KCTX_PZ;
5615
5616	/*
5617	 * If there was an error, then nothing to do. Only generate
5618	 * audit record on first successful recv.
5619	 */
5620	if (error) {
5621		/* Turn off audit record generation here. */
5622		tad->tad_flag = 0;
5623		/* free any residual audit data */
5624		au_close(kctx, &(u_ad), 0, 0, 0, NULL);
5625		return;
5626	}
5627
5628	fd = (int)uap->fd;
5629
5630	if ((so = getsonode(fd, &err, &fp)) == NULL) {
5631		/* Turn off audit record generation here. */
5632		tad->tad_flag = 0;
5633		/* free any residual audit data */
5634		au_close(kctx, &(u_ad), 0, 0, 0, NULL);
5635		return;
5636	}
5637
5638	/* get path from file struct here */
5639	fad = F2A(fp);
5640	ASSERT(fad);
5641
5642	/*
5643	 * already processed this file for read attempt
5644	 */
5645	if (fad->fad_flags & FAD_READ) {
5646		releasef(fd);
5647		/* don't really want to audit every recv call */
5648		tad->tad_flag = 0;
5649		/* free any residual audit data */
5650		au_close(kctx, &(u_ad), 0, 0, 0, NULL);
5651		return;
5652	}
5653
5654	/* mark things so we know what happened and don't repeat things */
5655	fad->fad_flags |= FAD_READ;
5656
5657	so_family = so->so_family;
5658	so_type   = so->so_type;
5659
5660	switch (so_family) {
5661	case AF_INET:
5662	case AF_INET6:
5663		/*
5664		 * Only for connections.
5665		 * XXX - do we need to worry about SOCK_DGRAM or other types???
5666		 */
5667		if (so->so_state & SS_ISBOUND) {
5668
5669			bzero((void *)so_laddr, sizeof (so_laddr));
5670			bzero((void *)so_faddr, sizeof (so_faddr));
5671
5672			/* get local and foreign addresses */
5673			len = sizeof (so_laddr);
5674			(void) socket_getsockname(so,
5675			    (struct sockaddr *)so_laddr, &len, CRED());
5676			len = sizeof (so_faddr);
5677			(void) socket_getpeername(so,
5678			    (struct sockaddr *)so_faddr, &len, B_FALSE, CRED());
5679
5680			/*
5681			 * only way to drop out of switch. Note that we
5682			 * we release fd below.
5683			 */
5684
5685			break;
5686		}
5687
5688		releasef(fd);
5689
5690		/* don't really want to audit every recv call */
5691		tad->tad_flag = 0;
5692		/* free any residual audit data */
5693		au_close(kctx, &(u_ad), 0, 0, 0, NULL);
5694
5695		return;
5696
5697	case AF_UNIX:
5698
5699		if (fad->fad_aupath != NULL) {
5700			au_uwrite(au_to_path(fad->fad_aupath));
5701		} else {
5702			au_uwrite(au_to_arg32(1, "no path: fd", fd));
5703		}
5704
5705		audit_attributes(fp->f_vnode);
5706
5707		releasef(fd);
5708
5709		return;
5710
5711	default:
5712		releasef(fd);
5713
5714		au_uwrite(au_to_arg32(1, "so", (uint32_t)fd));
5715		au_uwrite(au_to_arg32(1, "family", (uint32_t)so_family));
5716		au_uwrite(au_to_arg32(1, "type", (uint32_t)so_type));
5717
5718		return;
5719	}
5720
5721	releasef(fd);
5722
5723	au_uwrite(au_to_arg32(1, "so", (uint32_t)fd));
5724
5725	au_uwrite(au_to_socket_ex(so_family, so_type, so_laddr, so_faddr));
5726
5727}
5728
5729/*ARGSUSED*/
5730static void
5731auf_send(struct t_audit_data *tad, int error, rval_t *rval)
5732{
5733	struct sonode *so;
5734	char so_laddr[sizeof (struct sockaddr_in6)];
5735	char so_faddr[sizeof (struct sockaddr_in6)];
5736	struct file *fp;
5737	struct f_audit_data *fad;
5738	int fd;
5739	int err;
5740	socklen_t len;
5741	short so_family, so_type;
5742	register struct a {
5743		long	fd;
5744	} *uap = (struct a *)ttolwp(curthread)->lwp_ap;
5745	au_kcontext_t	*kctx = GET_KCTX_PZ;
5746
5747	fd = (int)uap->fd;
5748
5749	/*
5750	 * If there was an error, then nothing to do. Only generate
5751	 * audit record on first successful send.
5752	 */
5753	if (error != 0) {
5754		/* Turn off audit record generation here. */
5755		tad->tad_flag = 0;
5756		/* free any residual audit data */
5757		au_close(kctx, &(u_ad), 0, 0, 0, NULL);
5758		return;
5759	}
5760
5761	fd = (int)uap->fd;
5762
5763	if ((so = getsonode(fd, &err, &fp)) == NULL) {
5764		/* Turn off audit record generation here. */
5765		tad->tad_flag = 0;
5766		/* free any residual audit data */
5767		au_close(kctx, &(u_ad), 0, 0, 0, NULL);
5768		return;
5769	}
5770
5771	/* get path from file struct here */
5772	fad = F2A(fp);
5773	ASSERT(fad);
5774
5775	/*
5776	 * already processed this file for write attempt
5777	 */
5778	if (fad->fad_flags & FAD_WRITE) {
5779		releasef(fd);
5780		/* don't really want to audit every send call */
5781		tad->tad_flag = 0;
5782		/* free any residual audit data */
5783		au_close(kctx, &(u_ad), 0, 0, 0, NULL);
5784		return;
5785	}
5786
5787	/* mark things so we know what happened and don't repeat things */
5788	fad->fad_flags |= FAD_WRITE;
5789
5790	so_family = so->so_family;
5791	so_type   = so->so_type;
5792
5793	switch (so_family) {
5794	case AF_INET:
5795	case AF_INET6:
5796		/*
5797		 * Only for connections.
5798		 * XXX - do we need to worry about SOCK_DGRAM or other types???
5799		 */
5800		if (so->so_state & SS_ISBOUND) {
5801
5802			bzero((void *)so_laddr, sizeof (so_laddr));
5803			bzero((void *)so_faddr, sizeof (so_faddr));
5804
5805			/* get local and foreign addresses */
5806			len = sizeof (so_laddr);
5807			(void) socket_getsockname(so,
5808			    (struct sockaddr *)so_laddr, &len, CRED());
5809			len = sizeof (so_faddr);
5810			(void) socket_getpeername(so,
5811			    (struct sockaddr *)so_faddr, &len, B_FALSE, CRED());
5812
5813			/*
5814			 * only way to drop out of switch. Note that we
5815			 * we release fd below.
5816			 */
5817
5818			break;
5819		}
5820
5821		releasef(fd);
5822		/* don't really want to audit every send call */
5823		tad->tad_flag = 0;
5824		/* free any residual audit data */
5825		au_close(kctx, &(u_ad), 0, 0, 0, NULL);
5826
5827		return;
5828
5829	case AF_UNIX:
5830
5831		if (fad->fad_aupath != NULL) {
5832			au_uwrite(au_to_path(fad->fad_aupath));
5833		} else {
5834			au_uwrite(au_to_arg32(1, "no path: fd", fd));
5835		}
5836
5837		audit_attributes(fp->f_vnode);
5838
5839		releasef(fd);
5840
5841		return;
5842
5843	default:
5844		releasef(fd);
5845
5846		au_uwrite(au_to_arg32(1, "so", (uint32_t)fd));
5847		au_uwrite(au_to_arg32(1, "family", (uint32_t)so_family));
5848		au_uwrite(au_to_arg32(1, "type", (uint32_t)so_type));
5849
5850		return;
5851	}
5852
5853	releasef(fd);
5854
5855	au_uwrite(au_to_arg32(1, "so", (uint32_t)fd));
5856
5857	au_uwrite(au_to_socket_ex(so_family, so_type, so_laddr, so_faddr));
5858}
5859
5860static au_event_t
5861aui_forksys(au_event_t e)
5862{
5863	struct a {
5864		long	subcode;
5865		long	flags;
5866	} *uap = (struct a *)ttolwp(curthread)->lwp_ap;
5867
5868	switch ((uint_t)uap->subcode) {
5869	case 0:
5870		e = AUE_FORK1;
5871		break;
5872	case 1:
5873		e = AUE_FORKALL;
5874		break;
5875	case 2:
5876		e = AUE_VFORK;
5877		break;
5878	default:
5879		e = AUE_NULL;
5880		break;
5881	}
5882
5883	return (e);
5884}
5885
5886/*ARGSUSED*/
5887static au_event_t
5888aui_portfs(au_event_t e)
5889{
5890	struct a {		/* portfs */
5891		long	a1;
5892		long	a2;
5893		long	a3;
5894	} *uap = (struct a *)ttolwp(curthread)->lwp_ap;
5895
5896	/*
5897	 * check opcode
5898	 */
5899	switch (((uint_t)uap->a1) & PORT_CODE_MASK) {
5900	case PORT_ASSOCIATE:
5901		/* check source */
5902		if (((uint_t)uap->a3 == PORT_SOURCE_FILE) ||
5903		    ((uint_t)uap->a3 == PORT_SOURCE_FD)) {
5904			e = AUE_PORTFS_ASSOCIATE;
5905		} else {
5906			e = AUE_NULL;
5907		}
5908		break;
5909	case PORT_DISSOCIATE:
5910		/* check source */
5911		if (((uint_t)uap->a3 == PORT_SOURCE_FILE) ||
5912		    ((uint_t)uap->a3 == PORT_SOURCE_FD)) {
5913			e = AUE_PORTFS_DISSOCIATE;
5914		} else {
5915			e = AUE_NULL;
5916		}
5917		break;
5918	default:
5919		e = AUE_NULL;
5920	}
5921	return (e);
5922}
5923