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