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