xref: /illumos-gate/usr/src/lib/libbsm/common/adt.c (revision 0542eecf8a04bde577ee69151dfe367a36053e40)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
24  */
25 
26 #include <bsm/adt.h>
27 #include <bsm/adt_event.h>
28 #include <assert.h>
29 #include <bsm/audit.h>
30 #include <bsm/audit_record.h>
31 #include <bsm/libbsm.h>
32 #include <door.h>
33 #include <errno.h>
34 #include <generic.h>
35 #include <md5.h>
36 #include <sys/mkdev.h>
37 #include <netdb.h>
38 #include <nss_dbdefs.h>
39 #include <pwd.h>
40 #include <sys/stat.h>
41 #include <time.h>
42 #include <stdlib.h>
43 #include <string.h>
44 #include <synch.h>
45 #include <sys/systeminfo.h>
46 #include <syslog.h>
47 #include <thread.h>
48 #include <unistd.h>
49 #include <adt_xlate.h>
50 #include <adt_ucred.h>
51 #include <arpa/inet.h>
52 #include <net/if.h>
53 #include <libinetutil.h>
54 
55 static int adt_selected(struct adt_event_state *, au_event_t, int);
56 static int adt_init(adt_internal_state_t *, int);
57 static int adt_import(adt_internal_state_t *, const adt_export_data_t *);
58 static m_label_t *adt_ucred_label(ucred_t *);
59 static void adt_setto_unaudited(adt_internal_state_t *);
60 static int adt_get_local_address(int, struct ifaddrlist *);
61 
62 #ifdef C2_DEBUG
63 #define	DPRINTF(x) { (void) printf x; }
64 #define	DFLUSH (void) fflush(stdout);
65 #else
66 #define	DPRINTF(x)
67 #define	DFLUSH
68 #endif
69 
70 /*
71  * Local audit states are a bit mask
72  *
73  * The global audit states are
74  *
75  * AUC_UNSET             0      - on/off hasn't been decided
76  * AUC_ENABLED           1      - loaded and enabled
77  *
78  * The local Zone states are
79  *
80  * AUC_AUDITING         0x1     - audit daemon is active
81  * AUC_NOAUDIT          0x2     - audit daemon is not active
82  * AUC_INIT_AUDIT       0x4     - audit is ready but auditd has not run
83  * AUC_NOSPACE          0x8     - audit enabled, no space for audit records
84  *
85  * The only values returned by auditon(A_GETCOND) are:
86  * AUC_INIT_AUDIT, AUC_AUDITING, AUC_NOAUDIT, AUC_NOSPACE
87  *
88  * The pseudo audit state used when the c2audit module is excluded is
89  *
90  * AUC_DISABLED		0x100	- c2audit module is excluded
91  */
92 
93 static int auditstate = AUC_DISABLED;	/* default state */
94 
95 /*
96  * adt_write_syslog
97  *
98  * errors that are not the user's fault (bugs or whatever in
99  * the underlying audit code are noted in syslog.)
100  *
101  * Avoid calling adt_write_syslog for things that can happen
102  * at high volume.
103  *
104  * syslog's open (openlog) and close (closelog) are interesting;
105  * openlog *may* create a file descriptor and is optional.  closelog
106  * *will* close any open file descriptors and is also optional.
107  *
108  * Since syslog may also be used by the calling application, the
109  * choice is to avoid openlog, which sets some otherwise useful
110  * parameters, and to embed "Solaris_audit" in the log message.
111  */
112 
113 void
114 adt_write_syslog(const char *message, int err)
115 {
116 	int	save_errno = errno;
117 	int	mask_priority;
118 
119 	DPRINTF(("syslog called: %s\n", message));
120 
121 	mask_priority = setlogmask(LOG_MASK(LOG_ALERT));
122 	errno = err;
123 	syslog(LOG_ALERT, "Solaris_audit %s: %m", message);
124 	(void) setlogmask(mask_priority);
125 	errno = save_errno;
126 }
127 
128 /*
129  * return true if c2audit is not excluded.
130  *
131  *	For purpose of this API, anything but AUC_DISABLED
132  *	is enabled; however one never actually sees
133  *	AUC_DISABLED since auditon returns ENOTSUP in that case.  Any
134  *	auditon error is considered the same as ENOTSUP for our
135  *	purpose.  auditstate is not changed by auditon if an error
136  *	is returned.
137  */
138 
139 /*
140  * XXX	this should probably be eliminated and adt_audit_state() replace it.
141  *	All the legitimate uses	are to not fork a waiting process for
142  *	process exit processing, as in su, login, dtlogin.  Other bogus
143  *	users are zoneadmd and init.
144  *	All but dtlogin are in ON, so we can do this without cross gate
145  *	synchronization.
146  *
147  *	No longer used in adt.c.
148  */
149 
150 boolean_t
151 adt_audit_enabled(void)
152 {
153 
154 	(void) auditon(A_GETCOND, (caddr_t)&auditstate, sizeof (auditstate));
155 
156 	return (auditstate != AUC_DISABLED);
157 }
158 
159 /*
160  *	See adt_audit_enabled() for state discussions.
161  *	The state parameter is a hedge until all the uses become clear.
162  *	Likely if adt_audit_enabled is brought internal to this file,
163  *	it can take a parameter discussing the state.
164  */
165 
166 boolean_t
167 adt_audit_state(int state)
168 {
169 
170 	(void) auditon(A_GETCOND, (caddr_t)&auditstate, sizeof (auditstate));
171 
172 	return (auditstate & state);
173 }
174 
175 /*
176  * The man page for getpwuid_r says the buffer must be big enough
177  * or ERANGE will be returned, but offers no guidance for how big
178  * the buffer should be or a way to calculate it.  If you get
179  * ERANGE, double pwd_buff's size.
180  *
181  * This may be called even when auditing is off.
182  */
183 
184 #define	NAFLAG_LEN 512
185 
186 static int
187 adt_get_mask_from_user(uid_t uid, au_mask_t *mask)
188 {
189 	struct passwd	pwd;
190 	char		pwd_buff[NSS_BUFSIZ];
191 	char		naflag_buf[NAFLAG_LEN];
192 
193 	if (auditstate & AUC_DISABLED) {
194 		/* c2audit excluded */
195 		mask->am_success = 0;
196 		mask->am_failure = 0;
197 	} else if (uid <= MAXUID) {
198 		if (getpwuid_r(uid, &pwd, pwd_buff, NSS_BUFSIZ) == NULL) {
199 			/*
200 			 * getpwuid_r returns NULL without setting
201 			 * errno if the user does not exist; only
202 			 * if the input is the wrong length does it
203 			 * set errno.
204 			 */
205 			if (errno != ERANGE)
206 				errno = EINVAL;
207 			return (-1);
208 		}
209 		if (au_user_mask(pwd.pw_name, mask)) {
210 			errno = EFAULT; /* undetermined failure */
211 			return (-1);
212 		}
213 	} else if (getacna(naflag_buf, NAFLAG_LEN - 1) == 0) {
214 		if (getauditflagsbin(naflag_buf, mask))
215 			return (-1);
216 	} else {
217 		return (-1);
218 	}
219 	return (0);
220 }
221 
222 /*
223  * adt_get_unique_id -- generate a hopefully unique 32 bit value
224  *
225  * there will be a follow up to replace this with the use of /dev/random
226  *
227  * An MD5 hash is taken on a buffer of
228  *     hostname . audit id . unix time . pid . count
229  *
230  * "count = noise++;" is subject to a race condition but I don't
231  * see a need to put a lock around it.
232  */
233 
234 au_asid_t
235 adt_get_unique_id(au_id_t uid)
236 {
237 	char		hostname[MAXHOSTNAMELEN];
238 	union {
239 		au_id_t		v[4];
240 		unsigned char	obuff[128/8];
241 	} output;
242 	MD5_CTX	context;
243 
244 	static int	noise = 0;
245 
246 	int		count = noise++;
247 	time_t		timebits = time(NULL);
248 	pid_t		pidbits = getpid();
249 	au_asid_t	retval = 0;
250 
251 	if (gethostname(hostname, MAXHOSTNAMELEN)) {
252 		adt_write_syslog("gethostname call failed", errno);
253 		(void) strncpy(hostname, "invalidHostName", MAXHOSTNAMELEN);
254 	}
255 
256 	while (retval == 0) {  /* 0 is the only invalid result */
257 		MD5Init(&context);
258 
259 		MD5Update(&context, (unsigned char *)hostname,
260 		    (unsigned int) strlen((const char *)hostname));
261 
262 		MD5Update(&context, (unsigned char *) &uid, sizeof (uid_t));
263 
264 		MD5Update(&context,
265 		    (unsigned char *) &timebits, sizeof (time_t));
266 
267 		MD5Update(&context, (unsigned char *) &pidbits,
268 		    sizeof (pid_t));
269 
270 		MD5Update(&context, (unsigned char *) &(count), sizeof (int));
271 		MD5Final(output.obuff, &context);
272 
273 		retval = output.v[count % 4];
274 	}
275 	return (retval);
276 }
277 
278 /*
279  * the following "port" function deals with the following issues:
280  *
281  * 1    the kernel and ucred deal with a dev_t as a 64 bit value made
282  *      up from a 32 bit major and 32 bit minor.
283  * 2    User space deals with a dev_t as either the above 64 bit value
284  *      or a 32 bit value made from a 14 bit major and an 18 bit minor.
285  * 3    The various audit interfaces (except ucred) pass the 32 or
286  *      64 bit version depending the architecture of the userspace
287  *      application.  If you get a port value from ucred and pass it
288  *      to the kernel via auditon(), it must be squeezed into a 32
289  *      bit value because the kernel knows the userspace app's bit
290  *      size.
291  *
292  * The internal state structure for adt (adt_internal_state_t) uses
293  * dev_t, so adt converts data from ucred to fit.  The import/export
294  * functions, however, can't know if they are importing/exporting
295  * from 64 or 32 bit applications, so they always send 64 bits and
296  * the 32 bit end(s) are responsible to convert 32 -> 64 -> 32 as
297  * appropriate.
298  */
299 
300 /*
301  * adt_cpy_tid() -- if lib is 64 bit, just copy it (dev_t and port are
302  * both 64 bits).  If lib is 32 bits, squeeze the two-int port into
303  * a 32 bit dev_t.  A port fits in the "minor" part of au_port_t,
304  * so it isn't broken up into pieces.  (When it goes to the kernel
305  * and back, however, it will have been split into major/minor
306  * pieces.)
307  */
308 
309 static void
310 adt_cpy_tid(au_tid_addr_t *dest, const au_tid64_addr_t *src)
311 {
312 #ifdef _LP64
313 	(void) memcpy(dest, src, sizeof (au_tid_addr_t));
314 #else	/* _LP64 */
315 	dest->at_type = src->at_type;
316 
317 	dest->at_port  = src->at_port.at_minor & MAXMIN32;
318 	dest->at_port |= (src->at_port.at_major & MAXMAJ32) <<
319 	    NBITSMINOR32;
320 
321 	(void) memcpy(dest->at_addr, src->at_addr, 4 * sizeof (uint32_t));
322 #endif	/* _LP64 */
323 }
324 
325 /*
326  * adt_start_session -- create interface handle, create context
327  *
328  * The imported_state input is normally NULL, if not, it represents
329  * a continued session; its values obviate the need for a subsequent
330  * call to adt_set_user().
331  *
332  * The flag is used to decide how to set the initial state of the session.
333  * If 0, the session is "no audit" until a call to adt_set_user; if
334  * ADT_USE_PROC_DATA, the session is built from the process audit
335  * characteristics obtained from the kernel.  If imported_state is
336  * not NULL, the resulting audit mask is an OR of the current process
337  * audit mask and that passed in.
338  *
339  * The basic model is that the caller can use the pointer returned
340  * by adt_start_session whether or not auditing is enabled or an
341  * error was returned.  The functions that take the session handle
342  * as input generally return without doing anything if auditing is
343  * disabled.
344  */
345 
346 int
347 adt_start_session(adt_session_data_t **new_session,
348     const adt_export_data_t *imported_state, adt_session_flags_t flags)
349 {
350 	adt_internal_state_t	*state;
351 	adt_session_flags_t	flgmask = ADT_FLAGS_ALL;
352 
353 	/* test and set auditstate */
354 	if (adt_audit_state(AUC_DISABLED)) {
355 		/* c2audit excluded */
356 		*new_session = NULL;
357 		return (0);
358 	}
359 
360 	if ((flags & ~flgmask) != 0) {
361 		errno = EINVAL;
362 		goto return_err;
363 	}
364 
365 	if ((state = calloc(1, sizeof (adt_internal_state_t))) == NULL) {
366 		goto return_err;
367 	}
368 
369 	if (adt_init(state, flags & ADT_USE_PROC_DATA) != 0) {
370 		goto return_err_free;    /* errno from adt_init() */
371 	}
372 
373 	/*
374 	 * The imported state overwrites the initial state if the
375 	 * imported state represents a valid audit trail
376 	 */
377 
378 	if (imported_state != NULL) {
379 		if (adt_import(state, imported_state) != 0) {
380 			goto return_err_free;
381 		}
382 	} else if (flags & ADT_USE_PROC_DATA) {
383 		state->as_session_model = ADT_PROCESS_MODEL;
384 	}
385 	state->as_flags = flags;
386 	DPRINTF(("(%lld) Starting session id = %08X\n",
387 	    (long long) getpid(), state->as_info.ai_asid));
388 
389 	*new_session = (adt_session_data_t *)state;
390 	return (0);
391 
392 return_err_free:
393 	free(state);
394 return_err:
395 	*new_session = NULL;
396 	adt_write_syslog("audit session create failed", errno);
397 	return (-1);
398 }
399 
400 /*
401  * adt_load_table()
402  *
403  * loads the event translation table into the audit session.
404  */
405 
406 void
407 adt_load_table(const adt_session_data_t *session_data,
408     adt_translation_t **xlate, void (*preload)(au_event_t, adt_event_data_t *))
409 {
410 	adt_internal_state_t	*state = (adt_internal_state_t *)session_data;
411 
412 	if (state != NULL) {
413 		assert(state->as_check == ADT_VALID);
414 		state->as_xlate = xlate;
415 		state->as_preload = preload;
416 	}
417 }
418 
419 /*
420  * adt_get_asid() and adt_set_asid()
421  *
422  * if you use this interface, you are responsible to insure that the
423  * rest of the session data is populated correctly before calling
424  * adt_proccess_attr()
425  *
426  * neither of these are intended for general use and will likely
427  * remain private interfaces for a long time.  Forever is a long
428  * time.  In the case of adt_set_asid(), you should have a very,
429  * very good reason for setting your own session id.  The process
430  * audit characteristics are not changed by put, use adt_set_proc().
431  *
432  * These are "volatile" (more changable than "evolving") and will
433  * probably change in the S10 period.
434  */
435 
436 void
437 adt_get_asid(const adt_session_data_t *session_data, au_asid_t *asid)
438 {
439 
440 	if (session_data == NULL) {
441 		*asid = 0;
442 	} else {
443 		assert(((adt_internal_state_t *)session_data)->as_check ==
444 		    ADT_VALID);
445 
446 		*asid = ((adt_internal_state_t *)session_data)->as_info.ai_asid;
447 	}
448 }
449 
450 void
451 adt_set_asid(const adt_session_data_t *session_data, const au_asid_t session_id)
452 {
453 
454 	if (session_data != NULL) {
455 		assert(((adt_internal_state_t *)session_data)->as_check ==
456 		    ADT_VALID);
457 
458 		((adt_internal_state_t *)session_data)->as_have_user_data |=
459 		    ADT_HAVE_ASID;
460 		((adt_internal_state_t *)session_data)->as_info.ai_asid =
461 		    session_id;
462 	}
463 }
464 
465 /*
466  * adt_get_auid() and adt_set_auid()
467  *
468  * neither of these are intended for general use and will likely
469  * remain private interfaces for a long time.  Forever is a long
470  * time.  In the case of adt_set_auid(), you should have a very,
471  * very good reason for setting your own audit id.  The process
472  * audit characteristics are not changed by put, use adt_set_proc().
473  */
474 
475 void
476 adt_get_auid(const adt_session_data_t *session_data, au_id_t *auid)
477 {
478 
479 	if (session_data == NULL) {
480 		*auid = AU_NOAUDITID;
481 	} else {
482 		assert(((adt_internal_state_t *)session_data)->as_check ==
483 		    ADT_VALID);
484 
485 		*auid = ((adt_internal_state_t *)session_data)->as_info.ai_auid;
486 	}
487 }
488 
489 void
490 adt_set_auid(const adt_session_data_t *session_data, const au_id_t audit_id)
491 {
492 
493 	if (session_data != NULL) {
494 		assert(((adt_internal_state_t *)session_data)->as_check ==
495 		    ADT_VALID);
496 
497 		((adt_internal_state_t *)session_data)->as_have_user_data |=
498 		    ADT_HAVE_AUID;
499 		((adt_internal_state_t *)session_data)->as_info.ai_auid =
500 		    audit_id;
501 	}
502 }
503 
504 /*
505  * adt_get_termid(), adt_set_termid()
506  *
507  * if you use this interface, you are responsible to insure that the
508  * rest of the session data is populated correctly before calling
509  * adt_proccess_attr()
510  *
511  * The process  audit characteristics are not changed by put, use
512  * adt_set_proc().
513  */
514 
515 void
516 adt_get_termid(const adt_session_data_t *session_data, au_tid_addr_t *termid)
517 {
518 
519 	if (session_data == NULL) {
520 		(void) memset(termid, 0, sizeof (au_tid_addr_t));
521 		termid->at_type = AU_IPv4;
522 	} else {
523 		assert(((adt_internal_state_t *)session_data)->as_check ==
524 		    ADT_VALID);
525 
526 		*termid =
527 		    ((adt_internal_state_t *)session_data)->as_info.ai_termid;
528 	}
529 }
530 
531 void
532 adt_set_termid(const adt_session_data_t *session_data,
533     const au_tid_addr_t *termid)
534 {
535 
536 	if (session_data != NULL) {
537 		assert(((adt_internal_state_t *)session_data)->as_check ==
538 		    ADT_VALID);
539 
540 		((adt_internal_state_t *)session_data)->as_info.ai_termid =
541 		    *termid;
542 
543 		((adt_internal_state_t *)session_data)->as_have_user_data |=
544 		    ADT_HAVE_TID;
545 	}
546 }
547 
548 /*
549  * adt_get_mask(), adt_set_mask()
550  *
551  * if you use this interface, you are responsible to insure that the
552  * rest of the session data is populated correctly before calling
553  * adt_proccess_attr()
554  *
555  * The process  audit characteristics are not changed by put, use
556  * adt_set_proc().
557  */
558 
559 void
560 adt_get_mask(const adt_session_data_t *session_data, au_mask_t *mask)
561 {
562 
563 	if (session_data == NULL) {
564 		mask->am_success = 0;
565 		mask->am_failure = 0;
566 	} else {
567 		assert(((adt_internal_state_t *)session_data)->as_check ==
568 		    ADT_VALID);
569 
570 		*mask = ((adt_internal_state_t *)session_data)->as_info.ai_mask;
571 	}
572 }
573 
574 void
575 adt_set_mask(const adt_session_data_t *session_data, const au_mask_t *mask)
576 {
577 
578 	if (session_data != NULL) {
579 		assert(((adt_internal_state_t *)session_data)->as_check ==
580 		    ADT_VALID);
581 
582 		((adt_internal_state_t *)session_data)->as_info.ai_mask = *mask;
583 
584 		((adt_internal_state_t *)session_data)->as_have_user_data |=
585 		    ADT_HAVE_MASK;
586 	}
587 }
588 
589 /*
590  * helpers for adt_load_termid
591  */
592 
593 static void
594 adt_do_ipv6_address(struct sockaddr_in6 *peer, struct sockaddr_in6 *sock,
595     au_tid_addr_t *termid)
596 {
597 
598 	termid->at_port = ((peer->sin6_port<<16) | (sock->sin6_port));
599 	termid->at_type = AU_IPv6;
600 	(void) memcpy(termid->at_addr, &peer->sin6_addr, 4 * sizeof (uint_t));
601 }
602 
603 static void
604 adt_do_ipv4_address(struct sockaddr_in *peer, struct sockaddr_in *sock,
605     au_tid_addr_t *termid)
606 {
607 
608 	termid->at_port = ((peer->sin_port<<16) | (sock->sin_port));
609 
610 	termid->at_type = AU_IPv4;
611 	termid->at_addr[0] = (uint32_t)peer->sin_addr.s_addr;
612 	(void) memset(&(termid->at_addr[1]), 0, 3 * sizeof (uint_t));
613 }
614 
615 /*
616  * adt_load_termid:  convenience function; inputs file handle and
617  * outputs an au_tid_addr struct.
618  *
619  * This code was stolen from audit_settid.c; it differs from audit_settid()
620  * in that it does not write the terminal id to the process.
621  */
622 
623 int
624 adt_load_termid(int fd, adt_termid_t **termid)
625 {
626 	au_tid_addr_t		*p_term;
627 	struct sockaddr_in6	peer;
628 	struct sockaddr_in6	sock;
629 	int			peerlen = sizeof (peer);
630 	int			socklen = sizeof (sock);
631 
632 	/* get peer name if its a socket, else assume local terminal */
633 
634 	if (getpeername(fd, (struct sockaddr *)&peer, (socklen_t *)&peerlen)
635 	    < 0) {
636 		if (errno == ENOTSOCK) {
637 			return (adt_load_hostname(NULL, termid));
638 		}
639 		goto return_err;
640 	}
641 
642 	if ((p_term = calloc(1, sizeof (au_tid_addr_t))) == NULL) {
643 		goto return_err;
644 	}
645 
646 	/* get sock name */
647 	if (getsockname(fd, (struct sockaddr *)&sock,
648 	    (socklen_t *)&socklen) < 0) {
649 		goto return_err_free;
650 	}
651 
652 	if (peer.sin6_family == AF_INET6) {
653 		adt_do_ipv6_address(&peer, &sock, p_term);
654 	} else {
655 		adt_do_ipv4_address((struct sockaddr_in *)&peer,
656 		    (struct sockaddr_in *)&sock, p_term);
657 	}
658 	*termid = (adt_termid_t *)p_term;
659 
660 	return (0);
661 
662 return_err_free:
663 	free(p_term);
664 return_err:
665 	*termid = NULL;
666 	return (-1);
667 }
668 
669 static boolean_t
670 adt_have_termid(au_tid_addr_t *dest)
671 {
672 	struct auditinfo_addr	audit_data;
673 
674 	if (getaudit_addr(&audit_data, sizeof (audit_data)) < 0) {
675 		adt_write_syslog("getaudit failed", errno);
676 		return (B_FALSE);
677 	}
678 
679 	if ((audit_data.ai_termid.at_type == 0) ||
680 	    (audit_data.ai_termid.at_addr[0] |
681 	    audit_data.ai_termid.at_addr[1]  |
682 	    audit_data.ai_termid.at_addr[2]  |
683 	    audit_data.ai_termid.at_addr[3]) == 0)
684 		return (B_FALSE);
685 
686 	(void) memcpy(dest, &(audit_data.ai_termid),
687 	    sizeof (au_tid_addr_t));
688 
689 	return (B_TRUE);
690 }
691 
692 /*
693  * adt_get_hostIP - construct a terminal id from a hostname
694  *
695  *	Returns	 0 = success
696  *		-1 = failure and errno = ENETDOWN with the address
697  *		     defaulted to IPv4 loopback.
698  */
699 
700 static int
701 adt_get_hostIP(const char *hostname, au_tid_addr_t *p_term)
702 {
703 	struct addrinfo	*ai = NULL;
704 	int	tries = 3;
705 	char	msg[512];
706 	int	eai_err;
707 
708 	while ((tries-- > 0) &&
709 	    ((eai_err = getaddrinfo(hostname, NULL, NULL, &ai)) != 0)) {
710 		/*
711 		 * getaddrinfo returns its own set of errors.
712 		 * Log them here, so any subsequent syslogs will
713 		 * have a context.  adt_get_hostIP callers can only
714 		 * return errno, so subsequent syslogs may be lacking
715 		 * that getaddrinfo failed.
716 		 */
717 		(void) snprintf(msg, sizeof (msg), "getaddrinfo(%s) "
718 		    "failed[%s]", hostname, gai_strerror(eai_err));
719 		adt_write_syslog(msg, 0);
720 
721 		if (eai_err != EAI_AGAIN) {
722 
723 			break;
724 		}
725 		/* see if resolution becomes available */
726 		(void) sleep(1);
727 	}
728 	if (ai != NULL) {
729 		if (ai->ai_family == AF_INET) {
730 			p_term->at_type = AU_IPv4;
731 			(void) memcpy(p_term->at_addr,
732 			    /* LINTED */
733 			    &((struct sockaddr_in *)ai->ai_addr)->sin_addr,
734 			    AU_IPv4);
735 		} else {
736 			p_term->at_type = AU_IPv6;
737 			(void) memcpy(p_term->at_addr,
738 			    /* LINTED */
739 			    &((struct sockaddr_in6 *)ai->ai_addr)->sin6_addr,
740 			    AU_IPv6);
741 		}
742 		freeaddrinfo(ai);
743 		return (0);
744 	} else if (auditstate & (AUC_AUDITING | AUC_NOSPACE)) {
745 		auditinfo_addr_t  audit_info;
746 
747 		/*
748 		 * auditd is running so there should be a
749 		 * kernel audit context
750 		 */
751 		if (auditon(A_GETKAUDIT, (caddr_t)&audit_info,
752 		    sizeof (audit_info)) < 0) {
753 			adt_write_syslog("unable to get kernel audit context",
754 			    errno);
755 			goto try_interface;
756 		}
757 		adt_write_syslog("setting Audit IP address to kernel", 0);
758 		*p_term = audit_info.ai_termid;
759 		return (0);
760 	}
761 try_interface:
762 	{
763 		struct ifaddrlist al;
764 		int	family;
765 		char	ntop[INET6_ADDRSTRLEN];
766 
767 		/*
768 		 * getaddrinfo has failed to map the hostname
769 		 * to an IP address, try to get an IP address
770 		 * from a local interface.  If none up, default
771 		 * to loopback.
772 		 */
773 		family = AF_INET6;
774 		if (adt_get_local_address(family, &al) != 0) {
775 			family = AF_INET;
776 
777 			if (adt_get_local_address(family, &al) != 0) {
778 				adt_write_syslog("adt_get_local_address "
779 				    "failed, no Audit IP address available, "
780 				    "faking loopback and error",
781 				    errno);
782 				IN_SET_LOOPBACK_ADDR(
783 				    (struct sockaddr_in *)&(al.addr.addr));
784 				(void) memcpy(p_term->at_addr, &al.addr.addr,
785 				    AU_IPv4);
786 				p_term->at_type = AU_IPv4;
787 				return (-1);
788 			}
789 		}
790 		if (family == AF_INET) {
791 			p_term->at_type = AU_IPv4;
792 			(void) memcpy(p_term->at_addr, &al.addr.addr, AU_IPv4);
793 		} else {
794 			p_term->at_type = AU_IPv6;
795 			(void) memcpy(p_term->at_addr, &al.addr.addr6, AU_IPv6);
796 		}
797 
798 		(void) snprintf(msg, sizeof (msg), "mapping %s to %s",
799 		    hostname, inet_ntop(family, &(al.addr), ntop,
800 		    sizeof (ntop)));
801 		adt_write_syslog(msg, 0);
802 		return (0);
803 	}
804 }
805 
806 /*
807  * adt_load_hostname() is called when the caller does not have a file
808  * handle that gives access to the socket info or any other way to
809  * pass in both port and ip address.  The hostname input is ignored if
810  * the terminal id has already been set; instead it returns the
811  * existing terminal id.
812  *
813  * If c2audit is excluded, success is returned.
814  * If the hostname lookup fails, the loopback address is assumed,
815  * errno is set to ENETDOWN, this allows the caller to interpret
816  * whether failure is fatal, and if not to have a address for the
817  * hostname.
818  * Otherwise the caller would need to be aware of the audit state.
819  *
820  * Other errors are ignored if not auditing.
821  */
822 
823 int
824 adt_load_hostname(const char *hostname, adt_termid_t **termid)
825 {
826 	char		localhost[MAXHOSTNAMELEN + 1];
827 	au_tid_addr_t	*p_term;
828 
829 	if (adt_audit_state(AUC_DISABLED)) {
830 		/* c2audit excluded */
831 		*termid = NULL;
832 		return (0);
833 	}
834 
835 	if ((p_term = calloc(1, sizeof (au_tid_addr_t))) == NULL) {
836 		goto return_err;
837 	}
838 
839 	if (adt_have_termid(p_term)) {
840 		*termid = (adt_termid_t *)p_term;
841 		return (0);
842 	}
843 	p_term->at_port = 0;
844 
845 	if (hostname == NULL || *hostname == '\0') {
846 		(void) sysinfo(SI_HOSTNAME, localhost, MAXHOSTNAMELEN);
847 		hostname = localhost;
848 	}
849 	if (adt_get_hostIP(hostname, p_term) == 0) {
850 		*termid = (adt_termid_t *)p_term;
851 		return (0);
852 	} else {
853 		*termid = (adt_termid_t *)p_term;
854 		return (-1);
855 	}
856 
857 return_err:
858 	*termid = NULL;
859 	if (auditstate & AUC_NOAUDIT) {
860 		return (0);
861 	}
862 
863 	return (-1);
864 }
865 
866 /*
867  * adt_load_ttyname() is called when the caller does not have a file
868  * handle that gives access to the local terminal or any other way
869  * of determining the device id.  The ttyname input is ignored if
870  * the terminal id has already been set; instead it returns the
871  * existing terminal id.
872  *
873  * If c2audit is excluded, success is returned.
874  * The local hostname is used for the local IP address.
875  * If that hostname lookup fails, the loopback address is assumed,
876  * errno is set to ENETDOWN, this allows the caller to interpret
877  * whether failure is fatal, and if not to have a address for the
878  * hostname.
879  * Otherwise the caller would need to be aware of the audit state.
880  *
881  * Other errors are ignored if not auditing.
882  */
883 
884 int
885 adt_load_ttyname(const char *ttyname, adt_termid_t **termid)
886 {
887 	char		localhost[MAXHOSTNAMELEN + 1];
888 	au_tid_addr_t	*p_term;
889 	struct stat	stat_buf;
890 
891 	if (adt_audit_state(AUC_DISABLED)) {
892 		/* c2audit excluded */
893 		*termid = NULL;
894 		return (0);
895 	}
896 
897 	if ((p_term = calloc(1, sizeof (au_tid_addr_t))) == NULL) {
898 		goto return_err;
899 	}
900 
901 	if (adt_have_termid(p_term)) {
902 		*termid = (adt_termid_t *)p_term;
903 		return (0);
904 	}
905 
906 	p_term->at_port = 0;
907 
908 	if (sysinfo(SI_HOSTNAME, localhost, MAXHOSTNAMELEN) < 0) {
909 		goto return_err_free; /* errno from sysinfo */
910 	}
911 
912 	if (ttyname != NULL && *ttyname != '\0') {
913 		if (stat(ttyname, &stat_buf) < 0) {
914 			goto return_err_free;
915 		}
916 
917 		p_term->at_port = stat_buf.st_rdev;
918 	}
919 
920 	if (adt_get_hostIP(localhost, p_term) == 0) {
921 		*termid = (adt_termid_t *)p_term;
922 		return (0);
923 	} else {
924 		*termid = (adt_termid_t *)p_term;
925 		return (-1);
926 	}
927 
928 return_err_free:
929 	free(p_term);
930 
931 return_err:
932 	*termid = NULL;
933 	if (auditstate & AUC_NOAUDIT) {
934 		return (0);
935 	}
936 
937 	return (-1);
938 }
939 
940 /*
941  * adt_get_session_id returns a stringified representation of
942  * the audit session id.  See also adt_get_asid() for how to
943  * get the unexpurgated version.  No guarantees as to how long
944  * the returned string will be or its general form; hex for now.
945  *
946  * An empty string is returned if auditing is off; length = 1
947  * and the pointer is valid.
948  *
949  * returns strlen + 1 if buffer is valid; else 0 and errno.
950  */
951 
952 size_t
953 adt_get_session_id(const adt_session_data_t *session_data, char **buff)
954 {
955 	au_asid_t	session_id;
956 	size_t		length;
957 	/*
958 	 * output is 0x followed by
959 	 * two characters per byte
960 	 * plus terminator,
961 	 * except leading 0's are suppressed, so a few bytes may
962 	 * be unused.
963 	 */
964 	length = 2 + (2 * sizeof (session_id)) + 1;
965 	*buff = malloc(length);
966 
967 	if (*buff == NULL) {
968 		return (0);
969 	}
970 	if (session_data == NULL) { /* NULL is not an error */
971 		**buff = '\0';
972 		return (1);
973 	}
974 	adt_get_asid(session_data, &session_id);
975 
976 	length = snprintf(*buff, length, "0x%X", (int)session_id);
977 
978 	/* length < 1 is a bug: the session data type may have changed */
979 	assert(length > 0);
980 
981 	return (length);
982 }
983 
984 /*
985  * adt_end_session -- close handle, clear context
986  *
987  * if as_check is invalid, no harm, no foul, EXCEPT that this could
988  * be an attempt to free data already free'd, so output to syslog
989  * to help explain why the process cored dumped.
990  */
991 
992 int
993 adt_end_session(adt_session_data_t *session_data)
994 {
995 	adt_internal_state_t	*state;
996 
997 	if (session_data != NULL) {
998 		state = (adt_internal_state_t *)session_data;
999 		if (state->as_check != ADT_VALID) {
1000 			adt_write_syslog("freeing invalid data", EINVAL);
1001 		} else {
1002 			state->as_check = 0;
1003 			m_label_free(state->as_label);
1004 			free(session_data);
1005 		}
1006 	}
1007 	/* no errors yet defined */
1008 	return (0);
1009 }
1010 
1011 /*
1012  * adt_dup_session -- copy the session data
1013  */
1014 
1015 int
1016 adt_dup_session(const adt_session_data_t *source, adt_session_data_t **dest)
1017 {
1018 	adt_internal_state_t	*source_state;
1019 	adt_internal_state_t	*dest_state = NULL;
1020 	int			rc = 0;
1021 
1022 	if (source != NULL) {
1023 		source_state = (adt_internal_state_t *)source;
1024 		assert(source_state->as_check == ADT_VALID);
1025 
1026 		dest_state = malloc(sizeof (adt_internal_state_t));
1027 		if (dest_state == NULL) {
1028 			rc = -1;
1029 			goto return_rc;
1030 		}
1031 		(void) memcpy(dest_state, source,
1032 		    sizeof (struct adt_internal_state));
1033 
1034 		if (source_state->as_label != NULL) {
1035 			dest_state->as_label = NULL;
1036 			if ((rc = m_label_dup(&dest_state->as_label,
1037 			    source_state->as_label)) != 0) {
1038 				free(dest_state);
1039 				dest_state = NULL;
1040 			}
1041 		}
1042 	}
1043 return_rc:
1044 	*dest = (adt_session_data_t *)dest_state;
1045 	return (rc);
1046 }
1047 
1048 /*
1049  * from_export_format()
1050  * read from a network order buffer into struct adt_session_data
1051  */
1052 
1053 static size_t
1054 adt_from_export_format(adt_internal_state_t *internal,
1055     const adt_export_data_t *external)
1056 {
1057 	struct export_header	head;
1058 	struct export_link	link;
1059 	adr_t			context;
1060 	int32_t 		offset;
1061 	int32_t 		length;
1062 	int32_t 		version;
1063 	size_t			label_len;
1064 	char			*p = (char *)external;
1065 
1066 	adrm_start(&context, (char *)external);
1067 	adrm_int32(&context, (int *)&head, 4);
1068 
1069 	if ((internal->as_check = head.ax_check) != ADT_VALID) {
1070 		errno = EINVAL;
1071 		return (0);
1072 	}
1073 	offset = head.ax_link.ax_offset;
1074 	version = head.ax_link.ax_version;
1075 	length = head.ax_buffer_length;
1076 
1077 	/*
1078 	 * Skip newer versions.
1079 	 */
1080 	while (version > PROTOCOL_VERSION_2) {
1081 		if (offset < 1) {
1082 			return (0);	/* failed to match version */
1083 		}
1084 		p += offset;		/* point to next version # */
1085 
1086 		if (p > (char *)external + length) {
1087 			return (0);
1088 		}
1089 		adrm_start(&context, p);
1090 		adrm_int32(&context, (int *)&link, 2);
1091 		offset = link.ax_offset;
1092 		version = link.ax_version;
1093 		assert(version != 0);
1094 	}
1095 	/*
1096 	 * Adjust buffer pointer to the first data item (euid).
1097 	 */
1098 	if (p == (char *)external) {
1099 		adrm_start(&context, (char *)(p + sizeof (head)));
1100 	} else {
1101 		adrm_start(&context, (char *)(p + sizeof (link)));
1102 	}
1103 	/*
1104 	 * if down rev version, neither pid nor label are included
1105 	 * in v1 ax_size_of_tsol_data intentionally ignored
1106 	 */
1107 	if (version == PROTOCOL_VERSION_1) {
1108 		adrm_int32(&context, (int *)&(internal->as_euid), 1);
1109 		adrm_int32(&context, (int *)&(internal->as_ruid), 1);
1110 		adrm_int32(&context, (int *)&(internal->as_egid), 1);
1111 		adrm_int32(&context, (int *)&(internal->as_rgid), 1);
1112 		adrm_int32(&context, (int *)&(internal->as_info.ai_auid), 1);
1113 		adrm_int32(&context,
1114 		    (int *)&(internal->as_info.ai_mask.am_success), 2);
1115 		adrm_int32(&context,
1116 		    (int *)&(internal->as_info.ai_termid.at_port), 1);
1117 		adrm_int32(&context,
1118 		    (int *)&(internal->as_info.ai_termid.at_type), 1);
1119 		adrm_int32(&context,
1120 		    (int *)&(internal->as_info.ai_termid.at_addr[0]), 4);
1121 		adrm_int32(&context, (int *)&(internal->as_info.ai_asid), 1);
1122 		adrm_int32(&context, (int *)&(internal->as_audit_state), 1);
1123 		internal->as_pid = (pid_t)-1;
1124 		internal->as_label = NULL;
1125 	} else if (version == PROTOCOL_VERSION_2) {
1126 		adrm_int32(&context, (int *)&(internal->as_euid), 1);
1127 		adrm_int32(&context, (int *)&(internal->as_ruid), 1);
1128 		adrm_int32(&context, (int *)&(internal->as_egid), 1);
1129 		adrm_int32(&context, (int *)&(internal->as_rgid), 1);
1130 		adrm_int32(&context, (int *)&(internal->as_info.ai_auid), 1);
1131 		adrm_int32(&context,
1132 		    (int *)&(internal->as_info.ai_mask.am_success), 2);
1133 		adrm_int32(&context,
1134 		    (int *)&(internal->as_info.ai_termid.at_port), 1);
1135 		adrm_int32(&context,
1136 		    (int *)&(internal->as_info.ai_termid.at_type), 1);
1137 		adrm_int32(&context,
1138 		    (int *)&(internal->as_info.ai_termid.at_addr[0]), 4);
1139 		adrm_int32(&context, (int *)&(internal->as_info.ai_asid), 1);
1140 		adrm_int32(&context, (int *)&(internal->as_audit_state), 1);
1141 		adrm_int32(&context, (int *)&(internal->as_pid), 1);
1142 		adrm_int32(&context, (int *)&label_len, 1);
1143 		if (label_len > 0) {
1144 			/* read in and deal with different sized labels. */
1145 			size32_t my_label_len = blabel_size();
1146 
1147 			if ((internal->as_label =
1148 			    m_label_alloc(MAC_LABEL)) == NULL) {
1149 				return (0);
1150 			}
1151 			if (label_len > my_label_len) {
1152 				errno = EINVAL;
1153 				m_label_free(internal->as_label);
1154 				return (0);
1155 			}
1156 			(void) memset(internal->as_label, 0, my_label_len);
1157 			adrm_int32(&context, (int *)(internal->as_label),
1158 			    label_len / sizeof (int32_t));
1159 		} else {
1160 			internal->as_label = NULL;
1161 		}
1162 	}
1163 
1164 	return (length);
1165 }
1166 
1167 /*
1168  * adt_to_export_format
1169  * read from struct adt_session_data into a network order buffer.
1170  *
1171  * (network order 'cause this data may be shared with a remote host.)
1172  */
1173 
1174 static size_t
1175 adt_to_export_format(adt_export_data_t *external,
1176     adt_internal_state_t *internal)
1177 {
1178 	struct export_header	head;
1179 	struct export_link	tail;
1180 	adr_t			context;
1181 	size32_t		label_len = 0;
1182 
1183 	adrm_start(&context, (char *)external);
1184 
1185 	if (internal->as_label != NULL) {
1186 		label_len = blabel_size();
1187 	}
1188 
1189 	head.ax_check = ADT_VALID;
1190 	head.ax_buffer_length = sizeof (struct adt_export_data) + label_len;
1191 
1192 	/* version 2 first */
1193 
1194 	head.ax_link.ax_version = PROTOCOL_VERSION_2;
1195 	head.ax_link.ax_offset = sizeof (struct export_header) +
1196 	    sizeof (struct adt_export_v2) + label_len;
1197 
1198 	adrm_putint32(&context, (int *)&head, 4);
1199 
1200 	adrm_putint32(&context, (int *)&(internal->as_euid), 1);
1201 	adrm_putint32(&context, (int *)&(internal->as_ruid), 1);
1202 	adrm_putint32(&context, (int *)&(internal->as_egid), 1);
1203 	adrm_putint32(&context, (int *)&(internal->as_rgid), 1);
1204 	adrm_putint32(&context, (int *)&(internal->as_info.ai_auid), 1);
1205 	adrm_putint32(&context,
1206 	    (int *)&(internal->as_info.ai_mask.am_success), 2);
1207 	adrm_putint32(&context,
1208 	    (int *)&(internal->as_info.ai_termid.at_port), 1);
1209 	adrm_putint32(&context,
1210 	    (int *)&(internal->as_info.ai_termid.at_type), 1);
1211 	adrm_putint32(&context,
1212 	    (int *)&(internal->as_info.ai_termid.at_addr[0]), 4);
1213 	adrm_putint32(&context, (int *)&(internal->as_info.ai_asid), 1);
1214 	adrm_putint32(&context, (int *)&(internal->as_audit_state), 1);
1215 	adrm_putint32(&context, (int *)&(internal->as_pid), 1);
1216 	adrm_putint32(&context, (int *)&label_len, 1);
1217 	if (internal->as_label != NULL) {
1218 		/* serialize the label */
1219 		adrm_putint32(&context, (int *)(internal->as_label),
1220 		    (label_len / sizeof (int32_t)));
1221 	}
1222 
1223 	/* now version 1 */
1224 
1225 	tail.ax_version = PROTOCOL_VERSION_1;
1226 	tail.ax_offset = 0;
1227 
1228 	adrm_putint32(&context, (int *)&tail, 2);
1229 
1230 	adrm_putint32(&context, (int *)&(internal->as_euid), 1);
1231 	adrm_putint32(&context, (int *)&(internal->as_ruid), 1);
1232 	adrm_putint32(&context, (int *)&(internal->as_egid), 1);
1233 	adrm_putint32(&context, (int *)&(internal->as_rgid), 1);
1234 	adrm_putint32(&context, (int *)&(internal->as_info.ai_auid), 1);
1235 	adrm_putint32(&context,
1236 	    (int *)&(internal->as_info.ai_mask.am_success), 2);
1237 	adrm_putint32(&context,
1238 	    (int *)&(internal->as_info.ai_termid.at_port), 1);
1239 	adrm_putint32(&context,
1240 	    (int *)&(internal->as_info.ai_termid.at_type), 1);
1241 	adrm_putint32(&context,
1242 	    (int *)&(internal->as_info.ai_termid.at_addr[0]), 4);
1243 	adrm_putint32(&context, (int *)&(internal->as_info.ai_asid), 1);
1244 	adrm_putint32(&context, (int *)&(internal->as_audit_state), 1);
1245 	/* ignored in v1 */
1246 	adrm_putint32(&context, (int *)&label_len, 1);
1247 
1248 	/* finally terminator */
1249 
1250 	tail.ax_version = 0; /* invalid version number */
1251 	tail.ax_offset = 0;
1252 
1253 	adrm_putint32(&context, (int *)&tail, 2);
1254 
1255 	return (head.ax_buffer_length);
1256 }
1257 
1258 /*
1259  * adt_ucred_label() -- if label is available, duplicate it.
1260  */
1261 
1262 static m_label_t *
1263 adt_ucred_label(ucred_t *uc)
1264 {
1265 	m_label_t	*ul = NULL;
1266 
1267 	if (ucred_getlabel(uc) != NULL) {
1268 		(void) m_label_dup(&ul, ucred_getlabel(uc));
1269 	}
1270 
1271 	return (ul);
1272 }
1273 
1274 /*
1275  * adt_import() -- convert from network order to machine-specific order
1276  */
1277 
1278 static int
1279 adt_import(adt_internal_state_t *internal, const adt_export_data_t *external)
1280 {
1281 	au_mask_t mask;
1282 
1283 	/* save local audit state */
1284 	int	local_audit_state = internal->as_audit_state;
1285 
1286 	if (adt_from_export_format(internal, external) < 1)
1287 		return (-1); /* errno from adt_from_export_format */
1288 
1289 	/*
1290 	 * If audit isn't enabled on the remote, they were unable
1291 	 * to generate the audit mask, so generate it based on
1292 	 * local configuration.  If the user id has changed, the
1293 	 * resulting mask may miss some subtleties that occurred
1294 	 * on the remote system.
1295 	 *
1296 	 * If the remote failed to generate a terminal id, it is not
1297 	 * recoverable.
1298 	 */
1299 
1300 	if (!(internal->as_audit_state & AUC_DISABLED)) {
1301 		if (adt_get_mask_from_user(internal->as_info.ai_auid,
1302 		    &(internal->as_info.ai_mask)))
1303 			return (-1);
1304 		if (internal->as_info.ai_auid != internal->as_ruid) {
1305 			if (adt_get_mask_from_user(internal->as_info.ai_auid,
1306 			    &mask))
1307 				return (-1);
1308 			internal->as_info.ai_mask.am_success |=
1309 			    mask.am_success;
1310 			internal->as_info.ai_mask.am_failure |=
1311 			    mask.am_failure;
1312 		}
1313 	}
1314 	internal->as_audit_state = local_audit_state;
1315 
1316 	DPRINTF(("(%lld)imported asid = %X %u\n", (long long) getpid(),
1317 	    internal->as_info.ai_asid,
1318 	    internal->as_info.ai_asid));
1319 
1320 	internal->as_have_user_data = ADT_HAVE_ALL;
1321 
1322 	return (0);
1323 }
1324 
1325 /*
1326  * adt_export_session_data()
1327  * copies a adt_session_data struct into a network order buffer
1328  *
1329  * In a misconfigured network, the local host may have auditing
1330  * off while the destination may have auditing on, so if there
1331  * is sufficient memory, a buffer will be returned even in the
1332  * audit off case.
1333  */
1334 
1335 size_t
1336 adt_export_session_data(const adt_session_data_t *internal,
1337     adt_export_data_t **external)
1338 {
1339 	size32_t		length = 0;
1340 
1341 	if ((internal != NULL) &&
1342 	    ((adt_internal_state_t *)internal)->as_label != NULL) {
1343 		length = blabel_size();
1344 	}
1345 
1346 	*external = malloc(sizeof (adt_export_data_t) + length);
1347 
1348 	if (*external == NULL)
1349 		return (0);
1350 
1351 	if (internal == NULL) {
1352 		adt_internal_state_t	*dummy;
1353 
1354 		dummy = malloc(sizeof (adt_internal_state_t));
1355 		if (dummy == NULL)
1356 			goto return_length_free;
1357 
1358 		if (adt_init(dummy, 0)) { /* 0 == don't copy from proc */
1359 			free(dummy);
1360 			goto return_length_free;
1361 		}
1362 		length = adt_to_export_format(*external, dummy);
1363 		free(dummy);
1364 	} else {
1365 		length = adt_to_export_format(*external,
1366 		    (adt_internal_state_t *)internal);
1367 	}
1368 	return (length);
1369 
1370 return_length_free:
1371 	free(*external);
1372 	*external = NULL;
1373 	return (0);
1374 }
1375 
1376 static void
1377 adt_setto_unaudited(adt_internal_state_t *state)
1378 {
1379 	if (state->as_audit_state & AUC_DISABLED) {
1380 		state->as_ruid = AU_NOAUDITID;
1381 		state->as_euid = AU_NOAUDITID;
1382 		state->as_rgid = AU_NOAUDITID;
1383 		state->as_egid = AU_NOAUDITID;
1384 		state->as_pid = (pid_t)-1;
1385 		state->as_label = NULL;
1386 	} else {
1387 		state->as_info.ai_asid = 0;
1388 		state->as_info.ai_auid = AU_NOAUDITID;
1389 
1390 		(void) memset((void *)&(state->as_info.ai_termid), 0,
1391 		    sizeof (au_tid_addr_t));
1392 		state->as_info.ai_termid.at_type = AU_IPv4;
1393 
1394 		(void) memset((void *)&(state->as_info.ai_mask), 0,
1395 		    sizeof (au_mask_t));
1396 		state->as_have_user_data = 0;
1397 	}
1398 }
1399 
1400 /*
1401  * adt_init -- set session context by copying the audit characteristics
1402  * from the proc and picking up current uid/tid information.
1403  *
1404  * By default, an audit session is based on the process; the default
1405  * is overriden by adt_set_user()
1406  */
1407 
1408 static int
1409 adt_init(adt_internal_state_t *state, int use_proc_data)
1410 {
1411 	/* ensure auditstate is set */
1412 
1413 	(void) adt_audit_state(0);
1414 	state->as_audit_state = auditstate;
1415 
1416 	if (use_proc_data) {
1417 		state->as_ruid = getuid();
1418 		state->as_euid = geteuid();
1419 		state->as_rgid = getgid();
1420 		state->as_egid = getegid();
1421 		state->as_pid = getpid();
1422 
1423 		if (!(state->as_audit_state & AUC_DISABLED)) {
1424 			const au_tid64_addr_t	*tid;
1425 			const au_mask_t		*mask;
1426 			ucred_t			*ucred = ucred_get(P_MYID);
1427 
1428 			/*
1429 			 * Even if the ucred is NULL, the underlying
1430 			 * credential may have a valid terminal id; if the
1431 			 * terminal id is set, then that's good enough.  An
1432 			 * example of where this matters is failed login,
1433 			 * where rlogin/telnet sets the terminal id before
1434 			 * calling login; login does not load the credential
1435 			 * since auth failed.
1436 			 */
1437 			if (ucred == NULL) {
1438 				if (!adt_have_termid(
1439 				    &(state->as_info.ai_termid)))
1440 					return (-1);
1441 			} else {
1442 				mask = ucred_getamask(ucred);
1443 				if (mask != NULL) {
1444 					state->as_info.ai_mask = *mask;
1445 				} else {
1446 					ucred_free(ucred);
1447 					return (-1);
1448 				}
1449 				tid = ucred_getatid(ucred);
1450 				if (tid != NULL) {
1451 					adt_cpy_tid(&(state->as_info.ai_termid),
1452 					    tid);
1453 				} else {
1454 					ucred_free(ucred);
1455 					return (-1);
1456 				}
1457 				state->as_info.ai_asid = ucred_getasid(ucred);
1458 				state->as_info.ai_auid = ucred_getauid(ucred);
1459 				state->as_label = adt_ucred_label(ucred);
1460 				ucred_free(ucred);
1461 			}
1462 			state->as_have_user_data = ADT_HAVE_ALL;
1463 		}
1464 	} else {
1465 		adt_setto_unaudited(state);
1466 	}
1467 	state->as_session_model = ADT_SESSION_MODEL;	/* default */
1468 
1469 	if ((state->as_audit_state & (AUC_AUDITING | AUC_NOSPACE)) &&
1470 	    auditon(A_GETPOLICY, (caddr_t)&(state->as_kernel_audit_policy),
1471 	    sizeof (state->as_kernel_audit_policy))) {
1472 		return (-1);  /* errno set by auditon */
1473 	}
1474 	state->as_check = ADT_VALID;
1475 	adt_load_table((adt_session_data_t *)state, &adt_xlate_table[0],
1476 	    &adt_preload);
1477 	return (0);
1478 }
1479 
1480 /*
1481  * adt_set_proc
1482  *
1483  * Copy the current session state to the process.  If this function
1484  * is called, the model becomes a process model rather than a
1485  * session model.
1486  *
1487  * In the current implementation, the value state->as_have_user_data
1488  * must contain all of: ADT_HAVE_{AUID,MASK,TID,ASID}.  These are all set
1489  * by adt_set_user() when the ADT_SETTID or ADT_NEW flag is passed in.
1490  *
1491  */
1492 
1493 int
1494 adt_set_proc(const adt_session_data_t *session_data)
1495 {
1496 	adt_internal_state_t	*state;
1497 
1498 	if (session_data == NULL) {
1499 		return (0);
1500 	}
1501 
1502 	state = (adt_internal_state_t *)session_data;
1503 
1504 	assert(state->as_check == ADT_VALID);
1505 
1506 	if ((state->as_have_user_data & (ADT_HAVE_ALL & ~ADT_HAVE_IDS)) !=
1507 	    (ADT_HAVE_ALL & ~ADT_HAVE_IDS)) {
1508 		errno = EINVAL;
1509 		goto return_err;
1510 	}
1511 
1512 	if (setaudit_addr((auditinfo_addr_t *)&(state->as_info),
1513 	    sizeof (auditinfo_addr_t)) < 0) {
1514 		goto return_err;	/* errno set by setaudit_addr() */
1515 	}
1516 
1517 	state->as_session_model = ADT_PROCESS_MODEL;
1518 
1519 	return (0);
1520 
1521 return_err:
1522 	adt_write_syslog("failed to set process audit characteristics", errno);
1523 	return (-1);
1524 }
1525 
1526 static int
1527 adt_newuser(adt_internal_state_t *state, uid_t ruid, au_tid_addr_t *termid)
1528 {
1529 	au_tid_addr_t	no_tid = {0, AU_IPv4, 0, 0, 0, 0};
1530 	au_mask_t	no_mask = {0, 0};
1531 
1532 	if (ruid == ADT_NO_AUDIT) {
1533 		state->as_info.ai_auid = AU_NOAUDITID;
1534 		state->as_info.ai_asid = 0;
1535 		state->as_info.ai_termid = no_tid;
1536 		state->as_info.ai_mask = no_mask;
1537 		return (0);
1538 	}
1539 	state->as_info.ai_auid = ruid;
1540 	state->as_info.ai_asid = adt_get_unique_id(ruid);
1541 	if (termid != NULL)
1542 		state->as_info.ai_termid = *termid;
1543 
1544 	if (adt_get_mask_from_user(ruid, &(state->as_info.ai_mask)))
1545 		return (-1);
1546 
1547 	/* Assume intending to audit as this process */
1548 
1549 	if (state->as_pid == (pid_t)-1)
1550 		state->as_pid = getpid();
1551 
1552 	if (is_system_labeled() && state->as_label == NULL) {
1553 		ucred_t	*ucred = ucred_get(P_MYID);
1554 
1555 		state->as_label = adt_ucred_label(ucred);
1556 		ucred_free(ucred);
1557 	}
1558 
1559 	return (0);
1560 }
1561 
1562 static int
1563 adt_changeuser(adt_internal_state_t *state, uid_t ruid)
1564 {
1565 	au_mask_t		mask;
1566 
1567 	if (!(state->as_have_user_data & ADT_HAVE_AUID))
1568 		state->as_info.ai_auid = ruid;
1569 	if (!(state->as_have_user_data & ADT_HAVE_ASID))
1570 		state->as_info.ai_asid = adt_get_unique_id(ruid);
1571 
1572 	if (ruid <= MAXEPHUID) {
1573 		if (adt_get_mask_from_user(ruid, &mask))
1574 			return (-1);
1575 
1576 		state->as_info.ai_mask.am_success |= mask.am_success;
1577 		state->as_info.ai_mask.am_failure |= mask.am_failure;
1578 	}
1579 	DPRINTF(("changed mask to %08X/%08X for ruid=%d\n",
1580 	    state->as_info.ai_mask.am_success,
1581 	    state->as_info.ai_mask.am_failure,
1582 	    ruid));
1583 	return (0);
1584 }
1585 
1586 /*
1587  * adt_set_user -- see also adt_set_from_ucred()
1588  *
1589  * ADT_NO_ATTRIB is a valid uid/gid meaning "not known" or
1590  * "unattributed."  If ruid, change the model to session.
1591  *
1592  * ADT_NO_CHANGE is a valid uid/gid meaning "do not change this value"
1593  * only valid with ADT_UPDATE.
1594  *
1595  * ADT_NO_AUDIT is the external equivalent to AU_NOAUDITID -- there
1596  * isn't a good reason to call adt_set_user() with it unless you don't
1597  * have a good value yet and intend to replace it later; auid will be
1598  * AU_NOAUDITID.
1599  *
1600  * adt_set_user should be called even if auditing is not enabled
1601  * so that adt_export_session_data() will have useful stuff to
1602  * work with.
1603  *
1604  * See the note preceding adt_set_proc() about the use of ADT_HAVE_TID
1605  * and ADT_HAVE_ALL.
1606  */
1607 
1608 int
1609 adt_set_user(const adt_session_data_t *session_data, uid_t euid, gid_t egid,
1610     uid_t ruid, gid_t rgid, const adt_termid_t *termid,
1611     enum adt_user_context user_context)
1612 {
1613 	adt_internal_state_t	*state;
1614 	int			rc;
1615 
1616 	if (session_data == NULL) /* no session exists to audit */
1617 		return (0);
1618 
1619 	state = (adt_internal_state_t *)session_data;
1620 	assert(state->as_check == ADT_VALID);
1621 
1622 	switch (user_context) {
1623 	case ADT_NEW:
1624 		if (ruid == ADT_NO_CHANGE || euid == ADT_NO_CHANGE ||
1625 		    rgid == ADT_NO_CHANGE || egid == ADT_NO_CHANGE) {
1626 			errno = EINVAL;
1627 			return (-1);
1628 		}
1629 		if ((rc = adt_newuser(state, ruid,
1630 		    (au_tid_addr_t *)termid)) != 0)
1631 			return (rc);
1632 
1633 		state->as_have_user_data = ADT_HAVE_ALL;
1634 		break;
1635 	case ADT_UPDATE:
1636 		if (state->as_have_user_data != ADT_HAVE_ALL) {
1637 			errno = EINVAL;
1638 			return (-1);
1639 		}
1640 
1641 		if (ruid != ADT_NO_CHANGE)
1642 			if ((rc = adt_changeuser(state, ruid)) != 0)
1643 				return (rc);
1644 		break;
1645 	case ADT_USER:
1646 		if (state->as_have_user_data != ADT_HAVE_ALL) {
1647 			errno = EINVAL;
1648 			return (-1);
1649 		}
1650 		break;
1651 	case ADT_SETTID:
1652 		assert(termid != NULL);
1653 		state->as_info.ai_termid = *((au_tid_addr_t *)termid);
1654 		/* avoid fooling pam_setcred()... */
1655 		state->as_info.ai_auid = AU_NOAUDITID;
1656 		state->as_info.ai_asid = 0;
1657 		state->as_info.ai_mask.am_failure = 0;
1658 		state->as_info.ai_mask.am_success = 0;
1659 		state->as_have_user_data = ADT_HAVE_TID |
1660 		    ADT_HAVE_AUID | ADT_HAVE_ASID | ADT_HAVE_MASK;
1661 		return (0);
1662 	default:
1663 		errno = EINVAL;
1664 		return (-1);
1665 	}
1666 
1667 	if (ruid == ADT_NO_AUDIT) {
1668 		state->as_ruid = AU_NOAUDITID;
1669 		state->as_euid = AU_NOAUDITID;
1670 		state->as_rgid = AU_NOAUDITID;
1671 		state->as_egid = AU_NOAUDITID;
1672 	} else {
1673 		if (ruid != ADT_NO_CHANGE)
1674 			state->as_ruid = ruid;
1675 		if (euid != ADT_NO_CHANGE)
1676 			state->as_euid = euid;
1677 		if (rgid != ADT_NO_CHANGE)
1678 			state->as_rgid = rgid;
1679 		if (egid != ADT_NO_CHANGE)
1680 			state->as_egid = egid;
1681 	}
1682 
1683 	if (ruid == ADT_NO_ATTRIB) {
1684 		state->as_session_model = ADT_SESSION_MODEL;
1685 	}
1686 
1687 	return (0);
1688 }
1689 
1690 /*
1691  * adt_set_from_ucred()
1692  *
1693  * an alternate to adt_set_user that fills the same role but uses
1694  * a pointer to a ucred rather than a list of id's.  If the ucred
1695  * pointer is NULL, use the credential from the this process.
1696  *
1697  * A key difference is that for ADT_NEW, adt_set_from_ucred() does
1698  * not overwrite the asid and auid unless auid has not been set.
1699  * ADT_NEW differs from ADT_UPDATE in that it does not OR together
1700  * the incoming audit mask with the one that already exists.
1701  *
1702  * adt_set_from_ucred should be called even if auditing is not enabled
1703  * so that adt_export_session_data() will have useful stuff to
1704  * work with.
1705  */
1706 
1707 int
1708 adt_set_from_ucred(const adt_session_data_t *session_data, const ucred_t *uc,
1709     enum adt_user_context user_context)
1710 {
1711 	adt_internal_state_t	*state;
1712 	int			rc = -1;
1713 	const au_tid64_addr_t		*tid64;
1714 	au_tid_addr_t		termid, *tid;
1715 	ucred_t	*ucred = (ucred_t *)uc;
1716 	boolean_t	local_uc = B_FALSE;
1717 
1718 	if (session_data == NULL) /* no session exists to audit */
1719 		return (0);
1720 
1721 	state = (adt_internal_state_t *)session_data;
1722 	assert(state->as_check == ADT_VALID);
1723 
1724 	if (ucred == NULL) {
1725 		ucred = ucred_get(P_MYID);
1726 
1727 		if (ucred == NULL)
1728 			goto return_rc;
1729 		local_uc = B_TRUE;
1730 	}
1731 
1732 	switch (user_context) {
1733 	case ADT_NEW:
1734 		tid64 = ucred_getatid(ucred);
1735 		if (tid64 != NULL) {
1736 			adt_cpy_tid(&termid, tid64);
1737 			tid = &termid;
1738 		} else {
1739 			tid = NULL;
1740 		}
1741 		if (ucred_getauid(ucred) == AU_NOAUDITID) {
1742 			adt_setto_unaudited(state);
1743 			state->as_have_user_data = ADT_HAVE_ALL;
1744 			rc = 0;
1745 			goto return_rc;
1746 		} else {
1747 			state->as_info.ai_auid = ucred_getauid(ucred);
1748 			state->as_info.ai_asid = ucred_getasid(ucred);
1749 			state->as_info.ai_mask = *ucred_getamask(ucred);
1750 			state->as_info.ai_termid = *tid;
1751 		}
1752 		state->as_have_user_data = ADT_HAVE_ALL;
1753 		break;
1754 	case ADT_UPDATE:
1755 		if (state->as_have_user_data != ADT_HAVE_ALL) {
1756 			errno = EINVAL;
1757 			goto return_rc;
1758 		}
1759 
1760 		if ((rc = adt_changeuser(state, ucred_getruid(ucred))) != 0)
1761 			goto return_rc;
1762 		break;
1763 	case ADT_USER:
1764 		if (state->as_have_user_data != ADT_HAVE_ALL) {
1765 			errno = EINVAL;
1766 			goto return_rc;
1767 		}
1768 		break;
1769 	default:
1770 		errno = EINVAL;
1771 		goto return_rc;
1772 	}
1773 	rc = 0;
1774 
1775 	state->as_ruid = ucred_getruid(ucred);
1776 	state->as_euid = ucred_geteuid(ucred);
1777 	state->as_rgid = ucred_getrgid(ucred);
1778 	state->as_egid = ucred_getegid(ucred);
1779 	state->as_pid = ucred_getpid(ucred);
1780 	state->as_label = adt_ucred_label(ucred);
1781 
1782 return_rc:
1783 	if (local_uc) {
1784 		ucred_free(ucred);
1785 	}
1786 	return (rc);
1787 }
1788 
1789 /*
1790  * adt_alloc_event() returns a pointer to allocated memory
1791  *
1792  */
1793 
1794 adt_event_data_t
1795 *adt_alloc_event(const adt_session_data_t *session_data, au_event_t event_id)
1796 {
1797 	struct adt_event_state	*event_state;
1798 	adt_internal_state_t	*session_state;
1799 	adt_event_data_t	*return_event = NULL;
1800 	/*
1801 	 * need to return a valid event pointer even if audit is
1802 	 * off, else the caller will end up either (1) keeping its
1803 	 * own flags for on/off or (2) writing to a NULL pointer.
1804 	 * If auditing is on, the session data must be valid; otherwise
1805 	 * we don't care.
1806 	 */
1807 	if (session_data != NULL) {
1808 		session_state = (adt_internal_state_t *)session_data;
1809 		assert(session_state->as_check == ADT_VALID);
1810 	}
1811 	event_state = calloc(1, sizeof (struct adt_event_state));
1812 	if (event_state == NULL)
1813 		goto return_ptr;
1814 
1815 	event_state->ae_check = ADT_VALID;
1816 
1817 	event_state->ae_event_id = event_id;
1818 	event_state->ae_session = (struct adt_internal_state *)session_data;
1819 
1820 	return_event = (adt_event_data_t *)&(event_state->ae_event_data);
1821 
1822 	/*
1823 	 * preload data so the adt_au_*() functions can detect un-supplied
1824 	 * values (0 and NULL are free via calloc()).
1825 	 */
1826 	if (session_data != NULL) {
1827 		session_state->as_preload(event_id, return_event);
1828 	}
1829 
1830 return_ptr:
1831 	return (return_event);
1832 }
1833 
1834 /*
1835  * adt_getXlateTable -- look up translation table address for event id
1836  */
1837 
1838 static adt_translation_t *
1839 adt_getXlateTable(adt_translation_t **xlate, au_event_t event_id)
1840 {
1841 	/* xlate_table is global in adt_xlate.c */
1842 	adt_translation_t	**p_xlate = xlate;
1843 	adt_translation_t	*p_event;
1844 
1845 	while (*p_xlate != NULL) {
1846 		p_event = *p_xlate;
1847 		if (event_id == p_event->tx_external_event)
1848 			return (p_event);
1849 		p_xlate++;
1850 	}
1851 	return (NULL);
1852 }
1853 
1854 /*
1855  * adt_calcOffsets
1856  *
1857  * the call to this function is surrounded by a mutex.
1858  *
1859  * i walks down the table picking up next_token.  j walks again to
1860  * calculate the offset to the input data.  k points to the next
1861  * token's row.  Finally, l, is used to sum the values in the
1862  * datadef array.
1863  *
1864  * What's going on?  The entry array is in the order of the input
1865  * fields but the processing of array entries is in the order of
1866  * the output (see next_token).  Calculating the offset to the
1867  * "next" input can't be done in the outer loop (i) since i doesn't
1868  * point to the current entry and it can't be done with the k index
1869  * because it doesn't represent the order of input fields.
1870  *
1871  * While the resulting algorithm is n**2, it is only done once per
1872  * event type.
1873  */
1874 
1875 /*
1876  * adt_calcOffsets is only called once per event type, but it uses
1877  * the address alignment of memory allocated for that event as if it
1878  * were the same for all subsequently allocated memory.  This is
1879  * guaranteed by calloc/malloc.  Arrays take special handling since
1880  * what matters for figuring out the correct alignment is the size
1881  * of the array element.
1882  */
1883 
1884 static void
1885 adt_calcOffsets(struct entry *p_entry, int tablesize, void *p_data)
1886 {
1887 	int		i, j;
1888 	size_t		this_size, prev_size;
1889 	void		*struct_start = p_data;
1890 
1891 	for (i = 0; i < tablesize; i++) {
1892 		if (p_entry[i].en_type_def == NULL) {
1893 			p_entry[i].en_offset = 0;
1894 			continue;
1895 		}
1896 		prev_size = 0;
1897 		p_entry[i].en_offset = (char *)p_data - (char *)struct_start;
1898 
1899 		for (j = 0; j < p_entry[i].en_count_types; j++) {
1900 			if (p_entry[i].en_type_def[j].dd_datatype == ADT_MSG)
1901 				this_size = sizeof (enum adt_generic);
1902 			else
1903 				this_size =
1904 				    p_entry[i].en_type_def[j].dd_input_size;
1905 
1906 			/* adj for first entry */
1907 			if (prev_size == 0)
1908 				prev_size = this_size;
1909 
1910 			if (p_entry[i].en_type_def[j].dd_datatype ==
1911 			    ADT_UINT32ARRAY) {
1912 				p_data = (char *)adt_adjust_address(p_data,
1913 				    prev_size, sizeof (uint32_t)) +
1914 				    this_size - sizeof (uint32_t);
1915 
1916 				prev_size = sizeof (uint32_t);
1917 			} else {
1918 				p_data = adt_adjust_address(p_data, prev_size,
1919 				    this_size);
1920 				prev_size = this_size;
1921 			}
1922 		}
1923 	}
1924 }
1925 
1926 /*
1927  * adt_generate_event
1928  * generate event record from external struct.  The order is based on
1929  * the output tokens, allowing for the possibility that the input data
1930  * is in a different order.
1931  *
1932  */
1933 
1934 static int
1935 adt_generate_event(const adt_event_data_t *p_extdata,
1936     struct adt_event_state *p_event,
1937     adt_translation_t *p_xlate)
1938 {
1939 	struct entry		*p_entry;
1940 	static mutex_t	lock = DEFAULTMUTEX;
1941 
1942 	p_entry = p_xlate->tx_first_entry;
1943 	assert(p_entry != NULL);
1944 
1945 	p_event->ae_internal_id = p_xlate->tx_internal_event;
1946 	adt_token_open(p_event);
1947 
1948 	/*
1949 	 * offsets are not pre-calculated; the initial offsets are all
1950 	 * 0; valid offsets are >= 0.  Offsets for no-input tokens such
1951 	 * as subject are set to -1 by adt_calcOffset()
1952 	 */
1953 	if (p_xlate->tx_offsetsCalculated == 0) {
1954 		(void) mutex_lock(&lock);
1955 		p_xlate->tx_offsetsCalculated = 1;
1956 
1957 		adt_calcOffsets(p_xlate->tx_top_entry, p_xlate->tx_entries,
1958 		    (void *)p_extdata);
1959 		(void) mutex_unlock(&lock);
1960 	}
1961 	while (p_entry != NULL) {
1962 		adt_generate_token(p_entry, (char *)p_extdata, p_event);
1963 
1964 		p_entry = p_entry->en_next_token;
1965 	}
1966 	return (adt_token_close(p_event));
1967 }
1968 
1969 /*
1970  * adt_put_event -- main event generation function.
1971  * The input "event" is the address of the struct containing
1972  * event-specific data.
1973  *
1974  * However if auditing is off or the session handle
1975  * is NULL, no attempt to write a record is made.
1976  */
1977 
1978 int
1979 adt_put_event(const adt_event_data_t *event, int status, int return_val)
1980 {
1981 	struct adt_event_state	*event_state;
1982 	adt_translation_t	*xlate;
1983 
1984 	if (event == NULL) {
1985 		errno = EINVAL;
1986 		return (-1);
1987 	}
1988 	event_state = (struct adt_event_state *)event;
1989 
1990 	/* if this is a broken session or not auditing, exit */
1991 	if ((event_state->ae_session == NULL) ||
1992 	    !(event_state->ae_session->as_audit_state &
1993 	    (AUC_AUDITING | AUC_NOSPACE))) {
1994 		return (0);
1995 	}
1996 
1997 	assert(event_state->ae_check == ADT_VALID);
1998 
1999 	event_state->ae_rc = status;
2000 	event_state->ae_type = return_val;
2001 
2002 	/* look up the event */
2003 
2004 	xlate = adt_getXlateTable(event_state->ae_session->as_xlate,
2005 	    event_state->ae_event_id);
2006 
2007 	if (xlate == NULL) {
2008 		errno = EINVAL;
2009 		return (-1);
2010 	}
2011 	DPRINTF(("got event %d\n", xlate->tx_internal_event));
2012 
2013 	if (adt_selected(event_state, xlate->tx_internal_event, status)) {
2014 		return (adt_generate_event(event, event_state, xlate));
2015 	}
2016 
2017 	return (0);
2018 }
2019 
2020 /*
2021  * adt_free_event -- invalidate and free
2022  */
2023 
2024 void
2025 adt_free_event(adt_event_data_t *event)
2026 {
2027 	struct adt_event_state	*event_state;
2028 
2029 	if (event == NULL)
2030 		return;
2031 
2032 	event_state = (struct adt_event_state *)event;
2033 
2034 	assert(event_state->ae_check == ADT_VALID);
2035 
2036 	event_state->ae_check = 0;
2037 
2038 	free(event_state);
2039 }
2040 
2041 /*
2042  * adt_is_selected -- helper to adt_selected(), below.
2043  *
2044  * "sorf" is "success or fail" status; au_preselect compares
2045  * that with success, fail, or both.
2046  */
2047 
2048 static int
2049 adt_is_selected(au_event_t e, au_mask_t *m, int sorf)
2050 {
2051 	int prs_sorf;
2052 
2053 	if (sorf == 0)
2054 		prs_sorf = AU_PRS_SUCCESS;
2055 	else
2056 		prs_sorf = AU_PRS_FAILURE;
2057 
2058 	return (au_preselect(e, m, prs_sorf, AU_PRS_REREAD));
2059 }
2060 
2061 /*
2062  * selected -- see if this event is preselected.
2063  *
2064  * if errors are encountered trying to check a preselection mask
2065  * or look up a user name, the event is selected.  Otherwise, the
2066  * preselection mask is used for the job.
2067  */
2068 
2069 static int
2070 adt_selected(struct adt_event_state *event, au_event_t actual_id, int status)
2071 {
2072 	adt_internal_state_t *sp;
2073 	au_mask_t	namask;
2074 
2075 	sp = event->ae_session;
2076 
2077 	if ((sp->as_have_user_data & ADT_HAVE_IDS) == 0) {
2078 		adt_write_syslog("No user data available", EINVAL);
2079 		return (1);	/* default is "selected" */
2080 	}
2081 
2082 	/* non-attributable? */
2083 	if ((sp->as_info.ai_auid == AU_NOAUDITID) ||
2084 	    (sp->as_info.ai_auid == ADT_NO_AUDIT)) {
2085 		if (auditon(A_GETKMASK, (caddr_t)&namask,
2086 		    sizeof (namask)) != 0) {
2087 			adt_write_syslog("auditon failure", errno);
2088 			return (1);
2089 		}
2090 		return (adt_is_selected(actual_id, &namask, status));
2091 	} else {
2092 		return (adt_is_selected(actual_id, &(sp->as_info.ai_mask),
2093 		    status));
2094 	}
2095 }
2096 
2097 /*
2098  * Can't map the host name to an IP address in
2099  * adt_get_hostIP.  Get something off an interface
2100  * to act as the hosts IP address for auditing.
2101  */
2102 
2103 static int
2104 adt_get_local_address(int family, struct ifaddrlist *al)
2105 {
2106 	struct ifaddrlist	*ifal;
2107 	char	errbuf[ERRBUFSIZE] = "empty list";
2108 	char	msg[ERRBUFSIZE + 512];
2109 	int	ifal_count;
2110 	int	i;
2111 
2112 	if ((ifal_count = ifaddrlist(&ifal, family, 0, errbuf)) <= 0) {
2113 		int serrno = errno;
2114 
2115 		(void) snprintf(msg, sizeof (msg), "adt_get_local_address "
2116 		    "couldn't get %d addrlist %s", family, errbuf);
2117 		adt_write_syslog(msg, serrno);
2118 		errno = serrno;
2119 		return (-1);
2120 	}
2121 
2122 	for (i = 0; i < ifal_count; i++) {
2123 		/*
2124 		 * loopback always defined,
2125 		 * even if there is no real address
2126 		 */
2127 		if ((ifal[i].flags & (IFF_UP | IFF_LOOPBACK)) == IFF_UP) {
2128 			break;
2129 		}
2130 	}
2131 	if (i >= ifal_count) {
2132 		free(ifal);
2133 		/*
2134 		 * Callers of adt_get_hostIP() can only return
2135 		 * errno to their callers and eventually the application.
2136 		 * Picked one that seemed least worse for saying no
2137 		 * usable address for Audit terminal ID.
2138 		 */
2139 		errno = ENETDOWN;
2140 		return (-1);
2141 	}
2142 
2143 	*al = ifal[i];
2144 	free(ifal);
2145 	return (0);
2146 }
2147