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 2008 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 27 #define _REENTRANT 28 29 #include <ctype.h> 30 #include <errno.h> 31 #include <grp.h> 32 #include <libintl.h> 33 #include <netdb.h> 34 #include <time.h> 35 #include <pwd.h> 36 #include <stdio.h> 37 #include <stdlib.h> 38 #include <string.h> 39 #include <wchar.h> 40 41 #include <arpa/inet.h> 42 43 #include <bsm/audit.h> 44 #include <bsm/audit_record.h> 45 #include <bsm/libbsm.h> 46 #include <security/pam_appl.h> 47 48 #include <sys/inttypes.h> 49 #include <sys/mkdev.h> 50 #include <sys/types.h> 51 #include <aclutils.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(au_emod_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(au_emod_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 short length; 1639 int returnstat; 1640 uval_t uval; 1641 1642 /* 1643 * We need to know how much space to allocate for our string, so 1644 * read the length first, then call pr_adr_char to read those bytes. 1645 */ 1646 if (status < 0) 1647 return (status); 1648 1649 if ((returnstat = pr_adr_short(context, &length, 1)) != 0) 1650 return (returnstat); 1651 if ((c = (char *)malloc(length + 1)) == NULL) 1652 return (-1); 1653 if ((returnstat = pr_adr_char(context, c, length)) != 0) { 1654 free(c); 1655 return (returnstat); 1656 } 1657 1658 uval.uvaltype = PRA_STRING; 1659 uval.string_val = c; 1660 returnstat = pa_print(context, &uval, flag); 1661 free(c); 1662 return (returnstat); 1663 } 1664 1665 /* 1666 * ----------------------------------------------------------------------- 1667 * pa_file_string: Retrieves a file string from the input stream and prints it 1668 * if status >= 0 1669 * return codes : -1 - error 1670 * : 0 - successful 1671 * ----------------------------------------------------------------------- 1672 */ 1673 int 1674 pa_file_string(pr_context_t *context, int status, int flag) 1675 { 1676 char *c; 1677 char *p; 1678 short length; 1679 int returnstat; 1680 uval_t uval; 1681 1682 /* 1683 * We need to know how much space to allocate for our string, so 1684 * read the length first, then call pr_adr_char to read those bytes. 1685 */ 1686 if (status < 0) 1687 return (status); 1688 1689 if ((returnstat = pr_adr_short(context, &length, 1)) != 0) 1690 return (returnstat); 1691 if ((c = (char *)malloc(length + 1)) == NULL) 1692 return (-1); 1693 if ((p = (char *)malloc((length * 4) + 1)) == NULL) { 1694 free(c); 1695 return (-1); 1696 } 1697 if ((returnstat = pr_adr_char(context, c, length)) != 0) { 1698 free(c); 1699 free(p); 1700 return (returnstat); 1701 } 1702 1703 if (is_file_token(context->tokenid)) 1704 context->audit_rec_len += length; 1705 1706 convertascii(p, c, length - 1); 1707 uval.uvaltype = PRA_STRING; 1708 uval.string_val = p; 1709 1710 if (returnstat == 0) 1711 returnstat = finish_open_tag(context); 1712 1713 if (returnstat == 0) 1714 returnstat = pa_print(context, &uval, flag); 1715 1716 free(c); 1717 free(p); 1718 return (returnstat); 1719 } 1720 1721 static int 1722 pa_putstr_xml(pr_context_t *context, int printable, char *str, size_t len) 1723 { 1724 int err; 1725 1726 if (!printable) { 1727 /* 1728 * Unprintable chars should always be converted to the 1729 * visible form. If there are unprintable characters which 1730 * require special treatment in xml, those should be 1731 * handled here. 1732 */ 1733 do { 1734 err = pr_printf(context, "\\%03o", 1735 (unsigned char)*str++); 1736 } while (err == 0 && --len != 0); 1737 return (err); 1738 } 1739 /* printable characters */ 1740 if (len == 1) { 1741 /* 1742 * check for the special chars only when char size was 1 1743 * ie, ignore special chars appear in the middle of multibyte 1744 * sequence. 1745 */ 1746 1747 /* Escape for XML */ 1748 switch (*str) { 1749 case '&': 1750 err = pr_printf(context, "%s", "&"); 1751 break; 1752 1753 case '<': 1754 err = pr_printf(context, "%s", "<"); 1755 break; 1756 1757 case '>': 1758 err = pr_printf(context, "%s", ">"); 1759 break; 1760 1761 case '\"': 1762 err = pr_printf(context, "%s", """); 1763 break; 1764 1765 case '\'': 1766 err = pr_printf(context, "%s", "'"); 1767 break; 1768 1769 default: 1770 err = pr_putchar(context, *str); 1771 break; 1772 } 1773 return (err); 1774 } 1775 do { 1776 err = pr_putchar(context, *str++); 1777 } while (err == 0 && --len != 0); 1778 return (err); 1779 } 1780 1781 static int 1782 pa_putstr(pr_context_t *context, int printable, char *str, size_t len) 1783 { 1784 int err; 1785 1786 if (context->format & PRF_XMLM) 1787 return (pa_putstr_xml(context, printable, str, len)); 1788 1789 if (!printable) { 1790 do { 1791 err = pr_printf(context, "\\%03o", 1792 (unsigned char)*str++); 1793 } while (err == 0 && --len != 0); 1794 return (err); 1795 } 1796 do { 1797 err = pr_putchar(context, *str++); 1798 } while (err == 0 && --len != 0); 1799 return (err); 1800 } 1801 1802 int 1803 pa_string(pr_context_t *context, int status, int flag) 1804 { 1805 int rstat, wstat; 1806 int i, printable, eos; 1807 int mlen, rlen; 1808 int mbmax = MB_CUR_MAX; 1809 wchar_t wc; 1810 char mbuf[MB_LEN_MAX + 1]; 1811 char c; 1812 1813 if (status < 0) 1814 return (status); 1815 1816 rstat = wstat = 0; 1817 1818 if (mbmax == 1) { 1819 while (wstat == 0) { 1820 if ((rstat = pr_adr_char(context, &c, 1)) < 0) 1821 break; 1822 if (c == '\0') 1823 break; 1824 printable = isprint((unsigned char)c); 1825 wstat = pa_putstr(context, printable, &c, 1); 1826 } 1827 goto done; 1828 } 1829 1830 mlen = eos = 0; 1831 while (wstat == 0) { 1832 rlen = 0; 1833 do { 1834 if (!eos) { 1835 rstat = pr_adr_char(context, &c, 1); 1836 if (rstat != 0 || c == '\0') 1837 eos = 1; 1838 else 1839 mbuf[mlen++] = c; 1840 } 1841 rlen = mbtowc(&wc, mbuf, mlen); 1842 } while (!eos && mlen < mbmax && rlen <= 0); 1843 1844 if (mlen == 0) 1845 break; /* end of string */ 1846 1847 if (rlen <= 0) { /* no good sequence */ 1848 rlen = 1; 1849 printable = 0; 1850 } else { 1851 printable = iswprint(wc); 1852 } 1853 wstat = pa_putstr(context, printable, mbuf, rlen); 1854 mlen -= rlen; 1855 if (mlen > 0) { 1856 for (i = 0; i < mlen; i++) 1857 mbuf[i] = mbuf[rlen + i]; 1858 } 1859 } 1860 1861 done: 1862 if (wstat == 0) 1863 wstat = do_newline(context, flag); 1864 1865 if (wstat == 0 && context->data_mode == FILEMODE) 1866 (void) fflush(stdout); 1867 1868 return ((rstat != 0 || wstat != 0) ? -1 : 0); 1869 } 1870 1871 /* 1872 * ----------------------------------------------------------------------- 1873 * pa_adr_u_int32: Issues pr_adr_u_int32 to retrieve the next ADR item from 1874 * the input stream pointed to by audit_adr, and prints it 1875 * if status = 0 1876 * return codes : -1 - error 1877 * : 0 - successful 1878 * ----------------------------------------------------------------------- 1879 */ 1880 1881 1882 int 1883 pa_adr_u_int32(pr_context_t *context, int status, int flag) 1884 { 1885 uint32_t c; 1886 uval_t uval; 1887 1888 if (status >= 0) { 1889 if (pr_adr_u_int32(context, &c, 1) == 0) { 1890 uval.uvaltype = PRA_UINT32; 1891 uval.uint32_val = c; 1892 return (pa_print(context, &uval, flag)); 1893 } else 1894 return (-1); 1895 } else 1896 return (status); 1897 } 1898 1899 1900 1901 /* 1902 * ----------------------------------------------------------------------- 1903 * pa_adr_u_int64: Issues pr_adr_u_int64 to retrieve the next ADR item from the 1904 * input stream pointed to by audit_adr, and prints it 1905 * if status = 0 1906 * return codes : -1 - error 1907 * : 0 - successful 1908 * ----------------------------------------------------------------------- 1909 */ 1910 int 1911 pa_adr_u_int64(pr_context_t *context, int status, int flag) 1912 { 1913 uint64_t c; 1914 uval_t uval; 1915 1916 if (status >= 0) { 1917 if (pr_adr_u_int64(context, &c, 1) == 0) { 1918 uval.uvaltype = PRA_UINT64; 1919 uval.uint64_val = c; 1920 return (pa_print(context, &uval, flag)); 1921 } else 1922 return (-1); 1923 } else 1924 return (status); 1925 } 1926 1927 1928 /* 1929 * ----------------------------------------------------------------------- 1930 * pa_adr_u_short: Issues pr_adr_u_short to retrieve the next ADR item from 1931 * the input stream pointed to by audit_adr, and prints it 1932 * if status = 0 1933 * return codes : -1 - error 1934 * : 0 - successful 1935 * ----------------------------------------------------------------------- 1936 */ 1937 int 1938 pa_adr_u_short(pr_context_t *context, int status, int flag) 1939 { 1940 ushort_t c; 1941 uval_t uval; 1942 1943 if (status >= 0) { 1944 if (pr_adr_u_short(context, &c, 1) == 0) { 1945 uval.uvaltype = PRA_USHORT; 1946 uval.ushort_val = c; 1947 return (pa_print(context, &uval, flag)); 1948 } else 1949 return (-1); 1950 } else 1951 return (status); 1952 } 1953 1954 /* 1955 * ----------------------------------------------------------------------- 1956 * pa_reclen: Issues pr_adr_u_long to retrieve the length of the record 1957 * from the input stream pointed to by audit_adr, 1958 * and prints it (unless format is XML) if status = 0 1959 * return codes : -1 - error 1960 * : 0 - successful 1961 * ----------------------------------------------------------------------- 1962 */ 1963 int 1964 pa_reclen(pr_context_t *context, int status) 1965 { 1966 uint32_t c; 1967 uval_t uval; 1968 1969 if (status >= 0) { 1970 if ((int)pr_adr_u_int32(context, &c, 1) == 0) { 1971 context->audit_rec_len = c; 1972 1973 /* Don't print this for XML format */ 1974 if (context->format & PRF_XMLM) { 1975 return (0); 1976 } else { 1977 uval.uvaltype = PRA_UINT32; 1978 uval.uint32_val = c; 1979 return (pa_print(context, &uval, 0)); 1980 } 1981 } else 1982 return (-1); 1983 } else 1984 return (status); 1985 } 1986 1987 /* 1988 * ----------------------------------------------------------------------- 1989 * pa_mode : Issues pr_adr_u_short to retrieve the next ADR item from 1990 * the input stream pointed to by audit_adr, and prints it 1991 * in octal if status = 0 1992 * return codes : -1 - error 1993 * : 0 - successful 1994 * ----------------------------------------------------------------------- 1995 */ 1996 int 1997 pa_mode(pr_context_t *context, int status, int flag) 1998 { 1999 uint32_t c; 2000 uval_t uval; 2001 2002 if (status >= 0) { 2003 if (pr_adr_u_int32(context, &c, 1) == 0) { 2004 uval.uvaltype = PRA_LOCT; 2005 uval.uint32_val = c; 2006 return (pa_print(context, &uval, flag)); 2007 } else 2008 return (-1); 2009 } else 2010 return (status); 2011 } 2012 2013 static int 2014 pa_print_uid(pr_context_t *context, uid_t uid, int status, int flag) 2015 { 2016 int returnstat; 2017 struct passwd *pw; 2018 uval_t uval; 2019 2020 if (status < 0) 2021 return (status); 2022 2023 if (!(context->format & PRF_RAWM)) { 2024 /* get password file entry */ 2025 if ((pw = getpwuid(uid)) == NULL) { 2026 returnstat = 1; 2027 } else { 2028 /* print in ASCII form */ 2029 uval.uvaltype = PRA_STRING; 2030 uval.string_val = pw->pw_name; 2031 returnstat = pa_print(context, &uval, flag); 2032 } 2033 } 2034 /* print in integer form */ 2035 if ((context->format & PRF_RAWM) || (returnstat == 1)) { 2036 uval.uvaltype = PRA_INT32; 2037 uval.int32_val = uid; 2038 returnstat = pa_print(context, &uval, flag); 2039 } 2040 return (returnstat); 2041 } 2042 2043 2044 /* 2045 * ----------------------------------------------------------------------- 2046 * pa_pw_uid() : Issues pr_adr_u_int32 to reads uid from input stream 2047 * pointed to by audit_adr, and displays it in either 2048 * raw form or its ASCII representation, if status >= 0. 2049 * return codes : -1 - error 2050 * : 1 - warning, passwd entry not found 2051 * : 0 - successful 2052 * ----------------------------------------------------------------------- 2053 */ 2054 int 2055 pa_pw_uid(pr_context_t *context, int status, int flag) 2056 { 2057 uint32_t uid; 2058 2059 if (status < 0) 2060 return (status); 2061 2062 if (pr_adr_u_int32(context, &uid, 1) != 0) 2063 /* cannot retrieve uid */ 2064 return (-1); 2065 2066 return (pa_print_uid(context, uid, status, flag)); 2067 } 2068 2069 static int 2070 pa_print_gid(pr_context_t *context, gid_t gid, int status, int flag) 2071 { 2072 int returnstat; 2073 struct group *gr; 2074 uval_t uval; 2075 2076 if (status < 0) 2077 return (status); 2078 2079 if (!(context->format & PRF_RAWM)) { 2080 /* get group file entry */ 2081 if ((gr = getgrgid(gid)) == NULL) { 2082 returnstat = 1; 2083 } else { 2084 /* print in ASCII form */ 2085 uval.uvaltype = PRA_STRING; 2086 uval.string_val = gr->gr_name; 2087 returnstat = pa_print(context, &uval, flag); 2088 } 2089 } 2090 /* print in integer form */ 2091 if ((context->format & PRF_RAWM) || (returnstat == 1)) { 2092 uval.uvaltype = PRA_INT32; 2093 uval.int32_val = gid; 2094 returnstat = pa_print(context, &uval, flag); 2095 } 2096 return (returnstat); 2097 } 2098 2099 2100 /* 2101 * ----------------------------------------------------------------------- 2102 * pa_gr_uid() : Issues pr_adr_u_int32 to reads group uid from input stream 2103 * pointed to by audit_adr, and displays it in either 2104 * raw form or its ASCII representation, if status >= 0. 2105 * return codes : -1 - error 2106 * : 1 - warning, passwd entry not found 2107 * : 0 - successful 2108 * ----------------------------------------------------------------------- 2109 */ 2110 int 2111 pa_gr_uid(pr_context_t *context, int status, int flag) 2112 { 2113 uint32_t gid; 2114 2115 if (status < 0) 2116 return (status); 2117 2118 if (pr_adr_u_int32(context, &gid, 1) != 0) 2119 /* cannot retrieve gid */ 2120 return (-1); 2121 2122 return (pa_print_gid(context, gid, status, flag)); 2123 } 2124 2125 2126 /* 2127 * ----------------------------------------------------------------------- 2128 * pa_pw_uid_gr_gid() : Issues pr_adr_u_int32 to reads uid or group uid 2129 * from input stream 2130 * pointed to by audit_adr, and displays it in either 2131 * raw form or its ASCII representation, if status >= 0. 2132 * return codes : -1 - error 2133 * : 1 - warning, passwd entry not found 2134 * : 0 - successful 2135 * ----------------------------------------------------------------------- 2136 */ 2137 int 2138 pa_pw_uid_gr_gid(pr_context_t *context, int status, int flag) 2139 { 2140 int returnstat; 2141 uint32_t value; 2142 uval_t uval; 2143 2144 if (status < 0) 2145 return (status); 2146 2147 /* get value of a_type */ 2148 if ((returnstat = pr_adr_u_int32(context, &value, 1)) != 0) 2149 return (returnstat); 2150 2151 if ((returnstat = open_tag(context, TAG_ACLTYPE)) != 0) 2152 return (returnstat); 2153 2154 uval.uvaltype = PRA_UINT32; 2155 uval.uint32_val = value; 2156 if ((returnstat = pa_print(context, &uval, flag)) != 0) 2157 return (returnstat); 2158 2159 if ((returnstat = close_tag(context, TAG_ACLTYPE)) != 0) 2160 return (returnstat); 2161 2162 if ((returnstat = open_tag(context, TAG_ACLVAL)) != 0) 2163 return (returnstat); 2164 /* 2165 * TRANSLATION_NOTE 2166 * The "mask" and "other" strings refer to the class mask 2167 * and other (or world) entries in an ACL. 2168 * The "unrecognized" string refers to an unrecognized ACL 2169 * entry. 2170 */ 2171 switch (value) { 2172 case USER_OBJ: 2173 case USER: 2174 returnstat = pa_pw_uid(context, returnstat, flag); 2175 break; 2176 case GROUP_OBJ: 2177 case GROUP: 2178 returnstat = pa_gr_uid(context, returnstat, flag); 2179 break; 2180 case CLASS_OBJ: 2181 returnstat = pr_adr_u_int32(context, &value, 1); 2182 if (returnstat != 0) 2183 return (returnstat); 2184 2185 if (!(context->format & PRF_RAWM)) { 2186 uval.uvaltype = PRA_STRING; 2187 uval.string_val = gettext("mask"); 2188 returnstat = pa_print(context, &uval, flag); 2189 } else { 2190 uval.uvaltype = PRA_UINT32; 2191 uval.uint32_val = value; 2192 if ((returnstat = 2193 pa_print(context, &uval, flag)) != 0) { 2194 return (returnstat); 2195 } 2196 } 2197 break; 2198 case OTHER_OBJ: 2199 returnstat = pr_adr_u_int32(context, &value, 1); 2200 if (returnstat != 0) 2201 return (returnstat); 2202 2203 if (!(context->format & PRF_RAWM)) { 2204 uval.uvaltype = PRA_STRING; 2205 uval.string_val = gettext("other"); 2206 returnstat = pa_print(context, &uval, flag); 2207 } else { 2208 uval.uvaltype = PRA_UINT32; 2209 uval.uint32_val = value; 2210 if ((returnstat = 2211 pa_print(context, &uval, flag)) != 0) { 2212 return (returnstat); 2213 } 2214 } 2215 break; 2216 default: 2217 returnstat = pr_adr_u_int32(context, &value, 1); 2218 if (returnstat != 0) 2219 return (returnstat); 2220 2221 if (!(context->format & PRF_RAWM)) { 2222 uval.uvaltype = PRA_STRING; 2223 uval.string_val = gettext("unrecognized"); 2224 returnstat = pa_print(context, &uval, flag); 2225 } else { 2226 uval.uvaltype = PRA_UINT32; 2227 uval.uint32_val = value; 2228 if ((returnstat = 2229 pa_print(context, &uval, flag)) != 0) { 2230 return (returnstat); 2231 } 2232 } 2233 } 2234 2235 if ((returnstat = close_tag(context, TAG_ACLVAL)) != 0) 2236 return (returnstat); 2237 2238 return (returnstat); 2239 } 2240 2241 2242 /* 2243 * ----------------------------------------------------------------------- 2244 * pa_event_modifier(): Issues pr_adr_u_short to retrieve the next ADR item from 2245 * the input stream pointed to by audit_adr. This is the 2246 * event type, and is displayed in hex; 2247 * return codes : -1 - error 2248 * : 0 - successful 2249 * ----------------------------------------------------------------------- 2250 */ 2251 int 2252 pa_event_modifier(pr_context_t *context, int status, int flag) 2253 { 2254 int returnstat; 2255 au_emod_t emodifier; 2256 uval_t uval; 2257 char modstring[64]; 2258 2259 if (status < 0) 2260 return (status); 2261 2262 if ((returnstat = pr_adr_u_short(context, &emodifier, 1)) != 0) 2263 return (returnstat); 2264 2265 /* For XML, only print when modifier is non-zero */ 2266 if (!(context->format & PRF_XMLM) || (emodifier != 0)) { 2267 uval.uvaltype = PRA_STRING; 2268 2269 returnstat = open_tag(context, TAG_EVMOD); 2270 2271 if (returnstat >= 0) { 2272 if (!(context->format & PRF_RAWM)) { 2273 eventmodifier2string(emodifier, modstring, 2274 sizeof (modstring)); 2275 uval.string_val = modstring; 2276 returnstat = pa_print(context, &uval, flag); 2277 } else { 2278 uval.string_val = hexconvert((char *)&emodifier, 2279 sizeof (emodifier), sizeof (emodifier)); 2280 if (uval.string_val) { 2281 returnstat = pa_print(context, &uval, 2282 flag); 2283 free(uval.string_val); 2284 } 2285 } 2286 } 2287 if (returnstat >= 0) 2288 returnstat = close_tag(context, TAG_EVMOD); 2289 } 2290 2291 return (returnstat); 2292 } 2293 2294 2295 /* 2296 * ----------------------------------------------------------------------- 2297 * pa_event_type(): Issues pr_adr_u_short to retrieve the next ADR item from 2298 * the input stream pointed to by audit_adr. This is the 2299 * event type, and is displayed in either raw or 2300 * ASCII form as appropriate 2301 * return codes : -1 - error 2302 * : 0 - successful 2303 * ----------------------------------------------------------------------- 2304 */ 2305 int 2306 pa_event_type(pr_context_t *context, int status, int flag) 2307 { 2308 au_event_t etype; 2309 int returnstat; 2310 au_event_ent_t *p_event = NULL; 2311 uval_t uval; 2312 2313 if (status >= 0) { 2314 if ((returnstat = pr_adr_u_short(context, &etype, 1)) == 0) { 2315 if (!(context->format & PRF_RAWM)) { 2316 uval.uvaltype = PRA_STRING; 2317 if (context->format & PRF_NOCACHE) { 2318 p_event = getauevnum(etype); 2319 } else { 2320 (void) cacheauevent(&p_event, etype); 2321 } 2322 if (p_event != NULL) { 2323 if (context->format & PRF_SHORTM) 2324 uval.string_val = 2325 p_event->ae_name; 2326 else 2327 uval.string_val = 2328 p_event->ae_desc; 2329 } else { 2330 uval.string_val = 2331 gettext("invalid event number"); 2332 } 2333 returnstat = pa_print(context, &uval, flag); 2334 } else { 2335 uval.uvaltype = PRA_USHORT; 2336 uval.ushort_val = etype; 2337 returnstat = pa_print(context, &uval, flag); 2338 } 2339 } 2340 return (returnstat); 2341 } else 2342 return (status); 2343 2344 } 2345 2346 2347 /* 2348 * Print time from struct timeval to millisecond resolution. 2349 * 2350 * typedef long time_t; time of day in seconds 2351 * typedef long useconds_t; signed # of microseconds 2352 * 2353 * struct timeval { 2354 * time_t tv_sec; seconds 2355 * suseconds_t tv_usec; and microseconds 2356 * }; 2357 */ 2358 2359 int 2360 pa_utime32(pr_context_t *context, int status, int flag) 2361 { 2362 uint32_t scale = 1000; /* usec to msec */ 2363 2364 return (do_mtime32(context, status, flag, scale)); 2365 } 2366 2367 /* 2368 * Print time from timestruc_t to millisecond resolution. 2369 * 2370 * typedef struct timespec timestruct_t; 2371 * struct timespec{ 2372 * time_t tv_sec; seconds 2373 * long tv_nsec; and nanoseconds 2374 * }; 2375 */ 2376 int 2377 pa_ntime32(pr_context_t *context, int status, int flag) 2378 { 2379 uint32_t scale = 1000000; /* nsec to msec */ 2380 2381 return (do_mtime32(context, status, flag, scale)); 2382 } 2383 2384 /* 2385 * Format the timezone +/- HH:MM and terminate the string 2386 * Note tm and tv_sec are the same time. 2387 * Too bad strftime won't produce an ISO 8601 time zone numeric 2388 */ 2389 2390 #define MINS (24L * 60) 2391 static void 2392 tzone(struct tm *tm, time_t *tv_sec, char *p) 2393 { 2394 struct tm *gmt; 2395 int min_off; 2396 2397 gmt = gmtime(tv_sec); 2398 2399 min_off = ((tm->tm_hour - gmt->tm_hour) * 60) + 2400 (tm->tm_min - gmt->tm_min); 2401 2402 if (tm->tm_year < gmt->tm_year) /* cross new year */ 2403 min_off -= MINS; 2404 else if (tm->tm_year > gmt->tm_year) 2405 min_off += MINS; 2406 else if (tm->tm_yday < gmt->tm_yday) /* cross dateline */ 2407 min_off -= MINS; 2408 else if (tm->tm_yday > gmt->tm_yday) 2409 min_off += MINS; 2410 2411 if (min_off < 0) { 2412 min_off = -min_off; 2413 *p++ = '-'; 2414 } else { 2415 *p++ = '+'; 2416 } 2417 2418 *p++ = min_off / 600 + '0'; /* 10s of hours */ 2419 min_off = min_off - min_off / 600 * 600; 2420 *p++ = min_off / 60 % 10 + '0'; /* hours */ 2421 min_off = min_off - min_off / 60 * 60; 2422 *p++ = ':'; 2423 *p++ = min_off / 10 + '0'; /* 10s of minutes */ 2424 *p++ = min_off % 10 + '0'; /* minutes */ 2425 *p = '\0'; 2426 } 2427 2428 /* 2429 * Format the milliseconds in place in the string. 2430 * Borrowed from strftime.c:itoa() 2431 */ 2432 static void 2433 msec32(uint32_t msec, char *p) 2434 { 2435 *p++ = msec / 100 + '0'; 2436 msec = msec - msec / 100 * 100; 2437 *p++ = msec / 10 + '0'; 2438 *p++ = msec % 10 +'0'; 2439 } 2440 2441 /* 2442 * Format time and print relative to scale factor from micro/nano seconds. 2443 */ 2444 static int 2445 do_mtime32(pr_context_t *context, int status, int flag, uint32_t scale) 2446 { 2447 uint32_t t32; 2448 time_t tv_sec; 2449 struct tm tm; 2450 char time_created[sizeof ("YYYY-MM-DD HH:MM:SS.sss -HH:MM")]; 2451 int returnstat; 2452 uval_t uval; 2453 2454 if (status < 0) 2455 return (status); 2456 2457 if ((returnstat = open_tag(context, TAG_ISO)) != 0) 2458 return (returnstat); 2459 2460 if ((returnstat = pr_adr_u_int32(context, 2461 (uint32_t *)&tv_sec, 1)) != 0) 2462 return (returnstat); 2463 if ((returnstat = pr_adr_u_int32(context, &t32, 1)) == 0) { 2464 if (!(context->format & PRF_RAWM)) { 2465 (void) localtime_r(&tv_sec, &tm); 2466 (void) strftime(time_created, 2467 sizeof ("YYYY-MM-DD HH:MM:SS.xxx "), 2468 "%Y-%m-%d %H:%M:%S.xxx ", &tm); 2469 msec32(t32/scale, 2470 &time_created[sizeof ("YYYY-MM-DD HH:MM:SS.")-1]); 2471 tzone(&tm, &tv_sec, 2472 &time_created[ 2473 sizeof ("YYYY-MM-DD HH:MM:SS.xxx ")-1]); 2474 uval.uvaltype = PRA_STRING; 2475 uval.string_val = time_created; 2476 } else { 2477 uval.uvaltype = PRA_UINT32; 2478 uval.uint32_val = (uint32_t)tv_sec; 2479 (void) pa_print(context, &uval, 0); 2480 uval.uvaltype = PRA_UINT32; 2481 uval.uint32_val = t32; 2482 } 2483 returnstat = pa_print(context, &uval, flag); 2484 } 2485 2486 if (returnstat == 0) 2487 return (close_tag(context, TAG_ISO)); 2488 else 2489 return (returnstat); 2490 } 2491 2492 /* 2493 * Print time from struct timeval to millisecond resolution. 2494 * 2495 * typedef long time_t; time of day in seconds 2496 * typedef long useconds_t; signed # of microseconds 2497 * 2498 * struct timeval { 2499 * time_t tv_sec; seconds 2500 * suseconds_t tv_usec; and microseconds 2501 * }; 2502 */ 2503 2504 int 2505 pa_utime64(pr_context_t *context, int status, int flag) 2506 { 2507 uint64_t scale = 1000; /* usec to msec */ 2508 2509 return (do_mtime64(context, status, flag, scale)); 2510 } 2511 2512 /* 2513 * Print time from timestruc_t to millisecond resolution. 2514 * 2515 * typedef struct timespec timestruct_t; 2516 * struct timespec{ 2517 * time_t tv_sec; seconds 2518 * long tv_nsec; and nanoseconds 2519 * }; 2520 */ 2521 int 2522 pa_ntime64(pr_context_t *context, int status, int flag) 2523 { 2524 uint64_t scale = 1000000; /* nsec to msec */ 2525 2526 return (do_mtime64(context, status, flag, scale)); 2527 } 2528 2529 /* 2530 * Format the milliseconds in place in the string. 2531 * Borrowed from strftime.c:itoa() 2532 */ 2533 static void 2534 msec64(uint64_t msec, char *p) 2535 { 2536 *p++ = msec / 100 + '0'; 2537 msec = msec - msec / 100 * 100; 2538 *p++ = msec / 10 + '0'; 2539 *p++ = msec % 10 +'0'; 2540 } 2541 2542 /* 2543 * Format time and print relative to scale factor from micro/nano seconds. 2544 */ 2545 static int 2546 do_mtime64(pr_context_t *context, int status, int flag, uint64_t scale) 2547 { 2548 uint64_t t64_sec; 2549 uint64_t t64_msec; 2550 time_t tv_sec; 2551 struct tm tm; 2552 char time_created[sizeof ("YYYY-MM-DD HH:MM:SS.sss -HH:MM")]; 2553 int returnstat; 2554 uval_t uval; 2555 2556 if (status < 0) 2557 return (status); 2558 2559 if ((returnstat = open_tag(context, TAG_ISO)) != 0) 2560 return (returnstat); 2561 2562 if ((returnstat = pr_adr_u_int64(context, &t64_sec, 1)) != 0) 2563 return (returnstat); 2564 if ((returnstat = pr_adr_u_int64(context, &t64_msec, 1)) == 0) { 2565 if (!(context->format & PRF_RAWM)) { 2566 #ifndef _LP64 2567 /* 2568 * N.B. 2569 * This fails for years from 2038 2570 * The Y2K+38 problem 2571 */ 2572 #endif /* !_LP64 */ 2573 tv_sec = (time_t)t64_sec; 2574 (void) localtime_r(&tv_sec, &tm); 2575 (void) strftime(time_created, 2576 sizeof ("YYYY-MM-DD HH:MM:SS.xxx "), 2577 "%Y-%m-%d %H:%M:%S.xxx ", &tm); 2578 msec64(t64_msec/scale, 2579 &time_created[sizeof ("YYYY-MM-DD HH:MM:SS.")-1]); 2580 tzone(&tm, &tv_sec, 2581 &time_created[ 2582 sizeof ("YYYY-MM-DD HH:MM:SS.xxx ")-1]); 2583 uval.uvaltype = PRA_STRING; 2584 uval.string_val = time_created; 2585 } else { 2586 uval.uvaltype = PRA_UINT64; 2587 uval.uint64_val = t64_sec; 2588 (void) pa_print(context, &uval, 0); 2589 uval.uvaltype = PRA_UINT64; 2590 uval.uint64_val = t64_msec; 2591 } 2592 returnstat = pa_print(context, &uval, flag); 2593 } 2594 2595 if (returnstat < 0) 2596 return (returnstat); 2597 2598 return (close_tag(context, TAG_ISO)); 2599 } 2600 2601 /* 2602 * ----------------------------------------------------------------------- 2603 * pa_error() : convert the return token error code. 2604 * 2605 * output : buf string representing return token error code. 2606 * 2607 * ----------------------------------------------------------------------- 2608 */ 2609 void 2610 pa_error(const uchar_t err, char *buf, size_t buflen) 2611 { 2612 if (err == ADT_SUCCESS) { 2613 (void) strlcpy(buf, gettext("success"), buflen); 2614 } else if ((char)err == ADT_FAILURE) { 2615 (void) strlcpy(buf, gettext("failure"), buflen); 2616 } else { 2617 char *emsg = strerror(err); 2618 2619 if (emsg != NULL) { 2620 (void) strlcpy(buf, gettext("failure: "), buflen); 2621 (void) strlcat(buf, emsg, buflen); 2622 } else { 2623 (void) snprintf(buf, buflen, "%s%d", 2624 gettext("failure: "), err); 2625 } 2626 } 2627 } 2628 2629 /* 2630 * ----------------------------------------------------------------------- 2631 * pa_retval() : convert the return token return value code. 2632 * 2633 * input : err, for kernel success 0, or 2634 * failure errno: 0 > & < sys_nerr. 2635 * for userland success ADT_SUCCESS (0) or 2636 * failure ADT_FAILURE (-1). 2637 * pa_error() above has already converted err. 2638 * 2639 * : retval, for kernel arbitrary return value for success, or 2640 * failure: -1. 2641 * for userland, 2642 * >= ADT_FAIL_VALUE < ADT_FAIL_PAM, an adt message code; 2643 * >= ADT_FAIL_PAM, a pam_strerror value; 2644 * < ADT_FAIL_VALUE, supposed to be an errno. 2645 * 2646 * output : buf string representing return token error code. 2647 * 2648 * ----------------------------------------------------------------------- 2649 */ 2650 void 2651 pa_retval(const uchar_t err, const int32_t retval, char *buf, size_t buflen) 2652 { 2653 struct msg_text *msglist; 2654 char *emsg; 2655 2656 /* success or kernel failure */ 2657 if (((char)err == ADT_SUCCESS) || 2658 (retval < 0)) { 2659 2660 (void) snprintf(buf, buflen, "%d", retval); 2661 return; 2662 } 2663 2664 /* userland failure */ 2665 msglist = &adt_msg_text[ADT_LIST_FAIL_VALUE]; 2666 2667 if ((retval + msglist->ml_offset >= msglist->ml_min_index) && 2668 (retval + msglist->ml_offset <= msglist->ml_max_index)) { 2669 2670 (void) strlcpy(buf, 2671 gettext(msglist->ml_msg_list[retval + msglist->ml_offset]), 2672 buflen); 2673 } else if ((retval >= ADT_FAIL_PAM) && 2674 (retval < ADT_FAIL_PAM + PAM_TOTAL_ERRNUM)) { 2675 2676 (void) strlcpy(buf, pam_strerror(NULL, retval - ADT_FAIL_PAM), 2677 buflen); 2678 } else if ((emsg = strerror(retval)) != NULL) { 2679 2680 (void) strlcpy(buf, emsg, buflen); 2681 } else { 2682 2683 (void) snprintf(buf, buflen, "%d", retval); 2684 } 2685 } 2686 2687 /* 2688 * ----------------------------------------------------------------------- 2689 * pa_printstr() : print a given string, translating unprintables 2690 * : as needed. 2691 */ 2692 static int 2693 pa_printstr(pr_context_t *context, char *str) 2694 { 2695 int err = 0; 2696 int len, printable; 2697 int mbmax = MB_CUR_MAX; 2698 wchar_t wc; 2699 char c; 2700 2701 if (mbmax == 1) { 2702 /* fast path */ 2703 while (err == 0 && *str != '\0') { 2704 c = *str++; 2705 printable = isprint((unsigned char)c); 2706 err = pa_putstr(context, printable, &c, 1); 2707 } 2708 return (err); 2709 } 2710 while (err == 0 && *str != '\0') { 2711 len = mbtowc(&wc, str, mbmax); 2712 if (len <= 0) { 2713 len = 1; 2714 printable = 0; 2715 } else { 2716 printable = iswprint(wc); 2717 } 2718 err = pa_putstr(context, printable, str, len); 2719 str += len; 2720 } 2721 return (err); 2722 } 2723 2724 /* 2725 * ----------------------------------------------------------------------- 2726 * pa_print() : print as one str or formatted for easy reading. 2727 * : flag - indicates whether to output a new line for 2728 * : multi-line output. 2729 * : = 0; no new line 2730 * : = 1; new line if regular output 2731 * output : The audit record information is displayed in the 2732 * type specified by uvaltype and value specified in 2733 * uval. The printing of the delimiter or newline is 2734 * determined by PRF_ONELINE, and the flag value, 2735 * as follows: 2736 * +--------+------+------+-----------------+ 2737 * |ONELINE | flag | last | Action | 2738 * +--------+------+------+-----------------+ 2739 * | Y | Y | T | print new line | 2740 * | Y | Y | F | print delimiter | 2741 * | Y | N | T | print new line | 2742 * | Y | N | F | print delimiter | 2743 * | N | Y | T | print new line | 2744 * | N | Y | F | print new line | 2745 * | N | N | T | print new line | 2746 * | N | N | F | print delimiter | 2747 * +--------+------+------+-----------------+ 2748 * 2749 * return codes : -1 - error 2750 * 0 - successful 2751 * ----------------------------------------------------------------------- 2752 */ 2753 int 2754 pa_print(pr_context_t *context, uval_t *uval, int flag) 2755 { 2756 int returnstat = 0; 2757 int last; 2758 2759 switch (uval->uvaltype) { 2760 case PRA_INT32: 2761 returnstat = pr_printf(context, "%d", uval->int32_val); 2762 break; 2763 case PRA_UINT32: 2764 returnstat = pr_printf(context, "%u", uval->uint32_val); 2765 break; 2766 case PRA_INT64: 2767 returnstat = pr_printf(context, "%"PRId64, uval->int64_val); 2768 break; 2769 case PRA_UINT64: 2770 returnstat = pr_printf(context, "%"PRIu64, uval->uint64_val); 2771 break; 2772 case PRA_SHORT: 2773 returnstat = pr_printf(context, "%hd", uval->short_val); 2774 break; 2775 case PRA_USHORT: 2776 returnstat = pr_printf(context, "%hu", uval->ushort_val); 2777 break; 2778 case PRA_CHAR: 2779 returnstat = pr_printf(context, "%c", uval->char_val); 2780 break; 2781 case PRA_BYTE: 2782 returnstat = pr_printf(context, "%d", uval->char_val); 2783 break; 2784 case PRA_STRING: 2785 returnstat = pa_printstr(context, uval->string_val); 2786 break; 2787 case PRA_HEX32: 2788 returnstat = pr_printf(context, "0x%x", uval->int32_val); 2789 break; 2790 case PRA_HEX64: 2791 returnstat = pr_printf(context, "0x%"PRIx64, uval->int64_val); 2792 break; 2793 case PRA_SHEX: 2794 returnstat = pr_printf(context, "0x%hx", uval->short_val); 2795 break; 2796 case PRA_OCT: 2797 returnstat = pr_printf(context, "%ho", uval->ushort_val); 2798 break; 2799 case PRA_LOCT: 2800 returnstat = pr_printf(context, "%o", (int)uval->uint32_val); 2801 break; 2802 default: 2803 (void) fprintf(stderr, gettext("praudit: Unknown type.\n")); 2804 returnstat = -1; 2805 break; 2806 } 2807 if (returnstat < 0) 2808 return (returnstat); 2809 2810 last = (context->audit_adr->adr_now == 2811 (context->audit_rec_start + context->audit_rec_len)); 2812 2813 if (!(context->format & PRF_XMLM)) { 2814 if (!(context->format & PRF_ONELINE)) { 2815 if ((flag == 1) || last) 2816 returnstat = pr_putchar(context, '\n'); 2817 else 2818 returnstat = pr_printf(context, "%s", 2819 context->SEPARATOR); 2820 } else { 2821 if (!last) 2822 returnstat = pr_printf(context, "%s", 2823 context->SEPARATOR); 2824 else 2825 returnstat = pr_putchar(context, '\n'); 2826 } 2827 } 2828 if ((returnstat == 0) && (context->data_mode == FILEMODE)) 2829 (void) fflush(stdout); 2830 2831 return (returnstat); 2832 } 2833 2834 static struct cntrl_mapping { 2835 char from; 2836 char to; 2837 } cntrl_map[] = { 2838 '\0', '0', 2839 '\a', 'a', 2840 '\b', 'b', 2841 '\t', 't', 2842 '\f', 'f', 2843 '\n', 'n', 2844 '\r', 'r', 2845 '\v', 'v' 2846 }; 2847 2848 static int cntrl_map_entries = sizeof (cntrl_map) 2849 / sizeof (struct cntrl_mapping); 2850 2851 /* 2852 * Convert binary data to ASCII for printing. 2853 */ 2854 void 2855 convertascii(char *p, char *c, int size) 2856 { 2857 int i, j, uc; 2858 2859 for (i = 0; i < size; i++) { 2860 uc = (unsigned char)*(c + i); 2861 if (isascii(uc)) { 2862 if (iscntrl(uc)) { 2863 for (j = 0; j < cntrl_map_entries; j++) { 2864 if (cntrl_map[j].from == uc) { 2865 *p++ = '\\'; 2866 *p++ = cntrl_map[j].to; 2867 break; 2868 } 2869 } 2870 if (j == cntrl_map_entries) { 2871 *p++ = '^'; 2872 *p++ = (char)(uc ^ 0100); 2873 } 2874 } else { 2875 *p++ = (char)uc; 2876 } 2877 } else { 2878 p += sprintf(p, "\\%03o", uc); 2879 } 2880 } 2881 *p = '\0'; 2882 } 2883 2884 /* 2885 * ----------------------------------------------------------------------- 2886 * pa_xgeneric: Process Xobject token and display contents 2887 * This routine will handle many of the attribute 2888 * types introduced in TS 2.x, such as: 2889 * 2890 * AUT_XCOLORMAP, AUT_XCURSOR, AUT_XFONT, 2891 * AUT_XGC, AUT_XPIXMAP, AUT_XWINDOW 2892 * 2893 * NOTE: At the time of call, the token id has been retrieved 2894 * 2895 * return codes : -1 - error 2896 * : 0 - successful 2897 * NOTE: At the time of call, the xatom token id has been retrieved 2898 * 2899 * Format of xobj 2900 * text token id adr_char 2901 * XID adr_u_int32 2902 * creator uid adr_pw_uid 2903 * ----------------------------------------------------------------------- 2904 */ 2905 int 2906 pa_xgeneric(pr_context_t *context) 2907 { 2908 int returnstat; 2909 2910 returnstat = process_tag(context, TAG_XID, 0, 0); 2911 return (process_tag(context, TAG_XCUID, returnstat, 1)); 2912 } 2913 2914 2915 /* 2916 * ------------------------------------------------------------------------ 2917 * pa_liaison : Issues pr_adr_char to retrieve the next ADR item from the 2918 * input stream pointed to by audit_adr, and prints it 2919 * if status >= 0 either in ASCII or raw form 2920 * return codes : -1 - error 2921 * : 0 - successful 2922 * : 1 - warning, unknown label type 2923 * ----------------------------------------------------------------------- 2924 */ 2925 int 2926 pa_liaison(pr_context_t *context, int status, int flag) 2927 { 2928 int returnstat; 2929 int32_t li; 2930 uval_t uval; 2931 2932 if (status >= 0) { 2933 if ((returnstat = pr_adr_int32(context, &li, 1)) != 0) { 2934 return (returnstat); 2935 } 2936 if (!(context->format & PRF_RAWM)) { 2937 uval.uvaltype = PRA_UINT32; 2938 uval.uint32_val = li; 2939 returnstat = pa_print(context, &uval, flag); 2940 } 2941 /* print in hexadecimal form */ 2942 if ((context->format & PRF_RAWM) || (returnstat == 1)) { 2943 uval.uvaltype = PRA_HEX32; 2944 uval.uint32_val = li; 2945 returnstat = pa_print(context, &uval, flag); 2946 } 2947 return (returnstat); 2948 } else 2949 return (status); 2950 } 2951 2952 /* 2953 * ------------------------------------------------------------------------ 2954 * pa_xid : Issues pr_adr_int32 to retrieve the XID from the input 2955 * stream pointed to by audit_adr, and prints it if 2956 * status >= 0 either in ASCII or raw form 2957 * return codes : -1 - error 2958 * : 0 - successful 2959 * : 1 - warning, unknown label type 2960 * ------------------------------------------------------------------------ 2961 */ 2962 2963 int 2964 pa_xid(pr_context_t *context, int status, int flag) 2965 { 2966 int returnstat; 2967 int32_t xid; 2968 uval_t uval; 2969 2970 if (status < 0) 2971 return (status); 2972 2973 /* get XID from stream */ 2974 if ((returnstat = pr_adr_int32(context, (int32_t *)&xid, 1)) != 0) 2975 return (returnstat); 2976 2977 if (!(context->format & PRF_RAWM)) { 2978 uval.uvaltype = PRA_STRING; 2979 uval.string_val = hexconvert((char *)&xid, sizeof (xid), 2980 sizeof (xid)); 2981 if (uval.string_val) { 2982 returnstat = pa_print(context, &uval, flag); 2983 free(uval.string_val); 2984 } 2985 } else { 2986 uval.uvaltype = PRA_INT32; 2987 uval.int32_val = xid; 2988 returnstat = pa_print(context, &uval, flag); 2989 } 2990 2991 return (returnstat); 2992 } 2993 2994 static int 2995 pa_ace_flags(pr_context_t *context, ace_t *ace, int status, int flag) 2996 { 2997 int returnstat; 2998 uval_t uval; 2999 3000 if (status < 0) 3001 return (status); 3002 3003 /* 3004 * TRANSLATION_NOTE 3005 * ace->a_flags refers to access flags of ZFS/NFSv4 ACL entry. 3006 */ 3007 if ((returnstat = open_tag(context, TAG_ACEFLAGS)) != 0) 3008 return (returnstat); 3009 if (!(context->format & PRF_RAWM)) { 3010 uval.uvaltype = PRA_STRING; 3011 switch (ace->a_flags & ACE_TYPE_FLAGS) { 3012 case ACE_OWNER: 3013 uval.string_val = gettext(OWNERAT_TXT); 3014 break; 3015 case ACE_GROUP | ACE_IDENTIFIER_GROUP: 3016 uval.string_val = gettext(GROUPAT_TXT); 3017 break; 3018 case ACE_IDENTIFIER_GROUP: 3019 uval.string_val = gettext(GROUP_TXT); 3020 break; 3021 case ACE_EVERYONE: 3022 uval.string_val = gettext(EVERYONEAT_TXT); 3023 break; 3024 case 0: 3025 uval.string_val = gettext(USER_TXT); 3026 break; 3027 default: 3028 uval.uvaltype = PRA_USHORT; 3029 uval.uint32_val = ace->a_flags; 3030 } 3031 } else { 3032 uval.uvaltype = PRA_USHORT; 3033 uval.uint32_val = ace->a_flags; 3034 } 3035 if ((returnstat = pa_print(context, &uval, flag)) != 0) 3036 return (returnstat); 3037 return (close_tag(context, TAG_ACEFLAGS)); 3038 } 3039 3040 static int 3041 pa_ace_who(pr_context_t *context, ace_t *ace, int status, int flag) 3042 { 3043 int returnstat; 3044 3045 if (status < 0) 3046 return (status); 3047 3048 /* 3049 * TRANSLATION_NOTE 3050 * ace->a_who refers to user id or group id of ZFS/NFSv4 ACL entry. 3051 */ 3052 if ((returnstat = open_tag(context, TAG_ACEID)) != 0) 3053 return (returnstat); 3054 switch (ace->a_flags & ACE_TYPE_FLAGS) { 3055 case ACE_IDENTIFIER_GROUP: /* group id */ 3056 returnstat = pa_print_gid(context, ace->a_who, returnstat, 3057 flag); 3058 break; 3059 default: /* user id */ 3060 returnstat = pa_print_uid(context, ace->a_who, returnstat, 3061 flag); 3062 break; 3063 } 3064 if (returnstat < 0) 3065 return (returnstat); 3066 return (close_tag(context, TAG_ACEID)); 3067 } 3068 3069 /* 3070 * Appends what to str, (re)allocating str if necessary. 3071 */ 3072 #define INITIAL_ALLOC 256 3073 static int 3074 strappend(char **str, char *what, size_t *alloc) 3075 { 3076 char *s, *newstr; 3077 size_t needed; 3078 3079 s = *str; 3080 3081 if (s == NULL) { 3082 s = malloc(INITIAL_ALLOC); 3083 if (s == NULL) { 3084 *alloc = 0; 3085 return (-1); 3086 } 3087 *alloc = INITIAL_ALLOC; 3088 s[0] = '\0'; 3089 *str = s; 3090 } 3091 3092 needed = strlen(s) + strlen(what) + 1; 3093 if (*alloc < needed) { 3094 newstr = realloc(s, needed); 3095 if (newstr == NULL) 3096 return (-1); 3097 s = newstr; 3098 *alloc = needed; 3099 *str = s; 3100 } 3101 (void) strlcat(s, what, *alloc); 3102 3103 return (0); 3104 } 3105 3106 static int 3107 pa_ace_access_mask(pr_context_t *context, ace_t *ace, int status, int flag) 3108 { 3109 int returnstat, i; 3110 uval_t uval; 3111 char *permstr = NULL; 3112 size_t permstr_alloc = 0; 3113 3114 if (status < 0) 3115 return (status); 3116 3117 /* 3118 * TRANSLATION_NOTE 3119 * ace->a_access_mask refers to access mask of ZFS/NFSv4 ACL entry. 3120 */ 3121 if ((returnstat = open_tag(context, TAG_ACEMASK)) != 0) 3122 return (returnstat); 3123 if (context->format & PRF_SHORTM && 3124 ((permstr = malloc(15)) != NULL)) { 3125 for (i = 0; i < 14; i++) 3126 permstr[i] = '-'; 3127 3128 if (ace->a_access_mask & ACE_READ_DATA) 3129 permstr[0] = 'r'; 3130 if (ace->a_access_mask & ACE_WRITE_DATA) 3131 permstr[1] = 'w'; 3132 if (ace->a_access_mask & ACE_EXECUTE) 3133 permstr[2] = 'x'; 3134 if (ace->a_access_mask & ACE_APPEND_DATA) 3135 permstr[3] = 'p'; 3136 if (ace->a_access_mask & ACE_DELETE) 3137 permstr[4] = 'd'; 3138 if (ace->a_access_mask & ACE_DELETE_CHILD) 3139 permstr[5] = 'D'; 3140 if (ace->a_access_mask & ACE_READ_ATTRIBUTES) 3141 permstr[6] = 'a'; 3142 if (ace->a_access_mask & ACE_WRITE_ATTRIBUTES) 3143 permstr[7] = 'A'; 3144 if (ace->a_access_mask & ACE_READ_NAMED_ATTRS) 3145 permstr[8] = 'R'; 3146 if (ace->a_access_mask & ACE_WRITE_NAMED_ATTRS) 3147 permstr[9] = 'W'; 3148 if (ace->a_access_mask & ACE_READ_ACL) 3149 permstr[10] = 'c'; 3150 if (ace->a_access_mask & ACE_WRITE_ACL) 3151 permstr[11] = 'C'; 3152 if (ace->a_access_mask & ACE_WRITE_OWNER) 3153 permstr[12] = 'o'; 3154 if (ace->a_access_mask & ACE_SYNCHRONIZE) 3155 permstr[13] = 's'; 3156 permstr[14] = '\0'; 3157 uval.uvaltype = PRA_STRING; 3158 uval.string_val = permstr; 3159 } else if (!(context->format & PRF_RAWM)) { 3160 3161 /* 3162 * Note this differs from acltext.c:ace_perm_txt() 3163 * because we don't know if the acl belongs to a file 3164 * or directory. ace mask value are the same 3165 * nonetheless, see sys/acl.h 3166 */ 3167 if (ace->a_access_mask & ACE_LIST_DIRECTORY) { 3168 returnstat = strappend(&permstr, gettext(READ_DIR_TXT), 3169 &permstr_alloc); 3170 } 3171 if (ace->a_access_mask & ACE_ADD_FILE) { 3172 returnstat = strappend(&permstr, gettext(ADD_FILE_TXT), 3173 &permstr_alloc); 3174 } 3175 if (ace->a_access_mask & ACE_ADD_SUBDIRECTORY) { 3176 returnstat = strappend(&permstr, gettext(ADD_DIR_TXT), 3177 &permstr_alloc); 3178 } 3179 if (ace->a_access_mask & ACE_READ_NAMED_ATTRS) { 3180 returnstat = strappend(&permstr, 3181 gettext(READ_XATTR_TXT), &permstr_alloc); 3182 } 3183 if (ace->a_access_mask & ACE_WRITE_NAMED_ATTRS) { 3184 returnstat = strappend(&permstr, 3185 gettext(WRITE_XATTR_TXT), &permstr_alloc); 3186 } 3187 if (ace->a_access_mask & ACE_EXECUTE) { 3188 returnstat = strappend(&permstr, 3189 gettext(EXECUTE_TXT), &permstr_alloc); 3190 } 3191 if (ace->a_access_mask & ACE_DELETE_CHILD) { 3192 returnstat = strappend(&permstr, 3193 gettext(DELETE_CHILD_TXT), &permstr_alloc); 3194 } 3195 if (ace->a_access_mask & ACE_READ_ATTRIBUTES) { 3196 returnstat = strappend(&permstr, 3197 gettext(READ_ATTRIBUTES_TXT), &permstr_alloc); 3198 } 3199 if (ace->a_access_mask & ACE_WRITE_ATTRIBUTES) { 3200 returnstat = strappend(&permstr, 3201 gettext(WRITE_ATTRIBUTES_TXT), &permstr_alloc); 3202 } 3203 if (ace->a_access_mask & ACE_DELETE) { 3204 returnstat = strappend(&permstr, gettext(DELETE_TXT), 3205 &permstr_alloc); 3206 } 3207 if (ace->a_access_mask & ACE_READ_ACL) { 3208 returnstat = strappend(&permstr, gettext(READ_ACL_TXT), 3209 &permstr_alloc); 3210 } 3211 if (ace->a_access_mask & ACE_WRITE_ACL) { 3212 returnstat = strappend(&permstr, gettext(WRITE_ACL_TXT), 3213 &permstr_alloc); 3214 } 3215 if (ace->a_access_mask & ACE_WRITE_OWNER) { 3216 returnstat = strappend(&permstr, 3217 gettext(WRITE_OWNER_TXT), &permstr_alloc); 3218 } 3219 if (ace->a_access_mask & ACE_SYNCHRONIZE) { 3220 returnstat = strappend(&permstr, 3221 gettext(SYNCHRONIZE_TXT), &permstr_alloc); 3222 } 3223 if (permstr[strlen(permstr) - 1] == '/') 3224 permstr[strlen(permstr) - 1] = '\0'; 3225 uval.uvaltype = PRA_STRING; 3226 uval.string_val = permstr; 3227 } 3228 if ((permstr == NULL) || (returnstat != 0) || 3229 (context->format & PRF_RAWM)) { 3230 uval.uvaltype = PRA_UINT32; 3231 uval.uint32_val = ace->a_access_mask; 3232 } 3233 returnstat = pa_print(context, &uval, flag); 3234 3235 if (permstr != NULL) 3236 free(permstr); 3237 if (returnstat != 0) 3238 return (returnstat); 3239 return (close_tag(context, TAG_ACEMASK)); 3240 } 3241 3242 static int 3243 pa_ace_type(pr_context_t *context, ace_t *ace, int status, int flag) 3244 { 3245 int returnstat; 3246 uval_t uval; 3247 3248 if (status < 0) 3249 return (status); 3250 3251 /* 3252 * TRANSLATION_NOTE 3253 * ace->a_type refers to access type of ZFS/NFSv4 ACL entry. 3254 */ 3255 if ((returnstat = open_tag(context, TAG_ACETYPE)) != 0) 3256 return (returnstat); 3257 if (!(context->format & PRF_RAWM)) { 3258 uval.uvaltype = PRA_STRING; 3259 switch (ace->a_type) { 3260 case ACE_ACCESS_ALLOWED_ACE_TYPE: 3261 uval.string_val = gettext(ALLOW_TXT); 3262 break; 3263 case ACE_ACCESS_DENIED_ACE_TYPE: 3264 uval.string_val = gettext(DENY_TXT); 3265 break; 3266 case ACE_SYSTEM_AUDIT_ACE_TYPE: 3267 uval.string_val = gettext(AUDIT_TXT); 3268 break; 3269 case ACE_SYSTEM_ALARM_ACE_TYPE: 3270 uval.string_val = gettext(ALARM_TXT); 3271 break; 3272 default: 3273 uval.string_val = gettext(UNKNOWN_TXT); 3274 } 3275 } else { 3276 uval.uvaltype = PRA_USHORT; 3277 uval.uint32_val = ace->a_type; 3278 } 3279 if ((returnstat = pa_print(context, &uval, flag)) != 0) 3280 return (returnstat); 3281 return (close_tag(context, TAG_ACETYPE)); 3282 } 3283 3284 int 3285 pa_ace(pr_context_t *context, int status, int flag) 3286 { 3287 int returnstat; 3288 ace_t ace; 3289 3290 if (status < 0) 3291 return (status); 3292 3293 if ((returnstat = pr_adr_u_int32(context, &ace.a_who, 1)) != 0) 3294 return (returnstat); 3295 if ((returnstat = pr_adr_u_int32(context, &ace.a_access_mask, 1)) != 0) 3296 return (returnstat); 3297 if ((returnstat = pr_adr_u_short(context, &ace.a_flags, 1)) != 0) 3298 return (returnstat); 3299 if ((returnstat = pr_adr_u_short(context, &ace.a_type, 1)) != 0) 3300 return (returnstat); 3301 3302 if ((returnstat = pa_ace_flags(context, &ace, returnstat, 0)) != 0) 3303 return (returnstat); 3304 /* pa_ace_who can returns 1 if uid/gid is not found */ 3305 if ((returnstat = pa_ace_who(context, &ace, returnstat, 0)) < 0) 3306 return (returnstat); 3307 if ((returnstat = pa_ace_access_mask(context, &ace, 3308 returnstat, 0)) != 0) 3309 return (returnstat); 3310 return (pa_ace_type(context, &ace, returnstat, flag)); 3311 } 3312