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