xref: /onnv-gate/usr/src/lib/libbsm/common/adt_token.c (revision 11893:ff6e80260186)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
51676Sjpk  * Common Development and Distribution License (the "License").
61676Sjpk  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
210Sstevel@tonic-gate /*
220Sstevel@tonic-gate  * adt_token.c
230Sstevel@tonic-gate  *
2411706SJan.Friedel@Sun.COM  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
250Sstevel@tonic-gate  * Use is subject to license terms.
260Sstevel@tonic-gate  *
270Sstevel@tonic-gate  * This file does not provide any user callable functions.  See adt.c
280Sstevel@tonic-gate  */
290Sstevel@tonic-gate 
300Sstevel@tonic-gate #include <bsm/adt.h>
310Sstevel@tonic-gate #include <bsm/adt_event.h>
320Sstevel@tonic-gate #include <bsm/audit.h>
335537Sgww 
340Sstevel@tonic-gate #include <adt_xlate.h>
3511134SCasper.Dik@Sun.COM #include <alloca.h>
360Sstevel@tonic-gate #include <assert.h>
370Sstevel@tonic-gate #include <netdb.h>
380Sstevel@tonic-gate #include <priv.h>
390Sstevel@tonic-gate #include <string.h>
400Sstevel@tonic-gate #include <strings.h>
413222Sgww #include <stdlib.h>
425537Sgww #include <time.h>
435537Sgww #include <unistd.h>
445537Sgww 
450Sstevel@tonic-gate #include <sys/priv_names.h>
465537Sgww #include <sys/socket.h>
470Sstevel@tonic-gate #include <sys/types.h>
480Sstevel@tonic-gate #include <sys/vnode.h>
495537Sgww 
501676Sjpk #include <tsol/label.h>
510Sstevel@tonic-gate 
523222Sgww #ifdef	C2_DEBUG
5311706SJan.Friedel@Sun.COM #define	DPRINTF(x) { (void) printf x; }
5411706SJan.Friedel@Sun.COM #define	DFLUSH (void) fflush(stdout);
553222Sgww 
563222Sgww /* 0x + Classification + Compartments + end of string */
573222Sgww #define	HEX_SIZE 2 + 2*2 + 2*32 + 1
583222Sgww 
593222Sgww static char *
dprt_label(m_label_t * label)603222Sgww dprt_label(m_label_t *label)
613222Sgww {
623222Sgww 	static char	hex[HEX_SIZE];
633222Sgww 	char		*direct = NULL;
643222Sgww 
653222Sgww 	if (label_to_str(label, &direct, M_INTERNAL, DEF_NAMES) != 0) {
663222Sgww 		adt_write_syslog("label_to_str(M_INTERNAL)", errno);
673222Sgww 		return ("hex label failed");
683222Sgww 	}
693222Sgww 	(void) strlcpy(hex, direct, sizeof (hex));
703222Sgww 	free(direct);
713222Sgww 	return (hex);
723222Sgww }
733222Sgww #else	/* !C2_DEBUG */
740Sstevel@tonic-gate #define	DPRINTF(x)
750Sstevel@tonic-gate #define	DFLUSH
763222Sgww #endif	/* C2_DEBUG */
770Sstevel@tonic-gate 
780Sstevel@tonic-gate static adt_token_func_t adt_getTokenFunction(char);
790Sstevel@tonic-gate 
800Sstevel@tonic-gate static char	*empty = "";
810Sstevel@tonic-gate 
820Sstevel@tonic-gate /*
830Sstevel@tonic-gate  * call adt_token_open() first and adt_token_close() last.
840Sstevel@tonic-gate  *
850Sstevel@tonic-gate  * au_open is sort of broken; it returns a -1 when out of memory that
860Sstevel@tonic-gate  * you're supposed to ignore; au_write and au_close return without
870Sstevel@tonic-gate  * doing anything when a -1 is passed.  This code sort of follows the
880Sstevel@tonic-gate  * au_open model except that it calls syslog to indicate underlying
890Sstevel@tonic-gate  * brokenness.  Other than that, -1 is ignored.
900Sstevel@tonic-gate  */
910Sstevel@tonic-gate 
920Sstevel@tonic-gate void
adt_token_open(struct adt_event_state * event)930Sstevel@tonic-gate adt_token_open(struct adt_event_state *event)
940Sstevel@tonic-gate {
950Sstevel@tonic-gate 	static int	have_syslogged = 0;
960Sstevel@tonic-gate 
970Sstevel@tonic-gate 	event->ae_event_handle = au_open();
980Sstevel@tonic-gate 	if (event->ae_event_handle < 0) {
990Sstevel@tonic-gate 		if (!have_syslogged) {
1000Sstevel@tonic-gate 			adt_write_syslog("au_open failed", ENOMEM);
1010Sstevel@tonic-gate 			have_syslogged = 1;
1020Sstevel@tonic-gate 		}
1035537Sgww 	} else {
1045537Sgww 		have_syslogged = 0;
1050Sstevel@tonic-gate 	}
1060Sstevel@tonic-gate }
1070Sstevel@tonic-gate 
1080Sstevel@tonic-gate /*
1090Sstevel@tonic-gate  * call generate_token for each token in the order you want the tokens
1100Sstevel@tonic-gate  * generated.
1110Sstevel@tonic-gate  */
1120Sstevel@tonic-gate 
1130Sstevel@tonic-gate void
adt_generate_token(struct entry * p_entry,void * p_data,struct adt_event_state * event)1140Sstevel@tonic-gate adt_generate_token(struct entry *p_entry, void *p_data,
1150Sstevel@tonic-gate     struct adt_event_state *event)
1160Sstevel@tonic-gate {
1170Sstevel@tonic-gate 	adt_token_func_t	p_func;
1180Sstevel@tonic-gate 
1190Sstevel@tonic-gate 	assert((p_entry != NULL) && (p_data != NULL) && (event != NULL));
1200Sstevel@tonic-gate 
1210Sstevel@tonic-gate 	p_func = adt_getTokenFunction(p_entry->en_token_id);
1220Sstevel@tonic-gate 	assert(p_func != NULL);
1230Sstevel@tonic-gate 
12411706SJan.Friedel@Sun.COM 	DPRINTF(("p_entry=%p, p_data=%p, offset=%llu, msgFmt=%s\n",
12511706SJan.Friedel@Sun.COM 	    (void *)p_entry, p_data, (long long)p_entry->en_offset,
12611706SJan.Friedel@Sun.COM 	    p_entry->en_msg_format));
1270Sstevel@tonic-gate 	DFLUSH
1280Sstevel@tonic-gate 
1290Sstevel@tonic-gate 	(*p_func)(p_entry->en_type_def,
1300Sstevel@tonic-gate 	    (char *)p_data + p_entry->en_offset, p_entry->en_required, event,
1310Sstevel@tonic-gate 	    p_entry->en_msg_format);
1320Sstevel@tonic-gate }
1330Sstevel@tonic-gate 
1340Sstevel@tonic-gate /* call this last */
1350Sstevel@tonic-gate 
1367496Sgww@eng.sun.com int
adt_token_close(struct adt_event_state * event)1370Sstevel@tonic-gate adt_token_close(struct adt_event_state *event)
1380Sstevel@tonic-gate {
1390Sstevel@tonic-gate 	int	rc;
1400Sstevel@tonic-gate 
1410Sstevel@tonic-gate 	rc = au_close(event->ae_event_handle, AU_TO_WRITE,
1420Sstevel@tonic-gate 	    event->ae_internal_id);
1430Sstevel@tonic-gate 	if (rc < 0)
1440Sstevel@tonic-gate 		adt_write_syslog("au_close failed", errno);
1457496Sgww@eng.sun.com 	return (rc);
1460Sstevel@tonic-gate }
1470Sstevel@tonic-gate 
1480Sstevel@tonic-gate /*
1490Sstevel@tonic-gate  * one function per token -- see the jump table at the end of file
1500Sstevel@tonic-gate  */
1510Sstevel@tonic-gate 
1520Sstevel@tonic-gate /* ARGSUSED */
1530Sstevel@tonic-gate static void
adt_to_return(datadef * def,void * p_data,int required,struct adt_event_state * event,char * notUsed)1540Sstevel@tonic-gate adt_to_return(datadef *def, void *p_data, int required,
1550Sstevel@tonic-gate     struct adt_event_state *event, char *notUsed)
1560Sstevel@tonic-gate {
1570Sstevel@tonic-gate 
1580Sstevel@tonic-gate #ifdef _LP64
1590Sstevel@tonic-gate 	(void) au_write(event->ae_event_handle,
1600Sstevel@tonic-gate 	    au_to_return64((int64_t)event->ae_rc, event->ae_type));
1610Sstevel@tonic-gate #else
1620Sstevel@tonic-gate 	(void) au_write(event->ae_event_handle,
1630Sstevel@tonic-gate 	    au_to_return32((int32_t)event->ae_rc, event->ae_type));
1640Sstevel@tonic-gate #endif
1650Sstevel@tonic-gate }
1660Sstevel@tonic-gate 
1670Sstevel@tonic-gate /*
1680Sstevel@tonic-gate  * AUT_CMD
1690Sstevel@tonic-gate  *
1700Sstevel@tonic-gate  * the command line is described with argc and argv and the environment
1710Sstevel@tonic-gate  * with envp.  The envp list is NULL terminated and has no separate
1720Sstevel@tonic-gate  * counter; envp will be a NULL list unless the AUDIT_ARGE policy is
1730Sstevel@tonic-gate  * set.
1740Sstevel@tonic-gate  */
1750Sstevel@tonic-gate 
1760Sstevel@tonic-gate /* ARGSUSED */
1770Sstevel@tonic-gate static void
adt_to_cmd(datadef * def,void * p_data,int required,struct adt_event_state * event,char * notUsed)1780Sstevel@tonic-gate adt_to_cmd(datadef *def, void *p_data, int required,
1790Sstevel@tonic-gate     struct adt_event_state *event, char *notUsed)
1800Sstevel@tonic-gate {
1810Sstevel@tonic-gate 	struct adt_internal_state	*sp = event->ae_session;
1820Sstevel@tonic-gate 	int				argc;
1830Sstevel@tonic-gate 	char				**argv;
1840Sstevel@tonic-gate 	char				**envp = NULL;
1850Sstevel@tonic-gate 
1860Sstevel@tonic-gate 	argc = ((union convert *)p_data)->tint;
1870Sstevel@tonic-gate 	p_data = adt_adjust_address(p_data, sizeof (int), sizeof (char **));
1880Sstevel@tonic-gate 	argv = ((union convert *)p_data)->tchar2star;
1890Sstevel@tonic-gate 	p_data = adt_adjust_address(p_data, sizeof (char **), sizeof (char **));
1900Sstevel@tonic-gate 
1910Sstevel@tonic-gate 	if (sp->as_kernel_audit_policy & AUDIT_ARGE)
1920Sstevel@tonic-gate 		envp = ((union convert *)p_data)->tchar2star;
1930Sstevel@tonic-gate 
1940Sstevel@tonic-gate 	(void) au_write(event->ae_event_handle,
1950Sstevel@tonic-gate 	    au_to_cmd(argc, argv, envp));
1960Sstevel@tonic-gate }
1970Sstevel@tonic-gate 
1980Sstevel@tonic-gate /*
1990Sstevel@tonic-gate  * special case of AUT_CMD with 1 argument that is
2000Sstevel@tonic-gate  * a string showing the whole command and no envp
2010Sstevel@tonic-gate  */
2020Sstevel@tonic-gate /* ARGSUSED */
2030Sstevel@tonic-gate static void
adt_to_cmd1(datadef * def,void * p_data,int required,struct adt_event_state * event,char * notUsed)2040Sstevel@tonic-gate adt_to_cmd1(datadef *def, void *p_data, int required,
2050Sstevel@tonic-gate     struct adt_event_state *event, char *notUsed)
2060Sstevel@tonic-gate {
2070Sstevel@tonic-gate 	char	*string;
2080Sstevel@tonic-gate 
2090Sstevel@tonic-gate 	string = ((union convert *)p_data)->tcharstar;
2100Sstevel@tonic-gate 
2110Sstevel@tonic-gate 	if (string == NULL) {
2125537Sgww 		if (required) {
2130Sstevel@tonic-gate 			string = empty;
2145537Sgww 		} else {
2150Sstevel@tonic-gate 			return;
2165537Sgww 		}
2170Sstevel@tonic-gate 	}
2180Sstevel@tonic-gate 	/* argc is hardcoded as 1 */
2190Sstevel@tonic-gate 	(void) au_write(event->ae_event_handle, au_to_cmd(1, &string,
2200Sstevel@tonic-gate 	    NULL));
2210Sstevel@tonic-gate }
2220Sstevel@tonic-gate 
2230Sstevel@tonic-gate /*
2240Sstevel@tonic-gate  * adt_to_tid	-- generic address (ip is only one defined at present)
2250Sstevel@tonic-gate  *	input:
2260Sstevel@tonic-gate  *		terminal type:  ADT_IPv4, ADT_IPv6...
2270Sstevel@tonic-gate  *		case: ADT_IPv4 or ADT_IPv6...
2280Sstevel@tonic-gate  *			ip type
2290Sstevel@tonic-gate  *			remote port
2300Sstevel@tonic-gate  *			local port
2310Sstevel@tonic-gate  *			address
2320Sstevel@tonic-gate  *		case: not defined...
2330Sstevel@tonic-gate  */
2340Sstevel@tonic-gate /* ARGSUSED */
2350Sstevel@tonic-gate static void
adt_to_tid(datadef * def,void * p_data,int required,struct adt_event_state * event,char * notUsed)2360Sstevel@tonic-gate adt_to_tid(datadef *def, void *p_data, int required,
2370Sstevel@tonic-gate     struct adt_event_state *event, char *notUsed)
2380Sstevel@tonic-gate {
2390Sstevel@tonic-gate 	au_generic_tid_t	tid;
2400Sstevel@tonic-gate 	uint32_t		type;
2410Sstevel@tonic-gate 	au_ip_t			*ip;
2420Sstevel@tonic-gate 
2430Sstevel@tonic-gate 	type = ((union convert *)p_data)->tuint32;
2440Sstevel@tonic-gate 
2450Sstevel@tonic-gate 	switch (type) {
2460Sstevel@tonic-gate 	case ADT_IPv4:
2470Sstevel@tonic-gate 	case ADT_IPv6:
2480Sstevel@tonic-gate 		p_data = adt_adjust_address(p_data, sizeof (uint32_t),
2490Sstevel@tonic-gate 		    sizeof (uint32_t));
2500Sstevel@tonic-gate 
2510Sstevel@tonic-gate 		tid.gt_type = AU_IPADR;
2520Sstevel@tonic-gate 		ip = &(tid.gt_adr.at_ip);
2530Sstevel@tonic-gate 
2540Sstevel@tonic-gate 		ip->at_type = (type == ADT_IPv4) ?
2550Sstevel@tonic-gate 		    AU_IPv4 : AU_IPv6;
2560Sstevel@tonic-gate 
2570Sstevel@tonic-gate 		ip->at_r_port = ((union convert *)p_data)->tuint16;
2580Sstevel@tonic-gate 		p_data = adt_adjust_address(p_data, sizeof (uint16_t),
2590Sstevel@tonic-gate 		    sizeof (uint16_t));
2600Sstevel@tonic-gate 
2610Sstevel@tonic-gate 		ip->at_l_port = ((union convert *)p_data)->tuint16;
2620Sstevel@tonic-gate 
2630Sstevel@tonic-gate 		/* arg3 is for the array element, not the array size */
2640Sstevel@tonic-gate 		p_data = adt_adjust_address(p_data, sizeof (uint16_t),
2650Sstevel@tonic-gate 		    sizeof (uint32_t));
2660Sstevel@tonic-gate 
2670Sstevel@tonic-gate 		(void) memcpy(ip->at_addr, p_data, ip->at_type);
2680Sstevel@tonic-gate 		break;
2690Sstevel@tonic-gate 	default:
2700Sstevel@tonic-gate 		adt_write_syslog("Invalid terminal id type", EINVAL);
2710Sstevel@tonic-gate 		return;
2720Sstevel@tonic-gate 	}
2730Sstevel@tonic-gate 	(void) au_write(event->ae_event_handle, au_to_tid(&tid));
2740Sstevel@tonic-gate }
2750Sstevel@tonic-gate 
2760Sstevel@tonic-gate /*
2771780Sgww  * au_to_frmi takes a char * that is the fmri.
2781780Sgww  */
2791780Sgww /* ARGSUSED */
2801780Sgww static void
adt_to_frmi(datadef * def,void * p_data,int required,struct adt_event_state * event,char * notUsed)2811780Sgww adt_to_frmi(datadef *def, void *p_data, int required,
2821780Sgww     struct adt_event_state *event, char *notUsed)
2831780Sgww {
2841780Sgww 	char		*fmri;
2851780Sgww 
2861780Sgww 	DPRINTF(("  adt_to_fmri dd_datatype=%d\n", def->dd_datatype));
2871780Sgww 
2881780Sgww 	fmri = ((union convert *)p_data)->tcharstar;
2891780Sgww 
2901780Sgww 	if (fmri == NULL) {
2915537Sgww 		if (required) {
2921780Sgww 			fmri = empty;
2935537Sgww 		} else {
2941780Sgww 			return;
2955537Sgww 		}
2961780Sgww 	}
2971780Sgww 	DPRINTF(("  fmri=%s\n", fmri));
2981780Sgww 	(void) au_write(event->ae_event_handle, au_to_fmri(fmri));
2991780Sgww }
3001780Sgww 
3011780Sgww /*
3023222Sgww  * au_to_label takes an m_label_t * that is the label.
3033222Sgww  */
3043222Sgww /* ARGSUSED */
3053222Sgww static void
adt_to_label(datadef * def,void * p_data,int required,struct adt_event_state * event,char * notUsed)3063222Sgww adt_to_label(datadef *def, void *p_data, int required,
3073222Sgww     struct adt_event_state *event, char *notUsed)
3083222Sgww {
3093222Sgww 	m_label_t	*label;
3103222Sgww 
3113222Sgww 	DPRINTF(("  adt_to_label dd_datatype=%d\n", def->dd_datatype));
3123222Sgww 
3133222Sgww 	label = ((union convert *)p_data)->tm_label;
3143222Sgww 
3153222Sgww 	if (label != NULL) {
3163222Sgww 		DPRINTF(("  label=%s\n", dprt_label(label)));
3173222Sgww 		DFLUSH
3183222Sgww 		(void) au_write(event->ae_event_handle, au_to_label(label));
3193222Sgww 	} else {
3203222Sgww 		DPRINTF(("  Null label\n"));
3213222Sgww 		if (required)
3223222Sgww 			adt_write_syslog("adt_to_label no required label", 0);
3233222Sgww 	}
3243222Sgww }
3253222Sgww 
3263222Sgww /*
3270Sstevel@tonic-gate  * au_to_newgroups takes a length and an array of gids
3280Sstevel@tonic-gate  * as input.  The input to adt_to_newgroups is a length
3290Sstevel@tonic-gate  * and a pointer to an array of gids.
3300Sstevel@tonic-gate  */
3310Sstevel@tonic-gate 
3320Sstevel@tonic-gate /* ARGSUSED */
3330Sstevel@tonic-gate static void
adt_to_newgroups(datadef * def,void * p_data,int required,struct adt_event_state * event,char * notUsed)3340Sstevel@tonic-gate adt_to_newgroups(datadef *def, void *p_data, int required,
3350Sstevel@tonic-gate     struct adt_event_state *event, char *notUsed)
3360Sstevel@tonic-gate {
3370Sstevel@tonic-gate 	int	n;
3380Sstevel@tonic-gate 	gid_t	*groups;
3390Sstevel@tonic-gate 
3400Sstevel@tonic-gate 	n = ((union convert *)p_data)->tint;
3410Sstevel@tonic-gate 	if (n < 1) {
3420Sstevel@tonic-gate 		if (required) {
3430Sstevel@tonic-gate 			n = 0;  /* in case negative n was passed */
3445537Sgww 		} else {
3450Sstevel@tonic-gate 			return;
3465537Sgww 		}
3470Sstevel@tonic-gate 	}
3480Sstevel@tonic-gate 	p_data = adt_adjust_address(p_data, sizeof (int), sizeof (int32_t *));
3490Sstevel@tonic-gate 
3500Sstevel@tonic-gate 	groups = ((union convert *)p_data)->tgidstar;
3510Sstevel@tonic-gate 
3520Sstevel@tonic-gate 	(void) au_write(event->ae_event_handle, au_to_newgroups(n, groups));
3530Sstevel@tonic-gate }
3540Sstevel@tonic-gate 
3550Sstevel@tonic-gate /* ARGSUSED */
3560Sstevel@tonic-gate static void
adt_to_path(datadef * def,void * p_data,int required,struct adt_event_state * event,char * notUsed)3570Sstevel@tonic-gate adt_to_path(datadef *def, void *p_data, int required,
3580Sstevel@tonic-gate     struct adt_event_state *event, char *notUsed)
3590Sstevel@tonic-gate {
3600Sstevel@tonic-gate 	char	*path;
3610Sstevel@tonic-gate 
3620Sstevel@tonic-gate 	path = ((union convert *)p_data)->tcharstar;
3630Sstevel@tonic-gate 
3640Sstevel@tonic-gate 	if (path != NULL) {
3650Sstevel@tonic-gate 		DPRINTF(("  path=%s\n", path));
3660Sstevel@tonic-gate 		(void) au_write(event->ae_event_handle, au_to_path(path));
3670Sstevel@tonic-gate 	} else {
3680Sstevel@tonic-gate 		DPRINTF(("  Null path\n"));
3695537Sgww 		if (required) {
3700Sstevel@tonic-gate 			(void) au_write(event->ae_event_handle,
3710Sstevel@tonic-gate 			    au_to_path(empty));
3725537Sgww 		}
3730Sstevel@tonic-gate 	}
3740Sstevel@tonic-gate }
3750Sstevel@tonic-gate 
3760Sstevel@tonic-gate /*
3770Sstevel@tonic-gate  * dummy token id:  AUT_PATHLIST
3780Sstevel@tonic-gate  */
3790Sstevel@tonic-gate 
3800Sstevel@tonic-gate /* ARGSUSED */
3810Sstevel@tonic-gate static void
adt_to_pathlist(datadef * def,void * p_data,int required,struct adt_event_state * event,char * notUsed)3820Sstevel@tonic-gate adt_to_pathlist(datadef *def, void *p_data, int required,
3830Sstevel@tonic-gate     struct adt_event_state *event, char *notUsed)
3840Sstevel@tonic-gate {
3850Sstevel@tonic-gate 	char	*path;
3860Sstevel@tonic-gate 	char	*working_buf;
3870Sstevel@tonic-gate 	char	*pathlist;
3880Sstevel@tonic-gate 	char	*last_str;
3890Sstevel@tonic-gate 
3900Sstevel@tonic-gate 	pathlist = ((union convert *)p_data)->tcharstar;
3910Sstevel@tonic-gate 
3920Sstevel@tonic-gate 	if (pathlist != NULL) {
3930Sstevel@tonic-gate 		working_buf = strdup(pathlist);
3940Sstevel@tonic-gate 		if (working_buf == NULL) {
3950Sstevel@tonic-gate 			adt_write_syslog("audit failure", errno);
3965537Sgww 			if (required) {
3970Sstevel@tonic-gate 				(void) au_write(event->ae_event_handle,
3980Sstevel@tonic-gate 				    au_to_path(empty));
3995537Sgww 			}
4000Sstevel@tonic-gate 			return;
4010Sstevel@tonic-gate 		}
4020Sstevel@tonic-gate 		for (path = strtok_r(working_buf, " ", &last_str);
4030Sstevel@tonic-gate 		    path; path = strtok_r(NULL, " ", &last_str)) {
4040Sstevel@tonic-gate 			DPRINTF(("  path=%s\n", path));
4050Sstevel@tonic-gate 			(void) au_write(event->ae_event_handle,
4060Sstevel@tonic-gate 			    au_to_path(path));
4070Sstevel@tonic-gate 		}
4080Sstevel@tonic-gate 	} else {
4090Sstevel@tonic-gate 		DPRINTF(("  Null path list\n"));
4100Sstevel@tonic-gate 		if (required)
4110Sstevel@tonic-gate 			(void) au_write(event->ae_event_handle,
4120Sstevel@tonic-gate 			    au_to_path(empty));
4130Sstevel@tonic-gate 	}
4140Sstevel@tonic-gate }
4150Sstevel@tonic-gate 
4160Sstevel@tonic-gate /*
4170Sstevel@tonic-gate  * AUT_PRIV
4180Sstevel@tonic-gate  */
4190Sstevel@tonic-gate 
4200Sstevel@tonic-gate /* ARGSUSED */
4210Sstevel@tonic-gate static void
adt_to_priv(datadef * def,void * p_data,int required,struct adt_event_state * event,const char * priv_type)4220Sstevel@tonic-gate adt_to_priv(datadef *def, void *p_data, int required,
4230Sstevel@tonic-gate     struct adt_event_state *event, const char *priv_type)
4240Sstevel@tonic-gate {
4250Sstevel@tonic-gate 	priv_set_t	*privilege;
4260Sstevel@tonic-gate 
4270Sstevel@tonic-gate 	privilege = ((union convert *)p_data)->tprivstar;
4280Sstevel@tonic-gate 
4290Sstevel@tonic-gate 	if (privilege != NULL) {
4300Sstevel@tonic-gate 		(void) au_write(event->ae_event_handle,
4310Sstevel@tonic-gate 		    au_to_privset(priv_type, privilege));
4320Sstevel@tonic-gate 	} else {
4330Sstevel@tonic-gate 		if (required) {
4340Sstevel@tonic-gate 			DPRINTF(("  Null privilege\n"));
4350Sstevel@tonic-gate 			(void) au_write(event->ae_event_handle,
4360Sstevel@tonic-gate 			    au_to_privset(empty, NULL));
4370Sstevel@tonic-gate 		}
4380Sstevel@tonic-gate 	}
4390Sstevel@tonic-gate }
4400Sstevel@tonic-gate 
4410Sstevel@tonic-gate /*
4420Sstevel@tonic-gate  * -AUT_PRIV_L	AUT_PRIV for a limit set
4430Sstevel@tonic-gate  */
4440Sstevel@tonic-gate 
4450Sstevel@tonic-gate /* ARGSUSED */
4460Sstevel@tonic-gate static void
adt_to_priv_limit(datadef * def,void * p_data,int required,struct adt_event_state * event,char * notUsed)4470Sstevel@tonic-gate adt_to_priv_limit(datadef *def, void *p_data, int required,
4480Sstevel@tonic-gate     struct adt_event_state *event, char *notUsed)
4490Sstevel@tonic-gate {
4500Sstevel@tonic-gate 	adt_to_priv(def, p_data, required, event, PRIV_LIMIT);
4510Sstevel@tonic-gate }
4520Sstevel@tonic-gate 
4530Sstevel@tonic-gate /*
4540Sstevel@tonic-gate  * -AUT_PRIV_I	AUT_PRIV for an inherit set
4550Sstevel@tonic-gate  */
4560Sstevel@tonic-gate 
4570Sstevel@tonic-gate /* ARGSUSED */
4580Sstevel@tonic-gate static void
adt_to_priv_inherit(datadef * def,void * p_data,int required,struct adt_event_state * event,char * notUsed)4590Sstevel@tonic-gate adt_to_priv_inherit(datadef *def, void *p_data, int required,
4600Sstevel@tonic-gate     struct adt_event_state *event, char *notUsed)
4610Sstevel@tonic-gate {
4620Sstevel@tonic-gate 	adt_to_priv(def, p_data, required, event, PRIV_INHERITABLE);
4630Sstevel@tonic-gate }
4640Sstevel@tonic-gate 
4650Sstevel@tonic-gate /* ARGSUSED */
4660Sstevel@tonic-gate static void
adt_to_priv_effective(datadef * def,void * p_data,int required,struct adt_event_state * event,char * notUsed)4670Sstevel@tonic-gate adt_to_priv_effective(datadef *def, void *p_data, int required,
4680Sstevel@tonic-gate     struct adt_event_state *event, char *notUsed)
4690Sstevel@tonic-gate {
4700Sstevel@tonic-gate 	adt_to_priv(def, p_data, required, event, PRIV_EFFECTIVE);
4710Sstevel@tonic-gate }
4720Sstevel@tonic-gate 
4730Sstevel@tonic-gate static void
getCharacteristics(struct auditpinfo_addr * info,pid_t * pid)4740Sstevel@tonic-gate getCharacteristics(struct auditpinfo_addr *info, pid_t *pid)
4750Sstevel@tonic-gate {
4760Sstevel@tonic-gate 	int	rc;
4770Sstevel@tonic-gate 
4785537Sgww 	if (*pid == 0) {		/* getpinfo for this pid */
4790Sstevel@tonic-gate 		info->ap_pid = getpid();
4805537Sgww 	} else {
4810Sstevel@tonic-gate 		info->ap_pid = *pid;
4825537Sgww 	}
4830Sstevel@tonic-gate 
4840Sstevel@tonic-gate 	rc = auditon(A_GETPINFO_ADDR, (caddr_t)info,
4850Sstevel@tonic-gate 	    sizeof (struct auditpinfo_addr));
4860Sstevel@tonic-gate 	if (rc == -1) {
4870Sstevel@tonic-gate 		info->ap_auid = AU_NOAUDITID;
4880Sstevel@tonic-gate 		info->ap_asid = 0;
4890Sstevel@tonic-gate 		(void) memset((void *)&(info->ap_termid), 0,
4900Sstevel@tonic-gate 		    sizeof (au_tid_addr_t));
4910Sstevel@tonic-gate 		info->ap_termid.at_type = AU_IPv4;
4920Sstevel@tonic-gate 	}
4930Sstevel@tonic-gate }
4940Sstevel@tonic-gate 
4950Sstevel@tonic-gate /*
4960Sstevel@tonic-gate  * AUT_PROCESS
4970Sstevel@tonic-gate  *
4980Sstevel@tonic-gate  */
4990Sstevel@tonic-gate 
5000Sstevel@tonic-gate /* ARGSUSED */
5010Sstevel@tonic-gate static void
adt_to_process(datadef * def,void * p_data,int required,struct adt_event_state * event,char * notUsed)5020Sstevel@tonic-gate adt_to_process(datadef *def, void *p_data, int required,
5030Sstevel@tonic-gate     struct adt_event_state *event, char *notUsed)
5040Sstevel@tonic-gate {
5050Sstevel@tonic-gate 	au_id_t			auid;
5060Sstevel@tonic-gate 	uid_t			euid;
5070Sstevel@tonic-gate 	gid_t			egid;
5080Sstevel@tonic-gate 	uid_t			ruid;
5090Sstevel@tonic-gate 	gid_t			rgid;
5100Sstevel@tonic-gate 	pid_t			pid;
5110Sstevel@tonic-gate 	au_asid_t		sid;
5120Sstevel@tonic-gate 	au_tid_addr_t		*tid;
5130Sstevel@tonic-gate 	struct auditpinfo_addr	info;
5140Sstevel@tonic-gate 
5150Sstevel@tonic-gate 	auid = ((union convert *)p_data)->tuid;
5160Sstevel@tonic-gate 	p_data = adt_adjust_address(p_data, sizeof (uid_t), sizeof (uid_t));
5170Sstevel@tonic-gate 	euid = ((union convert *)p_data)->tuid;
5180Sstevel@tonic-gate 	p_data = adt_adjust_address(p_data, sizeof (uid_t), sizeof (gid_t));
5190Sstevel@tonic-gate 	egid = ((union convert *)p_data)->tgid;
5200Sstevel@tonic-gate 	p_data = adt_adjust_address(p_data, sizeof (gid_t), sizeof (uid_t));
5210Sstevel@tonic-gate 	ruid = ((union convert *)p_data)->tuid;
5220Sstevel@tonic-gate 	p_data = adt_adjust_address(p_data, sizeof (uid_t), sizeof (gid_t));
5230Sstevel@tonic-gate 	rgid = ((union convert *)p_data)->tgid;
5240Sstevel@tonic-gate 	p_data = adt_adjust_address(p_data, sizeof (gid_t), sizeof (pid_t));
5250Sstevel@tonic-gate 	pid  = ((union convert *)p_data)->tpid;
5260Sstevel@tonic-gate 	p_data = adt_adjust_address(p_data, sizeof (pid_t), sizeof (uint32_t));
5270Sstevel@tonic-gate 	sid  = ((union convert *)p_data)->tuint32;
5280Sstevel@tonic-gate 	p_data = adt_adjust_address(p_data, sizeof (uint32_t),
5290Sstevel@tonic-gate 	    sizeof (au_tid_addr_t *));
5300Sstevel@tonic-gate 	tid  = ((union convert *)p_data)->ttermid;
5310Sstevel@tonic-gate 
5320Sstevel@tonic-gate 	getCharacteristics(&info, &pid);
5330Sstevel@tonic-gate 
5340Sstevel@tonic-gate 	if (auid == AU_NOAUDITID)
5350Sstevel@tonic-gate 		auid = info.ap_auid;
5360Sstevel@tonic-gate 
5370Sstevel@tonic-gate 	if (euid == AU_NOAUDITID)
5380Sstevel@tonic-gate 		euid = geteuid();
5390Sstevel@tonic-gate 
5400Sstevel@tonic-gate 	if (egid == AU_NOAUDITID)
5410Sstevel@tonic-gate 		egid = getegid();
5420Sstevel@tonic-gate 
5430Sstevel@tonic-gate 	if (ruid == AU_NOAUDITID)
5440Sstevel@tonic-gate 		ruid = getuid();
5450Sstevel@tonic-gate 
5460Sstevel@tonic-gate 	if (rgid == AU_NOAUDITID)
5470Sstevel@tonic-gate 		rgid = getgid();
5480Sstevel@tonic-gate 
5490Sstevel@tonic-gate 	if (tid == NULL)
5500Sstevel@tonic-gate 		tid = &(info.ap_termid);
5510Sstevel@tonic-gate 
5520Sstevel@tonic-gate 	if (sid == 0)
5530Sstevel@tonic-gate 		sid = info.ap_asid;
5540Sstevel@tonic-gate 
5550Sstevel@tonic-gate 	if (pid == 0)
5560Sstevel@tonic-gate 		pid = info.ap_pid;
5570Sstevel@tonic-gate 
5580Sstevel@tonic-gate 	(void) au_write(event->ae_event_handle,
5590Sstevel@tonic-gate 	    au_to_process_ex(auid, euid, egid, ruid, rgid, pid, sid, tid));
5600Sstevel@tonic-gate }
5610Sstevel@tonic-gate 
5620Sstevel@tonic-gate /*
5632425Sgww  * Generate subject information.
5642425Sgww  * If labels are present, generate the subject label token.
5652425Sgww  * If the group audit policy is set, generate the subject group token.
5660Sstevel@tonic-gate  *
5670Sstevel@tonic-gate  * The required flag does not apply here.
5680Sstevel@tonic-gate  *
5690Sstevel@tonic-gate  * Non-attributable records are indicated by an auid of AU_NOAUDITID;
5700Sstevel@tonic-gate  * no subject token or group token is generated for a non-attributable
5710Sstevel@tonic-gate  * record.
5720Sstevel@tonic-gate  */
5730Sstevel@tonic-gate 
5740Sstevel@tonic-gate /* ARGSUSED */
5750Sstevel@tonic-gate static void
adt_to_subject(datadef * def,void * p_data,int required,struct adt_event_state * event,char * notUsed)5760Sstevel@tonic-gate adt_to_subject(datadef *def, void *p_data, int required,
5770Sstevel@tonic-gate     struct adt_event_state *event, char *notUsed)
5780Sstevel@tonic-gate {
5790Sstevel@tonic-gate 	struct adt_internal_state	*sp = event->ae_session;
5800Sstevel@tonic-gate 
5810Sstevel@tonic-gate 	if (sp->as_info.ai_auid == AU_NOAUDITID)
5820Sstevel@tonic-gate 		return;
5830Sstevel@tonic-gate 
5840Sstevel@tonic-gate 	assert(sp->as_have_user_data == ADT_HAVE_ALL);
5850Sstevel@tonic-gate 
5860Sstevel@tonic-gate 	(void) au_write(event->ae_event_handle,
5870Sstevel@tonic-gate 	    au_to_subject_ex(sp->as_info.ai_auid,
5884899Stz204579 	    sp->as_euid, sp->as_egid, sp->as_ruid, sp->as_rgid,
5894899Stz204579 	    sp->as_pid, sp->as_info.ai_asid,
5904899Stz204579 	    &(sp->as_info.ai_termid)));
5912835Sgww 	if (is_system_labeled()) {
5922835Sgww 		(void) au_write(event->ae_event_handle,
5932835Sgww 		    au_to_label(sp->as_label));
5942835Sgww 	}
5950Sstevel@tonic-gate 	/*
5962478Sgww 	 * Add optional tokens if in the process model.
5972478Sgww 	 * In a session model, the groups list is undefined and label
5982835Sgww 	 * is in the state.
5990Sstevel@tonic-gate 	 */
6002478Sgww 	if (sp->as_session_model == ADT_PROCESS_MODEL) {
6012478Sgww 		if (sp->as_kernel_audit_policy & AUDIT_GROUP) {
6022478Sgww 			int group_count;
60311134SCasper.Dik@Sun.COM 			int maxgrp = getgroups(0, NULL);
60411134SCasper.Dik@Sun.COM 			gid_t *grouplist = alloca(maxgrp * sizeof (gid_t));
6052478Sgww 
60611134SCasper.Dik@Sun.COM 			if ((group_count = getgroups(maxgrp, grouplist)) > 0) {
6070Sstevel@tonic-gate 				(void) au_write(event->ae_event_handle,
6080Sstevel@tonic-gate 				    au_to_newgroups(group_count, grouplist));
6090Sstevel@tonic-gate 			}
6100Sstevel@tonic-gate 		}
6110Sstevel@tonic-gate 	}
6120Sstevel@tonic-gate }
6130Sstevel@tonic-gate 
6140Sstevel@tonic-gate /*
6150Sstevel@tonic-gate  * adt_to_text()
6160Sstevel@tonic-gate  *
6170Sstevel@tonic-gate  * The format string, normally null, is sort of a wrapper around
6180Sstevel@tonic-gate  * the input.  adt_write_text() is a wrapper around au_write that
6190Sstevel@tonic-gate  * handles the format string
6200Sstevel@tonic-gate  *
6210Sstevel@tonic-gate  */
6220Sstevel@tonic-gate #define	TEXT_LENGTH 49
6230Sstevel@tonic-gate 
6240Sstevel@tonic-gate static void
adt_write_text(int handle,char * main_text,const char * format)6250Sstevel@tonic-gate adt_write_text(int handle, char *main_text, const char *format)
6260Sstevel@tonic-gate {
6270Sstevel@tonic-gate 	char	buffer[TEXT_LENGTH * 2 + 1];
6280Sstevel@tonic-gate 
6295537Sgww 	if (format == NULL) {
6300Sstevel@tonic-gate 		(void) au_write(handle, au_to_text(main_text));
6315537Sgww 	} else {
6320Sstevel@tonic-gate 		(void) snprintf(buffer, TEXT_LENGTH * 2, format, main_text);
6330Sstevel@tonic-gate 		(void) au_write(handle, au_to_text(buffer));
6340Sstevel@tonic-gate 	}
6350Sstevel@tonic-gate }
6360Sstevel@tonic-gate 
6370Sstevel@tonic-gate static void
adt_to_text(datadef * def,void * p_data,int required,struct adt_event_state * event,char * format)6380Sstevel@tonic-gate adt_to_text(datadef *def, void *p_data, int required,
6390Sstevel@tonic-gate     struct adt_event_state *event, char *format)
6400Sstevel@tonic-gate {
6410Sstevel@tonic-gate 	static int	have_syslogged = 0;
6420Sstevel@tonic-gate 	char		*string;
6430Sstevel@tonic-gate 	char		**string_list;
6440Sstevel@tonic-gate 	char		buffer[TEXT_LENGTH + 1];
6450Sstevel@tonic-gate 	time_t		date;
6460Sstevel@tonic-gate 	struct tm	tm;
6470Sstevel@tonic-gate 	uint32_t	*int_list;
6480Sstevel@tonic-gate 	int		written, available;
6490Sstevel@tonic-gate 	int		i, arrayCount;
6500Sstevel@tonic-gate 	struct msg_text *list;
6510Sstevel@tonic-gate 	int		list_index;
6520Sstevel@tonic-gate 
6530Sstevel@tonic-gate 	DPRINTF(("  adt_to_text dd_datatype=%d\n", def->dd_datatype));
6540Sstevel@tonic-gate 	switch (def->dd_datatype) {
6550Sstevel@tonic-gate 	case ADT_DATE:
6560Sstevel@tonic-gate 		/*
6570Sstevel@tonic-gate 		 * Consider creating a separate token type for dates
6580Sstevel@tonic-gate 		 * -- store as longs and format them in praudit.
6590Sstevel@tonic-gate 		 * For now, a date is input as a time_t and output as
6600Sstevel@tonic-gate 		 * a text token.  If we do this, we need to consider
6610Sstevel@tonic-gate 		 * carrying timezone info so that praudit can
6620Sstevel@tonic-gate 		 * represent times in an unambiguous manner.
6630Sstevel@tonic-gate 		 */
6640Sstevel@tonic-gate 		date = ((union convert *)p_data)->tlong;
6650Sstevel@tonic-gate 		if (strftime(buffer, sizeof (buffer), "%x",
6660Sstevel@tonic-gate 		    localtime_r(&date, &tm)) > TEXT_LENGTH) {
6675537Sgww 			if (required) {
6680Sstevel@tonic-gate 				(void) strncpy(buffer, "invalid date",
6690Sstevel@tonic-gate 				    TEXT_LENGTH);
6705537Sgww 			} else {
6710Sstevel@tonic-gate 				break;
6725537Sgww 			}
6730Sstevel@tonic-gate 		}
6740Sstevel@tonic-gate 		DPRINTF(("  text=%s\n", buffer));
6750Sstevel@tonic-gate 		adt_write_text(event->ae_event_handle, buffer, format);
6760Sstevel@tonic-gate 		break;
6770Sstevel@tonic-gate 		/*
6780Sstevel@tonic-gate 		 * The "input size" is overloaded to mean the list number
6790Sstevel@tonic-gate 		 * and the msg_selector indexes the desired string in
6800Sstevel@tonic-gate 		 * that list
6810Sstevel@tonic-gate 		 */
6820Sstevel@tonic-gate 	case ADT_MSG:
6838484Sgww@eng.sun.com 		list = &adt_msg_text[(enum adt_msg_list)def->dd_input_size];
6840Sstevel@tonic-gate 		list_index = ((union convert *)p_data)->msg_selector;
6850Sstevel@tonic-gate 
6865319Stz204579 		if ((list_index + list->ml_offset < list->ml_min_index) ||
6875537Sgww 		    (list_index + list->ml_offset > list->ml_max_index)) {
6880Sstevel@tonic-gate 			string = "Invalid message index";
6895537Sgww 		} else {
6900Sstevel@tonic-gate 			string = list->ml_msg_list[list_index +
6910Sstevel@tonic-gate 			    list->ml_offset];
6925537Sgww 		}
6930Sstevel@tonic-gate 
6940Sstevel@tonic-gate 		if (string == NULL) {	/* null is valid; means skip */
6950Sstevel@tonic-gate 			if (required) {
6960Sstevel@tonic-gate 				string = empty;
6975537Sgww 			} else {
6980Sstevel@tonic-gate 				break;
6995537Sgww 			}
7000Sstevel@tonic-gate 		}
7010Sstevel@tonic-gate 		DPRINTF(("  text=%s\n", string));
7020Sstevel@tonic-gate 		adt_write_text(event->ae_event_handle, string, format);
7030Sstevel@tonic-gate 		break;
7040Sstevel@tonic-gate 	case ADT_UID:
7050Sstevel@tonic-gate 	case ADT_GID:
7060Sstevel@tonic-gate 	case ADT_UINT:
7074899Stz204579 	case ADT_UINT32:
7084899Stz204579 		(void) snprintf(buffer, TEXT_LENGTH, "%u",
7094899Stz204579 		    ((union convert *)p_data)->tuint);
7104899Stz204579 
7114899Stz204579 		DPRINTF(("  text=%s\n", buffer));
7124899Stz204579 		adt_write_text(event->ae_event_handle, buffer, format);
7134899Stz204579 		break;
7144899Stz204579 	case ADT_INT:
7154899Stz204579 	case ADT_INT32:
7160Sstevel@tonic-gate 		(void) snprintf(buffer, TEXT_LENGTH, "%d",
7174899Stz204579 		    ((union convert *)p_data)->tint);
7184899Stz204579 
7194899Stz204579 		DPRINTF(("  text=%s\n", buffer));
7204899Stz204579 		adt_write_text(event->ae_event_handle, buffer, format);
7214899Stz204579 		break;
7224899Stz204579 	case ADT_LONG:
7234899Stz204579 		(void) snprintf(buffer, TEXT_LENGTH, "%ld",
7244899Stz204579 		    ((union convert *)p_data)->tlong);
7250Sstevel@tonic-gate 
7260Sstevel@tonic-gate 		DPRINTF(("  text=%s\n", buffer));
7270Sstevel@tonic-gate 		adt_write_text(event->ae_event_handle, buffer, format);
7280Sstevel@tonic-gate 		break;
7290Sstevel@tonic-gate 	case ADT_UIDSTAR:
7300Sstevel@tonic-gate 	case ADT_GIDSTAR:
7310Sstevel@tonic-gate 	case ADT_UINT32STAR:
7320Sstevel@tonic-gate 		int_list = ((union convert *)p_data)->tuint32star;
7330Sstevel@tonic-gate 		p_data = adt_adjust_address(p_data, sizeof (int *),
7340Sstevel@tonic-gate 		    sizeof (int));
7350Sstevel@tonic-gate 		arrayCount = ((union convert *)p_data)->tint;
7360Sstevel@tonic-gate 
7370Sstevel@tonic-gate 		string = buffer;
7380Sstevel@tonic-gate 		available = TEXT_LENGTH;	/* space available in buffer */
7390Sstevel@tonic-gate 
7400Sstevel@tonic-gate 		if (arrayCount < 0)
7410Sstevel@tonic-gate 			arrayCount = 0;
7420Sstevel@tonic-gate 
7430Sstevel@tonic-gate 		if ((arrayCount > 0) && (int_list != NULL)) {
7440Sstevel@tonic-gate 			for (; arrayCount > 0; arrayCount--) {
7450Sstevel@tonic-gate 				written = snprintf(string, available,
7460Sstevel@tonic-gate 				    "%d ", *int_list++);
7470Sstevel@tonic-gate 				if (written < 1)
7480Sstevel@tonic-gate 					break;
7490Sstevel@tonic-gate 				string += written;
7500Sstevel@tonic-gate 				available -= written;
7510Sstevel@tonic-gate 			}
7525537Sgww 		} else if (required) {
7530Sstevel@tonic-gate 			string = empty;
7545537Sgww 		} else {
7550Sstevel@tonic-gate 			break;
7565537Sgww 		}
7570Sstevel@tonic-gate 
7580Sstevel@tonic-gate 		adt_write_text(event->ae_event_handle, buffer, format);
7590Sstevel@tonic-gate 		break;
7600Sstevel@tonic-gate 	case ADT_ULONG:
7614899Stz204579 		(void) snprintf(buffer, TEXT_LENGTH, "%lu",
7620Sstevel@tonic-gate 		    ((union convert *)p_data)->tulong);
7630Sstevel@tonic-gate 
7640Sstevel@tonic-gate 		DPRINTF(("  text=%s\n", buffer));
7650Sstevel@tonic-gate 		adt_write_text(event->ae_event_handle, buffer, format);
7660Sstevel@tonic-gate 		break;
7674899Stz204579 	case ADT_UINT64:
7684899Stz204579 		(void) snprintf(buffer, TEXT_LENGTH, "%llu",
7694899Stz204579 		    ((union convert *)p_data)->tuint64);
7704899Stz204579 
7714899Stz204579 		DPRINTF(("  text=%s\n", buffer));
7724899Stz204579 		adt_write_text(event->ae_event_handle, buffer, format);
7734899Stz204579 		break;
7740Sstevel@tonic-gate 	case ADT_CHARSTAR:
7750Sstevel@tonic-gate 		string = ((union convert *)p_data)->tcharstar;
7760Sstevel@tonic-gate 
7770Sstevel@tonic-gate 		if (string == NULL) {
7785537Sgww 			if (required) {
7790Sstevel@tonic-gate 				string = empty;
7805537Sgww 			} else {
7810Sstevel@tonic-gate 				break;
7825537Sgww 			}
7830Sstevel@tonic-gate 		}
7840Sstevel@tonic-gate 		DPRINTF(("  text=%s\n", string));
7850Sstevel@tonic-gate 		adt_write_text(event->ae_event_handle, string, format);
7860Sstevel@tonic-gate 		break;
7870Sstevel@tonic-gate 	case ADT_CHAR2STAR:
7880Sstevel@tonic-gate 		string_list = ((union convert *)p_data)->tchar2star;
7890Sstevel@tonic-gate 		p_data = adt_adjust_address(p_data, sizeof (char **),
7900Sstevel@tonic-gate 		    sizeof (int));
7910Sstevel@tonic-gate 		arrayCount = ((union convert *)p_data)->tint;
7920Sstevel@tonic-gate 
7930Sstevel@tonic-gate 		if (arrayCount < 0)
7940Sstevel@tonic-gate 			arrayCount = 0;
7950Sstevel@tonic-gate 
7960Sstevel@tonic-gate 		if ((arrayCount > 0) && (string_list != NULL)) {
7970Sstevel@tonic-gate 			for (i = 0; i < arrayCount; i++) {
7980Sstevel@tonic-gate 				string = string_list[i];
7990Sstevel@tonic-gate 				if (string != NULL)
8000Sstevel@tonic-gate 					adt_write_text(event->ae_event_handle,
8010Sstevel@tonic-gate 					    string, format);
8020Sstevel@tonic-gate 			}
8035537Sgww 		} else if (required) {
8040Sstevel@tonic-gate 			adt_write_text(event->ae_event_handle, empty, format);
8055537Sgww 		} else {
8060Sstevel@tonic-gate 			break;
8075537Sgww 		}
8080Sstevel@tonic-gate 		break;
8090Sstevel@tonic-gate 	default:
8100Sstevel@tonic-gate 		if (!have_syslogged) { /* don't flood the log */
8110Sstevel@tonic-gate 			adt_write_syslog("unsupported data conversion",
8120Sstevel@tonic-gate 			    ENOTSUP);
8130Sstevel@tonic-gate 			have_syslogged = 1;
8140Sstevel@tonic-gate 		}
8150Sstevel@tonic-gate 		break;
8160Sstevel@tonic-gate 	}
8170Sstevel@tonic-gate 	DFLUSH
8180Sstevel@tonic-gate }
8190Sstevel@tonic-gate 
8205537Sgww /*
8215537Sgww  * AUT_UAUTH
8225537Sgww  */
8235537Sgww 
8240Sstevel@tonic-gate /* ARGSUSED */
8250Sstevel@tonic-gate static void
adt_to_uauth(datadef * def,void * p_data,int required,struct adt_event_state * event,char * format)8260Sstevel@tonic-gate adt_to_uauth(datadef *def, void *p_data, int required,
8270Sstevel@tonic-gate     struct adt_event_state *event, char *format)
8280Sstevel@tonic-gate {
8290Sstevel@tonic-gate 	char		*string;
8300Sstevel@tonic-gate 
8310Sstevel@tonic-gate 	DPRINTF(("  adt_to_uauth dd_datatype=%d\n", def->dd_datatype));
8320Sstevel@tonic-gate 
8330Sstevel@tonic-gate 	string = ((union convert *)p_data)->tcharstar;
8340Sstevel@tonic-gate 
8350Sstevel@tonic-gate 	if (string == NULL) {
8365537Sgww 		if (required) {
8370Sstevel@tonic-gate 			string = empty;
8385537Sgww 		} else {
8390Sstevel@tonic-gate 			return;
8405537Sgww 		}
8410Sstevel@tonic-gate 	}
8420Sstevel@tonic-gate 	DPRINTF(("  text=%s\n", string));
8430Sstevel@tonic-gate 	(void) au_write(event->ae_event_handle, au_to_uauth(string));
8440Sstevel@tonic-gate }
8450Sstevel@tonic-gate 
8465537Sgww /*
847*11893Sgww@eng.sun.com  * AUT_USER
848*11893Sgww@eng.sun.com  */
849*11893Sgww@eng.sun.com 
850*11893Sgww@eng.sun.com /* ARGSUSED */
851*11893Sgww@eng.sun.com static void
adt_to_user(datadef * def,void * p_data,int required,struct adt_event_state * event,char * format)852*11893Sgww@eng.sun.com adt_to_user(datadef *def, void *p_data, int required,
853*11893Sgww@eng.sun.com     struct adt_event_state *event, char *format)
854*11893Sgww@eng.sun.com {
855*11893Sgww@eng.sun.com 	uid_t	uid;
856*11893Sgww@eng.sun.com 	char	*username;
857*11893Sgww@eng.sun.com 
858*11893Sgww@eng.sun.com 	DPRINTF(("  adt_to_user dd_datatype=%d\n", def->dd_datatype));
859*11893Sgww@eng.sun.com 
860*11893Sgww@eng.sun.com 	uid = ((union convert *)p_data)->tuid;
861*11893Sgww@eng.sun.com 	p_data = adt_adjust_address(p_data, sizeof (uid_t), sizeof (uid_t));
862*11893Sgww@eng.sun.com 
863*11893Sgww@eng.sun.com 	username = ((union convert *)p_data)->tcharstar;
864*11893Sgww@eng.sun.com 
865*11893Sgww@eng.sun.com 	if (username == NULL) {
866*11893Sgww@eng.sun.com 		if (required) {
867*11893Sgww@eng.sun.com 			username = empty;
868*11893Sgww@eng.sun.com 		} else {
869*11893Sgww@eng.sun.com 			return;
870*11893Sgww@eng.sun.com 		}
871*11893Sgww@eng.sun.com 	}
872*11893Sgww@eng.sun.com 	DPRINTF(("  username=%s\n", username));
873*11893Sgww@eng.sun.com 	(void) au_write(event->ae_event_handle, au_to_user(uid, username));
874*11893Sgww@eng.sun.com }
875*11893Sgww@eng.sun.com 
876*11893Sgww@eng.sun.com /*
8775537Sgww  * AUT_ZONENAME
8785537Sgww  */
8795537Sgww 
8800Sstevel@tonic-gate /* ARGSUSED */
8810Sstevel@tonic-gate static void
adt_to_zonename(datadef * def,void * p_data,int required,struct adt_event_state * event,char * notUsed)8820Sstevel@tonic-gate adt_to_zonename(datadef *def, void *p_data, int required,
8830Sstevel@tonic-gate     struct adt_event_state *event, char *notUsed)
8840Sstevel@tonic-gate {
8850Sstevel@tonic-gate 	char	*name;
8860Sstevel@tonic-gate 
8870Sstevel@tonic-gate 	name = ((union convert *)p_data)->tcharstar;
8880Sstevel@tonic-gate 
8890Sstevel@tonic-gate 	if (name != NULL) {
8900Sstevel@tonic-gate 		DPRINTF(("  name=%s\n", name));
8910Sstevel@tonic-gate 		(void) au_write(event->ae_event_handle, au_to_zonename(name));
8920Sstevel@tonic-gate 	} else {
8930Sstevel@tonic-gate 		DPRINTF(("  Null name\n"));
8945537Sgww 		if (required) {
8950Sstevel@tonic-gate 			(void) au_write(event->ae_event_handle,
8960Sstevel@tonic-gate 			    au_to_zonename(empty));
8975537Sgww 		}
8985537Sgww 	}
8995537Sgww }
9005537Sgww 
9015537Sgww /*
9025537Sgww  * ADT_IN_PEER dummy token
9035537Sgww  */
9045537Sgww 
9055537Sgww /* ARGSUSED */
9065537Sgww static void
adt_to_in_peer(datadef * def,void * p_data,int required,struct adt_event_state * event,char * notUsed)9075537Sgww adt_to_in_peer(datadef *def, void *p_data, int required,
9085537Sgww     struct adt_event_state *event, char *notUsed)
9095537Sgww {
9105537Sgww 	int	sock;
9115537Sgww 	struct sockaddr_in6 peer;
9125537Sgww 	int	peerlen = sizeof (peer);
9135537Sgww 
9145537Sgww 	DPRINTF(("    adt_to_in_peer dd_datatype=%d\n", def->dd_datatype));
9155537Sgww 
9165622Ssabdar 	sock = ((union convert *)p_data)->tfd;
9175537Sgww 
9185537Sgww 	if (sock < 0) {
9195537Sgww 		DPRINTF(("  Socket fd %d\n", sock));
9205622Ssabdar 		if (required) {
9215622Ssabdar 			adt_write_syslog("adt_to_in_peer no required socket",
9225622Ssabdar 			    0);
9235622Ssabdar 		}
9245537Sgww 		return;
9255537Sgww 	}
9265537Sgww 	if (getpeername(sock, (struct sockaddr *)&peer, (socklen_t *)&peerlen)
9275537Sgww 	    < 0) {
9285537Sgww 
9295537Sgww 		adt_write_syslog("adt_to_in_addr getpeername", errno);
9305622Ssabdar 		return;
9315537Sgww 	}
9325537Sgww 	if (peer.sin6_family == AF_INET6) {
9335537Sgww 		(void) au_write(event->ae_event_handle,
9345537Sgww 		    au_to_in_addr_ex(&(peer.sin6_addr)));
9355537Sgww 		(void) au_write(event->ae_event_handle,
9365537Sgww 		    au_to_iport((ushort_t)peer.sin6_port));
9375537Sgww 	} else {
9385537Sgww 		(void) au_write(event->ae_event_handle,
9395537Sgww 		    au_to_in_addr(&(((struct sockaddr_in *)&peer)->sin_addr)));
9405537Sgww 		(void) au_write(event->ae_event_handle,
9415537Sgww 		    au_to_iport(
9425537Sgww 		    (ushort_t)(((struct sockaddr_in *)&peer)->sin_port)));
9430Sstevel@tonic-gate 	}
9440Sstevel@tonic-gate }
9450Sstevel@tonic-gate 
94610645Sgww@eng.sun.com /*
94710645Sgww@eng.sun.com  * ADT_IN_REMOTE dummy token
94810645Sgww@eng.sun.com  *
94910645Sgww@eng.sun.com  * Similar to ADT_IN_PEER except the input is
95010645Sgww@eng.sun.com  * an IP address type (ADT_IPv4 | ADT_IPv6) and an address V4/V6
95110645Sgww@eng.sun.com  */
95210645Sgww@eng.sun.com 
95310645Sgww@eng.sun.com /* ARGSUSED */
95410645Sgww@eng.sun.com static void
adt_to_in_remote(datadef * def,void * p_data,int required,struct adt_event_state * event,char * notUsed)95510645Sgww@eng.sun.com adt_to_in_remote(datadef *def, void *p_data, int required,
95610645Sgww@eng.sun.com     struct adt_event_state *event, char *notUsed)
95710645Sgww@eng.sun.com {
95810645Sgww@eng.sun.com 	int32_t	type;
95910645Sgww@eng.sun.com 
96010645Sgww@eng.sun.com 	DPRINTF(("    adt_to_in_remote dd_datatype=%d\n", def->dd_datatype));
96110645Sgww@eng.sun.com 
96210645Sgww@eng.sun.com 	type = ((union convert *)p_data)->tuint32;
96310645Sgww@eng.sun.com 
96410645Sgww@eng.sun.com 	if (type ==  0) {
96510645Sgww@eng.sun.com 		if (required == 0) {
96610645Sgww@eng.sun.com 			return;
96710645Sgww@eng.sun.com 		}
96810645Sgww@eng.sun.com 		/* required and not specified */
96910645Sgww@eng.sun.com 		adt_write_syslog("adt_to_in_remote required address not "
97010645Sgww@eng.sun.com 		    "specified", 0);
97110645Sgww@eng.sun.com 		type = ADT_IPv4;
97210645Sgww@eng.sun.com 	}
97310645Sgww@eng.sun.com 	p_data = adt_adjust_address(p_data, sizeof (int32_t),
97410645Sgww@eng.sun.com 	    sizeof (uint32_t));
97510645Sgww@eng.sun.com 
97610645Sgww@eng.sun.com 	switch (type) {
97710645Sgww@eng.sun.com 	case ADT_IPv4:
97810645Sgww@eng.sun.com 		(void) au_write(event->ae_event_handle, au_to_in_addr(
97910645Sgww@eng.sun.com 		    (struct in_addr *)&(((union convert *)p_data)->tuint32)));
98010645Sgww@eng.sun.com 		break;
98110645Sgww@eng.sun.com 	case ADT_IPv6:
98210645Sgww@eng.sun.com 		(void) au_write(event->ae_event_handle, au_to_in_addr_ex(
98310645Sgww@eng.sun.com 		    (struct in6_addr *)&(((union convert *)p_data)->tuint32)));
98410645Sgww@eng.sun.com 		break;
98510645Sgww@eng.sun.com 	default:
98610645Sgww@eng.sun.com 		adt_write_syslog("adt_to_in_remote invalid type", EINVAL);
98710645Sgww@eng.sun.com 		return;
98810645Sgww@eng.sun.com 	}
98910645Sgww@eng.sun.com }
99010645Sgww@eng.sun.com 
99110645Sgww@eng.sun.com /*
99210645Sgww@eng.sun.com  * adt_to_iport takes a uint16_t IP port.
99310645Sgww@eng.sun.com  */
99410645Sgww@eng.sun.com 
99510645Sgww@eng.sun.com /* ARGSUSED */
99610645Sgww@eng.sun.com static void
adt_to_iport(datadef * def,void * p_data,int required,struct adt_event_state * event,char * notUsed)99710645Sgww@eng.sun.com adt_to_iport(datadef *def, void *p_data, int required,
99810645Sgww@eng.sun.com     struct adt_event_state *event, char *notUsed)
99910645Sgww@eng.sun.com {
100010645Sgww@eng.sun.com 	ushort_t port;
100110645Sgww@eng.sun.com 
100210645Sgww@eng.sun.com 	DPRINTF(("  adt_to_iport dd_datatype=%d\n", def->dd_datatype));
100310645Sgww@eng.sun.com 
100410645Sgww@eng.sun.com 	port = ((union convert *)p_data)->tuint16;
100510645Sgww@eng.sun.com 
100610645Sgww@eng.sun.com 	if (port == 0) {
100710645Sgww@eng.sun.com 		if (required == 0) {
100810645Sgww@eng.sun.com 			return;
100910645Sgww@eng.sun.com 		}
101010645Sgww@eng.sun.com 		/* required and not specified */
101110645Sgww@eng.sun.com 		adt_write_syslog("adt_to_iport no required port", 0);
101210645Sgww@eng.sun.com 	}
101310645Sgww@eng.sun.com 	(void) au_write(event->ae_event_handle, au_to_iport(port));
101410645Sgww@eng.sun.com 
101510645Sgww@eng.sun.com }
101610645Sgww@eng.sun.com 
10170Sstevel@tonic-gate 
10180Sstevel@tonic-gate /*
10195537Sgww  *	This is a compact table that defines only the tokens that are
10205537Sgww  * actually generated in the adt.xml file.  It can't be a  pure
10215537Sgww  * indexed table because the adt.xml language defines internal extension
10225537Sgww  * tokens for some processing.  VIZ. ADT_CMD_ALT, ADT_AUT_PRIV_* (see
10235537Sgww  * adt_xlate.h), and the -AUT_PATH value.
10240Sstevel@tonic-gate  */
10250Sstevel@tonic-gate 
1026*11893Sgww@eng.sun.com #define	MAX_TOKEN_JMP 21
10270Sstevel@tonic-gate 
10280Sstevel@tonic-gate static struct token_jmp token_table[MAX_TOKEN_JMP] =
10290Sstevel@tonic-gate {
10300Sstevel@tonic-gate 	{AUT_CMD, adt_to_cmd},
10310Sstevel@tonic-gate 	{ADT_CMD_ALT, adt_to_cmd1},
10325537Sgww 	{AUT_FMRI, adt_to_frmi},
10335537Sgww 	{ADT_IN_PEER, adt_to_in_peer},
103410645Sgww@eng.sun.com 	{ADT_IN_REMOTE, adt_to_in_remote},
103510645Sgww@eng.sun.com 	{AUT_IPORT, adt_to_iport},
10365537Sgww 	{AUT_LABEL, adt_to_label},
10375537Sgww 	{AUT_NEWGROUPS, adt_to_newgroups},
10385537Sgww 	{AUT_PATH, adt_to_path},
10395537Sgww 	{-AUT_PATH, adt_to_pathlist},	/* private extension of token values */
10400Sstevel@tonic-gate 	{ADT_AUT_PRIV_L, adt_to_priv_limit},
10410Sstevel@tonic-gate 	{ADT_AUT_PRIV_I, adt_to_priv_inherit},
10420Sstevel@tonic-gate 	{ADT_AUT_PRIV_E, adt_to_priv_effective},
10430Sstevel@tonic-gate 	{AUT_PROCESS, adt_to_process},
10440Sstevel@tonic-gate 	{AUT_RETURN, adt_to_return},
10450Sstevel@tonic-gate 	{AUT_SUBJECT, adt_to_subject},
10460Sstevel@tonic-gate 	{AUT_TEXT, adt_to_text},
10471780Sgww 	{AUT_TID, adt_to_tid},
10480Sstevel@tonic-gate 	{AUT_UAUTH, adt_to_uauth},
1049*11893Sgww@eng.sun.com 	{AUT_USER, adt_to_user},
10500Sstevel@tonic-gate 	{AUT_ZONENAME, adt_to_zonename}
10510Sstevel@tonic-gate };
10525537Sgww 
10530Sstevel@tonic-gate /*
10545537Sgww  *	{AUT_ACL, adt_to_acl},			not used
10555537Sgww  *	{AUT_ARBITRARY, adt_to_arbitrary},	AUT_ARBITRARY is undefined
10565537Sgww  *	{AUT_ARG, adt_to_arg},			not used
10575537Sgww  *	{AUT_ATTR, adt_to_attr},		not used in mountd
10585537Sgww  *	{AUT_XATOM, adt_to_atom},		not used
10595537Sgww  *	{AUT_EXEC_ARGS, adt_to_exec_args},	not used
10605537Sgww  *	{AUT_EXEC_ENV, adt_to_exec_env},	not used
10615537Sgww  *	{AUT_EXIT, adt_to_exit},		obsolete
10625537Sgww  *	{AUT_FILE, adt_to_file},		AUT_FILE is undefined
10635537Sgww  *	{AUT_XCOLORMAP, adt_to_colormap},	not used
10645537Sgww  *	{AUT_XCURSOR, adt_to_cursor},		not used
10655537Sgww  *	{AUT_XFONT, adt_to_font},		not used
10665537Sgww  *	{AUT_XGC, adt_to_gc},			not used
10675537Sgww  *	{AUT_GROUPS, adt_to_groups},		obsolete
10685537Sgww  *	{AUT_HEADER, adt_to_header},		generated by au_close
10695537Sgww  *	{AUT_IP, adt_to_ip},			not used
10705537Sgww  *	{AUT_IPC, adt_to_ipc},			not used
10715537Sgww  *	{AUT_IPC_PERM, adt_to_ipc_perm},	not used
10725537Sgww  *	{AUT_OPAQUE, adt_to_opaque},		not used
10735537Sgww  *	{AUT_XPIXMAP, adt_to_pixmap},		not used
10745537Sgww  *	{AUT_XPROPERTY, adt_to_property},	not used
10755537Sgww  *	{AUT_SEQ, adt_to_seq},			not used
10765537Sgww  *	{AUT_SOCKET, adt_to_socket},		not used
10775537Sgww  *	{AUT_SOCKET_INET, adt_to_socket_inet},  AUT_SOCKET_INET is undefined
10785537Sgww  *	{AUT_TRAILER, adt_to_trailer},		generated by au_close
10795537Sgww  *	{AUT_XCLIENT, adt_to_xclient}		not used
10800Sstevel@tonic-gate  */
10810Sstevel@tonic-gate 
10820Sstevel@tonic-gate /* find function to generate token */
10830Sstevel@tonic-gate 
10840Sstevel@tonic-gate static adt_token_func_t
adt_getTokenFunction(char token_id)10850Sstevel@tonic-gate adt_getTokenFunction(char token_id)
10860Sstevel@tonic-gate {
10870Sstevel@tonic-gate 	int	i;
10880Sstevel@tonic-gate 	struct token_jmp	*p_jmp = token_table;
10890Sstevel@tonic-gate 
10900Sstevel@tonic-gate 	for (i = 0; i < MAX_TOKEN_JMP; i++) {
10910Sstevel@tonic-gate 		if (token_id == p_jmp->jmp_id) {
10920Sstevel@tonic-gate 			return (p_jmp->jmp_to);
10930Sstevel@tonic-gate 		}
10940Sstevel@tonic-gate 		p_jmp++;
10950Sstevel@tonic-gate 	}
10960Sstevel@tonic-gate 	errno = EINVAL;
10970Sstevel@tonic-gate 	return (NULL);
10980Sstevel@tonic-gate }
10990Sstevel@tonic-gate 
11000Sstevel@tonic-gate /*
11010Sstevel@tonic-gate  * adjustAddress -- given the address of data, its size, and the type of
11020Sstevel@tonic-gate  * the next data field, calculate the offset to the next piece of data.
11030Sstevel@tonic-gate  * Depending on the caller, "current" and "next" mean the current pointer
11040Sstevel@tonic-gate  * and the next pointer or the last pointer and the current pointer.
11050Sstevel@tonic-gate  */
11060Sstevel@tonic-gate void *
adt_adjust_address(void * current_address,size_t current_size,size_t next_size)11070Sstevel@tonic-gate adt_adjust_address(void *current_address, size_t current_size,
11080Sstevel@tonic-gate     size_t next_size)
11090Sstevel@tonic-gate {
11100Sstevel@tonic-gate 	ptrdiff_t adjustment;
11110Sstevel@tonic-gate 	ptrdiff_t remainder;
11120Sstevel@tonic-gate 
11130Sstevel@tonic-gate 	adjustment = (size_t)current_address + current_size;
11140Sstevel@tonic-gate 
11150Sstevel@tonic-gate 	if (next_size) {
11160Sstevel@tonic-gate 		remainder = adjustment % next_size;
11170Sstevel@tonic-gate 		if (remainder != 0)
11180Sstevel@tonic-gate 			adjustment += next_size - remainder;
11190Sstevel@tonic-gate 	}
11200Sstevel@tonic-gate 	return ((char *)adjustment);
11210Sstevel@tonic-gate }
1122