1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 2003 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*7c478bd9Sstevel@tonic-gate 29*7c478bd9Sstevel@tonic-gate #include <dirent.h> 30*7c478bd9Sstevel@tonic-gate #include <locale.h> 31*7c478bd9Sstevel@tonic-gate #include <libintl.h> 32*7c478bd9Sstevel@tonic-gate #include <stdlib.h> 33*7c478bd9Sstevel@tonic-gate #include <strings.h> 34*7c478bd9Sstevel@tonic-gate #include <stdio.h> 35*7c478bd9Sstevel@tonic-gate #include <unistd.h> 36*7c478bd9Sstevel@tonic-gate 37*7c478bd9Sstevel@tonic-gate #include <sys/types.h> 38*7c478bd9Sstevel@tonic-gate #include <sys/file.h> 39*7c478bd9Sstevel@tonic-gate 40*7c478bd9Sstevel@tonic-gate #include <bsm/audit.h> 41*7c478bd9Sstevel@tonic-gate #include <bsm/audit_record.h> 42*7c478bd9Sstevel@tonic-gate #include <bsm/libbsm.h> 43*7c478bd9Sstevel@tonic-gate 44*7c478bd9Sstevel@tonic-gate #include "praudit.h" 45*7c478bd9Sstevel@tonic-gate #include "toktable.h" 46*7c478bd9Sstevel@tonic-gate 47*7c478bd9Sstevel@tonic-gate extern void init_tokens(void); /* shared with auditreduce */ 48*7c478bd9Sstevel@tonic-gate 49*7c478bd9Sstevel@tonic-gate static int check_inputs(int flags, const char *separator); 50*7c478bd9Sstevel@tonic-gate static void checkpoint_progress(pr_context_t *context); 51*7c478bd9Sstevel@tonic-gate static int print_audit_common(pr_context_t *context, int flags, 52*7c478bd9Sstevel@tonic-gate const char *separator); 53*7c478bd9Sstevel@tonic-gate static int token_processing(pr_context_t *context); 54*7c478bd9Sstevel@tonic-gate 55*7c478bd9Sstevel@tonic-gate static int initdone = 0; 56*7c478bd9Sstevel@tonic-gate 57*7c478bd9Sstevel@tonic-gate /* 58*7c478bd9Sstevel@tonic-gate * This source is shared outside of praudit; the following lint directive 59*7c478bd9Sstevel@tonic-gate * is needed to suppress praudit lint warnings about unused functions, for 60*7c478bd9Sstevel@tonic-gate * functions which are only invoked outside praudit. 61*7c478bd9Sstevel@tonic-gate */ 62*7c478bd9Sstevel@tonic-gate 63*7c478bd9Sstevel@tonic-gate /*LINTLIBRARY*/ 64*7c478bd9Sstevel@tonic-gate 65*7c478bd9Sstevel@tonic-gate /* 66*7c478bd9Sstevel@tonic-gate * ---------------------------------------------------------------------- 67*7c478bd9Sstevel@tonic-gate * check_inputs() - check input flags and delimiter. 68*7c478bd9Sstevel@tonic-gate * Returns: 69*7c478bd9Sstevel@tonic-gate * 0 - successful 70*7c478bd9Sstevel@tonic-gate * -1 - invalid inputs. errno is set to EINVAL 71*7c478bd9Sstevel@tonic-gate * ---------------------------------------------------------------------- 72*7c478bd9Sstevel@tonic-gate */ 73*7c478bd9Sstevel@tonic-gate static int 74*7c478bd9Sstevel@tonic-gate check_inputs(int flags, const char *separator) 75*7c478bd9Sstevel@tonic-gate { 76*7c478bd9Sstevel@tonic-gate if ((flags & PRF_RAWM) && (flags & PRF_SHORTM)) { 77*7c478bd9Sstevel@tonic-gate errno = EINVAL; 78*7c478bd9Sstevel@tonic-gate return (-1); 79*7c478bd9Sstevel@tonic-gate } 80*7c478bd9Sstevel@tonic-gate 81*7c478bd9Sstevel@tonic-gate /* Ignore the delimiter when XML is specified */ 82*7c478bd9Sstevel@tonic-gate if (!(flags & PRF_XMLM) && (strlen(separator) >= SEP_SIZE)) { 83*7c478bd9Sstevel@tonic-gate errno = EINVAL; 84*7c478bd9Sstevel@tonic-gate return (-1); 85*7c478bd9Sstevel@tonic-gate } 86*7c478bd9Sstevel@tonic-gate 87*7c478bd9Sstevel@tonic-gate return (0); 88*7c478bd9Sstevel@tonic-gate } 89*7c478bd9Sstevel@tonic-gate 90*7c478bd9Sstevel@tonic-gate /* 91*7c478bd9Sstevel@tonic-gate * ---------------------------------------------------------------------- 92*7c478bd9Sstevel@tonic-gate * print_audit_xml_prolog_buf() - print the XML prolog. 93*7c478bd9Sstevel@tonic-gate * 0 - successful 94*7c478bd9Sstevel@tonic-gate * -1 - output buffer too small. errno is set to ENOSPC 95*7c478bd9Sstevel@tonic-gate * ---------------------------------------------------------------------- 96*7c478bd9Sstevel@tonic-gate */ 97*7c478bd9Sstevel@tonic-gate int 98*7c478bd9Sstevel@tonic-gate print_audit_xml_prolog_buf(char *out_buf, const int out_buf_len) 99*7c478bd9Sstevel@tonic-gate { 100*7c478bd9Sstevel@tonic-gate if (xml_prolog_len > out_buf_len) { 101*7c478bd9Sstevel@tonic-gate errno = ENOSPC; 102*7c478bd9Sstevel@tonic-gate return (-1); 103*7c478bd9Sstevel@tonic-gate } 104*7c478bd9Sstevel@tonic-gate 105*7c478bd9Sstevel@tonic-gate (void) snprintf(out_buf, out_buf_len, "%s%s%s%s", prolog1, prolog_xsl, 106*7c478bd9Sstevel@tonic-gate prolog2, xml_start); 107*7c478bd9Sstevel@tonic-gate 108*7c478bd9Sstevel@tonic-gate return (0); 109*7c478bd9Sstevel@tonic-gate } 110*7c478bd9Sstevel@tonic-gate 111*7c478bd9Sstevel@tonic-gate /* 112*7c478bd9Sstevel@tonic-gate * ---------------------------------------------------------------------- 113*7c478bd9Sstevel@tonic-gate * print_audit_xml_ending_buf() - print the XML ending. 114*7c478bd9Sstevel@tonic-gate * 0 - successful 115*7c478bd9Sstevel@tonic-gate * -1 - output buffer too small. errno is set to ENOSPC 116*7c478bd9Sstevel@tonic-gate * ---------------------------------------------------------------------- 117*7c478bd9Sstevel@tonic-gate */ 118*7c478bd9Sstevel@tonic-gate int 119*7c478bd9Sstevel@tonic-gate print_audit_xml_ending_buf(char *out_buf, const int out_buf_len) 120*7c478bd9Sstevel@tonic-gate { 121*7c478bd9Sstevel@tonic-gate if (xml_end_len > out_buf_len) { 122*7c478bd9Sstevel@tonic-gate errno = ENOSPC; 123*7c478bd9Sstevel@tonic-gate return (-1); 124*7c478bd9Sstevel@tonic-gate } 125*7c478bd9Sstevel@tonic-gate 126*7c478bd9Sstevel@tonic-gate (void) snprintf(out_buf, out_buf_len, "%s", xml_ending); 127*7c478bd9Sstevel@tonic-gate return (0); 128*7c478bd9Sstevel@tonic-gate } 129*7c478bd9Sstevel@tonic-gate 130*7c478bd9Sstevel@tonic-gate /* 131*7c478bd9Sstevel@tonic-gate * ---------------------------------------------------------------------- 132*7c478bd9Sstevel@tonic-gate * print_prolog() - print the XML prolog. 133*7c478bd9Sstevel@tonic-gate * ---------------------------------------------------------------------- 134*7c478bd9Sstevel@tonic-gate */ 135*7c478bd9Sstevel@tonic-gate void 136*7c478bd9Sstevel@tonic-gate print_audit_xml_prolog(void) 137*7c478bd9Sstevel@tonic-gate { 138*7c478bd9Sstevel@tonic-gate (void) printf("%s%s%s%s", prolog1, prolog_xsl, prolog2, xml_start); 139*7c478bd9Sstevel@tonic-gate } 140*7c478bd9Sstevel@tonic-gate 141*7c478bd9Sstevel@tonic-gate /* 142*7c478bd9Sstevel@tonic-gate * ---------------------------------------------------------------------- 143*7c478bd9Sstevel@tonic-gate * print_ending() - print the XML ending. 144*7c478bd9Sstevel@tonic-gate * ---------------------------------------------------------------------- 145*7c478bd9Sstevel@tonic-gate */ 146*7c478bd9Sstevel@tonic-gate void 147*7c478bd9Sstevel@tonic-gate print_audit_xml_ending(void) 148*7c478bd9Sstevel@tonic-gate { 149*7c478bd9Sstevel@tonic-gate (void) printf("%s", xml_ending); 150*7c478bd9Sstevel@tonic-gate } 151*7c478bd9Sstevel@tonic-gate 152*7c478bd9Sstevel@tonic-gate /* 153*7c478bd9Sstevel@tonic-gate * ---------------------------------------------------------------------- 154*7c478bd9Sstevel@tonic-gate * checkpoint_progress() - If starting a new file or header token, 155*7c478bd9Sstevel@tonic-gate * checkpoint as needed to mark progress. 156*7c478bd9Sstevel@tonic-gate * ---------------------------------------------------------------------- 157*7c478bd9Sstevel@tonic-gate */ 158*7c478bd9Sstevel@tonic-gate static void 159*7c478bd9Sstevel@tonic-gate checkpoint_progress(pr_context_t *context) 160*7c478bd9Sstevel@tonic-gate { 161*7c478bd9Sstevel@tonic-gate int tokenid = context->tokenid; 162*7c478bd9Sstevel@tonic-gate 163*7c478bd9Sstevel@tonic-gate if (is_file_token(tokenid) || is_header_token(tokenid)) { 164*7c478bd9Sstevel@tonic-gate if (context->data_mode == BUFMODE) { 165*7c478bd9Sstevel@tonic-gate context->inbuf_last = context->audit_adr->adr_now - 1; 166*7c478bd9Sstevel@tonic-gate context->outbuf_last = context->outbuf_p; 167*7c478bd9Sstevel@tonic-gate } 168*7c478bd9Sstevel@tonic-gate context->audit_rec_start = context->audit_adr->adr_now - 1; 169*7c478bd9Sstevel@tonic-gate if (is_file_token(tokenid)) { 170*7c478bd9Sstevel@tonic-gate context->audit_rec_len = 11; 171*7c478bd9Sstevel@tonic-gate } 172*7c478bd9Sstevel@tonic-gate } 173*7c478bd9Sstevel@tonic-gate } 174*7c478bd9Sstevel@tonic-gate 175*7c478bd9Sstevel@tonic-gate /* 176*7c478bd9Sstevel@tonic-gate * ---------------------------------------------------------------------- 177*7c478bd9Sstevel@tonic-gate * print_audit_buf() - display contents of audit trail file 178*7c478bd9Sstevel@tonic-gate * 179*7c478bd9Sstevel@tonic-gate * Parses the binary audit data from the specified input 180*7c478bd9Sstevel@tonic-gate * buffer, and formats as requested to the specified output 181*7c478bd9Sstevel@tonic-gate * buffer. 182*7c478bd9Sstevel@tonic-gate * 183*7c478bd9Sstevel@tonic-gate * inputs: 184*7c478bd9Sstevel@tonic-gate * in_buf, - address and length of binary audit input. 185*7c478bd9Sstevel@tonic-gate * in_buf_len 186*7c478bd9Sstevel@tonic-gate * out_buf, - address and length of output buffer to 187*7c478bd9Sstevel@tonic-gate * out_buf_len copy formatted audit data to. 188*7c478bd9Sstevel@tonic-gate * flags - formatting flags as defined in praudit.h 189*7c478bd9Sstevel@tonic-gate * separator - field delimiter (or NULL if the default 190*7c478bd9Sstevel@tonic-gate * delimiter of comma is to be used). 191*7c478bd9Sstevel@tonic-gate * 192*7c478bd9Sstevel@tonic-gate * return codes: 0 - success 193*7c478bd9Sstevel@tonic-gate * ENOSPC... 194*7c478bd9Sstevel@tonic-gate * ---------------------------------------------------------------------- 195*7c478bd9Sstevel@tonic-gate */ 196*7c478bd9Sstevel@tonic-gate int 197*7c478bd9Sstevel@tonic-gate print_audit_buf(char **in_buf, int *in_buf_len, char **out_buf, 198*7c478bd9Sstevel@tonic-gate int *out_buf_len, const int flags, const char *separator) 199*7c478bd9Sstevel@tonic-gate { 200*7c478bd9Sstevel@tonic-gate int retstat = 0; 201*7c478bd9Sstevel@tonic-gate pr_context_t *context; 202*7c478bd9Sstevel@tonic-gate 203*7c478bd9Sstevel@tonic-gate if ((retstat = check_inputs(flags, separator)) != 0) 204*7c478bd9Sstevel@tonic-gate return (retstat); 205*7c478bd9Sstevel@tonic-gate 206*7c478bd9Sstevel@tonic-gate if ((context = (pr_context_t *)malloc(sizeof (pr_context_t))) == NULL) { 207*7c478bd9Sstevel@tonic-gate errno = EPERM; 208*7c478bd9Sstevel@tonic-gate return (-1); 209*7c478bd9Sstevel@tonic-gate } 210*7c478bd9Sstevel@tonic-gate 211*7c478bd9Sstevel@tonic-gate /* Init internal pointers and lengths... */ 212*7c478bd9Sstevel@tonic-gate context->data_mode = BUFMODE; 213*7c478bd9Sstevel@tonic-gate context->inbuf_last = context->inbuf_start = *in_buf; 214*7c478bd9Sstevel@tonic-gate context->inbuf_totalsize = *in_buf_len; 215*7c478bd9Sstevel@tonic-gate 216*7c478bd9Sstevel@tonic-gate context->pending_flag = 0; 217*7c478bd9Sstevel@tonic-gate context->current_rec = 0; 218*7c478bd9Sstevel@tonic-gate 219*7c478bd9Sstevel@tonic-gate context->outbuf_last = context->outbuf_start = 220*7c478bd9Sstevel@tonic-gate context->outbuf_p = *out_buf; 221*7c478bd9Sstevel@tonic-gate context->outbuf_remain_len = *out_buf_len; 222*7c478bd9Sstevel@tonic-gate 223*7c478bd9Sstevel@tonic-gate /* 224*7c478bd9Sstevel@tonic-gate * get an adr pointer to the audit input buf 225*7c478bd9Sstevel@tonic-gate */ 226*7c478bd9Sstevel@tonic-gate context->audit_adr = (adr_t *)malloc(sizeof (adr_t)); 227*7c478bd9Sstevel@tonic-gate (void) adrm_start(context->audit_adr, *in_buf); 228*7c478bd9Sstevel@tonic-gate context->audit_rec_start = NULL; 229*7c478bd9Sstevel@tonic-gate context->audit_rec_len = 0; 230*7c478bd9Sstevel@tonic-gate 231*7c478bd9Sstevel@tonic-gate retstat = print_audit_common(context, flags, separator); 232*7c478bd9Sstevel@tonic-gate 233*7c478bd9Sstevel@tonic-gate /* Check for and handle partial results as needed */ 234*7c478bd9Sstevel@tonic-gate if (retstat != 0) { 235*7c478bd9Sstevel@tonic-gate *in_buf = context->inbuf_last; 236*7c478bd9Sstevel@tonic-gate *in_buf_len = context->inbuf_totalsize - 237*7c478bd9Sstevel@tonic-gate (context->inbuf_last - context->inbuf_start); 238*7c478bd9Sstevel@tonic-gate 239*7c478bd9Sstevel@tonic-gate /* Return size of output */ 240*7c478bd9Sstevel@tonic-gate *out_buf_len = context->outbuf_last - context->outbuf_start; 241*7c478bd9Sstevel@tonic-gate if (*out_buf_len > 0) { 242*7c478bd9Sstevel@tonic-gate /* null-terminate the output */ 243*7c478bd9Sstevel@tonic-gate *(context->outbuf_last) = '\0'; 244*7c478bd9Sstevel@tonic-gate *out_buf_len = *out_buf_len + 1; 245*7c478bd9Sstevel@tonic-gate } 246*7c478bd9Sstevel@tonic-gate } else { 247*7c478bd9Sstevel@tonic-gate /* Return size of output */ 248*7c478bd9Sstevel@tonic-gate *out_buf_len = context->outbuf_p - context->outbuf_start + 1; 249*7c478bd9Sstevel@tonic-gate *(context->outbuf_p) = '\0'; /* null-terminate the output */ 250*7c478bd9Sstevel@tonic-gate } 251*7c478bd9Sstevel@tonic-gate 252*7c478bd9Sstevel@tonic-gate (void) free(context->audit_adr); 253*7c478bd9Sstevel@tonic-gate (void) free(context); 254*7c478bd9Sstevel@tonic-gate return (retstat); 255*7c478bd9Sstevel@tonic-gate } 256*7c478bd9Sstevel@tonic-gate 257*7c478bd9Sstevel@tonic-gate /* 258*7c478bd9Sstevel@tonic-gate * ---------------------------------------------------------------------- 259*7c478bd9Sstevel@tonic-gate * print_audit() - display contents of audit trail file 260*7c478bd9Sstevel@tonic-gate * 261*7c478bd9Sstevel@tonic-gate * Parses the binary audit data from the file mapped as stdin, 262*7c478bd9Sstevel@tonic-gate * and formats as requested to file mapped as stdout. 263*7c478bd9Sstevel@tonic-gate * inputs: 264*7c478bd9Sstevel@tonic-gate * flags - formatting flags as defined in praudit.h 265*7c478bd9Sstevel@tonic-gate * separator - field delimiter (or NULL if the default 266*7c478bd9Sstevel@tonic-gate * delimiter of comma is to be used). 267*7c478bd9Sstevel@tonic-gate * 268*7c478bd9Sstevel@tonic-gate * return codes: -1 - error 269*7c478bd9Sstevel@tonic-gate * 0 - successful 270*7c478bd9Sstevel@tonic-gate * ---------------------------------------------------------------------- 271*7c478bd9Sstevel@tonic-gate */ 272*7c478bd9Sstevel@tonic-gate int 273*7c478bd9Sstevel@tonic-gate print_audit(const int flags, const char *separator) 274*7c478bd9Sstevel@tonic-gate { 275*7c478bd9Sstevel@tonic-gate int retstat = 0; 276*7c478bd9Sstevel@tonic-gate pr_context_t *context; 277*7c478bd9Sstevel@tonic-gate 278*7c478bd9Sstevel@tonic-gate if ((retstat = check_inputs(flags, separator)) != 0) 279*7c478bd9Sstevel@tonic-gate return (retstat); 280*7c478bd9Sstevel@tonic-gate 281*7c478bd9Sstevel@tonic-gate if ((context = (pr_context_t *)malloc(sizeof (pr_context_t))) == NULL) { 282*7c478bd9Sstevel@tonic-gate errno = EPERM; 283*7c478bd9Sstevel@tonic-gate return (-1); 284*7c478bd9Sstevel@tonic-gate } 285*7c478bd9Sstevel@tonic-gate 286*7c478bd9Sstevel@tonic-gate /* 287*7c478bd9Sstevel@tonic-gate * get an adr pointer to the current audit file (stdin) 288*7c478bd9Sstevel@tonic-gate */ 289*7c478bd9Sstevel@tonic-gate context->audit_adr = malloc(sizeof (adr_t)); 290*7c478bd9Sstevel@tonic-gate context->audit_adrf = malloc(sizeof (adrf_t)); 291*7c478bd9Sstevel@tonic-gate 292*7c478bd9Sstevel@tonic-gate adrf_start(context->audit_adrf, context->audit_adr, stdin); 293*7c478bd9Sstevel@tonic-gate 294*7c478bd9Sstevel@tonic-gate context->data_mode = FILEMODE; 295*7c478bd9Sstevel@tonic-gate context->audit_rec_start = NULL; 296*7c478bd9Sstevel@tonic-gate context->audit_rec_len = 0; 297*7c478bd9Sstevel@tonic-gate 298*7c478bd9Sstevel@tonic-gate context->pending_flag = 0; 299*7c478bd9Sstevel@tonic-gate context->current_rec = 0; 300*7c478bd9Sstevel@tonic-gate 301*7c478bd9Sstevel@tonic-gate retstat = print_audit_common(context, flags, separator); 302*7c478bd9Sstevel@tonic-gate 303*7c478bd9Sstevel@tonic-gate (void) free(context->audit_adr); 304*7c478bd9Sstevel@tonic-gate (void) free(context->audit_adrf); 305*7c478bd9Sstevel@tonic-gate (void) free(context); 306*7c478bd9Sstevel@tonic-gate return (retstat); 307*7c478bd9Sstevel@tonic-gate } 308*7c478bd9Sstevel@tonic-gate 309*7c478bd9Sstevel@tonic-gate /* 310*7c478bd9Sstevel@tonic-gate * ---------------------------------------------------------------------- 311*7c478bd9Sstevel@tonic-gate * print_audit_common() - common routine for print_audit* functions. 312*7c478bd9Sstevel@tonic-gate * 313*7c478bd9Sstevel@tonic-gate * Parses the binary audit data, and formats as requested. 314*7c478bd9Sstevel@tonic-gate * The context parameter defines whether the source of the 315*7c478bd9Sstevel@tonic-gate * audit data is a buffer, or a file mapped to stdin, and 316*7c478bd9Sstevel@tonic-gate * whether the output is to a buffer or a file mapped to 317*7c478bd9Sstevel@tonic-gate * stdout. 318*7c478bd9Sstevel@tonic-gate * 319*7c478bd9Sstevel@tonic-gate * inputs: 320*7c478bd9Sstevel@tonic-gate * context - defines the context of the request, including 321*7c478bd9Sstevel@tonic-gate * info about the source and output. 322*7c478bd9Sstevel@tonic-gate * flags - formatting flags as defined in praudit.h 323*7c478bd9Sstevel@tonic-gate * separator - field delimiter (or NULL if the default 324*7c478bd9Sstevel@tonic-gate * delimiter of comma is to be used). 325*7c478bd9Sstevel@tonic-gate * 326*7c478bd9Sstevel@tonic-gate * return codes: -1 - error 327*7c478bd9Sstevel@tonic-gate * 0 - successful 328*7c478bd9Sstevel@tonic-gate * ---------------------------------------------------------------------- 329*7c478bd9Sstevel@tonic-gate */ 330*7c478bd9Sstevel@tonic-gate static int 331*7c478bd9Sstevel@tonic-gate print_audit_common(pr_context_t *context, const int flags, 332*7c478bd9Sstevel@tonic-gate const char *separator) 333*7c478bd9Sstevel@tonic-gate { 334*7c478bd9Sstevel@tonic-gate int retstat = 0; 335*7c478bd9Sstevel@tonic-gate 336*7c478bd9Sstevel@tonic-gate if (!initdone) { 337*7c478bd9Sstevel@tonic-gate init_tokens(); 338*7c478bd9Sstevel@tonic-gate initdone++; 339*7c478bd9Sstevel@tonic-gate } 340*7c478bd9Sstevel@tonic-gate 341*7c478bd9Sstevel@tonic-gate context->format = flags; 342*7c478bd9Sstevel@tonic-gate 343*7c478bd9Sstevel@tonic-gate /* start with default delimiter of comma */ 344*7c478bd9Sstevel@tonic-gate (void) strlcpy(context->SEPARATOR, ",", SEP_SIZE); 345*7c478bd9Sstevel@tonic-gate if (separator != NULL) { 346*7c478bd9Sstevel@tonic-gate if (strlen(separator) < SEP_SIZE) { 347*7c478bd9Sstevel@tonic-gate (void) strlcpy(context->SEPARATOR, separator, SEP_SIZE); 348*7c478bd9Sstevel@tonic-gate } 349*7c478bd9Sstevel@tonic-gate } 350*7c478bd9Sstevel@tonic-gate 351*7c478bd9Sstevel@tonic-gate while ((retstat == 0) && pr_input_remaining(context, 1)) { 352*7c478bd9Sstevel@tonic-gate if (pr_adr_char(context, (char *)&(context->tokenid), 1) == 0) { 353*7c478bd9Sstevel@tonic-gate retstat = token_processing(context); 354*7c478bd9Sstevel@tonic-gate } else 355*7c478bd9Sstevel@tonic-gate break; 356*7c478bd9Sstevel@tonic-gate } 357*7c478bd9Sstevel@tonic-gate 358*7c478bd9Sstevel@tonic-gate /* 359*7c478bd9Sstevel@tonic-gate * For buffer processing, if the entire input buffer was processed 360*7c478bd9Sstevel@tonic-gate * successfully, but the last record in the buffer was incomplete 361*7c478bd9Sstevel@tonic-gate * (according to the length from its header), then reflect an 362*7c478bd9Sstevel@tonic-gate * "incomplete input" error (which will cause partial results to be 363*7c478bd9Sstevel@tonic-gate * returned). 364*7c478bd9Sstevel@tonic-gate */ 365*7c478bd9Sstevel@tonic-gate if ((context->data_mode == BUFMODE) && (retstat == 0) && 366*7c478bd9Sstevel@tonic-gate (context->audit_adr->adr_now < (context->audit_rec_start + 367*7c478bd9Sstevel@tonic-gate context->audit_rec_len))) { 368*7c478bd9Sstevel@tonic-gate retstat = -1; 369*7c478bd9Sstevel@tonic-gate errno = EIO; 370*7c478bd9Sstevel@tonic-gate } 371*7c478bd9Sstevel@tonic-gate 372*7c478bd9Sstevel@tonic-gate /* 373*7c478bd9Sstevel@tonic-gate * If there was a last record that didn't get officially closed 374*7c478bd9Sstevel@tonic-gate * off, do it now. 375*7c478bd9Sstevel@tonic-gate */ 376*7c478bd9Sstevel@tonic-gate if ((retstat == 0) && (context->format & PRF_XMLM) && 377*7c478bd9Sstevel@tonic-gate (context->current_rec)) { 378*7c478bd9Sstevel@tonic-gate retstat = do_newline(context, 1); 379*7c478bd9Sstevel@tonic-gate if (retstat == 0) 380*7c478bd9Sstevel@tonic-gate retstat = close_tag(context, context->current_rec); 381*7c478bd9Sstevel@tonic-gate } 382*7c478bd9Sstevel@tonic-gate 383*7c478bd9Sstevel@tonic-gate return (retstat); 384*7c478bd9Sstevel@tonic-gate } 385*7c478bd9Sstevel@tonic-gate 386*7c478bd9Sstevel@tonic-gate /* 387*7c478bd9Sstevel@tonic-gate * ----------------------------------------------------------------------- 388*7c478bd9Sstevel@tonic-gate * token_processing: 389*7c478bd9Sstevel@tonic-gate * Calls the routine corresponding to the token id 390*7c478bd9Sstevel@tonic-gate * passed in the parameter from the token table, tokentable 391*7c478bd9Sstevel@tonic-gate * return codes : -1 - error 392*7c478bd9Sstevel@tonic-gate * : 0 - successful 393*7c478bd9Sstevel@tonic-gate * ----------------------------------------------------------------------- 394*7c478bd9Sstevel@tonic-gate */ 395*7c478bd9Sstevel@tonic-gate static int 396*7c478bd9Sstevel@tonic-gate token_processing(pr_context_t *context) 397*7c478bd9Sstevel@tonic-gate { 398*7c478bd9Sstevel@tonic-gate uval_t uval; 399*7c478bd9Sstevel@tonic-gate int retstat; 400*7c478bd9Sstevel@tonic-gate int tokenid = context->tokenid; 401*7c478bd9Sstevel@tonic-gate 402*7c478bd9Sstevel@tonic-gate if ((tokenid > 0) && (tokenid <= MAXTOKEN) && 403*7c478bd9Sstevel@tonic-gate (tokentable[tokenid].func != NOFUNC)) { 404*7c478bd9Sstevel@tonic-gate /* 405*7c478bd9Sstevel@tonic-gate * First check if there's a previous record that needs to be 406*7c478bd9Sstevel@tonic-gate * closed off now; then checkpoint our progress as needed. 407*7c478bd9Sstevel@tonic-gate */ 408*7c478bd9Sstevel@tonic-gate if ((retstat = check_close_rec(context, tokenid)) != 0) 409*7c478bd9Sstevel@tonic-gate return (retstat); 410*7c478bd9Sstevel@tonic-gate checkpoint_progress(context); 411*7c478bd9Sstevel@tonic-gate 412*7c478bd9Sstevel@tonic-gate /* print token name */ 413*7c478bd9Sstevel@tonic-gate if (context->format & PRF_XMLM) { 414*7c478bd9Sstevel@tonic-gate retstat = open_tag(context, tokenid); 415*7c478bd9Sstevel@tonic-gate } else { 416*7c478bd9Sstevel@tonic-gate if (!(context->format & PRF_RAWM) && 417*7c478bd9Sstevel@tonic-gate (tokentable[tokenid].t_name != (char *)0)) { 418*7c478bd9Sstevel@tonic-gate uval.uvaltype = PRA_STRING; 419*7c478bd9Sstevel@tonic-gate uval.string_val = 420*7c478bd9Sstevel@tonic-gate gettext(tokentable[tokenid].t_name); 421*7c478bd9Sstevel@tonic-gate } else { 422*7c478bd9Sstevel@tonic-gate uval.uvaltype = PRA_BYTE; 423*7c478bd9Sstevel@tonic-gate uval.char_val = tokenid; 424*7c478bd9Sstevel@tonic-gate } 425*7c478bd9Sstevel@tonic-gate retstat = pa_print(context, &uval, 0); 426*7c478bd9Sstevel@tonic-gate } 427*7c478bd9Sstevel@tonic-gate if (retstat == 0) 428*7c478bd9Sstevel@tonic-gate retstat = (*tokentable[tokenid].func)(context); 429*7c478bd9Sstevel@tonic-gate 430*7c478bd9Sstevel@tonic-gate /* 431*7c478bd9Sstevel@tonic-gate * For XML, close the token tag. Header tokens wrap the 432*7c478bd9Sstevel@tonic-gate * entire record, so they only get closed later implicitly; 433*7c478bd9Sstevel@tonic-gate * here, just make sure the header open tag gets finished. 434*7c478bd9Sstevel@tonic-gate */ 435*7c478bd9Sstevel@tonic-gate if ((retstat == 0) && (context->format & PRF_XMLM)) { 436*7c478bd9Sstevel@tonic-gate if (!is_header_token(tokenid)) 437*7c478bd9Sstevel@tonic-gate retstat = close_tag(context, tokenid); 438*7c478bd9Sstevel@tonic-gate else 439*7c478bd9Sstevel@tonic-gate retstat = finish_open_tag(context); 440*7c478bd9Sstevel@tonic-gate } 441*7c478bd9Sstevel@tonic-gate return (retstat); 442*7c478bd9Sstevel@tonic-gate } 443*7c478bd9Sstevel@tonic-gate /* here if token id is not in table */ 444*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("praudit: No code associated with " 445*7c478bd9Sstevel@tonic-gate "token id %d\n"), tokenid); 446*7c478bd9Sstevel@tonic-gate return (0); 447*7c478bd9Sstevel@tonic-gate } 448