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", major_32(dev_maj_min), 699 minor_32(dev_maj_min), 700 ipstring); 701 702 return (pa_print(context, &uval, flag)); 703 } 704 705 int 706 pa_tid32_ex(pr_context_t *context, int status, int flag) 707 { 708 int returnstat; 709 int32_t dev_maj_min; 710 uint32_t ip_addr[16]; 711 uint32_t ip_type; 712 struct in_addr ia; 713 char *ipstring; 714 char hostname[256]; 715 char buf[256]; 716 char tbuf[256]; 717 uval_t uval; 718 719 if (status < 0) 720 return (status); 721 722 /* get port info */ 723 if ((returnstat = pr_adr_int32(context, &dev_maj_min, 1)) != 0) 724 return (returnstat); 725 726 /* get address type */ 727 if ((returnstat = pr_adr_u_int32(context, &ip_type, 1)) != 0) 728 return (returnstat); 729 730 /* legal address types are either AU_IPv4 or AU_IPv6 only */ 731 if ((ip_type != AU_IPv4) && (ip_type != AU_IPv6)) 732 return (-1); 733 734 /* get address (4/16) */ 735 if ((returnstat = pr_adr_char(context, (char *)ip_addr, ip_type)) != 0) 736 return (returnstat); 737 738 uval.uvaltype = PRA_STRING; 739 if (ip_type == AU_IPv4) { 740 uval.string_val = buf; 741 742 if (!(context->format & PRF_RAWM)) { 743 get_Hname(ip_addr[0], hostname, sizeof (hostname)); 744 (void) snprintf(buf, sizeof (buf), "%d %d %s", 745 major_32(dev_maj_min), minor_32(dev_maj_min), 746 hostname); 747 return (pa_print(context, &uval, flag)); 748 } 749 750 ia.s_addr = ip_addr[0]; 751 if ((ipstring = inet_ntoa(ia)) == NULL) 752 return (-1); 753 754 (void) snprintf(buf, sizeof (buf), "%d %d %s", 755 major_32(dev_maj_min), minor_32(dev_maj_min), ipstring); 756 757 return (pa_print(context, &uval, flag)); 758 } else { 759 uval.string_val = buf; 760 761 if (!(context->format & PRF_RAWM)) { 762 get_Hname_ex(ip_addr, hostname, sizeof (hostname)); 763 (void) snprintf(buf, sizeof (buf), "%d %d %s", 764 major_32(dev_maj_min), minor_32(dev_maj_min), 765 hostname); 766 return (pa_print(context, &uval, flag)); 767 } 768 769 (void) inet_ntop(AF_INET6, (void *) ip_addr, tbuf, 770 sizeof (tbuf)); 771 772 (void) snprintf(buf, sizeof (buf), "%d %d %s", 773 major_32(dev_maj_min), minor_32(dev_maj_min), tbuf); 774 775 return (pa_print(context, &uval, flag)); 776 } 777 } 778 779 int 780 pa_ip_addr(pr_context_t *context, int status, int flag) 781 { 782 int returnstat; 783 uval_t uval; 784 uint32_t ip_addr[4]; 785 uint32_t ip_type; 786 struct in_addr ia; 787 char *ipstring; 788 char hostname[256]; 789 char buf[256]; 790 char tbuf[256]; 791 792 if (status < 0) 793 return (status); 794 795 /* get address type */ 796 if ((returnstat = pr_adr_u_int32(context, &ip_type, 1)) != 0) 797 return (returnstat); 798 799 /* legal address type is AU_IPv4 or AU_IPv6 */ 800 if ((ip_type != AU_IPv4) && (ip_type != AU_IPv6)) 801 return (-1); 802 803 /* get address (4/16) */ 804 if ((returnstat = pr_adr_char(context, (char *)ip_addr, ip_type)) != 0) 805 return (returnstat); 806 807 uval.uvaltype = PRA_STRING; 808 if (ip_type == AU_IPv4) { 809 uval.string_val = buf; 810 811 if (!(context->format & PRF_RAWM)) { 812 get_Hname(ip_addr[0], hostname, sizeof (hostname)); 813 (void) snprintf(buf, sizeof (buf), "%s", hostname); 814 return (pa_print(context, &uval, flag)); 815 } 816 817 ia.s_addr = ip_addr[0]; 818 if ((ipstring = inet_ntoa(ia)) == NULL) 819 return (-1); 820 821 (void) snprintf(buf, sizeof (buf), "%s", ipstring); 822 823 return (pa_print(context, &uval, flag)); 824 } else { 825 uval.string_val = buf; 826 827 if (!(context->format & PRF_RAWM)) { 828 get_Hname_ex(ip_addr, hostname, sizeof (hostname)); 829 (void) snprintf(buf, sizeof (buf), "%s", 830 hostname); 831 return (pa_print(context, &uval, flag)); 832 } 833 834 (void) inet_ntop(AF_INET6, (void *) ip_addr, tbuf, 835 sizeof (tbuf)); 836 837 (void) snprintf(buf, sizeof (buf), "%s", tbuf); 838 839 return (pa_print(context, &uval, flag)); 840 } 841 842 } 843 844 int 845 pa_tid64(pr_context_t *context, int status, int flag) 846 { 847 int returnstat; 848 int64_t dev_maj_min; 849 uint32_t ip_addr; 850 struct in_addr ia; 851 char *ipstring; 852 char buf[256]; 853 uval_t uval; 854 855 if (status < 0) 856 return (status); 857 858 if ((returnstat = pr_adr_int64(context, &dev_maj_min, 1)) != 0) 859 return (returnstat); 860 861 if ((returnstat = pr_adr_char(context, (char *)&ip_addr, 4)) != 0) 862 return (returnstat); 863 864 uval.uvaltype = PRA_STRING; 865 uval.string_val = buf; 866 867 if (!(context->format & PRF_RAWM)) { 868 char hostname[256]; 869 870 get_Hname(ip_addr, hostname, sizeof (hostname)); 871 (void) snprintf(buf, sizeof (buf), "%d %d %s", 872 major_64(dev_maj_min), minor_64(dev_maj_min), hostname); 873 return (pa_print(context, &uval, flag)); 874 } 875 876 ia.s_addr = ip_addr; 877 if ((ipstring = inet_ntoa(ia)) == NULL) 878 return (-1); 879 880 (void) snprintf(buf, sizeof (buf), "%d %d %s", 881 major_64(dev_maj_min), minor_64(dev_maj_min), ipstring); 882 883 return (pa_print(context, &uval, flag)); 884 } 885 886 int 887 pa_tid64_ex(pr_context_t *context, int status, int flag) 888 { 889 int returnstat; 890 int64_t dev_maj_min; 891 uint32_t ip_addr[4]; 892 uint32_t ip_type; 893 struct in_addr ia; 894 char *ipstring; 895 char hostname[256]; 896 char buf[256]; 897 char tbuf[256]; 898 uval_t uval; 899 900 if (status < 0) 901 return (status); 902 903 /* get port info */ 904 if ((returnstat = pr_adr_int64(context, &dev_maj_min, 1)) != 0) 905 return (returnstat); 906 907 /* get address type */ 908 if ((returnstat = pr_adr_u_int32(context, &ip_type, 1)) != 0) 909 return (returnstat); 910 911 /* legal address types are either AU_IPv4 or AU_IPv6 only */ 912 if ((ip_type != AU_IPv4) && (ip_type != AU_IPv6)) 913 return (-1); 914 915 /* get address (4/16) */ 916 if ((returnstat = pr_adr_char(context, (char *)&ip_addr, ip_type)) != 0) 917 return (returnstat); 918 919 uval.uvaltype = PRA_STRING; 920 if (ip_type == AU_IPv4) { 921 uval.string_val = buf; 922 923 if (!(context->format & PRF_RAWM)) { 924 get_Hname(ip_addr[0], hostname, sizeof (hostname)); 925 uval.string_val = buf; 926 (void) snprintf(buf, sizeof (buf), "%d %d %s", 927 major_64(dev_maj_min), minor_64(dev_maj_min), 928 hostname); 929 return (pa_print(context, &uval, flag)); 930 } 931 932 ia.s_addr = ip_addr[0]; 933 if ((ipstring = inet_ntoa(ia)) == NULL) 934 return (-1); 935 936 (void) snprintf(buf, sizeof (buf), "%d %d %s", 937 major_64(dev_maj_min), minor_64(dev_maj_min), ipstring); 938 939 return (pa_print(context, &uval, flag)); 940 } else { 941 uval.string_val = buf; 942 943 if (!(context->format & PRF_RAWM)) { 944 get_Hname_ex(ip_addr, hostname, sizeof (hostname)); 945 (void) snprintf(buf, sizeof (buf), "%d %d %s", 946 major_64(dev_maj_min), minor_64(dev_maj_min), 947 hostname); 948 return (pa_print(context, &uval, flag)); 949 } 950 951 (void) inet_ntop(AF_INET6, (void *)ip_addr, tbuf, 952 sizeof (tbuf)); 953 954 (void) snprintf(buf, sizeof (buf), "%d %d %s", 955 major_64(dev_maj_min), minor_64(dev_maj_min), tbuf); 956 957 return (pa_print(context, &uval, flag)); 958 } 959 } 960 961 962 /* 963 * ---------------------------------------------------------------- 964 * findfieldwidth: 965 * Returns the field width based on the basic unit and print mode. 966 * This routine is called to determine the field width for the 967 * data items in the arbitrary data token where the tokens are 968 * to be printed in more than one line. The field width can be 969 * found in the fwidth structure. 970 * 971 * Input parameters: 972 * basicunit Can be one of AUR_CHAR, AUR_BYTE, AUR_SHORT, 973 * AUR_INT32, or AUR_INT64 974 * howtoprint Print mode. Can be one of AUP_BINARY, AUP_OCTAL, 975 * AUP_DECIMAL, or AUP_HEX. 976 * ---------------------------------------------------------------- 977 */ 978 int 979 findfieldwidth(char basicunit, char howtoprint) 980 { 981 int i, j; 982 983 for (i = 0; i < numwidthentries; i++) { 984 if (fwidth[i].basic_unit == basicunit) { 985 for (j = 0; j <= 4; j++) { 986 if (fwidth[i].pwidth[j].print_base == 987 howtoprint) { 988 return ( 989 fwidth[i].pwidth[j].field_width); 990 } 991 } 992 /* 993 * if we got here, then we didn't get what we were after 994 */ 995 return (0); 996 } 997 } 998 /* if we got here, we didn't get what we wanted either */ 999 return (0); 1000 } 1001 1002 1003 /* 1004 * ----------------------------------------------------------------------- 1005 * pa_cmd: Retrieves the cmd item from the input stream. 1006 * return codes : -1 - error 1007 * : 0 - successful 1008 * ----------------------------------------------------------------------- 1009 */ 1010 int 1011 pa_cmd(pr_context_t *context, int status, int flag) 1012 { 1013 char *cmd; /* cmd */ 1014 short length; 1015 int returnstat; 1016 uval_t uval; 1017 1018 /* 1019 * We need to know how much space to allocate for our string, so 1020 * read the length first, then call pr_adr_char to read those bytes. 1021 */ 1022 if (status >= 0) { 1023 if (pr_adr_short(context, &length, 1) == 0) { 1024 if ((cmd = (char *)malloc(length + 1)) == NULL) 1025 return (-1); 1026 if (pr_adr_char(context, cmd, length) == 0) { 1027 uval.uvaltype = PRA_STRING; 1028 uval.string_val = cmd; 1029 returnstat = pa_print(context, &uval, flag); 1030 } else { 1031 returnstat = -1; 1032 } 1033 free(cmd); 1034 return (returnstat); 1035 } else 1036 return (-1); 1037 } else 1038 return (status); 1039 } 1040 1041 1042 1043 /* 1044 * ----------------------------------------------------------------------- 1045 * pa_adr_byte : Issues pr_adr_char to retrieve the next ADR item from 1046 * the input stream pointed to by audit_adr, and prints it 1047 * as an integer if status >= 0 1048 * return codes : -1 - error 1049 * : 0 - successful 1050 * ----------------------------------------------------------------------- 1051 */ 1052 int 1053 pa_adr_byte(pr_context_t *context, int status, int flag) 1054 { 1055 char c; 1056 uval_t uval; 1057 1058 if (status >= 0) { 1059 if (pr_adr_char(context, &c, 1) == 0) { 1060 uval.uvaltype = PRA_BYTE; 1061 uval.char_val = c; 1062 return (pa_print(context, &uval, flag)); 1063 } else 1064 return (-1); 1065 } else 1066 return (status); 1067 } 1068 1069 /* 1070 * ----------------------------------------------------------------------- 1071 * pa_adr_charhex: Issues pr_adr_char to retrieve the next ADR item from 1072 * the input stream pointed to by audit_adr, and prints it 1073 * in hexadecimal if status >= 0 1074 * return codes : -1 - error 1075 * : 0 - successful 1076 * ----------------------------------------------------------------------- 1077 */ 1078 int 1079 pa_adr_charhex(pr_context_t *context, int status, int flag) 1080 { 1081 char p[2]; 1082 int returnstat; 1083 uval_t uval; 1084 1085 if (status >= 0) { 1086 p[0] = p[1] = 0; 1087 1088 if ((returnstat = pr_adr_char(context, p, 1)) == 0) { 1089 uval.uvaltype = PRA_STRING; 1090 uval.string_val = hexconvert(p, sizeof (char), 1091 sizeof (char)); 1092 if (uval.string_val) { 1093 returnstat = pa_print(context, &uval, flag); 1094 free(uval.string_val); 1095 } 1096 } 1097 return (returnstat); 1098 } else 1099 return (status); 1100 } 1101 1102 /* 1103 * ----------------------------------------------------------------------- 1104 * pa_adr_int32 : Issues pr_adr_int32 to retrieve the next ADR item from the 1105 * input stream pointed to by audit_adr, and prints it 1106 * if status >= 0 1107 * return codes : -1 - error 1108 * : 0 - successful 1109 * ----------------------------------------------------------------------- 1110 */ 1111 int 1112 pa_adr_int32(pr_context_t *context, int status, int flag) 1113 { 1114 int32_t c; 1115 uval_t uval; 1116 1117 if (status >= 0) { 1118 if (pr_adr_int32(context, &c, 1) == 0) { 1119 uval.uvaltype = PRA_INT32; 1120 uval.int32_val = c; 1121 return (pa_print(context, &uval, flag)); 1122 } else 1123 return (-1); 1124 } else 1125 return (status); 1126 } 1127 1128 1129 1130 1131 /* 1132 * ----------------------------------------------------------------------- 1133 * pa_adr_int64 : Issues pr_adr_int64 to retrieve the next ADR item from the 1134 * input stream pointed to by audit_adr, and prints it 1135 * if status >= 0 1136 * return codes : -1 - error 1137 * : 0 - successful 1138 * ----------------------------------------------------------------------- 1139 */ 1140 int 1141 pa_adr_int64(pr_context_t *context, int status, int flag) 1142 { 1143 int64_t c; 1144 uval_t uval; 1145 1146 if (status >= 0) { 1147 if (pr_adr_int64(context, &c, 1) == 0) { 1148 uval.uvaltype = PRA_INT64; 1149 uval.int64_val = c; 1150 return (pa_print(context, &uval, flag)); 1151 } else 1152 return (-1); 1153 } else 1154 return (status); 1155 } 1156 1157 /* 1158 * ----------------------------------------------------------------------- 1159 * pa_adr_int64hex: Issues pr_adr_int64 to retrieve the next ADR item from the 1160 * input stream pointed to by audit_adr, and prints it 1161 * in hexadecimal if status >= 0 1162 * return codes : -1 - error 1163 * : 0 - successful 1164 * ----------------------------------------------------------------------- 1165 */ 1166 int 1167 pa_adr_int32hex(pr_context_t *context, int status, int flag) 1168 { 1169 int32_t l; 1170 int returnstat; 1171 uval_t uval; 1172 1173 if (status >= 0) { 1174 if ((returnstat = pr_adr_int32(context, &l, 1)) == 0) { 1175 uval.uvaltype = PRA_HEX32; 1176 uval.int32_val = l; 1177 returnstat = pa_print(context, &uval, flag); 1178 } 1179 return (returnstat); 1180 } else 1181 return (status); 1182 } 1183 1184 /* 1185 * ----------------------------------------------------------------------- 1186 * pa_adr_int64hex: Issues pr_adr_int64 to retrieve the next ADR item from the 1187 * input stream pointed to by audit_adr, and prints it 1188 * in hexadecimal if status >= 0 1189 * return codes : -1 - error 1190 * : 0 - successful 1191 * ----------------------------------------------------------------------- 1192 */ 1193 int 1194 pa_adr_int64hex(pr_context_t *context, int status, int flag) 1195 { 1196 int64_t l; 1197 int returnstat; 1198 uval_t uval; 1199 1200 if (status >= 0) { 1201 if ((returnstat = pr_adr_int64(context, &l, 1)) == 0) { 1202 uval.uvaltype = PRA_HEX64; 1203 uval.int64_val = l; 1204 returnstat = pa_print(context, &uval, flag); 1205 } 1206 return (returnstat); 1207 } else 1208 return (status); 1209 } 1210 1211 1212 /* 1213 * ------------------------------------------------------------------- 1214 * bu2string: Maps a print basic unit type to a string. 1215 * returns : The string mapping or "unknown basic unit type". 1216 * ------------------------------------------------------------------- 1217 */ 1218 char * 1219 bu2string(char basic_unit) 1220 { 1221 register int i; 1222 1223 struct bu_map_ent { 1224 char basic_unit; 1225 char *string; 1226 }; 1227 1228 /* 1229 * TRANSLATION_NOTE 1230 * These names are data units when displaying the arbitrary data 1231 * token. 1232 */ 1233 1234 static struct bu_map_ent bu_map[] = { 1235 { AUR_BYTE, "byte" }, 1236 { AUR_CHAR, "char" }, 1237 { AUR_SHORT, "short" }, 1238 { AUR_INT32, "int32" }, 1239 { AUR_INT64, "int64" } }; 1240 1241 for (i = 0; i < sizeof (bu_map) / sizeof (struct bu_map_ent); i++) 1242 if (basic_unit == bu_map[i].basic_unit) 1243 return (gettext(bu_map[i].string)); 1244 1245 return (gettext("unknown basic unit type")); 1246 } 1247 1248 1249 /* 1250 * ------------------------------------------------------------------- 1251 * eventmodifier2string: Maps event modifier flags to a readable string. 1252 * returns: The string mapping or "none". 1253 * ------------------------------------------------------------------- 1254 */ 1255 static void 1256 eventmodifier2string(ushort_t emodifier, char *modstring, size_t modlen) 1257 { 1258 register int i, j; 1259 1260 struct em_map_ent { 1261 int mask; 1262 char *string; 1263 }; 1264 1265 /* 1266 * TRANSLATION_NOTE 1267 * These abbreviations represent the event modifier field of the 1268 * header token. To gain a better understanding of each modifier, 1269 * read 1270 * System Administration Guide: Security Services >> Solaris Auditing 1271 * at http://docs.sun.com. 1272 */ 1273 1274 static struct em_map_ent em_map[] = { 1275 { (int)PAD_READ, "rd" }, /* data read from object */ 1276 { (int)PAD_WRITE, "wr" }, /* data written to object */ 1277 { (int)PAD_SPRIVUSE, "sp" }, /* successfully used priv */ 1278 { (int)PAD_FPRIVUSE, "fp" }, /* failed use of priv */ 1279 { (int)PAD_NONATTR, "na" }, /* non-attributable event */ 1280 { (int)PAD_FAILURE, "fe" } /* fail audit event */ 1281 }; 1282 1283 modstring[0] = '\0'; 1284 1285 for (i = 0, j = 0; i < sizeof (em_map) / sizeof (struct em_map_ent); 1286 i++) { 1287 if ((int)emodifier & em_map[i].mask) { 1288 if (j++) 1289 (void) strlcat(modstring, ":", modlen); 1290 (void) strlcat(modstring, em_map[i].string, modlen); 1291 } 1292 } 1293 } 1294 1295 1296 /* 1297 * --------------------------------------------------------- 1298 * convert_char_to_string: 1299 * Converts a byte to string depending on the print mode 1300 * input : printmode, which may be one of AUP_BINARY, 1301 * AUP_OCTAL, AUP_DECIMAL, and AUP_HEX 1302 * c, which is the byte to convert 1303 * output : p, which is a pointer to the location where 1304 * the resulting string is to be stored 1305 * ---------------------------------------------------------- 1306 */ 1307 1308 int 1309 convert_char_to_string(char printmode, char c, char *p) 1310 { 1311 union { 1312 char c1[4]; 1313 int c2; 1314 } dat; 1315 1316 dat.c2 = 0; 1317 dat.c1[3] = c; 1318 1319 if (printmode == AUP_BINARY) 1320 (void) convertbinary(p, &c, sizeof (char)); 1321 else if (printmode == AUP_OCTAL) 1322 (void) sprintf(p, "%o", (int)dat.c2); 1323 else if (printmode == AUP_DECIMAL) 1324 (void) sprintf(p, "%d", c); 1325 else if (printmode == AUP_HEX) 1326 (void) sprintf(p, "0x%x", (int)dat.c2); 1327 else if (printmode == AUP_STRING) 1328 convertascii(p, &c, sizeof (char)); 1329 return (0); 1330 } 1331 1332 /* 1333 * -------------------------------------------------------------- 1334 * convert_short_to_string: 1335 * Converts a short integer to string depending on the print mode 1336 * input : printmode, which may be one of AUP_BINARY, 1337 * AUP_OCTAL, AUP_DECIMAL, and AUP_HEX 1338 * c, which is the short integer to convert 1339 * output : p, which is a pointer to the location where 1340 * the resulting string is to be stored 1341 * --------------------------------------------------------------- 1342 */ 1343 int 1344 convert_short_to_string(char printmode, short c, char *p) 1345 { 1346 union { 1347 short c1[2]; 1348 int c2; 1349 } dat; 1350 1351 dat.c2 = 0; 1352 dat.c1[1] = c; 1353 1354 if (printmode == AUP_BINARY) 1355 (void) convertbinary(p, (char *)&c, sizeof (short)); 1356 else if (printmode == AUP_OCTAL) 1357 (void) sprintf(p, "%o", (int)dat.c2); 1358 else if (printmode == AUP_DECIMAL) 1359 (void) sprintf(p, "%hd", c); 1360 else if (printmode == AUP_HEX) 1361 (void) sprintf(p, "0x%x", (int)dat.c2); 1362 else if (printmode == AUP_STRING) 1363 convertascii(p, (char *)&c, sizeof (short)); 1364 return (0); 1365 } 1366 1367 /* 1368 * --------------------------------------------------------- 1369 * convert_int32_to_string: 1370 * Converts a integer to string depending on the print mode 1371 * input : printmode, which may be one of AUP_BINARY, 1372 * AUP_OCTAL, AUP_DECIMAL, and AUP_HEX 1373 * c, which is the integer to convert 1374 * output : p, which is a pointer to the location where 1375 * the resulting string is to be stored 1376 * ---------------------------------------------------------- 1377 */ 1378 int 1379 convert_int32_to_string(char printmode, int32_t c, char *p) 1380 { 1381 if (printmode == AUP_BINARY) 1382 (void) convertbinary(p, (char *)&c, sizeof (int32_t)); 1383 else if (printmode == AUP_OCTAL) 1384 (void) sprintf(p, "%o", c); 1385 else if (printmode == AUP_DECIMAL) 1386 (void) sprintf(p, "%d", c); 1387 else if (printmode == AUP_HEX) 1388 (void) sprintf(p, "0x%x", c); 1389 else if (printmode == AUP_STRING) 1390 convertascii(p, (char *)&c, sizeof (int)); 1391 return (0); 1392 } 1393 1394 /* 1395 * --------------------------------------------------------- 1396 * convert_int64_to_string: 1397 * Converts a integer to string depending on the print mode 1398 * input : printmode, which may be one of AUP_BINARY, 1399 * AUP_OCTAL, AUP_DECIMAL, and AUP_HEX 1400 * c, which is the integer to convert 1401 * output : p, which is a pointer to the location where 1402 * the resulting string is to be stored 1403 * ---------------------------------------------------------- 1404 */ 1405 int 1406 convert_int64_to_string(char printmode, int64_t c, char *p) 1407 { 1408 if (printmode == AUP_BINARY) 1409 (void) convertbinary(p, (char *)&c, sizeof (int64_t)); 1410 else if (printmode == AUP_OCTAL) 1411 (void) sprintf(p, "%"PRIo64, c); 1412 else if (printmode == AUP_DECIMAL) 1413 (void) sprintf(p, "%"PRId64, c); 1414 else if (printmode == AUP_HEX) 1415 (void) sprintf(p, "0x%"PRIx64, c); 1416 else if (printmode == AUP_STRING) 1417 convertascii(p, (char *)&c, sizeof (int64_t)); 1418 return (0); 1419 } 1420 1421 1422 /* 1423 * ----------------------------------------------------------- 1424 * convertbinary: 1425 * Converts a unit c of 'size' bytes long into a binary string 1426 * and returns it into the position pointed to by p 1427 * ------------------------------------------------------------ 1428 */ 1429 int 1430 convertbinary(char *p, char *c, int size) 1431 { 1432 char *s, *t, *ss; 1433 int i, j; 1434 1435 if ((s = (char *)malloc(8 * size + 1)) == NULL) 1436 return (0); 1437 1438 ss = s; 1439 1440 /* first convert to binary */ 1441 t = s; 1442 for (i = 0; i < size; i++) { 1443 for (j = 0; j < 8; j++) 1444 (void) sprintf(t++, "%d", ((*c >> (7 - j)) & (0x01))); 1445 c++; 1446 } 1447 *t = '\0'; 1448 1449 /* now string leading zero's if any */ 1450 j = strlen(s) - 1; 1451 for (i = 0; i < j; i++) { 1452 if (*s != '0') 1453 break; 1454 else 1455 s++; 1456 } 1457 1458 /* now copy the contents of s to p */ 1459 t = p; 1460 for (i = 0; i < (8 * size + 1); i++) { 1461 if (*s == '\0') { 1462 *t = '\0'; 1463 break; 1464 } 1465 *t++ = *s++; 1466 } 1467 free(ss); 1468 1469 return (1); 1470 } 1471 1472 1473 static char hex[] = "0123456789abcdef"; 1474 /* 1475 * ------------------------------------------------------------------- 1476 * hexconvert : Converts a string of (size) bytes to hexadecimal, and 1477 * returns the hexadecimal string. 1478 * returns : - NULL if memory cannot be allocated for the string, or 1479 * - pointer to the hexadecimal string if successful 1480 * ------------------------------------------------------------------- 1481 */ 1482 char * 1483 hexconvert(char *c, int size, int chunk) 1484 { 1485 register char *s, *t; 1486 register int i, j, k; 1487 int numchunks; 1488 int leftovers; 1489 1490 if (size <= 0) 1491 return (NULL); 1492 1493 if ((s = (char *)malloc((size * 5) + 1)) == NULL) 1494 return (NULL); 1495 1496 if (chunk > size || chunk <= 0) 1497 chunk = size; 1498 1499 numchunks = size / chunk; 1500 leftovers = size % chunk; 1501 1502 t = s; 1503 for (i = j = 0; i < numchunks; i++) { 1504 if (j++) { 1505 *t++ = ' '; 1506 } 1507 *t++ = '0'; 1508 *t++ = 'x'; 1509 for (k = 0; k < chunk; k++) { 1510 *t++ = hex[(uint_t)((uchar_t)*c >> 4)]; 1511 *t++ = hex[(uint_t)((uchar_t)*c & 0xF)]; 1512 c++; 1513 } 1514 } 1515 1516 if (leftovers) { 1517 *t++ = ' '; 1518 *t++ = '0'; 1519 *t++ = 'x'; 1520 for (i = 0; i < leftovers; i++) { 1521 *t++ = hex[(uint_t)((uchar_t)*c >> 4)]; 1522 *t++ = hex[(uint_t)((uchar_t)*c & 0xF)]; 1523 c++; 1524 } 1525 } 1526 1527 *t = '\0'; 1528 return (s); 1529 } 1530 1531 1532 /* 1533 * ------------------------------------------------------------------- 1534 * htp2string: Maps a print suggestion to a string. 1535 * returns : The string mapping or "unknown print suggestion". 1536 * ------------------------------------------------------------------- 1537 */ 1538 char * 1539 htp2string(char print_sugg) 1540 { 1541 register int i; 1542 1543 struct htp_map_ent { 1544 char print_sugg; 1545 char *print_string; 1546 }; 1547 1548 /* 1549 * TRANSLATION_NOTE 1550 * These names are data types when displaying the arbitrary data 1551 * token. 1552 */ 1553 1554 static struct htp_map_ent htp_map[] = { 1555 { AUP_BINARY, "binary" }, 1556 { AUP_OCTAL, "octal" }, 1557 { AUP_DECIMAL, "decimal" }, 1558 { AUP_HEX, "hexadecimal" }, 1559 { AUP_STRING, "string" } }; 1560 1561 for (i = 0; i < sizeof (htp_map) / sizeof (struct htp_map_ent); i++) 1562 if (print_sugg == htp_map[i].print_sugg) 1563 return (gettext(htp_map[i].print_string)); 1564 1565 return (gettext("unknown print suggestion")); 1566 } 1567 1568 /* 1569 * ---------------------------------------------------------------------- 1570 * pa_adr_short: Issues pr_adr_short to retrieve the next ADR item from the 1571 * input stream pointed to by audit_adr, and prints it 1572 * if status >= 0 1573 * return codes: -1 - error 1574 * : 0 - successful 1575 * ---------------------------------------------------------------------- 1576 */ 1577 int 1578 pa_adr_short(pr_context_t *context, int status, int flag) 1579 { 1580 short c; 1581 uval_t uval; 1582 1583 if (status >= 0) { 1584 if (pr_adr_short(context, &c, 1) == 0) { 1585 uval.uvaltype = PRA_SHORT; 1586 uval.short_val = c; 1587 return (pa_print(context, &uval, flag)); 1588 } else 1589 return (-1); 1590 } else 1591 return (status); 1592 } 1593 1594 /* 1595 * ----------------------------------------------------------------------- 1596 * pa_adr_shorthex: Issues pr_adr_short to retrieve the next ADR item from the 1597 * input stream pointed to by audit_adr, and prints it 1598 * in hexadecimal if status >= 0 1599 * return codes : -1 - error 1600 * : 0 - successful 1601 * ----------------------------------------------------------------------- 1602 */ 1603 int 1604 pa_adr_shorthex(pr_context_t *context, int status, int flag) 1605 { 1606 short s; 1607 int returnstat; 1608 uval_t uval; 1609 1610 if (status >= 0) { 1611 if ((returnstat = pr_adr_short(context, &s, 1)) == 0) { 1612 uval.uvaltype = PRA_STRING; 1613 uval.string_val = hexconvert((char *)&s, sizeof (s), 1614 sizeof (s)); 1615 if (uval.string_val) { 1616 returnstat = pa_print(context, &uval, flag); 1617 free(uval.string_val); 1618 } 1619 } 1620 return (returnstat); 1621 } else 1622 return (status); 1623 } 1624 1625 1626 /* 1627 * ----------------------------------------------------------------------- 1628 * pa_adr_string: Retrieves a string from the input stream and prints it 1629 * if status >= 0 1630 * return codes : -1 - error 1631 * : 0 - successful 1632 * ----------------------------------------------------------------------- 1633 */ 1634 int 1635 pa_adr_string(pr_context_t *context, int status, int flag) 1636 { 1637 char *c; 1638 char *p; 1639 short length; 1640 int returnstat; 1641 uval_t uval; 1642 1643 /* 1644 * We need to know how much space to allocate for our string, so 1645 * read the length first, then call pr_adr_char to read those bytes. 1646 */ 1647 if (status < 0) 1648 return (status); 1649 1650 if ((returnstat = pr_adr_short(context, &length, 1)) != 0) 1651 return (returnstat); 1652 if ((c = (char *)malloc(length + 1)) == NULL) 1653 return (-1); 1654 if ((p = (char *)malloc((length * 2) + 1)) == NULL) { 1655 free(c); 1656 return (-1); 1657 } 1658 if ((returnstat = pr_adr_char(context, c, length)) != 0) { 1659 free(c); 1660 free(p); 1661 return (returnstat); 1662 } 1663 convertascii(p, c, length - 1); 1664 uval.uvaltype = PRA_STRING; 1665 uval.string_val = p; 1666 returnstat = pa_print(context, &uval, flag); 1667 free(c); 1668 free(p); 1669 return (returnstat); 1670 } 1671 1672 /* 1673 * ----------------------------------------------------------------------- 1674 * pa_file_string: Retrieves a file string from the input stream and prints it 1675 * if status >= 0 1676 * return codes : -1 - error 1677 * : 0 - successful 1678 * ----------------------------------------------------------------------- 1679 */ 1680 int 1681 pa_file_string(pr_context_t *context, int status, int flag) 1682 { 1683 char *c; 1684 char *p; 1685 short length; 1686 int returnstat; 1687 uval_t uval; 1688 1689 /* 1690 * We need to know how much space to allocate for our string, so 1691 * read the length first, then call pr_adr_char to read those bytes. 1692 */ 1693 if (status < 0) 1694 return (status); 1695 1696 if ((returnstat = pr_adr_short(context, &length, 1)) != 0) 1697 return (returnstat); 1698 if ((c = (char *)malloc(length + 1)) == NULL) 1699 return (-1); 1700 if ((p = (char *)malloc((length * 2) + 1)) == NULL) { 1701 free(c); 1702 return (-1); 1703 } 1704 if ((returnstat = pr_adr_char(context, c, length)) != 0) { 1705 free(c); 1706 free(p); 1707 return (returnstat); 1708 } 1709 1710 if (is_file_token(context->tokenid)) 1711 context->audit_rec_len += length; 1712 1713 convertascii(p, c, length - 1); 1714 uval.uvaltype = PRA_STRING; 1715 uval.string_val = p; 1716 1717 if (returnstat == 0) 1718 returnstat = finish_open_tag(context); 1719 1720 if (returnstat == 0) 1721 returnstat = pa_print(context, &uval, flag); 1722 1723 free(c); 1724 free(p); 1725 return (returnstat); 1726 } 1727 1728 static int 1729 pa_putstr_xml(pr_context_t *context, int printable, char *str, size_t len) 1730 { 1731 int err; 1732 1733 if (!printable) { 1734 /* 1735 * Unprintable chars should always be converted to the 1736 * visible form. If there are unprintable characters which 1737 * require special treatment in xml, those should be 1738 * handled here. 1739 */ 1740 do { 1741 err = pr_printf(context, "\\%03o", 1742 (unsigned char)*str++); 1743 } while (err == 0 && --len != 0); 1744 return (err); 1745 } 1746 /* printable characters */ 1747 if (len == 1) { 1748 /* 1749 * check for the special chars only when char size was 1 1750 * ie, ignore special chars appear in the middle of multibyte 1751 * sequence. 1752 */ 1753 1754 /* Escape for XML */ 1755 switch (*str) { 1756 case '&': 1757 err = pr_printf(context, "%s", "&"); 1758 break; 1759 1760 case '<': 1761 err = pr_printf(context, "%s", "<"); 1762 break; 1763 1764 case '>': 1765 err = pr_printf(context, "%s", ">"); 1766 break; 1767 1768 case '\"': 1769 err = pr_printf(context, "%s", """); 1770 break; 1771 1772 case '\'': 1773 err = pr_printf(context, "%s", "'"); 1774 break; 1775 1776 default: 1777 err = pr_putchar(context, *str); 1778 break; 1779 } 1780 return (err); 1781 } 1782 do { 1783 err = pr_putchar(context, *str++); 1784 } while (err == 0 && --len != 0); 1785 return (err); 1786 } 1787 1788 static int 1789 pa_putstr(pr_context_t *context, int printable, char *str, size_t len) 1790 { 1791 int err; 1792 1793 if (context->format & PRF_XMLM) 1794 return (pa_putstr_xml(context, printable, str, len)); 1795 1796 if (!printable) { 1797 do { 1798 err = pr_printf(context, "\\%03o", 1799 (unsigned char)*str++); 1800 } while (err == 0 && --len != 0); 1801 return (err); 1802 } 1803 do { 1804 err = pr_putchar(context, *str++); 1805 } while (err == 0 && --len != 0); 1806 return (err); 1807 } 1808 1809 int 1810 pa_string(pr_context_t *context, int status, int flag) 1811 { 1812 int rstat, wstat; 1813 int i, printable, eos; 1814 int mlen, rlen; 1815 int mbmax = MB_CUR_MAX; 1816 wchar_t wc; 1817 char mbuf[MB_LEN_MAX + 1]; 1818 char c; 1819 1820 if (status < 0) 1821 return (status); 1822 1823 rstat = wstat = 0; 1824 1825 if (mbmax == 1) { 1826 while (wstat == 0) { 1827 if ((rstat = pr_adr_char(context, &c, 1)) < 0) 1828 break; 1829 if (c == '\0') 1830 break; 1831 printable = isprint((unsigned char)c); 1832 wstat = pa_putstr(context, printable, &c, 1); 1833 } 1834 goto done; 1835 } 1836 1837 mlen = eos = 0; 1838 while (wstat == 0) { 1839 rlen = 0; 1840 do { 1841 if (!eos) { 1842 rstat = pr_adr_char(context, &c, 1); 1843 if (rstat != 0 || c == '\0') 1844 eos = 1; 1845 else 1846 mbuf[mlen++] = c; 1847 } 1848 rlen = mbtowc(&wc, mbuf, mlen); 1849 } while (!eos && mlen < mbmax && rlen <= 0); 1850 1851 if (mlen == 0) 1852 break; /* end of string */ 1853 1854 if (rlen <= 0) { /* no good sequence */ 1855 rlen = 1; 1856 printable = 0; 1857 } else { 1858 printable = iswprint(wc); 1859 } 1860 wstat = pa_putstr(context, printable, mbuf, rlen); 1861 mlen -= rlen; 1862 if (mlen > 0) { 1863 for (i = 0; i < mlen; i++) 1864 mbuf[i] = mbuf[rlen + i]; 1865 } 1866 } 1867 1868 done: 1869 if (wstat == 0) 1870 wstat = do_newline(context, flag); 1871 1872 if (wstat == 0 && context->data_mode == FILEMODE) 1873 (void) fflush(stdout); 1874 1875 return ((rstat != 0 || wstat != 0) ? -1 : 0); 1876 } 1877 1878 /* 1879 * ----------------------------------------------------------------------- 1880 * pa_adr_u_int32: Issues pr_adr_u_int32 to retrieve the next ADR item from 1881 * the input stream pointed to by audit_adr, and prints it 1882 * if status = 0 1883 * return codes : -1 - error 1884 * : 0 - successful 1885 * ----------------------------------------------------------------------- 1886 */ 1887 1888 1889 int 1890 pa_adr_u_int32(pr_context_t *context, int status, int flag) 1891 { 1892 uint32_t c; 1893 uval_t uval; 1894 1895 if (status >= 0) { 1896 if (pr_adr_u_int32(context, &c, 1) == 0) { 1897 uval.uvaltype = PRA_UINT32; 1898 uval.uint32_val = c; 1899 return (pa_print(context, &uval, flag)); 1900 } else 1901 return (-1); 1902 } else 1903 return (status); 1904 } 1905 1906 1907 1908 /* 1909 * ----------------------------------------------------------------------- 1910 * pa_adr_u_int64: Issues pr_adr_u_int64 to retrieve the next ADR item from the 1911 * input stream pointed to by audit_adr, and prints it 1912 * if status = 0 1913 * return codes : -1 - error 1914 * : 0 - successful 1915 * ----------------------------------------------------------------------- 1916 */ 1917 int 1918 pa_adr_u_int64(pr_context_t *context, int status, int flag) 1919 { 1920 uint64_t c; 1921 uval_t uval; 1922 1923 if (status >= 0) { 1924 if (pr_adr_u_int64(context, &c, 1) == 0) { 1925 uval.uvaltype = PRA_UINT64; 1926 uval.uint64_val = c; 1927 return (pa_print(context, &uval, flag)); 1928 } else 1929 return (-1); 1930 } else 1931 return (status); 1932 } 1933 1934 1935 /* 1936 * ----------------------------------------------------------------------- 1937 * pa_adr_u_short: Issues pr_adr_u_short to retrieve the next ADR item from 1938 * the input stream pointed to by audit_adr, and prints it 1939 * if status = 0 1940 * return codes : -1 - error 1941 * : 0 - successful 1942 * ----------------------------------------------------------------------- 1943 */ 1944 int 1945 pa_adr_u_short(pr_context_t *context, int status, int flag) 1946 { 1947 ushort_t c; 1948 uval_t uval; 1949 1950 if (status >= 0) { 1951 if (pr_adr_u_short(context, &c, 1) == 0) { 1952 uval.uvaltype = PRA_USHORT; 1953 uval.ushort_val = c; 1954 return (pa_print(context, &uval, flag)); 1955 } else 1956 return (-1); 1957 } else 1958 return (status); 1959 } 1960 1961 /* 1962 * ----------------------------------------------------------------------- 1963 * pa_reclen: Issues pr_adr_u_long to retrieve the length of the record 1964 * from the input stream pointed to by audit_adr, 1965 * and prints it (unless format is XML) if status = 0 1966 * return codes : -1 - error 1967 * : 0 - successful 1968 * ----------------------------------------------------------------------- 1969 */ 1970 int 1971 pa_reclen(pr_context_t *context, int status) 1972 { 1973 uint32_t c; 1974 uval_t uval; 1975 1976 if (status >= 0) { 1977 if ((int)pr_adr_u_int32(context, &c, 1) == 0) { 1978 context->audit_rec_len = c; 1979 1980 /* Don't print this for XML format */ 1981 if (context->format & PRF_XMLM) { 1982 return (0); 1983 } else { 1984 uval.uvaltype = PRA_UINT32; 1985 uval.uint32_val = c; 1986 return (pa_print(context, &uval, 0)); 1987 } 1988 } else 1989 return (-1); 1990 } else 1991 return (status); 1992 } 1993 1994 /* 1995 * ----------------------------------------------------------------------- 1996 * pa_mode : Issues pr_adr_u_short to retrieve the next ADR item from 1997 * the input stream pointed to by audit_adr, and prints it 1998 * in octal if status = 0 1999 * return codes : -1 - error 2000 * : 0 - successful 2001 * ----------------------------------------------------------------------- 2002 */ 2003 int 2004 pa_mode(pr_context_t *context, int status, int flag) 2005 { 2006 uint32_t c; 2007 uval_t uval; 2008 2009 if (status >= 0) { 2010 if (pr_adr_u_int32(context, &c, 1) == 0) { 2011 uval.uvaltype = PRA_LOCT; 2012 uval.uint32_val = c; 2013 return (pa_print(context, &uval, flag)); 2014 } else 2015 return (-1); 2016 } else 2017 return (status); 2018 } 2019 2020 2021 /* 2022 * ----------------------------------------------------------------------- 2023 * pa_pw_uid() : Issues pr_adr_u_int32 to reads uid from input stream 2024 * pointed to by audit_adr, and displays it in either 2025 * raw form or its ASCII representation, if status >= 0. 2026 * return codes : -1 - error 2027 * : 1 - warning, passwd entry not found 2028 * : 0 - successful 2029 * ----------------------------------------------------------------------- 2030 */ 2031 int 2032 pa_pw_uid(pr_context_t *context, int status, int flag) 2033 { 2034 int returnstat; 2035 struct passwd *pw; 2036 uint32_t uid; 2037 uval_t uval; 2038 2039 if (status < 0) 2040 return (status); 2041 2042 if (pr_adr_u_int32(context, &uid, 1) != 0) 2043 /* cannot retrieve uid */ 2044 return (-1); 2045 2046 if (!(context->format & PRF_RAWM)) { 2047 /* get password file entry */ 2048 if ((pw = getpwuid(uid)) == NULL) { 2049 returnstat = 1; 2050 } else { 2051 /* print in ASCII form */ 2052 uval.uvaltype = PRA_STRING; 2053 uval.string_val = pw->pw_name; 2054 returnstat = pa_print(context, &uval, flag); 2055 } 2056 } 2057 /* print in integer form */ 2058 if ((context->format & PRF_RAWM) || (returnstat == 1)) { 2059 uval.uvaltype = PRA_INT32; 2060 uval.int32_val = uid; 2061 returnstat = pa_print(context, &uval, flag); 2062 } 2063 return (returnstat); 2064 } 2065 2066 2067 /* 2068 * ----------------------------------------------------------------------- 2069 * pa_gr_uid() : Issues pr_adr_u_int32 to reads group uid from input stream 2070 * pointed to by audit_adr, and displays it in either 2071 * raw form or its ASCII representation, if status >= 0. 2072 * return codes : -1 - error 2073 * : 1 - warning, passwd entry not found 2074 * : 0 - successful 2075 * ----------------------------------------------------------------------- 2076 */ 2077 int 2078 pa_gr_uid(pr_context_t *context, int status, int flag) 2079 { 2080 int returnstat; 2081 struct group *gr; 2082 uint32_t gid; 2083 uval_t uval; 2084 2085 if (status < 0) 2086 return (status); 2087 2088 if (pr_adr_u_int32(context, &gid, 1) != 0) 2089 /* cannot retrieve gid */ 2090 return (-1); 2091 2092 if (!(context->format & PRF_RAWM)) { 2093 /* get group file entry */ 2094 if ((gr = getgrgid(gid)) == NULL) { 2095 returnstat = 1; 2096 } else { 2097 /* print in ASCII form */ 2098 uval.uvaltype = PRA_STRING; 2099 uval.string_val = gr->gr_name; 2100 returnstat = pa_print(context, &uval, flag); 2101 } 2102 } 2103 /* print in integer form */ 2104 if ((context->format & PRF_RAWM) || (returnstat == 1)) { 2105 uval.uvaltype = PRA_INT32; 2106 uval.int32_val = gid; 2107 returnstat = pa_print(context, &uval, flag); 2108 } 2109 return (returnstat); 2110 } 2111 2112 2113 /* 2114 * ----------------------------------------------------------------------- 2115 * pa_pw_uid_gr_gid() : Issues pr_adr_u_int32 to reads uid or group uid 2116 * from input stream 2117 * pointed to by audit_adr, and displays it in either 2118 * raw form or its ASCII representation, if status >= 0. 2119 * return codes : -1 - error 2120 * : 1 - warning, passwd entry not found 2121 * : 0 - successful 2122 * ----------------------------------------------------------------------- 2123 */ 2124 int 2125 pa_pw_uid_gr_gid(pr_context_t *context, int status, int flag) 2126 { 2127 int returnstat; 2128 uint32_t value; 2129 uval_t uval; 2130 2131 if (status < 0) 2132 return (status); 2133 2134 /* get value of a_type */ 2135 if ((returnstat = pr_adr_u_int32(context, &value, 1)) != 0) 2136 return (returnstat); 2137 2138 if ((returnstat = open_tag(context, TAG_ACLTYPE)) != 0) 2139 return (returnstat); 2140 2141 uval.uvaltype = PRA_UINT32; 2142 uval.uint32_val = value; 2143 if ((returnstat = pa_print(context, &uval, flag)) != 0) 2144 return (returnstat); 2145 2146 if ((returnstat = close_tag(context, TAG_ACLTYPE)) != 0) 2147 return (returnstat); 2148 2149 if ((returnstat = open_tag(context, TAG_ACLVAL)) != 0) 2150 return (returnstat); 2151 /* 2152 * TRANSLATION_NOTE 2153 * The "mask" and "other" strings refer to the class mask 2154 * and other (or world) entries in an ACL. 2155 * The "unrecognized" string refers to an unrecognized ACL 2156 * entry. 2157 */ 2158 switch (value) { 2159 case USER_OBJ: 2160 case USER: 2161 returnstat = pa_pw_uid(context, returnstat, flag); 2162 break; 2163 case GROUP_OBJ: 2164 case GROUP: 2165 returnstat = pa_gr_uid(context, returnstat, flag); 2166 break; 2167 case CLASS_OBJ: 2168 returnstat = pr_adr_u_int32(context, &value, 1); 2169 if (returnstat != 0) 2170 return (returnstat); 2171 2172 if (!(context->format & PRF_RAWM)) { 2173 uval.uvaltype = PRA_STRING; 2174 uval.string_val = gettext("mask"); 2175 returnstat = pa_print(context, &uval, flag); 2176 } else { 2177 uval.uvaltype = PRA_UINT32; 2178 uval.uint32_val = value; 2179 if ((returnstat = 2180 pa_print(context, &uval, flag)) != 0) { 2181 return (returnstat); 2182 } 2183 } 2184 break; 2185 case OTHER_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("other"); 2193 returnstat = pa_print(context, &uval, flag); 2194 } else { 2195 uval.uvaltype = PRA_UINT32; 2196 uval.uint32_val = value; 2197 if ((returnstat = 2198 pa_print(context, &uval, flag)) != 0) { 2199 return (returnstat); 2200 } 2201 } 2202 break; 2203 default: 2204 returnstat = pr_adr_u_int32(context, &value, 1); 2205 if (returnstat != 0) 2206 return (returnstat); 2207 2208 if (!(context->format & PRF_RAWM)) { 2209 uval.uvaltype = PRA_STRING; 2210 uval.string_val = gettext("unrecognized"); 2211 returnstat = pa_print(context, &uval, flag); 2212 } else { 2213 uval.uvaltype = PRA_UINT32; 2214 uval.uint32_val = value; 2215 if ((returnstat = 2216 pa_print(context, &uval, flag)) != 0) { 2217 return (returnstat); 2218 } 2219 } 2220 } 2221 2222 if ((returnstat = close_tag(context, TAG_ACLVAL)) != 0) 2223 return (returnstat); 2224 2225 return (returnstat); 2226 } 2227 2228 2229 /* 2230 * ----------------------------------------------------------------------- 2231 * pa_event_modifier(): Issues pr_adr_u_short to retrieve the next ADR item from 2232 * the input stream pointed to by audit_adr. This is the 2233 * event type, and is displayed in hex; 2234 * return codes : -1 - error 2235 * : 0 - successful 2236 * ----------------------------------------------------------------------- 2237 */ 2238 int 2239 pa_event_modifier(pr_context_t *context, int status, int flag) 2240 { 2241 int returnstat; 2242 ushort_t emodifier; 2243 uval_t uval; 2244 char modstring[64]; 2245 2246 if (status < 0) 2247 return (status); 2248 2249 if ((returnstat = pr_adr_u_short(context, &emodifier, 1)) != 0) 2250 return (returnstat); 2251 2252 /* For XML, only print when modifier is non-zero */ 2253 if (!(context->format & PRF_XMLM) || (emodifier != 0)) { 2254 uval.uvaltype = PRA_STRING; 2255 2256 returnstat = open_tag(context, TAG_EVMOD); 2257 2258 if (returnstat >= 0) { 2259 if (!(context->format & PRF_RAWM)) { 2260 eventmodifier2string(emodifier, modstring, 2261 sizeof (modstring)); 2262 uval.string_val = modstring; 2263 returnstat = pa_print(context, &uval, flag); 2264 } else { 2265 uval.string_val = hexconvert((char *)&emodifier, 2266 sizeof (emodifier), sizeof (emodifier)); 2267 if (uval.string_val) { 2268 returnstat = pa_print(context, &uval, 2269 flag); 2270 free(uval.string_val); 2271 } 2272 } 2273 } 2274 if (returnstat >= 0) 2275 returnstat = close_tag(context, TAG_EVMOD); 2276 } 2277 2278 return (returnstat); 2279 } 2280 2281 2282 /* 2283 * ----------------------------------------------------------------------- 2284 * pa_event_type(): Issues pr_adr_u_short to retrieve the next ADR item from 2285 * the input stream pointed to by audit_adr. This is the 2286 * event type, and is displayed in either raw or 2287 * ASCII form as appropriate 2288 * return codes : -1 - error 2289 * : 0 - successful 2290 * ----------------------------------------------------------------------- 2291 */ 2292 int 2293 pa_event_type(pr_context_t *context, int status, int flag) 2294 { 2295 ushort_t etype; 2296 int returnstat; 2297 au_event_ent_t *p_event = NULL; 2298 uval_t uval; 2299 2300 if (status >= 0) { 2301 if ((returnstat = pr_adr_u_short(context, &etype, 1)) == 0) { 2302 if (!(context->format & PRF_RAWM)) { 2303 uval.uvaltype = PRA_STRING; 2304 if (context->format & PRF_NOCACHE) { 2305 p_event = getauevnum(etype); 2306 } else { 2307 (void) cacheauevent(&p_event, etype); 2308 } 2309 if (p_event != NULL) { 2310 if (context->format & PRF_SHORTM) 2311 uval.string_val = 2312 p_event->ae_name; 2313 else 2314 uval.string_val = 2315 p_event->ae_desc; 2316 } else { 2317 uval.string_val = 2318 gettext("invalid event number"); 2319 } 2320 returnstat = pa_print(context, &uval, flag); 2321 } else { 2322 uval.uvaltype = PRA_USHORT; 2323 uval.ushort_val = etype; 2324 returnstat = pa_print(context, &uval, flag); 2325 } 2326 } 2327 return (returnstat); 2328 } else 2329 return (status); 2330 2331 } 2332 2333 2334 /* 2335 * Print time from struct timeval to millisecond resolution. 2336 * 2337 * typedef long time_t; time of day in seconds 2338 * typedef long useconds_t; signed # of microseconds 2339 * 2340 * struct timeval { 2341 * time_t tv_sec; seconds 2342 * suseconds_t tv_usec; and microseconds 2343 * }; 2344 */ 2345 2346 int 2347 pa_utime32(pr_context_t *context, int status, int flag) 2348 { 2349 uint32_t scale = 1000; /* usec to msec */ 2350 2351 return (do_mtime32(context, status, flag, scale)); 2352 } 2353 2354 /* 2355 * Print time from timestruc_t to millisecond resolution. 2356 * 2357 * typedef struct timespec timestruct_t; 2358 * struct timespec{ 2359 * time_t tv_sec; seconds 2360 * long tv_nsec; and nanoseconds 2361 * }; 2362 */ 2363 int 2364 pa_ntime32(pr_context_t *context, int status, int flag) 2365 { 2366 uint32_t scale = 1000000; /* nsec to msec */ 2367 2368 return (do_mtime32(context, status, flag, scale)); 2369 } 2370 2371 /* 2372 * Format the timezone +/- HH:MM and terminate the string 2373 * Note tm and tv_sec are the same time. 2374 * Too bad strftime won't produce an ISO 8601 time zone numeric 2375 */ 2376 2377 #define MINS (24L * 60) 2378 static void 2379 tzone(struct tm *tm, time_t *tv_sec, char *p) 2380 { 2381 struct tm *gmt; 2382 int min_off; 2383 2384 gmt = gmtime(tv_sec); 2385 2386 min_off = ((tm->tm_hour - gmt->tm_hour) * 60) + 2387 (tm->tm_min - gmt->tm_min); 2388 2389 if (tm->tm_year < gmt->tm_year) /* cross new year */ 2390 min_off -= MINS; 2391 else if (tm->tm_year > gmt->tm_year) 2392 min_off += MINS; 2393 else if (tm->tm_yday < gmt->tm_yday) /* cross dateline */ 2394 min_off -= MINS; 2395 else if (tm->tm_yday > gmt->tm_yday) 2396 min_off += MINS; 2397 2398 if (min_off < 0) { 2399 min_off = -min_off; 2400 *p++ = '-'; 2401 } else { 2402 *p++ = '+'; 2403 } 2404 2405 *p++ = min_off / 600 + '0'; /* 10s of hours */ 2406 min_off = min_off - min_off / 600 * 600; 2407 *p++ = min_off / 60 % 10 + '0'; /* hours */ 2408 min_off = min_off - min_off / 60 * 60; 2409 *p++ = ':'; 2410 *p++ = min_off / 10 + '0'; /* 10s of minutes */ 2411 *p++ = min_off % 10 + '0'; /* minutes */ 2412 *p = '\0'; 2413 } 2414 2415 /* 2416 * Format the milliseconds in place in the string. 2417 * Borrowed from strftime.c:itoa() 2418 */ 2419 static void 2420 msec32(uint32_t msec, char *p) 2421 { 2422 *p++ = msec / 100 + '0'; 2423 msec = msec - msec / 100 * 100; 2424 *p++ = msec / 10 + '0'; 2425 *p++ = msec % 10 +'0'; 2426 } 2427 2428 /* 2429 * Format time and print relative to scale factor from micro/nano seconds. 2430 */ 2431 static int 2432 do_mtime32(pr_context_t *context, int status, int flag, uint32_t scale) 2433 { 2434 uint32_t t32; 2435 time_t tv_sec; 2436 struct tm tm; 2437 char time_created[sizeof ("YYYY-MM-DD HH:MM:SS.sss -HH:MM")]; 2438 int returnstat; 2439 uval_t uval; 2440 2441 if (status < 0) 2442 return (status); 2443 2444 if ((returnstat = open_tag(context, TAG_ISO)) != 0) 2445 return (returnstat); 2446 2447 if ((returnstat = pr_adr_u_int32(context, 2448 (uint32_t *)&tv_sec, 1)) != 0) 2449 return (returnstat); 2450 if ((returnstat = pr_adr_u_int32(context, &t32, 1)) == 0) { 2451 if (!(context->format & PRF_RAWM)) { 2452 (void) localtime_r(&tv_sec, &tm); 2453 (void) strftime(time_created, 2454 sizeof ("YYYY-MM-DD HH:MM:SS.xxx "), 2455 "%Y-%m-%d %H:%M:%S.xxx ", &tm); 2456 msec32(t32/scale, 2457 &time_created[sizeof ("YYYY-MM-DD HH:MM:SS.")-1]); 2458 tzone(&tm, &tv_sec, 2459 &time_created[ 2460 sizeof ("YYYY-MM-DD HH:MM:SS.xxx ")-1]); 2461 uval.uvaltype = PRA_STRING; 2462 uval.string_val = time_created; 2463 } else { 2464 uval.uvaltype = PRA_UINT32; 2465 uval.uint32_val = (uint32_t)tv_sec; 2466 (void) pa_print(context, &uval, 0); 2467 uval.uvaltype = PRA_UINT32; 2468 uval.uint32_val = t32; 2469 } 2470 returnstat = pa_print(context, &uval, flag); 2471 } 2472 2473 if (returnstat == 0) 2474 return (close_tag(context, TAG_ISO)); 2475 else 2476 return (returnstat); 2477 } 2478 2479 /* 2480 * Print time from struct timeval to millisecond resolution. 2481 * 2482 * typedef long time_t; time of day in seconds 2483 * typedef long useconds_t; signed # of microseconds 2484 * 2485 * struct timeval { 2486 * time_t tv_sec; seconds 2487 * suseconds_t tv_usec; and microseconds 2488 * }; 2489 */ 2490 2491 int 2492 pa_utime64(pr_context_t *context, int status, int flag) 2493 { 2494 uint64_t scale = 1000; /* usec to msec */ 2495 2496 return (do_mtime64(context, status, flag, scale)); 2497 } 2498 2499 /* 2500 * Print time from timestruc_t to millisecond resolution. 2501 * 2502 * typedef struct timespec timestruct_t; 2503 * struct timespec{ 2504 * time_t tv_sec; seconds 2505 * long tv_nsec; and nanoseconds 2506 * }; 2507 */ 2508 int 2509 pa_ntime64(pr_context_t *context, int status, int flag) 2510 { 2511 uint64_t scale = 1000000; /* nsec to msec */ 2512 2513 return (do_mtime64(context, status, flag, scale)); 2514 } 2515 2516 /* 2517 * Format the milliseconds in place in the string. 2518 * Borrowed from strftime.c:itoa() 2519 */ 2520 static void 2521 msec64(uint64_t msec, char *p) 2522 { 2523 *p++ = msec / 100 + '0'; 2524 msec = msec - msec / 100 * 100; 2525 *p++ = msec / 10 + '0'; 2526 *p++ = msec % 10 +'0'; 2527 } 2528 2529 /* 2530 * Format time and print relative to scale factor from micro/nano seconds. 2531 */ 2532 static int 2533 do_mtime64(pr_context_t *context, int status, int flag, uint64_t scale) 2534 { 2535 uint64_t t64_sec; 2536 uint64_t t64_msec; 2537 time_t tv_sec; 2538 struct tm tm; 2539 char time_created[sizeof ("YYYY-MM-DD HH:MM:SS.sss -HH:MM")]; 2540 int returnstat; 2541 uval_t uval; 2542 2543 if (status < 0) 2544 return (status); 2545 2546 if ((returnstat = open_tag(context, TAG_ISO)) != 0) 2547 return (returnstat); 2548 2549 if ((returnstat = pr_adr_u_int64(context, &t64_sec, 1)) != 0) 2550 return (returnstat); 2551 if ((returnstat = pr_adr_u_int64(context, &t64_msec, 1)) == 0) { 2552 if (!(context->format & PRF_RAWM)) { 2553 #ifndef _LP64 2554 /* 2555 * N.B. 2556 * This fails for years from 2038 2557 * The Y2K+38 problem 2558 */ 2559 #endif /* !_LP64 */ 2560 tv_sec = (time_t)t64_sec; 2561 (void) localtime_r(&tv_sec, &tm); 2562 (void) strftime(time_created, 2563 sizeof ("YYYY-MM-DD HH:MM:SS.xxx "), 2564 "%Y-%m-%d %H:%M:%S.xxx ", &tm); 2565 msec64(t64_msec/scale, 2566 &time_created[sizeof ("YYYY-MM-DD HH:MM:SS.")-1]); 2567 tzone(&tm, &tv_sec, 2568 &time_created[ 2569 sizeof ("YYYY-MM-DD HH:MM:SS.xxx ")-1]); 2570 uval.uvaltype = PRA_STRING; 2571 uval.string_val = time_created; 2572 } else { 2573 uval.uvaltype = PRA_UINT64; 2574 uval.uint64_val = t64_sec; 2575 (void) pa_print(context, &uval, 0); 2576 uval.uvaltype = PRA_UINT64; 2577 uval.uint64_val = t64_msec; 2578 } 2579 returnstat = pa_print(context, &uval, flag); 2580 } 2581 2582 if (returnstat < 0) 2583 return (returnstat); 2584 2585 return (close_tag(context, TAG_ISO)); 2586 } 2587 2588 /* 2589 * ----------------------------------------------------------------------- 2590 * pa_error() : convert the return token error code. 2591 * 2592 * output : buf string representing return token error code. 2593 * 2594 * ----------------------------------------------------------------------- 2595 */ 2596 void 2597 pa_error(const uchar_t err, char *buf, size_t buflen) 2598 { 2599 if (err == 0) { 2600 (void) strlcpy(buf, gettext("success"), buflen); 2601 } else if ((char)err == -1) { 2602 (void) strlcpy(buf, gettext("failure"), buflen); 2603 } else { 2604 char *emsg = strerror(err); 2605 2606 if (emsg != NULL) { 2607 (void) strlcpy(buf, gettext("failure: "), buflen); 2608 (void) strlcat(buf, emsg, buflen); 2609 } else { 2610 (void) snprintf(buf, buflen, "%s%d", 2611 gettext("failure: "), err); 2612 } 2613 } 2614 } 2615 2616 /* 2617 * ----------------------------------------------------------------------- 2618 * pa_retval() : convert the return token return value code. 2619 * 2620 * output : buf string representing return token error code. 2621 * 2622 * ----------------------------------------------------------------------- 2623 */ 2624 void 2625 pa_retval(const int32_t retval, char *buf, size_t buflen) 2626 { 2627 struct msg_text *msglist = &adt_msg_text[ADT_LIST_FAIL_VALUE]; 2628 2629 if ((retval + msglist->ml_offset >= msglist->ml_min_index) && 2630 (retval + msglist->ml_offset <= msglist->ml_max_index)) { 2631 2632 (void) strlcpy(buf, 2633 gettext(msglist->ml_msg_list[retval + msglist->ml_offset]), 2634 buflen); 2635 } else if ((retval >= ADT_FAIL_PAM) && 2636 (retval < ADT_FAIL_PAM + PAM_TOTAL_ERRNUM)) 2637 (void) strlcpy(buf, pam_strerror(NULL, retval - ADT_FAIL_PAM), 2638 buflen); 2639 else 2640 (void) snprintf(buf, buflen, "%d", retval); 2641 } 2642 2643 2644 /* 2645 * ----------------------------------------------------------------------- 2646 * pa_printstr() : print a given string, translating unprintables 2647 * : as needed. 2648 */ 2649 static int 2650 pa_printstr(pr_context_t *context, char *str) 2651 { 2652 int err = 0; 2653 int len, printable; 2654 int mbmax = MB_CUR_MAX; 2655 wchar_t wc; 2656 char c; 2657 2658 if (mbmax == 1) { 2659 /* fast path */ 2660 while (err == 0 && *str != '\0') { 2661 c = *str++; 2662 printable = isprint((unsigned char)c); 2663 err = pa_putstr(context, printable, &c, 1); 2664 } 2665 return (err); 2666 } 2667 while (err == 0 && *str != '\0') { 2668 len = mbtowc(&wc, str, mbmax); 2669 if (len <= 0) { 2670 len = 1; 2671 printable = 0; 2672 } else { 2673 printable = iswprint(wc); 2674 } 2675 err = pa_putstr(context, printable, str, len); 2676 str += len; 2677 } 2678 return (err); 2679 } 2680 2681 /* 2682 * ----------------------------------------------------------------------- 2683 * pa_print() : print as one str or formatted for easy reading. 2684 * : flag - indicates whether to output a new line for 2685 * : multi-line output. 2686 * : = 0; no new line 2687 * : = 1; new line if regular output 2688 * output : The audit record information is displayed in the 2689 * type specified by uvaltype and value specified in 2690 * uval. The printing of the delimiter or newline is 2691 * determined by PRF_ONELINE, and the flag value, 2692 * as follows: 2693 * +--------+------+------+-----------------+ 2694 * |ONELINE | flag | last | Action | 2695 * +--------+------+------+-----------------+ 2696 * | Y | Y | T | print new line | 2697 * | Y | Y | F | print delimiter | 2698 * | Y | N | T | print new line | 2699 * | Y | N | F | print delimiter | 2700 * | N | Y | T | print new line | 2701 * | N | Y | F | print new line | 2702 * | N | N | T | print new line | 2703 * | N | N | F | print delimiter | 2704 * +--------+------+------+-----------------+ 2705 * 2706 * return codes : -1 - error 2707 * 0 - successful 2708 * ----------------------------------------------------------------------- 2709 */ 2710 int 2711 pa_print(pr_context_t *context, uval_t *uval, int flag) 2712 { 2713 int returnstat = 0; 2714 int last; 2715 2716 switch (uval->uvaltype) { 2717 case PRA_INT32: 2718 returnstat = pr_printf(context, "%d", uval->int32_val); 2719 break; 2720 case PRA_UINT32: 2721 returnstat = pr_printf(context, "%u", uval->uint32_val); 2722 break; 2723 case PRA_INT64: 2724 returnstat = pr_printf(context, "%"PRId64, uval->int64_val); 2725 break; 2726 case PRA_UINT64: 2727 returnstat = pr_printf(context, "%"PRIu64, uval->uint64_val); 2728 break; 2729 case PRA_SHORT: 2730 returnstat = pr_printf(context, "%hd", uval->short_val); 2731 break; 2732 case PRA_USHORT: 2733 returnstat = pr_printf(context, "%hu", uval->ushort_val); 2734 break; 2735 case PRA_CHAR: 2736 returnstat = pr_printf(context, "%c", uval->char_val); 2737 break; 2738 case PRA_BYTE: 2739 returnstat = pr_printf(context, "%d", uval->char_val); 2740 break; 2741 case PRA_STRING: 2742 returnstat = pa_printstr(context, uval->string_val); 2743 break; 2744 case PRA_HEX32: 2745 returnstat = pr_printf(context, "0x%x", uval->int32_val); 2746 break; 2747 case PRA_HEX64: 2748 returnstat = pr_printf(context, "0x%"PRIx64, uval->int64_val); 2749 break; 2750 case PRA_SHEX: 2751 returnstat = pr_printf(context, "0x%hx", uval->short_val); 2752 break; 2753 case PRA_OCT: 2754 returnstat = pr_printf(context, "%ho", uval->ushort_val); 2755 break; 2756 case PRA_LOCT: 2757 returnstat = pr_printf(context, "%o", (int)uval->uint32_val); 2758 break; 2759 default: 2760 (void) fprintf(stderr, gettext("praudit: Unknown type.\n")); 2761 returnstat = -1; 2762 break; 2763 } 2764 if (returnstat < 0) 2765 return (returnstat); 2766 2767 last = (context->audit_adr->adr_now == 2768 (context->audit_rec_start + context->audit_rec_len)); 2769 2770 if (!(context->format & PRF_XMLM)) { 2771 if (!(context->format & PRF_ONELINE)) { 2772 if ((flag == 1) || last) 2773 returnstat = pr_putchar(context, '\n'); 2774 else 2775 returnstat = pr_printf(context, "%s", 2776 context->SEPARATOR); 2777 } else { 2778 if (!last) 2779 returnstat = pr_printf(context, "%s", 2780 context->SEPARATOR); 2781 else 2782 returnstat = pr_putchar(context, '\n'); 2783 } 2784 } 2785 if ((returnstat == 0) && (context->data_mode == FILEMODE)) 2786 (void) fflush(stdout); 2787 2788 return (returnstat); 2789 } 2790 2791 static struct cntrl_mapping { 2792 char from; 2793 char to; 2794 } cntrl_map[] = { 2795 '\0', '0', 2796 '\a', 'a', 2797 '\b', 'b', 2798 '\t', 't', 2799 '\f', 'f', 2800 '\n', 'n', 2801 '\r', 'r', 2802 '\v', 'v' 2803 }; 2804 2805 static int cntrl_map_entries = sizeof (cntrl_map) 2806 / sizeof (struct cntrl_mapping); 2807 2808 /* 2809 * Convert binary data to ASCII for printing. 2810 */ 2811 void 2812 convertascii(char *p, char *c, int size) 2813 { 2814 register int i; 2815 register int j, match; 2816 2817 for (i = 0; i < size; i++) { 2818 *(c + i) = (char)toascii(*(c + i)); 2819 if ((int)iscntrl(*(c + i))) { 2820 for (j = match = 0; j < cntrl_map_entries; j++) 2821 if (cntrl_map[j].from == *(c + i)) { 2822 *p++ = '\\'; 2823 *p++ = cntrl_map[j].to; 2824 match = 1; 2825 } 2826 if (!match) { 2827 *p++ = '^'; 2828 *p++ = (char)(*(c + i) + 0x40); 2829 } 2830 } else 2831 *p++ = *(c + i); 2832 } 2833 2834 *p = '\0'; 2835 2836 } 2837 2838 2839 /* 2840 * ----------------------------------------------------------------------- 2841 * pa_xgeneric: Process Xobject token and display contents 2842 * This routine will handle many of the attribute 2843 * types introduced in TS 2.x, such as: 2844 * 2845 * AUT_XCOLORMAP, AUT_XCURSOR, AUT_XFONT, 2846 * AUT_XGC, AUT_XPIXMAP, AUT_XWINDOW 2847 * 2848 * NOTE: At the time of call, the token id has been retrieved 2849 * 2850 * return codes : -1 - error 2851 * : 0 - successful 2852 * NOTE: At the time of call, the xatom token id has been retrieved 2853 * 2854 * Format of xobj 2855 * text token id adr_char 2856 * XID adr_u_int32 2857 * creator uid adr_pw_uid 2858 * ----------------------------------------------------------------------- 2859 */ 2860 int 2861 pa_xgeneric(pr_context_t *context) 2862 { 2863 int returnstat; 2864 2865 returnstat = process_tag(context, TAG_XID, 0, 0); 2866 return (process_tag(context, TAG_XCUID, returnstat, 1)); 2867 } 2868 2869 2870 /* 2871 * ------------------------------------------------------------------------ 2872 * pa_liaison : Issues pr_adr_char to retrieve the next ADR item from the 2873 * input stream pointed to by audit_adr, and prints it 2874 * if status >= 0 either in ASCII or raw form 2875 * return codes : -1 - error 2876 * : 0 - successful 2877 * : 1 - warning, unknown label type 2878 * ----------------------------------------------------------------------- 2879 */ 2880 int 2881 pa_liaison(pr_context_t *context, int status, int flag) 2882 { 2883 int returnstat; 2884 int32_t li; 2885 uval_t uval; 2886 2887 if (status >= 0) { 2888 if ((returnstat = pr_adr_int32(context, &li, 1)) != 0) { 2889 return (returnstat); 2890 } 2891 if (!(context->format & PRF_RAWM)) { 2892 uval.uvaltype = PRA_UINT32; 2893 uval.uint32_val = li; 2894 returnstat = pa_print(context, &uval, flag); 2895 } 2896 /* print in hexadecimal form */ 2897 if ((context->format & PRF_RAWM) || (returnstat == 1)) { 2898 uval.uvaltype = PRA_HEX32; 2899 uval.uint32_val = li; 2900 returnstat = pa_print(context, &uval, flag); 2901 } 2902 return (returnstat); 2903 } else 2904 return (status); 2905 } 2906 2907 /* 2908 * ------------------------------------------------------------------------ 2909 * pa_xid : Issues pr_adr_int32 to retrieve the XID from the input 2910 * stream pointed to by audit_adr, and prints it if 2911 * status >= 0 either in ASCII or raw form 2912 * return codes : -1 - error 2913 * : 0 - successful 2914 * : 1 - warning, unknown label type 2915 * ------------------------------------------------------------------------ 2916 */ 2917 2918 int 2919 pa_xid(pr_context_t *context, int status, int flag) 2920 { 2921 int returnstat; 2922 int32_t xid; 2923 uval_t uval; 2924 2925 if (status < 0) 2926 return (status); 2927 2928 /* get XID from stream */ 2929 if ((returnstat = pr_adr_int32(context, (int32_t *)&xid, 1)) != 0) 2930 return (returnstat); 2931 2932 if (!(context->format & PRF_RAWM)) { 2933 uval.uvaltype = PRA_STRING; 2934 uval.string_val = hexconvert((char *)&xid, sizeof (xid), 2935 sizeof (xid)); 2936 if (uval.string_val) { 2937 returnstat = pa_print(context, &uval, flag); 2938 free(uval.string_val); 2939 } 2940 } else { 2941 uval.uvaltype = PRA_INT32; 2942 uval.int32_val = xid; 2943 returnstat = pa_print(context, &uval, flag); 2944 } 2945 2946 return (returnstat); 2947 } 2948