1181053Srwatson/*-
2180701Srwatson * Copyright (c) 1999-2005 Apple Inc.
3155192Srwatson * All rights reserved.
4155192Srwatson *
5155192Srwatson * Redistribution and use in source and binary forms, with or without
6155192Srwatson * modification, are permitted provided that the following conditions
7155192Srwatson * are met:
8155192Srwatson * 1.  Redistributions of source code must retain the above copyright
9155192Srwatson *     notice, this list of conditions and the following disclaimer.
10155192Srwatson * 2.  Redistributions in binary form must reproduce the above copyright
11155192Srwatson *     notice, this list of conditions and the following disclaimer in the
12155192Srwatson *     documentation and/or other materials provided with the distribution.
13180701Srwatson * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
14155192Srwatson *     its contributors may be used to endorse or promote products derived
15155192Srwatson *     from this software without specific prior written permission.
16155192Srwatson *
17155192Srwatson * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND
18155192Srwatson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19155192Srwatson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20155192Srwatson * ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR
21155192Srwatson * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22155192Srwatson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23155192Srwatson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24155192Srwatson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
25155192Srwatson * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
26155192Srwatson * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27155192Srwatson * POSSIBILITY OF SUCH DAMAGE.
28155192Srwatson */
29155192Srwatson
30178186Srwatson#include <sys/cdefs.h>
31178186Srwatson__FBSDID("$FreeBSD$");
32178186Srwatson
33155192Srwatson#include <sys/param.h>
34155192Srwatson#include <sys/filedesc.h>
35155192Srwatson#include <sys/ipc.h>
36155192Srwatson#include <sys/mount.h>
37155192Srwatson#include <sys/proc.h>
38155192Srwatson#include <sys/socket.h>
39155192Srwatson#include <sys/socketvar.h>
40155192Srwatson#include <sys/protosw.h>
41155192Srwatson#include <sys/domain.h>
42159277Srwatson#include <sys/sbuf.h>
43155192Srwatson#include <sys/systm.h>
44155192Srwatson#include <sys/un.h>
45155192Srwatson#include <sys/vnode.h>
46155192Srwatson
47155192Srwatson#include <netinet/in.h>
48155192Srwatson#include <netinet/in_pcb.h>
49155192Srwatson
50155192Srwatson#include <security/audit/audit.h>
51155192Srwatson#include <security/audit/audit_private.h>
52155192Srwatson
53155192Srwatson/*
54155192Srwatson * Calls to manipulate elements of the audit record structure from system
55170196Srwatson * call code.  Macro wrappers will prevent this functions from being entered
56170196Srwatson * if auditing is disabled, avoiding the function call cost.  We check the
57170196Srwatson * thread audit record pointer anyway, as the audit condition could change,
58170196Srwatson * and pre-selection may not have allocated an audit record for this event.
59155192Srwatson *
60155192Srwatson * XXXAUDIT: Should we assert, in each case, that this field of the record
61155192Srwatson * hasn't already been filled in?
62155192Srwatson */
63155192Srwatsonvoid
64170585Srwatsonaudit_arg_addr(void *addr)
65155192Srwatson{
66155192Srwatson	struct kaudit_record *ar;
67155192Srwatson
68155192Srwatson	ar = currecord();
69155192Srwatson	if (ar == NULL)
70155192Srwatson		return;
71155192Srwatson
72155192Srwatson	ar->k_ar.ar_arg_addr = addr;
73155192Srwatson	ARG_SET_VALID(ar, ARG_ADDR);
74155192Srwatson}
75155192Srwatson
76155192Srwatsonvoid
77155192Srwatsonaudit_arg_exit(int status, int retval)
78155192Srwatson{
79155192Srwatson	struct kaudit_record *ar;
80155192Srwatson
81155192Srwatson	ar = currecord();
82155192Srwatson	if (ar == NULL)
83155192Srwatson		return;
84155192Srwatson
85155192Srwatson	ar->k_ar.ar_arg_exitstatus = status;
86155192Srwatson	ar->k_ar.ar_arg_exitretval = retval;
87155192Srwatson	ARG_SET_VALID(ar, ARG_EXIT);
88155192Srwatson}
89155192Srwatson
90155192Srwatsonvoid
91155192Srwatsonaudit_arg_len(int len)
92155192Srwatson{
93155192Srwatson	struct kaudit_record *ar;
94155192Srwatson
95155192Srwatson	ar = currecord();
96155192Srwatson	if (ar == NULL)
97155192Srwatson		return;
98155192Srwatson
99155192Srwatson	ar->k_ar.ar_arg_len = len;
100155192Srwatson	ARG_SET_VALID(ar, ARG_LEN);
101155192Srwatson}
102155192Srwatson
103155192Srwatsonvoid
104195925Srwatsonaudit_arg_atfd1(int atfd)
105195925Srwatson{
106195925Srwatson	struct kaudit_record *ar;
107195925Srwatson
108195925Srwatson	ar = currecord();
109195925Srwatson	if (ar == NULL)
110195925Srwatson		return;
111195925Srwatson
112195925Srwatson	ar->k_ar.ar_arg_atfd1 = atfd;
113195925Srwatson	ARG_SET_VALID(ar, ARG_ATFD1);
114195925Srwatson}
115195925Srwatson
116195925Srwatsonvoid
117195925Srwatsonaudit_arg_atfd2(int atfd)
118195925Srwatson{
119195925Srwatson	struct kaudit_record *ar;
120195925Srwatson
121195925Srwatson	ar = currecord();
122195925Srwatson	if (ar == NULL)
123195925Srwatson		return;
124195925Srwatson
125195925Srwatson	ar->k_ar.ar_arg_atfd2 = atfd;
126195925Srwatson	ARG_SET_VALID(ar, ARG_ATFD2);
127195925Srwatson}
128195925Srwatson
129195925Srwatsonvoid
130155192Srwatsonaudit_arg_fd(int fd)
131155192Srwatson{
132155192Srwatson	struct kaudit_record *ar;
133155192Srwatson
134155192Srwatson	ar = currecord();
135155192Srwatson	if (ar == NULL)
136155192Srwatson		return;
137155192Srwatson
138155192Srwatson	ar->k_ar.ar_arg_fd = fd;
139155192Srwatson	ARG_SET_VALID(ar, ARG_FD);
140155192Srwatson}
141155192Srwatson
142155192Srwatsonvoid
143155192Srwatsonaudit_arg_fflags(int fflags)
144155192Srwatson{
145155192Srwatson	struct kaudit_record *ar;
146155192Srwatson
147155192Srwatson	ar = currecord();
148155192Srwatson	if (ar == NULL)
149155192Srwatson		return;
150155192Srwatson
151155192Srwatson	ar->k_ar.ar_arg_fflags = fflags;
152155192Srwatson	ARG_SET_VALID(ar, ARG_FFLAGS);
153155192Srwatson}
154155192Srwatson
155155192Srwatsonvoid
156155192Srwatsonaudit_arg_gid(gid_t gid)
157155192Srwatson{
158155192Srwatson	struct kaudit_record *ar;
159155192Srwatson
160155192Srwatson	ar = currecord();
161155192Srwatson	if (ar == NULL)
162155192Srwatson		return;
163155192Srwatson
164155192Srwatson	ar->k_ar.ar_arg_gid = gid;
165155192Srwatson	ARG_SET_VALID(ar, ARG_GID);
166155192Srwatson}
167155192Srwatson
168155192Srwatsonvoid
169155192Srwatsonaudit_arg_uid(uid_t uid)
170155192Srwatson{
171155192Srwatson	struct kaudit_record *ar;
172155192Srwatson
173155192Srwatson	ar = currecord();
174155192Srwatson	if (ar == NULL)
175155192Srwatson		return;
176155192Srwatson
177155192Srwatson	ar->k_ar.ar_arg_uid = uid;
178155192Srwatson	ARG_SET_VALID(ar, ARG_UID);
179155192Srwatson}
180155192Srwatson
181155192Srwatsonvoid
182155192Srwatsonaudit_arg_egid(gid_t egid)
183155192Srwatson{
184155192Srwatson	struct kaudit_record *ar;
185155192Srwatson
186155192Srwatson	ar = currecord();
187155192Srwatson	if (ar == NULL)
188155192Srwatson		return;
189155192Srwatson
190155192Srwatson	ar->k_ar.ar_arg_egid = egid;
191155192Srwatson	ARG_SET_VALID(ar, ARG_EGID);
192155192Srwatson}
193155192Srwatson
194155192Srwatsonvoid
195155192Srwatsonaudit_arg_euid(uid_t euid)
196155192Srwatson{
197155192Srwatson	struct kaudit_record *ar;
198155192Srwatson
199155192Srwatson	ar = currecord();
200155192Srwatson	if (ar == NULL)
201155192Srwatson		return;
202155192Srwatson
203155192Srwatson	ar->k_ar.ar_arg_euid = euid;
204155192Srwatson	ARG_SET_VALID(ar, ARG_EUID);
205155192Srwatson}
206155192Srwatson
207155192Srwatsonvoid
208155192Srwatsonaudit_arg_rgid(gid_t rgid)
209155192Srwatson{
210155192Srwatson	struct kaudit_record *ar;
211155192Srwatson
212155192Srwatson	ar = currecord();
213155192Srwatson	if (ar == NULL)
214155192Srwatson		return;
215155192Srwatson
216155192Srwatson	ar->k_ar.ar_arg_rgid = rgid;
217155192Srwatson	ARG_SET_VALID(ar, ARG_RGID);
218155192Srwatson}
219155192Srwatson
220155192Srwatsonvoid
221155192Srwatsonaudit_arg_ruid(uid_t ruid)
222155192Srwatson{
223155192Srwatson	struct kaudit_record *ar;
224155192Srwatson
225155192Srwatson	ar = currecord();
226155192Srwatson	if (ar == NULL)
227155192Srwatson		return;
228155192Srwatson
229155192Srwatson	ar->k_ar.ar_arg_ruid = ruid;
230155192Srwatson	ARG_SET_VALID(ar, ARG_RUID);
231155192Srwatson}
232155192Srwatson
233155192Srwatsonvoid
234155192Srwatsonaudit_arg_sgid(gid_t sgid)
235155192Srwatson{
236155192Srwatson	struct kaudit_record *ar;
237155192Srwatson
238155192Srwatson	ar = currecord();
239155192Srwatson	if (ar == NULL)
240155192Srwatson		return;
241155192Srwatson
242155192Srwatson	ar->k_ar.ar_arg_sgid = sgid;
243155192Srwatson	ARG_SET_VALID(ar, ARG_SGID);
244155192Srwatson}
245155192Srwatson
246155192Srwatsonvoid
247155192Srwatsonaudit_arg_suid(uid_t suid)
248155192Srwatson{
249155192Srwatson	struct kaudit_record *ar;
250155192Srwatson
251155192Srwatson	ar = currecord();
252155192Srwatson	if (ar == NULL)
253155192Srwatson		return;
254155192Srwatson
255155192Srwatson	ar->k_ar.ar_arg_suid = suid;
256155192Srwatson	ARG_SET_VALID(ar, ARG_SUID);
257155192Srwatson}
258155192Srwatson
259155192Srwatsonvoid
260155192Srwatsonaudit_arg_groupset(gid_t *gidset, u_int gidset_size)
261155192Srwatson{
262180699Srwatson	u_int i;
263155192Srwatson	struct kaudit_record *ar;
264155192Srwatson
265202143Sbrooks	KASSERT(gidset_size <= ngroups_max + 1,
266202143Sbrooks	    ("audit_arg_groupset: gidset_size > (kern.ngroups + 1)"));
267195177Ssson
268155192Srwatson	ar = currecord();
269155192Srwatson	if (ar == NULL)
270155192Srwatson		return;
271155192Srwatson
272195177Ssson	if (ar->k_ar.ar_arg_groups.gidset == NULL)
273195177Ssson		ar->k_ar.ar_arg_groups.gidset = malloc(
274195177Ssson		    sizeof(gid_t) * gidset_size, M_AUDITGIDSET, M_WAITOK);
275195177Ssson
276155192Srwatson	for (i = 0; i < gidset_size; i++)
277155192Srwatson		ar->k_ar.ar_arg_groups.gidset[i] = gidset[i];
278155192Srwatson	ar->k_ar.ar_arg_groups.gidset_size = gidset_size;
279155192Srwatson	ARG_SET_VALID(ar, ARG_GROUPSET);
280155192Srwatson}
281155192Srwatson
282155192Srwatsonvoid
283155192Srwatsonaudit_arg_login(char *login)
284155192Srwatson{
285155192Srwatson	struct kaudit_record *ar;
286155192Srwatson
287155192Srwatson	ar = currecord();
288155192Srwatson	if (ar == NULL)
289155192Srwatson		return;
290155192Srwatson
291155192Srwatson	strlcpy(ar->k_ar.ar_arg_login, login, MAXLOGNAME);
292155192Srwatson	ARG_SET_VALID(ar, ARG_LOGIN);
293155192Srwatson}
294155192Srwatson
295155192Srwatsonvoid
296155192Srwatsonaudit_arg_ctlname(int *name, int namelen)
297155192Srwatson{
298155192Srwatson	struct kaudit_record *ar;
299155192Srwatson
300155192Srwatson	ar = currecord();
301155192Srwatson	if (ar == NULL)
302155192Srwatson		return;
303155192Srwatson
304155192Srwatson	bcopy(name, &ar->k_ar.ar_arg_ctlname, namelen * sizeof(int));
305155192Srwatson	ar->k_ar.ar_arg_len = namelen;
306155192Srwatson	ARG_SET_VALID(ar, ARG_CTLNAME | ARG_LEN);
307155192Srwatson}
308155192Srwatson
309155192Srwatsonvoid
310155192Srwatsonaudit_arg_mask(int mask)
311155192Srwatson{
312155192Srwatson	struct kaudit_record *ar;
313155192Srwatson
314155192Srwatson	ar = currecord();
315155192Srwatson	if (ar == NULL)
316155192Srwatson		return;
317155192Srwatson
318155192Srwatson	ar->k_ar.ar_arg_mask = mask;
319155192Srwatson	ARG_SET_VALID(ar, ARG_MASK);
320155192Srwatson}
321155192Srwatson
322155192Srwatsonvoid
323155192Srwatsonaudit_arg_mode(mode_t mode)
324155192Srwatson{
325155192Srwatson	struct kaudit_record *ar;
326155192Srwatson
327155192Srwatson	ar = currecord();
328155192Srwatson	if (ar == NULL)
329155192Srwatson		return;
330155192Srwatson
331155192Srwatson	ar->k_ar.ar_arg_mode = mode;
332155192Srwatson	ARG_SET_VALID(ar, ARG_MODE);
333155192Srwatson}
334155192Srwatson
335155192Srwatsonvoid
336155192Srwatsonaudit_arg_dev(int dev)
337155192Srwatson{
338155192Srwatson	struct kaudit_record *ar;
339155192Srwatson
340155192Srwatson	ar = currecord();
341155192Srwatson	if (ar == NULL)
342155192Srwatson		return;
343155192Srwatson
344155192Srwatson	ar->k_ar.ar_arg_dev = dev;
345155192Srwatson	ARG_SET_VALID(ar, ARG_DEV);
346155192Srwatson}
347155192Srwatson
348155192Srwatsonvoid
349155192Srwatsonaudit_arg_value(long value)
350155192Srwatson{
351155192Srwatson	struct kaudit_record *ar;
352155192Srwatson
353155192Srwatson	ar = currecord();
354155192Srwatson	if (ar == NULL)
355155192Srwatson		return;
356155192Srwatson
357155192Srwatson	ar->k_ar.ar_arg_value = value;
358155192Srwatson	ARG_SET_VALID(ar, ARG_VALUE);
359155192Srwatson}
360155192Srwatson
361155192Srwatsonvoid
362155192Srwatsonaudit_arg_owner(uid_t uid, gid_t gid)
363155192Srwatson{
364155192Srwatson	struct kaudit_record *ar;
365155192Srwatson
366155192Srwatson	ar = currecord();
367155192Srwatson	if (ar == NULL)
368155192Srwatson		return;
369155192Srwatson
370155192Srwatson	ar->k_ar.ar_arg_uid = uid;
371155192Srwatson	ar->k_ar.ar_arg_gid = gid;
372155192Srwatson	ARG_SET_VALID(ar, ARG_UID | ARG_GID);
373155192Srwatson}
374155192Srwatson
375155192Srwatsonvoid
376155192Srwatsonaudit_arg_pid(pid_t pid)
377155192Srwatson{
378155192Srwatson	struct kaudit_record *ar;
379155192Srwatson
380155192Srwatson	ar = currecord();
381155192Srwatson	if (ar == NULL)
382155192Srwatson		return;
383155192Srwatson
384155192Srwatson	ar->k_ar.ar_arg_pid = pid;
385155192Srwatson	ARG_SET_VALID(ar, ARG_PID);
386155192Srwatson}
387155192Srwatson
388155192Srwatsonvoid
389155192Srwatsonaudit_arg_process(struct proc *p)
390155192Srwatson{
391155192Srwatson	struct kaudit_record *ar;
392184948Srwatson	struct ucred *cred;
393155192Srwatson
394160086Srwatson	KASSERT(p != NULL, ("audit_arg_process: p == NULL"));
395160086Srwatson
396160086Srwatson	PROC_LOCK_ASSERT(p, MA_OWNED);
397160086Srwatson
398155192Srwatson	ar = currecord();
399160086Srwatson	if (ar == NULL)
400155192Srwatson		return;
401155192Srwatson
402184948Srwatson	cred = p->p_ucred;
403184948Srwatson	ar->k_ar.ar_arg_auid = cred->cr_audit.ai_auid;
404184948Srwatson	ar->k_ar.ar_arg_euid = cred->cr_uid;
405184948Srwatson	ar->k_ar.ar_arg_egid = cred->cr_groups[0];
406184948Srwatson	ar->k_ar.ar_arg_ruid = cred->cr_ruid;
407184948Srwatson	ar->k_ar.ar_arg_rgid = cred->cr_rgid;
408184948Srwatson	ar->k_ar.ar_arg_asid = cred->cr_audit.ai_asid;
409184948Srwatson	ar->k_ar.ar_arg_termid_addr = cred->cr_audit.ai_termid;
410159277Srwatson	ar->k_ar.ar_arg_pid = p->p_pid;
411155192Srwatson	ARG_SET_VALID(ar, ARG_AUID | ARG_EUID | ARG_EGID | ARG_RUID |
412168688Scsjp	    ARG_RGID | ARG_ASID | ARG_TERMID_ADDR | ARG_PID | ARG_PROCESS);
413155192Srwatson}
414155192Srwatson
415155192Srwatsonvoid
416155192Srwatsonaudit_arg_signum(u_int signum)
417155192Srwatson{
418155192Srwatson	struct kaudit_record *ar;
419155192Srwatson
420155192Srwatson	ar = currecord();
421155192Srwatson	if (ar == NULL)
422155192Srwatson		return;
423155192Srwatson
424155192Srwatson	ar->k_ar.ar_arg_signum = signum;
425155192Srwatson	ARG_SET_VALID(ar, ARG_SIGNUM);
426155192Srwatson}
427155192Srwatson
428155192Srwatsonvoid
429155192Srwatsonaudit_arg_socket(int sodomain, int sotype, int soprotocol)
430155192Srwatson{
431155192Srwatson	struct kaudit_record *ar;
432156889Srwatson
433155192Srwatson	ar = currecord();
434155192Srwatson	if (ar == NULL)
435155192Srwatson		return;
436155192Srwatson
437155192Srwatson	ar->k_ar.ar_arg_sockinfo.so_domain = sodomain;
438155192Srwatson	ar->k_ar.ar_arg_sockinfo.so_type = sotype;
439155192Srwatson	ar->k_ar.ar_arg_sockinfo.so_protocol = soprotocol;
440155192Srwatson	ARG_SET_VALID(ar, ARG_SOCKINFO);
441155192Srwatson}
442155192Srwatson
443155192Srwatsonvoid
444247667Spjdaudit_arg_sockaddr(struct thread *td, int dirfd, struct sockaddr *sa)
445155192Srwatson{
446155192Srwatson	struct kaudit_record *ar;
447155192Srwatson
448160086Srwatson	KASSERT(td != NULL, ("audit_arg_sockaddr: td == NULL"));
449160086Srwatson	KASSERT(sa != NULL, ("audit_arg_sockaddr: sa == NULL"));
450160086Srwatson
451155192Srwatson	ar = currecord();
452160086Srwatson	if (ar == NULL)
453155192Srwatson		return;
454155192Srwatson
455164011Scsjp	bcopy(sa, &ar->k_ar.ar_arg_sockaddr, sa->sa_len);
456160086Srwatson	switch (sa->sa_family) {
457155192Srwatson	case AF_INET:
458155192Srwatson		ARG_SET_VALID(ar, ARG_SADDRINET);
459155192Srwatson		break;
460155192Srwatson
461155192Srwatson	case AF_INET6:
462155192Srwatson		ARG_SET_VALID(ar, ARG_SADDRINET6);
463155192Srwatson		break;
464155192Srwatson
465155192Srwatson	case AF_UNIX:
466247667Spjd		if (dirfd != AT_FDCWD)
467247667Spjd			audit_arg_atfd1(dirfd);
468247667Spjd		audit_arg_upath1(td, dirfd,
469243726Spjd		    ((struct sockaddr_un *)sa)->sun_path);
470155192Srwatson		ARG_SET_VALID(ar, ARG_SADDRUNIX);
471155192Srwatson		break;
472155192Srwatson	/* XXXAUDIT: default:? */
473155192Srwatson	}
474155192Srwatson}
475155192Srwatson
476155192Srwatsonvoid
477155192Srwatsonaudit_arg_auid(uid_t auid)
478155192Srwatson{
479155192Srwatson	struct kaudit_record *ar;
480155192Srwatson
481155192Srwatson	ar = currecord();
482155192Srwatson	if (ar == NULL)
483155192Srwatson		return;
484155192Srwatson
485155192Srwatson	ar->k_ar.ar_arg_auid = auid;
486155192Srwatson	ARG_SET_VALID(ar, ARG_AUID);
487155192Srwatson}
488155192Srwatson
489155192Srwatsonvoid
490155192Srwatsonaudit_arg_auditinfo(struct auditinfo *au_info)
491155192Srwatson{
492155192Srwatson	struct kaudit_record *ar;
493155192Srwatson
494155192Srwatson	ar = currecord();
495155192Srwatson	if (ar == NULL)
496155192Srwatson		return;
497155192Srwatson
498155192Srwatson	ar->k_ar.ar_arg_auid = au_info->ai_auid;
499155192Srwatson	ar->k_ar.ar_arg_asid = au_info->ai_asid;
500155192Srwatson	ar->k_ar.ar_arg_amask.am_success = au_info->ai_mask.am_success;
501155192Srwatson	ar->k_ar.ar_arg_amask.am_failure = au_info->ai_mask.am_failure;
502155192Srwatson	ar->k_ar.ar_arg_termid.port = au_info->ai_termid.port;
503155192Srwatson	ar->k_ar.ar_arg_termid.machine = au_info->ai_termid.machine;
504155192Srwatson	ARG_SET_VALID(ar, ARG_AUID | ARG_ASID | ARG_AMASK | ARG_TERMID);
505155192Srwatson}
506155192Srwatson
507155192Srwatsonvoid
508171066Scsjpaudit_arg_auditinfo_addr(struct auditinfo_addr *au_info)
509171066Scsjp{
510171066Scsjp	struct kaudit_record *ar;
511171066Scsjp
512171066Scsjp	ar = currecord();
513171066Scsjp	if (ar == NULL)
514171066Scsjp		return;
515171066Scsjp
516171066Scsjp	ar->k_ar.ar_arg_auid = au_info->ai_auid;
517171066Scsjp	ar->k_ar.ar_arg_asid = au_info->ai_asid;
518171066Scsjp	ar->k_ar.ar_arg_amask.am_success = au_info->ai_mask.am_success;
519171066Scsjp	ar->k_ar.ar_arg_amask.am_failure = au_info->ai_mask.am_failure;
520171066Scsjp	ar->k_ar.ar_arg_termid_addr.at_type = au_info->ai_termid.at_type;
521171066Scsjp	ar->k_ar.ar_arg_termid_addr.at_port = au_info->ai_termid.at_port;
522171066Scsjp	ar->k_ar.ar_arg_termid_addr.at_addr[0] = au_info->ai_termid.at_addr[0];
523171066Scsjp	ar->k_ar.ar_arg_termid_addr.at_addr[1] = au_info->ai_termid.at_addr[1];
524171066Scsjp	ar->k_ar.ar_arg_termid_addr.at_addr[2] = au_info->ai_termid.at_addr[2];
525171066Scsjp	ar->k_ar.ar_arg_termid_addr.at_addr[3] = au_info->ai_termid.at_addr[3];
526171066Scsjp	ARG_SET_VALID(ar, ARG_AUID | ARG_ASID | ARG_AMASK | ARG_TERMID_ADDR);
527171066Scsjp}
528171066Scsjp
529171066Scsjpvoid
530155192Srwatsonaudit_arg_text(char *text)
531155192Srwatson{
532155192Srwatson	struct kaudit_record *ar;
533155192Srwatson
534160086Srwatson	KASSERT(text != NULL, ("audit_arg_text: text == NULL"));
535160086Srwatson
536155192Srwatson	ar = currecord();
537155192Srwatson	if (ar == NULL)
538155192Srwatson		return;
539155192Srwatson
540155192Srwatson	/* Invalidate the text string */
541155192Srwatson	ar->k_ar.ar_valid_arg &= (ARG_ALL ^ ARG_TEXT);
542155192Srwatson
543155192Srwatson	if (ar->k_ar.ar_arg_text == NULL)
544155192Srwatson		ar->k_ar.ar_arg_text = malloc(MAXPATHLEN, M_AUDITTEXT,
545155192Srwatson		    M_WAITOK);
546155192Srwatson
547155192Srwatson	strncpy(ar->k_ar.ar_arg_text, text, MAXPATHLEN);
548155192Srwatson	ARG_SET_VALID(ar, ARG_TEXT);
549155192Srwatson}
550155192Srwatson
551155192Srwatsonvoid
552155192Srwatsonaudit_arg_cmd(int cmd)
553155192Srwatson{
554155192Srwatson	struct kaudit_record *ar;
555155192Srwatson
556155192Srwatson	ar = currecord();
557155192Srwatson	if (ar == NULL)
558155192Srwatson		return;
559155192Srwatson
560155192Srwatson	ar->k_ar.ar_arg_cmd = cmd;
561155192Srwatson	ARG_SET_VALID(ar, ARG_CMD);
562155192Srwatson}
563155192Srwatson
564155192Srwatsonvoid
565155192Srwatsonaudit_arg_svipc_cmd(int cmd)
566155192Srwatson{
567155192Srwatson	struct kaudit_record *ar;
568155192Srwatson
569155192Srwatson	ar = currecord();
570155192Srwatson	if (ar == NULL)
571155192Srwatson		return;
572155192Srwatson
573155192Srwatson	ar->k_ar.ar_arg_svipc_cmd = cmd;
574155192Srwatson	ARG_SET_VALID(ar, ARG_SVIPC_CMD);
575155192Srwatson}
576155192Srwatson
577155192Srwatsonvoid
578155192Srwatsonaudit_arg_svipc_perm(struct ipc_perm *perm)
579155192Srwatson{
580155192Srwatson	struct kaudit_record *ar;
581155192Srwatson
582155192Srwatson	ar = currecord();
583155192Srwatson	if (ar == NULL)
584155192Srwatson		return;
585155192Srwatson
586156889Srwatson	bcopy(perm, &ar->k_ar.ar_arg_svipc_perm,
587156889Srwatson	    sizeof(ar->k_ar.ar_arg_svipc_perm));
588155192Srwatson	ARG_SET_VALID(ar, ARG_SVIPC_PERM);
589155192Srwatson}
590155192Srwatson
591155192Srwatsonvoid
592155192Srwatsonaudit_arg_svipc_id(int id)
593155192Srwatson{
594155192Srwatson	struct kaudit_record *ar;
595155192Srwatson
596155192Srwatson	ar = currecord();
597155192Srwatson	if (ar == NULL)
598155192Srwatson		return;
599155192Srwatson
600155192Srwatson	ar->k_ar.ar_arg_svipc_id = id;
601155192Srwatson	ARG_SET_VALID(ar, ARG_SVIPC_ID);
602155192Srwatson}
603155192Srwatson
604155192Srwatsonvoid
605155192Srwatsonaudit_arg_svipc_addr(void * addr)
606155192Srwatson{
607155192Srwatson	struct kaudit_record *ar;
608155192Srwatson
609155192Srwatson	ar = currecord();
610155192Srwatson	if (ar == NULL)
611155192Srwatson		return;
612155192Srwatson
613155192Srwatson	ar->k_ar.ar_arg_svipc_addr = addr;
614155192Srwatson	ARG_SET_VALID(ar, ARG_SVIPC_ADDR);
615155192Srwatson}
616155192Srwatson
617155192Srwatsonvoid
618155192Srwatsonaudit_arg_posix_ipc_perm(uid_t uid, gid_t gid, mode_t mode)
619155192Srwatson{
620155192Srwatson	struct kaudit_record *ar;
621155192Srwatson
622155192Srwatson	ar = currecord();
623155192Srwatson	if (ar == NULL)
624155192Srwatson		return;
625155192Srwatson
626155192Srwatson	ar->k_ar.ar_arg_pipc_perm.pipc_uid = uid;
627155192Srwatson	ar->k_ar.ar_arg_pipc_perm.pipc_gid = gid;
628155192Srwatson	ar->k_ar.ar_arg_pipc_perm.pipc_mode = mode;
629155192Srwatson	ARG_SET_VALID(ar, ARG_POSIX_IPC_PERM);
630155192Srwatson}
631155192Srwatson
632155192Srwatsonvoid
633155192Srwatsonaudit_arg_auditon(union auditon_udata *udata)
634155192Srwatson{
635155192Srwatson	struct kaudit_record *ar;
636155192Srwatson
637155192Srwatson	ar = currecord();
638155192Srwatson	if (ar == NULL)
639155192Srwatson		return;
640155192Srwatson
641156889Srwatson	bcopy((void *)udata, &ar->k_ar.ar_arg_auditon,
642156889Srwatson	    sizeof(ar->k_ar.ar_arg_auditon));
643155192Srwatson	ARG_SET_VALID(ar, ARG_AUDITON);
644155192Srwatson}
645155192Srwatson
646155192Srwatson/*
647155192Srwatson * Audit information about a file, either the file's vnode info, or its
648155192Srwatson * socket address info.
649155192Srwatson */
650155192Srwatsonvoid
651155192Srwatsonaudit_arg_file(struct proc *p, struct file *fp)
652155192Srwatson{
653155192Srwatson	struct kaudit_record *ar;
654155192Srwatson	struct socket *so;
655155192Srwatson	struct inpcb *pcb;
656155192Srwatson	struct vnode *vp;
657155192Srwatson
658160086Srwatson	ar = currecord();
659160086Srwatson	if (ar == NULL)
660160086Srwatson		return;
661160086Srwatson
662155192Srwatson	switch (fp->f_type) {
663155192Srwatson	case DTYPE_VNODE:
664155192Srwatson	case DTYPE_FIFO:
665155192Srwatson		/*
666155192Srwatson		 * XXXAUDIT: Only possibly to record as first vnode?
667155192Srwatson		 */
668155192Srwatson		vp = fp->f_vnode;
669184661Sjhb		vn_lock(vp, LK_SHARED | LK_RETRY);
670195926Srwatson		audit_arg_vnode1(vp);
671175294Sattilio		VOP_UNLOCK(vp, 0);
672155192Srwatson		break;
673155192Srwatson
674155192Srwatson	case DTYPE_SOCKET:
675155192Srwatson		so = (struct socket *)fp->f_data;
676155192Srwatson		if (INP_CHECK_SOCKAF(so, PF_INET)) {
677166845Srwatson			SOCK_LOCK(so);
678155192Srwatson			ar->k_ar.ar_arg_sockinfo.so_type =
679156889Srwatson			    so->so_type;
680155192Srwatson			ar->k_ar.ar_arg_sockinfo.so_domain =
681156889Srwatson			    INP_SOCKAF(so);
682155192Srwatson			ar->k_ar.ar_arg_sockinfo.so_protocol =
683156889Srwatson			    so->so_proto->pr_protocol;
684166845Srwatson			SOCK_UNLOCK(so);
685155192Srwatson			pcb = (struct inpcb *)so->so_pcb;
686178322Srwatson			INP_RLOCK(pcb);
687155192Srwatson			ar->k_ar.ar_arg_sockinfo.so_raddr =
688156889Srwatson			    pcb->inp_faddr.s_addr;
689155192Srwatson			ar->k_ar.ar_arg_sockinfo.so_laddr =
690156889Srwatson			    pcb->inp_laddr.s_addr;
691155192Srwatson			ar->k_ar.ar_arg_sockinfo.so_rport =
692156889Srwatson			    pcb->inp_fport;
693155192Srwatson			ar->k_ar.ar_arg_sockinfo.so_lport =
694156889Srwatson			    pcb->inp_lport;
695178322Srwatson			INP_RUNLOCK(pcb);
696155192Srwatson			ARG_SET_VALID(ar, ARG_SOCKINFO);
697155192Srwatson		}
698155192Srwatson		break;
699155192Srwatson
700155192Srwatson	default:
701155192Srwatson		/* XXXAUDIT: else? */
702155192Srwatson		break;
703155192Srwatson	}
704155192Srwatson}
705155192Srwatson
706156889Srwatson/*
707156889Srwatson * Store a path as given by the user process for auditing into the audit
708180703Srwatson * record stored on the user thread.  This function will allocate the memory
709180703Srwatson * to store the path info if not already available.  This memory will be
710180703Srwatson * freed when the audit record is freed.
711155192Srwatson */
712195939Srwatsonstatic void
713243726Spjdaudit_arg_upath(struct thread *td, int dirfd, char *upath, char **pathp)
714195939Srwatson{
715195939Srwatson
716195939Srwatson	if (*pathp == NULL)
717195939Srwatson		*pathp = malloc(MAXPATHLEN, M_AUDITPATH, M_WAITOK);
718243726Spjd	audit_canon_path(td, dirfd, upath, *pathp);
719195939Srwatson}
720195939Srwatson
721155192Srwatsonvoid
722243726Spjdaudit_arg_upath1(struct thread *td, int dirfd, char *upath)
723155192Srwatson{
724155192Srwatson	struct kaudit_record *ar;
725155192Srwatson
726160086Srwatson	ar = currecord();
727160086Srwatson	if (ar == NULL)
728160086Srwatson		return;
729160086Srwatson
730243726Spjd	audit_arg_upath(td, dirfd, upath, &ar->k_ar.ar_arg_upath1);
731195939Srwatson	ARG_SET_VALID(ar, ARG_UPATH1);
732195939Srwatson}
733155192Srwatson
734195939Srwatsonvoid
735243726Spjdaudit_arg_upath2(struct thread *td, int dirfd, char *upath)
736195939Srwatson{
737195939Srwatson	struct kaudit_record *ar;
738155192Srwatson
739195939Srwatson	ar = currecord();
740195939Srwatson	if (ar == NULL)
741195939Srwatson		return;
742155192Srwatson
743243726Spjd	audit_arg_upath(td, dirfd, upath, &ar->k_ar.ar_arg_upath2);
744195939Srwatson	ARG_SET_VALID(ar, ARG_UPATH2);
745155192Srwatson}
746155192Srwatson
747155192Srwatson/*
748156889Srwatson * Function to save the path and vnode attr information into the audit
749156889Srwatson * record.
750155192Srwatson *
751155192Srwatson * It is assumed that the caller will hold any vnode locks necessary to
752155192Srwatson * perform a VOP_GETATTR() on the passed vnode.
753155192Srwatson *
754170196Srwatson * XXX: The attr code is very similar to vfs_vnops.c:vn_stat(), but always
755170196Srwatson * provides access to the generation number as we need that to construct the
756170196Srwatson * BSM file ID.
757170196Srwatson *
758170196Srwatson * XXX: We should accept the process argument from the caller, since it's
759170196Srwatson * very likely they already have a reference.
760170196Srwatson *
761155192Srwatson * XXX: Error handling in this function is poor.
762155192Srwatson *
763155192Srwatson * XXXAUDIT: Possibly KASSERT the path pointer is NULL?
764155192Srwatson */
765195926Srwatsonstatic int
766195926Srwatsonaudit_arg_vnode(struct vnode *vp, struct vnode_au_info *vnp)
767155192Srwatson{
768155192Srwatson	struct vattr vattr;
769155192Srwatson	int error;
770155192Srwatson
771155192Srwatson	ASSERT_VOP_LOCKED(vp, "audit_arg_vnode");
772155192Srwatson
773182371Sattilio	error = VOP_GETATTR(vp, &vattr, curthread->td_ucred);
774155192Srwatson	if (error) {
775155192Srwatson		/* XXX: How to handle this case? */
776195926Srwatson		return (error);
777155192Srwatson	}
778155192Srwatson
779155192Srwatson	vnp->vn_mode = vattr.va_mode;
780155192Srwatson	vnp->vn_uid = vattr.va_uid;
781155192Srwatson	vnp->vn_gid = vattr.va_gid;
782155192Srwatson	vnp->vn_dev = vattr.va_rdev;
783155192Srwatson	vnp->vn_fsid = vattr.va_fsid;
784155192Srwatson	vnp->vn_fileid = vattr.va_fileid;
785155192Srwatson	vnp->vn_gen = vattr.va_gen;
786195926Srwatson	return (0);
787195926Srwatson}
788195926Srwatson
789195926Srwatsonvoid
790195926Srwatsonaudit_arg_vnode1(struct vnode *vp)
791195926Srwatson{
792195926Srwatson	struct kaudit_record *ar;
793195926Srwatson	int error;
794195926Srwatson
795195926Srwatson	ar = currecord();
796195926Srwatson	if (ar == NULL)
797195926Srwatson		return;
798195926Srwatson
799195926Srwatson	ARG_CLEAR_VALID(ar, ARG_VNODE1);
800195926Srwatson	error = audit_arg_vnode(vp, &ar->k_ar.ar_arg_vnode1);
801195926Srwatson	if (error == 0)
802155192Srwatson		ARG_SET_VALID(ar, ARG_VNODE1);
803195926Srwatson}
804195926Srwatson
805195926Srwatsonvoid
806195926Srwatsonaudit_arg_vnode2(struct vnode *vp)
807195926Srwatson{
808195926Srwatson	struct kaudit_record *ar;
809195926Srwatson	int error;
810195926Srwatson
811195926Srwatson	ar = currecord();
812195926Srwatson	if (ar == NULL)
813195926Srwatson		return;
814195926Srwatson
815195926Srwatson	ARG_CLEAR_VALID(ar, ARG_VNODE2);
816195926Srwatson	error = audit_arg_vnode(vp, &ar->k_ar.ar_arg_vnode2);
817195926Srwatson	if (error == 0)
818155192Srwatson		ARG_SET_VALID(ar, ARG_VNODE2);
819155192Srwatson}
820155192Srwatson
821155192Srwatson/*
822161813Swsalamon * Audit the argument strings passed to exec.
823161813Swsalamon */
824161813Swsalamonvoid
825161813Swsalamonaudit_arg_argv(char *argv, int argc, int length)
826161813Swsalamon{
827161813Swsalamon	struct kaudit_record *ar;
828161813Swsalamon
829161813Swsalamon	if (audit_argv == 0)
830161813Swsalamon		return;
831161813Swsalamon
832161813Swsalamon	ar = currecord();
833161813Swsalamon	if (ar == NULL)
834161813Swsalamon		return;
835161813Swsalamon
836161813Swsalamon	ar->k_ar.ar_arg_argv = malloc(length, M_AUDITTEXT, M_WAITOK);
837161813Swsalamon	bcopy(argv, ar->k_ar.ar_arg_argv, length);
838161813Swsalamon	ar->k_ar.ar_arg_argc = argc;
839161813Swsalamon	ARG_SET_VALID(ar, ARG_ARGV);
840161813Swsalamon}
841161813Swsalamon
842161813Swsalamon/*
843161813Swsalamon * Audit the environment strings passed to exec.
844161813Swsalamon */
845161813Swsalamonvoid
846161813Swsalamonaudit_arg_envv(char *envv, int envc, int length)
847161813Swsalamon{
848161813Swsalamon	struct kaudit_record *ar;
849161813Swsalamon
850161813Swsalamon	if (audit_arge == 0)
851161813Swsalamon		return;
852161813Swsalamon
853161813Swsalamon	ar = currecord();
854161813Swsalamon	if (ar == NULL)
855161813Swsalamon		return;
856161813Swsalamon
857161813Swsalamon	ar->k_ar.ar_arg_envv = malloc(length, M_AUDITTEXT, M_WAITOK);
858161813Swsalamon	bcopy(envv, ar->k_ar.ar_arg_envv, length);
859161813Swsalamon	ar->k_ar.ar_arg_envc = envc;
860161813Swsalamon	ARG_SET_VALID(ar, ARG_ENVV);
861161813Swsalamon}
862161813Swsalamon
863224181Sjonathanvoid
864255219Spjdaudit_arg_rights(cap_rights_t *rightsp)
865224181Sjonathan{
866224181Sjonathan	struct kaudit_record *ar;
867224181Sjonathan
868224181Sjonathan	ar = currecord();
869224181Sjonathan	if (ar == NULL)
870224181Sjonathan		return;
871224181Sjonathan
872255219Spjd	ar->k_ar.ar_arg_rights = *rightsp;
873224181Sjonathan	ARG_SET_VALID(ar, ARG_RIGHTS);
874224181Sjonathan}
875224181Sjonathan
876247602Spjdvoid
877247602Spjdaudit_arg_fcntl_rights(uint32_t fcntlrights)
878247602Spjd{
879247602Spjd	struct kaudit_record *ar;
880247602Spjd
881247602Spjd	ar = currecord();
882247602Spjd	if (ar == NULL)
883247602Spjd		return;
884247602Spjd
885247602Spjd	ar->k_ar.ar_arg_fcntl_rights = fcntlrights;
886247602Spjd	ARG_SET_VALID(ar, ARG_FCNTL_RIGHTS);
887247602Spjd}
888247602Spjd
889161813Swsalamon/*
890156889Srwatson * The close() system call uses it's own audit call to capture the path/vnode
891156889Srwatson * information because those pieces are not easily obtained within the system
892156889Srwatson * call itself.
893155192Srwatson */
894155192Srwatsonvoid
895155192Srwatsonaudit_sysclose(struct thread *td, int fd)
896155192Srwatson{
897160086Srwatson	struct kaudit_record *ar;
898155192Srwatson	struct vnode *vp;
899155192Srwatson	struct file *fp;
900155192Srwatson
901160086Srwatson	KASSERT(td != NULL, ("audit_sysclose: td == NULL"));
902160086Srwatson
903160086Srwatson	ar = currecord();
904160086Srwatson	if (ar == NULL)
905160086Srwatson		return;
906160086Srwatson
907155192Srwatson	audit_arg_fd(fd);
908155192Srwatson
909224778Srwatson	if (getvnode(td->td_proc->p_fd, fd, 0, &fp) != 0)
910155192Srwatson		return;
911155192Srwatson
912155192Srwatson	vp = fp->f_vnode;
913184661Sjhb	vn_lock(vp, LK_SHARED | LK_RETRY);
914195926Srwatson	audit_arg_vnode1(vp);
915175294Sattilio	VOP_UNLOCK(vp, 0);
916155192Srwatson	fdrop(fp, td);
917156889Srwatson}
918