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
check_inputs(int flags,const char * separator)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
print_audit_xml_prolog_buf(char * out_buf,const int out_buf_len)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
print_audit_xml_ending_buf(char * out_buf,const int out_buf_len)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
print_audit_xml_prolog(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
print_audit_xml_ending(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
checkpoint_progress(pr_context_t * context)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
print_audit_buf(char ** in_buf,int * in_buf_len,char ** out_buf,int * out_buf_len,const int flags,const char * separator)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
print_audit(const int flags,const char * separator)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
print_audit_common(pr_context_t * context,const int flags,const char * separator)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
token_processing(pr_context_t * context)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