audit_syscalls.c revision 175294
1/*
2 * Copyright (c) 1999-2005 Apple Computer, 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 Computer, 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 * $FreeBSD: head/sys/security/audit/audit_syscalls.c 175294 2008-01-13 14:44:15Z attilio $
30 */
31
32#include "opt_mac.h"
33
34#include <sys/param.h>
35#include <sys/mount.h>
36#include <sys/namei.h>
37#include <sys/priv.h>
38#include <sys/proc.h>
39#include <sys/sysproto.h>
40#include <sys/systm.h>
41#include <sys/vnode.h>
42#include <sys/jail.h>
43
44#include <bsm/audit.h>
45#include <bsm/audit_kevents.h>
46
47#include <security/audit/audit.h>
48#include <security/audit/audit_private.h>
49#include <security/mac/mac_framework.h>
50
51#ifdef AUDIT
52
53/*
54 * System call to allow a user space application to submit a BSM audit record
55 * to the kernel for inclusion in the audit log.  This function does little
56 * verification on the audit record that is submitted.
57 *
58 * XXXAUDIT: Audit preselection for user records does not currently work,
59 * since we pre-select only based on the AUE_audit event type, not the event
60 * type submitted as part of the user audit data.
61 */
62/* ARGSUSED */
63int
64audit(struct thread *td, struct audit_args *uap)
65{
66	int error;
67	void * rec;
68	struct kaudit_record *ar;
69
70	if (jailed(td->td_ucred))
71		return (ENOSYS);
72	error = priv_check(td, PRIV_AUDIT_SUBMIT);
73	if (error)
74		return (error);
75
76	if ((uap->length <= 0) || (uap->length > audit_qctrl.aq_bufsz))
77		return (EINVAL);
78
79	ar = currecord();
80
81	/*
82	 * If there's no current audit record (audit() itself not audited)
83	 * commit the user audit record.
84	 */
85	if (ar == NULL) {
86
87		/*
88		 * This is not very efficient; we're required to allocate a
89		 * complete kernel audit record just so the user record can
90		 * tag along.
91		 *
92		 * XXXAUDIT: Maybe AUE_AUDIT in the system call context and
93		 * special pre-select handling?
94		 */
95		td->td_ar = audit_new(AUE_NULL, td);
96		if (td->td_ar == NULL)
97			return (ENOTSUP);
98		ar = td->td_ar;
99	}
100
101	if (uap->length > MAX_AUDIT_RECORD_SIZE)
102		return (EINVAL);
103
104	rec = malloc(uap->length, M_AUDITDATA, M_WAITOK);
105
106	error = copyin(uap->record, rec, uap->length);
107	if (error)
108		goto free_out;
109
110	/* Verify the record. */
111	if (bsm_rec_verify(rec) == 0) {
112		error = EINVAL;
113		goto free_out;
114	}
115
116#ifdef MAC
117	error = mac_system_check_audit(td->td_ucred, rec, uap->length);
118	if (error)
119		goto free_out;
120#endif
121
122	/*
123	 * Attach the user audit record to the kernel audit record.  Because
124	 * this system call is an auditable event, we will write the user
125	 * record along with the record for this audit event.
126	 *
127	 * XXXAUDIT: KASSERT appropriate starting values of k_udata, k_ulen,
128	 * k_ar_commit & AR_COMMIT_USER?
129	 */
130	ar->k_udata = rec;
131	ar->k_ulen  = uap->length;
132	ar->k_ar_commit |= AR_COMMIT_USER;
133
134	/*
135	 * Currently we assume that all preselection has been performed in
136	 * userspace.  We unconditionally set these masks so that the records
137	 * get committed both to the trail and pipe.  In the future we will
138	 * want to setup kernel based preselection.
139	 */
140	ar->k_ar_commit |= (AR_PRESELECT_USER_TRAIL | AR_PRESELECT_USER_PIPE);
141	return (0);
142
143free_out:
144	/*
145	 * audit_syscall_exit() will free the audit record on the thread even
146	 * if we allocated it above.
147	 */
148	free(rec, M_AUDITDATA);
149	return (error);
150}
151
152/*
153 *  System call to manipulate auditing.
154 */
155/* ARGSUSED */
156int
157auditon(struct thread *td, struct auditon_args *uap)
158{
159	struct ucred *newcred, *oldcred;
160	int error;
161	union auditon_udata udata;
162	struct proc *tp;
163
164	if (jailed(td->td_ucred))
165		return (ENOSYS);
166	AUDIT_ARG(cmd, uap->cmd);
167
168#ifdef MAC
169	error = mac_system_check_auditon(td->td_ucred, uap->cmd);
170	if (error)
171		return (error);
172#endif
173
174	error = priv_check(td, PRIV_AUDIT_CONTROL);
175	if (error)
176		return (error);
177
178	if ((uap->length <= 0) || (uap->length > sizeof(union auditon_udata)))
179		return (EINVAL);
180
181	memset((void *)&udata, 0, sizeof(udata));
182
183	/*
184	 * Some of the GET commands use the arguments too.
185	 */
186	switch (uap->cmd) {
187	case A_SETPOLICY:
188	case A_SETKMASK:
189	case A_SETQCTRL:
190	case A_SETSTAT:
191	case A_SETUMASK:
192	case A_SETSMASK:
193	case A_SETCOND:
194	case A_SETCLASS:
195	case A_SETPMASK:
196	case A_SETFSIZE:
197	case A_SETKAUDIT:
198	case A_GETCLASS:
199	case A_GETPINFO:
200	case A_GETPINFO_ADDR:
201	case A_SENDTRIGGER:
202		error = copyin(uap->data, (void *)&udata, uap->length);
203		if (error)
204			return (error);
205		AUDIT_ARG(auditon, &udata);
206		break;
207	}
208
209	/*
210	 * XXXAUDIT: Locking?
211	 */
212	switch (uap->cmd) {
213	case A_GETPOLICY:
214		if (!audit_fail_stop)
215			udata.au_policy |= AUDIT_CNT;
216		if (audit_panic_on_write_fail)
217			udata.au_policy |= AUDIT_AHLT;
218		if (audit_argv)
219			udata.au_policy |= AUDIT_ARGV;
220		if (audit_arge)
221			udata.au_policy |= AUDIT_ARGE;
222		break;
223
224	case A_SETPOLICY:
225		if (udata.au_policy & ~(AUDIT_CNT|AUDIT_AHLT|AUDIT_ARGV|
226		    AUDIT_ARGE))
227			return (EINVAL);
228		/*
229		 * XXX - Need to wake up waiters if the policy relaxes?
230		 */
231		audit_fail_stop = ((udata.au_policy & AUDIT_CNT) == 0);
232		audit_panic_on_write_fail = (udata.au_policy & AUDIT_AHLT);
233		audit_argv = (udata.au_policy & AUDIT_ARGV);
234		audit_arge = (udata.au_policy & AUDIT_ARGE);
235		break;
236
237	case A_GETKMASK:
238		udata.au_mask = audit_nae_mask;
239		break;
240
241	case A_SETKMASK:
242		audit_nae_mask = udata.au_mask;
243		break;
244
245	case A_GETQCTRL:
246		udata.au_qctrl = audit_qctrl;
247		break;
248
249	case A_SETQCTRL:
250		if ((udata.au_qctrl.aq_hiwater > AQ_MAXHIGH) ||
251		    (udata.au_qctrl.aq_lowater >= udata.au_qctrl.aq_hiwater) ||
252		    (udata.au_qctrl.aq_bufsz > AQ_MAXBUFSZ) ||
253		    (udata.au_qctrl.aq_minfree < 0) ||
254		    (udata.au_qctrl.aq_minfree > 100))
255			return (EINVAL);
256
257		audit_qctrl = udata.au_qctrl;
258		/* XXX The queue delay value isn't used with the kernel. */
259		audit_qctrl.aq_delay = -1;
260		break;
261
262	case A_GETCWD:
263		return (ENOSYS);
264		break;
265
266	case A_GETCAR:
267		return (ENOSYS);
268		break;
269
270	case A_GETSTAT:
271		return (ENOSYS);
272		break;
273
274	case A_SETSTAT:
275		return (ENOSYS);
276		break;
277
278	case A_SETUMASK:
279		return (ENOSYS);
280		break;
281
282	case A_SETSMASK:
283		return (ENOSYS);
284		break;
285
286	case A_GETCOND:
287		if (audit_enabled && !audit_suspended)
288			udata.au_cond = AUC_AUDITING;
289		else
290			udata.au_cond = AUC_NOAUDIT;
291		break;
292
293	case A_SETCOND:
294		if (udata.au_cond == AUC_NOAUDIT)
295			audit_suspended = 1;
296		if (udata.au_cond == AUC_AUDITING)
297			audit_suspended = 0;
298		if (udata.au_cond == AUC_DISABLED) {
299			audit_suspended = 1;
300			audit_shutdown(NULL, 0);
301		}
302		break;
303
304	case A_GETCLASS:
305		udata.au_evclass.ec_class = au_event_class(
306		    udata.au_evclass.ec_number);
307		break;
308
309	case A_SETCLASS:
310		au_evclassmap_insert(udata.au_evclass.ec_number,
311		    udata.au_evclass.ec_class);
312		break;
313
314	case A_GETPINFO:
315		if (udata.au_aupinfo.ap_pid < 1)
316			return (EINVAL);
317		if ((tp = pfind(udata.au_aupinfo.ap_pid)) == NULL)
318			return (EINVAL);
319		if (p_cansee(td, tp) != 0) {
320			PROC_UNLOCK(tp);
321			return (EINVAL);
322		}
323		if (tp->p_ucred->cr_audit.ai_termid.at_type == AU_IPv6) {
324			PROC_UNLOCK(tp);
325			return (EINVAL);
326		}
327		udata.au_aupinfo.ap_auid =
328		    tp->p_ucred->cr_audit.ai_auid;
329		udata.au_aupinfo.ap_mask.am_success =
330		    tp->p_ucred->cr_audit.ai_mask.am_success;
331		udata.au_aupinfo.ap_mask.am_failure =
332		    tp->p_ucred->cr_audit.ai_mask.am_failure;
333		udata.au_aupinfo.ap_termid.machine =
334		    tp->p_ucred->cr_audit.ai_termid.at_addr[0];
335		udata.au_aupinfo.ap_termid.port =
336		    (dev_t)tp->p_ucred->cr_audit.ai_termid.at_port;
337		udata.au_aupinfo.ap_asid =
338		    tp->p_ucred->cr_audit.ai_asid;
339		PROC_UNLOCK(tp);
340		break;
341
342	case A_SETPMASK:
343		if (udata.au_aupinfo.ap_pid < 1)
344			return (EINVAL);
345		newcred = crget();
346		if ((tp = pfind(udata.au_aupinfo.ap_pid)) == NULL) {
347			crfree(newcred);
348			return (EINVAL);
349		}
350		if (p_cansee(td, tp) != 0) {
351			PROC_UNLOCK(tp);
352			crfree(newcred);
353			return (EINVAL);
354		}
355		oldcred = tp->p_ucred;
356		crcopy(newcred, oldcred);
357		newcred->cr_audit.ai_mask.am_success =
358		    udata.au_aupinfo.ap_mask.am_success;
359		newcred->cr_audit.ai_mask.am_failure =
360		    udata.au_aupinfo.ap_mask.am_failure;
361		td->td_proc->p_ucred = newcred;
362		PROC_UNLOCK(tp);
363		crfree(oldcred);
364		break;
365
366	case A_SETFSIZE:
367		if ((udata.au_fstat.af_filesz != 0) &&
368		   (udata.au_fstat.af_filesz < MIN_AUDIT_FILE_SIZE))
369			return (EINVAL);
370		audit_fstat.af_filesz = udata.au_fstat.af_filesz;
371		break;
372
373	case A_GETFSIZE:
374		udata.au_fstat.af_filesz = audit_fstat.af_filesz;
375		udata.au_fstat.af_currsz = audit_fstat.af_currsz;
376		break;
377
378	case A_GETPINFO_ADDR:
379		if (udata.au_aupinfo_addr.ap_pid < 1)
380			return (EINVAL);
381		if ((tp = pfind(udata.au_aupinfo_addr.ap_pid)) == NULL)
382			return (EINVAL);
383		udata.au_aupinfo_addr.ap_auid =
384		    tp->p_ucred->cr_audit.ai_auid;
385		udata.au_aupinfo_addr.ap_mask.am_success =
386		    tp->p_ucred->cr_audit.ai_mask.am_success;
387		udata.au_aupinfo_addr.ap_mask.am_failure =
388		    tp->p_ucred->cr_audit.ai_mask.am_failure;
389		udata.au_aupinfo_addr.ap_termid =
390		    tp->p_ucred->cr_audit.ai_termid;
391		udata.au_aupinfo_addr.ap_asid =
392		    tp->p_ucred->cr_audit.ai_asid;
393		PROC_UNLOCK(tp);
394		break;
395
396	case A_GETKAUDIT:
397		return (ENOSYS);
398		break;
399
400	case A_SETKAUDIT:
401		return (ENOSYS);
402		break;
403
404	case A_SENDTRIGGER:
405		if ((udata.au_trigger < AUDIT_TRIGGER_MIN) ||
406		    (udata.au_trigger > AUDIT_TRIGGER_MAX))
407			return (EINVAL);
408		return (send_trigger(udata.au_trigger));
409	}
410
411	/*
412	 * Copy data back to userspace for the GET comands.
413	 */
414	switch (uap->cmd) {
415	case A_GETPOLICY:
416	case A_GETKMASK:
417	case A_GETQCTRL:
418	case A_GETCWD:
419	case A_GETCAR:
420	case A_GETSTAT:
421	case A_GETCOND:
422	case A_GETCLASS:
423	case A_GETPINFO:
424	case A_GETFSIZE:
425	case A_GETPINFO_ADDR:
426	case A_GETKAUDIT:
427		error = copyout((void *)&udata, uap->data, uap->length);
428		if (error)
429			return (error);
430		break;
431	}
432
433	return (0);
434}
435
436/*
437 * System calls to manage the user audit information.
438 */
439/* ARGSUSED */
440int
441getauid(struct thread *td, struct getauid_args *uap)
442{
443	int error;
444
445	if (jailed(td->td_ucred))
446		return (ENOSYS);
447	error = priv_check(td, PRIV_AUDIT_GETAUDIT);
448	if (error)
449		return (error);
450	return (copyout(&td->td_ucred->cr_audit.ai_auid, uap->auid,
451	    sizeof(td->td_ucred->cr_audit.ai_auid)));
452}
453
454/* ARGSUSED */
455int
456setauid(struct thread *td, struct setauid_args *uap)
457{
458	struct ucred *newcred, *oldcred;
459	au_id_t id;
460	int error;
461
462	if (jailed(td->td_ucred))
463		return (ENOSYS);
464	error = copyin(uap->auid, &id, sizeof(id));
465	if (error)
466		return (error);
467	audit_arg_auid(id);
468	newcred = crget();
469	PROC_LOCK(td->td_proc);
470	oldcred = td->td_proc->p_ucred;
471	crcopy(newcred, oldcred);
472#ifdef MAC
473	error = mac_proc_check_setauid(oldcred, id);
474	if (error)
475		goto fail;
476#endif
477	error = priv_check_cred(oldcred, PRIV_AUDIT_SETAUDIT, 0);
478	if (error)
479		goto fail;
480	newcred->cr_audit.ai_auid = id;
481	td->td_proc->p_ucred = newcred;
482	PROC_UNLOCK(td->td_proc);
483	crfree(oldcred);
484	return (0);
485fail:
486	PROC_UNLOCK(td->td_proc);
487	crfree(newcred);
488	return (error);
489}
490
491/*
492 * System calls to get and set process audit information.
493 */
494/* ARGSUSED */
495int
496getaudit(struct thread *td, struct getaudit_args *uap)
497{
498	struct auditinfo ai;
499	int error;
500
501	if (jailed(td->td_ucred))
502		return (ENOSYS);
503	error = priv_check(td, PRIV_AUDIT_GETAUDIT);
504	if (error)
505		return (error);
506	if (td->td_ucred->cr_audit.ai_termid.at_type == AU_IPv6)
507		return (E2BIG);
508	bzero(&ai, sizeof(ai));
509	ai.ai_auid = td->td_ucred->cr_audit.ai_auid;
510	ai.ai_mask = td->td_ucred->cr_audit.ai_mask;
511	ai.ai_asid = td->td_ucred->cr_audit.ai_asid;
512	ai.ai_termid.machine = td->td_ucred->cr_audit.ai_termid.at_addr[0];
513	ai.ai_termid.port = td->td_ucred->cr_audit.ai_termid.at_port;
514	return (copyout(&ai, uap->auditinfo, sizeof(ai)));
515}
516
517/* ARGSUSED */
518int
519setaudit(struct thread *td, struct setaudit_args *uap)
520{
521	struct ucred *newcred, *oldcred;
522	struct auditinfo ai;
523	int error;
524
525	if (jailed(td->td_ucred))
526		return (ENOSYS);
527	error = copyin(uap->auditinfo, &ai, sizeof(ai));
528	if (error)
529		return (error);
530	audit_arg_auditinfo(&ai);
531	newcred = crget();
532	PROC_LOCK(td->td_proc);
533	oldcred = td->td_proc->p_ucred;
534	crcopy(newcred, oldcred);
535#ifdef MAC
536	error = mac_proc_check_setaudit(oldcred, &ai);
537	if (error)
538		goto fail;
539#endif
540	error = priv_check_cred(oldcred, PRIV_AUDIT_SETAUDIT, 0);
541	if (error)
542		goto fail;
543	bzero(&newcred->cr_audit, sizeof(newcred->cr_audit));
544	newcred->cr_audit.ai_auid = ai.ai_auid;
545	newcred->cr_audit.ai_mask = ai.ai_mask;
546	newcred->cr_audit.ai_asid = ai.ai_asid;
547	newcred->cr_audit.ai_termid.at_addr[0] = ai.ai_termid.machine;
548	newcred->cr_audit.ai_termid.at_port = ai.ai_termid.port;
549	newcred->cr_audit.ai_termid.at_type = AU_IPv4;
550	td->td_proc->p_ucred = newcred;
551	PROC_UNLOCK(td->td_proc);
552	crfree(oldcred);
553	return (0);
554fail:
555	PROC_UNLOCK(td->td_proc);
556	crfree(newcred);
557	return (error);
558}
559
560/* ARGSUSED */
561int
562getaudit_addr(struct thread *td, struct getaudit_addr_args *uap)
563{
564	int error;
565
566	if (jailed(td->td_ucred))
567		return (ENOSYS);
568	if (uap->length < sizeof(*uap->auditinfo_addr))
569		return (EOVERFLOW);
570	error = priv_check(td, PRIV_AUDIT_GETAUDIT);
571	if (error)
572		return (error);
573	return (copyout(&td->td_ucred->cr_audit, uap->auditinfo_addr,
574	    sizeof(*uap->auditinfo_addr)));
575}
576
577/* ARGSUSED */
578int
579setaudit_addr(struct thread *td, struct setaudit_addr_args *uap)
580{
581	struct ucred *newcred, *oldcred;
582	struct auditinfo_addr aia;
583	int error;
584
585	if (jailed(td->td_ucred))
586		return (ENOSYS);
587	error = copyin(uap->auditinfo_addr, &aia, sizeof(aia));
588	if (error)
589		return (error);
590	audit_arg_auditinfo_addr(&aia);
591	if (aia.ai_termid.at_type != AU_IPv6 &&
592	    aia.ai_termid.at_type != AU_IPv4)
593		return (EINVAL);
594	newcred = crget();
595	PROC_LOCK(td->td_proc);
596	oldcred = td->td_proc->p_ucred;
597	crcopy(newcred, oldcred);
598#ifdef MAC
599	error = mac_proc_check_setaudit_addr(oldcred, &aia);
600	if (error)
601		goto fail;
602#endif
603	error = priv_check_cred(oldcred, PRIV_AUDIT_SETAUDIT, 0);
604	if (error)
605		goto fail;
606	newcred->cr_audit = aia;
607	td->td_proc->p_ucred = newcred;
608	PROC_UNLOCK(td->td_proc);
609	crfree(oldcred);
610	return (0);
611fail:
612	PROC_UNLOCK(td->td_proc);
613	crfree(newcred);
614	return (error);
615}
616
617/*
618 * Syscall to manage audit files.
619 */
620/* ARGSUSED */
621int
622auditctl(struct thread *td, struct auditctl_args *uap)
623{
624	struct nameidata nd;
625	struct ucred *cred;
626	struct vnode *vp;
627	int error = 0;
628	int flags, vfslocked;
629
630	if (jailed(td->td_ucred))
631		return (ENOSYS);
632	error = priv_check(td, PRIV_AUDIT_CONTROL);
633	if (error)
634		return (error);
635
636	vp = NULL;
637	cred = NULL;
638
639	/*
640	 * If a path is specified, open the replacement vnode, perform
641	 * validity checks, and grab another reference to the current
642	 * credential.
643	 *
644	 * On Darwin, a NULL path argument is also used to disable audit.
645	 */
646	if (uap->path == NULL)
647		return (EINVAL);
648
649	NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | MPSAFE | AUDITVNODE1,
650	    UIO_USERSPACE, uap->path, td);
651	flags = AUDIT_OPEN_FLAGS;
652	error = vn_open(&nd, &flags, 0, NULL);
653	if (error)
654		return (error);
655	vfslocked = NDHASGIANT(&nd);
656	vp = nd.ni_vp;
657#ifdef MAC
658	error = mac_system_check_auditctl(td->td_ucred, vp);
659	VOP_UNLOCK(vp, 0);
660	if (error) {
661		vn_close(vp, AUDIT_CLOSE_FLAGS, td->td_ucred, td);
662		VFS_UNLOCK_GIANT(vfslocked);
663		return (error);
664	}
665#else
666	VOP_UNLOCK(vp, 0);
667#endif
668	NDFREE(&nd, NDF_ONLY_PNBUF);
669	if (vp->v_type != VREG) {
670		vn_close(vp, AUDIT_CLOSE_FLAGS, td->td_ucred, td);
671		VFS_UNLOCK_GIANT(vfslocked);
672		return (EINVAL);
673	}
674	VFS_UNLOCK_GIANT(vfslocked);
675	cred = td->td_ucred;
676	crhold(cred);
677
678	/*
679	 * XXXAUDIT: Should audit_suspended actually be cleared by
680	 * audit_worker?
681	 */
682	audit_suspended = 0;
683
684	audit_rotate_vnode(cred, vp);
685
686	return (error);
687}
688
689#else /* !AUDIT */
690
691int
692audit(struct thread *td, struct audit_args *uap)
693{
694
695	return (ENOSYS);
696}
697
698int
699auditon(struct thread *td, struct auditon_args *uap)
700{
701
702	return (ENOSYS);
703}
704
705int
706getauid(struct thread *td, struct getauid_args *uap)
707{
708
709	return (ENOSYS);
710}
711
712int
713setauid(struct thread *td, struct setauid_args *uap)
714{
715
716	return (ENOSYS);
717}
718
719int
720getaudit(struct thread *td, struct getaudit_args *uap)
721{
722
723	return (ENOSYS);
724}
725
726int
727setaudit(struct thread *td, struct setaudit_args *uap)
728{
729
730	return (ENOSYS);
731}
732
733int
734getaudit_addr(struct thread *td, struct getaudit_addr_args *uap)
735{
736
737	return (ENOSYS);
738}
739
740int
741setaudit_addr(struct thread *td, struct setaudit_addr_args *uap)
742{
743
744	return (ENOSYS);
745}
746
747int
748auditctl(struct thread *td, struct auditctl_args *uap)
749{
750
751	return (ENOSYS);
752}
753#endif /* AUDIT */
754