17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 545916cd2Sjpk * Common Development and Distribution License (the "License"). 645916cd2Sjpk * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate /* 227c478bd9Sstevel@tonic-gate * adt_token.c 237c478bd9Sstevel@tonic-gate * 24dfc7be02SJan Friedel * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 257c478bd9Sstevel@tonic-gate * Use is subject to license terms. 267c478bd9Sstevel@tonic-gate * 277c478bd9Sstevel@tonic-gate * This file does not provide any user callable functions. See adt.c 287c478bd9Sstevel@tonic-gate */ 297c478bd9Sstevel@tonic-gate 307c478bd9Sstevel@tonic-gate #include <bsm/adt.h> 317c478bd9Sstevel@tonic-gate #include <bsm/adt_event.h> 327c478bd9Sstevel@tonic-gate #include <bsm/audit.h> 33f72effdeSgww 347c478bd9Sstevel@tonic-gate #include <adt_xlate.h> 3567dbe2beSCasper H.S. Dik #include <alloca.h> 367c478bd9Sstevel@tonic-gate #include <assert.h> 377c478bd9Sstevel@tonic-gate #include <netdb.h> 387c478bd9Sstevel@tonic-gate #include <priv.h> 397c478bd9Sstevel@tonic-gate #include <string.h> 407c478bd9Sstevel@tonic-gate #include <strings.h> 416af17881Sgww #include <stdlib.h> 427c478bd9Sstevel@tonic-gate #include <time.h> 437c478bd9Sstevel@tonic-gate #include <unistd.h> 447c478bd9Sstevel@tonic-gate 45f72effdeSgww #include <sys/priv_names.h> 46f72effdeSgww #include <sys/socket.h> 47f72effdeSgww #include <sys/types.h> 48f72effdeSgww #include <sys/vnode.h> 49f72effdeSgww 50f72effdeSgww #include <tsol/label.h> 51f72effdeSgww 527c478bd9Sstevel@tonic-gate #ifdef C2_DEBUG 53dfc7be02SJan Friedel #define DPRINTF(x) { (void) printf x; } 54dfc7be02SJan Friedel #define DFLUSH (void) fflush(stdout); 556af17881Sgww 566af17881Sgww /* 0x + Classification + Compartments + end of string */ 576af17881Sgww #define HEX_SIZE 2 + 2*2 + 2*32 + 1 586af17881Sgww 596af17881Sgww static char * 606af17881Sgww dprt_label(m_label_t *label) 616af17881Sgww { 626af17881Sgww static char hex[HEX_SIZE]; 636af17881Sgww char *direct = NULL; 646af17881Sgww 656af17881Sgww if (label_to_str(label, &direct, M_INTERNAL, DEF_NAMES) != 0) { 666af17881Sgww adt_write_syslog("label_to_str(M_INTERNAL)", errno); 676af17881Sgww return ("hex label failed"); 686af17881Sgww } 696af17881Sgww (void) strlcpy(hex, direct, sizeof (hex)); 706af17881Sgww free(direct); 716af17881Sgww return (hex); 726af17881Sgww } 736af17881Sgww #else /* !C2_DEBUG */ 747c478bd9Sstevel@tonic-gate #define DPRINTF(x) 757c478bd9Sstevel@tonic-gate #define DFLUSH 766af17881Sgww #endif /* C2_DEBUG */ 777c478bd9Sstevel@tonic-gate 787c478bd9Sstevel@tonic-gate static adt_token_func_t adt_getTokenFunction(char); 797c478bd9Sstevel@tonic-gate 807c478bd9Sstevel@tonic-gate static char *empty = ""; 817c478bd9Sstevel@tonic-gate 827c478bd9Sstevel@tonic-gate /* 837c478bd9Sstevel@tonic-gate * call adt_token_open() first and adt_token_close() last. 847c478bd9Sstevel@tonic-gate * 857c478bd9Sstevel@tonic-gate * au_open is sort of broken; it returns a -1 when out of memory that 867c478bd9Sstevel@tonic-gate * you're supposed to ignore; au_write and au_close return without 877c478bd9Sstevel@tonic-gate * doing anything when a -1 is passed. This code sort of follows the 887c478bd9Sstevel@tonic-gate * au_open model except that it calls syslog to indicate underlying 897c478bd9Sstevel@tonic-gate * brokenness. Other than that, -1 is ignored. 907c478bd9Sstevel@tonic-gate */ 917c478bd9Sstevel@tonic-gate 927c478bd9Sstevel@tonic-gate void 937c478bd9Sstevel@tonic-gate adt_token_open(struct adt_event_state *event) 947c478bd9Sstevel@tonic-gate { 957c478bd9Sstevel@tonic-gate static int have_syslogged = 0; 967c478bd9Sstevel@tonic-gate 977c478bd9Sstevel@tonic-gate event->ae_event_handle = au_open(); 987c478bd9Sstevel@tonic-gate if (event->ae_event_handle < 0) { 997c478bd9Sstevel@tonic-gate if (!have_syslogged) { 1007c478bd9Sstevel@tonic-gate adt_write_syslog("au_open failed", ENOMEM); 1017c478bd9Sstevel@tonic-gate have_syslogged = 1; 1027c478bd9Sstevel@tonic-gate } 103f72effdeSgww } else { 1047c478bd9Sstevel@tonic-gate have_syslogged = 0; 1057c478bd9Sstevel@tonic-gate } 106f72effdeSgww } 1077c478bd9Sstevel@tonic-gate 1087c478bd9Sstevel@tonic-gate /* 1097c478bd9Sstevel@tonic-gate * call generate_token for each token in the order you want the tokens 1107c478bd9Sstevel@tonic-gate * generated. 1117c478bd9Sstevel@tonic-gate */ 1127c478bd9Sstevel@tonic-gate 1137c478bd9Sstevel@tonic-gate void 1147c478bd9Sstevel@tonic-gate adt_generate_token(struct entry *p_entry, void *p_data, 1157c478bd9Sstevel@tonic-gate struct adt_event_state *event) 1167c478bd9Sstevel@tonic-gate { 1177c478bd9Sstevel@tonic-gate adt_token_func_t p_func; 1187c478bd9Sstevel@tonic-gate 1197c478bd9Sstevel@tonic-gate assert((p_entry != NULL) && (p_data != NULL) && (event != NULL)); 1207c478bd9Sstevel@tonic-gate 1217c478bd9Sstevel@tonic-gate p_func = adt_getTokenFunction(p_entry->en_token_id); 1227c478bd9Sstevel@tonic-gate assert(p_func != NULL); 1237c478bd9Sstevel@tonic-gate 124dfc7be02SJan Friedel DPRINTF(("p_entry=%p, p_data=%p, offset=%llu, msgFmt=%s\n", 125dfc7be02SJan Friedel (void *)p_entry, p_data, (long long)p_entry->en_offset, 126dfc7be02SJan Friedel p_entry->en_msg_format)); 1277c478bd9Sstevel@tonic-gate DFLUSH 1287c478bd9Sstevel@tonic-gate 1297c478bd9Sstevel@tonic-gate (*p_func)(p_entry->en_type_def, 1307c478bd9Sstevel@tonic-gate (char *)p_data + p_entry->en_offset, p_entry->en_required, event, 1317c478bd9Sstevel@tonic-gate p_entry->en_msg_format); 1327c478bd9Sstevel@tonic-gate } 1337c478bd9Sstevel@tonic-gate 1347c478bd9Sstevel@tonic-gate /* call this last */ 1357c478bd9Sstevel@tonic-gate 1360ad2061eSgww int 1377c478bd9Sstevel@tonic-gate adt_token_close(struct adt_event_state *event) 1387c478bd9Sstevel@tonic-gate { 1397c478bd9Sstevel@tonic-gate int rc; 1407c478bd9Sstevel@tonic-gate 1417c478bd9Sstevel@tonic-gate rc = au_close(event->ae_event_handle, AU_TO_WRITE, 1427c478bd9Sstevel@tonic-gate event->ae_internal_id); 1437c478bd9Sstevel@tonic-gate if (rc < 0) 1447c478bd9Sstevel@tonic-gate adt_write_syslog("au_close failed", errno); 1450ad2061eSgww return (rc); 1467c478bd9Sstevel@tonic-gate } 1477c478bd9Sstevel@tonic-gate 1487c478bd9Sstevel@tonic-gate /* 1497c478bd9Sstevel@tonic-gate * one function per token -- see the jump table at the end of file 1507c478bd9Sstevel@tonic-gate */ 1517c478bd9Sstevel@tonic-gate 1527c478bd9Sstevel@tonic-gate /* ARGSUSED */ 1537c478bd9Sstevel@tonic-gate static void 1547c478bd9Sstevel@tonic-gate adt_to_return(datadef *def, void *p_data, int required, 1557c478bd9Sstevel@tonic-gate struct adt_event_state *event, char *notUsed) 1567c478bd9Sstevel@tonic-gate { 1577c478bd9Sstevel@tonic-gate 1587c478bd9Sstevel@tonic-gate #ifdef _LP64 1597c478bd9Sstevel@tonic-gate (void) au_write(event->ae_event_handle, 1607c478bd9Sstevel@tonic-gate au_to_return64((int64_t)event->ae_rc, event->ae_type)); 1617c478bd9Sstevel@tonic-gate #else 1627c478bd9Sstevel@tonic-gate (void) au_write(event->ae_event_handle, 1637c478bd9Sstevel@tonic-gate au_to_return32((int32_t)event->ae_rc, event->ae_type)); 1647c478bd9Sstevel@tonic-gate #endif 1657c478bd9Sstevel@tonic-gate } 1667c478bd9Sstevel@tonic-gate 1677c478bd9Sstevel@tonic-gate /* 1687c478bd9Sstevel@tonic-gate * AUT_CMD 1697c478bd9Sstevel@tonic-gate * 1707c478bd9Sstevel@tonic-gate * the command line is described with argc and argv and the environment 1717c478bd9Sstevel@tonic-gate * with envp. The envp list is NULL terminated and has no separate 1727c478bd9Sstevel@tonic-gate * counter; envp will be a NULL list unless the AUDIT_ARGE policy is 1737c478bd9Sstevel@tonic-gate * set. 1747c478bd9Sstevel@tonic-gate */ 1757c478bd9Sstevel@tonic-gate 1767c478bd9Sstevel@tonic-gate /* ARGSUSED */ 1777c478bd9Sstevel@tonic-gate static void 1787c478bd9Sstevel@tonic-gate adt_to_cmd(datadef *def, void *p_data, int required, 1797c478bd9Sstevel@tonic-gate struct adt_event_state *event, char *notUsed) 1807c478bd9Sstevel@tonic-gate { 1817c478bd9Sstevel@tonic-gate struct adt_internal_state *sp = event->ae_session; 1827c478bd9Sstevel@tonic-gate int argc; 1837c478bd9Sstevel@tonic-gate char **argv; 1847c478bd9Sstevel@tonic-gate char **envp = NULL; 1857c478bd9Sstevel@tonic-gate 1867c478bd9Sstevel@tonic-gate argc = ((union convert *)p_data)->tint; 1877c478bd9Sstevel@tonic-gate p_data = adt_adjust_address(p_data, sizeof (int), sizeof (char **)); 1887c478bd9Sstevel@tonic-gate argv = ((union convert *)p_data)->tchar2star; 1897c478bd9Sstevel@tonic-gate p_data = adt_adjust_address(p_data, sizeof (char **), sizeof (char **)); 1907c478bd9Sstevel@tonic-gate 1917c478bd9Sstevel@tonic-gate if (sp->as_kernel_audit_policy & AUDIT_ARGE) 1927c478bd9Sstevel@tonic-gate envp = ((union convert *)p_data)->tchar2star; 1937c478bd9Sstevel@tonic-gate 1947c478bd9Sstevel@tonic-gate (void) au_write(event->ae_event_handle, 1957c478bd9Sstevel@tonic-gate au_to_cmd(argc, argv, envp)); 1967c478bd9Sstevel@tonic-gate } 1977c478bd9Sstevel@tonic-gate 1987c478bd9Sstevel@tonic-gate /* 1997c478bd9Sstevel@tonic-gate * special case of AUT_CMD with 1 argument that is 2007c478bd9Sstevel@tonic-gate * a string showing the whole command and no envp 2017c478bd9Sstevel@tonic-gate */ 2027c478bd9Sstevel@tonic-gate /* ARGSUSED */ 2037c478bd9Sstevel@tonic-gate static void 2047c478bd9Sstevel@tonic-gate adt_to_cmd1(datadef *def, void *p_data, int required, 2057c478bd9Sstevel@tonic-gate struct adt_event_state *event, char *notUsed) 2067c478bd9Sstevel@tonic-gate { 2077c478bd9Sstevel@tonic-gate char *string; 2087c478bd9Sstevel@tonic-gate 2097c478bd9Sstevel@tonic-gate string = ((union convert *)p_data)->tcharstar; 2107c478bd9Sstevel@tonic-gate 2117c478bd9Sstevel@tonic-gate if (string == NULL) { 212f72effdeSgww if (required) { 2137c478bd9Sstevel@tonic-gate string = empty; 214f72effdeSgww } else { 2157c478bd9Sstevel@tonic-gate return; 2167c478bd9Sstevel@tonic-gate } 217f72effdeSgww } 2187c478bd9Sstevel@tonic-gate /* argc is hardcoded as 1 */ 2197c478bd9Sstevel@tonic-gate (void) au_write(event->ae_event_handle, au_to_cmd(1, &string, 2207c478bd9Sstevel@tonic-gate NULL)); 2217c478bd9Sstevel@tonic-gate } 2227c478bd9Sstevel@tonic-gate 2237c478bd9Sstevel@tonic-gate /* 2247c478bd9Sstevel@tonic-gate * adt_to_tid -- generic address (ip is only one defined at present) 2257c478bd9Sstevel@tonic-gate * input: 2267c478bd9Sstevel@tonic-gate * terminal type: ADT_IPv4, ADT_IPv6... 2277c478bd9Sstevel@tonic-gate * case: ADT_IPv4 or ADT_IPv6... 2287c478bd9Sstevel@tonic-gate * ip type 2297c478bd9Sstevel@tonic-gate * remote port 2307c478bd9Sstevel@tonic-gate * local port 2317c478bd9Sstevel@tonic-gate * address 2327c478bd9Sstevel@tonic-gate * case: not defined... 2337c478bd9Sstevel@tonic-gate */ 2347c478bd9Sstevel@tonic-gate /* ARGSUSED */ 2357c478bd9Sstevel@tonic-gate static void 2367c478bd9Sstevel@tonic-gate adt_to_tid(datadef *def, void *p_data, int required, 2377c478bd9Sstevel@tonic-gate struct adt_event_state *event, char *notUsed) 2387c478bd9Sstevel@tonic-gate { 2397c478bd9Sstevel@tonic-gate au_generic_tid_t tid; 2407c478bd9Sstevel@tonic-gate uint32_t type; 2417c478bd9Sstevel@tonic-gate au_ip_t *ip; 2427c478bd9Sstevel@tonic-gate 2437c478bd9Sstevel@tonic-gate type = ((union convert *)p_data)->tuint32; 2447c478bd9Sstevel@tonic-gate 2457c478bd9Sstevel@tonic-gate switch (type) { 2467c478bd9Sstevel@tonic-gate case ADT_IPv4: 2477c478bd9Sstevel@tonic-gate case ADT_IPv6: 2487c478bd9Sstevel@tonic-gate p_data = adt_adjust_address(p_data, sizeof (uint32_t), 2497c478bd9Sstevel@tonic-gate sizeof (uint32_t)); 2507c478bd9Sstevel@tonic-gate 2517c478bd9Sstevel@tonic-gate tid.gt_type = AU_IPADR; 2527c478bd9Sstevel@tonic-gate ip = &(tid.gt_adr.at_ip); 2537c478bd9Sstevel@tonic-gate 2547c478bd9Sstevel@tonic-gate ip->at_type = (type == ADT_IPv4) ? 2557c478bd9Sstevel@tonic-gate AU_IPv4 : AU_IPv6; 2567c478bd9Sstevel@tonic-gate 2577c478bd9Sstevel@tonic-gate ip->at_r_port = ((union convert *)p_data)->tuint16; 2587c478bd9Sstevel@tonic-gate p_data = adt_adjust_address(p_data, sizeof (uint16_t), 2597c478bd9Sstevel@tonic-gate sizeof (uint16_t)); 2607c478bd9Sstevel@tonic-gate 2617c478bd9Sstevel@tonic-gate ip->at_l_port = ((union convert *)p_data)->tuint16; 2627c478bd9Sstevel@tonic-gate 2637c478bd9Sstevel@tonic-gate /* arg3 is for the array element, not the array size */ 2647c478bd9Sstevel@tonic-gate p_data = adt_adjust_address(p_data, sizeof (uint16_t), 2657c478bd9Sstevel@tonic-gate sizeof (uint32_t)); 2667c478bd9Sstevel@tonic-gate 2677c478bd9Sstevel@tonic-gate (void) memcpy(ip->at_addr, p_data, ip->at_type); 2687c478bd9Sstevel@tonic-gate break; 2697c478bd9Sstevel@tonic-gate default: 2707c478bd9Sstevel@tonic-gate adt_write_syslog("Invalid terminal id type", EINVAL); 2717c478bd9Sstevel@tonic-gate return; 2727c478bd9Sstevel@tonic-gate } 2737c478bd9Sstevel@tonic-gate (void) au_write(event->ae_event_handle, au_to_tid(&tid)); 2747c478bd9Sstevel@tonic-gate } 2757c478bd9Sstevel@tonic-gate 2767c478bd9Sstevel@tonic-gate /* 277103b2b15Sgww * au_to_frmi takes a char * that is the fmri. 278103b2b15Sgww */ 279103b2b15Sgww /* ARGSUSED */ 280103b2b15Sgww static void 281103b2b15Sgww adt_to_frmi(datadef *def, void *p_data, int required, 282103b2b15Sgww struct adt_event_state *event, char *notUsed) 283103b2b15Sgww { 284103b2b15Sgww char *fmri; 285103b2b15Sgww 286103b2b15Sgww DPRINTF((" adt_to_fmri dd_datatype=%d\n", def->dd_datatype)); 287103b2b15Sgww 288103b2b15Sgww fmri = ((union convert *)p_data)->tcharstar; 289103b2b15Sgww 290103b2b15Sgww if (fmri == NULL) { 291f72effdeSgww if (required) { 292103b2b15Sgww fmri = empty; 293f72effdeSgww } else { 294103b2b15Sgww return; 295103b2b15Sgww } 296f72effdeSgww } 297103b2b15Sgww DPRINTF((" fmri=%s\n", fmri)); 298103b2b15Sgww (void) au_write(event->ae_event_handle, au_to_fmri(fmri)); 299103b2b15Sgww } 300103b2b15Sgww 301103b2b15Sgww /* 3026af17881Sgww * au_to_label takes an m_label_t * that is the label. 3036af17881Sgww */ 3046af17881Sgww /* ARGSUSED */ 3056af17881Sgww static void 3066af17881Sgww adt_to_label(datadef *def, void *p_data, int required, 3076af17881Sgww struct adt_event_state *event, char *notUsed) 3086af17881Sgww { 3096af17881Sgww m_label_t *label; 3106af17881Sgww 3116af17881Sgww DPRINTF((" adt_to_label dd_datatype=%d\n", def->dd_datatype)); 3126af17881Sgww 3136af17881Sgww label = ((union convert *)p_data)->tm_label; 3146af17881Sgww 3156af17881Sgww if (label != NULL) { 3166af17881Sgww DPRINTF((" label=%s\n", dprt_label(label))); 3176af17881Sgww DFLUSH 3186af17881Sgww (void) au_write(event->ae_event_handle, au_to_label(label)); 3196af17881Sgww } else { 3206af17881Sgww DPRINTF((" Null label\n")); 3216af17881Sgww if (required) 3226af17881Sgww adt_write_syslog("adt_to_label no required label", 0); 3236af17881Sgww } 3246af17881Sgww } 3256af17881Sgww 3266af17881Sgww /* 3277c478bd9Sstevel@tonic-gate * au_to_newgroups takes a length and an array of gids 3287c478bd9Sstevel@tonic-gate * as input. The input to adt_to_newgroups is a length 3297c478bd9Sstevel@tonic-gate * and a pointer to an array of gids. 3307c478bd9Sstevel@tonic-gate */ 3317c478bd9Sstevel@tonic-gate 3327c478bd9Sstevel@tonic-gate /* ARGSUSED */ 3337c478bd9Sstevel@tonic-gate static void 3347c478bd9Sstevel@tonic-gate adt_to_newgroups(datadef *def, void *p_data, int required, 3357c478bd9Sstevel@tonic-gate struct adt_event_state *event, char *notUsed) 3367c478bd9Sstevel@tonic-gate { 3377c478bd9Sstevel@tonic-gate int n; 3387c478bd9Sstevel@tonic-gate gid_t *groups; 3397c478bd9Sstevel@tonic-gate 3407c478bd9Sstevel@tonic-gate n = ((union convert *)p_data)->tint; 3417c478bd9Sstevel@tonic-gate if (n < 1) { 3427c478bd9Sstevel@tonic-gate if (required) { 3437c478bd9Sstevel@tonic-gate n = 0; /* in case negative n was passed */ 344f72effdeSgww } else { 3457c478bd9Sstevel@tonic-gate return; 3467c478bd9Sstevel@tonic-gate } 347f72effdeSgww } 3487c478bd9Sstevel@tonic-gate p_data = adt_adjust_address(p_data, sizeof (int), sizeof (int32_t *)); 3497c478bd9Sstevel@tonic-gate 3507c478bd9Sstevel@tonic-gate groups = ((union convert *)p_data)->tgidstar; 3517c478bd9Sstevel@tonic-gate 3527c478bd9Sstevel@tonic-gate (void) au_write(event->ae_event_handle, au_to_newgroups(n, groups)); 3537c478bd9Sstevel@tonic-gate } 3547c478bd9Sstevel@tonic-gate 3557c478bd9Sstevel@tonic-gate /* ARGSUSED */ 3567c478bd9Sstevel@tonic-gate static void 3577c478bd9Sstevel@tonic-gate adt_to_path(datadef *def, void *p_data, int required, 3587c478bd9Sstevel@tonic-gate struct adt_event_state *event, char *notUsed) 3597c478bd9Sstevel@tonic-gate { 3607c478bd9Sstevel@tonic-gate char *path; 3617c478bd9Sstevel@tonic-gate 3627c478bd9Sstevel@tonic-gate path = ((union convert *)p_data)->tcharstar; 3637c478bd9Sstevel@tonic-gate 3647c478bd9Sstevel@tonic-gate if (path != NULL) { 3657c478bd9Sstevel@tonic-gate DPRINTF((" path=%s\n", path)); 3667c478bd9Sstevel@tonic-gate (void) au_write(event->ae_event_handle, au_to_path(path)); 3677c478bd9Sstevel@tonic-gate } else { 3687c478bd9Sstevel@tonic-gate DPRINTF((" Null path\n")); 369f72effdeSgww if (required) { 3707c478bd9Sstevel@tonic-gate (void) au_write(event->ae_event_handle, 3717c478bd9Sstevel@tonic-gate au_to_path(empty)); 3727c478bd9Sstevel@tonic-gate } 3737c478bd9Sstevel@tonic-gate } 374f72effdeSgww } 3757c478bd9Sstevel@tonic-gate 3767c478bd9Sstevel@tonic-gate /* 3777c478bd9Sstevel@tonic-gate * dummy token id: AUT_PATHLIST 3787c478bd9Sstevel@tonic-gate */ 3797c478bd9Sstevel@tonic-gate 3807c478bd9Sstevel@tonic-gate /* ARGSUSED */ 3817c478bd9Sstevel@tonic-gate static void 3827c478bd9Sstevel@tonic-gate adt_to_pathlist(datadef *def, void *p_data, int required, 3837c478bd9Sstevel@tonic-gate struct adt_event_state *event, char *notUsed) 3847c478bd9Sstevel@tonic-gate { 3857c478bd9Sstevel@tonic-gate char *path; 3867c478bd9Sstevel@tonic-gate char *working_buf; 3877c478bd9Sstevel@tonic-gate char *pathlist; 3887c478bd9Sstevel@tonic-gate char *last_str; 3897c478bd9Sstevel@tonic-gate 3907c478bd9Sstevel@tonic-gate pathlist = ((union convert *)p_data)->tcharstar; 3917c478bd9Sstevel@tonic-gate 3927c478bd9Sstevel@tonic-gate if (pathlist != NULL) { 3937c478bd9Sstevel@tonic-gate working_buf = strdup(pathlist); 3947c478bd9Sstevel@tonic-gate if (working_buf == NULL) { 3957c478bd9Sstevel@tonic-gate adt_write_syslog("audit failure", errno); 396f72effdeSgww if (required) { 3977c478bd9Sstevel@tonic-gate (void) au_write(event->ae_event_handle, 3987c478bd9Sstevel@tonic-gate au_to_path(empty)); 399f72effdeSgww } 4007c478bd9Sstevel@tonic-gate return; 4017c478bd9Sstevel@tonic-gate } 4027c478bd9Sstevel@tonic-gate for (path = strtok_r(working_buf, " ", &last_str); 4037c478bd9Sstevel@tonic-gate path; path = strtok_r(NULL, " ", &last_str)) { 4047c478bd9Sstevel@tonic-gate DPRINTF((" path=%s\n", path)); 4057c478bd9Sstevel@tonic-gate (void) au_write(event->ae_event_handle, 4067c478bd9Sstevel@tonic-gate au_to_path(path)); 4077c478bd9Sstevel@tonic-gate } 4087c478bd9Sstevel@tonic-gate } else { 4097c478bd9Sstevel@tonic-gate DPRINTF((" Null path list\n")); 4107c478bd9Sstevel@tonic-gate if (required) 4117c478bd9Sstevel@tonic-gate (void) au_write(event->ae_event_handle, 4127c478bd9Sstevel@tonic-gate au_to_path(empty)); 4137c478bd9Sstevel@tonic-gate } 4147c478bd9Sstevel@tonic-gate } 4157c478bd9Sstevel@tonic-gate 4167c478bd9Sstevel@tonic-gate /* 4177c478bd9Sstevel@tonic-gate * AUT_PRIV 4187c478bd9Sstevel@tonic-gate */ 4197c478bd9Sstevel@tonic-gate 4207c478bd9Sstevel@tonic-gate /* ARGSUSED */ 4217c478bd9Sstevel@tonic-gate static void 4227c478bd9Sstevel@tonic-gate adt_to_priv(datadef *def, void *p_data, int required, 4237c478bd9Sstevel@tonic-gate struct adt_event_state *event, const char *priv_type) 4247c478bd9Sstevel@tonic-gate { 4257c478bd9Sstevel@tonic-gate priv_set_t *privilege; 4267c478bd9Sstevel@tonic-gate 4277c478bd9Sstevel@tonic-gate privilege = ((union convert *)p_data)->tprivstar; 4287c478bd9Sstevel@tonic-gate 4297c478bd9Sstevel@tonic-gate if (privilege != NULL) { 4307c478bd9Sstevel@tonic-gate (void) au_write(event->ae_event_handle, 4317c478bd9Sstevel@tonic-gate au_to_privset(priv_type, privilege)); 4327c478bd9Sstevel@tonic-gate } else { 4337c478bd9Sstevel@tonic-gate if (required) { 4347c478bd9Sstevel@tonic-gate DPRINTF((" Null privilege\n")); 4357c478bd9Sstevel@tonic-gate (void) au_write(event->ae_event_handle, 4367c478bd9Sstevel@tonic-gate au_to_privset(empty, NULL)); 4377c478bd9Sstevel@tonic-gate } 4387c478bd9Sstevel@tonic-gate } 4397c478bd9Sstevel@tonic-gate } 4407c478bd9Sstevel@tonic-gate 4417c478bd9Sstevel@tonic-gate /* 4427c478bd9Sstevel@tonic-gate * -AUT_PRIV_L AUT_PRIV for a limit set 4437c478bd9Sstevel@tonic-gate */ 4447c478bd9Sstevel@tonic-gate 4457c478bd9Sstevel@tonic-gate /* ARGSUSED */ 4467c478bd9Sstevel@tonic-gate static void 4477c478bd9Sstevel@tonic-gate adt_to_priv_limit(datadef *def, void *p_data, int required, 4487c478bd9Sstevel@tonic-gate struct adt_event_state *event, char *notUsed) 4497c478bd9Sstevel@tonic-gate { 4507c478bd9Sstevel@tonic-gate adt_to_priv(def, p_data, required, event, PRIV_LIMIT); 4517c478bd9Sstevel@tonic-gate } 4527c478bd9Sstevel@tonic-gate 4537c478bd9Sstevel@tonic-gate /* 4547c478bd9Sstevel@tonic-gate * -AUT_PRIV_I AUT_PRIV for an inherit set 4557c478bd9Sstevel@tonic-gate */ 4567c478bd9Sstevel@tonic-gate 4577c478bd9Sstevel@tonic-gate /* ARGSUSED */ 4587c478bd9Sstevel@tonic-gate static void 4597c478bd9Sstevel@tonic-gate adt_to_priv_inherit(datadef *def, void *p_data, int required, 4607c478bd9Sstevel@tonic-gate struct adt_event_state *event, char *notUsed) 4617c478bd9Sstevel@tonic-gate { 4627c478bd9Sstevel@tonic-gate adt_to_priv(def, p_data, required, event, PRIV_INHERITABLE); 4637c478bd9Sstevel@tonic-gate } 4647c478bd9Sstevel@tonic-gate 4657c478bd9Sstevel@tonic-gate /* ARGSUSED */ 4667c478bd9Sstevel@tonic-gate static void 4677c478bd9Sstevel@tonic-gate adt_to_priv_effective(datadef *def, void *p_data, int required, 4687c478bd9Sstevel@tonic-gate struct adt_event_state *event, char *notUsed) 4697c478bd9Sstevel@tonic-gate { 4707c478bd9Sstevel@tonic-gate adt_to_priv(def, p_data, required, event, PRIV_EFFECTIVE); 4717c478bd9Sstevel@tonic-gate } 4727c478bd9Sstevel@tonic-gate 4737c478bd9Sstevel@tonic-gate static void 4747c478bd9Sstevel@tonic-gate getCharacteristics(struct auditpinfo_addr *info, pid_t *pid) 4757c478bd9Sstevel@tonic-gate { 4767c478bd9Sstevel@tonic-gate int rc; 4777c478bd9Sstevel@tonic-gate 478f72effdeSgww if (*pid == 0) { /* getpinfo for this pid */ 4797c478bd9Sstevel@tonic-gate info->ap_pid = getpid(); 480f72effdeSgww } else { 4817c478bd9Sstevel@tonic-gate info->ap_pid = *pid; 482f72effdeSgww } 4837c478bd9Sstevel@tonic-gate 4847c478bd9Sstevel@tonic-gate rc = auditon(A_GETPINFO_ADDR, (caddr_t)info, 4857c478bd9Sstevel@tonic-gate sizeof (struct auditpinfo_addr)); 4867c478bd9Sstevel@tonic-gate if (rc == -1) { 4877c478bd9Sstevel@tonic-gate info->ap_auid = AU_NOAUDITID; 4887c478bd9Sstevel@tonic-gate info->ap_asid = 0; 4897c478bd9Sstevel@tonic-gate (void) memset((void *)&(info->ap_termid), 0, 4907c478bd9Sstevel@tonic-gate sizeof (au_tid_addr_t)); 4917c478bd9Sstevel@tonic-gate info->ap_termid.at_type = AU_IPv4; 4927c478bd9Sstevel@tonic-gate } 4937c478bd9Sstevel@tonic-gate } 4947c478bd9Sstevel@tonic-gate 4957c478bd9Sstevel@tonic-gate /* 4967c478bd9Sstevel@tonic-gate * AUT_PROCESS 4977c478bd9Sstevel@tonic-gate * 4987c478bd9Sstevel@tonic-gate */ 4997c478bd9Sstevel@tonic-gate 5007c478bd9Sstevel@tonic-gate /* ARGSUSED */ 5017c478bd9Sstevel@tonic-gate static void 5027c478bd9Sstevel@tonic-gate adt_to_process(datadef *def, void *p_data, int required, 5037c478bd9Sstevel@tonic-gate struct adt_event_state *event, char *notUsed) 5047c478bd9Sstevel@tonic-gate { 5057c478bd9Sstevel@tonic-gate au_id_t auid; 5067c478bd9Sstevel@tonic-gate uid_t euid; 5077c478bd9Sstevel@tonic-gate gid_t egid; 5087c478bd9Sstevel@tonic-gate uid_t ruid; 5097c478bd9Sstevel@tonic-gate gid_t rgid; 5107c478bd9Sstevel@tonic-gate pid_t pid; 5117c478bd9Sstevel@tonic-gate au_asid_t sid; 5127c478bd9Sstevel@tonic-gate au_tid_addr_t *tid; 5137c478bd9Sstevel@tonic-gate struct auditpinfo_addr info; 5147c478bd9Sstevel@tonic-gate 5157c478bd9Sstevel@tonic-gate auid = ((union convert *)p_data)->tuid; 5167c478bd9Sstevel@tonic-gate p_data = adt_adjust_address(p_data, sizeof (uid_t), sizeof (uid_t)); 5177c478bd9Sstevel@tonic-gate euid = ((union convert *)p_data)->tuid; 5187c478bd9Sstevel@tonic-gate p_data = adt_adjust_address(p_data, sizeof (uid_t), sizeof (gid_t)); 5197c478bd9Sstevel@tonic-gate egid = ((union convert *)p_data)->tgid; 5207c478bd9Sstevel@tonic-gate p_data = adt_adjust_address(p_data, sizeof (gid_t), sizeof (uid_t)); 5217c478bd9Sstevel@tonic-gate ruid = ((union convert *)p_data)->tuid; 5227c478bd9Sstevel@tonic-gate p_data = adt_adjust_address(p_data, sizeof (uid_t), sizeof (gid_t)); 5237c478bd9Sstevel@tonic-gate rgid = ((union convert *)p_data)->tgid; 5247c478bd9Sstevel@tonic-gate p_data = adt_adjust_address(p_data, sizeof (gid_t), sizeof (pid_t)); 5257c478bd9Sstevel@tonic-gate pid = ((union convert *)p_data)->tpid; 5267c478bd9Sstevel@tonic-gate p_data = adt_adjust_address(p_data, sizeof (pid_t), sizeof (uint32_t)); 5277c478bd9Sstevel@tonic-gate sid = ((union convert *)p_data)->tuint32; 5287c478bd9Sstevel@tonic-gate p_data = adt_adjust_address(p_data, sizeof (uint32_t), 5297c478bd9Sstevel@tonic-gate sizeof (au_tid_addr_t *)); 5307c478bd9Sstevel@tonic-gate tid = ((union convert *)p_data)->ttermid; 5317c478bd9Sstevel@tonic-gate 5327c478bd9Sstevel@tonic-gate getCharacteristics(&info, &pid); 5337c478bd9Sstevel@tonic-gate 5347c478bd9Sstevel@tonic-gate if (auid == AU_NOAUDITID) 5357c478bd9Sstevel@tonic-gate auid = info.ap_auid; 5367c478bd9Sstevel@tonic-gate 5377c478bd9Sstevel@tonic-gate if (euid == AU_NOAUDITID) 5387c478bd9Sstevel@tonic-gate euid = geteuid(); 5397c478bd9Sstevel@tonic-gate 5407c478bd9Sstevel@tonic-gate if (egid == AU_NOAUDITID) 5417c478bd9Sstevel@tonic-gate egid = getegid(); 5427c478bd9Sstevel@tonic-gate 5437c478bd9Sstevel@tonic-gate if (ruid == AU_NOAUDITID) 5447c478bd9Sstevel@tonic-gate ruid = getuid(); 5457c478bd9Sstevel@tonic-gate 5467c478bd9Sstevel@tonic-gate if (rgid == AU_NOAUDITID) 5477c478bd9Sstevel@tonic-gate rgid = getgid(); 5487c478bd9Sstevel@tonic-gate 5497c478bd9Sstevel@tonic-gate if (tid == NULL) 5507c478bd9Sstevel@tonic-gate tid = &(info.ap_termid); 5517c478bd9Sstevel@tonic-gate 5527c478bd9Sstevel@tonic-gate if (sid == 0) 5537c478bd9Sstevel@tonic-gate sid = info.ap_asid; 5547c478bd9Sstevel@tonic-gate 5557c478bd9Sstevel@tonic-gate if (pid == 0) 5567c478bd9Sstevel@tonic-gate pid = info.ap_pid; 5577c478bd9Sstevel@tonic-gate 5587c478bd9Sstevel@tonic-gate (void) au_write(event->ae_event_handle, 5597c478bd9Sstevel@tonic-gate au_to_process_ex(auid, euid, egid, ruid, rgid, pid, sid, tid)); 5607c478bd9Sstevel@tonic-gate } 5617c478bd9Sstevel@tonic-gate 5627c478bd9Sstevel@tonic-gate /* 56381490fd2Sgww * Generate subject information. 56481490fd2Sgww * If labels are present, generate the subject label token. 56581490fd2Sgww * If the group audit policy is set, generate the subject group token. 5667c478bd9Sstevel@tonic-gate * 5677c478bd9Sstevel@tonic-gate * The required flag does not apply here. 5687c478bd9Sstevel@tonic-gate * 5697c478bd9Sstevel@tonic-gate * Non-attributable records are indicated by an auid of AU_NOAUDITID; 5707c478bd9Sstevel@tonic-gate * no subject token or group token is generated for a non-attributable 5717c478bd9Sstevel@tonic-gate * record. 5727c478bd9Sstevel@tonic-gate */ 5737c478bd9Sstevel@tonic-gate 5747c478bd9Sstevel@tonic-gate /* ARGSUSED */ 5757c478bd9Sstevel@tonic-gate static void 5767c478bd9Sstevel@tonic-gate adt_to_subject(datadef *def, void *p_data, int required, 5777c478bd9Sstevel@tonic-gate struct adt_event_state *event, char *notUsed) 5787c478bd9Sstevel@tonic-gate { 5797c478bd9Sstevel@tonic-gate struct adt_internal_state *sp = event->ae_session; 5807c478bd9Sstevel@tonic-gate 5817c478bd9Sstevel@tonic-gate if (sp->as_info.ai_auid == AU_NOAUDITID) 5827c478bd9Sstevel@tonic-gate return; 5837c478bd9Sstevel@tonic-gate 5847c478bd9Sstevel@tonic-gate assert(sp->as_have_user_data == ADT_HAVE_ALL); 5857c478bd9Sstevel@tonic-gate 5867c478bd9Sstevel@tonic-gate (void) au_write(event->ae_event_handle, 5877c478bd9Sstevel@tonic-gate au_to_subject_ex(sp->as_info.ai_auid, 5887c478bd9Sstevel@tonic-gate sp->as_euid, sp->as_egid, sp->as_ruid, sp->as_rgid, 589c529a23fSgww sp->as_pid, sp->as_info.ai_asid, 5907c478bd9Sstevel@tonic-gate &(sp->as_info.ai_termid))); 591c529a23fSgww if (is_system_labeled()) { 592c529a23fSgww (void) au_write(event->ae_event_handle, 593c529a23fSgww au_to_label(sp->as_label)); 594c529a23fSgww } 5957c478bd9Sstevel@tonic-gate /* 59626fba2a6Sgww * Add optional tokens if in the process model. 59726fba2a6Sgww * In a session model, the groups list is undefined and label 598c529a23fSgww * is in the state. 5997c478bd9Sstevel@tonic-gate */ 60026fba2a6Sgww if (sp->as_session_model == ADT_PROCESS_MODEL) { 6017c478bd9Sstevel@tonic-gate if (sp->as_kernel_audit_policy & AUDIT_GROUP) { 6027c478bd9Sstevel@tonic-gate int group_count; 60367dbe2beSCasper H.S. Dik int maxgrp = getgroups(0, NULL); 60467dbe2beSCasper H.S. Dik gid_t *grouplist = alloca(maxgrp * sizeof (gid_t)); 6057c478bd9Sstevel@tonic-gate 60667dbe2beSCasper H.S. Dik if ((group_count = getgroups(maxgrp, grouplist)) > 0) { 6077c478bd9Sstevel@tonic-gate (void) au_write(event->ae_event_handle, 6087c478bd9Sstevel@tonic-gate au_to_newgroups(group_count, grouplist)); 6097c478bd9Sstevel@tonic-gate } 6107c478bd9Sstevel@tonic-gate } 6117c478bd9Sstevel@tonic-gate } 6127c478bd9Sstevel@tonic-gate } 6137c478bd9Sstevel@tonic-gate 6147c478bd9Sstevel@tonic-gate /* 6157c478bd9Sstevel@tonic-gate * adt_to_text() 6167c478bd9Sstevel@tonic-gate * 6177c478bd9Sstevel@tonic-gate * The format string, normally null, is sort of a wrapper around 6187c478bd9Sstevel@tonic-gate * the input. adt_write_text() is a wrapper around au_write that 6197c478bd9Sstevel@tonic-gate * handles the format string 6207c478bd9Sstevel@tonic-gate * 6217c478bd9Sstevel@tonic-gate */ 6227c478bd9Sstevel@tonic-gate #define TEXT_LENGTH 49 6237c478bd9Sstevel@tonic-gate 6247c478bd9Sstevel@tonic-gate static void 6257c478bd9Sstevel@tonic-gate adt_write_text(int handle, char *main_text, const char *format) 6267c478bd9Sstevel@tonic-gate { 6277c478bd9Sstevel@tonic-gate char buffer[TEXT_LENGTH * 2 + 1]; 6287c478bd9Sstevel@tonic-gate 629f72effdeSgww if (format == NULL) { 6307c478bd9Sstevel@tonic-gate (void) au_write(handle, au_to_text(main_text)); 631f72effdeSgww } else { 6327c478bd9Sstevel@tonic-gate (void) snprintf(buffer, TEXT_LENGTH * 2, format, main_text); 6337c478bd9Sstevel@tonic-gate (void) au_write(handle, au_to_text(buffer)); 6347c478bd9Sstevel@tonic-gate } 6357c478bd9Sstevel@tonic-gate } 6367c478bd9Sstevel@tonic-gate 6377c478bd9Sstevel@tonic-gate static void 6387c478bd9Sstevel@tonic-gate adt_to_text(datadef *def, void *p_data, int required, 6397c478bd9Sstevel@tonic-gate struct adt_event_state *event, char *format) 6407c478bd9Sstevel@tonic-gate { 6417c478bd9Sstevel@tonic-gate static int have_syslogged = 0; 6427c478bd9Sstevel@tonic-gate char *string; 6437c478bd9Sstevel@tonic-gate char **string_list; 6447c478bd9Sstevel@tonic-gate char buffer[TEXT_LENGTH + 1]; 6457c478bd9Sstevel@tonic-gate time_t date; 6467c478bd9Sstevel@tonic-gate struct tm tm; 6477c478bd9Sstevel@tonic-gate uint32_t *int_list; 6487c478bd9Sstevel@tonic-gate int written, available; 6497c478bd9Sstevel@tonic-gate int i, arrayCount; 6507c478bd9Sstevel@tonic-gate struct msg_text *list; 6517c478bd9Sstevel@tonic-gate int list_index; 6527c478bd9Sstevel@tonic-gate 6537c478bd9Sstevel@tonic-gate DPRINTF((" adt_to_text dd_datatype=%d\n", def->dd_datatype)); 6547c478bd9Sstevel@tonic-gate switch (def->dd_datatype) { 6557c478bd9Sstevel@tonic-gate case ADT_DATE: 6567c478bd9Sstevel@tonic-gate /* 6577c478bd9Sstevel@tonic-gate * Consider creating a separate token type for dates 6587c478bd9Sstevel@tonic-gate * -- store as longs and format them in praudit. 6597c478bd9Sstevel@tonic-gate * For now, a date is input as a time_t and output as 6607c478bd9Sstevel@tonic-gate * a text token. If we do this, we need to consider 6617c478bd9Sstevel@tonic-gate * carrying timezone info so that praudit can 6627c478bd9Sstevel@tonic-gate * represent times in an unambiguous manner. 6637c478bd9Sstevel@tonic-gate */ 6647c478bd9Sstevel@tonic-gate date = ((union convert *)p_data)->tlong; 6657c478bd9Sstevel@tonic-gate if (strftime(buffer, sizeof (buffer), "%x", 6667c478bd9Sstevel@tonic-gate localtime_r(&date, &tm)) > TEXT_LENGTH) { 667f72effdeSgww if (required) { 6687c478bd9Sstevel@tonic-gate (void) strncpy(buffer, "invalid date", 6697c478bd9Sstevel@tonic-gate TEXT_LENGTH); 670f72effdeSgww } else { 6717c478bd9Sstevel@tonic-gate break; 6727c478bd9Sstevel@tonic-gate } 673f72effdeSgww } 6747c478bd9Sstevel@tonic-gate DPRINTF((" text=%s\n", buffer)); 6757c478bd9Sstevel@tonic-gate adt_write_text(event->ae_event_handle, buffer, format); 6767c478bd9Sstevel@tonic-gate break; 6777c478bd9Sstevel@tonic-gate /* 6787c478bd9Sstevel@tonic-gate * The "input size" is overloaded to mean the list number 6797c478bd9Sstevel@tonic-gate * and the msg_selector indexes the desired string in 6807c478bd9Sstevel@tonic-gate * that list 6817c478bd9Sstevel@tonic-gate */ 6827c478bd9Sstevel@tonic-gate case ADT_MSG: 683732675ddSgww list = &adt_msg_text[(enum adt_msg_list)def->dd_input_size]; 6847c478bd9Sstevel@tonic-gate list_index = ((union convert *)p_data)->msg_selector; 6857c478bd9Sstevel@tonic-gate 6866a3b10dbStz204579 if ((list_index + list->ml_offset < list->ml_min_index) || 687f72effdeSgww (list_index + list->ml_offset > list->ml_max_index)) { 6887c478bd9Sstevel@tonic-gate string = "Invalid message index"; 689f72effdeSgww } else { 6907c478bd9Sstevel@tonic-gate string = list->ml_msg_list[list_index + 6917c478bd9Sstevel@tonic-gate list->ml_offset]; 692f72effdeSgww } 6937c478bd9Sstevel@tonic-gate 6947c478bd9Sstevel@tonic-gate if (string == NULL) { /* null is valid; means skip */ 6957c478bd9Sstevel@tonic-gate if (required) { 6967c478bd9Sstevel@tonic-gate string = empty; 697f72effdeSgww } else { 6987c478bd9Sstevel@tonic-gate break; 6997c478bd9Sstevel@tonic-gate } 700f72effdeSgww } 7017c478bd9Sstevel@tonic-gate DPRINTF((" text=%s\n", string)); 7027c478bd9Sstevel@tonic-gate adt_write_text(event->ae_event_handle, string, format); 7037c478bd9Sstevel@tonic-gate break; 7047c478bd9Sstevel@tonic-gate case ADT_UID: 7057c478bd9Sstevel@tonic-gate case ADT_GID: 7067c478bd9Sstevel@tonic-gate case ADT_UINT: 7076ff475f7Stz204579 case ADT_UINT32: 7086ff475f7Stz204579 (void) snprintf(buffer, TEXT_LENGTH, "%u", 7097c478bd9Sstevel@tonic-gate ((union convert *)p_data)->tuint); 7107c478bd9Sstevel@tonic-gate 7117c478bd9Sstevel@tonic-gate DPRINTF((" text=%s\n", buffer)); 7127c478bd9Sstevel@tonic-gate adt_write_text(event->ae_event_handle, buffer, format); 7137c478bd9Sstevel@tonic-gate break; 7146ff475f7Stz204579 case ADT_INT: 7156ff475f7Stz204579 case ADT_INT32: 7166ff475f7Stz204579 (void) snprintf(buffer, TEXT_LENGTH, "%d", 7176ff475f7Stz204579 ((union convert *)p_data)->tint); 7186ff475f7Stz204579 7196ff475f7Stz204579 DPRINTF((" text=%s\n", buffer)); 7206ff475f7Stz204579 adt_write_text(event->ae_event_handle, buffer, format); 7216ff475f7Stz204579 break; 7226ff475f7Stz204579 case ADT_LONG: 7236ff475f7Stz204579 (void) snprintf(buffer, TEXT_LENGTH, "%ld", 7246ff475f7Stz204579 ((union convert *)p_data)->tlong); 7256ff475f7Stz204579 7266ff475f7Stz204579 DPRINTF((" text=%s\n", buffer)); 7276ff475f7Stz204579 adt_write_text(event->ae_event_handle, buffer, format); 7286ff475f7Stz204579 break; 7297c478bd9Sstevel@tonic-gate case ADT_UIDSTAR: 7307c478bd9Sstevel@tonic-gate case ADT_GIDSTAR: 7317c478bd9Sstevel@tonic-gate case ADT_UINT32STAR: 7327c478bd9Sstevel@tonic-gate int_list = ((union convert *)p_data)->tuint32star; 7337c478bd9Sstevel@tonic-gate p_data = adt_adjust_address(p_data, sizeof (int *), 7347c478bd9Sstevel@tonic-gate sizeof (int)); 7357c478bd9Sstevel@tonic-gate arrayCount = ((union convert *)p_data)->tint; 7367c478bd9Sstevel@tonic-gate 7377c478bd9Sstevel@tonic-gate string = buffer; 7387c478bd9Sstevel@tonic-gate available = TEXT_LENGTH; /* space available in buffer */ 7397c478bd9Sstevel@tonic-gate 7407c478bd9Sstevel@tonic-gate if (arrayCount < 0) 7417c478bd9Sstevel@tonic-gate arrayCount = 0; 7427c478bd9Sstevel@tonic-gate 7437c478bd9Sstevel@tonic-gate if ((arrayCount > 0) && (int_list != NULL)) { 7447c478bd9Sstevel@tonic-gate for (; arrayCount > 0; arrayCount--) { 7457c478bd9Sstevel@tonic-gate written = snprintf(string, available, 7467c478bd9Sstevel@tonic-gate "%d ", *int_list++); 7477c478bd9Sstevel@tonic-gate if (written < 1) 7487c478bd9Sstevel@tonic-gate break; 7497c478bd9Sstevel@tonic-gate string += written; 7507c478bd9Sstevel@tonic-gate available -= written; 7517c478bd9Sstevel@tonic-gate } 752f72effdeSgww } else if (required) { 7537c478bd9Sstevel@tonic-gate string = empty; 754f72effdeSgww } else { 7557c478bd9Sstevel@tonic-gate break; 756f72effdeSgww } 7577c478bd9Sstevel@tonic-gate 7587c478bd9Sstevel@tonic-gate adt_write_text(event->ae_event_handle, buffer, format); 7597c478bd9Sstevel@tonic-gate break; 7607c478bd9Sstevel@tonic-gate case ADT_ULONG: 7616ff475f7Stz204579 (void) snprintf(buffer, TEXT_LENGTH, "%lu", 7627c478bd9Sstevel@tonic-gate ((union convert *)p_data)->tulong); 7637c478bd9Sstevel@tonic-gate 7647c478bd9Sstevel@tonic-gate DPRINTF((" text=%s\n", buffer)); 7657c478bd9Sstevel@tonic-gate adt_write_text(event->ae_event_handle, buffer, format); 7667c478bd9Sstevel@tonic-gate break; 7676ff475f7Stz204579 case ADT_UINT64: 7686ff475f7Stz204579 (void) snprintf(buffer, TEXT_LENGTH, "%llu", 7696ff475f7Stz204579 ((union convert *)p_data)->tuint64); 7706ff475f7Stz204579 7716ff475f7Stz204579 DPRINTF((" text=%s\n", buffer)); 7726ff475f7Stz204579 adt_write_text(event->ae_event_handle, buffer, format); 7736ff475f7Stz204579 break; 7747c478bd9Sstevel@tonic-gate case ADT_CHARSTAR: 7757c478bd9Sstevel@tonic-gate string = ((union convert *)p_data)->tcharstar; 7767c478bd9Sstevel@tonic-gate 7777c478bd9Sstevel@tonic-gate if (string == NULL) { 778f72effdeSgww if (required) { 7797c478bd9Sstevel@tonic-gate string = empty; 780f72effdeSgww } else { 7817c478bd9Sstevel@tonic-gate break; 7827c478bd9Sstevel@tonic-gate } 783f72effdeSgww } 7847c478bd9Sstevel@tonic-gate DPRINTF((" text=%s\n", string)); 7857c478bd9Sstevel@tonic-gate adt_write_text(event->ae_event_handle, string, format); 7867c478bd9Sstevel@tonic-gate break; 7877c478bd9Sstevel@tonic-gate case ADT_CHAR2STAR: 7887c478bd9Sstevel@tonic-gate string_list = ((union convert *)p_data)->tchar2star; 7897c478bd9Sstevel@tonic-gate p_data = adt_adjust_address(p_data, sizeof (char **), 7907c478bd9Sstevel@tonic-gate sizeof (int)); 7917c478bd9Sstevel@tonic-gate arrayCount = ((union convert *)p_data)->tint; 7927c478bd9Sstevel@tonic-gate 7937c478bd9Sstevel@tonic-gate if (arrayCount < 0) 7947c478bd9Sstevel@tonic-gate arrayCount = 0; 7957c478bd9Sstevel@tonic-gate 7967c478bd9Sstevel@tonic-gate if ((arrayCount > 0) && (string_list != NULL)) { 7977c478bd9Sstevel@tonic-gate for (i = 0; i < arrayCount; i++) { 7987c478bd9Sstevel@tonic-gate string = string_list[i]; 7997c478bd9Sstevel@tonic-gate if (string != NULL) 8007c478bd9Sstevel@tonic-gate adt_write_text(event->ae_event_handle, 8017c478bd9Sstevel@tonic-gate string, format); 8027c478bd9Sstevel@tonic-gate } 803f72effdeSgww } else if (required) { 8047c478bd9Sstevel@tonic-gate adt_write_text(event->ae_event_handle, empty, format); 805f72effdeSgww } else { 8067c478bd9Sstevel@tonic-gate break; 807f72effdeSgww } 8087c478bd9Sstevel@tonic-gate break; 8097c478bd9Sstevel@tonic-gate default: 8107c478bd9Sstevel@tonic-gate if (!have_syslogged) { /* don't flood the log */ 8117c478bd9Sstevel@tonic-gate adt_write_syslog("unsupported data conversion", 8127c478bd9Sstevel@tonic-gate ENOTSUP); 8137c478bd9Sstevel@tonic-gate have_syslogged = 1; 8147c478bd9Sstevel@tonic-gate } 8157c478bd9Sstevel@tonic-gate break; 8167c478bd9Sstevel@tonic-gate } 8177c478bd9Sstevel@tonic-gate DFLUSH 8187c478bd9Sstevel@tonic-gate } 8197c478bd9Sstevel@tonic-gate 820f72effdeSgww /* 821f72effdeSgww * AUT_UAUTH 822f72effdeSgww */ 823f72effdeSgww 8247c478bd9Sstevel@tonic-gate /* ARGSUSED */ 8257c478bd9Sstevel@tonic-gate static void 8267c478bd9Sstevel@tonic-gate adt_to_uauth(datadef *def, void *p_data, int required, 8277c478bd9Sstevel@tonic-gate struct adt_event_state *event, char *format) 8287c478bd9Sstevel@tonic-gate { 8297c478bd9Sstevel@tonic-gate char *string; 8307c478bd9Sstevel@tonic-gate 8317c478bd9Sstevel@tonic-gate DPRINTF((" adt_to_uauth dd_datatype=%d\n", def->dd_datatype)); 8327c478bd9Sstevel@tonic-gate 8337c478bd9Sstevel@tonic-gate string = ((union convert *)p_data)->tcharstar; 8347c478bd9Sstevel@tonic-gate 8357c478bd9Sstevel@tonic-gate if (string == NULL) { 836f72effdeSgww if (required) { 8377c478bd9Sstevel@tonic-gate string = empty; 838f72effdeSgww } else { 8397c478bd9Sstevel@tonic-gate return; 8407c478bd9Sstevel@tonic-gate } 841f72effdeSgww } 8427c478bd9Sstevel@tonic-gate DPRINTF((" text=%s\n", string)); 8437c478bd9Sstevel@tonic-gate (void) au_write(event->ae_event_handle, au_to_uauth(string)); 8447c478bd9Sstevel@tonic-gate } 8457c478bd9Sstevel@tonic-gate 846f72effdeSgww /* 847*047f6e6fSgww * AUT_USER 848*047f6e6fSgww */ 849*047f6e6fSgww 850*047f6e6fSgww /* ARGSUSED */ 851*047f6e6fSgww static void 852*047f6e6fSgww adt_to_user(datadef *def, void *p_data, int required, 853*047f6e6fSgww struct adt_event_state *event, char *format) 854*047f6e6fSgww { 855*047f6e6fSgww uid_t uid; 856*047f6e6fSgww char *username; 857*047f6e6fSgww 858*047f6e6fSgww DPRINTF((" adt_to_user dd_datatype=%d\n", def->dd_datatype)); 859*047f6e6fSgww 860*047f6e6fSgww uid = ((union convert *)p_data)->tuid; 861*047f6e6fSgww p_data = adt_adjust_address(p_data, sizeof (uid_t), sizeof (uid_t)); 862*047f6e6fSgww 863*047f6e6fSgww username = ((union convert *)p_data)->tcharstar; 864*047f6e6fSgww 865*047f6e6fSgww if (username == NULL) { 866*047f6e6fSgww if (required) { 867*047f6e6fSgww username = empty; 868*047f6e6fSgww } else { 869*047f6e6fSgww return; 870*047f6e6fSgww } 871*047f6e6fSgww } 872*047f6e6fSgww DPRINTF((" username=%s\n", username)); 873*047f6e6fSgww (void) au_write(event->ae_event_handle, au_to_user(uid, username)); 874*047f6e6fSgww } 875*047f6e6fSgww 876*047f6e6fSgww /* 877f72effdeSgww * AUT_ZONENAME 878f72effdeSgww */ 879f72effdeSgww 8807c478bd9Sstevel@tonic-gate /* ARGSUSED */ 8817c478bd9Sstevel@tonic-gate static void 8827c478bd9Sstevel@tonic-gate adt_to_zonename(datadef *def, void *p_data, int required, 8837c478bd9Sstevel@tonic-gate struct adt_event_state *event, char *notUsed) 8847c478bd9Sstevel@tonic-gate { 8857c478bd9Sstevel@tonic-gate char *name; 8867c478bd9Sstevel@tonic-gate 8877c478bd9Sstevel@tonic-gate name = ((union convert *)p_data)->tcharstar; 8887c478bd9Sstevel@tonic-gate 8897c478bd9Sstevel@tonic-gate if (name != NULL) { 8907c478bd9Sstevel@tonic-gate DPRINTF((" name=%s\n", name)); 8917c478bd9Sstevel@tonic-gate (void) au_write(event->ae_event_handle, au_to_zonename(name)); 8927c478bd9Sstevel@tonic-gate } else { 8937c478bd9Sstevel@tonic-gate DPRINTF((" Null name\n")); 894f72effdeSgww if (required) { 8957c478bd9Sstevel@tonic-gate (void) au_write(event->ae_event_handle, 8967c478bd9Sstevel@tonic-gate au_to_zonename(empty)); 8977c478bd9Sstevel@tonic-gate } 8987c478bd9Sstevel@tonic-gate } 899f72effdeSgww } 900f72effdeSgww 901f72effdeSgww /* 902f72effdeSgww * ADT_IN_PEER dummy token 903f72effdeSgww */ 904f72effdeSgww 905f72effdeSgww /* ARGSUSED */ 906f72effdeSgww static void 907f72effdeSgww adt_to_in_peer(datadef *def, void *p_data, int required, 908f72effdeSgww struct adt_event_state *event, char *notUsed) 909f72effdeSgww { 910f72effdeSgww int sock; 911f72effdeSgww struct sockaddr_in6 peer; 912f72effdeSgww int peerlen = sizeof (peer); 913f72effdeSgww 914f72effdeSgww DPRINTF((" adt_to_in_peer dd_datatype=%d\n", def->dd_datatype)); 915f72effdeSgww 91669987563Ssabdar sock = ((union convert *)p_data)->tfd; 917f72effdeSgww 918f72effdeSgww if (sock < 0) { 919f72effdeSgww DPRINTF((" Socket fd %d\n", sock)); 92069987563Ssabdar if (required) { 92169987563Ssabdar adt_write_syslog("adt_to_in_peer no required socket", 92269987563Ssabdar 0); 92369987563Ssabdar } 924f72effdeSgww return; 925f72effdeSgww } 926f72effdeSgww if (getpeername(sock, (struct sockaddr *)&peer, (socklen_t *)&peerlen) 927f72effdeSgww < 0) { 928f72effdeSgww 929f72effdeSgww adt_write_syslog("adt_to_in_addr getpeername", errno); 93069987563Ssabdar return; 931f72effdeSgww } 932f72effdeSgww if (peer.sin6_family == AF_INET6) { 933f72effdeSgww (void) au_write(event->ae_event_handle, 934f72effdeSgww au_to_in_addr_ex(&(peer.sin6_addr))); 935f72effdeSgww (void) au_write(event->ae_event_handle, 936f72effdeSgww au_to_iport((ushort_t)peer.sin6_port)); 937f72effdeSgww } else { 938f72effdeSgww (void) au_write(event->ae_event_handle, 939f72effdeSgww au_to_in_addr(&(((struct sockaddr_in *)&peer)->sin_addr))); 940f72effdeSgww (void) au_write(event->ae_event_handle, 941f72effdeSgww au_to_iport( 942f72effdeSgww (ushort_t)(((struct sockaddr_in *)&peer)->sin_port))); 943f72effdeSgww } 944f72effdeSgww } 9457c478bd9Sstevel@tonic-gate 94611bc41c8Sgww /* 94711bc41c8Sgww * ADT_IN_REMOTE dummy token 94811bc41c8Sgww * 94911bc41c8Sgww * Similar to ADT_IN_PEER except the input is 95011bc41c8Sgww * an IP address type (ADT_IPv4 | ADT_IPv6) and an address V4/V6 95111bc41c8Sgww */ 95211bc41c8Sgww 95311bc41c8Sgww /* ARGSUSED */ 95411bc41c8Sgww static void 95511bc41c8Sgww adt_to_in_remote(datadef *def, void *p_data, int required, 95611bc41c8Sgww struct adt_event_state *event, char *notUsed) 95711bc41c8Sgww { 95811bc41c8Sgww int32_t type; 95911bc41c8Sgww 96011bc41c8Sgww DPRINTF((" adt_to_in_remote dd_datatype=%d\n", def->dd_datatype)); 96111bc41c8Sgww 96211bc41c8Sgww type = ((union convert *)p_data)->tuint32; 96311bc41c8Sgww 96411bc41c8Sgww if (type == 0) { 96511bc41c8Sgww if (required == 0) { 96611bc41c8Sgww return; 96711bc41c8Sgww } 96811bc41c8Sgww /* required and not specified */ 96911bc41c8Sgww adt_write_syslog("adt_to_in_remote required address not " 97011bc41c8Sgww "specified", 0); 97111bc41c8Sgww type = ADT_IPv4; 97211bc41c8Sgww } 97311bc41c8Sgww p_data = adt_adjust_address(p_data, sizeof (int32_t), 97411bc41c8Sgww sizeof (uint32_t)); 97511bc41c8Sgww 97611bc41c8Sgww switch (type) { 97711bc41c8Sgww case ADT_IPv4: 97811bc41c8Sgww (void) au_write(event->ae_event_handle, au_to_in_addr( 97911bc41c8Sgww (struct in_addr *)&(((union convert *)p_data)->tuint32))); 98011bc41c8Sgww break; 98111bc41c8Sgww case ADT_IPv6: 98211bc41c8Sgww (void) au_write(event->ae_event_handle, au_to_in_addr_ex( 98311bc41c8Sgww (struct in6_addr *)&(((union convert *)p_data)->tuint32))); 98411bc41c8Sgww break; 98511bc41c8Sgww default: 98611bc41c8Sgww adt_write_syslog("adt_to_in_remote invalid type", EINVAL); 98711bc41c8Sgww return; 98811bc41c8Sgww } 98911bc41c8Sgww } 99011bc41c8Sgww 99111bc41c8Sgww /* 99211bc41c8Sgww * adt_to_iport takes a uint16_t IP port. 99311bc41c8Sgww */ 99411bc41c8Sgww 99511bc41c8Sgww /* ARGSUSED */ 99611bc41c8Sgww static void 99711bc41c8Sgww adt_to_iport(datadef *def, void *p_data, int required, 99811bc41c8Sgww struct adt_event_state *event, char *notUsed) 99911bc41c8Sgww { 100011bc41c8Sgww ushort_t port; 100111bc41c8Sgww 100211bc41c8Sgww DPRINTF((" adt_to_iport dd_datatype=%d\n", def->dd_datatype)); 100311bc41c8Sgww 100411bc41c8Sgww port = ((union convert *)p_data)->tuint16; 100511bc41c8Sgww 100611bc41c8Sgww if (port == 0) { 100711bc41c8Sgww if (required == 0) { 100811bc41c8Sgww return; 100911bc41c8Sgww } 101011bc41c8Sgww /* required and not specified */ 101111bc41c8Sgww adt_write_syslog("adt_to_iport no required port", 0); 101211bc41c8Sgww } 101311bc41c8Sgww (void) au_write(event->ae_event_handle, au_to_iport(port)); 101411bc41c8Sgww 101511bc41c8Sgww } 101611bc41c8Sgww 10177c478bd9Sstevel@tonic-gate 10187c478bd9Sstevel@tonic-gate /* 1019f72effdeSgww * This is a compact table that defines only the tokens that are 1020f72effdeSgww * actually generated in the adt.xml file. It can't be a pure 1021f72effdeSgww * indexed table because the adt.xml language defines internal extension 1022f72effdeSgww * tokens for some processing. VIZ. ADT_CMD_ALT, ADT_AUT_PRIV_* (see 1023f72effdeSgww * adt_xlate.h), and the -AUT_PATH value. 10247c478bd9Sstevel@tonic-gate */ 10257c478bd9Sstevel@tonic-gate 1026*047f6e6fSgww #define MAX_TOKEN_JMP 21 10277c478bd9Sstevel@tonic-gate 10287c478bd9Sstevel@tonic-gate static struct token_jmp token_table[MAX_TOKEN_JMP] = 10297c478bd9Sstevel@tonic-gate { 10307c478bd9Sstevel@tonic-gate {AUT_CMD, adt_to_cmd}, 10317c478bd9Sstevel@tonic-gate {ADT_CMD_ALT, adt_to_cmd1}, 1032f72effdeSgww {AUT_FMRI, adt_to_frmi}, 1033f72effdeSgww {ADT_IN_PEER, adt_to_in_peer}, 103411bc41c8Sgww {ADT_IN_REMOTE, adt_to_in_remote}, 103511bc41c8Sgww {AUT_IPORT, adt_to_iport}, 1036f72effdeSgww {AUT_LABEL, adt_to_label}, 1037f72effdeSgww {AUT_NEWGROUPS, adt_to_newgroups}, 1038f72effdeSgww {AUT_PATH, adt_to_path}, 1039f72effdeSgww {-AUT_PATH, adt_to_pathlist}, /* private extension of token values */ 10407c478bd9Sstevel@tonic-gate {ADT_AUT_PRIV_L, adt_to_priv_limit}, 10417c478bd9Sstevel@tonic-gate {ADT_AUT_PRIV_I, adt_to_priv_inherit}, 10427c478bd9Sstevel@tonic-gate {ADT_AUT_PRIV_E, adt_to_priv_effective}, 10437c478bd9Sstevel@tonic-gate {AUT_PROCESS, adt_to_process}, 10447c478bd9Sstevel@tonic-gate {AUT_RETURN, adt_to_return}, 10457c478bd9Sstevel@tonic-gate {AUT_SUBJECT, adt_to_subject}, 10467c478bd9Sstevel@tonic-gate {AUT_TEXT, adt_to_text}, 1047103b2b15Sgww {AUT_TID, adt_to_tid}, 10487c478bd9Sstevel@tonic-gate {AUT_UAUTH, adt_to_uauth}, 1049*047f6e6fSgww {AUT_USER, adt_to_user}, 10507c478bd9Sstevel@tonic-gate {AUT_ZONENAME, adt_to_zonename} 10517c478bd9Sstevel@tonic-gate }; 1052f72effdeSgww 10537c478bd9Sstevel@tonic-gate /* 10547c478bd9Sstevel@tonic-gate * {AUT_ACL, adt_to_acl}, not used 10557c478bd9Sstevel@tonic-gate * {AUT_ARBITRARY, adt_to_arbitrary}, AUT_ARBITRARY is undefined 1056f72effdeSgww * {AUT_ARG, adt_to_arg}, not used 10577c478bd9Sstevel@tonic-gate * {AUT_ATTR, adt_to_attr}, not used in mountd 1058f72effdeSgww * {AUT_XATOM, adt_to_atom}, not used 10597c478bd9Sstevel@tonic-gate * {AUT_EXEC_ARGS, adt_to_exec_args}, not used 10607c478bd9Sstevel@tonic-gate * {AUT_EXEC_ENV, adt_to_exec_env}, not used 10617c478bd9Sstevel@tonic-gate * {AUT_EXIT, adt_to_exit}, obsolete 10627c478bd9Sstevel@tonic-gate * {AUT_FILE, adt_to_file}, AUT_FILE is undefined 1063f72effdeSgww * {AUT_XCOLORMAP, adt_to_colormap}, not used 1064f72effdeSgww * {AUT_XCURSOR, adt_to_cursor}, not used 1065f72effdeSgww * {AUT_XFONT, adt_to_font}, not used 1066f72effdeSgww * {AUT_XGC, adt_to_gc}, not used 10677c478bd9Sstevel@tonic-gate * {AUT_GROUPS, adt_to_groups}, obsolete 1068f72effdeSgww * {AUT_HEADER, adt_to_header}, generated by au_close 10697c478bd9Sstevel@tonic-gate * {AUT_IP, adt_to_ip}, not used 10707c478bd9Sstevel@tonic-gate * {AUT_IPC, adt_to_ipc}, not used 10717c478bd9Sstevel@tonic-gate * {AUT_IPC_PERM, adt_to_ipc_perm}, not used 10727c478bd9Sstevel@tonic-gate * {AUT_OPAQUE, adt_to_opaque}, not used 1073f72effdeSgww * {AUT_XPIXMAP, adt_to_pixmap}, not used 1074f72effdeSgww * {AUT_XPROPERTY, adt_to_property}, not used 10757c478bd9Sstevel@tonic-gate * {AUT_SEQ, adt_to_seq}, not used 10767c478bd9Sstevel@tonic-gate * {AUT_SOCKET, adt_to_socket}, not used 10777c478bd9Sstevel@tonic-gate * {AUT_SOCKET_INET, adt_to_socket_inet}, AUT_SOCKET_INET is undefined 1078f72effdeSgww * {AUT_TRAILER, adt_to_trailer}, generated by au_close 1079f72effdeSgww * {AUT_XCLIENT, adt_to_xclient} not used 10807c478bd9Sstevel@tonic-gate */ 10817c478bd9Sstevel@tonic-gate 10827c478bd9Sstevel@tonic-gate /* find function to generate token */ 10837c478bd9Sstevel@tonic-gate 10847c478bd9Sstevel@tonic-gate static adt_token_func_t 10857c478bd9Sstevel@tonic-gate adt_getTokenFunction(char token_id) 10867c478bd9Sstevel@tonic-gate { 10877c478bd9Sstevel@tonic-gate int i; 10887c478bd9Sstevel@tonic-gate struct token_jmp *p_jmp = token_table; 10897c478bd9Sstevel@tonic-gate 10907c478bd9Sstevel@tonic-gate for (i = 0; i < MAX_TOKEN_JMP; i++) { 10917c478bd9Sstevel@tonic-gate if (token_id == p_jmp->jmp_id) { 10927c478bd9Sstevel@tonic-gate return (p_jmp->jmp_to); 10937c478bd9Sstevel@tonic-gate } 10947c478bd9Sstevel@tonic-gate p_jmp++; 10957c478bd9Sstevel@tonic-gate } 10967c478bd9Sstevel@tonic-gate errno = EINVAL; 10977c478bd9Sstevel@tonic-gate return (NULL); 10987c478bd9Sstevel@tonic-gate } 10997c478bd9Sstevel@tonic-gate 11007c478bd9Sstevel@tonic-gate /* 11017c478bd9Sstevel@tonic-gate * adjustAddress -- given the address of data, its size, and the type of 11027c478bd9Sstevel@tonic-gate * the next data field, calculate the offset to the next piece of data. 11037c478bd9Sstevel@tonic-gate * Depending on the caller, "current" and "next" mean the current pointer 11047c478bd9Sstevel@tonic-gate * and the next pointer or the last pointer and the current pointer. 11057c478bd9Sstevel@tonic-gate */ 11067c478bd9Sstevel@tonic-gate void * 11077c478bd9Sstevel@tonic-gate adt_adjust_address(void *current_address, size_t current_size, 11087c478bd9Sstevel@tonic-gate size_t next_size) 11097c478bd9Sstevel@tonic-gate { 11107c478bd9Sstevel@tonic-gate ptrdiff_t adjustment; 11117c478bd9Sstevel@tonic-gate ptrdiff_t remainder; 11127c478bd9Sstevel@tonic-gate 11137c478bd9Sstevel@tonic-gate adjustment = (size_t)current_address + current_size; 11147c478bd9Sstevel@tonic-gate 11157c478bd9Sstevel@tonic-gate if (next_size) { 11167c478bd9Sstevel@tonic-gate remainder = adjustment % next_size; 11177c478bd9Sstevel@tonic-gate if (remainder != 0) 11187c478bd9Sstevel@tonic-gate adjustment += next_size - remainder; 11197c478bd9Sstevel@tonic-gate } 11207c478bd9Sstevel@tonic-gate return ((char *)adjustment); 11217c478bd9Sstevel@tonic-gate } 1122