Print this page
NEX-13644 File access audit logging
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
Reviewed by: Saso Kiselkov <saso.kiselkov@nexenta.com>
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/cmd/praudit/format.c
+++ new/usr/src/cmd/praudit/format.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
|
↓ open down ↓ |
13 lines elided |
↑ open up ↑ |
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 + *
25 + * Copyright 2018 Nexenta Systems, Inc. All rights reserved.
24 26 */
25 27
26 28
27 29 #define _REENTRANT
28 30
29 31 #include <ctype.h>
30 32 #include <errno.h>
31 33 #include <grp.h>
32 34 #include <libintl.h>
33 35 #include <netdb.h>
34 36 #include <time.h>
35 37 #include <pwd.h>
36 38 #include <stdio.h>
37 39 #include <stdlib.h>
38 40 #include <string.h>
39 41 #include <wchar.h>
40 42
41 43 #include <arpa/inet.h>
|
↓ open down ↓ |
8 lines elided |
↑ open up ↑ |
42 44
43 45 #include <bsm/audit.h>
44 46 #include <bsm/audit_record.h>
45 47 #include <bsm/libbsm.h>
46 48 #include <security/pam_appl.h>
47 49
48 50 #include <sys/inttypes.h>
49 51 #include <sys/mkdev.h>
50 52 #include <sys/types.h>
51 53 #include <aclutils.h>
54 +#include <smbsrv/libsmb.h>
52 55
53 56 #include "praudit.h"
54 57 #include "toktable.h"
55 58 #include "adt_xlate.h"
56 59
57 60 static void convertascii(char *p, char *c, int size);
58 61 static int convertbinary(char *p, char *c, int size);
59 62 static void eventmodifier2string(au_emod_t emodifier, char *modstring,
60 63 size_t modlen);
61 64 static int do_mtime32(pr_context_t *context, int status, int flag,
62 65 uint32_t scale);
63 66 static int do_mtime64(pr_context_t *context, int status, int flag,
64 67 uint64_t scale);
65 68
66 69 /*
67 70 * ------------------------------------------------------
68 71 * field widths for arbitrary data token type
69 72 * ------------------------------------------------------
70 73 */
71 74 static struct fw {
72 75 char basic_unit;
73 76 struct {
74 77 char print_base;
75 78 int field_width;
76 79 } pwidth[5];
77 80 } fwidth[] = {
78 81 /* character data type, 8 bits */
79 82 AUR_CHAR, AUP_BINARY, 12,
80 83 AUP_OCTAL, 6,
81 84 AUP_DECIMAL, 6,
82 85 AUP_HEX, 6,
83 86 AUP_STRING, 1,
84 87 AUR_BYTE, AUP_BINARY, 12,
85 88 AUP_OCTAL, 6,
86 89 AUP_DECIMAL, 6,
87 90 AUP_HEX, 6,
88 91 AUP_STRING, 1,
89 92 AUR_SHORT, AUP_BINARY, 20,
90 93 AUP_OCTAL, 10,
91 94 AUP_DECIMAL, 10,
92 95 AUP_HEX, 8,
93 96 AUP_STRING, 6,
94 97 AUR_INT32, AUP_BINARY, 36,
95 98 AUP_OCTAL, 18,
96 99 AUP_DECIMAL, 18,
97 100 AUP_HEX, 12,
98 101 AUP_STRING, 10,
99 102 AUR_INT64, AUP_BINARY, 68,
100 103 AUP_OCTAL, 34,
101 104 AUP_DECIMAL, 34,
102 105 AUP_HEX, 20,
103 106 AUP_STRING, 20};
104 107
105 108
106 109 static int numwidthentries = sizeof (fwidth)
107 110 / sizeof (struct fw);
108 111
109 112
110 113 /*
111 114 * -----------------------------------------------------------------------
112 115 * do_newline:
113 116 * Print a newline, if needed according to various formatting
114 117 * rules.
115 118 * return codes : 0 - success
116 119 * : -1 - error
117 120 * -----------------------------------------------------------------------
118 121 */
119 122 int
120 123 do_newline(pr_context_t *context, int flag)
121 124 {
122 125 int retstat = 0;
123 126
124 127 if (!(context->format & PRF_ONELINE) && (flag == 1))
125 128 retstat = pr_putchar(context, '\n');
126 129 else if (!(context->format & PRF_XMLM))
127 130 retstat = pr_printf(context, "%s", context->SEPARATOR);
128 131
129 132 return (retstat);
130 133 }
131 134
132 135 int
133 136 open_tag(pr_context_t *context, int tagnum)
134 137 {
135 138 int err = 0;
136 139 token_desc_t *tag;
137 140
138 141 /* no-op if not doing XML format */
139 142 if (!(context->format & PRF_XMLM))
140 143 return (0);
141 144
142 145 tag = &tokentable[tagnum];
143 146
144 147 /*
145 148 * First if needed do an implicit finish of a pending open for an
146 149 * extended tag. I.e., for the extended tag xxx:
147 150 * <xxx a=".." b=".."> ... </xxx>
148 151 * -- insert a close bracket after the last attribute
149 152 * (in other words, when the 1st non-attribute is opened while
150 153 * this is pending). Note that only one tag could be pending at
151 154 * a given time -- it couldn't be nested.
152 155 */
153 156 if (context->pending_flag && (tag->t_type != T_ATTRIBUTE)) {
154 157 /* complete pending extended open */
155 158 err = pr_putchar(context, '>');
156 159 if (err != 0)
157 160 return (err);
158 161 context->pending_flag = 0;
159 162 }
160 163
161 164 if (is_header_token(tagnum) || is_file_token(tagnum)) {
162 165 /* File token or new record on new line */
163 166 err = pr_putchar(context, '\n');
164 167 } else if (is_token(tagnum)) {
165 168 /* Each token on new line if possible */
166 169 err = do_newline(context, 1);
167 170 }
168 171 if (err != 0)
169 172 return (err);
170 173
171 174 switch (tag->t_type) {
172 175 case T_ATTRIBUTE:
173 176 err = pr_printf(context, " %s=\"", tag->t_tagname);
174 177 break;
175 178 case T_ELEMENT:
176 179 err = pr_printf(context, "<%s>", tag->t_tagname);
177 180 break;
178 181 case T_ENCLOSED:
179 182 err = pr_printf(context, "<%s", tag->t_tagname);
180 183 break;
181 184 case T_EXTENDED:
182 185 err = pr_printf(context, "<%s", tag->t_tagname);
183 186 if (err == 0)
184 187 context->pending_flag = tagnum;
185 188 break;
186 189 default:
187 190 break;
188 191 }
189 192
190 193 if (is_header_token(tagnum) && (err == 0))
191 194 context->current_rec = tagnum; /* set start of new record */
192 195
193 196 return (err);
194 197 }
195 198
196 199 /*
197 200 * Do an implicit close of a record when needed.
198 201 */
199 202 int
200 203 check_close_rec(pr_context_t *context, int tagnum)
201 204 {
202 205 int err = 0;
203 206
204 207 /* no-op if not doing XML format */
205 208 if (!(context->format & PRF_XMLM))
206 209 return (0);
207 210
208 211 /*
209 212 * If we're opening a header or the file token (i.e., starting a new
210 213 * record), if there's a current record in progress do an implicit
211 214 * close of it.
212 215 */
213 216 if ((is_header_token(tagnum) || is_file_token(tagnum)) &&
214 217 context->current_rec) {
215 218 err = do_newline(context, 1);
216 219 if (err == 0)
217 220 err = close_tag(context, context->current_rec);
218 221 }
219 222
220 223 return (err);
221 224 }
222 225
223 226 /*
224 227 * explicit finish of a pending open for an extended tag.
225 228 */
226 229 int
227 230 finish_open_tag(pr_context_t *context)
228 231 {
229 232 int err = 0;
230 233
231 234 /* no-op if not doing XML format */
232 235 if (!(context->format & PRF_XMLM))
233 236 return (0);
234 237
235 238 if (context->pending_flag) {
236 239 /* complete pending extended open */
237 240 err = pr_putchar(context, '>');
238 241 if (err == 0)
239 242 context->pending_flag = 0;
240 243 }
241 244 return (err);
242 245 }
243 246
244 247 int
245 248 close_tag(pr_context_t *context, int tagnum)
246 249 {
247 250 int err = 0;
248 251 token_desc_t *tag;
249 252
250 253 /* no-op if not doing XML format */
251 254 if (!(context->format & PRF_XMLM))
252 255 return (0);
253 256
254 257 tag = &tokentable[tagnum];
255 258
256 259 switch (tag->t_type) {
257 260 case T_ATTRIBUTE:
258 261 err = pr_putchar(context, '\"');
259 262 break;
260 263 case T_ELEMENT:
261 264 err = pr_printf(context, "</%s>", tag->t_tagname);
262 265 break;
263 266 case T_ENCLOSED:
264 267 err = pr_printf(context, "/>");
265 268 break;
266 269 case T_EXTENDED:
267 270 err = pr_printf(context, "</%s>", tag->t_tagname);
268 271 break;
269 272 default:
270 273 break;
271 274 }
272 275
273 276 if (is_header_token(tagnum) && (err == 0))
274 277 context->current_rec = 0; /* closing rec; none current */
275 278
276 279 return (err);
277 280 }
278 281
279 282 /*
280 283 * -----------------------------------------------------------------------
281 284 * process_tag:
282 285 * Calls the routine corresponding to the tag
283 286 * Note that to use this mechanism, all such routines must
284 287 * take 2 ints for their parameters; the first of these is
285 288 * the current status.
286 289 *
287 290 * flag = 1 for newline / delimiter, else 0
288 291 * return codes : -1 - error
289 292 * : 0 - successful
290 293 * -----------------------------------------------------------------------
291 294 */
292 295 int
293 296 process_tag(pr_context_t *context, int tagnum, int status, int flag)
294 297 {
295 298 int retstat;
296 299
297 300 retstat = status;
298 301
299 302 if (retstat)
300 303 return (retstat);
301 304
302 305 if ((tagnum > 0) && (tagnum <= MAXTAG) &&
303 306 (tokentable[tagnum].func != NOFUNC)) {
304 307 retstat = open_tag(context, tagnum);
305 308 if (!retstat)
306 309 retstat = (*tokentable[tagnum].func)(context, status,
307 310 flag);
308 311 if (!retstat)
309 312 retstat = close_tag(context, tagnum);
310 313 return (retstat);
311 314 }
312 315 /* here if token id is not in table */
313 316 (void) fprintf(stderr, gettext("praudit: No code associated with "
314 317 "tag id %d\n"), tagnum);
315 318 return (0);
316 319 }
317 320
318 321 void
319 322 get_Hname(uint32_t addr, char *buf, size_t buflen)
320 323 {
321 324 extern char *inet_ntoa(const struct in_addr);
322 325 struct hostent *phe;
323 326 struct in_addr ia;
324 327
325 328 phe = gethostbyaddr((const char *)&addr, 4, AF_INET);
326 329 if (phe == (struct hostent *)0) {
327 330 ia.s_addr = addr;
328 331 (void) snprintf(buf, buflen, "%s", inet_ntoa(ia));
329 332 return;
330 333 }
331 334 ia.s_addr = addr;
332 335 (void) snprintf(buf, buflen, "%s", phe->h_name);
333 336 }
334 337
335 338 void
336 339 get_Hname_ex(uint32_t *addr, char *buf, size_t buflen)
337 340 {
338 341 struct hostent *phe;
339 342 int err;
340 343
341 344 phe = getipnodebyaddr((const void *)addr, 16, AF_INET6, &err);
342 345
343 346 if (phe == (struct hostent *)0) {
344 347 (void) inet_ntop(AF_INET6, (void *)addr, buf, buflen);
345 348 } else
346 349 (void) snprintf(buf, buflen, "%s", phe->h_name);
347 350
348 351 if (phe)
349 352 freehostent(phe);
350 353 }
351 354
352 355 int
353 356 pa_hostname(pr_context_t *context, int status, int flag)
354 357 {
355 358 int returnstat;
356 359 uint32_t ip_addr;
357 360 struct in_addr ia;
358 361 uval_t uval;
359 362 char buf[256];
360 363
361 364 if (status < 0)
362 365 return (status);
363 366
364 367 if ((returnstat = pr_adr_char(context, (char *)&ip_addr, 4)) != 0)
365 368 return (returnstat);
366 369
367 370 uval.uvaltype = PRA_STRING;
368 371
369 372 if (!(context->format & PRF_RAWM)) {
370 373 uval.string_val = buf;
371 374 get_Hname(ip_addr, buf, sizeof (buf));
372 375 returnstat = pa_print(context, &uval, flag);
373 376 } else {
374 377 ia.s_addr = ip_addr;
375 378 if ((uval.string_val = inet_ntoa(ia)) == NULL)
376 379 return (-1);
377 380 returnstat = pa_print(context, &uval, flag);
378 381 }
379 382 return (returnstat);
380 383 }
381 384
382 385 int
383 386 pa_hostname_ex(pr_context_t *context, int status, int flag)
384 387 {
385 388 int returnstat;
386 389 uint32_t ip_type;
387 390 uint32_t ip_addr[4];
388 391 struct in_addr ia;
389 392 char buf[256];
390 393 uval_t uval;
391 394
392 395 if (status < 0)
393 396 return (status);
394 397
395 398 /* get ip type */
396 399 if ((returnstat = pr_adr_int32(context, (int32_t *)&ip_type, 1)) != 0)
397 400 return (returnstat);
398 401
399 402 /* only IPv4 and IPv6 addresses are legal */
400 403 if ((ip_type != AU_IPv4) && (ip_type != AU_IPv6))
401 404 return (-1);
402 405
403 406 /* get ip address */
404 407 if ((returnstat = pr_adr_char(context, (char *)ip_addr, ip_type)) != 0)
405 408 return (returnstat);
406 409
407 410 if ((returnstat = open_tag(context, TAG_HOSTID)) != 0)
408 411 return (returnstat);
409 412
410 413 uval.uvaltype = PRA_STRING;
411 414 if (ip_type == AU_IPv4) { /* ipv4 address */
412 415 if (!(context->format & PRF_RAWM)) {
413 416 uval.string_val = buf;
414 417 get_Hname(ip_addr[0], buf, sizeof (buf));
415 418 returnstat = pa_print(context, &uval, flag);
416 419 } else {
417 420 ia.s_addr = ip_addr[0];
418 421 if ((uval.string_val = inet_ntoa(ia)) == NULL)
419 422 return (-1);
420 423 returnstat = pa_print(context, &uval, flag);
421 424 }
422 425 } else if (ip_type == AU_IPv6) { /* IPv6 addresss (128 bits) */
423 426 if (!(context->format & PRF_RAWM)) {
424 427 uval.string_val = buf;
425 428 get_Hname_ex(ip_addr, buf, sizeof (buf));
426 429 returnstat = pa_print(context, &uval, flag);
427 430 } else {
428 431 uval.string_val = (char *)buf;
429 432 (void) inet_ntop(AF_INET6, (void *)ip_addr, buf,
430 433 sizeof (buf));
431 434 returnstat = pa_print(context, &uval, flag);
432 435 }
433 436 }
434 437
435 438 if (returnstat != 0)
436 439 return (returnstat);
437 440 return (close_tag(context, TAG_HOSTID));
438 441 }
439 442
440 443 int
441 444 pa_hostname_so(pr_context_t *context, int status, int flag)
442 445 {
443 446 int returnstat;
444 447 short ip_type;
445 448 ushort_t ip_port;
446 449 uint32_t ip_addr[4];
447 450 struct in_addr ia;
448 451 char buf[256];
449 452 uval_t uval;
450 453
451 454 if (status < 0)
452 455 return (status);
453 456
454 457 /* get ip type */
455 458 if ((returnstat = pr_adr_short(context, &ip_type, 1)) != 0)
456 459 return (returnstat);
457 460
458 461 /* only IPv4 and IPv6 addresses are legal */
459 462 if ((ip_type != AU_IPv4) && (ip_type != AU_IPv6))
460 463 return (-1);
461 464
462 465 /* get local ip port */
463 466 if ((returnstat = pr_adr_u_short(context, &ip_port, 1)) != 0)
464 467 return (returnstat);
465 468
466 469 if ((returnstat = open_tag(context, TAG_SOCKEXLPORT)) != 0)
467 470 return (returnstat);
468 471
469 472 uval.uvaltype = PRA_STRING;
470 473 uval.string_val = hexconvert((char *)&ip_port, sizeof (ip_port),
471 474 sizeof (ip_port));
472 475 if (uval.string_val) {
473 476 returnstat = pa_print(context, &uval, 0);
474 477 free(uval.string_val);
475 478 } else
476 479 returnstat = -1;
477 480 if (returnstat)
478 481 return (returnstat);
479 482
480 483 if ((returnstat = close_tag(context, TAG_SOCKEXLPORT)) != 0)
481 484 return (returnstat);
482 485
483 486 /* get local ip address */
484 487 if ((returnstat = pr_adr_char(context, (char *)ip_addr, ip_type)) != 0)
485 488 return (returnstat);
486 489
487 490 if ((returnstat = open_tag(context, TAG_SOCKEXLADDR)) != 0)
488 491 return (returnstat);
489 492
490 493 if (ip_type == AU_IPv4) { /* ipv4 address */
491 494
492 495 if (!(context->format & PRF_RAWM)) {
493 496 uval.string_val = buf;
494 497 get_Hname(ip_addr[0], buf, sizeof (buf));
495 498 returnstat = pa_print(context, &uval, 0);
496 499 } else {
497 500 ia.s_addr = ip_addr[0];
498 501 if ((uval.string_val = inet_ntoa(ia)) == NULL)
499 502 return (-1);
500 503 returnstat = pa_print(context, &uval, 0);
501 504 }
502 505
503 506 } else if (ip_type == AU_IPv6) { /* IPv6 addresss (128 bits) */
504 507
505 508 if (!(context->format & PRF_RAWM)) {
506 509 uval.string_val = buf;
507 510 get_Hname_ex(ip_addr, buf, sizeof (buf));
508 511 returnstat = pa_print(context, &uval, 0);
509 512 } else {
510 513 uval.string_val = (char *)buf;
511 514 (void) inet_ntop(AF_INET6, (void *)ip_addr, buf,
512 515 sizeof (buf));
513 516 returnstat = pa_print(context, &uval, 0);
514 517 }
515 518 } else
516 519 returnstat = -1;
517 520
518 521 if (returnstat)
519 522 return (returnstat);
520 523
521 524 if ((returnstat = close_tag(context, TAG_SOCKEXLADDR)) != 0)
522 525 return (returnstat);
523 526
524 527 /* get foreign ip port */
525 528 if ((returnstat = pr_adr_u_short(context, &ip_port, 1)) != 0)
526 529 return (returnstat);
527 530
528 531 if ((returnstat = open_tag(context, TAG_SOCKEXFPORT)) != 0)
529 532 return (returnstat);
530 533
531 534 uval.string_val = hexconvert((char *)&ip_port, sizeof (ip_port),
532 535 sizeof (ip_port));
533 536 if (uval.string_val) {
534 537 returnstat = pa_print(context, &uval, 0);
535 538 free(uval.string_val);
536 539 } else
537 540 returnstat = -1;
538 541
539 542 if (returnstat)
540 543 return (returnstat);
541 544
542 545 if ((returnstat = close_tag(context, TAG_SOCKEXFPORT)) != 0)
543 546 return (returnstat);
544 547
545 548 /* get foreign ip address */
546 549 if ((returnstat = pr_adr_char(context, (char *)ip_addr, ip_type)) != 0)
547 550 return (returnstat);
548 551
549 552 if ((returnstat = open_tag(context, TAG_SOCKEXFADDR)) != 0)
550 553 return (returnstat);
551 554
552 555 if (ip_type == AU_IPv4) { /* ipv4 address */
553 556
554 557 if (!(context->format & PRF_RAWM)) {
555 558 uval.string_val = buf;
556 559 get_Hname(ip_addr[0], buf, sizeof (buf));
557 560 returnstat = pa_print(context, &uval, flag);
558 561 } else {
559 562 ia.s_addr = ip_addr[0];
560 563 if ((uval.string_val = inet_ntoa(ia)) == NULL)
561 564 return (-1);
562 565 returnstat = pa_print(context, &uval, flag);
563 566 }
564 567
565 568 } else if (ip_type == AU_IPv6) { /* IPv6 addresss (128 bits) */
566 569
567 570 if (!(context->format & PRF_RAWM)) {
568 571 uval.string_val = buf;
569 572 get_Hname_ex(ip_addr, buf, sizeof (buf));
570 573 returnstat = pa_print(context, &uval, flag);
571 574 } else {
572 575 uval.string_val = (char *)buf;
573 576 (void) inet_ntop(AF_INET6, (void *)ip_addr, buf,
574 577 sizeof (buf));
575 578 returnstat = pa_print(context, &uval, flag);
576 579 }
577 580 } else
578 581 returnstat = -1;
579 582
580 583 if (returnstat)
581 584 return (returnstat);
582 585
583 586 if ((returnstat = close_tag(context, TAG_SOCKEXFADDR)) != 0)
584 587 return (returnstat);
585 588
586 589 return (returnstat);
587 590 }
588 591
589 592
590 593 #define NBITSMAJOR64 32 /* # of major device bits in 64-bit Solaris */
591 594 #define NBITSMINOR64 32 /* # of minor device bits in 64-bit Solaris */
592 595 #define MAXMAJ64 0xfffffffful /* max major value */
593 596 #define MAXMIN64 0xfffffffful /* max minor value */
594 597
595 598 #define NBITSMAJOR32 14 /* # of SVR4 major device bits */
596 599 #define NBITSMINOR32 18 /* # of SVR4 minor device bits */
597 600 #define NMAXMAJ32 0x3fff /* SVR4 max major value */
598 601 #define NMAXMIN32 0x3ffff /* MAX minor for 3b2 software drivers. */
599 602
600 603
601 604 static int32_t
602 605 minor_64(uint64_t dev)
603 606 {
604 607 if (dev == NODEV) {
605 608 errno = EINVAL;
606 609 return (NODEV);
607 610 }
608 611 return (int32_t)(dev & MAXMIN64);
609 612 }
610 613
611 614 static int32_t
612 615 major_64(uint64_t dev)
613 616 {
614 617 uint32_t maj;
615 618
616 619 maj = (uint32_t)(dev >> NBITSMINOR64);
617 620
618 621 if (dev == NODEV || maj > MAXMAJ64) {
619 622 errno = EINVAL;
620 623 return (NODEV);
621 624 }
622 625 return (int32_t)(maj);
623 626 }
624 627
625 628 static int32_t
626 629 minor_32(uint32_t dev)
627 630 {
628 631 if (dev == NODEV) {
629 632 errno = EINVAL;
630 633 return (NODEV);
631 634 }
632 635 return (int32_t)(dev & MAXMIN32);
633 636 }
634 637
635 638 static int32_t
636 639 major_32(uint32_t dev)
637 640 {
638 641 uint32_t maj;
639 642
640 643 maj = (uint32_t)(dev >> NBITSMINOR32);
641 644
642 645 if (dev == NODEV || maj > MAXMAJ32) {
643 646 errno = EINVAL;
644 647 return (NODEV);
645 648 }
646 649 return (int32_t)(maj);
647 650 }
648 651
649 652
650 653 /*
651 654 * -----------------------------------------------------------------------
652 655 * pa_tid() : Process terminal id and display contents
653 656 * return codes : -1 - error
654 657 * : 0 - successful
655 658 *
656 659 * terminal id port adr_int32
657 660 * terminal id machine adr_int32
658 661 * -----------------------------------------------------------------------
659 662 */
660 663 int
661 664 pa_tid32(pr_context_t *context, int status, int flag)
662 665 {
663 666 int returnstat;
664 667 int32_t dev_maj_min;
665 668 uint32_t ip_addr;
666 669 struct in_addr ia;
667 670 char *ipstring;
668 671 char buf[256];
669 672 uval_t uval;
670 673
671 674 if (status < 0)
672 675 return (status);
673 676
674 677 if ((returnstat = pr_adr_int32(context, &dev_maj_min, 1)) != 0)
675 678 return (returnstat);
676 679
677 680 if ((returnstat = pr_adr_char(context, (char *)&ip_addr, 4)) != 0)
678 681 return (returnstat);
679 682
680 683 uval.uvaltype = PRA_STRING;
681 684 uval.string_val = buf;
682 685
683 686 if (!(context->format & PRF_RAWM)) {
684 687 char hostname[256];
685 688
686 689 get_Hname(ip_addr, hostname, sizeof (hostname));
687 690 (void) snprintf(buf, sizeof (buf), "%d %d %s",
688 691 major_32(dev_maj_min),
689 692 minor_32(dev_maj_min),
690 693 hostname);
691 694 return (pa_print(context, &uval, flag));
692 695 }
693 696
694 697 ia.s_addr = ip_addr;
695 698 if ((ipstring = inet_ntoa(ia)) == NULL)
696 699 return (-1);
697 700
698 701 (void) snprintf(buf, sizeof (buf), "%d %d %s", major_32(dev_maj_min),
699 702 minor_32(dev_maj_min),
700 703 ipstring);
701 704
702 705 return (pa_print(context, &uval, flag));
703 706 }
704 707
705 708 int
706 709 pa_tid32_ex(pr_context_t *context, int status, int flag)
707 710 {
708 711 int returnstat;
709 712 int32_t dev_maj_min;
710 713 uint32_t ip_addr[16];
711 714 uint32_t ip_type;
712 715 struct in_addr ia;
713 716 char *ipstring;
714 717 char hostname[256];
715 718 char buf[256];
716 719 char tbuf[256];
717 720 uval_t uval;
718 721
719 722 if (status < 0)
720 723 return (status);
721 724
722 725 /* get port info */
723 726 if ((returnstat = pr_adr_int32(context, &dev_maj_min, 1)) != 0)
724 727 return (returnstat);
725 728
726 729 /* get address type */
727 730 if ((returnstat = pr_adr_u_int32(context, &ip_type, 1)) != 0)
728 731 return (returnstat);
729 732
730 733 /* legal address types are either AU_IPv4 or AU_IPv6 only */
731 734 if ((ip_type != AU_IPv4) && (ip_type != AU_IPv6))
732 735 return (-1);
733 736
734 737 /* get address (4/16) */
735 738 if ((returnstat = pr_adr_char(context, (char *)ip_addr, ip_type)) != 0)
736 739 return (returnstat);
737 740
738 741 uval.uvaltype = PRA_STRING;
739 742 if (ip_type == AU_IPv4) {
740 743 uval.string_val = buf;
741 744
742 745 if (!(context->format & PRF_RAWM)) {
743 746 get_Hname(ip_addr[0], hostname, sizeof (hostname));
744 747 (void) snprintf(buf, sizeof (buf), "%d %d %s",
745 748 major_32(dev_maj_min), minor_32(dev_maj_min),
746 749 hostname);
747 750 return (pa_print(context, &uval, flag));
748 751 }
749 752
750 753 ia.s_addr = ip_addr[0];
751 754 if ((ipstring = inet_ntoa(ia)) == NULL)
752 755 return (-1);
753 756
754 757 (void) snprintf(buf, sizeof (buf), "%d %d %s",
755 758 major_32(dev_maj_min), minor_32(dev_maj_min), ipstring);
756 759
757 760 return (pa_print(context, &uval, flag));
758 761 } else {
759 762 uval.string_val = buf;
760 763
761 764 if (!(context->format & PRF_RAWM)) {
762 765 get_Hname_ex(ip_addr, hostname, sizeof (hostname));
763 766 (void) snprintf(buf, sizeof (buf), "%d %d %s",
764 767 major_32(dev_maj_min), minor_32(dev_maj_min),
765 768 hostname);
766 769 return (pa_print(context, &uval, flag));
767 770 }
768 771
769 772 (void) inet_ntop(AF_INET6, (void *) ip_addr, tbuf,
770 773 sizeof (tbuf));
771 774
772 775 (void) snprintf(buf, sizeof (buf), "%d %d %s",
773 776 major_32(dev_maj_min), minor_32(dev_maj_min), tbuf);
774 777
775 778 return (pa_print(context, &uval, flag));
776 779 }
777 780 }
778 781
779 782 int
780 783 pa_ip_addr(pr_context_t *context, int status, int flag)
781 784 {
782 785 int returnstat;
783 786 uval_t uval;
784 787 uint32_t ip_addr[4];
785 788 uint32_t ip_type;
786 789 struct in_addr ia;
787 790 char *ipstring;
788 791 char hostname[256];
789 792 char buf[256];
790 793 char tbuf[256];
791 794
792 795 if (status < 0)
793 796 return (status);
794 797
795 798 /* get address type */
796 799 if ((returnstat = pr_adr_u_int32(context, &ip_type, 1)) != 0)
797 800 return (returnstat);
798 801
799 802 /* legal address type is AU_IPv4 or AU_IPv6 */
800 803 if ((ip_type != AU_IPv4) && (ip_type != AU_IPv6))
801 804 return (-1);
802 805
803 806 /* get address (4/16) */
804 807 if ((returnstat = pr_adr_char(context, (char *)ip_addr, ip_type)) != 0)
805 808 return (returnstat);
806 809
807 810 uval.uvaltype = PRA_STRING;
808 811 if (ip_type == AU_IPv4) {
809 812 uval.string_val = buf;
810 813
811 814 if (!(context->format & PRF_RAWM)) {
812 815 get_Hname(ip_addr[0], hostname, sizeof (hostname));
813 816 (void) snprintf(buf, sizeof (buf), "%s", hostname);
814 817 return (pa_print(context, &uval, flag));
815 818 }
816 819
817 820 ia.s_addr = ip_addr[0];
818 821 if ((ipstring = inet_ntoa(ia)) == NULL)
819 822 return (-1);
820 823
821 824 (void) snprintf(buf, sizeof (buf), "%s", ipstring);
822 825
823 826 return (pa_print(context, &uval, flag));
824 827 } else {
825 828 uval.string_val = buf;
826 829
827 830 if (!(context->format & PRF_RAWM)) {
828 831 get_Hname_ex(ip_addr, hostname, sizeof (hostname));
829 832 (void) snprintf(buf, sizeof (buf), "%s",
830 833 hostname);
831 834 return (pa_print(context, &uval, flag));
832 835 }
833 836
834 837 (void) inet_ntop(AF_INET6, (void *) ip_addr, tbuf,
835 838 sizeof (tbuf));
836 839
837 840 (void) snprintf(buf, sizeof (buf), "%s", tbuf);
838 841
839 842 return (pa_print(context, &uval, flag));
840 843 }
841 844
842 845 }
843 846
844 847 int
845 848 pa_tid64(pr_context_t *context, int status, int flag)
846 849 {
847 850 int returnstat;
848 851 int64_t dev_maj_min;
849 852 uint32_t ip_addr;
850 853 struct in_addr ia;
851 854 char *ipstring;
852 855 char buf[256];
853 856 uval_t uval;
854 857
855 858 if (status < 0)
856 859 return (status);
857 860
858 861 if ((returnstat = pr_adr_int64(context, &dev_maj_min, 1)) != 0)
859 862 return (returnstat);
860 863
861 864 if ((returnstat = pr_adr_char(context, (char *)&ip_addr, 4)) != 0)
862 865 return (returnstat);
863 866
864 867 uval.uvaltype = PRA_STRING;
865 868 uval.string_val = buf;
866 869
867 870 if (!(context->format & PRF_RAWM)) {
868 871 char hostname[256];
869 872
870 873 get_Hname(ip_addr, hostname, sizeof (hostname));
871 874 (void) snprintf(buf, sizeof (buf), "%d %d %s",
872 875 major_64(dev_maj_min), minor_64(dev_maj_min), hostname);
873 876 return (pa_print(context, &uval, flag));
874 877 }
875 878
876 879 ia.s_addr = ip_addr;
877 880 if ((ipstring = inet_ntoa(ia)) == NULL)
878 881 return (-1);
879 882
880 883 (void) snprintf(buf, sizeof (buf), "%d %d %s",
881 884 major_64(dev_maj_min), minor_64(dev_maj_min), ipstring);
882 885
883 886 return (pa_print(context, &uval, flag));
884 887 }
885 888
886 889 int
887 890 pa_tid64_ex(pr_context_t *context, int status, int flag)
888 891 {
889 892 int returnstat;
890 893 int64_t dev_maj_min;
891 894 uint32_t ip_addr[4];
892 895 uint32_t ip_type;
893 896 struct in_addr ia;
894 897 char *ipstring;
895 898 char hostname[256];
896 899 char buf[256];
897 900 char tbuf[256];
898 901 uval_t uval;
899 902
900 903 if (status < 0)
901 904 return (status);
902 905
903 906 /* get port info */
904 907 if ((returnstat = pr_adr_int64(context, &dev_maj_min, 1)) != 0)
905 908 return (returnstat);
906 909
907 910 /* get address type */
908 911 if ((returnstat = pr_adr_u_int32(context, &ip_type, 1)) != 0)
909 912 return (returnstat);
910 913
911 914 /* legal address types are either AU_IPv4 or AU_IPv6 only */
912 915 if ((ip_type != AU_IPv4) && (ip_type != AU_IPv6))
913 916 return (-1);
914 917
915 918 /* get address (4/16) */
916 919 if ((returnstat = pr_adr_char(context, (char *)&ip_addr, ip_type)) != 0)
917 920 return (returnstat);
918 921
919 922 uval.uvaltype = PRA_STRING;
920 923 if (ip_type == AU_IPv4) {
921 924 uval.string_val = buf;
922 925
923 926 if (!(context->format & PRF_RAWM)) {
924 927 get_Hname(ip_addr[0], hostname, sizeof (hostname));
925 928 uval.string_val = buf;
926 929 (void) snprintf(buf, sizeof (buf), "%d %d %s",
927 930 major_64(dev_maj_min), minor_64(dev_maj_min),
928 931 hostname);
929 932 return (pa_print(context, &uval, flag));
930 933 }
931 934
932 935 ia.s_addr = ip_addr[0];
933 936 if ((ipstring = inet_ntoa(ia)) == NULL)
934 937 return (-1);
935 938
936 939 (void) snprintf(buf, sizeof (buf), "%d %d %s",
937 940 major_64(dev_maj_min), minor_64(dev_maj_min), ipstring);
938 941
939 942 return (pa_print(context, &uval, flag));
940 943 } else {
941 944 uval.string_val = buf;
942 945
943 946 if (!(context->format & PRF_RAWM)) {
944 947 get_Hname_ex(ip_addr, hostname, sizeof (hostname));
945 948 (void) snprintf(buf, sizeof (buf), "%d %d %s",
946 949 major_64(dev_maj_min), minor_64(dev_maj_min),
947 950 hostname);
948 951 return (pa_print(context, &uval, flag));
949 952 }
950 953
951 954 (void) inet_ntop(AF_INET6, (void *)ip_addr, tbuf,
952 955 sizeof (tbuf));
953 956
954 957 (void) snprintf(buf, sizeof (buf), "%d %d %s",
955 958 major_64(dev_maj_min), minor_64(dev_maj_min), tbuf);
956 959
957 960 return (pa_print(context, &uval, flag));
958 961 }
959 962 }
960 963
961 964
962 965 /*
963 966 * ----------------------------------------------------------------
964 967 * findfieldwidth:
965 968 * Returns the field width based on the basic unit and print mode.
966 969 * This routine is called to determine the field width for the
967 970 * data items in the arbitrary data token where the tokens are
968 971 * to be printed in more than one line. The field width can be
969 972 * found in the fwidth structure.
970 973 *
971 974 * Input parameters:
972 975 * basicunit Can be one of AUR_CHAR, AUR_BYTE, AUR_SHORT,
973 976 * AUR_INT32, or AUR_INT64
974 977 * howtoprint Print mode. Can be one of AUP_BINARY, AUP_OCTAL,
975 978 * AUP_DECIMAL, or AUP_HEX.
976 979 * ----------------------------------------------------------------
977 980 */
978 981 int
979 982 findfieldwidth(char basicunit, char howtoprint)
980 983 {
981 984 int i, j;
982 985
983 986 for (i = 0; i < numwidthentries; i++) {
984 987 if (fwidth[i].basic_unit == basicunit) {
985 988 for (j = 0; j <= 4; j++) {
986 989 if (fwidth[i].pwidth[j].print_base ==
987 990 howtoprint) {
988 991 return (
989 992 fwidth[i].pwidth[j].field_width);
990 993 }
991 994 }
992 995 /*
993 996 * if we got here, then we didn't get what we were after
994 997 */
995 998 return (0);
996 999 }
997 1000 }
998 1001 /* if we got here, we didn't get what we wanted either */
999 1002 return (0);
1000 1003 }
1001 1004
1002 1005
1003 1006 /*
1004 1007 * -----------------------------------------------------------------------
1005 1008 * pa_cmd: Retrieves the cmd item from the input stream.
1006 1009 * return codes : -1 - error
1007 1010 * : 0 - successful
1008 1011 * -----------------------------------------------------------------------
1009 1012 */
1010 1013 int
1011 1014 pa_cmd(pr_context_t *context, int status, int flag)
1012 1015 {
1013 1016 char *cmd; /* cmd */
1014 1017 short length;
1015 1018 int returnstat;
1016 1019 uval_t uval;
1017 1020
1018 1021 /*
1019 1022 * We need to know how much space to allocate for our string, so
1020 1023 * read the length first, then call pr_adr_char to read those bytes.
1021 1024 */
1022 1025 if (status >= 0) {
1023 1026 if (pr_adr_short(context, &length, 1) == 0) {
1024 1027 if ((cmd = (char *)malloc(length + 1)) == NULL)
1025 1028 return (-1);
1026 1029 if (pr_adr_char(context, cmd, length) == 0) {
1027 1030 uval.uvaltype = PRA_STRING;
1028 1031 uval.string_val = cmd;
1029 1032 returnstat = pa_print(context, &uval, flag);
1030 1033 } else {
1031 1034 returnstat = -1;
1032 1035 }
1033 1036 free(cmd);
1034 1037 return (returnstat);
1035 1038 } else
1036 1039 return (-1);
1037 1040 } else
1038 1041 return (status);
1039 1042 }
1040 1043
1041 1044
1042 1045
1043 1046 /*
1044 1047 * -----------------------------------------------------------------------
1045 1048 * pa_adr_byte : Issues pr_adr_char to retrieve the next ADR item from
1046 1049 * the input stream pointed to by audit_adr, and prints it
1047 1050 * as an integer if status >= 0
1048 1051 * return codes : -1 - error
1049 1052 * : 0 - successful
1050 1053 * -----------------------------------------------------------------------
1051 1054 */
1052 1055 int
1053 1056 pa_adr_byte(pr_context_t *context, int status, int flag)
1054 1057 {
1055 1058 char c;
1056 1059 uval_t uval;
1057 1060
1058 1061 if (status >= 0) {
1059 1062 if (pr_adr_char(context, &c, 1) == 0) {
1060 1063 uval.uvaltype = PRA_BYTE;
1061 1064 uval.char_val = c;
1062 1065 return (pa_print(context, &uval, flag));
1063 1066 } else
1064 1067 return (-1);
1065 1068 } else
1066 1069 return (status);
1067 1070 }
1068 1071
1069 1072 /*
1070 1073 * -----------------------------------------------------------------------
1071 1074 * pa_adr_charhex: Issues pr_adr_char to retrieve the next ADR item from
1072 1075 * the input stream pointed to by audit_adr, and prints it
1073 1076 * in hexadecimal if status >= 0
1074 1077 * return codes : -1 - error
1075 1078 * : 0 - successful
1076 1079 * -----------------------------------------------------------------------
1077 1080 */
1078 1081 int
1079 1082 pa_adr_charhex(pr_context_t *context, int status, int flag)
1080 1083 {
1081 1084 char p[2];
1082 1085 int returnstat;
1083 1086 uval_t uval;
1084 1087
1085 1088 if (status >= 0) {
1086 1089 p[0] = p[1] = 0;
1087 1090
1088 1091 if ((returnstat = pr_adr_char(context, p, 1)) == 0) {
1089 1092 uval.uvaltype = PRA_STRING;
1090 1093 uval.string_val = hexconvert(p, sizeof (char),
1091 1094 sizeof (char));
1092 1095 if (uval.string_val) {
1093 1096 returnstat = pa_print(context, &uval, flag);
1094 1097 free(uval.string_val);
1095 1098 }
1096 1099 }
1097 1100 return (returnstat);
1098 1101 } else
1099 1102 return (status);
1100 1103 }
1101 1104
1102 1105 /*
1103 1106 * -----------------------------------------------------------------------
1104 1107 * pa_adr_int32 : Issues pr_adr_int32 to retrieve the next ADR item from the
1105 1108 * input stream pointed to by audit_adr, and prints it
1106 1109 * if status >= 0
1107 1110 * return codes : -1 - error
1108 1111 * : 0 - successful
1109 1112 * -----------------------------------------------------------------------
1110 1113 */
1111 1114 int
1112 1115 pa_adr_int32(pr_context_t *context, int status, int flag)
1113 1116 {
1114 1117 int32_t c;
1115 1118 uval_t uval;
1116 1119
1117 1120 if (status >= 0) {
1118 1121 if (pr_adr_int32(context, &c, 1) == 0) {
1119 1122 uval.uvaltype = PRA_INT32;
1120 1123 uval.int32_val = c;
1121 1124 return (pa_print(context, &uval, flag));
1122 1125 } else
1123 1126 return (-1);
1124 1127 } else
1125 1128 return (status);
1126 1129 }
1127 1130
1128 1131
1129 1132
1130 1133
1131 1134 /*
1132 1135 * -----------------------------------------------------------------------
1133 1136 * pa_adr_int64 : Issues pr_adr_int64 to retrieve the next ADR item from the
1134 1137 * input stream pointed to by audit_adr, and prints it
1135 1138 * if status >= 0
1136 1139 * return codes : -1 - error
1137 1140 * : 0 - successful
1138 1141 * -----------------------------------------------------------------------
1139 1142 */
1140 1143 int
1141 1144 pa_adr_int64(pr_context_t *context, int status, int flag)
1142 1145 {
1143 1146 int64_t c;
1144 1147 uval_t uval;
1145 1148
1146 1149 if (status >= 0) {
1147 1150 if (pr_adr_int64(context, &c, 1) == 0) {
1148 1151 uval.uvaltype = PRA_INT64;
1149 1152 uval.int64_val = c;
1150 1153 return (pa_print(context, &uval, flag));
1151 1154 } else
1152 1155 return (-1);
1153 1156 } else
1154 1157 return (status);
1155 1158 }
1156 1159
1157 1160 /*
1158 1161 * -----------------------------------------------------------------------
1159 1162 * pa_adr_int64hex: Issues pr_adr_int64 to retrieve the next ADR item from the
1160 1163 * input stream pointed to by audit_adr, and prints it
1161 1164 * in hexadecimal if status >= 0
1162 1165 * return codes : -1 - error
1163 1166 * : 0 - successful
1164 1167 * -----------------------------------------------------------------------
1165 1168 */
1166 1169 int
1167 1170 pa_adr_int32hex(pr_context_t *context, int status, int flag)
1168 1171 {
1169 1172 int32_t l;
1170 1173 int returnstat;
1171 1174 uval_t uval;
1172 1175
1173 1176 if (status >= 0) {
1174 1177 if ((returnstat = pr_adr_int32(context, &l, 1)) == 0) {
1175 1178 uval.uvaltype = PRA_HEX32;
1176 1179 uval.int32_val = l;
1177 1180 returnstat = pa_print(context, &uval, flag);
1178 1181 }
1179 1182 return (returnstat);
1180 1183 } else
1181 1184 return (status);
1182 1185 }
1183 1186
1184 1187 /*
1185 1188 * -----------------------------------------------------------------------
1186 1189 * pa_adr_int64hex: Issues pr_adr_int64 to retrieve the next ADR item from the
1187 1190 * input stream pointed to by audit_adr, and prints it
1188 1191 * in hexadecimal if status >= 0
1189 1192 * return codes : -1 - error
1190 1193 * : 0 - successful
1191 1194 * -----------------------------------------------------------------------
1192 1195 */
1193 1196 int
1194 1197 pa_adr_int64hex(pr_context_t *context, int status, int flag)
1195 1198 {
1196 1199 int64_t l;
1197 1200 int returnstat;
1198 1201 uval_t uval;
1199 1202
1200 1203 if (status >= 0) {
1201 1204 if ((returnstat = pr_adr_int64(context, &l, 1)) == 0) {
1202 1205 uval.uvaltype = PRA_HEX64;
1203 1206 uval.int64_val = l;
1204 1207 returnstat = pa_print(context, &uval, flag);
1205 1208 }
1206 1209 return (returnstat);
1207 1210 } else
1208 1211 return (status);
1209 1212 }
1210 1213
1211 1214
1212 1215 /*
1213 1216 * -------------------------------------------------------------------
1214 1217 * bu2string: Maps a print basic unit type to a string.
1215 1218 * returns : The string mapping or "unknown basic unit type".
1216 1219 * -------------------------------------------------------------------
1217 1220 */
1218 1221 char *
1219 1222 bu2string(char basic_unit)
1220 1223 {
1221 1224 register int i;
1222 1225
1223 1226 struct bu_map_ent {
1224 1227 char basic_unit;
1225 1228 char *string;
1226 1229 };
1227 1230
1228 1231 /*
1229 1232 * TRANSLATION_NOTE
1230 1233 * These names are data units when displaying the arbitrary data
1231 1234 * token.
1232 1235 */
1233 1236
1234 1237 static struct bu_map_ent bu_map[] = {
1235 1238 { AUR_BYTE, "byte" },
1236 1239 { AUR_CHAR, "char" },
1237 1240 { AUR_SHORT, "short" },
1238 1241 { AUR_INT32, "int32" },
1239 1242 { AUR_INT64, "int64" } };
1240 1243
1241 1244 for (i = 0; i < sizeof (bu_map) / sizeof (struct bu_map_ent); i++)
1242 1245 if (basic_unit == bu_map[i].basic_unit)
1243 1246 return (gettext(bu_map[i].string));
1244 1247
1245 1248 return (gettext("unknown basic unit type"));
1246 1249 }
1247 1250
1248 1251
1249 1252 /*
1250 1253 * -------------------------------------------------------------------
1251 1254 * eventmodifier2string: Maps event modifier flags to a readable string.
1252 1255 * returns: The string mapping or "none".
1253 1256 * -------------------------------------------------------------------
1254 1257 */
1255 1258 static void
1256 1259 eventmodifier2string(au_emod_t emodifier, char *modstring, size_t modlen)
1257 1260 {
1258 1261 register int i, j;
1259 1262
1260 1263 struct em_map_ent {
1261 1264 int mask;
1262 1265 char *string;
1263 1266 };
1264 1267
1265 1268 /*
1266 1269 * TRANSLATION_NOTE
1267 1270 * These abbreviations represent the event modifier field of the
1268 1271 * header token. To gain a better understanding of each modifier,
1269 1272 * read
1270 1273 * System Administration Guide: Security Services >> Solaris Auditing
1271 1274 * at http://docs.sun.com.
1272 1275 */
1273 1276
1274 1277 static struct em_map_ent em_map[] = {
1275 1278 { (int)PAD_READ, "rd" }, /* data read from object */
1276 1279 { (int)PAD_WRITE, "wr" }, /* data written to object */
1277 1280 { (int)PAD_SPRIVUSE, "sp" }, /* successfully used priv */
1278 1281 { (int)PAD_FPRIVUSE, "fp" }, /* failed use of priv */
1279 1282 { (int)PAD_NONATTR, "na" }, /* non-attributable event */
1280 1283 { (int)PAD_FAILURE, "fe" } /* fail audit event */
1281 1284 };
1282 1285
1283 1286 modstring[0] = '\0';
1284 1287
1285 1288 for (i = 0, j = 0; i < sizeof (em_map) / sizeof (struct em_map_ent);
1286 1289 i++) {
1287 1290 if ((int)emodifier & em_map[i].mask) {
1288 1291 if (j++)
1289 1292 (void) strlcat(modstring, ":", modlen);
1290 1293 (void) strlcat(modstring, em_map[i].string, modlen);
1291 1294 }
1292 1295 }
1293 1296 }
1294 1297
1295 1298
1296 1299 /*
1297 1300 * ---------------------------------------------------------
1298 1301 * convert_char_to_string:
1299 1302 * Converts a byte to string depending on the print mode
1300 1303 * input : printmode, which may be one of AUP_BINARY,
1301 1304 * AUP_OCTAL, AUP_DECIMAL, and AUP_HEX
1302 1305 * c, which is the byte to convert
1303 1306 * output : p, which is a pointer to the location where
1304 1307 * the resulting string is to be stored
1305 1308 * ----------------------------------------------------------
1306 1309 */
1307 1310
1308 1311 int
1309 1312 convert_char_to_string(char printmode, char c, char *p)
1310 1313 {
1311 1314 union {
1312 1315 char c1[4];
1313 1316 int c2;
1314 1317 } dat;
1315 1318
1316 1319 dat.c2 = 0;
1317 1320 dat.c1[3] = c;
1318 1321
1319 1322 if (printmode == AUP_BINARY)
1320 1323 (void) convertbinary(p, &c, sizeof (char));
1321 1324 else if (printmode == AUP_OCTAL)
1322 1325 (void) sprintf(p, "%o", (int)dat.c2);
1323 1326 else if (printmode == AUP_DECIMAL)
1324 1327 (void) sprintf(p, "%d", c);
1325 1328 else if (printmode == AUP_HEX)
1326 1329 (void) sprintf(p, "0x%x", (int)dat.c2);
1327 1330 else if (printmode == AUP_STRING)
1328 1331 convertascii(p, &c, sizeof (char));
1329 1332 return (0);
1330 1333 }
1331 1334
1332 1335 /*
1333 1336 * --------------------------------------------------------------
1334 1337 * convert_short_to_string:
1335 1338 * Converts a short integer to string depending on the print mode
1336 1339 * input : printmode, which may be one of AUP_BINARY,
1337 1340 * AUP_OCTAL, AUP_DECIMAL, and AUP_HEX
1338 1341 * c, which is the short integer to convert
1339 1342 * output : p, which is a pointer to the location where
1340 1343 * the resulting string is to be stored
1341 1344 * ---------------------------------------------------------------
1342 1345 */
1343 1346 int
1344 1347 convert_short_to_string(char printmode, short c, char *p)
1345 1348 {
1346 1349 union {
1347 1350 short c1[2];
1348 1351 int c2;
1349 1352 } dat;
1350 1353
1351 1354 dat.c2 = 0;
1352 1355 dat.c1[1] = c;
1353 1356
1354 1357 if (printmode == AUP_BINARY)
1355 1358 (void) convertbinary(p, (char *)&c, sizeof (short));
1356 1359 else if (printmode == AUP_OCTAL)
1357 1360 (void) sprintf(p, "%o", (int)dat.c2);
1358 1361 else if (printmode == AUP_DECIMAL)
1359 1362 (void) sprintf(p, "%hd", c);
1360 1363 else if (printmode == AUP_HEX)
1361 1364 (void) sprintf(p, "0x%x", (int)dat.c2);
1362 1365 else if (printmode == AUP_STRING)
1363 1366 convertascii(p, (char *)&c, sizeof (short));
1364 1367 return (0);
1365 1368 }
1366 1369
1367 1370 /*
1368 1371 * ---------------------------------------------------------
1369 1372 * convert_int32_to_string:
1370 1373 * Converts a integer to string depending on the print mode
1371 1374 * input : printmode, which may be one of AUP_BINARY,
1372 1375 * AUP_OCTAL, AUP_DECIMAL, and AUP_HEX
1373 1376 * c, which is the integer to convert
1374 1377 * output : p, which is a pointer to the location where
1375 1378 * the resulting string is to be stored
1376 1379 * ----------------------------------------------------------
1377 1380 */
1378 1381 int
1379 1382 convert_int32_to_string(char printmode, int32_t c, char *p)
1380 1383 {
1381 1384 if (printmode == AUP_BINARY)
1382 1385 (void) convertbinary(p, (char *)&c, sizeof (int32_t));
1383 1386 else if (printmode == AUP_OCTAL)
1384 1387 (void) sprintf(p, "%o", c);
1385 1388 else if (printmode == AUP_DECIMAL)
1386 1389 (void) sprintf(p, "%d", c);
1387 1390 else if (printmode == AUP_HEX)
1388 1391 (void) sprintf(p, "0x%x", c);
1389 1392 else if (printmode == AUP_STRING)
1390 1393 convertascii(p, (char *)&c, sizeof (int));
1391 1394 return (0);
1392 1395 }
1393 1396
1394 1397 /*
1395 1398 * ---------------------------------------------------------
1396 1399 * convert_int64_to_string:
1397 1400 * Converts a integer to string depending on the print mode
1398 1401 * input : printmode, which may be one of AUP_BINARY,
1399 1402 * AUP_OCTAL, AUP_DECIMAL, and AUP_HEX
1400 1403 * c, which is the integer to convert
1401 1404 * output : p, which is a pointer to the location where
1402 1405 * the resulting string is to be stored
1403 1406 * ----------------------------------------------------------
1404 1407 */
1405 1408 int
1406 1409 convert_int64_to_string(char printmode, int64_t c, char *p)
1407 1410 {
1408 1411 if (printmode == AUP_BINARY)
1409 1412 (void) convertbinary(p, (char *)&c, sizeof (int64_t));
1410 1413 else if (printmode == AUP_OCTAL)
1411 1414 (void) sprintf(p, "%"PRIo64, c);
1412 1415 else if (printmode == AUP_DECIMAL)
1413 1416 (void) sprintf(p, "%"PRId64, c);
1414 1417 else if (printmode == AUP_HEX)
1415 1418 (void) sprintf(p, "0x%"PRIx64, c);
1416 1419 else if (printmode == AUP_STRING)
1417 1420 convertascii(p, (char *)&c, sizeof (int64_t));
1418 1421 return (0);
1419 1422 }
1420 1423
1421 1424
1422 1425 /*
1423 1426 * -----------------------------------------------------------
1424 1427 * convertbinary:
1425 1428 * Converts a unit c of 'size' bytes long into a binary string
1426 1429 * and returns it into the position pointed to by p
1427 1430 * ------------------------------------------------------------
1428 1431 */
1429 1432 int
1430 1433 convertbinary(char *p, char *c, int size)
1431 1434 {
1432 1435 char *s, *t, *ss;
1433 1436 int i, j;
1434 1437
1435 1438 if ((s = (char *)malloc(8 * size + 1)) == NULL)
1436 1439 return (0);
1437 1440
1438 1441 ss = s;
1439 1442
1440 1443 /* first convert to binary */
1441 1444 t = s;
1442 1445 for (i = 0; i < size; i++) {
1443 1446 for (j = 0; j < 8; j++)
1444 1447 (void) sprintf(t++, "%d", ((*c >> (7 - j)) & (0x01)));
1445 1448 c++;
1446 1449 }
1447 1450 *t = '\0';
1448 1451
1449 1452 /* now string leading zero's if any */
1450 1453 j = strlen(s) - 1;
1451 1454 for (i = 0; i < j; i++) {
1452 1455 if (*s != '0')
1453 1456 break;
1454 1457 else
1455 1458 s++;
1456 1459 }
1457 1460
1458 1461 /* now copy the contents of s to p */
1459 1462 t = p;
1460 1463 for (i = 0; i < (8 * size + 1); i++) {
1461 1464 if (*s == '\0') {
1462 1465 *t = '\0';
1463 1466 break;
1464 1467 }
1465 1468 *t++ = *s++;
1466 1469 }
1467 1470 free(ss);
1468 1471
1469 1472 return (1);
1470 1473 }
1471 1474
1472 1475
1473 1476 static char hex[] = "0123456789abcdef";
1474 1477 /*
1475 1478 * -------------------------------------------------------------------
1476 1479 * hexconvert : Converts a string of (size) bytes to hexadecimal, and
1477 1480 * returns the hexadecimal string.
1478 1481 * returns : - NULL if memory cannot be allocated for the string, or
1479 1482 * - pointer to the hexadecimal string if successful
1480 1483 * -------------------------------------------------------------------
1481 1484 */
1482 1485 char *
1483 1486 hexconvert(char *c, int size, int chunk)
1484 1487 {
1485 1488 register char *s, *t;
1486 1489 register int i, j, k;
1487 1490 int numchunks;
1488 1491 int leftovers;
1489 1492
1490 1493 if (size <= 0)
1491 1494 return (NULL);
1492 1495
1493 1496 if ((s = (char *)malloc((size * 5) + 1)) == NULL)
1494 1497 return (NULL);
1495 1498
1496 1499 if (chunk > size || chunk <= 0)
1497 1500 chunk = size;
1498 1501
1499 1502 numchunks = size / chunk;
1500 1503 leftovers = size % chunk;
1501 1504
1502 1505 t = s;
1503 1506 for (i = j = 0; i < numchunks; i++) {
1504 1507 if (j++) {
1505 1508 *t++ = ' ';
1506 1509 }
1507 1510 *t++ = '0';
1508 1511 *t++ = 'x';
1509 1512 for (k = 0; k < chunk; k++) {
1510 1513 *t++ = hex[(uint_t)((uchar_t)*c >> 4)];
1511 1514 *t++ = hex[(uint_t)((uchar_t)*c & 0xF)];
1512 1515 c++;
1513 1516 }
1514 1517 }
1515 1518
1516 1519 if (leftovers) {
1517 1520 *t++ = ' ';
1518 1521 *t++ = '0';
1519 1522 *t++ = 'x';
1520 1523 for (i = 0; i < leftovers; i++) {
1521 1524 *t++ = hex[(uint_t)((uchar_t)*c >> 4)];
1522 1525 *t++ = hex[(uint_t)((uchar_t)*c & 0xF)];
1523 1526 c++;
1524 1527 }
1525 1528 }
1526 1529
1527 1530 *t = '\0';
1528 1531 return (s);
1529 1532 }
1530 1533
1531 1534
1532 1535 /*
1533 1536 * -------------------------------------------------------------------
1534 1537 * htp2string: Maps a print suggestion to a string.
1535 1538 * returns : The string mapping or "unknown print suggestion".
1536 1539 * -------------------------------------------------------------------
1537 1540 */
1538 1541 char *
1539 1542 htp2string(char print_sugg)
1540 1543 {
1541 1544 register int i;
1542 1545
1543 1546 struct htp_map_ent {
1544 1547 char print_sugg;
1545 1548 char *print_string;
1546 1549 };
1547 1550
1548 1551 /*
1549 1552 * TRANSLATION_NOTE
1550 1553 * These names are data types when displaying the arbitrary data
1551 1554 * token.
1552 1555 */
1553 1556
1554 1557 static struct htp_map_ent htp_map[] = {
1555 1558 { AUP_BINARY, "binary" },
1556 1559 { AUP_OCTAL, "octal" },
1557 1560 { AUP_DECIMAL, "decimal" },
1558 1561 { AUP_HEX, "hexadecimal" },
1559 1562 { AUP_STRING, "string" } };
1560 1563
1561 1564 for (i = 0; i < sizeof (htp_map) / sizeof (struct htp_map_ent); i++)
1562 1565 if (print_sugg == htp_map[i].print_sugg)
1563 1566 return (gettext(htp_map[i].print_string));
1564 1567
1565 1568 return (gettext("unknown print suggestion"));
1566 1569 }
1567 1570
1568 1571 /*
1569 1572 * ----------------------------------------------------------------------
1570 1573 * pa_adr_short: Issues pr_adr_short to retrieve the next ADR item from the
1571 1574 * input stream pointed to by audit_adr, and prints it
1572 1575 * if status >= 0
1573 1576 * return codes: -1 - error
1574 1577 * : 0 - successful
1575 1578 * ----------------------------------------------------------------------
1576 1579 */
1577 1580 int
1578 1581 pa_adr_short(pr_context_t *context, int status, int flag)
1579 1582 {
1580 1583 short c;
1581 1584 uval_t uval;
1582 1585
1583 1586 if (status >= 0) {
1584 1587 if (pr_adr_short(context, &c, 1) == 0) {
1585 1588 uval.uvaltype = PRA_SHORT;
1586 1589 uval.short_val = c;
1587 1590 return (pa_print(context, &uval, flag));
1588 1591 } else
1589 1592 return (-1);
1590 1593 } else
1591 1594 return (status);
1592 1595 }
1593 1596
1594 1597 /*
1595 1598 * -----------------------------------------------------------------------
1596 1599 * pa_adr_shorthex: Issues pr_adr_short to retrieve the next ADR item from the
1597 1600 * input stream pointed to by audit_adr, and prints it
1598 1601 * in hexadecimal if status >= 0
1599 1602 * return codes : -1 - error
1600 1603 * : 0 - successful
1601 1604 * -----------------------------------------------------------------------
1602 1605 */
1603 1606 int
1604 1607 pa_adr_shorthex(pr_context_t *context, int status, int flag)
1605 1608 {
1606 1609 short s;
1607 1610 int returnstat;
1608 1611 uval_t uval;
1609 1612
1610 1613 if (status >= 0) {
1611 1614 if ((returnstat = pr_adr_short(context, &s, 1)) == 0) {
1612 1615 uval.uvaltype = PRA_STRING;
1613 1616 uval.string_val = hexconvert((char *)&s, sizeof (s),
1614 1617 sizeof (s));
1615 1618 if (uval.string_val) {
1616 1619 returnstat = pa_print(context, &uval, flag);
1617 1620 free(uval.string_val);
1618 1621 }
1619 1622 }
1620 1623 return (returnstat);
1621 1624 } else
1622 1625 return (status);
1623 1626 }
1624 1627
1625 1628
1626 1629 /*
1627 1630 * -----------------------------------------------------------------------
1628 1631 * pa_adr_string: Retrieves a string from the input stream and prints it
1629 1632 * if status >= 0
1630 1633 * return codes : -1 - error
1631 1634 * : 0 - successful
1632 1635 * -----------------------------------------------------------------------
1633 1636 */
1634 1637 int
1635 1638 pa_adr_string(pr_context_t *context, int status, int flag)
1636 1639 {
1637 1640 char *c;
1638 1641 short length;
1639 1642 int returnstat;
1640 1643 uval_t uval;
1641 1644
1642 1645 /*
1643 1646 * We need to know how much space to allocate for our string, so
1644 1647 * read the length first, then call pr_adr_char to read those bytes.
1645 1648 */
1646 1649 if (status < 0)
1647 1650 return (status);
1648 1651
1649 1652 if ((returnstat = pr_adr_short(context, &length, 1)) != 0)
1650 1653 return (returnstat);
1651 1654 if ((c = (char *)malloc(length + 1)) == NULL)
1652 1655 return (-1);
1653 1656 if ((returnstat = pr_adr_char(context, c, length)) != 0) {
1654 1657 free(c);
1655 1658 return (returnstat);
1656 1659 }
1657 1660
1658 1661 uval.uvaltype = PRA_STRING;
1659 1662 uval.string_val = c;
1660 1663 returnstat = pa_print(context, &uval, flag);
1661 1664 free(c);
1662 1665 return (returnstat);
1663 1666 }
1664 1667
1665 1668 /*
1666 1669 * -----------------------------------------------------------------------
1667 1670 * pa_file_string: Retrieves a file string from the input stream and prints it
1668 1671 * if status >= 0
1669 1672 * return codes : -1 - error
1670 1673 * : 0 - successful
1671 1674 * -----------------------------------------------------------------------
1672 1675 */
1673 1676 int
1674 1677 pa_file_string(pr_context_t *context, int status, int flag)
1675 1678 {
1676 1679 char *c;
1677 1680 char *p;
1678 1681 short length;
1679 1682 int returnstat;
1680 1683 uval_t uval;
1681 1684
1682 1685 /*
1683 1686 * We need to know how much space to allocate for our string, so
1684 1687 * read the length first, then call pr_adr_char to read those bytes.
1685 1688 */
1686 1689 if (status < 0)
1687 1690 return (status);
1688 1691
1689 1692 if ((returnstat = pr_adr_short(context, &length, 1)) != 0)
1690 1693 return (returnstat);
1691 1694 if ((c = (char *)malloc(length + 1)) == NULL)
1692 1695 return (-1);
1693 1696 if ((p = (char *)malloc((length * 4) + 1)) == NULL) {
1694 1697 free(c);
1695 1698 return (-1);
1696 1699 }
1697 1700 if ((returnstat = pr_adr_char(context, c, length)) != 0) {
1698 1701 free(c);
1699 1702 free(p);
1700 1703 return (returnstat);
1701 1704 }
1702 1705
1703 1706 if (is_file_token(context->tokenid))
1704 1707 context->audit_rec_len += length;
1705 1708
1706 1709 convertascii(p, c, length - 1);
1707 1710 uval.uvaltype = PRA_STRING;
1708 1711 uval.string_val = p;
1709 1712
1710 1713 if (returnstat == 0)
1711 1714 returnstat = finish_open_tag(context);
1712 1715
1713 1716 if (returnstat == 0)
1714 1717 returnstat = pa_print(context, &uval, flag);
1715 1718
1716 1719 free(c);
1717 1720 free(p);
1718 1721 return (returnstat);
1719 1722 }
1720 1723
1721 1724 static int
1722 1725 pa_putstr_xml(pr_context_t *context, int printable, char *str, size_t len)
1723 1726 {
1724 1727 int err;
1725 1728
1726 1729 if (!printable) {
1727 1730 /*
1728 1731 * Unprintable chars should always be converted to the
1729 1732 * visible form. If there are unprintable characters which
1730 1733 * require special treatment in xml, those should be
1731 1734 * handled here.
1732 1735 */
1733 1736 do {
1734 1737 err = pr_printf(context, "\\%03o",
1735 1738 (unsigned char)*str++);
1736 1739 } while (err == 0 && --len != 0);
1737 1740 return (err);
1738 1741 }
1739 1742 /* printable characters */
1740 1743 if (len == 1) {
1741 1744 /*
1742 1745 * check for the special chars only when char size was 1
1743 1746 * ie, ignore special chars appear in the middle of multibyte
1744 1747 * sequence.
1745 1748 */
1746 1749
1747 1750 /* Escape for XML */
1748 1751 switch (*str) {
1749 1752 case '&':
1750 1753 err = pr_printf(context, "%s", "&");
1751 1754 break;
1752 1755
1753 1756 case '<':
1754 1757 err = pr_printf(context, "%s", "<");
1755 1758 break;
1756 1759
1757 1760 case '>':
1758 1761 err = pr_printf(context, "%s", ">");
1759 1762 break;
1760 1763
1761 1764 case '\"':
1762 1765 err = pr_printf(context, "%s", """);
1763 1766 break;
1764 1767
1765 1768 case '\'':
1766 1769 err = pr_printf(context, "%s", "'");
1767 1770 break;
1768 1771
1769 1772 default:
1770 1773 err = pr_putchar(context, *str);
1771 1774 break;
1772 1775 }
1773 1776 return (err);
1774 1777 }
1775 1778 do {
1776 1779 err = pr_putchar(context, *str++);
1777 1780 } while (err == 0 && --len != 0);
1778 1781 return (err);
1779 1782 }
1780 1783
1781 1784 static int
1782 1785 pa_putstr(pr_context_t *context, int printable, char *str, size_t len)
1783 1786 {
1784 1787 int err;
1785 1788
1786 1789 if (context->format & PRF_XMLM)
1787 1790 return (pa_putstr_xml(context, printable, str, len));
1788 1791
1789 1792 if (!printable) {
1790 1793 do {
1791 1794 err = pr_printf(context, "\\%03o",
1792 1795 (unsigned char)*str++);
1793 1796 } while (err == 0 && --len != 0);
1794 1797 return (err);
1795 1798 }
1796 1799 do {
1797 1800 err = pr_putchar(context, *str++);
1798 1801 } while (err == 0 && --len != 0);
1799 1802 return (err);
1800 1803 }
1801 1804
1802 1805 int
1803 1806 pa_string(pr_context_t *context, int status, int flag)
1804 1807 {
1805 1808 int rstat, wstat;
1806 1809 int i, printable, eos;
1807 1810 int mlen, rlen;
1808 1811 int mbmax = MB_CUR_MAX;
1809 1812 wchar_t wc;
1810 1813 char mbuf[MB_LEN_MAX + 1];
1811 1814 char c;
1812 1815
1813 1816 if (status < 0)
1814 1817 return (status);
1815 1818
1816 1819 rstat = wstat = 0;
1817 1820
1818 1821 if (mbmax == 1) {
1819 1822 while (wstat == 0) {
1820 1823 if ((rstat = pr_adr_char(context, &c, 1)) < 0)
1821 1824 break;
1822 1825 if (c == '\0')
1823 1826 break;
1824 1827 printable = isprint((unsigned char)c);
1825 1828 wstat = pa_putstr(context, printable, &c, 1);
1826 1829 }
1827 1830 goto done;
1828 1831 }
1829 1832
1830 1833 mlen = eos = 0;
1831 1834 while (wstat == 0) {
1832 1835 rlen = 0;
1833 1836 do {
1834 1837 if (!eos) {
1835 1838 rstat = pr_adr_char(context, &c, 1);
1836 1839 if (rstat != 0 || c == '\0')
1837 1840 eos = 1;
1838 1841 else
1839 1842 mbuf[mlen++] = c;
1840 1843 }
1841 1844 rlen = mbtowc(&wc, mbuf, mlen);
1842 1845 } while (!eos && mlen < mbmax && rlen <= 0);
1843 1846
1844 1847 if (mlen == 0)
1845 1848 break; /* end of string */
1846 1849
1847 1850 if (rlen <= 0) { /* no good sequence */
1848 1851 rlen = 1;
1849 1852 printable = 0;
1850 1853 } else {
1851 1854 printable = iswprint(wc);
1852 1855 }
1853 1856 wstat = pa_putstr(context, printable, mbuf, rlen);
1854 1857 mlen -= rlen;
1855 1858 if (mlen > 0) {
1856 1859 for (i = 0; i < mlen; i++)
1857 1860 mbuf[i] = mbuf[rlen + i];
1858 1861 }
1859 1862 }
1860 1863
1861 1864 done:
1862 1865 if (wstat == 0)
1863 1866 wstat = do_newline(context, flag);
1864 1867
1865 1868 if (wstat == 0 && context->data_mode == FILEMODE)
1866 1869 (void) fflush(stdout);
1867 1870
1868 1871 return ((rstat != 0 || wstat != 0) ? -1 : 0);
1869 1872 }
1870 1873
1871 1874 /*
1872 1875 * -----------------------------------------------------------------------
1873 1876 * pa_adr_u_int32: Issues pr_adr_u_int32 to retrieve the next ADR item from
1874 1877 * the input stream pointed to by audit_adr, and prints it
1875 1878 * if status = 0
1876 1879 * return codes : -1 - error
1877 1880 * : 0 - successful
1878 1881 * -----------------------------------------------------------------------
1879 1882 */
1880 1883
1881 1884
1882 1885 int
1883 1886 pa_adr_u_int32(pr_context_t *context, int status, int flag)
1884 1887 {
1885 1888 uint32_t c;
1886 1889 uval_t uval;
1887 1890
1888 1891 if (status >= 0) {
1889 1892 if (pr_adr_u_int32(context, &c, 1) == 0) {
1890 1893 uval.uvaltype = PRA_UINT32;
1891 1894 uval.uint32_val = c;
1892 1895 return (pa_print(context, &uval, flag));
1893 1896 } else
1894 1897 return (-1);
1895 1898 } else
1896 1899 return (status);
1897 1900 }
1898 1901
1899 1902
1900 1903
1901 1904 /*
1902 1905 * -----------------------------------------------------------------------
1903 1906 * pa_adr_u_int64: Issues pr_adr_u_int64 to retrieve the next ADR item from the
1904 1907 * input stream pointed to by audit_adr, and prints it
1905 1908 * if status = 0
1906 1909 * return codes : -1 - error
1907 1910 * : 0 - successful
1908 1911 * -----------------------------------------------------------------------
1909 1912 */
1910 1913 int
1911 1914 pa_adr_u_int64(pr_context_t *context, int status, int flag)
1912 1915 {
1913 1916 uint64_t c;
1914 1917 uval_t uval;
1915 1918
1916 1919 if (status >= 0) {
1917 1920 if (pr_adr_u_int64(context, &c, 1) == 0) {
1918 1921 uval.uvaltype = PRA_UINT64;
1919 1922 uval.uint64_val = c;
1920 1923 return (pa_print(context, &uval, flag));
1921 1924 } else
1922 1925 return (-1);
1923 1926 } else
1924 1927 return (status);
1925 1928 }
1926 1929
1927 1930
1928 1931 /*
1929 1932 * -----------------------------------------------------------------------
1930 1933 * pa_adr_u_short: Issues pr_adr_u_short to retrieve the next ADR item from
1931 1934 * the input stream pointed to by audit_adr, and prints it
1932 1935 * if status = 0
1933 1936 * return codes : -1 - error
1934 1937 * : 0 - successful
1935 1938 * -----------------------------------------------------------------------
1936 1939 */
1937 1940 int
1938 1941 pa_adr_u_short(pr_context_t *context, int status, int flag)
1939 1942 {
1940 1943 ushort_t c;
1941 1944 uval_t uval;
1942 1945
1943 1946 if (status >= 0) {
1944 1947 if (pr_adr_u_short(context, &c, 1) == 0) {
1945 1948 uval.uvaltype = PRA_USHORT;
1946 1949 uval.ushort_val = c;
1947 1950 return (pa_print(context, &uval, flag));
1948 1951 } else
1949 1952 return (-1);
1950 1953 } else
1951 1954 return (status);
1952 1955 }
1953 1956
1954 1957 /*
1955 1958 * -----------------------------------------------------------------------
1956 1959 * pa_reclen: Issues pr_adr_u_long to retrieve the length of the record
1957 1960 * from the input stream pointed to by audit_adr,
1958 1961 * and prints it (unless format is XML) if status = 0
1959 1962 * return codes : -1 - error
1960 1963 * : 0 - successful
1961 1964 * -----------------------------------------------------------------------
1962 1965 */
1963 1966 int
1964 1967 pa_reclen(pr_context_t *context, int status)
1965 1968 {
1966 1969 uint32_t c;
1967 1970 uval_t uval;
1968 1971
1969 1972 if (status >= 0) {
1970 1973 if ((int)pr_adr_u_int32(context, &c, 1) == 0) {
1971 1974 context->audit_rec_len = c;
1972 1975
1973 1976 /* Don't print this for XML format */
1974 1977 if (context->format & PRF_XMLM) {
1975 1978 return (0);
1976 1979 } else {
1977 1980 uval.uvaltype = PRA_UINT32;
1978 1981 uval.uint32_val = c;
1979 1982 return (pa_print(context, &uval, 0));
1980 1983 }
1981 1984 } else
1982 1985 return (-1);
1983 1986 } else
1984 1987 return (status);
1985 1988 }
1986 1989
1987 1990 /*
1988 1991 * -----------------------------------------------------------------------
1989 1992 * pa_mode : Issues pr_adr_u_short to retrieve the next ADR item from
1990 1993 * the input stream pointed to by audit_adr, and prints it
1991 1994 * in octal if status = 0
1992 1995 * return codes : -1 - error
1993 1996 * : 0 - successful
1994 1997 * -----------------------------------------------------------------------
1995 1998 */
1996 1999 int
1997 2000 pa_mode(pr_context_t *context, int status, int flag)
1998 2001 {
1999 2002 uint32_t c;
2000 2003 uval_t uval;
2001 2004
2002 2005 if (status >= 0) {
2003 2006 if (pr_adr_u_int32(context, &c, 1) == 0) {
2004 2007 uval.uvaltype = PRA_LOCT;
2005 2008 uval.uint32_val = c;
2006 2009 return (pa_print(context, &uval, flag));
2007 2010 } else
2008 2011 return (-1);
2009 2012 } else
2010 2013 return (status);
2011 2014 }
2012 2015
2013 2016 static int
2014 2017 pa_print_uid(pr_context_t *context, uid_t uid, int status, int flag)
2015 2018 {
2016 2019 int returnstat;
2017 2020 struct passwd *pw;
2018 2021 uval_t uval;
2019 2022
2020 2023 if (status < 0)
2021 2024 return (status);
2022 2025
2023 2026 if (!(context->format & PRF_RAWM)) {
2024 2027 /* get password file entry */
2025 2028 if ((pw = getpwuid(uid)) == NULL) {
2026 2029 returnstat = 1;
2027 2030 } else {
2028 2031 /* print in ASCII form */
2029 2032 uval.uvaltype = PRA_STRING;
2030 2033 uval.string_val = pw->pw_name;
2031 2034 returnstat = pa_print(context, &uval, flag);
2032 2035 }
2033 2036 }
2034 2037 /* print in integer form */
2035 2038 if ((context->format & PRF_RAWM) || (returnstat == 1)) {
2036 2039 uval.uvaltype = PRA_INT32;
2037 2040 uval.int32_val = uid;
2038 2041 returnstat = pa_print(context, &uval, flag);
2039 2042 }
2040 2043 return (returnstat);
2041 2044 }
2042 2045
2043 2046
2044 2047 /*
2045 2048 * -----------------------------------------------------------------------
2046 2049 * pa_pw_uid() : Issues pr_adr_u_int32 to reads uid from input stream
2047 2050 * pointed to by audit_adr, and displays it in either
2048 2051 * raw form or its ASCII representation, if status >= 0.
2049 2052 * return codes : -1 - error
2050 2053 * : 1 - warning, passwd entry not found
2051 2054 * : 0 - successful
2052 2055 * -----------------------------------------------------------------------
2053 2056 */
2054 2057 int
2055 2058 pa_pw_uid(pr_context_t *context, int status, int flag)
2056 2059 {
2057 2060 uint32_t uid;
2058 2061
2059 2062 if (status < 0)
2060 2063 return (status);
2061 2064
2062 2065 if (pr_adr_u_int32(context, &uid, 1) != 0)
2063 2066 /* cannot retrieve uid */
2064 2067 return (-1);
2065 2068
2066 2069 return (pa_print_uid(context, uid, status, flag));
2067 2070 }
2068 2071
2069 2072 static int
2070 2073 pa_print_gid(pr_context_t *context, gid_t gid, int status, int flag)
2071 2074 {
2072 2075 int returnstat;
2073 2076 struct group *gr;
2074 2077 uval_t uval;
2075 2078
2076 2079 if (status < 0)
2077 2080 return (status);
2078 2081
2079 2082 if (!(context->format & PRF_RAWM)) {
2080 2083 /* get group file entry */
2081 2084 if ((gr = getgrgid(gid)) == NULL) {
2082 2085 returnstat = 1;
2083 2086 } else {
2084 2087 /* print in ASCII form */
2085 2088 uval.uvaltype = PRA_STRING;
2086 2089 uval.string_val = gr->gr_name;
2087 2090 returnstat = pa_print(context, &uval, flag);
2088 2091 }
2089 2092 }
2090 2093 /* print in integer form */
2091 2094 if ((context->format & PRF_RAWM) || (returnstat == 1)) {
2092 2095 uval.uvaltype = PRA_INT32;
2093 2096 uval.int32_val = gid;
2094 2097 returnstat = pa_print(context, &uval, flag);
2095 2098 }
2096 2099 return (returnstat);
2097 2100 }
2098 2101
2099 2102
2100 2103 /*
2101 2104 * -----------------------------------------------------------------------
2102 2105 * pa_gr_uid() : Issues pr_adr_u_int32 to reads group uid from input stream
2103 2106 * pointed to by audit_adr, and displays it in either
2104 2107 * raw form or its ASCII representation, if status >= 0.
2105 2108 * return codes : -1 - error
2106 2109 * : 1 - warning, passwd entry not found
2107 2110 * : 0 - successful
2108 2111 * -----------------------------------------------------------------------
2109 2112 */
2110 2113 int
2111 2114 pa_gr_uid(pr_context_t *context, int status, int flag)
2112 2115 {
2113 2116 uint32_t gid;
2114 2117
2115 2118 if (status < 0)
2116 2119 return (status);
2117 2120
2118 2121 if (pr_adr_u_int32(context, &gid, 1) != 0)
2119 2122 /* cannot retrieve gid */
2120 2123 return (-1);
2121 2124
2122 2125 return (pa_print_gid(context, gid, status, flag));
2123 2126 }
2124 2127
2125 2128
2126 2129 /*
2127 2130 * -----------------------------------------------------------------------
2128 2131 * pa_pw_uid_gr_gid() : Issues pr_adr_u_int32 to reads uid or group uid
2129 2132 * from input stream
2130 2133 * pointed to by audit_adr, and displays it in either
2131 2134 * raw form or its ASCII representation, if status >= 0.
2132 2135 * return codes : -1 - error
2133 2136 * : 1 - warning, passwd entry not found
2134 2137 * : 0 - successful
2135 2138 * -----------------------------------------------------------------------
2136 2139 */
2137 2140 int
2138 2141 pa_pw_uid_gr_gid(pr_context_t *context, int status, int flag)
2139 2142 {
2140 2143 int returnstat;
2141 2144 uint32_t value;
2142 2145 uval_t uval;
2143 2146
2144 2147 if (status < 0)
2145 2148 return (status);
2146 2149
2147 2150 /* get value of a_type */
2148 2151 if ((returnstat = pr_adr_u_int32(context, &value, 1)) != 0)
2149 2152 return (returnstat);
2150 2153
2151 2154 if ((returnstat = open_tag(context, TAG_ACLTYPE)) != 0)
2152 2155 return (returnstat);
2153 2156
2154 2157 uval.uvaltype = PRA_UINT32;
2155 2158 uval.uint32_val = value;
2156 2159 if ((returnstat = pa_print(context, &uval, flag)) != 0)
2157 2160 return (returnstat);
2158 2161
2159 2162 if ((returnstat = close_tag(context, TAG_ACLTYPE)) != 0)
2160 2163 return (returnstat);
2161 2164
2162 2165 if ((returnstat = open_tag(context, TAG_ACLVAL)) != 0)
2163 2166 return (returnstat);
2164 2167 /*
2165 2168 * TRANSLATION_NOTE
2166 2169 * The "mask" and "other" strings refer to the class mask
2167 2170 * and other (or world) entries in an ACL.
2168 2171 * The "unrecognized" string refers to an unrecognized ACL
2169 2172 * entry.
2170 2173 */
2171 2174 switch (value) {
2172 2175 case USER_OBJ:
2173 2176 case USER:
2174 2177 returnstat = pa_pw_uid(context, returnstat, flag);
2175 2178 break;
2176 2179 case GROUP_OBJ:
2177 2180 case GROUP:
2178 2181 returnstat = pa_gr_uid(context, returnstat, flag);
2179 2182 break;
2180 2183 case CLASS_OBJ:
2181 2184 returnstat = pr_adr_u_int32(context, &value, 1);
2182 2185 if (returnstat != 0)
2183 2186 return (returnstat);
2184 2187
2185 2188 if (!(context->format & PRF_RAWM)) {
2186 2189 uval.uvaltype = PRA_STRING;
2187 2190 uval.string_val = gettext("mask");
2188 2191 returnstat = pa_print(context, &uval, flag);
2189 2192 } else {
2190 2193 uval.uvaltype = PRA_UINT32;
2191 2194 uval.uint32_val = value;
2192 2195 if ((returnstat =
2193 2196 pa_print(context, &uval, flag)) != 0) {
2194 2197 return (returnstat);
2195 2198 }
2196 2199 }
2197 2200 break;
2198 2201 case OTHER_OBJ:
2199 2202 returnstat = pr_adr_u_int32(context, &value, 1);
2200 2203 if (returnstat != 0)
2201 2204 return (returnstat);
2202 2205
2203 2206 if (!(context->format & PRF_RAWM)) {
2204 2207 uval.uvaltype = PRA_STRING;
2205 2208 uval.string_val = gettext("other");
2206 2209 returnstat = pa_print(context, &uval, flag);
2207 2210 } else {
2208 2211 uval.uvaltype = PRA_UINT32;
2209 2212 uval.uint32_val = value;
2210 2213 if ((returnstat =
2211 2214 pa_print(context, &uval, flag)) != 0) {
2212 2215 return (returnstat);
2213 2216 }
2214 2217 }
2215 2218 break;
2216 2219 default:
2217 2220 returnstat = pr_adr_u_int32(context, &value, 1);
2218 2221 if (returnstat != 0)
2219 2222 return (returnstat);
2220 2223
2221 2224 if (!(context->format & PRF_RAWM)) {
2222 2225 uval.uvaltype = PRA_STRING;
2223 2226 uval.string_val = gettext("unrecognized");
2224 2227 returnstat = pa_print(context, &uval, flag);
2225 2228 } else {
2226 2229 uval.uvaltype = PRA_UINT32;
2227 2230 uval.uint32_val = value;
2228 2231 if ((returnstat =
2229 2232 pa_print(context, &uval, flag)) != 0) {
2230 2233 return (returnstat);
2231 2234 }
2232 2235 }
2233 2236 }
2234 2237
2235 2238 if ((returnstat = close_tag(context, TAG_ACLVAL)) != 0)
2236 2239 return (returnstat);
2237 2240
2238 2241 return (returnstat);
2239 2242 }
2240 2243
2241 2244
2242 2245 /*
2243 2246 * -----------------------------------------------------------------------
2244 2247 * pa_event_modifier(): Issues pr_adr_u_short to retrieve the next ADR item from
2245 2248 * the input stream pointed to by audit_adr. This is the
2246 2249 * event type, and is displayed in hex;
2247 2250 * return codes : -1 - error
2248 2251 * : 0 - successful
2249 2252 * -----------------------------------------------------------------------
2250 2253 */
2251 2254 int
2252 2255 pa_event_modifier(pr_context_t *context, int status, int flag)
2253 2256 {
2254 2257 int returnstat;
2255 2258 au_emod_t emodifier;
2256 2259 uval_t uval;
2257 2260 char modstring[64];
2258 2261
2259 2262 if (status < 0)
2260 2263 return (status);
2261 2264
2262 2265 if ((returnstat = pr_adr_u_short(context, &emodifier, 1)) != 0)
2263 2266 return (returnstat);
2264 2267
2265 2268 /* For XML, only print when modifier is non-zero */
2266 2269 if (!(context->format & PRF_XMLM) || (emodifier != 0)) {
2267 2270 uval.uvaltype = PRA_STRING;
2268 2271
2269 2272 returnstat = open_tag(context, TAG_EVMOD);
2270 2273
2271 2274 if (returnstat >= 0) {
2272 2275 if (!(context->format & PRF_RAWM)) {
2273 2276 eventmodifier2string(emodifier, modstring,
2274 2277 sizeof (modstring));
2275 2278 uval.string_val = modstring;
2276 2279 returnstat = pa_print(context, &uval, flag);
2277 2280 } else {
2278 2281 uval.string_val = hexconvert((char *)&emodifier,
2279 2282 sizeof (emodifier), sizeof (emodifier));
2280 2283 if (uval.string_val) {
2281 2284 returnstat = pa_print(context, &uval,
2282 2285 flag);
2283 2286 free(uval.string_val);
2284 2287 }
2285 2288 }
2286 2289 }
2287 2290 if (returnstat >= 0)
2288 2291 returnstat = close_tag(context, TAG_EVMOD);
2289 2292 }
2290 2293
2291 2294 return (returnstat);
2292 2295 }
2293 2296
2294 2297
2295 2298 /*
2296 2299 * -----------------------------------------------------------------------
2297 2300 * pa_event_type(): Issues pr_adr_u_short to retrieve the next ADR item from
2298 2301 * the input stream pointed to by audit_adr. This is the
2299 2302 * event type, and is displayed in either raw or
2300 2303 * ASCII form as appropriate
2301 2304 * return codes : -1 - error
2302 2305 * : 0 - successful
2303 2306 * -----------------------------------------------------------------------
2304 2307 */
2305 2308 int
2306 2309 pa_event_type(pr_context_t *context, int status, int flag)
2307 2310 {
2308 2311 au_event_t etype;
2309 2312 int returnstat;
2310 2313 au_event_ent_t *p_event = NULL;
2311 2314 uval_t uval;
2312 2315
2313 2316 if (status >= 0) {
2314 2317 if ((returnstat = pr_adr_u_short(context, &etype, 1)) == 0) {
2315 2318 if (!(context->format & PRF_RAWM)) {
2316 2319 uval.uvaltype = PRA_STRING;
2317 2320 if (context->format & PRF_NOCACHE) {
2318 2321 p_event = getauevnum(etype);
2319 2322 } else {
2320 2323 (void) cacheauevent(&p_event, etype);
2321 2324 }
2322 2325 if (p_event != NULL) {
2323 2326 if (context->format & PRF_SHORTM)
2324 2327 uval.string_val =
2325 2328 p_event->ae_name;
2326 2329 else
2327 2330 uval.string_val =
2328 2331 p_event->ae_desc;
2329 2332 } else {
2330 2333 uval.string_val =
2331 2334 gettext("invalid event number");
2332 2335 }
2333 2336 returnstat = pa_print(context, &uval, flag);
2334 2337 } else {
2335 2338 uval.uvaltype = PRA_USHORT;
2336 2339 uval.ushort_val = etype;
2337 2340 returnstat = pa_print(context, &uval, flag);
2338 2341 }
2339 2342 }
2340 2343 return (returnstat);
2341 2344 } else
2342 2345 return (status);
2343 2346
2344 2347 }
2345 2348
2346 2349
2347 2350 /*
2348 2351 * Print time from struct timeval to millisecond resolution.
2349 2352 *
2350 2353 * typedef long time_t; time of day in seconds
2351 2354 * typedef long useconds_t; signed # of microseconds
2352 2355 *
2353 2356 * struct timeval {
2354 2357 * time_t tv_sec; seconds
2355 2358 * suseconds_t tv_usec; and microseconds
2356 2359 * };
2357 2360 */
2358 2361
2359 2362 int
2360 2363 pa_utime32(pr_context_t *context, int status, int flag)
2361 2364 {
2362 2365 uint32_t scale = 1000; /* usec to msec */
2363 2366
2364 2367 return (do_mtime32(context, status, flag, scale));
2365 2368 }
2366 2369
2367 2370 /*
2368 2371 * Print time from timestruc_t to millisecond resolution.
2369 2372 *
2370 2373 * typedef struct timespec timestruct_t;
2371 2374 * struct timespec{
2372 2375 * time_t tv_sec; seconds
2373 2376 * long tv_nsec; and nanoseconds
2374 2377 * };
2375 2378 */
2376 2379 int
2377 2380 pa_ntime32(pr_context_t *context, int status, int flag)
2378 2381 {
2379 2382 uint32_t scale = 1000000; /* nsec to msec */
2380 2383
2381 2384 return (do_mtime32(context, status, flag, scale));
2382 2385 }
2383 2386
2384 2387 /*
2385 2388 * Format the timezone +/- HH:MM and terminate the string
2386 2389 * Note tm and tv_sec are the same time.
2387 2390 * Too bad strftime won't produce an ISO 8601 time zone numeric
2388 2391 */
2389 2392
2390 2393 #define MINS (24L * 60)
2391 2394 static void
2392 2395 tzone(struct tm *tm, time_t *tv_sec, char *p)
2393 2396 {
2394 2397 struct tm *gmt;
2395 2398 int min_off;
2396 2399
2397 2400 gmt = gmtime(tv_sec);
2398 2401
2399 2402 min_off = ((tm->tm_hour - gmt->tm_hour) * 60) +
2400 2403 (tm->tm_min - gmt->tm_min);
2401 2404
2402 2405 if (tm->tm_year < gmt->tm_year) /* cross new year */
2403 2406 min_off -= MINS;
2404 2407 else if (tm->tm_year > gmt->tm_year)
2405 2408 min_off += MINS;
2406 2409 else if (tm->tm_yday < gmt->tm_yday) /* cross dateline */
2407 2410 min_off -= MINS;
2408 2411 else if (tm->tm_yday > gmt->tm_yday)
2409 2412 min_off += MINS;
2410 2413
2411 2414 if (min_off < 0) {
2412 2415 min_off = -min_off;
2413 2416 *p++ = '-';
2414 2417 } else {
2415 2418 *p++ = '+';
2416 2419 }
2417 2420
2418 2421 *p++ = min_off / 600 + '0'; /* 10s of hours */
2419 2422 min_off = min_off - min_off / 600 * 600;
2420 2423 *p++ = min_off / 60 % 10 + '0'; /* hours */
2421 2424 min_off = min_off - min_off / 60 * 60;
2422 2425 *p++ = ':';
2423 2426 *p++ = min_off / 10 + '0'; /* 10s of minutes */
2424 2427 *p++ = min_off % 10 + '0'; /* minutes */
2425 2428 *p = '\0';
2426 2429 }
2427 2430
2428 2431 /*
2429 2432 * Format the milliseconds in place in the string.
2430 2433 * Borrowed from strftime.c:itoa()
2431 2434 */
2432 2435 static void
2433 2436 msec32(uint32_t msec, char *p)
2434 2437 {
2435 2438 *p++ = msec / 100 + '0';
2436 2439 msec = msec - msec / 100 * 100;
2437 2440 *p++ = msec / 10 + '0';
2438 2441 *p++ = msec % 10 +'0';
2439 2442 }
2440 2443
2441 2444 /*
2442 2445 * Format time and print relative to scale factor from micro/nano seconds.
2443 2446 */
2444 2447 static int
2445 2448 do_mtime32(pr_context_t *context, int status, int flag, uint32_t scale)
2446 2449 {
2447 2450 uint32_t t32;
2448 2451 time_t tv_sec;
2449 2452 struct tm tm;
2450 2453 char time_created[sizeof ("YYYY-MM-DD HH:MM:SS.sss -HH:MM")];
2451 2454 int returnstat;
2452 2455 uval_t uval;
2453 2456
2454 2457 if (status < 0)
2455 2458 return (status);
2456 2459
2457 2460 if ((returnstat = open_tag(context, TAG_ISO)) != 0)
2458 2461 return (returnstat);
2459 2462
2460 2463 if ((returnstat = pr_adr_u_int32(context,
2461 2464 (uint32_t *)&tv_sec, 1)) != 0)
2462 2465 return (returnstat);
2463 2466 if ((returnstat = pr_adr_u_int32(context, &t32, 1)) == 0) {
2464 2467 if (!(context->format & PRF_RAWM)) {
2465 2468 (void) localtime_r(&tv_sec, &tm);
2466 2469 (void) strftime(time_created,
2467 2470 sizeof ("YYYY-MM-DD HH:MM:SS.xxx "),
2468 2471 "%Y-%m-%d %H:%M:%S.xxx ", &tm);
2469 2472 msec32(t32/scale,
2470 2473 &time_created[sizeof ("YYYY-MM-DD HH:MM:SS.")-1]);
2471 2474 tzone(&tm, &tv_sec,
2472 2475 &time_created[
2473 2476 sizeof ("YYYY-MM-DD HH:MM:SS.xxx ")-1]);
2474 2477 uval.uvaltype = PRA_STRING;
2475 2478 uval.string_val = time_created;
2476 2479 } else {
2477 2480 uval.uvaltype = PRA_UINT32;
2478 2481 uval.uint32_val = (uint32_t)tv_sec;
2479 2482 (void) pa_print(context, &uval, 0);
2480 2483 if (context->format & PRF_XMLM) {
2481 2484 uval.uvaltype = PRA_CHAR;
2482 2485 uval.char_val = '.';
2483 2486 (void) pa_print(context, &uval, 0);
2484 2487 }
2485 2488 uval.uvaltype = PRA_UINT32;
2486 2489 uval.uint32_val = t32;
2487 2490 }
2488 2491 returnstat = pa_print(context, &uval, flag);
2489 2492 }
2490 2493
2491 2494 if (returnstat == 0)
2492 2495 return (close_tag(context, TAG_ISO));
2493 2496 else
2494 2497 return (returnstat);
2495 2498 }
2496 2499
2497 2500 /*
2498 2501 * Print time from struct timeval to millisecond resolution.
2499 2502 *
2500 2503 * typedef long time_t; time of day in seconds
2501 2504 * typedef long useconds_t; signed # of microseconds
2502 2505 *
2503 2506 * struct timeval {
2504 2507 * time_t tv_sec; seconds
2505 2508 * suseconds_t tv_usec; and microseconds
2506 2509 * };
2507 2510 */
2508 2511
2509 2512 int
2510 2513 pa_utime64(pr_context_t *context, int status, int flag)
2511 2514 {
2512 2515 uint64_t scale = 1000; /* usec to msec */
2513 2516
2514 2517 return (do_mtime64(context, status, flag, scale));
2515 2518 }
2516 2519
2517 2520 /*
2518 2521 * Print time from timestruc_t to millisecond resolution.
2519 2522 *
2520 2523 * typedef struct timespec timestruct_t;
2521 2524 * struct timespec{
2522 2525 * time_t tv_sec; seconds
2523 2526 * long tv_nsec; and nanoseconds
2524 2527 * };
2525 2528 */
2526 2529 int
2527 2530 pa_ntime64(pr_context_t *context, int status, int flag)
2528 2531 {
2529 2532 uint64_t scale = 1000000; /* nsec to msec */
2530 2533
2531 2534 return (do_mtime64(context, status, flag, scale));
2532 2535 }
2533 2536
2534 2537 /*
2535 2538 * Format the milliseconds in place in the string.
2536 2539 * Borrowed from strftime.c:itoa()
2537 2540 */
2538 2541 static void
2539 2542 msec64(uint64_t msec, char *p)
2540 2543 {
2541 2544 *p++ = msec / 100 + '0';
2542 2545 msec = msec - msec / 100 * 100;
2543 2546 *p++ = msec / 10 + '0';
2544 2547 *p++ = msec % 10 +'0';
2545 2548 }
2546 2549
2547 2550 /*
2548 2551 * Format time and print relative to scale factor from micro/nano seconds.
2549 2552 */
2550 2553 static int
2551 2554 do_mtime64(pr_context_t *context, int status, int flag, uint64_t scale)
2552 2555 {
2553 2556 uint64_t t64_sec;
2554 2557 uint64_t t64_msec;
2555 2558 time_t tv_sec;
2556 2559 struct tm tm;
2557 2560 char time_created[sizeof ("YYYY-MM-DD HH:MM:SS.sss -HH:MM")];
2558 2561 int returnstat;
2559 2562 uval_t uval;
2560 2563
2561 2564 if (status < 0)
2562 2565 return (status);
2563 2566
2564 2567 if ((returnstat = open_tag(context, TAG_ISO)) != 0)
2565 2568 return (returnstat);
2566 2569
2567 2570 if ((returnstat = pr_adr_u_int64(context, &t64_sec, 1)) != 0)
2568 2571 return (returnstat);
2569 2572 if ((returnstat = pr_adr_u_int64(context, &t64_msec, 1)) == 0) {
2570 2573 if (!(context->format & PRF_RAWM)) {
2571 2574 #ifndef _LP64
2572 2575 /*
2573 2576 * N.B.
2574 2577 * This fails for years from 2038
2575 2578 * The Y2K+38 problem
2576 2579 */
2577 2580 #endif /* !_LP64 */
2578 2581 tv_sec = (time_t)t64_sec;
2579 2582 (void) localtime_r(&tv_sec, &tm);
2580 2583 (void) strftime(time_created,
2581 2584 sizeof ("YYYY-MM-DD HH:MM:SS.xxx "),
2582 2585 "%Y-%m-%d %H:%M:%S.xxx ", &tm);
2583 2586 msec64(t64_msec/scale,
2584 2587 &time_created[sizeof ("YYYY-MM-DD HH:MM:SS.")-1]);
2585 2588 tzone(&tm, &tv_sec,
2586 2589 &time_created[
2587 2590 sizeof ("YYYY-MM-DD HH:MM:SS.xxx ")-1]);
2588 2591 uval.uvaltype = PRA_STRING;
2589 2592 uval.string_val = time_created;
2590 2593 } else {
2591 2594 uval.uvaltype = PRA_UINT64;
2592 2595 uval.uint64_val = t64_sec;
2593 2596 (void) pa_print(context, &uval, 0);
2594 2597 if (context->format & PRF_XMLM) {
2595 2598 uval.uvaltype = PRA_CHAR;
2596 2599 uval.char_val = '.';
2597 2600 (void) pa_print(context, &uval, 0);
2598 2601 }
2599 2602 uval.uvaltype = PRA_UINT64;
2600 2603 uval.uint64_val = t64_msec;
2601 2604 }
2602 2605 returnstat = pa_print(context, &uval, flag);
2603 2606 }
2604 2607
2605 2608 if (returnstat < 0)
2606 2609 return (returnstat);
2607 2610
2608 2611 return (close_tag(context, TAG_ISO));
2609 2612 }
2610 2613
2611 2614 /*
2612 2615 * -----------------------------------------------------------------------
2613 2616 * pa_error() : convert the return token error code.
2614 2617 *
2615 2618 * output : buf string representing return token error code.
2616 2619 *
2617 2620 * -----------------------------------------------------------------------
2618 2621 */
2619 2622 void
2620 2623 pa_error(const uchar_t err, char *buf, size_t buflen)
2621 2624 {
2622 2625 if (err == ADT_SUCCESS) {
2623 2626 (void) strlcpy(buf, gettext("success"), buflen);
2624 2627 } else if ((char)err == ADT_FAILURE) {
2625 2628 (void) strlcpy(buf, gettext("failure"), buflen);
2626 2629 } else {
2627 2630 char *emsg = strerror(err);
2628 2631
2629 2632 if (emsg != NULL) {
2630 2633 (void) strlcpy(buf, gettext("failure: "), buflen);
2631 2634 (void) strlcat(buf, emsg, buflen);
2632 2635 } else {
2633 2636 (void) snprintf(buf, buflen, "%s%d",
2634 2637 gettext("failure: "), err);
2635 2638 }
2636 2639 }
2637 2640 }
2638 2641
2639 2642 /*
2640 2643 * -----------------------------------------------------------------------
2641 2644 * pa_retval() : convert the return token return value code.
2642 2645 *
2643 2646 * input : err, for kernel success 0, or
2644 2647 * failure errno: 0 > & < sys_nerr.
2645 2648 * for userland success ADT_SUCCESS (0) or
2646 2649 * failure ADT_FAILURE (-1).
2647 2650 * pa_error() above has already converted err.
2648 2651 *
2649 2652 * : retval, for kernel arbitrary return value for success, or
2650 2653 * failure: -1.
2651 2654 * for userland,
2652 2655 * >= ADT_FAIL_VALUE < ADT_FAIL_PAM, an adt message code;
2653 2656 * >= ADT_FAIL_PAM, a pam_strerror value;
2654 2657 * < ADT_FAIL_VALUE, supposed to be an errno.
2655 2658 *
2656 2659 * output : buf string representing return token error code.
2657 2660 *
2658 2661 * -----------------------------------------------------------------------
2659 2662 */
2660 2663 void
2661 2664 pa_retval(const uchar_t err, const int32_t retval, char *buf, size_t buflen)
2662 2665 {
2663 2666 struct msg_text *msglist;
2664 2667 char *emsg;
2665 2668
2666 2669 /* success or kernel failure */
2667 2670 if (((char)err == ADT_SUCCESS) ||
2668 2671 (retval < 0)) {
2669 2672
2670 2673 (void) snprintf(buf, buflen, "%d", retval);
2671 2674 return;
2672 2675 }
2673 2676
2674 2677 /* userland failure */
2675 2678 msglist = &adt_msg_text[ADT_LIST_FAIL_VALUE];
2676 2679
2677 2680 if ((retval + msglist->ml_offset >= msglist->ml_min_index) &&
2678 2681 (retval + msglist->ml_offset <= msglist->ml_max_index)) {
2679 2682
2680 2683 (void) strlcpy(buf,
2681 2684 gettext(msglist->ml_msg_list[retval + msglist->ml_offset]),
2682 2685 buflen);
2683 2686 } else if ((retval >= ADT_FAIL_PAM) &&
2684 2687 (retval < ADT_FAIL_PAM + PAM_TOTAL_ERRNUM)) {
2685 2688
2686 2689 (void) strlcpy(buf, pam_strerror(NULL, retval - ADT_FAIL_PAM),
2687 2690 buflen);
2688 2691 } else if ((emsg = strerror(retval)) != NULL) {
2689 2692
2690 2693 (void) strlcpy(buf, emsg, buflen);
2691 2694 } else {
2692 2695
2693 2696 (void) snprintf(buf, buflen, "%d", retval);
2694 2697 }
2695 2698 }
2696 2699
2697 2700 /*
2698 2701 * -----------------------------------------------------------------------
2699 2702 * pa_printstr() : print a given string, translating unprintables
2700 2703 * : as needed.
2701 2704 */
2702 2705 static int
2703 2706 pa_printstr(pr_context_t *context, char *str)
2704 2707 {
2705 2708 int err = 0;
2706 2709 int len, printable;
2707 2710 int mbmax = MB_CUR_MAX;
2708 2711 wchar_t wc;
2709 2712 char c;
2710 2713
2711 2714 if (mbmax == 1) {
2712 2715 /* fast path */
2713 2716 while (err == 0 && *str != '\0') {
2714 2717 c = *str++;
2715 2718 printable = isprint((unsigned char)c);
2716 2719 err = pa_putstr(context, printable, &c, 1);
2717 2720 }
2718 2721 return (err);
2719 2722 }
2720 2723 while (err == 0 && *str != '\0') {
2721 2724 len = mbtowc(&wc, str, mbmax);
2722 2725 if (len <= 0) {
2723 2726 len = 1;
2724 2727 printable = 0;
2725 2728 } else {
2726 2729 printable = iswprint(wc);
2727 2730 }
2728 2731 err = pa_putstr(context, printable, str, len);
2729 2732 str += len;
2730 2733 }
2731 2734 return (err);
2732 2735 }
2733 2736
2734 2737 /*
2735 2738 * -----------------------------------------------------------------------
2736 2739 * pa_print() : print as one str or formatted for easy reading.
2737 2740 * : flag - indicates whether to output a new line for
2738 2741 * : multi-line output.
2739 2742 * : = 0; no new line
2740 2743 * : = 1; new line if regular output
2741 2744 * output : The audit record information is displayed in the
2742 2745 * type specified by uvaltype and value specified in
2743 2746 * uval. The printing of the delimiter or newline is
2744 2747 * determined by PRF_ONELINE, and the flag value,
2745 2748 * as follows:
2746 2749 * +--------+------+------+-----------------+
2747 2750 * |ONELINE | flag | last | Action |
2748 2751 * +--------+------+------+-----------------+
2749 2752 * | Y | Y | T | print new line |
2750 2753 * | Y | Y | F | print delimiter |
2751 2754 * | Y | N | T | print new line |
2752 2755 * | Y | N | F | print delimiter |
2753 2756 * | N | Y | T | print new line |
2754 2757 * | N | Y | F | print new line |
2755 2758 * | N | N | T | print new line |
2756 2759 * | N | N | F | print delimiter |
2757 2760 * +--------+------+------+-----------------+
2758 2761 *
2759 2762 * return codes : -1 - error
2760 2763 * 0 - successful
2761 2764 * -----------------------------------------------------------------------
2762 2765 */
2763 2766 int
2764 2767 pa_print(pr_context_t *context, uval_t *uval, int flag)
2765 2768 {
2766 2769 int returnstat = 0;
2767 2770 int last;
2768 2771
2769 2772 switch (uval->uvaltype) {
2770 2773 case PRA_INT32:
2771 2774 returnstat = pr_printf(context, "%d", uval->int32_val);
2772 2775 break;
2773 2776 case PRA_UINT32:
2774 2777 returnstat = pr_printf(context, "%u", uval->uint32_val);
2775 2778 break;
2776 2779 case PRA_INT64:
2777 2780 returnstat = pr_printf(context, "%"PRId64, uval->int64_val);
2778 2781 break;
2779 2782 case PRA_UINT64:
2780 2783 returnstat = pr_printf(context, "%"PRIu64, uval->uint64_val);
2781 2784 break;
2782 2785 case PRA_SHORT:
2783 2786 returnstat = pr_printf(context, "%hd", uval->short_val);
2784 2787 break;
2785 2788 case PRA_USHORT:
2786 2789 returnstat = pr_printf(context, "%hu", uval->ushort_val);
2787 2790 break;
2788 2791 case PRA_CHAR:
2789 2792 returnstat = pr_printf(context, "%c", uval->char_val);
2790 2793 break;
2791 2794 case PRA_BYTE:
2792 2795 returnstat = pr_printf(context, "%d", uval->char_val);
2793 2796 break;
2794 2797 case PRA_STRING:
2795 2798 returnstat = pa_printstr(context, uval->string_val);
2796 2799 break;
2797 2800 case PRA_HEX32:
2798 2801 returnstat = pr_printf(context, "0x%x", uval->int32_val);
2799 2802 break;
2800 2803 case PRA_HEX64:
2801 2804 returnstat = pr_printf(context, "0x%"PRIx64, uval->int64_val);
2802 2805 break;
2803 2806 case PRA_SHEX:
2804 2807 returnstat = pr_printf(context, "0x%hx", uval->short_val);
2805 2808 break;
2806 2809 case PRA_OCT:
2807 2810 returnstat = pr_printf(context, "%ho", uval->ushort_val);
2808 2811 break;
2809 2812 case PRA_LOCT:
2810 2813 returnstat = pr_printf(context, "%o", (int)uval->uint32_val);
2811 2814 break;
2812 2815 default:
2813 2816 (void) fprintf(stderr, gettext("praudit: Unknown type.\n"));
2814 2817 returnstat = -1;
2815 2818 break;
2816 2819 }
2817 2820 if (returnstat < 0)
2818 2821 return (returnstat);
2819 2822
2820 2823 last = (context->audit_adr->adr_now ==
2821 2824 (context->audit_rec_start + context->audit_rec_len));
2822 2825
2823 2826 if (!(context->format & PRF_XMLM)) {
2824 2827 if (!(context->format & PRF_ONELINE)) {
2825 2828 if ((flag == 1) || last)
2826 2829 returnstat = pr_putchar(context, '\n');
2827 2830 else
2828 2831 returnstat = pr_printf(context, "%s",
2829 2832 context->SEPARATOR);
2830 2833 } else {
2831 2834 if (!last)
2832 2835 returnstat = pr_printf(context, "%s",
2833 2836 context->SEPARATOR);
2834 2837 else
2835 2838 returnstat = pr_putchar(context, '\n');
2836 2839 }
2837 2840 }
2838 2841 if ((returnstat == 0) && (context->data_mode == FILEMODE))
2839 2842 (void) fflush(stdout);
2840 2843
2841 2844 return (returnstat);
2842 2845 }
2843 2846
2844 2847 static struct cntrl_mapping {
2845 2848 char from;
2846 2849 char to;
2847 2850 } cntrl_map[] = {
2848 2851 '\0', '0',
2849 2852 '\a', 'a',
2850 2853 '\b', 'b',
2851 2854 '\t', 't',
2852 2855 '\f', 'f',
2853 2856 '\n', 'n',
2854 2857 '\r', 'r',
2855 2858 '\v', 'v'
2856 2859 };
2857 2860
2858 2861 static int cntrl_map_entries = sizeof (cntrl_map)
2859 2862 / sizeof (struct cntrl_mapping);
2860 2863
2861 2864 /*
2862 2865 * Convert binary data to ASCII for printing.
2863 2866 */
2864 2867 void
2865 2868 convertascii(char *p, char *c, int size)
2866 2869 {
2867 2870 int i, j, uc;
2868 2871
2869 2872 for (i = 0; i < size; i++) {
2870 2873 uc = (unsigned char)*(c + i);
2871 2874 if (isascii(uc)) {
2872 2875 if (iscntrl(uc)) {
2873 2876 for (j = 0; j < cntrl_map_entries; j++) {
2874 2877 if (cntrl_map[j].from == uc) {
2875 2878 *p++ = '\\';
2876 2879 *p++ = cntrl_map[j].to;
2877 2880 break;
2878 2881 }
2879 2882 }
2880 2883 if (j == cntrl_map_entries) {
2881 2884 *p++ = '^';
2882 2885 *p++ = (char)(uc ^ 0100);
2883 2886 }
2884 2887 } else {
2885 2888 *p++ = (char)uc;
2886 2889 }
2887 2890 } else {
2888 2891 p += sprintf(p, "\\%03o", uc);
2889 2892 }
2890 2893 }
2891 2894 *p = '\0';
2892 2895 }
2893 2896
2894 2897 /*
2895 2898 * -----------------------------------------------------------------------
2896 2899 * pa_xgeneric: Process Xobject token and display contents
2897 2900 * This routine will handle many of the attribute
2898 2901 * types introduced in TS 2.x, such as:
2899 2902 *
2900 2903 * AUT_XCOLORMAP, AUT_XCURSOR, AUT_XFONT,
2901 2904 * AUT_XGC, AUT_XPIXMAP, AUT_XWINDOW
2902 2905 *
2903 2906 * NOTE: At the time of call, the token id has been retrieved
2904 2907 *
2905 2908 * return codes : -1 - error
2906 2909 * : 0 - successful
2907 2910 * NOTE: At the time of call, the xatom token id has been retrieved
2908 2911 *
2909 2912 * Format of xobj
2910 2913 * text token id adr_char
2911 2914 * XID adr_u_int32
2912 2915 * creator uid adr_pw_uid
2913 2916 * -----------------------------------------------------------------------
2914 2917 */
2915 2918 int
2916 2919 pa_xgeneric(pr_context_t *context)
2917 2920 {
2918 2921 int returnstat;
2919 2922
2920 2923 returnstat = process_tag(context, TAG_XID, 0, 0);
2921 2924 return (process_tag(context, TAG_XCUID, returnstat, 1));
2922 2925 }
2923 2926
2924 2927
2925 2928 /*
2926 2929 * ------------------------------------------------------------------------
2927 2930 * pa_liaison : Issues pr_adr_char to retrieve the next ADR item from the
2928 2931 * input stream pointed to by audit_adr, and prints it
2929 2932 * if status >= 0 either in ASCII or raw form
2930 2933 * return codes : -1 - error
2931 2934 * : 0 - successful
2932 2935 * : 1 - warning, unknown label type
2933 2936 * -----------------------------------------------------------------------
2934 2937 */
2935 2938 int
2936 2939 pa_liaison(pr_context_t *context, int status, int flag)
2937 2940 {
2938 2941 int returnstat;
2939 2942 int32_t li;
2940 2943 uval_t uval;
2941 2944
2942 2945 if (status >= 0) {
2943 2946 if ((returnstat = pr_adr_int32(context, &li, 1)) != 0) {
2944 2947 return (returnstat);
2945 2948 }
2946 2949 if (!(context->format & PRF_RAWM)) {
2947 2950 uval.uvaltype = PRA_UINT32;
2948 2951 uval.uint32_val = li;
2949 2952 returnstat = pa_print(context, &uval, flag);
2950 2953 }
2951 2954 /* print in hexadecimal form */
2952 2955 if ((context->format & PRF_RAWM) || (returnstat == 1)) {
2953 2956 uval.uvaltype = PRA_HEX32;
2954 2957 uval.uint32_val = li;
2955 2958 returnstat = pa_print(context, &uval, flag);
2956 2959 }
2957 2960 return (returnstat);
2958 2961 } else
2959 2962 return (status);
2960 2963 }
2961 2964
2962 2965 /*
2963 2966 * ------------------------------------------------------------------------
2964 2967 * pa_xid : Issues pr_adr_int32 to retrieve the XID from the input
2965 2968 * stream pointed to by audit_adr, and prints it if
2966 2969 * status >= 0 either in ASCII or raw form
2967 2970 * return codes : -1 - error
2968 2971 * : 0 - successful
2969 2972 * : 1 - warning, unknown label type
2970 2973 * ------------------------------------------------------------------------
2971 2974 */
2972 2975
2973 2976 int
2974 2977 pa_xid(pr_context_t *context, int status, int flag)
2975 2978 {
2976 2979 int returnstat;
2977 2980 int32_t xid;
2978 2981 uval_t uval;
2979 2982
2980 2983 if (status < 0)
2981 2984 return (status);
2982 2985
2983 2986 /* get XID from stream */
2984 2987 if ((returnstat = pr_adr_int32(context, (int32_t *)&xid, 1)) != 0)
2985 2988 return (returnstat);
2986 2989
2987 2990 if (!(context->format & PRF_RAWM)) {
2988 2991 uval.uvaltype = PRA_STRING;
2989 2992 uval.string_val = hexconvert((char *)&xid, sizeof (xid),
2990 2993 sizeof (xid));
2991 2994 if (uval.string_val) {
2992 2995 returnstat = pa_print(context, &uval, flag);
2993 2996 free(uval.string_val);
2994 2997 }
2995 2998 } else {
2996 2999 uval.uvaltype = PRA_INT32;
2997 3000 uval.int32_val = xid;
2998 3001 returnstat = pa_print(context, &uval, flag);
2999 3002 }
3000 3003
3001 3004 return (returnstat);
3002 3005 }
3003 3006
3004 3007 static int
3005 3008 pa_ace_flags(pr_context_t *context, ace_t *ace, int status, int flag)
3006 3009 {
3007 3010 int returnstat;
3008 3011 uval_t uval;
3009 3012
3010 3013 if (status < 0)
3011 3014 return (status);
3012 3015
3013 3016 /*
3014 3017 * TRANSLATION_NOTE
3015 3018 * ace->a_flags refers to access flags of ZFS/NFSv4 ACL entry.
3016 3019 */
3017 3020 if ((returnstat = open_tag(context, TAG_ACEFLAGS)) != 0)
3018 3021 return (returnstat);
3019 3022 if (!(context->format & PRF_RAWM)) {
3020 3023 uval.uvaltype = PRA_STRING;
3021 3024 switch (ace->a_flags & ACE_TYPE_FLAGS) {
3022 3025 case ACE_OWNER:
3023 3026 uval.string_val = gettext(OWNERAT_TXT);
3024 3027 break;
3025 3028 case ACE_GROUP | ACE_IDENTIFIER_GROUP:
3026 3029 uval.string_val = gettext(GROUPAT_TXT);
3027 3030 break;
3028 3031 case ACE_IDENTIFIER_GROUP:
3029 3032 uval.string_val = gettext(GROUP_TXT);
3030 3033 break;
3031 3034 case ACE_EVERYONE:
3032 3035 uval.string_val = gettext(EVERYONEAT_TXT);
3033 3036 break;
3034 3037 case 0:
3035 3038 uval.string_val = gettext(USER_TXT);
3036 3039 break;
3037 3040 default:
3038 3041 uval.uvaltype = PRA_USHORT;
3039 3042 uval.uint32_val = ace->a_flags;
3040 3043 }
3041 3044 } else {
3042 3045 uval.uvaltype = PRA_USHORT;
3043 3046 uval.uint32_val = ace->a_flags;
3044 3047 }
3045 3048 if ((returnstat = pa_print(context, &uval, flag)) != 0)
3046 3049 return (returnstat);
3047 3050 return (close_tag(context, TAG_ACEFLAGS));
3048 3051 }
3049 3052
3050 3053 static int
3051 3054 pa_ace_who(pr_context_t *context, ace_t *ace, int status, int flag)
3052 3055 {
3053 3056 int returnstat;
3054 3057
3055 3058 if (status < 0)
3056 3059 return (status);
3057 3060
3058 3061 /*
3059 3062 * TRANSLATION_NOTE
3060 3063 * ace->a_who refers to user id or group id of ZFS/NFSv4 ACL entry.
3061 3064 */
3062 3065 if ((returnstat = open_tag(context, TAG_ACEID)) != 0)
3063 3066 return (returnstat);
3064 3067 switch (ace->a_flags & ACE_TYPE_FLAGS) {
3065 3068 case ACE_IDENTIFIER_GROUP: /* group id */
3066 3069 returnstat = pa_print_gid(context, ace->a_who, returnstat,
3067 3070 flag);
3068 3071 break;
3069 3072 default: /* user id */
3070 3073 returnstat = pa_print_uid(context, ace->a_who, returnstat,
3071 3074 flag);
3072 3075 break;
3073 3076 }
3074 3077 if (returnstat < 0)
3075 3078 return (returnstat);
3076 3079 return (close_tag(context, TAG_ACEID));
3077 3080 }
3078 3081
3079 3082 /*
3080 3083 * Appends what to str, (re)allocating str if necessary.
3081 3084 */
3082 3085 #define INITIAL_ALLOC 256
3083 3086 static int
3084 3087 strappend(char **str, char *what, size_t *alloc)
3085 3088 {
3086 3089 char *s, *newstr;
3087 3090 size_t needed;
3088 3091
3089 3092 s = *str;
3090 3093
3091 3094 if (s == NULL) {
3092 3095 s = malloc(INITIAL_ALLOC);
3093 3096 if (s == NULL) {
3094 3097 *alloc = 0;
3095 3098 return (-1);
3096 3099 }
3097 3100 *alloc = INITIAL_ALLOC;
3098 3101 s[0] = '\0';
3099 3102 *str = s;
3100 3103 }
3101 3104
3102 3105 needed = strlen(s) + strlen(what) + 1;
3103 3106 if (*alloc < needed) {
3104 3107 newstr = realloc(s, needed);
3105 3108 if (newstr == NULL)
3106 3109 return (-1);
|
↓ open down ↓ |
3045 lines elided |
↑ open up ↑ |
3107 3110 s = newstr;
3108 3111 *alloc = needed;
3109 3112 *str = s;
3110 3113 }
3111 3114 (void) strlcat(s, what, *alloc);
3112 3115
3113 3116 return (0);
3114 3117 }
3115 3118
3116 3119 static int
3117 -pa_ace_access_mask(pr_context_t *context, ace_t *ace, int status, int flag)
3120 +pa_ace_access_mask(pr_context_t *context, uint32_t mask, int status, int flag)
3118 3121 {
3119 3122 int returnstat, i;
3120 3123 uval_t uval;
3121 3124 char *permstr = NULL;
3122 3125 size_t permstr_alloc = 0;
3123 3126
3124 3127 if (status < 0)
3125 3128 return (status);
3126 3129
3127 3130 /*
3128 3131 * TRANSLATION_NOTE
3129 - * ace->a_access_mask refers to access mask of ZFS/NFSv4 ACL entry.
3132 + * mask refers to access mask of ZFS/NFSv4 ACL entry.
3130 3133 */
3131 3134 if ((returnstat = open_tag(context, TAG_ACEMASK)) != 0)
3132 3135 return (returnstat);
3133 3136 if (context->format & PRF_SHORTM &&
3134 3137 ((permstr = malloc(15)) != NULL)) {
3135 3138 for (i = 0; i < 14; i++)
3136 3139 permstr[i] = '-';
3137 3140
3138 - if (ace->a_access_mask & ACE_READ_DATA)
3141 + if (mask & ACE_READ_DATA)
3139 3142 permstr[0] = 'r';
3140 - if (ace->a_access_mask & ACE_WRITE_DATA)
3143 + if (mask & ACE_WRITE_DATA)
3141 3144 permstr[1] = 'w';
3142 - if (ace->a_access_mask & ACE_EXECUTE)
3145 + if (mask & ACE_EXECUTE)
3143 3146 permstr[2] = 'x';
3144 - if (ace->a_access_mask & ACE_APPEND_DATA)
3147 + if (mask & ACE_APPEND_DATA)
3145 3148 permstr[3] = 'p';
3146 - if (ace->a_access_mask & ACE_DELETE)
3149 + if (mask & ACE_DELETE)
3147 3150 permstr[4] = 'd';
3148 - if (ace->a_access_mask & ACE_DELETE_CHILD)
3151 + if (mask & ACE_DELETE_CHILD)
3149 3152 permstr[5] = 'D';
3150 - if (ace->a_access_mask & ACE_READ_ATTRIBUTES)
3153 + if (mask & ACE_READ_ATTRIBUTES)
3151 3154 permstr[6] = 'a';
3152 - if (ace->a_access_mask & ACE_WRITE_ATTRIBUTES)
3155 + if (mask & ACE_WRITE_ATTRIBUTES)
3153 3156 permstr[7] = 'A';
3154 - if (ace->a_access_mask & ACE_READ_NAMED_ATTRS)
3157 + if (mask & ACE_READ_NAMED_ATTRS)
3155 3158 permstr[8] = 'R';
3156 - if (ace->a_access_mask & ACE_WRITE_NAMED_ATTRS)
3159 + if (mask & ACE_WRITE_NAMED_ATTRS)
3157 3160 permstr[9] = 'W';
3158 - if (ace->a_access_mask & ACE_READ_ACL)
3161 + if (mask & ACE_READ_ACL)
3159 3162 permstr[10] = 'c';
3160 - if (ace->a_access_mask & ACE_WRITE_ACL)
3163 + if (mask & ACE_WRITE_ACL)
3161 3164 permstr[11] = 'C';
3162 - if (ace->a_access_mask & ACE_WRITE_OWNER)
3165 + if (mask & ACE_WRITE_OWNER)
3163 3166 permstr[12] = 'o';
3164 - if (ace->a_access_mask & ACE_SYNCHRONIZE)
3167 + if (mask & ACE_SYNCHRONIZE)
3165 3168 permstr[13] = 's';
3166 3169 permstr[14] = '\0';
3167 3170 uval.uvaltype = PRA_STRING;
3168 3171 uval.string_val = permstr;
3169 3172 } else if (!(context->format & PRF_RAWM)) {
3170 3173
3171 3174 /*
3172 3175 * Note this differs from acltext.c:ace_perm_txt()
3173 3176 * because we don't know if the acl belongs to a file
3174 3177 * or directory. ace mask value are the same
3175 3178 * nonetheless, see sys/acl.h
3176 3179 */
3177 - if (ace->a_access_mask & ACE_LIST_DIRECTORY) {
3180 + if (mask & ACE_LIST_DIRECTORY) {
3178 3181 returnstat = strappend(&permstr, gettext(READ_DIR_TXT),
3179 3182 &permstr_alloc);
3180 3183 }
3181 - if (ace->a_access_mask & ACE_ADD_FILE) {
3184 + if (mask & ACE_ADD_FILE) {
3182 3185 returnstat = strappend(&permstr, gettext(ADD_FILE_TXT),
3183 3186 &permstr_alloc);
3184 3187 }
3185 - if (ace->a_access_mask & ACE_ADD_SUBDIRECTORY) {
3188 + if (mask & ACE_ADD_SUBDIRECTORY) {
3186 3189 returnstat = strappend(&permstr, gettext(ADD_DIR_TXT),
3187 3190 &permstr_alloc);
3188 3191 }
3189 - if (ace->a_access_mask & ACE_READ_NAMED_ATTRS) {
3192 + if (mask & ACE_READ_NAMED_ATTRS) {
3190 3193 returnstat = strappend(&permstr,
3191 3194 gettext(READ_XATTR_TXT), &permstr_alloc);
3192 3195 }
3193 - if (ace->a_access_mask & ACE_WRITE_NAMED_ATTRS) {
3196 + if (mask & ACE_WRITE_NAMED_ATTRS) {
3194 3197 returnstat = strappend(&permstr,
3195 3198 gettext(WRITE_XATTR_TXT), &permstr_alloc);
3196 3199 }
3197 - if (ace->a_access_mask & ACE_EXECUTE) {
3200 + if (mask & ACE_EXECUTE) {
3198 3201 returnstat = strappend(&permstr,
3199 3202 gettext(EXECUTE_TXT), &permstr_alloc);
3200 3203 }
3201 - if (ace->a_access_mask & ACE_DELETE_CHILD) {
3204 + if (mask & ACE_DELETE_CHILD) {
3202 3205 returnstat = strappend(&permstr,
3203 3206 gettext(DELETE_CHILD_TXT), &permstr_alloc);
3204 3207 }
3205 - if (ace->a_access_mask & ACE_READ_ATTRIBUTES) {
3208 + if (mask & ACE_READ_ATTRIBUTES) {
3206 3209 returnstat = strappend(&permstr,
3207 3210 gettext(READ_ATTRIBUTES_TXT), &permstr_alloc);
3208 3211 }
3209 - if (ace->a_access_mask & ACE_WRITE_ATTRIBUTES) {
3212 + if (mask & ACE_WRITE_ATTRIBUTES) {
3210 3213 returnstat = strappend(&permstr,
3211 3214 gettext(WRITE_ATTRIBUTES_TXT), &permstr_alloc);
3212 3215 }
3213 - if (ace->a_access_mask & ACE_DELETE) {
3216 + if (mask & ACE_DELETE) {
3214 3217 returnstat = strappend(&permstr, gettext(DELETE_TXT),
3215 3218 &permstr_alloc);
3216 3219 }
3217 - if (ace->a_access_mask & ACE_READ_ACL) {
3220 + if (mask & ACE_READ_ACL) {
3218 3221 returnstat = strappend(&permstr, gettext(READ_ACL_TXT),
3219 3222 &permstr_alloc);
3220 3223 }
3221 - if (ace->a_access_mask & ACE_WRITE_ACL) {
3224 + if (mask & ACE_WRITE_ACL) {
3222 3225 returnstat = strappend(&permstr, gettext(WRITE_ACL_TXT),
3223 3226 &permstr_alloc);
3224 3227 }
3225 - if (ace->a_access_mask & ACE_WRITE_OWNER) {
3228 + if (mask & ACE_WRITE_OWNER) {
3226 3229 returnstat = strappend(&permstr,
3227 3230 gettext(WRITE_OWNER_TXT), &permstr_alloc);
3228 3231 }
3229 - if (ace->a_access_mask & ACE_SYNCHRONIZE) {
3232 + if (mask & ACE_SYNCHRONIZE) {
3230 3233 returnstat = strappend(&permstr,
3231 3234 gettext(SYNCHRONIZE_TXT), &permstr_alloc);
3232 3235 }
3233 3236 if (permstr[strlen(permstr) - 1] == '/')
3234 3237 permstr[strlen(permstr) - 1] = '\0';
3235 3238 uval.uvaltype = PRA_STRING;
3236 3239 uval.string_val = permstr;
3237 3240 }
3238 3241 if ((permstr == NULL) || (returnstat != 0) ||
3239 3242 (context->format & PRF_RAWM)) {
3240 - uval.uvaltype = PRA_UINT32;
3241 - uval.uint32_val = ace->a_access_mask;
3243 + uval.uvaltype = PRA_HEX32;
3244 + uval.int32_val = mask;
3242 3245 }
3243 3246 returnstat = pa_print(context, &uval, flag);
3244 3247
3245 3248 if (permstr != NULL)
3246 3249 free(permstr);
3247 3250 if (returnstat != 0)
3248 3251 return (returnstat);
3249 3252 return (close_tag(context, TAG_ACEMASK));
3250 3253 }
3251 3254
3252 3255 static int
3253 3256 pa_ace_type(pr_context_t *context, ace_t *ace, int status, int flag)
3254 3257 {
3255 3258 int returnstat;
3256 3259 uval_t uval;
3257 3260
3258 3261 if (status < 0)
3259 3262 return (status);
3260 3263
3261 3264 /*
3262 3265 * TRANSLATION_NOTE
3263 3266 * ace->a_type refers to access type of ZFS/NFSv4 ACL entry.
3264 3267 */
3265 3268 if ((returnstat = open_tag(context, TAG_ACETYPE)) != 0)
3266 3269 return (returnstat);
3267 3270 if (!(context->format & PRF_RAWM)) {
3268 3271 uval.uvaltype = PRA_STRING;
3269 3272 switch (ace->a_type) {
3270 3273 case ACE_ACCESS_ALLOWED_ACE_TYPE:
3271 3274 uval.string_val = gettext(ALLOW_TXT);
3272 3275 break;
3273 3276 case ACE_ACCESS_DENIED_ACE_TYPE:
3274 3277 uval.string_val = gettext(DENY_TXT);
3275 3278 break;
3276 3279 case ACE_SYSTEM_AUDIT_ACE_TYPE:
3277 3280 uval.string_val = gettext(AUDIT_TXT);
3278 3281 break;
3279 3282 case ACE_SYSTEM_ALARM_ACE_TYPE:
3280 3283 uval.string_val = gettext(ALARM_TXT);
3281 3284 break;
3282 3285 default:
3283 3286 uval.string_val = gettext(UNKNOWN_TXT);
3284 3287 }
3285 3288 } else {
3286 3289 uval.uvaltype = PRA_USHORT;
3287 3290 uval.uint32_val = ace->a_type;
3288 3291 }
3289 3292 if ((returnstat = pa_print(context, &uval, flag)) != 0)
3290 3293 return (returnstat);
3291 3294 return (close_tag(context, TAG_ACETYPE));
3292 3295 }
3293 3296
3294 3297 int
3295 3298 pa_ace(pr_context_t *context, int status, int flag)
3296 3299 {
3297 3300 int returnstat;
3298 3301 ace_t ace;
3299 3302
3300 3303 if (status < 0)
3301 3304 return (status);
3302 3305
3303 3306 if ((returnstat = pr_adr_u_int32(context, &ace.a_who, 1)) != 0)
3304 3307 return (returnstat);
3305 3308 if ((returnstat = pr_adr_u_int32(context, &ace.a_access_mask, 1)) != 0)
3306 3309 return (returnstat);
|
↓ open down ↓ |
55 lines elided |
↑ open up ↑ |
3307 3310 if ((returnstat = pr_adr_u_short(context, &ace.a_flags, 1)) != 0)
3308 3311 return (returnstat);
3309 3312 if ((returnstat = pr_adr_u_short(context, &ace.a_type, 1)) != 0)
3310 3313 return (returnstat);
3311 3314
3312 3315 if ((returnstat = pa_ace_flags(context, &ace, returnstat, 0)) != 0)
3313 3316 return (returnstat);
3314 3317 /* pa_ace_who can returns 1 if uid/gid is not found */
3315 3318 if ((returnstat = pa_ace_who(context, &ace, returnstat, 0)) < 0)
3316 3319 return (returnstat);
3317 - if ((returnstat = pa_ace_access_mask(context, &ace,
3320 + if ((returnstat = pa_ace_access_mask(context, ace.a_access_mask,
3318 3321 returnstat, 0)) != 0)
3319 3322 return (returnstat);
3320 3323 return (pa_ace_type(context, &ace, returnstat, flag));
3324 +}
3325 +
3326 +int
3327 +pa_access_mask(pr_context_t *context, int status, int flag)
3328 +{
3329 + int returnstat;
3330 + uint32_t mask;
3331 +
3332 + if (status < 0)
3333 + return (status);
3334 +
3335 + returnstat = pr_adr_u_int32(context, &mask, 1);
3336 + return (pa_ace_access_mask(context, mask, returnstat, flag));
3337 +}
3338 +
3339 +int
3340 +pa_wsid(pr_context_t *context, int status, int flag)
3341 +{
3342 + int returnstat;
3343 + short length;
3344 + char *sid;
3345 + uval_t uval;
3346 + char *name = NULL;
3347 +
3348 + if (status < 0)
3349 + return (status);
3350 + if ((returnstat = open_tag(context, TAG_WSID)) != 0)
3351 + return (returnstat);
3352 +
3353 + if ((returnstat = pr_adr_short(context, &length, 1)) != 0)
3354 + return (returnstat);
3355 + if ((sid = (char *)malloc(length + 1)) == NULL)
3356 + return (-1);
3357 + if ((returnstat = pr_adr_char(context, sid, length)) != 0) {
3358 + free(sid);
3359 + return (returnstat);
3360 + }
3361 +
3362 + uval.uvaltype = PRA_STRING;
3363 + uval.string_val = sid;
3364 + if ((context->format & PRF_RAWM) == 0) {
3365 + int rc;
3366 + int flag = IDMAP_REQ_FLG_USE_CACHE;
3367 + rc = idmap_getwinnamebysid(sid, flag, &name);
3368 + if (rc == IDMAP_SUCCESS)
3369 + uval.string_val = name;
3370 + else
3371 + (void) fprintf(stderr,
3372 + gettext("praudit: failed to map sid to name "
3373 + "rc=%d\n"), rc);
3374 + }
3375 + returnstat = pa_print(context, &uval, flag);
3376 + free(sid);
3377 + if (name != NULL)
3378 + free(name);
3379 + if (returnstat == 0)
3380 + returnstat = close_tag(context, TAG_WSID);
3381 + return (returnstat);
3321 3382 }
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX