1/*-
2 * Copyright (c) 1999-2005 Apple Inc.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1.  Redistributions of source code must retain the above copyright
9 *     notice, this list of conditions and the following disclaimer.
10 * 2.  Redistributions in binary form must reproduce the above copyright
11 *     notice, this list of conditions and the following disclaimer in the
12 *     documentation and/or other materials provided with the distribution.
13 * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
14 *     its contributors may be used to endorse or promote products derived
15 *     from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR
21 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
25 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
26 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
28 */
29
30#include <sys/cdefs.h>
31__FBSDID("$FreeBSD$");
32
33#include <sys/param.h>
34#include <sys/filedesc.h>
35#include <sys/capsicum.h>
36#include <sys/ipc.h>
37#include <sys/mount.h>
38#include <sys/proc.h>
39#include <sys/socket.h>
40#include <sys/socketvar.h>
41#include <sys/protosw.h>
42#include <sys/domain.h>
43#include <sys/sbuf.h>
44#include <sys/systm.h>
45#include <sys/un.h>
46#include <sys/vnode.h>
47
48#include <netinet/in.h>
49#include <netinet/in_pcb.h>
50
51#include <security/audit/audit.h>
52#include <security/audit/audit_private.h>
53
54/*
55 * Calls to manipulate elements of the audit record structure from system
56 * call code.  Macro wrappers will prevent this functions from being entered
57 * if auditing is disabled, avoiding the function call cost.  We check the
58 * thread audit record pointer anyway, as the audit condition could change,
59 * and pre-selection may not have allocated an audit record for this event.
60 *
61 * XXXAUDIT: Should we assert, in each case, that this field of the record
62 * hasn't already been filled in?
63 */
64void
65audit_arg_addr(void *addr)
66{
67	struct kaudit_record *ar;
68
69	ar = currecord();
70	if (ar == NULL)
71		return;
72
73	ar->k_ar.ar_arg_addr = addr;
74	ARG_SET_VALID(ar, ARG_ADDR);
75}
76
77void
78audit_arg_exit(int status, int retval)
79{
80	struct kaudit_record *ar;
81
82	ar = currecord();
83	if (ar == NULL)
84		return;
85
86	ar->k_ar.ar_arg_exitstatus = status;
87	ar->k_ar.ar_arg_exitretval = retval;
88	ARG_SET_VALID(ar, ARG_EXIT);
89}
90
91void
92audit_arg_len(int len)
93{
94	struct kaudit_record *ar;
95
96	ar = currecord();
97	if (ar == NULL)
98		return;
99
100	ar->k_ar.ar_arg_len = len;
101	ARG_SET_VALID(ar, ARG_LEN);
102}
103
104void
105audit_arg_atfd1(int atfd)
106{
107	struct kaudit_record *ar;
108
109	ar = currecord();
110	if (ar == NULL)
111		return;
112
113	ar->k_ar.ar_arg_atfd1 = atfd;
114	ARG_SET_VALID(ar, ARG_ATFD1);
115}
116
117void
118audit_arg_atfd2(int atfd)
119{
120	struct kaudit_record *ar;
121
122	ar = currecord();
123	if (ar == NULL)
124		return;
125
126	ar->k_ar.ar_arg_atfd2 = atfd;
127	ARG_SET_VALID(ar, ARG_ATFD2);
128}
129
130void
131audit_arg_fd(int fd)
132{
133	struct kaudit_record *ar;
134
135	ar = currecord();
136	if (ar == NULL)
137		return;
138
139	ar->k_ar.ar_arg_fd = fd;
140	ARG_SET_VALID(ar, ARG_FD);
141}
142
143void
144audit_arg_fflags(int fflags)
145{
146	struct kaudit_record *ar;
147
148	ar = currecord();
149	if (ar == NULL)
150		return;
151
152	ar->k_ar.ar_arg_fflags = fflags;
153	ARG_SET_VALID(ar, ARG_FFLAGS);
154}
155
156void
157audit_arg_gid(gid_t gid)
158{
159	struct kaudit_record *ar;
160
161	ar = currecord();
162	if (ar == NULL)
163		return;
164
165	ar->k_ar.ar_arg_gid = gid;
166	ARG_SET_VALID(ar, ARG_GID);
167}
168
169void
170audit_arg_uid(uid_t uid)
171{
172	struct kaudit_record *ar;
173
174	ar = currecord();
175	if (ar == NULL)
176		return;
177
178	ar->k_ar.ar_arg_uid = uid;
179	ARG_SET_VALID(ar, ARG_UID);
180}
181
182void
183audit_arg_egid(gid_t egid)
184{
185	struct kaudit_record *ar;
186
187	ar = currecord();
188	if (ar == NULL)
189		return;
190
191	ar->k_ar.ar_arg_egid = egid;
192	ARG_SET_VALID(ar, ARG_EGID);
193}
194
195void
196audit_arg_euid(uid_t euid)
197{
198	struct kaudit_record *ar;
199
200	ar = currecord();
201	if (ar == NULL)
202		return;
203
204	ar->k_ar.ar_arg_euid = euid;
205	ARG_SET_VALID(ar, ARG_EUID);
206}
207
208void
209audit_arg_rgid(gid_t rgid)
210{
211	struct kaudit_record *ar;
212
213	ar = currecord();
214	if (ar == NULL)
215		return;
216
217	ar->k_ar.ar_arg_rgid = rgid;
218	ARG_SET_VALID(ar, ARG_RGID);
219}
220
221void
222audit_arg_ruid(uid_t ruid)
223{
224	struct kaudit_record *ar;
225
226	ar = currecord();
227	if (ar == NULL)
228		return;
229
230	ar->k_ar.ar_arg_ruid = ruid;
231	ARG_SET_VALID(ar, ARG_RUID);
232}
233
234void
235audit_arg_sgid(gid_t sgid)
236{
237	struct kaudit_record *ar;
238
239	ar = currecord();
240	if (ar == NULL)
241		return;
242
243	ar->k_ar.ar_arg_sgid = sgid;
244	ARG_SET_VALID(ar, ARG_SGID);
245}
246
247void
248audit_arg_suid(uid_t suid)
249{
250	struct kaudit_record *ar;
251
252	ar = currecord();
253	if (ar == NULL)
254		return;
255
256	ar->k_ar.ar_arg_suid = suid;
257	ARG_SET_VALID(ar, ARG_SUID);
258}
259
260void
261audit_arg_groupset(gid_t *gidset, u_int gidset_size)
262{
263	u_int i;
264	struct kaudit_record *ar;
265
266	KASSERT(gidset_size <= ngroups_max + 1,
267	    ("audit_arg_groupset: gidset_size > (kern.ngroups + 1)"));
268
269	ar = currecord();
270	if (ar == NULL)
271		return;
272
273	if (ar->k_ar.ar_arg_groups.gidset == NULL)
274		ar->k_ar.ar_arg_groups.gidset = malloc(
275		    sizeof(gid_t) * gidset_size, M_AUDITGIDSET, M_WAITOK);
276
277	for (i = 0; i < gidset_size; i++)
278		ar->k_ar.ar_arg_groups.gidset[i] = gidset[i];
279	ar->k_ar.ar_arg_groups.gidset_size = gidset_size;
280	ARG_SET_VALID(ar, ARG_GROUPSET);
281}
282
283void
284audit_arg_login(char *login)
285{
286	struct kaudit_record *ar;
287
288	ar = currecord();
289	if (ar == NULL)
290		return;
291
292	strlcpy(ar->k_ar.ar_arg_login, login, MAXLOGNAME);
293	ARG_SET_VALID(ar, ARG_LOGIN);
294}
295
296void
297audit_arg_ctlname(int *name, int namelen)
298{
299	struct kaudit_record *ar;
300
301	ar = currecord();
302	if (ar == NULL)
303		return;
304
305	bcopy(name, &ar->k_ar.ar_arg_ctlname, namelen * sizeof(int));
306	ar->k_ar.ar_arg_len = namelen;
307	ARG_SET_VALID(ar, ARG_CTLNAME | ARG_LEN);
308}
309
310void
311audit_arg_mask(int mask)
312{
313	struct kaudit_record *ar;
314
315	ar = currecord();
316	if (ar == NULL)
317		return;
318
319	ar->k_ar.ar_arg_mask = mask;
320	ARG_SET_VALID(ar, ARG_MASK);
321}
322
323void
324audit_arg_mode(mode_t mode)
325{
326	struct kaudit_record *ar;
327
328	ar = currecord();
329	if (ar == NULL)
330		return;
331
332	ar->k_ar.ar_arg_mode = mode;
333	ARG_SET_VALID(ar, ARG_MODE);
334}
335
336void
337audit_arg_dev(int dev)
338{
339	struct kaudit_record *ar;
340
341	ar = currecord();
342	if (ar == NULL)
343		return;
344
345	ar->k_ar.ar_arg_dev = dev;
346	ARG_SET_VALID(ar, ARG_DEV);
347}
348
349void
350audit_arg_value(long value)
351{
352	struct kaudit_record *ar;
353
354	ar = currecord();
355	if (ar == NULL)
356		return;
357
358	ar->k_ar.ar_arg_value = value;
359	ARG_SET_VALID(ar, ARG_VALUE);
360}
361
362void
363audit_arg_owner(uid_t uid, gid_t gid)
364{
365	struct kaudit_record *ar;
366
367	ar = currecord();
368	if (ar == NULL)
369		return;
370
371	ar->k_ar.ar_arg_uid = uid;
372	ar->k_ar.ar_arg_gid = gid;
373	ARG_SET_VALID(ar, ARG_UID | ARG_GID);
374}
375
376void
377audit_arg_pid(pid_t pid)
378{
379	struct kaudit_record *ar;
380
381	ar = currecord();
382	if (ar == NULL)
383		return;
384
385	ar->k_ar.ar_arg_pid = pid;
386	ARG_SET_VALID(ar, ARG_PID);
387}
388
389void
390audit_arg_process(struct proc *p)
391{
392	struct kaudit_record *ar;
393	struct ucred *cred;
394
395	KASSERT(p != NULL, ("audit_arg_process: p == NULL"));
396
397	PROC_LOCK_ASSERT(p, MA_OWNED);
398
399	ar = currecord();
400	if (ar == NULL)
401		return;
402
403	cred = p->p_ucred;
404	ar->k_ar.ar_arg_auid = cred->cr_audit.ai_auid;
405	ar->k_ar.ar_arg_euid = cred->cr_uid;
406	ar->k_ar.ar_arg_egid = cred->cr_groups[0];
407	ar->k_ar.ar_arg_ruid = cred->cr_ruid;
408	ar->k_ar.ar_arg_rgid = cred->cr_rgid;
409	ar->k_ar.ar_arg_asid = cred->cr_audit.ai_asid;
410	ar->k_ar.ar_arg_termid_addr = cred->cr_audit.ai_termid;
411	ar->k_ar.ar_arg_pid = p->p_pid;
412	ARG_SET_VALID(ar, ARG_AUID | ARG_EUID | ARG_EGID | ARG_RUID |
413	    ARG_RGID | ARG_ASID | ARG_TERMID_ADDR | ARG_PID | ARG_PROCESS);
414}
415
416void
417audit_arg_signum(u_int signum)
418{
419	struct kaudit_record *ar;
420
421	ar = currecord();
422	if (ar == NULL)
423		return;
424
425	ar->k_ar.ar_arg_signum = signum;
426	ARG_SET_VALID(ar, ARG_SIGNUM);
427}
428
429void
430audit_arg_socket(int sodomain, int sotype, int soprotocol)
431{
432	struct kaudit_record *ar;
433
434	ar = currecord();
435	if (ar == NULL)
436		return;
437
438	ar->k_ar.ar_arg_sockinfo.so_domain = sodomain;
439	ar->k_ar.ar_arg_sockinfo.so_type = sotype;
440	ar->k_ar.ar_arg_sockinfo.so_protocol = soprotocol;
441	ARG_SET_VALID(ar, ARG_SOCKINFO);
442}
443
444void
445audit_arg_sockaddr(struct thread *td, int dirfd, struct sockaddr *sa)
446{
447	struct kaudit_record *ar;
448
449	KASSERT(td != NULL, ("audit_arg_sockaddr: td == NULL"));
450	KASSERT(sa != NULL, ("audit_arg_sockaddr: sa == NULL"));
451
452	ar = currecord();
453	if (ar == NULL)
454		return;
455
456	bcopy(sa, &ar->k_ar.ar_arg_sockaddr, sa->sa_len);
457	switch (sa->sa_family) {
458	case AF_INET:
459		ARG_SET_VALID(ar, ARG_SADDRINET);
460		break;
461
462	case AF_INET6:
463		ARG_SET_VALID(ar, ARG_SADDRINET6);
464		break;
465
466	case AF_UNIX:
467		if (dirfd != AT_FDCWD)
468			audit_arg_atfd1(dirfd);
469		audit_arg_upath1(td, dirfd,
470		    ((struct sockaddr_un *)sa)->sun_path);
471		ARG_SET_VALID(ar, ARG_SADDRUNIX);
472		break;
473	/* XXXAUDIT: default:? */
474	}
475}
476
477void
478audit_arg_auid(uid_t auid)
479{
480	struct kaudit_record *ar;
481
482	ar = currecord();
483	if (ar == NULL)
484		return;
485
486	ar->k_ar.ar_arg_auid = auid;
487	ARG_SET_VALID(ar, ARG_AUID);
488}
489
490void
491audit_arg_auditinfo(struct auditinfo *au_info)
492{
493	struct kaudit_record *ar;
494
495	ar = currecord();
496	if (ar == NULL)
497		return;
498
499	ar->k_ar.ar_arg_auid = au_info->ai_auid;
500	ar->k_ar.ar_arg_asid = au_info->ai_asid;
501	ar->k_ar.ar_arg_amask.am_success = au_info->ai_mask.am_success;
502	ar->k_ar.ar_arg_amask.am_failure = au_info->ai_mask.am_failure;
503	ar->k_ar.ar_arg_termid.port = au_info->ai_termid.port;
504	ar->k_ar.ar_arg_termid.machine = au_info->ai_termid.machine;
505	ARG_SET_VALID(ar, ARG_AUID | ARG_ASID | ARG_AMASK | ARG_TERMID);
506}
507
508void
509audit_arg_auditinfo_addr(struct auditinfo_addr *au_info)
510{
511	struct kaudit_record *ar;
512
513	ar = currecord();
514	if (ar == NULL)
515		return;
516
517	ar->k_ar.ar_arg_auid = au_info->ai_auid;
518	ar->k_ar.ar_arg_asid = au_info->ai_asid;
519	ar->k_ar.ar_arg_amask.am_success = au_info->ai_mask.am_success;
520	ar->k_ar.ar_arg_amask.am_failure = au_info->ai_mask.am_failure;
521	ar->k_ar.ar_arg_termid_addr.at_type = au_info->ai_termid.at_type;
522	ar->k_ar.ar_arg_termid_addr.at_port = au_info->ai_termid.at_port;
523	ar->k_ar.ar_arg_termid_addr.at_addr[0] = au_info->ai_termid.at_addr[0];
524	ar->k_ar.ar_arg_termid_addr.at_addr[1] = au_info->ai_termid.at_addr[1];
525	ar->k_ar.ar_arg_termid_addr.at_addr[2] = au_info->ai_termid.at_addr[2];
526	ar->k_ar.ar_arg_termid_addr.at_addr[3] = au_info->ai_termid.at_addr[3];
527	ARG_SET_VALID(ar, ARG_AUID | ARG_ASID | ARG_AMASK | ARG_TERMID_ADDR);
528}
529
530void
531audit_arg_text(char *text)
532{
533	struct kaudit_record *ar;
534
535	KASSERT(text != NULL, ("audit_arg_text: text == NULL"));
536
537	ar = currecord();
538	if (ar == NULL)
539		return;
540
541	/* Invalidate the text string */
542	ar->k_ar.ar_valid_arg &= (ARG_ALL ^ ARG_TEXT);
543
544	if (ar->k_ar.ar_arg_text == NULL)
545		ar->k_ar.ar_arg_text = malloc(MAXPATHLEN, M_AUDITTEXT,
546		    M_WAITOK);
547
548	strncpy(ar->k_ar.ar_arg_text, text, MAXPATHLEN);
549	ARG_SET_VALID(ar, ARG_TEXT);
550}
551
552void
553audit_arg_cmd(int cmd)
554{
555	struct kaudit_record *ar;
556
557	ar = currecord();
558	if (ar == NULL)
559		return;
560
561	ar->k_ar.ar_arg_cmd = cmd;
562	ARG_SET_VALID(ar, ARG_CMD);
563}
564
565void
566audit_arg_svipc_cmd(int cmd)
567{
568	struct kaudit_record *ar;
569
570	ar = currecord();
571	if (ar == NULL)
572		return;
573
574	ar->k_ar.ar_arg_svipc_cmd = cmd;
575	ARG_SET_VALID(ar, ARG_SVIPC_CMD);
576}
577
578void
579audit_arg_svipc_perm(struct ipc_perm *perm)
580{
581	struct kaudit_record *ar;
582
583	ar = currecord();
584	if (ar == NULL)
585		return;
586
587	bcopy(perm, &ar->k_ar.ar_arg_svipc_perm,
588	    sizeof(ar->k_ar.ar_arg_svipc_perm));
589	ARG_SET_VALID(ar, ARG_SVIPC_PERM);
590}
591
592void
593audit_arg_svipc_id(int id)
594{
595	struct kaudit_record *ar;
596
597	ar = currecord();
598	if (ar == NULL)
599		return;
600
601	ar->k_ar.ar_arg_svipc_id = id;
602	ARG_SET_VALID(ar, ARG_SVIPC_ID);
603}
604
605void
606audit_arg_svipc_addr(void * addr)
607{
608	struct kaudit_record *ar;
609
610	ar = currecord();
611	if (ar == NULL)
612		return;
613
614	ar->k_ar.ar_arg_svipc_addr = addr;
615	ARG_SET_VALID(ar, ARG_SVIPC_ADDR);
616}
617
618void
619audit_arg_posix_ipc_perm(uid_t uid, gid_t gid, mode_t mode)
620{
621	struct kaudit_record *ar;
622
623	ar = currecord();
624	if (ar == NULL)
625		return;
626
627	ar->k_ar.ar_arg_pipc_perm.pipc_uid = uid;
628	ar->k_ar.ar_arg_pipc_perm.pipc_gid = gid;
629	ar->k_ar.ar_arg_pipc_perm.pipc_mode = mode;
630	ARG_SET_VALID(ar, ARG_POSIX_IPC_PERM);
631}
632
633void
634audit_arg_auditon(union auditon_udata *udata)
635{
636	struct kaudit_record *ar;
637
638	ar = currecord();
639	if (ar == NULL)
640		return;
641
642	bcopy((void *)udata, &ar->k_ar.ar_arg_auditon,
643	    sizeof(ar->k_ar.ar_arg_auditon));
644	ARG_SET_VALID(ar, ARG_AUDITON);
645}
646
647/*
648 * Audit information about a file, either the file's vnode info, or its
649 * socket address info.
650 */
651void
652audit_arg_file(struct proc *p, struct file *fp)
653{
654	struct kaudit_record *ar;
655	struct socket *so;
656	struct inpcb *pcb;
657	struct vnode *vp;
658
659	ar = currecord();
660	if (ar == NULL)
661		return;
662
663	switch (fp->f_type) {
664	case DTYPE_VNODE:
665	case DTYPE_FIFO:
666		/*
667		 * XXXAUDIT: Only possibly to record as first vnode?
668		 */
669		vp = fp->f_vnode;
670		vn_lock(vp, LK_SHARED | LK_RETRY);
671		audit_arg_vnode1(vp);
672		VOP_UNLOCK(vp, 0);
673		break;
674
675	case DTYPE_SOCKET:
676		so = (struct socket *)fp->f_data;
677		if (INP_CHECK_SOCKAF(so, PF_INET)) {
678			SOCK_LOCK(so);
679			ar->k_ar.ar_arg_sockinfo.so_type =
680			    so->so_type;
681			ar->k_ar.ar_arg_sockinfo.so_domain =
682			    INP_SOCKAF(so);
683			ar->k_ar.ar_arg_sockinfo.so_protocol =
684			    so->so_proto->pr_protocol;
685			SOCK_UNLOCK(so);
686			pcb = (struct inpcb *)so->so_pcb;
687			INP_RLOCK(pcb);
688			ar->k_ar.ar_arg_sockinfo.so_raddr =
689			    pcb->inp_faddr.s_addr;
690			ar->k_ar.ar_arg_sockinfo.so_laddr =
691			    pcb->inp_laddr.s_addr;
692			ar->k_ar.ar_arg_sockinfo.so_rport =
693			    pcb->inp_fport;
694			ar->k_ar.ar_arg_sockinfo.so_lport =
695			    pcb->inp_lport;
696			INP_RUNLOCK(pcb);
697			ARG_SET_VALID(ar, ARG_SOCKINFO);
698		}
699		break;
700
701	default:
702		/* XXXAUDIT: else? */
703		break;
704	}
705}
706
707/*
708 * Store a path as given by the user process for auditing into the audit
709 * record stored on the user thread.  This function will allocate the memory
710 * to store the path info if not already available.  This memory will be
711 * freed when the audit record is freed.
712 */
713static void
714audit_arg_upath(struct thread *td, int dirfd, char *upath, char **pathp)
715{
716
717	if (*pathp == NULL)
718		*pathp = malloc(MAXPATHLEN, M_AUDITPATH, M_WAITOK);
719	audit_canon_path(td, dirfd, upath, *pathp);
720}
721
722void
723audit_arg_upath1(struct thread *td, int dirfd, char *upath)
724{
725	struct kaudit_record *ar;
726
727	ar = currecord();
728	if (ar == NULL)
729		return;
730
731	audit_arg_upath(td, dirfd, upath, &ar->k_ar.ar_arg_upath1);
732	ARG_SET_VALID(ar, ARG_UPATH1);
733}
734
735void
736audit_arg_upath2(struct thread *td, int dirfd, char *upath)
737{
738	struct kaudit_record *ar;
739
740	ar = currecord();
741	if (ar == NULL)
742		return;
743
744	audit_arg_upath(td, dirfd, upath, &ar->k_ar.ar_arg_upath2);
745	ARG_SET_VALID(ar, ARG_UPATH2);
746}
747
748/*
749 * Function to save the path and vnode attr information into the audit
750 * record.
751 *
752 * It is assumed that the caller will hold any vnode locks necessary to
753 * perform a VOP_GETATTR() on the passed vnode.
754 *
755 * XXX: The attr code is very similar to vfs_vnops.c:vn_stat(), but always
756 * provides access to the generation number as we need that to construct the
757 * BSM file ID.
758 *
759 * XXX: We should accept the process argument from the caller, since it's
760 * very likely they already have a reference.
761 *
762 * XXX: Error handling in this function is poor.
763 *
764 * XXXAUDIT: Possibly KASSERT the path pointer is NULL?
765 */
766static int
767audit_arg_vnode(struct vnode *vp, struct vnode_au_info *vnp)
768{
769	struct vattr vattr;
770	int error;
771
772	ASSERT_VOP_LOCKED(vp, "audit_arg_vnode");
773
774	error = VOP_GETATTR(vp, &vattr, curthread->td_ucred);
775	if (error) {
776		/* XXX: How to handle this case? */
777		return (error);
778	}
779
780	vnp->vn_mode = vattr.va_mode;
781	vnp->vn_uid = vattr.va_uid;
782	vnp->vn_gid = vattr.va_gid;
783	vnp->vn_dev = vattr.va_rdev;
784	vnp->vn_fsid = vattr.va_fsid;
785	vnp->vn_fileid = vattr.va_fileid;
786	vnp->vn_gen = vattr.va_gen;
787	return (0);
788}
789
790void
791audit_arg_vnode1(struct vnode *vp)
792{
793	struct kaudit_record *ar;
794	int error;
795
796	ar = currecord();
797	if (ar == NULL)
798		return;
799
800	ARG_CLEAR_VALID(ar, ARG_VNODE1);
801	error = audit_arg_vnode(vp, &ar->k_ar.ar_arg_vnode1);
802	if (error == 0)
803		ARG_SET_VALID(ar, ARG_VNODE1);
804}
805
806void
807audit_arg_vnode2(struct vnode *vp)
808{
809	struct kaudit_record *ar;
810	int error;
811
812	ar = currecord();
813	if (ar == NULL)
814		return;
815
816	ARG_CLEAR_VALID(ar, ARG_VNODE2);
817	error = audit_arg_vnode(vp, &ar->k_ar.ar_arg_vnode2);
818	if (error == 0)
819		ARG_SET_VALID(ar, ARG_VNODE2);
820}
821
822/*
823 * Audit the argument strings passed to exec.
824 */
825void
826audit_arg_argv(char *argv, int argc, int length)
827{
828	struct kaudit_record *ar;
829
830	if (audit_argv == 0)
831		return;
832
833	ar = currecord();
834	if (ar == NULL)
835		return;
836
837	ar->k_ar.ar_arg_argv = malloc(length, M_AUDITTEXT, M_WAITOK);
838	bcopy(argv, ar->k_ar.ar_arg_argv, length);
839	ar->k_ar.ar_arg_argc = argc;
840	ARG_SET_VALID(ar, ARG_ARGV);
841}
842
843/*
844 * Audit the environment strings passed to exec.
845 */
846void
847audit_arg_envv(char *envv, int envc, int length)
848{
849	struct kaudit_record *ar;
850
851	if (audit_arge == 0)
852		return;
853
854	ar = currecord();
855	if (ar == NULL)
856		return;
857
858	ar->k_ar.ar_arg_envv = malloc(length, M_AUDITTEXT, M_WAITOK);
859	bcopy(envv, ar->k_ar.ar_arg_envv, length);
860	ar->k_ar.ar_arg_envc = envc;
861	ARG_SET_VALID(ar, ARG_ENVV);
862}
863
864void
865audit_arg_rights(cap_rights_t *rightsp)
866{
867	struct kaudit_record *ar;
868
869	ar = currecord();
870	if (ar == NULL)
871		return;
872
873	ar->k_ar.ar_arg_rights = *rightsp;
874	ARG_SET_VALID(ar, ARG_RIGHTS);
875}
876
877void
878audit_arg_fcntl_rights(uint32_t fcntlrights)
879{
880	struct kaudit_record *ar;
881
882	ar = currecord();
883	if (ar == NULL)
884		return;
885
886	ar->k_ar.ar_arg_fcntl_rights = fcntlrights;
887	ARG_SET_VALID(ar, ARG_FCNTL_RIGHTS);
888}
889
890/*
891 * The close() system call uses it's own audit call to capture the path/vnode
892 * information because those pieces are not easily obtained within the system
893 * call itself.
894 */
895void
896audit_sysclose(struct thread *td, int fd)
897{
898	cap_rights_t rights;
899	struct kaudit_record *ar;
900	struct vnode *vp;
901	struct file *fp;
902
903	KASSERT(td != NULL, ("audit_sysclose: td == NULL"));
904
905	ar = currecord();
906	if (ar == NULL)
907		return;
908
909	audit_arg_fd(fd);
910
911	if (getvnode(td, fd, cap_rights_init(&rights), &fp) != 0)
912		return;
913
914	vp = fp->f_vnode;
915	vn_lock(vp, LK_SHARED | LK_RETRY);
916	audit_arg_vnode1(vp);
917	VOP_UNLOCK(vp, 0);
918	fdrop(fp, td);
919}
920