1*0Sstevel@tonic-gate /* 2*0Sstevel@tonic-gate * CDDL HEADER START 3*0Sstevel@tonic-gate * 4*0Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*0Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*0Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*0Sstevel@tonic-gate * with the License. 8*0Sstevel@tonic-gate * 9*0Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*0Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*0Sstevel@tonic-gate * See the License for the specific language governing permissions 12*0Sstevel@tonic-gate * and limitations under the License. 13*0Sstevel@tonic-gate * 14*0Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*0Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*0Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*0Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*0Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*0Sstevel@tonic-gate * 20*0Sstevel@tonic-gate * CDDL HEADER END 21*0Sstevel@tonic-gate */ 22*0Sstevel@tonic-gate /* 23*0Sstevel@tonic-gate * adt_token.c 24*0Sstevel@tonic-gate * 25*0Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 26*0Sstevel@tonic-gate * Use is subject to license terms. 27*0Sstevel@tonic-gate * 28*0Sstevel@tonic-gate * This file does not provide any user callable functions. See adt.c 29*0Sstevel@tonic-gate */ 30*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 31*0Sstevel@tonic-gate 32*0Sstevel@tonic-gate #include <bsm/adt.h> 33*0Sstevel@tonic-gate #include <bsm/adt_event.h> 34*0Sstevel@tonic-gate #include <bsm/audit.h> 35*0Sstevel@tonic-gate #include <adt_xlate.h> 36*0Sstevel@tonic-gate #include <assert.h> 37*0Sstevel@tonic-gate #include <netdb.h> 38*0Sstevel@tonic-gate #include <priv.h> 39*0Sstevel@tonic-gate #include <string.h> 40*0Sstevel@tonic-gate #include <strings.h> 41*0Sstevel@tonic-gate #include <sys/priv_names.h> 42*0Sstevel@tonic-gate #include <sys/types.h> 43*0Sstevel@tonic-gate #include <sys/vnode.h> 44*0Sstevel@tonic-gate #include <time.h> 45*0Sstevel@tonic-gate #include <unistd.h> 46*0Sstevel@tonic-gate 47*0Sstevel@tonic-gate #ifdef C2_DEBUG 48*0Sstevel@tonic-gate #define DPRINTF(x) {printf x; } 49*0Sstevel@tonic-gate #define DFLUSH fflush(stdout); 50*0Sstevel@tonic-gate #else 51*0Sstevel@tonic-gate #define DPRINTF(x) 52*0Sstevel@tonic-gate #define DFLUSH 53*0Sstevel@tonic-gate #endif 54*0Sstevel@tonic-gate 55*0Sstevel@tonic-gate static adt_token_func_t adt_getTokenFunction(char); 56*0Sstevel@tonic-gate 57*0Sstevel@tonic-gate static char *empty = ""; 58*0Sstevel@tonic-gate 59*0Sstevel@tonic-gate /* 60*0Sstevel@tonic-gate * call adt_token_open() first and adt_token_close() last. 61*0Sstevel@tonic-gate * 62*0Sstevel@tonic-gate * au_open is sort of broken; it returns a -1 when out of memory that 63*0Sstevel@tonic-gate * you're supposed to ignore; au_write and au_close return without 64*0Sstevel@tonic-gate * doing anything when a -1 is passed. This code sort of follows the 65*0Sstevel@tonic-gate * au_open model except that it calls syslog to indicate underlying 66*0Sstevel@tonic-gate * brokenness. Other than that, -1 is ignored. 67*0Sstevel@tonic-gate */ 68*0Sstevel@tonic-gate 69*0Sstevel@tonic-gate void 70*0Sstevel@tonic-gate adt_token_open(struct adt_event_state *event) 71*0Sstevel@tonic-gate { 72*0Sstevel@tonic-gate static int have_syslogged = 0; 73*0Sstevel@tonic-gate 74*0Sstevel@tonic-gate event->ae_event_handle = au_open(); 75*0Sstevel@tonic-gate if (event->ae_event_handle < 0) { 76*0Sstevel@tonic-gate if (!have_syslogged) { 77*0Sstevel@tonic-gate adt_write_syslog("au_open failed", ENOMEM); 78*0Sstevel@tonic-gate have_syslogged = 1; 79*0Sstevel@tonic-gate } 80*0Sstevel@tonic-gate } 81*0Sstevel@tonic-gate else 82*0Sstevel@tonic-gate have_syslogged = 0; 83*0Sstevel@tonic-gate } 84*0Sstevel@tonic-gate 85*0Sstevel@tonic-gate /* 86*0Sstevel@tonic-gate * call generate_token for each token in the order you want the tokens 87*0Sstevel@tonic-gate * generated. 88*0Sstevel@tonic-gate */ 89*0Sstevel@tonic-gate 90*0Sstevel@tonic-gate void 91*0Sstevel@tonic-gate adt_generate_token(struct entry *p_entry, void *p_data, 92*0Sstevel@tonic-gate struct adt_event_state *event) 93*0Sstevel@tonic-gate { 94*0Sstevel@tonic-gate adt_token_func_t p_func; 95*0Sstevel@tonic-gate 96*0Sstevel@tonic-gate assert((p_entry != NULL) && (p_data != NULL) && (event != NULL)); 97*0Sstevel@tonic-gate 98*0Sstevel@tonic-gate p_func = adt_getTokenFunction(p_entry->en_token_id); 99*0Sstevel@tonic-gate assert(p_func != NULL); 100*0Sstevel@tonic-gate 101*0Sstevel@tonic-gate DPRINTF(("p_entry=%08X, p_data=%08X, offset=%X, msgFmt=%X\n", 102*0Sstevel@tonic-gate p_entry, p_data, p_entry->en_offset, p_entry->en_msg_format)); 103*0Sstevel@tonic-gate DFLUSH 104*0Sstevel@tonic-gate 105*0Sstevel@tonic-gate (*p_func)(p_entry->en_type_def, 106*0Sstevel@tonic-gate (char *)p_data + p_entry->en_offset, p_entry->en_required, event, 107*0Sstevel@tonic-gate p_entry->en_msg_format); 108*0Sstevel@tonic-gate } 109*0Sstevel@tonic-gate 110*0Sstevel@tonic-gate /* call this last */ 111*0Sstevel@tonic-gate 112*0Sstevel@tonic-gate void 113*0Sstevel@tonic-gate adt_token_close(struct adt_event_state *event) 114*0Sstevel@tonic-gate { 115*0Sstevel@tonic-gate int rc; 116*0Sstevel@tonic-gate 117*0Sstevel@tonic-gate rc = au_close(event->ae_event_handle, AU_TO_WRITE, 118*0Sstevel@tonic-gate event->ae_internal_id); 119*0Sstevel@tonic-gate if (rc < 0) 120*0Sstevel@tonic-gate adt_write_syslog("au_close failed", errno); 121*0Sstevel@tonic-gate } 122*0Sstevel@tonic-gate 123*0Sstevel@tonic-gate /* 124*0Sstevel@tonic-gate * one function per token -- see the jump table at the end of file 125*0Sstevel@tonic-gate */ 126*0Sstevel@tonic-gate 127*0Sstevel@tonic-gate /* ARGSUSED */ 128*0Sstevel@tonic-gate static void 129*0Sstevel@tonic-gate adt_to_return(datadef *def, void *p_data, int required, 130*0Sstevel@tonic-gate struct adt_event_state *event, char *notUsed) 131*0Sstevel@tonic-gate { 132*0Sstevel@tonic-gate 133*0Sstevel@tonic-gate #ifdef _LP64 134*0Sstevel@tonic-gate (void) au_write(event->ae_event_handle, 135*0Sstevel@tonic-gate au_to_return64((int64_t)event->ae_rc, event->ae_type)); 136*0Sstevel@tonic-gate #else 137*0Sstevel@tonic-gate (void) au_write(event->ae_event_handle, 138*0Sstevel@tonic-gate au_to_return32((int32_t)event->ae_rc, event->ae_type)); 139*0Sstevel@tonic-gate #endif 140*0Sstevel@tonic-gate } 141*0Sstevel@tonic-gate 142*0Sstevel@tonic-gate /* 143*0Sstevel@tonic-gate * AUT_CMD 144*0Sstevel@tonic-gate * 145*0Sstevel@tonic-gate * the command line is described with argc and argv and the environment 146*0Sstevel@tonic-gate * with envp. The envp list is NULL terminated and has no separate 147*0Sstevel@tonic-gate * counter; envp will be a NULL list unless the AUDIT_ARGE policy is 148*0Sstevel@tonic-gate * set. 149*0Sstevel@tonic-gate */ 150*0Sstevel@tonic-gate 151*0Sstevel@tonic-gate /* ARGSUSED */ 152*0Sstevel@tonic-gate static void 153*0Sstevel@tonic-gate adt_to_cmd(datadef *def, void *p_data, int required, 154*0Sstevel@tonic-gate struct adt_event_state *event, char *notUsed) 155*0Sstevel@tonic-gate { 156*0Sstevel@tonic-gate struct adt_internal_state *sp = event->ae_session; 157*0Sstevel@tonic-gate int argc; 158*0Sstevel@tonic-gate char **argv; 159*0Sstevel@tonic-gate char **envp = NULL; 160*0Sstevel@tonic-gate 161*0Sstevel@tonic-gate argc = ((union convert *)p_data)->tint; 162*0Sstevel@tonic-gate p_data = adt_adjust_address(p_data, sizeof (int), sizeof (char **)); 163*0Sstevel@tonic-gate argv = ((union convert *)p_data)->tchar2star; 164*0Sstevel@tonic-gate p_data = adt_adjust_address(p_data, sizeof (char **), sizeof (char **)); 165*0Sstevel@tonic-gate 166*0Sstevel@tonic-gate if (sp->as_kernel_audit_policy & AUDIT_ARGE) 167*0Sstevel@tonic-gate envp = ((union convert *)p_data)->tchar2star; 168*0Sstevel@tonic-gate 169*0Sstevel@tonic-gate (void) au_write(event->ae_event_handle, 170*0Sstevel@tonic-gate au_to_cmd(argc, argv, envp)); 171*0Sstevel@tonic-gate } 172*0Sstevel@tonic-gate 173*0Sstevel@tonic-gate /* 174*0Sstevel@tonic-gate * special case of AUT_CMD with 1 argument that is 175*0Sstevel@tonic-gate * a string showing the whole command and no envp 176*0Sstevel@tonic-gate */ 177*0Sstevel@tonic-gate /* ARGSUSED */ 178*0Sstevel@tonic-gate static void 179*0Sstevel@tonic-gate adt_to_cmd1(datadef *def, void *p_data, int required, 180*0Sstevel@tonic-gate struct adt_event_state *event, char *notUsed) 181*0Sstevel@tonic-gate { 182*0Sstevel@tonic-gate char *string; 183*0Sstevel@tonic-gate 184*0Sstevel@tonic-gate string = ((union convert *)p_data)->tcharstar; 185*0Sstevel@tonic-gate 186*0Sstevel@tonic-gate if (string == NULL) { 187*0Sstevel@tonic-gate if (required) 188*0Sstevel@tonic-gate string = empty; 189*0Sstevel@tonic-gate else 190*0Sstevel@tonic-gate return; 191*0Sstevel@tonic-gate } 192*0Sstevel@tonic-gate /* argc is hardcoded as 1 */ 193*0Sstevel@tonic-gate (void) au_write(event->ae_event_handle, au_to_cmd(1, &string, 194*0Sstevel@tonic-gate NULL)); 195*0Sstevel@tonic-gate } 196*0Sstevel@tonic-gate 197*0Sstevel@tonic-gate /* 198*0Sstevel@tonic-gate * adt_to_tid -- generic address (ip is only one defined at present) 199*0Sstevel@tonic-gate * input: 200*0Sstevel@tonic-gate * terminal type: ADT_IPv4, ADT_IPv6... 201*0Sstevel@tonic-gate * case: ADT_IPv4 or ADT_IPv6... 202*0Sstevel@tonic-gate * ip type 203*0Sstevel@tonic-gate * remote port 204*0Sstevel@tonic-gate * local port 205*0Sstevel@tonic-gate * address 206*0Sstevel@tonic-gate * case: not defined... 207*0Sstevel@tonic-gate */ 208*0Sstevel@tonic-gate /* ARGSUSED */ 209*0Sstevel@tonic-gate static void 210*0Sstevel@tonic-gate adt_to_tid(datadef *def, void *p_data, int required, 211*0Sstevel@tonic-gate struct adt_event_state *event, char *notUsed) 212*0Sstevel@tonic-gate { 213*0Sstevel@tonic-gate au_generic_tid_t tid; 214*0Sstevel@tonic-gate uint32_t type; 215*0Sstevel@tonic-gate au_ip_t *ip; 216*0Sstevel@tonic-gate 217*0Sstevel@tonic-gate type = ((union convert *)p_data)->tuint32; 218*0Sstevel@tonic-gate 219*0Sstevel@tonic-gate switch (type) { 220*0Sstevel@tonic-gate case ADT_IPv4: 221*0Sstevel@tonic-gate case ADT_IPv6: 222*0Sstevel@tonic-gate p_data = adt_adjust_address(p_data, sizeof (uint32_t), 223*0Sstevel@tonic-gate sizeof (uint32_t)); 224*0Sstevel@tonic-gate 225*0Sstevel@tonic-gate tid.gt_type = AU_IPADR; 226*0Sstevel@tonic-gate ip = &(tid.gt_adr.at_ip); 227*0Sstevel@tonic-gate 228*0Sstevel@tonic-gate ip->at_type = (type == ADT_IPv4) ? 229*0Sstevel@tonic-gate AU_IPv4 : AU_IPv6; 230*0Sstevel@tonic-gate 231*0Sstevel@tonic-gate ip->at_r_port = ((union convert *)p_data)->tuint16; 232*0Sstevel@tonic-gate p_data = adt_adjust_address(p_data, sizeof (uint16_t), 233*0Sstevel@tonic-gate sizeof (uint16_t)); 234*0Sstevel@tonic-gate 235*0Sstevel@tonic-gate ip->at_l_port = ((union convert *)p_data)->tuint16; 236*0Sstevel@tonic-gate 237*0Sstevel@tonic-gate /* arg3 is for the array element, not the array size */ 238*0Sstevel@tonic-gate p_data = adt_adjust_address(p_data, sizeof (uint16_t), 239*0Sstevel@tonic-gate sizeof (uint32_t)); 240*0Sstevel@tonic-gate 241*0Sstevel@tonic-gate (void) memcpy(ip->at_addr, p_data, ip->at_type); 242*0Sstevel@tonic-gate break; 243*0Sstevel@tonic-gate default: 244*0Sstevel@tonic-gate adt_write_syslog("Invalid terminal id type", EINVAL); 245*0Sstevel@tonic-gate return; 246*0Sstevel@tonic-gate } 247*0Sstevel@tonic-gate (void) au_write(event->ae_event_handle, au_to_tid(&tid)); 248*0Sstevel@tonic-gate } 249*0Sstevel@tonic-gate 250*0Sstevel@tonic-gate /* 251*0Sstevel@tonic-gate * au_to_newgroups takes a length and an array of gids 252*0Sstevel@tonic-gate * as input. The input to adt_to_newgroups is a length 253*0Sstevel@tonic-gate * and a pointer to an array of gids. 254*0Sstevel@tonic-gate */ 255*0Sstevel@tonic-gate 256*0Sstevel@tonic-gate /* ARGSUSED */ 257*0Sstevel@tonic-gate static void 258*0Sstevel@tonic-gate adt_to_newgroups(datadef *def, void *p_data, int required, 259*0Sstevel@tonic-gate struct adt_event_state *event, char *notUsed) 260*0Sstevel@tonic-gate { 261*0Sstevel@tonic-gate int n; 262*0Sstevel@tonic-gate gid_t *groups; 263*0Sstevel@tonic-gate 264*0Sstevel@tonic-gate n = ((union convert *)p_data)->tint; 265*0Sstevel@tonic-gate if (n < 1) { 266*0Sstevel@tonic-gate if (required) { 267*0Sstevel@tonic-gate n = 0; /* in case negative n was passed */ 268*0Sstevel@tonic-gate } else 269*0Sstevel@tonic-gate return; 270*0Sstevel@tonic-gate } 271*0Sstevel@tonic-gate p_data = adt_adjust_address(p_data, sizeof (int), sizeof (int32_t *)); 272*0Sstevel@tonic-gate 273*0Sstevel@tonic-gate groups = ((union convert *)p_data)->tgidstar; 274*0Sstevel@tonic-gate 275*0Sstevel@tonic-gate (void) au_write(event->ae_event_handle, au_to_newgroups(n, groups)); 276*0Sstevel@tonic-gate } 277*0Sstevel@tonic-gate 278*0Sstevel@tonic-gate /* ARGSUSED */ 279*0Sstevel@tonic-gate static void 280*0Sstevel@tonic-gate adt_to_path(datadef *def, void *p_data, int required, 281*0Sstevel@tonic-gate struct adt_event_state *event, char *notUsed) 282*0Sstevel@tonic-gate { 283*0Sstevel@tonic-gate char *path; 284*0Sstevel@tonic-gate 285*0Sstevel@tonic-gate path = ((union convert *)p_data)->tcharstar; 286*0Sstevel@tonic-gate 287*0Sstevel@tonic-gate if (path != NULL) { 288*0Sstevel@tonic-gate DPRINTF((" path=%s\n", path)); 289*0Sstevel@tonic-gate (void) au_write(event->ae_event_handle, au_to_path(path)); 290*0Sstevel@tonic-gate } else { 291*0Sstevel@tonic-gate DPRINTF((" Null path\n")); 292*0Sstevel@tonic-gate if (required) 293*0Sstevel@tonic-gate (void) au_write(event->ae_event_handle, 294*0Sstevel@tonic-gate au_to_path(empty)); 295*0Sstevel@tonic-gate } 296*0Sstevel@tonic-gate } 297*0Sstevel@tonic-gate 298*0Sstevel@tonic-gate /* 299*0Sstevel@tonic-gate * dummy token id: AUT_PATHLIST 300*0Sstevel@tonic-gate */ 301*0Sstevel@tonic-gate 302*0Sstevel@tonic-gate /* ARGSUSED */ 303*0Sstevel@tonic-gate static void 304*0Sstevel@tonic-gate adt_to_pathlist(datadef *def, void *p_data, int required, 305*0Sstevel@tonic-gate struct adt_event_state *event, char *notUsed) 306*0Sstevel@tonic-gate { 307*0Sstevel@tonic-gate char *path; 308*0Sstevel@tonic-gate char *working_buf; 309*0Sstevel@tonic-gate char *pathlist; 310*0Sstevel@tonic-gate char *last_str; 311*0Sstevel@tonic-gate 312*0Sstevel@tonic-gate pathlist = ((union convert *)p_data)->tcharstar; 313*0Sstevel@tonic-gate 314*0Sstevel@tonic-gate if (pathlist != NULL) { 315*0Sstevel@tonic-gate working_buf = strdup(pathlist); 316*0Sstevel@tonic-gate if (working_buf == NULL) { 317*0Sstevel@tonic-gate adt_write_syslog("audit failure", errno); 318*0Sstevel@tonic-gate if (required) 319*0Sstevel@tonic-gate (void) au_write(event->ae_event_handle, 320*0Sstevel@tonic-gate au_to_path(empty)); 321*0Sstevel@tonic-gate return; 322*0Sstevel@tonic-gate } 323*0Sstevel@tonic-gate for (path = strtok_r(working_buf, " ", &last_str); 324*0Sstevel@tonic-gate path; path = strtok_r(NULL, " ", &last_str)) { 325*0Sstevel@tonic-gate DPRINTF((" path=%s\n", path)); 326*0Sstevel@tonic-gate (void) au_write(event->ae_event_handle, 327*0Sstevel@tonic-gate au_to_path(path)); 328*0Sstevel@tonic-gate } 329*0Sstevel@tonic-gate } else { 330*0Sstevel@tonic-gate DPRINTF((" Null path list\n")); 331*0Sstevel@tonic-gate if (required) 332*0Sstevel@tonic-gate (void) au_write(event->ae_event_handle, 333*0Sstevel@tonic-gate au_to_path(empty)); 334*0Sstevel@tonic-gate } 335*0Sstevel@tonic-gate } 336*0Sstevel@tonic-gate 337*0Sstevel@tonic-gate /* 338*0Sstevel@tonic-gate * AUT_PRIV 339*0Sstevel@tonic-gate */ 340*0Sstevel@tonic-gate 341*0Sstevel@tonic-gate /* ARGSUSED */ 342*0Sstevel@tonic-gate static void 343*0Sstevel@tonic-gate adt_to_priv(datadef *def, void *p_data, int required, 344*0Sstevel@tonic-gate struct adt_event_state *event, const char *priv_type) 345*0Sstevel@tonic-gate { 346*0Sstevel@tonic-gate priv_set_t *privilege; 347*0Sstevel@tonic-gate 348*0Sstevel@tonic-gate privilege = ((union convert *)p_data)->tprivstar; 349*0Sstevel@tonic-gate 350*0Sstevel@tonic-gate if (privilege != NULL) { 351*0Sstevel@tonic-gate (void) au_write(event->ae_event_handle, 352*0Sstevel@tonic-gate au_to_privset(priv_type, privilege)); 353*0Sstevel@tonic-gate } else { 354*0Sstevel@tonic-gate if (required) { 355*0Sstevel@tonic-gate DPRINTF((" Null privilege\n")); 356*0Sstevel@tonic-gate (void) au_write(event->ae_event_handle, 357*0Sstevel@tonic-gate au_to_privset(empty, NULL)); 358*0Sstevel@tonic-gate } 359*0Sstevel@tonic-gate } 360*0Sstevel@tonic-gate } 361*0Sstevel@tonic-gate 362*0Sstevel@tonic-gate /* 363*0Sstevel@tonic-gate * -AUT_PRIV_L AUT_PRIV for a limit set 364*0Sstevel@tonic-gate */ 365*0Sstevel@tonic-gate 366*0Sstevel@tonic-gate /* ARGSUSED */ 367*0Sstevel@tonic-gate static void 368*0Sstevel@tonic-gate adt_to_priv_limit(datadef *def, void *p_data, int required, 369*0Sstevel@tonic-gate struct adt_event_state *event, char *notUsed) 370*0Sstevel@tonic-gate { 371*0Sstevel@tonic-gate adt_to_priv(def, p_data, required, event, PRIV_LIMIT); 372*0Sstevel@tonic-gate } 373*0Sstevel@tonic-gate 374*0Sstevel@tonic-gate /* 375*0Sstevel@tonic-gate * -AUT_PRIV_I AUT_PRIV for an inherit set 376*0Sstevel@tonic-gate */ 377*0Sstevel@tonic-gate 378*0Sstevel@tonic-gate /* ARGSUSED */ 379*0Sstevel@tonic-gate static void 380*0Sstevel@tonic-gate adt_to_priv_inherit(datadef *def, void *p_data, int required, 381*0Sstevel@tonic-gate struct adt_event_state *event, char *notUsed) 382*0Sstevel@tonic-gate { 383*0Sstevel@tonic-gate adt_to_priv(def, p_data, required, event, PRIV_INHERITABLE); 384*0Sstevel@tonic-gate } 385*0Sstevel@tonic-gate 386*0Sstevel@tonic-gate /* ARGSUSED */ 387*0Sstevel@tonic-gate static void 388*0Sstevel@tonic-gate adt_to_priv_effective(datadef *def, void *p_data, int required, 389*0Sstevel@tonic-gate struct adt_event_state *event, char *notUsed) 390*0Sstevel@tonic-gate { 391*0Sstevel@tonic-gate adt_to_priv(def, p_data, required, event, PRIV_EFFECTIVE); 392*0Sstevel@tonic-gate } 393*0Sstevel@tonic-gate 394*0Sstevel@tonic-gate static void 395*0Sstevel@tonic-gate getCharacteristics(struct auditpinfo_addr *info, pid_t *pid) 396*0Sstevel@tonic-gate { 397*0Sstevel@tonic-gate int rc; 398*0Sstevel@tonic-gate 399*0Sstevel@tonic-gate if (*pid == 0) /* getpinfo for this pid */ 400*0Sstevel@tonic-gate info->ap_pid = getpid(); 401*0Sstevel@tonic-gate else 402*0Sstevel@tonic-gate info->ap_pid = *pid; 403*0Sstevel@tonic-gate 404*0Sstevel@tonic-gate rc = auditon(A_GETPINFO_ADDR, (caddr_t)info, 405*0Sstevel@tonic-gate sizeof (struct auditpinfo_addr)); 406*0Sstevel@tonic-gate if (rc == -1) { 407*0Sstevel@tonic-gate info->ap_auid = AU_NOAUDITID; 408*0Sstevel@tonic-gate info->ap_asid = 0; 409*0Sstevel@tonic-gate (void) memset((void *)&(info->ap_termid), 0, 410*0Sstevel@tonic-gate sizeof (au_tid_addr_t)); 411*0Sstevel@tonic-gate info->ap_termid.at_type = AU_IPv4; 412*0Sstevel@tonic-gate } 413*0Sstevel@tonic-gate } 414*0Sstevel@tonic-gate 415*0Sstevel@tonic-gate /* 416*0Sstevel@tonic-gate * AUT_PROCESS 417*0Sstevel@tonic-gate * 418*0Sstevel@tonic-gate */ 419*0Sstevel@tonic-gate 420*0Sstevel@tonic-gate /* ARGSUSED */ 421*0Sstevel@tonic-gate static void 422*0Sstevel@tonic-gate adt_to_process(datadef *def, void *p_data, int required, 423*0Sstevel@tonic-gate struct adt_event_state *event, char *notUsed) 424*0Sstevel@tonic-gate { 425*0Sstevel@tonic-gate au_id_t auid; 426*0Sstevel@tonic-gate uid_t euid; 427*0Sstevel@tonic-gate gid_t egid; 428*0Sstevel@tonic-gate uid_t ruid; 429*0Sstevel@tonic-gate gid_t rgid; 430*0Sstevel@tonic-gate pid_t pid; 431*0Sstevel@tonic-gate au_asid_t sid; 432*0Sstevel@tonic-gate au_tid_addr_t *tid; 433*0Sstevel@tonic-gate struct auditpinfo_addr info; 434*0Sstevel@tonic-gate 435*0Sstevel@tonic-gate auid = ((union convert *)p_data)->tuid; 436*0Sstevel@tonic-gate p_data = adt_adjust_address(p_data, sizeof (uid_t), sizeof (uid_t)); 437*0Sstevel@tonic-gate euid = ((union convert *)p_data)->tuid; 438*0Sstevel@tonic-gate p_data = adt_adjust_address(p_data, sizeof (uid_t), sizeof (gid_t)); 439*0Sstevel@tonic-gate egid = ((union convert *)p_data)->tgid; 440*0Sstevel@tonic-gate p_data = adt_adjust_address(p_data, sizeof (gid_t), sizeof (uid_t)); 441*0Sstevel@tonic-gate ruid = ((union convert *)p_data)->tuid; 442*0Sstevel@tonic-gate p_data = adt_adjust_address(p_data, sizeof (uid_t), sizeof (gid_t)); 443*0Sstevel@tonic-gate rgid = ((union convert *)p_data)->tgid; 444*0Sstevel@tonic-gate p_data = adt_adjust_address(p_data, sizeof (gid_t), sizeof (pid_t)); 445*0Sstevel@tonic-gate pid = ((union convert *)p_data)->tpid; 446*0Sstevel@tonic-gate p_data = adt_adjust_address(p_data, sizeof (pid_t), sizeof (uint32_t)); 447*0Sstevel@tonic-gate sid = ((union convert *)p_data)->tuint32; 448*0Sstevel@tonic-gate p_data = adt_adjust_address(p_data, sizeof (uint32_t), 449*0Sstevel@tonic-gate sizeof (au_tid_addr_t *)); 450*0Sstevel@tonic-gate tid = ((union convert *)p_data)->ttermid; 451*0Sstevel@tonic-gate 452*0Sstevel@tonic-gate getCharacteristics(&info, &pid); 453*0Sstevel@tonic-gate 454*0Sstevel@tonic-gate if (auid == AU_NOAUDITID) 455*0Sstevel@tonic-gate auid = info.ap_auid; 456*0Sstevel@tonic-gate 457*0Sstevel@tonic-gate if (euid == AU_NOAUDITID) 458*0Sstevel@tonic-gate euid = geteuid(); 459*0Sstevel@tonic-gate 460*0Sstevel@tonic-gate if (egid == AU_NOAUDITID) 461*0Sstevel@tonic-gate egid = getegid(); 462*0Sstevel@tonic-gate 463*0Sstevel@tonic-gate if (ruid == AU_NOAUDITID) 464*0Sstevel@tonic-gate ruid = getuid(); 465*0Sstevel@tonic-gate 466*0Sstevel@tonic-gate if (rgid == AU_NOAUDITID) 467*0Sstevel@tonic-gate rgid = getgid(); 468*0Sstevel@tonic-gate 469*0Sstevel@tonic-gate if (tid == NULL) 470*0Sstevel@tonic-gate tid = &(info.ap_termid); 471*0Sstevel@tonic-gate 472*0Sstevel@tonic-gate if (sid == 0) 473*0Sstevel@tonic-gate sid = info.ap_asid; 474*0Sstevel@tonic-gate 475*0Sstevel@tonic-gate if (pid == 0) 476*0Sstevel@tonic-gate pid = info.ap_pid; 477*0Sstevel@tonic-gate 478*0Sstevel@tonic-gate (void) au_write(event->ae_event_handle, 479*0Sstevel@tonic-gate au_to_process_ex(auid, euid, egid, ruid, rgid, pid, sid, tid)); 480*0Sstevel@tonic-gate } 481*0Sstevel@tonic-gate 482*0Sstevel@tonic-gate /* 483*0Sstevel@tonic-gate * generate a subject token and, depending on audit policy, a 484*0Sstevel@tonic-gate * group token. For TSOL, this is probably the right place 485*0Sstevel@tonic-gate * to generate a label token. Alternatively, a TSOL token could 486*0Sstevel@tonic-gate * be defined in adt.xml with 'opt="none". 487*0Sstevel@tonic-gate * 488*0Sstevel@tonic-gate * The required flag does not apply here. 489*0Sstevel@tonic-gate * 490*0Sstevel@tonic-gate * Non-attributable records are indicated by an auid of AU_NOAUDITID; 491*0Sstevel@tonic-gate * no subject token or group token is generated for a non-attributable 492*0Sstevel@tonic-gate * record. 493*0Sstevel@tonic-gate */ 494*0Sstevel@tonic-gate 495*0Sstevel@tonic-gate /* ARGSUSED */ 496*0Sstevel@tonic-gate static void 497*0Sstevel@tonic-gate adt_to_subject(datadef *def, void *p_data, int required, 498*0Sstevel@tonic-gate struct adt_event_state *event, char *notUsed) 499*0Sstevel@tonic-gate { 500*0Sstevel@tonic-gate struct adt_internal_state *sp = event->ae_session; 501*0Sstevel@tonic-gate 502*0Sstevel@tonic-gate if (sp->as_info.ai_auid == AU_NOAUDITID) 503*0Sstevel@tonic-gate return; 504*0Sstevel@tonic-gate 505*0Sstevel@tonic-gate assert(sp->as_have_user_data == ADT_HAVE_ALL); 506*0Sstevel@tonic-gate 507*0Sstevel@tonic-gate (void) au_write(event->ae_event_handle, 508*0Sstevel@tonic-gate au_to_subject_ex(sp->as_info.ai_auid, 509*0Sstevel@tonic-gate sp->as_euid, sp->as_egid, sp->as_ruid, sp->as_rgid, 510*0Sstevel@tonic-gate getpid(), sp->as_info.ai_asid, 511*0Sstevel@tonic-gate &(sp->as_info.ai_termid))); 512*0Sstevel@tonic-gate /* 513*0Sstevel@tonic-gate * If AUDIT_GROUP is set, a groups token must be output. 514*0Sstevel@tonic-gate * In a session model, the groups list is undefined, so output an 515*0Sstevel@tonic-gate * empty list. In a process model, ship it! 516*0Sstevel@tonic-gate */ 517*0Sstevel@tonic-gate if (sp->as_kernel_audit_policy & AUDIT_GROUP) { 518*0Sstevel@tonic-gate int group_count; 519*0Sstevel@tonic-gate gid_t grouplist[NGROUPS_MAX]; 520*0Sstevel@tonic-gate 521*0Sstevel@tonic-gate (void) memset(grouplist, 0, sizeof (grouplist)); 522*0Sstevel@tonic-gate if (sp->as_session_model == ADT_PROCESS_MODEL) { 523*0Sstevel@tonic-gate if ((group_count = getgroups(NGROUPS_UMAX, 524*0Sstevel@tonic-gate grouplist))) { 525*0Sstevel@tonic-gate (void) au_write(event->ae_event_handle, 526*0Sstevel@tonic-gate au_to_newgroups(group_count, grouplist)); 527*0Sstevel@tonic-gate } 528*0Sstevel@tonic-gate } else { /* consider deleting this null output */ 529*0Sstevel@tonic-gate (void) au_write(event->ae_event_handle, 530*0Sstevel@tonic-gate au_to_newgroups(0, grouplist)); 531*0Sstevel@tonic-gate } 532*0Sstevel@tonic-gate } 533*0Sstevel@tonic-gate } 534*0Sstevel@tonic-gate 535*0Sstevel@tonic-gate /* 536*0Sstevel@tonic-gate * adt_to_text() 537*0Sstevel@tonic-gate * 538*0Sstevel@tonic-gate * The format string, normally null, is sort of a wrapper around 539*0Sstevel@tonic-gate * the input. adt_write_text() is a wrapper around au_write that 540*0Sstevel@tonic-gate * handles the format string 541*0Sstevel@tonic-gate * 542*0Sstevel@tonic-gate */ 543*0Sstevel@tonic-gate #define TEXT_LENGTH 49 544*0Sstevel@tonic-gate 545*0Sstevel@tonic-gate static void 546*0Sstevel@tonic-gate adt_write_text(int handle, char *main_text, const char *format) 547*0Sstevel@tonic-gate { 548*0Sstevel@tonic-gate char buffer[TEXT_LENGTH * 2 + 1]; 549*0Sstevel@tonic-gate 550*0Sstevel@tonic-gate if (format == NULL) 551*0Sstevel@tonic-gate (void) au_write(handle, au_to_text(main_text)); 552*0Sstevel@tonic-gate else { 553*0Sstevel@tonic-gate (void) snprintf(buffer, TEXT_LENGTH * 2, format, main_text); 554*0Sstevel@tonic-gate (void) au_write(handle, au_to_text(buffer)); 555*0Sstevel@tonic-gate } 556*0Sstevel@tonic-gate } 557*0Sstevel@tonic-gate 558*0Sstevel@tonic-gate static void 559*0Sstevel@tonic-gate adt_to_text(datadef *def, void *p_data, int required, 560*0Sstevel@tonic-gate struct adt_event_state *event, char *format) 561*0Sstevel@tonic-gate { 562*0Sstevel@tonic-gate static int have_syslogged = 0; 563*0Sstevel@tonic-gate char *string; 564*0Sstevel@tonic-gate char **string_list; 565*0Sstevel@tonic-gate char buffer[TEXT_LENGTH + 1]; 566*0Sstevel@tonic-gate time_t date; 567*0Sstevel@tonic-gate struct tm tm; 568*0Sstevel@tonic-gate uint32_t *int_list; 569*0Sstevel@tonic-gate int written, available; 570*0Sstevel@tonic-gate int i, arrayCount; 571*0Sstevel@tonic-gate struct msg_text *list; 572*0Sstevel@tonic-gate int list_index; 573*0Sstevel@tonic-gate 574*0Sstevel@tonic-gate DPRINTF((" adt_to_text dd_datatype=%d\n", def->dd_datatype)); 575*0Sstevel@tonic-gate switch (def->dd_datatype) { 576*0Sstevel@tonic-gate case ADT_DATE: 577*0Sstevel@tonic-gate /* 578*0Sstevel@tonic-gate * Consider creating a separate token type for dates 579*0Sstevel@tonic-gate * -- store as longs and format them in praudit. 580*0Sstevel@tonic-gate * For now, a date is input as a time_t and output as 581*0Sstevel@tonic-gate * a text token. If we do this, we need to consider 582*0Sstevel@tonic-gate * carrying timezone info so that praudit can 583*0Sstevel@tonic-gate * represent times in an unambiguous manner. 584*0Sstevel@tonic-gate */ 585*0Sstevel@tonic-gate date = ((union convert *)p_data)->tlong; 586*0Sstevel@tonic-gate if (strftime(buffer, sizeof (buffer), "%x", 587*0Sstevel@tonic-gate localtime_r(&date, &tm)) > TEXT_LENGTH) { 588*0Sstevel@tonic-gate if (required) 589*0Sstevel@tonic-gate (void) strncpy(buffer, "invalid date", 590*0Sstevel@tonic-gate TEXT_LENGTH); 591*0Sstevel@tonic-gate else 592*0Sstevel@tonic-gate break; 593*0Sstevel@tonic-gate } 594*0Sstevel@tonic-gate DPRINTF((" text=%s\n", buffer)); 595*0Sstevel@tonic-gate adt_write_text(event->ae_event_handle, buffer, format); 596*0Sstevel@tonic-gate break; 597*0Sstevel@tonic-gate /* 598*0Sstevel@tonic-gate * The "input size" is overloaded to mean the list number 599*0Sstevel@tonic-gate * and the msg_selector indexes the desired string in 600*0Sstevel@tonic-gate * that list 601*0Sstevel@tonic-gate */ 602*0Sstevel@tonic-gate case ADT_MSG: 603*0Sstevel@tonic-gate list = &adt_msg_text[(enum adt_login_text)def->dd_input_size]; 604*0Sstevel@tonic-gate list_index = ((union convert *)p_data)->msg_selector; 605*0Sstevel@tonic-gate 606*0Sstevel@tonic-gate if ((list_index < list->ml_min_index) | 607*0Sstevel@tonic-gate (list_index > list->ml_max_index)) 608*0Sstevel@tonic-gate string = "Invalid message index"; 609*0Sstevel@tonic-gate else 610*0Sstevel@tonic-gate string = list->ml_msg_list[list_index + 611*0Sstevel@tonic-gate list->ml_offset]; 612*0Sstevel@tonic-gate 613*0Sstevel@tonic-gate if (string == NULL) { /* null is valid; means skip */ 614*0Sstevel@tonic-gate if (required) { 615*0Sstevel@tonic-gate string = empty; 616*0Sstevel@tonic-gate } else 617*0Sstevel@tonic-gate break; 618*0Sstevel@tonic-gate } 619*0Sstevel@tonic-gate DPRINTF((" text=%s\n", string)); 620*0Sstevel@tonic-gate adt_write_text(event->ae_event_handle, string, format); 621*0Sstevel@tonic-gate break; 622*0Sstevel@tonic-gate case ADT_UID: 623*0Sstevel@tonic-gate case ADT_GID: 624*0Sstevel@tonic-gate case ADT_UINT: 625*0Sstevel@tonic-gate (void) snprintf(buffer, TEXT_LENGTH, "%d", 626*0Sstevel@tonic-gate ((union convert *)p_data)->tuint); 627*0Sstevel@tonic-gate 628*0Sstevel@tonic-gate DPRINTF((" text=%s\n", buffer)); 629*0Sstevel@tonic-gate adt_write_text(event->ae_event_handle, buffer, format); 630*0Sstevel@tonic-gate break; 631*0Sstevel@tonic-gate case ADT_UIDSTAR: 632*0Sstevel@tonic-gate case ADT_GIDSTAR: 633*0Sstevel@tonic-gate case ADT_UINT32STAR: 634*0Sstevel@tonic-gate int_list = ((union convert *)p_data)->tuint32star; 635*0Sstevel@tonic-gate p_data = adt_adjust_address(p_data, sizeof (int *), 636*0Sstevel@tonic-gate sizeof (int)); 637*0Sstevel@tonic-gate arrayCount = ((union convert *)p_data)->tint; 638*0Sstevel@tonic-gate 639*0Sstevel@tonic-gate string = buffer; 640*0Sstevel@tonic-gate available = TEXT_LENGTH; /* space available in buffer */ 641*0Sstevel@tonic-gate 642*0Sstevel@tonic-gate if (arrayCount < 0) 643*0Sstevel@tonic-gate arrayCount = 0; 644*0Sstevel@tonic-gate 645*0Sstevel@tonic-gate if ((arrayCount > 0) && (int_list != NULL)) { 646*0Sstevel@tonic-gate for (; arrayCount > 0; arrayCount--) { 647*0Sstevel@tonic-gate written = snprintf(string, available, 648*0Sstevel@tonic-gate "%d ", *int_list++); 649*0Sstevel@tonic-gate if (written < 1) 650*0Sstevel@tonic-gate break; 651*0Sstevel@tonic-gate string += written; 652*0Sstevel@tonic-gate available -= written; 653*0Sstevel@tonic-gate } 654*0Sstevel@tonic-gate } else if (required) 655*0Sstevel@tonic-gate string = empty; 656*0Sstevel@tonic-gate else 657*0Sstevel@tonic-gate break; 658*0Sstevel@tonic-gate 659*0Sstevel@tonic-gate adt_write_text(event->ae_event_handle, buffer, format); 660*0Sstevel@tonic-gate break; 661*0Sstevel@tonic-gate case ADT_ULONG: 662*0Sstevel@tonic-gate (void) snprintf(buffer, TEXT_LENGTH, "%ld", 663*0Sstevel@tonic-gate ((union convert *)p_data)->tulong); 664*0Sstevel@tonic-gate 665*0Sstevel@tonic-gate DPRINTF((" text=%s\n", buffer)); 666*0Sstevel@tonic-gate adt_write_text(event->ae_event_handle, buffer, format); 667*0Sstevel@tonic-gate break; 668*0Sstevel@tonic-gate case ADT_CHARSTAR: 669*0Sstevel@tonic-gate string = ((union convert *)p_data)->tcharstar; 670*0Sstevel@tonic-gate 671*0Sstevel@tonic-gate if (string == NULL) { 672*0Sstevel@tonic-gate if (required) 673*0Sstevel@tonic-gate string = empty; 674*0Sstevel@tonic-gate else 675*0Sstevel@tonic-gate break; 676*0Sstevel@tonic-gate } 677*0Sstevel@tonic-gate DPRINTF((" text=%s\n", string)); 678*0Sstevel@tonic-gate adt_write_text(event->ae_event_handle, string, format); 679*0Sstevel@tonic-gate break; 680*0Sstevel@tonic-gate case ADT_CHAR2STAR: 681*0Sstevel@tonic-gate string_list = ((union convert *)p_data)->tchar2star; 682*0Sstevel@tonic-gate p_data = adt_adjust_address(p_data, sizeof (char **), 683*0Sstevel@tonic-gate sizeof (int)); 684*0Sstevel@tonic-gate arrayCount = ((union convert *)p_data)->tint; 685*0Sstevel@tonic-gate 686*0Sstevel@tonic-gate if (arrayCount < 0) 687*0Sstevel@tonic-gate arrayCount = 0; 688*0Sstevel@tonic-gate 689*0Sstevel@tonic-gate if ((arrayCount > 0) && (string_list != NULL)) { 690*0Sstevel@tonic-gate for (i = 0; i < arrayCount; i++) { 691*0Sstevel@tonic-gate string = string_list[i]; 692*0Sstevel@tonic-gate if (string != NULL) 693*0Sstevel@tonic-gate adt_write_text(event->ae_event_handle, 694*0Sstevel@tonic-gate string, format); 695*0Sstevel@tonic-gate } 696*0Sstevel@tonic-gate } else if (required) 697*0Sstevel@tonic-gate adt_write_text(event->ae_event_handle, empty, format); 698*0Sstevel@tonic-gate else 699*0Sstevel@tonic-gate break; 700*0Sstevel@tonic-gate break; 701*0Sstevel@tonic-gate default: 702*0Sstevel@tonic-gate if (!have_syslogged) { /* don't flood the log */ 703*0Sstevel@tonic-gate adt_write_syslog("unsupported data conversion", 704*0Sstevel@tonic-gate ENOTSUP); 705*0Sstevel@tonic-gate have_syslogged = 1; 706*0Sstevel@tonic-gate } 707*0Sstevel@tonic-gate break; 708*0Sstevel@tonic-gate } 709*0Sstevel@tonic-gate DFLUSH 710*0Sstevel@tonic-gate } 711*0Sstevel@tonic-gate 712*0Sstevel@tonic-gate /* ARGSUSED */ 713*0Sstevel@tonic-gate static void 714*0Sstevel@tonic-gate adt_to_uauth(datadef *def, void *p_data, int required, 715*0Sstevel@tonic-gate struct adt_event_state *event, char *format) 716*0Sstevel@tonic-gate { 717*0Sstevel@tonic-gate char *string; 718*0Sstevel@tonic-gate 719*0Sstevel@tonic-gate DPRINTF((" adt_to_uauth dd_datatype=%d\n", def->dd_datatype)); 720*0Sstevel@tonic-gate 721*0Sstevel@tonic-gate string = ((union convert *)p_data)->tcharstar; 722*0Sstevel@tonic-gate 723*0Sstevel@tonic-gate if (string == NULL) { 724*0Sstevel@tonic-gate if (required) 725*0Sstevel@tonic-gate string = empty; 726*0Sstevel@tonic-gate else 727*0Sstevel@tonic-gate return; 728*0Sstevel@tonic-gate } 729*0Sstevel@tonic-gate DPRINTF((" text=%s\n", string)); 730*0Sstevel@tonic-gate (void) au_write(event->ae_event_handle, au_to_uauth(string)); 731*0Sstevel@tonic-gate } 732*0Sstevel@tonic-gate 733*0Sstevel@tonic-gate /* ARGSUSED */ 734*0Sstevel@tonic-gate static void 735*0Sstevel@tonic-gate adt_to_zonename(datadef *def, void *p_data, int required, 736*0Sstevel@tonic-gate struct adt_event_state *event, char *notUsed) 737*0Sstevel@tonic-gate { 738*0Sstevel@tonic-gate char *name; 739*0Sstevel@tonic-gate 740*0Sstevel@tonic-gate name = ((union convert *)p_data)->tcharstar; 741*0Sstevel@tonic-gate 742*0Sstevel@tonic-gate if (name != NULL) { 743*0Sstevel@tonic-gate DPRINTF((" name=%s\n", name)); 744*0Sstevel@tonic-gate (void) au_write(event->ae_event_handle, au_to_zonename(name)); 745*0Sstevel@tonic-gate } else { 746*0Sstevel@tonic-gate DPRINTF((" Null name\n")); 747*0Sstevel@tonic-gate if (required) 748*0Sstevel@tonic-gate (void) au_write(event->ae_event_handle, 749*0Sstevel@tonic-gate au_to_zonename(empty)); 750*0Sstevel@tonic-gate } 751*0Sstevel@tonic-gate } 752*0Sstevel@tonic-gate 753*0Sstevel@tonic-gate 754*0Sstevel@tonic-gate /* 755*0Sstevel@tonic-gate * no function for header -- the header is generated by au_close() 756*0Sstevel@tonic-gate * 757*0Sstevel@tonic-gate * no function for trailer -- the trailer is generated by au_close() 758*0Sstevel@tonic-gate */ 759*0Sstevel@tonic-gate 760*0Sstevel@tonic-gate #define MAX_TOKEN_JMP 15 761*0Sstevel@tonic-gate 762*0Sstevel@tonic-gate static struct token_jmp token_table[MAX_TOKEN_JMP] = 763*0Sstevel@tonic-gate { 764*0Sstevel@tonic-gate {AUT_CMD, adt_to_cmd}, 765*0Sstevel@tonic-gate {ADT_CMD_ALT, adt_to_cmd1}, 766*0Sstevel@tonic-gate {AUT_TID, adt_to_tid}, 767*0Sstevel@tonic-gate {AUT_NEWGROUPS, adt_to_newgroups}, 768*0Sstevel@tonic-gate {AUT_PATH, adt_to_path}, 769*0Sstevel@tonic-gate {-AUT_PATH, adt_to_pathlist}, /* private extension of token values */ 770*0Sstevel@tonic-gate {ADT_AUT_PRIV_L, adt_to_priv_limit}, 771*0Sstevel@tonic-gate {ADT_AUT_PRIV_I, adt_to_priv_inherit}, 772*0Sstevel@tonic-gate {ADT_AUT_PRIV_E, adt_to_priv_effective}, 773*0Sstevel@tonic-gate {AUT_PROCESS, adt_to_process}, 774*0Sstevel@tonic-gate {AUT_RETURN, adt_to_return}, 775*0Sstevel@tonic-gate {AUT_SUBJECT, adt_to_subject}, 776*0Sstevel@tonic-gate {AUT_TEXT, adt_to_text}, 777*0Sstevel@tonic-gate {AUT_UAUTH, adt_to_uauth}, 778*0Sstevel@tonic-gate {AUT_ZONENAME, adt_to_zonename} 779*0Sstevel@tonic-gate }; 780*0Sstevel@tonic-gate /* 781*0Sstevel@tonic-gate * {AUT_ARG, adt_to_arg}, not used 782*0Sstevel@tonic-gate * {AUT_ACL, adt_to_acl}, not used 783*0Sstevel@tonic-gate * {AUT_ARBITRARY, adt_to_arbitrary}, AUT_ARBITRARY is undefined 784*0Sstevel@tonic-gate * {AUT_ATTR, adt_to_attr}, not used in mountd 785*0Sstevel@tonic-gate * {AUT_EXEC_ARGS, adt_to_exec_args}, not used 786*0Sstevel@tonic-gate * {AUT_EXEC_ENV, adt_to_exec_env}, not used 787*0Sstevel@tonic-gate * {AUT_EXIT, adt_to_exit}, obsolete 788*0Sstevel@tonic-gate * {AUT_FILE, adt_to_file}, AUT_FILE is undefined 789*0Sstevel@tonic-gate * {AUT_GROUPS, adt_to_groups}, obsolete 790*0Sstevel@tonic-gate * {AUT_HEADER, adt_to_header} not used 791*0Sstevel@tonic-gate * {AUT_IN_ADDR, adt_to_in_addr}, not used 792*0Sstevel@tonic-gate * {AUT_IP, adt_to_ip}, not used 793*0Sstevel@tonic-gate * {AUT_IPC, adt_to_ipc}, not used 794*0Sstevel@tonic-gate * {AUT_IPC_PERM, adt_to_ipc_perm}, not used 795*0Sstevel@tonic-gate * {AUT_OPAQUE, adt_to_opaque}, not used 796*0Sstevel@tonic-gate * {AUT_SEQ, adt_to_seq}, not used 797*0Sstevel@tonic-gate * {AUT_SOCKET, adt_to_socket}, not used 798*0Sstevel@tonic-gate * {AUT_SOCKET_INET, adt_to_socket_inet}, AUT_SOCKET_INET is undefined 799*0Sstevel@tonic-gate * {AUT_TRAILER, adt_to_trailer} not used 800*0Sstevel@tonic-gate */ 801*0Sstevel@tonic-gate 802*0Sstevel@tonic-gate /* find function to generate token */ 803*0Sstevel@tonic-gate 804*0Sstevel@tonic-gate static adt_token_func_t 805*0Sstevel@tonic-gate adt_getTokenFunction(char token_id) 806*0Sstevel@tonic-gate { 807*0Sstevel@tonic-gate int i; 808*0Sstevel@tonic-gate struct token_jmp *p_jmp = token_table; 809*0Sstevel@tonic-gate 810*0Sstevel@tonic-gate for (i = 0; i < MAX_TOKEN_JMP; i++) { 811*0Sstevel@tonic-gate if (token_id == p_jmp->jmp_id) { 812*0Sstevel@tonic-gate return (p_jmp->jmp_to); 813*0Sstevel@tonic-gate } 814*0Sstevel@tonic-gate p_jmp++; 815*0Sstevel@tonic-gate } 816*0Sstevel@tonic-gate errno = EINVAL; 817*0Sstevel@tonic-gate return (NULL); 818*0Sstevel@tonic-gate } 819*0Sstevel@tonic-gate 820*0Sstevel@tonic-gate /* 821*0Sstevel@tonic-gate * adjustAddress -- given the address of data, its size, and the type of 822*0Sstevel@tonic-gate * the next data field, calculate the offset to the next piece of data. 823*0Sstevel@tonic-gate * Depending on the caller, "current" and "next" mean the current pointer 824*0Sstevel@tonic-gate * and the next pointer or the last pointer and the current pointer. 825*0Sstevel@tonic-gate */ 826*0Sstevel@tonic-gate void * 827*0Sstevel@tonic-gate adt_adjust_address(void *current_address, size_t current_size, 828*0Sstevel@tonic-gate size_t next_size) 829*0Sstevel@tonic-gate { 830*0Sstevel@tonic-gate ptrdiff_t adjustment; 831*0Sstevel@tonic-gate ptrdiff_t remainder; 832*0Sstevel@tonic-gate 833*0Sstevel@tonic-gate adjustment = (size_t)current_address + current_size; 834*0Sstevel@tonic-gate 835*0Sstevel@tonic-gate if (next_size) { 836*0Sstevel@tonic-gate remainder = adjustment % next_size; 837*0Sstevel@tonic-gate if (remainder != 0) 838*0Sstevel@tonic-gate adjustment += next_size - remainder; 839*0Sstevel@tonic-gate } 840*0Sstevel@tonic-gate return ((char *)adjustment); 841*0Sstevel@tonic-gate } 842