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