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