bsm_wrappers.c revision 186647
150477Speter/*-
2139749Simp * Copyright (c) 2004 Apple Inc.
335388Smjacob * All rights reserved.
435388Smjacob *
535388Smjacob * Redistribution and use in source and binary forms, with or without
6154704Smjacob * modification, are permitted provided that the following conditions
735388Smjacob * are met:
845040Smjacob * 1.  Redistributions of source code must retain the above copyright
935388Smjacob *     notice, this list of conditions and the following disclaimer.
1035388Smjacob * 2.  Redistributions in binary form must reproduce the above copyright
1135388Smjacob *     notice, this list of conditions and the following disclaimer in the
1235388Smjacob *     documentation and/or other materials provided with the distribution.
1335388Smjacob * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
1435388Smjacob *     its contributors may be used to endorse or promote products derived
1566189Smjacob *     from this software without specific prior written permission.
1635388Smjacob *
1735388Smjacob * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND
1835388Smjacob * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1935388Smjacob * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2035388Smjacob * ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR
2135388Smjacob * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2235388Smjacob * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2335388Smjacob * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2435388Smjacob * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
2535388Smjacob * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
2635388Smjacob * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2735388Smjacob * POSSIBILITY OF SUCH DAMAGE.
2835388Smjacob *
2935388Smjacob * $P4: //depot/projects/trustedbsd/openbsm/libbsm/bsm_wrappers.c#28 $
3035388Smjacob */
3135388Smjacob
3235388Smjacob#ifdef __APPLE__
3335388Smjacob#define	_SYS_AUDIT_H		/* Prevent include of sys/audit.h. */
3435388Smjacob#endif
3535388Smjacob
3635388Smjacob#include <sys/param.h>
3735388Smjacob#include <sys/stat.h>
3835388Smjacob
3935388Smjacob#ifdef __APPLE__
4035388Smjacob#include <sys/queue.h>		/* Our bsm/audit.h doesn't include queue.h. */
4135388Smjacob#endif
4235388Smjacob
4335388Smjacob#include <sys/sysctl.h>
4435388Smjacob
4535388Smjacob#include <bsm/libbsm.h>
4635388Smjacob
4735388Smjacob#include <unistd.h>
4835388Smjacob#include <syslog.h>
4935388Smjacob#include <stdarg.h>
5035388Smjacob#include <string.h>
5135388Smjacob#include <errno.h>
5246967Smjacob
5346967Smjacob/* These are not advertised in libbsm.h */
5446967Smjacobint audit_set_terminal_port(dev_t *p);
5546967Smjacobint audit_set_terminal_host(uint32_t *m);
5646967Smjacob
5746967Smjacob/*
5846967Smjacob * General purpose audit submission mechanism for userspace.
5946967Smjacob */
6035388Smjacobint
6135388Smjacobaudit_submit(short au_event, au_id_t auid, char status,
6244819Smjacob    int reterr, const char *fmt, ...)
6335388Smjacob{
6444819Smjacob	char text[MAX_AUDITSTRING_LEN];
6544819Smjacob	token_t *token;
6682689Smjacob	long acond;
67163899Smjacob	va_list ap;
6835388Smjacob	pid_t pid;
6935388Smjacob	int error, afd, subj_ex;
7044819Smjacob	struct auditinfo ai;
7135388Smjacob	struct auditinfo_addr aia;
7235388Smjacob	au_tid_t atid;
7344819Smjacob
7435388Smjacob	if (auditon(A_GETCOND, &acond, sizeof(acond)) < 0) {
7535388Smjacob		/*
7644819Smjacob		 * If auditon(2) returns ENOSYS, then audit has not been
7744819Smjacob		 * compiled into the kernel, so just return.
7844819Smjacob		 */
7944819Smjacob		if (errno == ENOSYS)
8064088Smjacob			return (0);
8164088Smjacob		error = errno;
8264088Smjacob		syslog(LOG_AUTH | LOG_ERR, "audit: auditon failed: %s",
8335388Smjacob		    strerror(errno));
8435388Smjacob		errno = error;
8535388Smjacob		return (-1);
8635388Smjacob	}
8735388Smjacob	if (acond == AUC_NOAUDIT)
8844819Smjacob		return (0);
8944819Smjacob	afd = au_open();
9044819Smjacob	if (afd < 0) {
9144819Smjacob		error = errno;
9244819Smjacob		syslog(LOG_AUTH | LOG_ERR, "audit: au_open failed: %s",
9344819Smjacob		    strerror(errno));
9444819Smjacob		errno = error;
9544819Smjacob		return (-1);
9635388Smjacob	}
9735388Smjacob	/*
9835388Smjacob	 * Try to use getaudit_addr(2) first.  If this kernel does not support
9935388Smjacob	 * it, then fall back on to getaudit(2).
10044819Smjacob	 */
10154671Smjacob	subj_ex = 0;
10254671Smjacob	error = getaudit_addr(&aia, sizeof(aia));
10354671Smjacob	if (error < 0 && errno == ENOSYS) {
10454671Smjacob		error = getaudit(&ai);
10554671Smjacob		if (error < 0) {
10654671Smjacob			error = errno;
10754671Smjacob			syslog(LOG_AUTH | LOG_ERR, "audit: getaudit failed: %s",
10854671Smjacob			    strerror(errno));
10954671Smjacob			errno = error;
11054671Smjacob			return (-1);
11154671Smjacob		}
11282689Smjacob		/*
11382689Smjacob		 * Convert this auditinfo_t to an auditinfo_addr_t to make the
11482689Smjacob		 * following code less complicated wrt to preselection and
11582689Smjacob		 * subject token generation.
11682689Smjacob		 */
11782689Smjacob		aia.ai_auid = ai.ai_auid;
11882689Smjacob		aia.ai_mask = ai.ai_mask;
11982689Smjacob		aia.ai_asid = ai.ai_asid;
12082689Smjacob		aia.ai_termid.at_type = AU_IPv4;
12182689Smjacob		aia.ai_termid.at_addr[0] = ai.ai_termid.machine;
12282689Smjacob		aia.ai_termid.at_port = ai.ai_termid.port;
12382689Smjacob	} else if (error < 0) {
12482689Smjacob		error = errno;
12582689Smjacob		syslog(LOG_AUTH | LOG_ERR, "audit: getaudit_addr failed: %s",
12682689Smjacob		    strerror(errno));
12782689Smjacob		errno = error;
12882689Smjacob		return (-1);
12982689Smjacob	}
13082689Smjacob	/*
13182689Smjacob	 * NB: We should be performing pre-selection here now that we have the
13282689Smjacob	 * masks for this process.
13382689Smjacob	 */
13482689Smjacob	if (aia.ai_termid.at_type == AU_IPv6)
13582689Smjacob		subj_ex = 1;
13682689Smjacob	pid = getpid();
137163899Smjacob	if (subj_ex == 0) {
13854671Smjacob		atid.port = aia.ai_termid.at_port;
13944819Smjacob		atid.machine = aia.ai_termid.at_addr[0];
14054671Smjacob		token = au_to_subject32(auid, geteuid(), getegid(),
14144819Smjacob		    getuid(), getgid(), pid, pid, &atid);
14244819Smjacob	} else
14344819Smjacob		token = au_to_subject_ex(auid, geteuid(), getegid(),
14444819Smjacob		    getuid(), getgid(), pid, pid, &aia.ai_termid);
14554671Smjacob	if (token == NULL) {
14635388Smjacob		syslog(LOG_AUTH | LOG_ERR,
14754671Smjacob		    "audit: unable to build subject token");
14854671Smjacob		(void) au_close(afd, AU_TO_NO_WRITE, au_event);
14954671Smjacob		errno = EPERM;
15054671Smjacob		return (-1);
15154671Smjacob	}
15254671Smjacob	if (au_write(afd, token) < 0) {
15354671Smjacob		error = errno;
15454671Smjacob		syslog(LOG_AUTH | LOG_ERR,
15535388Smjacob		    "audit: au_write failed: %s", strerror(errno));
15654671Smjacob		(void) au_close(afd, AU_TO_NO_WRITE, au_event);
15735388Smjacob		errno = error;
15854671Smjacob		return (-1);
15954671Smjacob	}
16054671Smjacob	if (fmt != NULL) {
16154671Smjacob		va_start(ap, fmt);
16254671Smjacob		(void) vsnprintf(text, MAX_AUDITSTRING_LEN, fmt, ap);
16354671Smjacob		va_end(ap);
16454671Smjacob		token = au_to_text(text);
16535388Smjacob		if (token == NULL) {
16654671Smjacob			syslog(LOG_AUTH | LOG_ERR,
16754671Smjacob			    "audit: failed to generate text token");
16835388Smjacob			(void) au_close(afd, AU_TO_NO_WRITE, au_event);
16935388Smjacob			errno = EPERM;
17035388Smjacob			return (-1);
17135388Smjacob		}
17235388Smjacob		if (au_write(afd, token) < 0) {
17335388Smjacob			error = errno;
17435388Smjacob			syslog(LOG_AUTH | LOG_ERR,
17535388Smjacob			    "audit: au_write failed: %s", strerror(errno));
17635388Smjacob			(void) au_close(afd, AU_TO_NO_WRITE, au_event);
17735388Smjacob			errno = error;
17835388Smjacob			return (-1);
17935388Smjacob		}
18035388Smjacob	}
18135388Smjacob	token = au_to_return32(status, au_errno_to_bsm(reterr));
18235388Smjacob	if (token == NULL) {
18335388Smjacob		syslog(LOG_AUTH | LOG_ERR,
18435388Smjacob		    "audit: enable to build return token");
18535388Smjacob		(void) au_close(afd, AU_TO_NO_WRITE, au_event);
18635388Smjacob		errno = EPERM;
18735388Smjacob		return (-1);
18835388Smjacob	}
18935388Smjacob	if (au_write(afd, token) < 0) {
19035388Smjacob		error = errno;
19135388Smjacob		syslog(LOG_AUTH | LOG_ERR,
19254671Smjacob		    "audit: au_write failed: %s", strerror(errno));
19354671Smjacob		(void) au_close(afd, AU_TO_NO_WRITE, au_event);
19444819Smjacob		errno = error;
19544819Smjacob		return (-1);
19645040Smjacob	}
19735388Smjacob	if (au_close(afd, AU_TO_WRITE, au_event) < 0) {
19835388Smjacob		error = errno;
19935388Smjacob		syslog(LOG_AUTH | LOG_ERR, "audit: record not committed");
20035388Smjacob		errno = error;
20135388Smjacob		return (-1);
20235388Smjacob	}
203160080Smjacob	return (0);
204160080Smjacob}
20535388Smjacob
20635388Smjacobint
20735388Smjacobaudit_set_terminal_port(dev_t *p)
20835388Smjacob{
20935388Smjacob	struct stat st;
21035388Smjacob
21135388Smjacob	if (p == NULL)
21235388Smjacob		return (kAUBadParamErr);
21335388Smjacob
21435388Smjacob#ifdef NODEV
21535388Smjacob	*p = NODEV;
21635388Smjacob#else
21735388Smjacob	*p = -1;
218163899Smjacob#endif
219163899Smjacob
22035388Smjacob	/* for /usr/bin/login, try fstat() first */
22135388Smjacob	if (fstat(STDIN_FILENO, &st) != 0) {
22235388Smjacob		if (errno != EBADF) {
22335388Smjacob			syslog(LOG_ERR, "fstat() failed (%s)",
22435388Smjacob			    strerror(errno));
22535388Smjacob			return (kAUStatErr);
22635388Smjacob		}
22735388Smjacob		if (stat("/dev/console", &st) != 0) {
22835388Smjacob			syslog(LOG_ERR, "stat() failed (%s)",
229163899Smjacob			    strerror(errno));
23035388Smjacob			return (kAUStatErr);
23135388Smjacob		}
23235388Smjacob	}
23335388Smjacob	*p = st.st_rdev;
23435388Smjacob	return (kAUNoErr);
23535388Smjacob}
23635388Smjacob
23735388Smjacobint
23835388Smjacobaudit_set_terminal_host(uint32_t *m)
23935388Smjacob{
24035388Smjacob
24135388Smjacob#ifdef KERN_HOSTID
24235388Smjacob	int name[2] = { CTL_KERN, KERN_HOSTID };
24335388Smjacob	size_t len;
24435388Smjacob
24535388Smjacob	if (m == NULL)
246163899Smjacob		return (kAUBadParamErr);
247163899Smjacob	*m = 0;
248163899Smjacob	len = sizeof(*m);
249163899Smjacob	if (sysctl(name, 2, m, &len, NULL, 0) != 0) {
25035388Smjacob		syslog(LOG_ERR, "sysctl() failed (%s)", strerror(errno));
25162170Smjacob		return (kAUSysctlErr);
252163899Smjacob	}
253163899Smjacob	return (kAUNoErr);
25462170Smjacob#else
25535388Smjacob	*m = -1;
25635388Smjacob	return (kAUNoErr);
25735388Smjacob#endif
25835388Smjacob}
25939235Sgibbs
26039235Sgibbsint
26139235Sgibbsaudit_set_terminal_id(au_tid_t *tid)
26239235Sgibbs{
26339235Sgibbs	int ret;
264160080Smjacob
26539235Sgibbs	if (tid == NULL)
26635388Smjacob		return (kAUBadParamErr);
26735388Smjacob	if ((ret = audit_set_terminal_port(&tid->port)) != kAUNoErr)
26835388Smjacob		return (ret);
26935388Smjacob	return (audit_set_terminal_host(&tid->machine));
27035388Smjacob}
27135388Smjacob
27235388Smjacob/*
27335388Smjacob * This is OK for those callers who have only one token to write.  If you have
27435388Smjacob * multiple tokens that logically form part of the same audit record, you need
27535388Smjacob * to use the existing au_open()/au_write()/au_close() API:
27635388Smjacob *
27735388Smjacob * aufd = au_open();
27835388Smjacob * tok = au_to_random_token_1(...);
27935388Smjacob * au_write(aufd, tok);
28035388Smjacob * tok = au_to_random_token_2(...);
28135388Smjacob * au_write(aufd, tok);
28235388Smjacob * ...
28335388Smjacob * au_close(aufd, AU_TO_WRITE, AUE_your_event_type);
28435388Smjacob *
28535388Smjacob * Assumes, like all wrapper calls, that the caller has previously checked
28635388Smjacob * that auditing is enabled via the audit_get_state() call.
28735388Smjacob *
28835388Smjacob * XXX: Should be more robust against bad arguments.
28935388Smjacob */
29035388Smjacobint
29135388Smjacobaudit_write(short event_code, token_t *subject, token_t *misctok, char retval,
29235388Smjacob    int errcode)
29335388Smjacob{
29435388Smjacob	int aufd;
29535388Smjacob	char *func = "audit_write()";
29635388Smjacob	token_t *rettok;
29735388Smjacob
29835388Smjacob	if ((aufd = au_open()) == -1) {
29935388Smjacob		au_free_token(subject);
30035388Smjacob		au_free_token(misctok);
30135388Smjacob		syslog(LOG_ERR, "%s: au_open() failed", func);
30235388Smjacob		return (kAUOpenErr);
30335388Smjacob	}
30435388Smjacob
30535388Smjacob	/* Save subject. */
30635388Smjacob	if (subject && au_write(aufd, subject) == -1) {
30735388Smjacob		au_free_token(subject);
30835388Smjacob		au_free_token(misctok);
30935388Smjacob		(void)au_close(aufd, AU_TO_NO_WRITE, event_code);
31035388Smjacob		syslog(LOG_ERR, "%s: write of subject failed", func);
31135388Smjacob		return (kAUWriteSubjectTokErr);
31235388Smjacob	}
31335388Smjacob
31435388Smjacob	/* Save the event-specific token. */
31535388Smjacob	if (misctok && au_write(aufd, misctok) == -1) {
31635388Smjacob		au_free_token(misctok);
31735388Smjacob		(void)au_close(aufd, AU_TO_NO_WRITE, event_code);
31835388Smjacob		syslog(LOG_ERR, "%s: write of caller token failed", func);
31935388Smjacob		return (kAUWriteCallerTokErr);
32035388Smjacob	}
32135388Smjacob
32235388Smjacob	/* Tokenize and save the return value. */
32335388Smjacob	if ((rettok = au_to_return32(retval, errcode)) == NULL) {
32435388Smjacob		(void)au_close(aufd, AU_TO_NO_WRITE, event_code);
32535388Smjacob		syslog(LOG_ERR, "%s: au_to_return32() failed", func);
32635388Smjacob		return (kAUMakeReturnTokErr);
32735388Smjacob	}
32835388Smjacob
32935388Smjacob	if (au_write(aufd, rettok) == -1) {
33035388Smjacob		au_free_token(rettok);
33135388Smjacob		(void)au_close(aufd, AU_TO_NO_WRITE, event_code);
33235388Smjacob		syslog(LOG_ERR, "%s: write of return code failed", func);
33335388Smjacob		return (kAUWriteReturnTokErr);
33435388Smjacob	}
33535388Smjacob
33635388Smjacob	/*
33735388Smjacob	 * We assume the caller wouldn't have bothered with this
33835388Smjacob	 * function if it hadn't already decided to keep the record.
33935388Smjacob	 */
34035388Smjacob	if (au_close(aufd, AU_TO_WRITE, event_code) < 0) {
34135388Smjacob		syslog(LOG_ERR, "%s: au_close() failed", func);
34235388Smjacob		return (kAUCloseErr);
34335388Smjacob	}
34435388Smjacob
34535388Smjacob	return (kAUNoErr);
34635388Smjacob}
347163899Smjacob
348163899Smjacob/*
349163899Smjacob * Same caveats as audit_write().  In addition, this function explicitly
350163899Smjacob * assumes success; use audit_write_failure() on error.
351163899Smjacob */
352163899Smjacobint
353163899Smjacobaudit_write_success(short event_code, token_t *tok, au_id_t auid, uid_t euid,
354163899Smjacob    gid_t egid, uid_t ruid, gid_t rgid, pid_t pid, au_asid_t sid,
355163899Smjacob    au_tid_t *tid)
356163899Smjacob{
357163899Smjacob	char *func = "audit_write_success()";
358163899Smjacob	token_t *subject = NULL;
359163899Smjacob
360163899Smjacob	/* Tokenize and save subject. */
361163899Smjacob	subject = au_to_subject32(auid, euid, egid, ruid, rgid, pid, sid,
362163899Smjacob	    tid);
363163899Smjacob	if (subject == NULL) {
364163899Smjacob		syslog(LOG_ERR, "%s: au_to_subject32() failed", func);
365163899Smjacob		return kAUMakeSubjectTokErr;
366163899Smjacob	}
367163899Smjacob
368163899Smjacob	return (audit_write(event_code, subject, tok, 0, 0));
369163899Smjacob}
370163899Smjacob
371163899Smjacob/*
372163899Smjacob * Same caveats as audit_write().  In addition, this function explicitly
373163899Smjacob * assumes success; use audit_write_failure_self() on error.
374163899Smjacob */
375163899Smjacobint
376163899Smjacobaudit_write_success_self(short event_code, token_t *tok)
377163899Smjacob{
378163899Smjacob	token_t *subject;
379163899Smjacob	char *func = "audit_write_success_self()";
380163899Smjacob
381163899Smjacob	if ((subject = au_to_me()) == NULL) {
382163899Smjacob		syslog(LOG_ERR, "%s: au_to_me() failed", func);
383163899Smjacob		return (kAUMakeSubjectTokErr);
384163899Smjacob	}
385163899Smjacob
386163899Smjacob	return (audit_write(event_code, subject, tok, 0, 0));
387163899Smjacob}
388163899Smjacob
389163899Smjacob/*
390163899Smjacob * Same caveats as audit_write().  In addition, this function explicitly
391163899Smjacob * assumes failure; use audit_write_success() otherwise.
392163899Smjacob *
393163899Smjacob * XXX  This should let the caller pass an error return value rather than
394163899Smjacob * hard-coding -1.
395163899Smjacob */
396163899Smjacobint
397163899Smjacobaudit_write_failure(short event_code, char *errmsg, int errcode, au_id_t auid,
398163899Smjacob    uid_t euid, gid_t egid, uid_t ruid, gid_t rgid, pid_t pid, au_asid_t sid,
399163899Smjacob    au_tid_t *tid)
400163899Smjacob{
401163899Smjacob	char *func = "audit_write_failure()";
402163899Smjacob	token_t *subject, *errtok;
403163899Smjacob
404163899Smjacob	subject = au_to_subject32(auid, euid, egid, ruid, rgid, pid, sid, tid);
405163899Smjacob	if (subject == NULL) {
406163899Smjacob		syslog(LOG_ERR, "%s: au_to_subject32() failed", func);
407163899Smjacob		return (kAUMakeSubjectTokErr);
408163899Smjacob	}
409163899Smjacob
410163899Smjacob	/* tokenize and save the error message */
411163899Smjacob	if ((errtok = au_to_text(errmsg)) == NULL) {
412166929Smjacob		au_free_token(subject);
413166929Smjacob		syslog(LOG_ERR, "%s: au_to_text() failed", func);
414166929Smjacob		return (kAUMakeTextTokErr);
415166929Smjacob	}
416166929Smjacob
417166929Smjacob	return (audit_write(event_code, subject, errtok, -1, errcode));
418166929Smjacob}
419166929Smjacob
420163899Smjacob/*
421163899Smjacob * Same caveats as audit_write().  In addition, this function explicitly
422163899Smjacob * assumes failure; use audit_write_success_self() otherwise.
423163899Smjacob *
424163899Smjacob * XXX  This should let the caller pass an error return value rather than
425163899Smjacob * hard-coding -1.
426163899Smjacob */
42735388Smjacobint
42835388Smjacobaudit_write_failure_self(short event_code, char *errmsg, int errret)
42935388Smjacob{
43054671Smjacob	char *func = "audit_write_failure_self()";
43154671Smjacob	token_t *subject, *errtok;
43254671Smjacob
43354671Smjacob	if ((subject = au_to_me()) == NULL) {
43454671Smjacob		syslog(LOG_ERR, "%s: au_to_me() failed", func);
43554671Smjacob		return (kAUMakeSubjectTokErr);
43654671Smjacob	}
43754671Smjacob	/* tokenize and save the error message */
43835388Smjacob	if ((errtok = au_to_text(errmsg)) == NULL) {
43954671Smjacob		au_free_token(subject);
44054671Smjacob		syslog(LOG_ERR, "%s: au_to_text() failed", func);
44154671Smjacob		return (kAUMakeTextTokErr);
44254671Smjacob	}
44354671Smjacob	return (audit_write(event_code, subject, errtok, -1, errret));
44454671Smjacob}
44554671Smjacob
44654671Smjacob/*
44735388Smjacob * For auditing errors during login.  Such errors are implicitly
448154704Smjacob * non-attributable (i.e., not ascribable to any user).
449154704Smjacob *
450154704Smjacob * Assumes, like all wrapper calls, that the caller has previously checked
451154704Smjacob * that auditing is enabled via the audit_get_state() call.
452163899Smjacob */
453154704Smjacobint
45462170Smjacobaudit_write_failure_na(short event_code, char *errmsg, int errret, uid_t euid,
45535388Smjacob    uid_t egid, pid_t pid, au_tid_t *tid)
45635388Smjacob{
457154704Smjacob
45862170Smjacob	return (audit_write_failure(event_code, errmsg, errret, -1, euid,
45962170Smjacob	    egid, -1, -1, pid, -1, tid));
460154704Smjacob}
46135388Smjacob
462154704Smjacob/* END OF au_write() WRAPPERS */
463154704Smjacob
464163899Smjacob#ifdef __APPLE__
465163899Smjacobvoid
466154704Smjacobaudit_token_to_au32(audit_token_t atoken, uid_t *auidp, uid_t *euidp,
467155704Smjacob    gid_t *egidp, uid_t *ruidp, gid_t *rgidp, pid_t *pidp, au_asid_t *asidp,
468163899Smjacob    au_tid_t *tidp)
469163899Smjacob{
470163899Smjacob
471163899Smjacob	if (auidp != NULL)
472163899Smjacob		*auidp = (uid_t)atoken.val[0];
473154704Smjacob	if (euidp != NULL)
47462170Smjacob		*euidp = (uid_t)atoken.val[1];
47535388Smjacob	if (egidp != NULL)
47671078Smjacob		*egidp = (gid_t)atoken.val[2];
47771078Smjacob	if (ruidp != NULL)
47871078Smjacob		*ruidp = (uid_t)atoken.val[3];
47971078Smjacob	if (rgidp != NULL)
48071078Smjacob		*rgidp = (gid_t)atoken.val[4];
48171078Smjacob	if (pidp != NULL)
48271078Smjacob		*pidp = (pid_t)atoken.val[5];
48371078Smjacob	if (asidp != NULL)
48471078Smjacob		*asidp = (au_asid_t)atoken.val[6];
48571078Smjacob	if (tidp != NULL) {
48671078Smjacob		audit_set_terminal_host(&tidp->machine);
48771078Smjacob		tidp->port = (dev_t)atoken.val[7];
48871078Smjacob	}
48935388Smjacob}
49035388Smjacob#endif /* !__APPLE__ */
49154671Smjacob