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