1/*-
2 * Copyright (c) 2004-2009 Apple Inc.
3 * Copyright (c) 2016 Robert N. M. Watson
4 * All rights reserved.
5 *
6 * Portions of this software were developed by BAE Systems, the University of
7 * Cambridge Computer Laboratory, and Memorial University under DARPA/AFRL
8 * contract FA8650-15-C-7558 ("CADETS"), as part of the DARPA Transparent
9 * Computing (TC) research program.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1.  Redistributions of source code must retain the above copyright
15 *     notice, this list of conditions and the following disclaimer.
16 * 2.  Redistributions in binary form must reproduce the above copyright
17 *     notice, this list of conditions and the following disclaimer in the
18 *     documentation and/or other materials provided with the distribution.
19 * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
20 *     its contributors may be used to endorse or promote products derived
21 *     from this software without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR
27 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
31 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
32 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 * POSSIBILITY OF SUCH DAMAGE.
34 */
35
36#ifdef __APPLE__
37#define	_SYS_AUDIT_H		/* Prevent include of sys/audit.h. */
38#endif
39
40#include <sys/param.h>
41#include <sys/stat.h>
42
43#ifdef __APPLE__
44#include <sys/queue.h>		/* Our bsm/audit.h doesn't include queue.h. */
45#endif
46
47#include <sys/sysctl.h>
48
49#include <bsm/libbsm.h>
50
51#include <unistd.h>
52#include <syslog.h>
53#include <stdarg.h>
54#include <string.h>
55#include <errno.h>
56
57/* These are not advertised in libbsm.h */
58int audit_set_terminal_port(dev_t *p);
59int audit_set_terminal_host(uint32_t *m);
60
61/*
62 * General purpose audit submission mechanism for userspace.
63 */
64int
65audit_submit(short au_event, au_id_t auid, char status,
66    int reterr, const char *fmt, ...)
67{
68	char text[MAX_AUDITSTRING_LEN];
69	token_t *token;
70	int acond;
71	va_list ap;
72	pid_t pid;
73	int error, afd, subj_ex;
74	struct auditinfo ai;
75	struct auditinfo_addr aia;
76	au_tid_t atid;
77
78	if (audit_get_cond(&acond) != 0) {
79		/*
80		 * If auditon(2) returns ENOSYS, then audit has not been
81		 * compiled into the kernel, so just return.
82		 */
83		if (errno == ENOSYS)
84			return (0);
85		error = errno;
86		syslog(LOG_AUTH | LOG_ERR, "audit: auditon failed: %s",
87		    strerror(errno));
88		errno = error;
89		return (-1);
90	}
91	if (acond == AUC_NOAUDIT)
92		return (0);
93	afd = au_open();
94	if (afd < 0) {
95		error = errno;
96		syslog(LOG_AUTH | LOG_ERR, "audit: au_open failed: %s",
97		    strerror(errno));
98		errno = error;
99		return (-1);
100	}
101	/*
102	 * Try to use getaudit_addr(2) first.  If this kernel does not support
103	 * it, then fall back on to getaudit(2).
104	 */
105	subj_ex = 0;
106	error = getaudit_addr(&aia, sizeof(aia));
107	if (error < 0 && errno == ENOSYS) {
108		error = getaudit(&ai);
109		if (error < 0) {
110			error = errno;
111			syslog(LOG_AUTH | LOG_ERR, "audit: getaudit failed: %s",
112			    strerror(errno));
113			errno = error;
114			return (-1);
115		}
116		/*
117		 * Convert this auditinfo_t to an auditinfo_addr_t to make the
118		 * following code less complicated wrt to preselection and
119		 * subject token generation.
120		 */
121		aia.ai_auid = ai.ai_auid;
122		aia.ai_mask = ai.ai_mask;
123		aia.ai_asid = ai.ai_asid;
124		aia.ai_termid.at_type = AU_IPv4;
125		aia.ai_termid.at_addr[0] = ai.ai_termid.machine;
126		aia.ai_termid.at_port = ai.ai_termid.port;
127	} else if (error < 0) {
128		error = errno;
129		syslog(LOG_AUTH | LOG_ERR, "audit: getaudit_addr failed: %s",
130		    strerror(errno));
131		errno = error;
132		return (-1);
133	}
134	/*
135	 * NB: We should be performing pre-selection here now that we have the
136	 * masks for this process.
137	 */
138	if (aia.ai_termid.at_type == AU_IPv6)
139		subj_ex = 1;
140	pid = getpid();
141	if (subj_ex == 0) {
142		atid.port = aia.ai_termid.at_port;
143		atid.machine = aia.ai_termid.at_addr[0];
144		token = au_to_subject32(auid, geteuid(), getegid(),
145		    getuid(), getgid(), pid, pid, &atid);
146	} else
147		token = au_to_subject_ex(auid, geteuid(), getegid(),
148		    getuid(), getgid(), pid, pid, &aia.ai_termid);
149	if (token == NULL) {
150		syslog(LOG_AUTH | LOG_ERR,
151		    "audit: unable to build subject token");
152		(void) au_close(afd, AU_TO_NO_WRITE, au_event);
153		errno = EPERM;
154		return (-1);
155	}
156	if (au_write(afd, token) < 0) {
157		error = errno;
158		syslog(LOG_AUTH | LOG_ERR,
159		    "audit: au_write failed: %s", strerror(errno));
160		(void) au_close(afd, AU_TO_NO_WRITE, au_event);
161		errno = error;
162		return (-1);
163	}
164	if (fmt != NULL) {
165		va_start(ap, fmt);
166		(void) vsnprintf(text, MAX_AUDITSTRING_LEN, fmt, ap);
167		va_end(ap);
168		token = au_to_text(text);
169		if (token == NULL) {
170			syslog(LOG_AUTH | LOG_ERR,
171			    "audit: failed to generate text token");
172			(void) au_close(afd, AU_TO_NO_WRITE, au_event);
173			errno = EPERM;
174			return (-1);
175		}
176		if (au_write(afd, token) < 0) {
177			error = errno;
178			syslog(LOG_AUTH | LOG_ERR,
179			    "audit: au_write failed: %s", strerror(errno));
180			(void) au_close(afd, AU_TO_NO_WRITE, au_event);
181			errno = error;
182			return (-1);
183		}
184	}
185	token = au_to_return32(au_errno_to_bsm(status), reterr);
186	if (token == NULL) {
187		syslog(LOG_AUTH | LOG_ERR,
188		    "audit: unable to build return token");
189		(void) au_close(afd, AU_TO_NO_WRITE, au_event);
190		errno = EPERM;
191		return (-1);
192	}
193	if (au_write(afd, token) < 0) {
194		error = errno;
195		syslog(LOG_AUTH | LOG_ERR,
196		    "audit: au_write failed: %s", strerror(errno));
197		(void) au_close(afd, AU_TO_NO_WRITE, au_event);
198		errno = error;
199		return (-1);
200	}
201	if (au_close(afd, AU_TO_WRITE, au_event) < 0) {
202		error = errno;
203		syslog(LOG_AUTH | LOG_ERR, "audit: record not committed");
204		errno = error;
205		return (-1);
206	}
207	return (0);
208}
209
210int
211audit_set_terminal_port(dev_t *p)
212{
213	struct stat st;
214
215	if (p == NULL)
216		return (kAUBadParamErr);
217
218#ifdef NODEV
219	*p = NODEV;
220#else
221	*p = -1;
222#endif
223
224	/* for /usr/bin/login, try fstat() first */
225	if (fstat(STDIN_FILENO, &st) != 0) {
226		if (errno != EBADF) {
227			syslog(LOG_ERR, "fstat() failed (%s)",
228			    strerror(errno));
229			return (kAUStatErr);
230		}
231		if (stat("/dev/console", &st) != 0) {
232			syslog(LOG_ERR, "stat() failed (%s)",
233			    strerror(errno));
234			return (kAUStatErr);
235		}
236	}
237	*p = st.st_rdev;
238	return (kAUNoErr);
239}
240
241int
242audit_set_terminal_host(uint32_t *m)
243{
244
245#ifdef KERN_HOSTID
246	int name[2] = { CTL_KERN, KERN_HOSTID };
247	size_t len;
248
249	if (m == NULL)
250		return (kAUBadParamErr);
251	*m = 0;
252	len = sizeof(*m);
253	if (sysctl(name, 2, m, &len, NULL, 0) != 0) {
254		syslog(LOG_ERR, "sysctl() failed (%s)", strerror(errno));
255		return (kAUSysctlErr);
256	}
257	return (kAUNoErr);
258#else
259	*m = -1;
260	return (kAUNoErr);
261#endif
262}
263
264int
265audit_set_terminal_id(au_tid_t *tid)
266{
267	dev_t port;
268	int ret;
269
270	if (tid == NULL)
271		return (kAUBadParamErr);
272	if ((ret = audit_set_terminal_port(&port)) != kAUNoErr)
273		return (ret);
274	tid->port = port;
275	return (audit_set_terminal_host(&tid->machine));
276}
277
278/*
279 * This is OK for those callers who have only one token to write.  If you have
280 * multiple tokens that logically form part of the same audit record, you need
281 * to use the existing au_open()/au_write()/au_close() API:
282 *
283 * aufd = au_open();
284 * tok = au_to_random_token_1(...);
285 * au_write(aufd, tok);
286 * tok = au_to_random_token_2(...);
287 * au_write(aufd, tok);
288 * ...
289 * au_close(aufd, AU_TO_WRITE, AUE_your_event_type);
290 *
291 * Assumes, like all wrapper calls, that the caller has previously checked
292 * that auditing is enabled via the audit_get_state() call.
293 *
294 * XXX: Should be more robust against bad arguments.
295 */
296int
297audit_write(short event_code, token_t *subject, token_t *misctok, char retval,
298    int errcode)
299{
300	int aufd;
301	char *func = "audit_write()";
302	token_t *rettok;
303
304	if ((aufd = au_open()) == -1) {
305		au_free_token(subject);
306		au_free_token(misctok);
307		syslog(LOG_ERR, "%s: au_open() failed", func);
308		return (kAUOpenErr);
309	}
310
311	/* Save subject. */
312	if (subject && au_write(aufd, subject) == -1) {
313		au_free_token(subject);
314		au_free_token(misctok);
315		(void)au_close(aufd, AU_TO_NO_WRITE, event_code);
316		syslog(LOG_ERR, "%s: write of subject failed", func);
317		return (kAUWriteSubjectTokErr);
318	}
319
320	/* Save the event-specific token. */
321	if (misctok && au_write(aufd, misctok) == -1) {
322		au_free_token(misctok);
323		(void)au_close(aufd, AU_TO_NO_WRITE, event_code);
324		syslog(LOG_ERR, "%s: write of caller token failed", func);
325		return (kAUWriteCallerTokErr);
326	}
327
328	/* Tokenize and save the return value. */
329	if ((rettok = au_to_return32(retval, errcode)) == NULL) {
330		(void)au_close(aufd, AU_TO_NO_WRITE, event_code);
331		syslog(LOG_ERR, "%s: au_to_return32() failed", func);
332		return (kAUMakeReturnTokErr);
333	}
334
335	if (au_write(aufd, rettok) == -1) {
336		au_free_token(rettok);
337		(void)au_close(aufd, AU_TO_NO_WRITE, event_code);
338		syslog(LOG_ERR, "%s: write of return code failed", func);
339		return (kAUWriteReturnTokErr);
340	}
341
342	/*
343	 * We assume the caller wouldn't have bothered with this
344	 * function if it hadn't already decided to keep the record.
345	 */
346	if (au_close(aufd, AU_TO_WRITE, event_code) < 0) {
347		syslog(LOG_ERR, "%s: au_close() failed", func);
348		return (kAUCloseErr);
349	}
350
351	return (kAUNoErr);
352}
353
354/*
355 * Same caveats as audit_write().  In addition, this function explicitly
356 * assumes success; use audit_write_failure() on error.
357 */
358int
359audit_write_success(short event_code, token_t *tok, au_id_t auid, uid_t euid,
360    gid_t egid, uid_t ruid, gid_t rgid, pid_t pid, au_asid_t sid,
361    au_tid_t *tid)
362{
363	char *func = "audit_write_success()";
364	token_t *subject = NULL;
365
366	/* Tokenize and save subject. */
367	subject = au_to_subject32(auid, euid, egid, ruid, rgid, pid, sid,
368	    tid);
369	if (subject == NULL) {
370		syslog(LOG_ERR, "%s: au_to_subject32() failed", func);
371		return kAUMakeSubjectTokErr;
372	}
373
374	return (audit_write(event_code, subject, tok, 0, 0));
375}
376
377/*
378 * Same caveats as audit_write().  In addition, this function explicitly
379 * assumes success; use audit_write_failure_self() on error.
380 */
381int
382audit_write_success_self(short event_code, token_t *tok)
383{
384	token_t *subject;
385	char *func = "audit_write_success_self()";
386
387	if ((subject = au_to_me()) == NULL) {
388		syslog(LOG_ERR, "%s: au_to_me() failed", func);
389		return (kAUMakeSubjectTokErr);
390	}
391
392	return (audit_write(event_code, subject, tok, 0, 0));
393}
394
395/*
396 * Same caveats as audit_write().  In addition, this function explicitly
397 * assumes failure; use audit_write_success() otherwise.
398 *
399 * XXX  This should let the caller pass an error return value rather than
400 * hard-coding -1.
401 */
402int
403audit_write_failure(short event_code, char *errmsg, int errcode, au_id_t auid,
404    uid_t euid, gid_t egid, uid_t ruid, gid_t rgid, pid_t pid, au_asid_t sid,
405    au_tid_t *tid)
406{
407	char *func = "audit_write_failure()";
408	token_t *subject, *errtok;
409
410	subject = au_to_subject32(auid, euid, egid, ruid, rgid, pid, sid, tid);
411	if (subject == NULL) {
412		syslog(LOG_ERR, "%s: au_to_subject32() failed", func);
413		return (kAUMakeSubjectTokErr);
414	}
415
416	/* tokenize and save the error message */
417	if ((errtok = au_to_text(errmsg)) == NULL) {
418		au_free_token(subject);
419		syslog(LOG_ERR, "%s: au_to_text() failed", func);
420		return (kAUMakeTextTokErr);
421	}
422
423	return (audit_write(event_code, subject, errtok, -1, errcode));
424}
425
426/*
427 * Same caveats as audit_write().  In addition, this function explicitly
428 * assumes failure; use audit_write_success_self() otherwise.
429 *
430 * XXX  This should let the caller pass an error return value rather than
431 * hard-coding -1.
432 */
433int
434audit_write_failure_self(short event_code, char *errmsg, int errret)
435{
436	char *func = "audit_write_failure_self()";
437	token_t *subject, *errtok;
438
439	if ((subject = au_to_me()) == NULL) {
440		syslog(LOG_ERR, "%s: au_to_me() failed", func);
441		return (kAUMakeSubjectTokErr);
442	}
443	/* tokenize and save the error message */
444	if ((errtok = au_to_text(errmsg)) == NULL) {
445		au_free_token(subject);
446		syslog(LOG_ERR, "%s: au_to_text() failed", func);
447		return (kAUMakeTextTokErr);
448	}
449	return (audit_write(event_code, subject, errtok, -1, errret));
450}
451
452/*
453 * For auditing errors during login.  Such errors are implicitly
454 * non-attributable (i.e., not ascribable to any user).
455 *
456 * Assumes, like all wrapper calls, that the caller has previously checked
457 * that auditing is enabled via the audit_get_state() call.
458 */
459int
460audit_write_failure_na(short event_code, char *errmsg, int errret, uid_t euid,
461    uid_t egid, pid_t pid, au_tid_t *tid)
462{
463
464	return (audit_write_failure(event_code, errmsg, errret, -1, euid,
465	    egid, -1, -1, pid, -1, tid));
466}
467
468/* END OF au_write() WRAPPERS */
469
470#ifdef __APPLE__
471void
472audit_token_to_au32(audit_token_t atoken, uid_t *auidp, uid_t *euidp,
473    gid_t *egidp, uid_t *ruidp, gid_t *rgidp, pid_t *pidp, au_asid_t *asidp,
474    au_tid_t *tidp)
475{
476
477	if (auidp != NULL)
478		*auidp = (uid_t)atoken.val[0];
479	if (euidp != NULL)
480		*euidp = (uid_t)atoken.val[1];
481	if (egidp != NULL)
482		*egidp = (gid_t)atoken.val[2];
483	if (ruidp != NULL)
484		*ruidp = (uid_t)atoken.val[3];
485	if (rgidp != NULL)
486		*rgidp = (gid_t)atoken.val[4];
487	if (pidp != NULL)
488		*pidp = (pid_t)atoken.val[5];
489	if (asidp != NULL)
490		*asidp = (au_asid_t)atoken.val[6];
491	if (tidp != NULL) {
492		audit_set_terminal_host(&tidp->machine);
493		tidp->port = (dev_t)atoken.val[7];
494	}
495}
496#endif /* !__APPLE__ */
497
498int
499audit_get_cond(int *cond)
500{
501	int ret;
502
503	ret = auditon(A_GETCOND, cond, sizeof(*cond));
504#ifdef A_OLDGETCOND
505	if ((0 != ret) && EINVAL == errno) {
506		long lcond = *cond;
507
508		ret = auditon(A_OLDGETCOND, &lcond, sizeof(lcond));
509		*cond = (int)lcond;
510	}
511#endif
512	return (ret);
513}
514
515int
516audit_set_cond(int *cond)
517{
518	int ret;
519
520	ret = auditon(A_SETCOND, cond, sizeof(*cond));
521#ifdef A_OLDSETCOND
522	if ((0 != ret) && (EINVAL == errno)) {
523		long lcond = (long)*cond;
524
525		ret = auditon(A_OLDSETCOND, &lcond, sizeof(lcond));
526		*cond = (int)lcond;
527	}
528#endif
529	return (ret);
530}
531
532int
533audit_get_policy(int *policy)
534{
535	int ret;
536
537	ret = auditon(A_GETPOLICY, policy, sizeof(*policy));
538#ifdef A_OLDGETPOLICY
539	if ((0 != ret) && (EINVAL == errno)){
540		long lpolicy = (long)*policy;
541
542		ret = auditon(A_OLDGETPOLICY, &lpolicy, sizeof(lpolicy));
543		*policy = (int)lpolicy;
544	}
545#endif
546	return (ret);
547}
548
549int
550audit_set_policy(int *policy)
551{
552	int ret;
553
554	ret = auditon(A_SETPOLICY, policy, sizeof(*policy));
555#ifdef A_OLDSETPOLICY
556	if ((0 != ret) && (EINVAL == errno)){
557		long lpolicy = (long)*policy;
558
559		ret = auditon(A_OLDSETPOLICY, &lpolicy, sizeof(lpolicy));
560		*policy = (int)lpolicy;
561	}
562#endif
563	return (ret);
564}
565
566int
567audit_get_qctrl(au_qctrl_t *qctrl, size_t sz)
568{
569	int ret;
570
571	if (sizeof(*qctrl) != sz) {
572		errno = EINVAL;
573		return (-1);
574	}
575
576	ret = auditon(A_GETQCTRL, qctrl, sizeof(*qctrl));
577#ifdef A_OLDGETQCTRL
578	if ((0 != ret) && (EINVAL == errno)){
579		struct old_qctrl {
580			size_t   oq_hiwater;
581			size_t   oq_lowater;
582			size_t   oq_bufsz;
583			clock_t  oq_delay;
584			int	 oq_minfree;
585		} oq;
586
587		oq.oq_hiwater = (size_t)qctrl->aq_hiwater;
588		oq.oq_lowater = (size_t)qctrl->aq_lowater;
589		oq.oq_bufsz = (size_t)qctrl->aq_bufsz;
590		oq.oq_delay = (clock_t)qctrl->aq_delay;
591		oq.oq_minfree = qctrl->aq_minfree;
592
593		ret = auditon(A_OLDGETQCTRL, &oq, sizeof(oq));
594
595		qctrl->aq_hiwater = (int)oq.oq_hiwater;
596		qctrl->aq_lowater = (int)oq.oq_lowater;
597		qctrl->aq_bufsz = (int)oq.oq_bufsz;
598		qctrl->aq_delay = (int)oq.oq_delay;
599		qctrl->aq_minfree = oq.oq_minfree;
600	}
601#endif /* A_OLDGETQCTRL */
602	return (ret);
603}
604
605int
606audit_set_qctrl(au_qctrl_t *qctrl, size_t sz)
607{
608	int ret;
609
610	if (sizeof(*qctrl) != sz) {
611		errno = EINVAL;
612		return (-1);
613	}
614
615	ret = auditon(A_SETQCTRL, qctrl, sz);
616#ifdef	A_OLDSETQCTRL
617	if ((0 != ret) && (EINVAL == errno)) {
618		struct old_qctrl {
619			size_t   oq_hiwater;
620			size_t   oq_lowater;
621			size_t   oq_bufsz;
622			clock_t  oq_delay;
623			int	 oq_minfree;
624		} oq;
625
626		oq.oq_hiwater = (size_t)qctrl->aq_hiwater;
627		oq.oq_lowater = (size_t)qctrl->aq_lowater;
628		oq.oq_bufsz = (size_t)qctrl->aq_bufsz;
629		oq.oq_delay = (clock_t)qctrl->aq_delay;
630		oq.oq_minfree = qctrl->aq_minfree;
631
632		ret = auditon(A_OLDSETQCTRL, &oq, sizeof(oq));
633
634		qctrl->aq_hiwater = (int)oq.oq_hiwater;
635		qctrl->aq_lowater = (int)oq.oq_lowater;
636		qctrl->aq_bufsz = (int)oq.oq_bufsz;
637		qctrl->aq_delay = (int)oq.oq_delay;
638		qctrl->aq_minfree = oq.oq_minfree;
639	}
640#endif /* A_OLDSETQCTRL */
641	return (ret);
642}
643
644int
645audit_send_trigger(int *trigger)
646{
647
648	return (auditon(A_SENDTRIGGER, trigger, sizeof(*trigger)));
649}
650
651int
652audit_get_kaudit(auditinfo_addr_t *aia, size_t sz)
653{
654
655	if (sizeof(*aia) != sz) {
656		errno = EINVAL;
657		return (-1);
658	}
659
660	return (auditon(A_GETKAUDIT, aia, sz));
661}
662
663int
664audit_set_kaudit(auditinfo_addr_t *aia, size_t sz)
665{
666
667	if (sizeof(*aia) != sz) {
668		errno = EINVAL;
669		return (-1);
670	}
671
672	return (auditon(A_SETKAUDIT, aia, sz));
673}
674
675int
676audit_get_class(au_evclass_map_t *evc_map, size_t sz)
677{
678
679	if (sizeof(*evc_map) != sz) {
680		errno = EINVAL;
681		return (-1);
682	}
683
684	return (auditon(A_GETCLASS, evc_map, sz));
685}
686
687int
688audit_set_class(au_evclass_map_t *evc_map, size_t sz)
689{
690
691	if (sizeof(*evc_map) != sz) {
692		errno = EINVAL;
693		return (-1);
694	}
695
696	return (auditon(A_SETCLASS, evc_map, sz));
697}
698
699int
700audit_get_event(au_evname_map_t *evn_map, size_t sz)
701{
702
703	if (sizeof(*evn_map) != sz) {
704		errno = EINVAL;
705		return (-1);
706	}
707
708	return (auditon(A_GETEVENT, evn_map, sz));
709}
710
711int
712audit_set_event(au_evname_map_t *evn_map, size_t sz)
713{
714
715	if (sizeof(*evn_map) != sz) {
716		errno = EINVAL;
717		return (-1);
718	}
719
720	return (auditon(A_SETEVENT, evn_map, sz));
721}
722
723int
724audit_get_kmask(au_mask_t *kmask, size_t sz)
725{
726	if (sizeof(*kmask) != sz) {
727		errno = EINVAL;
728		return (-1);
729	}
730
731	return (auditon(A_GETKMASK, kmask, sz));
732}
733
734int
735audit_set_kmask(au_mask_t *kmask, size_t sz)
736{
737	if (sizeof(*kmask) != sz) {
738		errno = EINVAL;
739		return (-1);
740	}
741
742	return (auditon(A_SETKMASK, kmask, sz));
743}
744
745int
746audit_get_fsize(au_fstat_t *fstat, size_t sz)
747{
748
749	if (sizeof(*fstat) != sz) {
750		errno = EINVAL;
751		return (-1);
752	}
753
754	return (auditon(A_GETFSIZE, fstat, sz));
755}
756
757int
758audit_set_fsize(au_fstat_t *fstat, size_t sz)
759{
760
761	if (sizeof(*fstat) != sz) {
762		errno = EINVAL;
763		return (-1);
764	}
765
766	return (auditon(A_SETFSIZE, fstat, sz));
767}
768
769int
770audit_set_pmask(auditpinfo_t *api, size_t sz)
771{
772
773	if (sizeof(*api) != sz) {
774		errno = EINVAL;
775		return (-1);
776	}
777
778	return (auditon(A_SETPMASK, api, sz));
779}
780
781int
782audit_get_pinfo(auditpinfo_t *api, size_t sz)
783{
784
785	if (sizeof(*api) != sz) {
786		errno = EINVAL;
787		return (-1);
788	}
789
790	return (auditon(A_GETPINFO, api, sz));
791}
792
793int
794audit_get_pinfo_addr(auditpinfo_addr_t *apia, size_t sz)
795{
796
797	if (sizeof(*apia) != sz) {
798		errno = EINVAL;
799		return (-1);
800	}
801
802	return (auditon(A_GETPINFO_ADDR, apia, sz));
803}
804
805int
806audit_get_sinfo_addr(auditinfo_addr_t *aia, size_t sz)
807{
808
809	if (sizeof(*aia) != sz) {
810		errno = EINVAL;
811		return (-1);
812	}
813
814	return (auditon(A_GETSINFO_ADDR, aia, sz));
815}
816
817int
818audit_get_stat(au_stat_t *stats, size_t sz)
819{
820
821	if (sizeof(*stats) != sz) {
822		errno = EINVAL;
823		return (-1);
824	}
825
826	return (auditon(A_GETSTAT, stats, sz));
827}
828
829int
830audit_set_stat(au_stat_t *stats, size_t sz)
831{
832
833	if (sizeof(*stats) != sz) {
834		errno = EINVAL;
835		return (-1);
836	}
837
838	return (auditon(A_GETSTAT, stats, sz));
839}
840
841int
842audit_get_cwd(char *path, size_t sz)
843{
844
845	return (auditon(A_GETCWD, path, sz));
846}
847
848int
849audit_get_car(char *path, size_t sz)
850{
851
852	return (auditon(A_GETCAR, path, sz));
853}
854