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