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