bsm_token.c revision 161818
1/* 2 * Copyright (c) 2004 Apple Computer, Inc. 3 * Copyright (c) 2005 SPARTA, Inc. 4 * All rights reserved. 5 * 6 * This code was developed in part by Robert N. M. Watson, Senior Principal 7 * Scientist, SPARTA, Inc. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of 18 * its contributors may be used to endorse or promote products derived 19 * from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR 25 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 29 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 30 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 * POSSIBILITY OF SUCH DAMAGE. 32 * 33 * $P4: //depot/projects/trustedbsd/openbsm/libbsm/bsm_token.c#51 $ 34 */ 35 36#include <sys/types.h> 37 38#include <config/config.h> 39#ifdef HAVE_SYS_ENDIAN_H 40#include <sys/endian.h> 41#else /* !HAVE_SYS_ENDIAN_H */ 42#ifdef HAVE_MACHINE_ENDIAN_H 43#include <machine/endian.h> 44#else /* !HAVE_MACHINE_ENDIAN_H */ 45#ifdef HAVE_ENDIAN_H 46#include <endian.h> 47#else /* !HAVE_ENDIAN_H */ 48#error "No supported endian.h" 49#endif /* !HAVE_ENDIAN_H */ 50#endif /* !HAVE_MACHINE_ENDIAN_H */ 51#include <compat/endian.h> 52#endif /* !HAVE_SYS_ENDIAN_H */ 53#ifdef HAVE_FULL_QUEUE_H 54#include <sys/queue.h> 55#else /* !HAVE_FULL_QUEUE_H */ 56#include <compat/queue.h> 57#endif /* !HAVE_FULL_QUEUE_H */ 58 59#include <sys/socket.h> 60#include <sys/time.h> 61#include <sys/un.h> 62 63#include <sys/ipc.h> 64 65#include <netinet/in.h> 66#include <netinet/in_systm.h> 67#include <netinet/ip.h> 68 69#include <assert.h> 70#include <errno.h> 71#include <string.h> 72#include <stdlib.h> 73#include <unistd.h> 74#include <sys/socketvar.h> 75 76#include <bsm/audit_internal.h> 77#include <bsm/libbsm.h> 78 79#define GET_TOKEN_AREA(t, dptr, length) do { \ 80 (t) = malloc(sizeof(token_t)); \ 81 if ((t) != NULL) { \ 82 (t)->len = (length); \ 83 (dptr) = (t->t_data) = malloc((length) * sizeof(u_char)); \ 84 if ((dptr) == NULL) { \ 85 free(t); \ 86 (t) = NULL; \ 87 } else \ 88 memset((dptr), 0, (length)); \ 89 } else \ 90 (dptr) = NULL; \ 91 assert(t == NULL || dptr != NULL); \ 92} while (0) 93 94/* 95 * token ID 1 byte 96 * argument # 1 byte 97 * argument value 4 bytes/8 bytes (32-bit/64-bit value) 98 * text length 2 bytes 99 * text N bytes + 1 terminating NULL byte 100 */ 101token_t * 102au_to_arg32(char n, char *text, u_int32_t v) 103{ 104 token_t *t; 105 u_char *dptr = NULL; 106 u_int16_t textlen; 107 108 textlen = strlen(text); 109 textlen += 1; 110 111 GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int32_t) + 112 sizeof(u_int16_t) + textlen); 113 if (t == NULL) 114 return (NULL); 115 116 ADD_U_CHAR(dptr, AUT_ARG32); 117 ADD_U_CHAR(dptr, n); 118 ADD_U_INT32(dptr, v); 119 ADD_U_INT16(dptr, textlen); 120 ADD_STRING(dptr, text, textlen); 121 122 return (t); 123 124} 125 126token_t * 127au_to_arg64(char n, char *text, u_int64_t v) 128{ 129 token_t *t; 130 u_char *dptr = NULL; 131 u_int16_t textlen; 132 133 textlen = strlen(text); 134 textlen += 1; 135 136 GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int64_t) + 137 sizeof(u_int16_t) + textlen); 138 if (t == NULL) 139 return (NULL); 140 141 ADD_U_CHAR(dptr, AUT_ARG64); 142 ADD_U_CHAR(dptr, n); 143 ADD_U_INT64(dptr, v); 144 ADD_U_INT16(dptr, textlen); 145 ADD_STRING(dptr, text, textlen); 146 147 return (t); 148 149} 150 151token_t * 152au_to_arg(char n, char *text, u_int32_t v) 153{ 154 155 return (au_to_arg32(n, text, v)); 156} 157 158#if defined(_KERNEL) || defined(KERNEL) 159/* 160 * token ID 1 byte 161 * file access mode 4 bytes 162 * owner user ID 4 bytes 163 * owner group ID 4 bytes 164 * file system ID 4 bytes 165 * node ID 8 bytes 166 * device 4 bytes/8 bytes (32-bit/64-bit) 167 */ 168token_t * 169au_to_attr32(struct vnode_au_info *vni) 170{ 171 token_t *t; 172 u_char *dptr = NULL; 173 u_int16_t pad0_16 = 0; 174 u_int16_t pad0_32 = 0; 175 176 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int16_t) + 177 3 * sizeof(u_int32_t) + sizeof(u_int64_t) + sizeof(u_int32_t)); 178 if (t == NULL) 179 return (NULL); 180 181 ADD_U_CHAR(dptr, AUT_ATTR32); 182 183 /* 184 * Darwin defines the size for the file mode 185 * as 2 bytes; BSM defines 4 so pad with 0 186 */ 187 ADD_U_INT16(dptr, pad0_16); 188 ADD_U_INT16(dptr, vni->vn_mode); 189 190 ADD_U_INT32(dptr, vni->vn_uid); 191 ADD_U_INT32(dptr, vni->vn_gid); 192 ADD_U_INT32(dptr, vni->vn_fsid); 193 194 /* 195 * Some systems use 32-bit file ID's, other's use 64-bit file IDs. 196 * Attempt to handle both, and let the compiler sort it out. If we 197 * could pick this out at compile-time, it would be better, so as to 198 * avoid the else case below. 199 */ 200 if (sizeof(vni->vn_fileid) == sizeof(uint32_t)) { 201 ADD_U_INT32(dptr, pad0_32); 202 ADD_U_INT32(dptr, vni->vn_fileid); 203 } else if (sizeof(vni->vn_fileid) == sizeof(uint64_t)) 204 ADD_U_INT64(dptr, vni->vn_fileid); 205 else 206 ADD_U_INT64(dptr, 0LL); 207 208 ADD_U_INT32(dptr, vni->vn_dev); 209 210 return (t); 211} 212 213token_t * 214au_to_attr64(struct vnode_au_info *vni) 215{ 216 217 errno = ENOTSUP; 218 return (NULL); 219} 220 221token_t * 222au_to_attr(struct vnode_au_info *vni) 223{ 224 225 return (au_to_attr32(vni)); 226} 227#endif /* !(defined(_KERNEL) || defined(KERNEL) */ 228 229/* 230 * token ID 1 byte 231 * how to print 1 byte 232 * basic unit 1 byte 233 * unit count 1 byte 234 * data items (depends on basic unit) 235 */ 236token_t * 237au_to_data(char unit_print, char unit_type, char unit_count, char *p) 238{ 239 token_t *t; 240 u_char *dptr = NULL; 241 size_t datasize, totdata; 242 243 /* Determine the size of the basic unit. */ 244 switch (unit_type) { 245 case AUR_BYTE: 246 /* case AUR_CHAR: */ 247 datasize = AUR_BYTE_SIZE; 248 break; 249 250 case AUR_SHORT: 251 datasize = AUR_SHORT_SIZE; 252 break; 253 254 case AUR_INT32: 255 /* case AUR_INT: */ 256 datasize = AUR_INT32_SIZE; 257 break; 258 259 case AUR_INT64: 260 datasize = AUR_INT64_SIZE; 261 break; 262 263 default: 264 errno = EINVAL; 265 return (NULL); 266 } 267 268 totdata = datasize * unit_count; 269 270 GET_TOKEN_AREA(t, dptr, 4 * sizeof(u_char) + totdata); 271 if (t == NULL) 272 return (NULL); 273 274 ADD_U_CHAR(dptr, AUT_DATA); 275 ADD_U_CHAR(dptr, unit_print); 276 ADD_U_CHAR(dptr, unit_type); 277 ADD_U_CHAR(dptr, unit_count); 278 ADD_MEM(dptr, p, totdata); 279 280 return (t); 281} 282 283 284/* 285 * token ID 1 byte 286 * status 4 bytes 287 * return value 4 bytes 288 */ 289token_t * 290au_to_exit(int retval, int err) 291{ 292 token_t *t; 293 u_char *dptr = NULL; 294 295 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int32_t)); 296 if (t == NULL) 297 return (NULL); 298 299 ADD_U_CHAR(dptr, AUT_EXIT); 300 ADD_U_INT32(dptr, err); 301 ADD_U_INT32(dptr, retval); 302 303 return (t); 304} 305 306/* 307 */ 308token_t * 309au_to_groups(int *groups) 310{ 311 312 return (au_to_newgroups(AUDIT_MAX_GROUPS, groups)); 313} 314 315/* 316 * token ID 1 byte 317 * number groups 2 bytes 318 * group list count * 4 bytes 319 */ 320token_t * 321au_to_newgroups(u_int16_t n, gid_t *groups) 322{ 323 token_t *t; 324 u_char *dptr = NULL; 325 int i; 326 327 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + 328 n * sizeof(u_int32_t)); 329 if (t == NULL) 330 return (NULL); 331 332 ADD_U_CHAR(dptr, AUT_NEWGROUPS); 333 ADD_U_INT16(dptr, n); 334 for (i = 0; i < n; i++) 335 ADD_U_INT32(dptr, groups[i]); 336 337 return (t); 338} 339 340/* 341 * token ID 1 byte 342 * internet address 4 bytes 343 */ 344token_t * 345au_to_in_addr(struct in_addr *internet_addr) 346{ 347 token_t *t; 348 u_char *dptr = NULL; 349 350 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(uint32_t)); 351 if (t == NULL) 352 return (NULL); 353 354 ADD_U_CHAR(dptr, AUT_IN_ADDR); 355 ADD_MEM(dptr, &internet_addr->s_addr, sizeof(uint32_t)); 356 357 return (t); 358} 359 360/* 361 * token ID 1 byte 362 * address type/length 4 bytes 363 * Address 16 bytes 364 */ 365token_t * 366au_to_in_addr_ex(struct in6_addr *internet_addr) 367{ 368 token_t *t; 369 u_char *dptr = NULL; 370 u_int32_t type = AF_INET6; 371 372 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 5 * sizeof(uint32_t)); 373 if (t == NULL) 374 return (NULL); 375 376 ADD_U_CHAR(dptr, AUT_IN_ADDR_EX); 377 ADD_U_INT32(dptr, type); 378 ADD_MEM(dptr, internet_addr, 5 * sizeof(uint32_t)); 379 380 return (t); 381} 382 383/* 384 * token ID 1 byte 385 * ip header 20 bytes 386 */ 387token_t * 388au_to_ip(struct ip *ip) 389{ 390 token_t *t; 391 u_char *dptr = NULL; 392 393 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(struct ip)); 394 if (t == NULL) 395 return (NULL); 396 397 ADD_U_CHAR(dptr, AUT_IP); 398 /* 399 * XXXRW: Any byte order work needed on the IP header before writing? 400 */ 401 ADD_MEM(dptr, ip, sizeof(struct ip)); 402 403 return (t); 404} 405 406/* 407 * token ID 1 byte 408 * object ID type 1 byte 409 * object ID 4 bytes 410 */ 411token_t * 412au_to_ipc(char type, int id) 413{ 414 token_t *t; 415 u_char *dptr = NULL; 416 417 GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int32_t)); 418 if (t == NULL) 419 return (NULL); 420 421 ADD_U_CHAR(dptr, AUT_IPC); 422 ADD_U_CHAR(dptr, type); 423 ADD_U_INT32(dptr, id); 424 425 return (t); 426} 427 428/* 429 * token ID 1 byte 430 * owner user ID 4 bytes 431 * owner group ID 4 bytes 432 * creator user ID 4 bytes 433 * creator group ID 4 bytes 434 * access mode 4 bytes 435 * slot sequence # 4 bytes 436 * key 4 bytes 437 */ 438token_t * 439au_to_ipc_perm(struct ipc_perm *perm) 440{ 441 token_t *t; 442 u_char *dptr = NULL; 443 u_int16_t pad0 = 0; 444 445 GET_TOKEN_AREA(t, dptr, 12 * sizeof(u_int16_t) + sizeof(u_int32_t)); 446 if (t == NULL) 447 return (NULL); 448 449 ADD_U_CHAR(dptr, AUT_IPC_PERM); 450 451 /* 452 * Darwin defines the sizes for ipc_perm members 453 * as 2 bytes; BSM defines 4 so pad with 0 454 */ 455 ADD_U_INT16(dptr, pad0); 456 ADD_U_INT16(dptr, perm->uid); 457 458 ADD_U_INT16(dptr, pad0); 459 ADD_U_INT16(dptr, perm->gid); 460 461 ADD_U_INT16(dptr, pad0); 462 ADD_U_INT16(dptr, perm->cuid); 463 464 ADD_U_INT16(dptr, pad0); 465 ADD_U_INT16(dptr, perm->cgid); 466 467 ADD_U_INT16(dptr, pad0); 468 ADD_U_INT16(dptr, perm->mode); 469 470 ADD_U_INT16(dptr, pad0); 471 472#ifdef HAVE_IPC_PERM___SEQ 473 ADD_U_INT16(dptr, perm->__seq); 474#else 475 ADD_U_INT16(dptr, perm->seq); 476#endif 477 478#ifdef HAVE_IPC_PERM___KEY 479 ADD_U_INT32(dptr, perm->__key); 480#else 481 ADD_U_INT32(dptr, perm->key); 482#endif 483 484 return (t); 485} 486 487/* 488 * token ID 1 byte 489 * port IP address 2 bytes 490 */ 491token_t * 492au_to_iport(u_int16_t iport) 493{ 494 token_t *t; 495 u_char *dptr = NULL; 496 497 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t)); 498 if (t == NULL) 499 return (NULL); 500 501 ADD_U_CHAR(dptr, AUT_IPORT); 502 ADD_U_INT16(dptr, iport); 503 504 return (t); 505} 506 507/* 508 * token ID 1 byte 509 * size 2 bytes 510 * data size bytes 511 */ 512token_t * 513au_to_opaque(char *data, u_int16_t bytes) 514{ 515 token_t *t; 516 u_char *dptr = NULL; 517 518 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + bytes); 519 if (t == NULL) 520 return (NULL); 521 522 ADD_U_CHAR(dptr, AUT_OPAQUE); 523 ADD_U_INT16(dptr, bytes); 524 ADD_MEM(dptr, data, bytes); 525 526 return (t); 527} 528 529/* 530 * token ID 1 byte 531 * seconds of time 4 bytes 532 * milliseconds of time 4 bytes 533 * file name len 2 bytes 534 * file pathname N bytes + 1 terminating NULL byte 535 */ 536token_t * 537au_to_file(char *file, struct timeval tm) 538{ 539 token_t *t; 540 u_char *dptr = NULL; 541 u_int16_t filelen; 542 u_int32_t timems; 543 544 filelen = strlen(file); 545 filelen += 1; 546 547 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int32_t) + 548 sizeof(u_int16_t) + filelen); 549 if (t == NULL) 550 return (NULL); 551 552 timems = tm.tv_usec/1000; 553 554 ADD_U_CHAR(dptr, AUT_OTHER_FILE32); 555 ADD_U_INT32(dptr, tm.tv_sec); 556 ADD_U_INT32(dptr, timems); /* We need time in ms. */ 557 ADD_U_INT16(dptr, filelen); 558 ADD_STRING(dptr, file, filelen); 559 560 return (t); 561} 562 563/* 564 * token ID 1 byte 565 * text length 2 bytes 566 * text N bytes + 1 terminating NULL byte 567 */ 568token_t * 569au_to_text(char *text) 570{ 571 token_t *t; 572 u_char *dptr = NULL; 573 u_int16_t textlen; 574 575 textlen = strlen(text); 576 textlen += 1; 577 578 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + textlen); 579 if (t == NULL) 580 return (NULL); 581 582 ADD_U_CHAR(dptr, AUT_TEXT); 583 ADD_U_INT16(dptr, textlen); 584 ADD_STRING(dptr, text, textlen); 585 586 return (t); 587} 588 589/* 590 * token ID 1 byte 591 * path length 2 bytes 592 * path N bytes + 1 terminating NULL byte 593 */ 594token_t * 595au_to_path(char *text) 596{ 597 token_t *t; 598 u_char *dptr = NULL; 599 u_int16_t textlen; 600 601 textlen = strlen(text); 602 textlen += 1; 603 604 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + textlen); 605 if (t == NULL) 606 return (NULL); 607 608 ADD_U_CHAR(dptr, AUT_PATH); 609 ADD_U_INT16(dptr, textlen); 610 ADD_STRING(dptr, text, textlen); 611 612 return (t); 613} 614 615/* 616 * token ID 1 byte 617 * audit ID 4 bytes 618 * effective user ID 4 bytes 619 * effective group ID 4 bytes 620 * real user ID 4 bytes 621 * real group ID 4 bytes 622 * process ID 4 bytes 623 * session ID 4 bytes 624 * terminal ID 625 * port ID 4 bytes/8 bytes (32-bit/64-bit value) 626 * machine address 4 bytes 627 */ 628token_t * 629au_to_process32(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid, 630 pid_t pid, au_asid_t sid, au_tid_t *tid) 631{ 632 token_t *t; 633 u_char *dptr = NULL; 634 635 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 9 * sizeof(u_int32_t)); 636 if (t == NULL) 637 return (NULL); 638 639 ADD_U_CHAR(dptr, AUT_PROCESS32); 640 ADD_U_INT32(dptr, auid); 641 ADD_U_INT32(dptr, euid); 642 ADD_U_INT32(dptr, egid); 643 ADD_U_INT32(dptr, ruid); 644 ADD_U_INT32(dptr, rgid); 645 ADD_U_INT32(dptr, pid); 646 ADD_U_INT32(dptr, sid); 647 ADD_U_INT32(dptr, tid->port); 648 ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t)); 649 650 return (t); 651} 652 653token_t * 654au_to_process64(__unused au_id_t auid, __unused uid_t euid, 655 __unused gid_t egid, __unused uid_t ruid, __unused gid_t rgid, 656 __unused pid_t pid, __unused au_asid_t sid, __unused au_tid_t *tid) 657{ 658 659 errno = ENOTSUP; 660 return (NULL); 661} 662 663token_t * 664au_to_process(__unused au_id_t auid, __unused uid_t euid, 665 __unused gid_t egid, __unused uid_t ruid, __unused gid_t rgid, 666 __unused pid_t pid, __unused au_asid_t sid, __unused au_tid_t *tid) 667{ 668 669 return (au_to_process32(auid, euid, egid, ruid, rgid, pid, sid, 670 tid)); 671} 672 673/* 674 * token ID 1 byte 675 * audit ID 4 bytes 676 * effective user ID 4 bytes 677 * effective group ID 4 bytes 678 * real user ID 4 bytes 679 * real group ID 4 bytes 680 * process ID 4 bytes 681 * session ID 4 bytes 682 * terminal ID 683 * port ID 4 bytes/8 bytes (32-bit/64-bit value) 684 * address type-len 4 bytes 685 * machine address 16 bytes 686 */ 687token_t * 688au_to_process32_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, 689 gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid) 690{ 691 token_t *t; 692 u_char *dptr = NULL; 693 694 if (tid->at_type == AU_IPv4) 695 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 696 10 * sizeof(u_int32_t)); 697 else if (tid->at_type == AU_IPv6) 698 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 699 13 * sizeof(u_int32_t)); 700 else { 701 errno = EINVAL; 702 return (NULL); 703 } 704 if (t == NULL) 705 return (NULL); 706 707 ADD_U_CHAR(dptr, AUT_PROCESS32_EX); 708 ADD_U_INT32(dptr, auid); 709 ADD_U_INT32(dptr, euid); 710 ADD_U_INT32(dptr, egid); 711 ADD_U_INT32(dptr, ruid); 712 ADD_U_INT32(dptr, rgid); 713 ADD_U_INT32(dptr, pid); 714 ADD_U_INT32(dptr, sid); 715 ADD_U_INT32(dptr, tid->at_port); 716 ADD_U_INT32(dptr, tid->at_type); 717 ADD_U_INT32(dptr, tid->at_addr[0]); 718 if (tid->at_type == AU_IPv6) { 719 ADD_U_INT32(dptr, tid->at_addr[1]); 720 ADD_U_INT32(dptr, tid->at_addr[2]); 721 ADD_U_INT32(dptr, tid->at_addr[3]); 722 } 723 724 return (t); 725} 726 727token_t * 728au_to_process64_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, 729 gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid) 730{ 731 732 errno = ENOTSUP; 733 return (NULL); 734} 735 736token_t * 737au_to_process_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, 738 gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid) 739{ 740 741 return (au_to_process32_ex(auid, euid, egid, ruid, rgid, pid, sid, 742 tid)); 743} 744 745/* 746 * token ID 1 byte 747 * error status 1 byte 748 * return value 4 bytes/8 bytes (32-bit/64-bit value) 749 */ 750token_t * 751au_to_return32(char status, u_int32_t ret) 752{ 753 token_t *t; 754 u_char *dptr = NULL; 755 756 GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int32_t)); 757 if (t == NULL) 758 return (NULL); 759 760 ADD_U_CHAR(dptr, AUT_RETURN32); 761 ADD_U_CHAR(dptr, status); 762 ADD_U_INT32(dptr, ret); 763 764 return (t); 765} 766 767token_t * 768au_to_return64(char status, u_int64_t ret) 769{ 770 token_t *t; 771 u_char *dptr = NULL; 772 773 GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int64_t)); 774 if (t == NULL) 775 return (NULL); 776 777 ADD_U_CHAR(dptr, AUT_RETURN64); 778 ADD_U_CHAR(dptr, status); 779 ADD_U_INT64(dptr, ret); 780 781 return (t); 782} 783 784token_t * 785au_to_return(char status, u_int32_t ret) 786{ 787 788 return (au_to_return32(status, ret)); 789} 790 791/* 792 * token ID 1 byte 793 * sequence number 4 bytes 794 */ 795token_t * 796au_to_seq(long audit_count) 797{ 798 token_t *t; 799 u_char *dptr = NULL; 800 801 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t)); 802 if (t == NULL) 803 return (NULL); 804 805 ADD_U_CHAR(dptr, AUT_SEQ); 806 ADD_U_INT32(dptr, audit_count); 807 808 return (t); 809} 810 811/* 812 * token ID 1 byte 813 * socket family 2 bytes 814 * path 104 bytes 815 */ 816token_t * 817au_to_sock_unix(struct sockaddr_un *so) 818{ 819 token_t *t; 820 u_char *dptr; 821 822 GET_TOKEN_AREA(t, dptr, 3 * sizeof(u_char) + strlen(so->sun_path) + 1); 823 if (t == NULL) 824 return (NULL); 825 826 ADD_U_CHAR(dptr, AU_SOCK_UNIX_TOKEN); 827 /* BSM token has two bytes for family */ 828 ADD_U_CHAR(dptr, 0); 829 ADD_U_CHAR(dptr, so->sun_family); 830 ADD_STRING(dptr, so->sun_path, strlen(so->sun_path) + 1); 831 832 return (t); 833} 834 835/* 836 * token ID 1 byte 837 * socket family 2 bytes 838 * local port 2 bytes 839 * socket address 4 bytes 840 */ 841token_t * 842au_to_sock_inet32(struct sockaddr_in *so) 843{ 844 token_t *t; 845 u_char *dptr = NULL; 846 uint16_t family; 847 848 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(uint16_t) + 849 sizeof(uint32_t)); 850 if (t == NULL) 851 return (NULL); 852 853 ADD_U_CHAR(dptr, AUT_SOCKINET32); 854 /* 855 * BSM defines the family field as 16 bits, but many operating 856 * systems have an 8-bit sin_family field. Extend to 16 bits before 857 * writing into the token. Assume that both the port and the address 858 * in the sockaddr_in are already in network byte order, but family 859 * is in local byte order. 860 * 861 * XXXRW: Should a name space conversion be taking place on the value 862 * of sin_family? 863 */ 864 family = so->sin_family; 865 ADD_U_INT16(dptr, family); 866 ADD_MEM(dptr, &so->sin_port, sizeof(uint16_t)); 867 ADD_MEM(dptr, &so->sin_addr.s_addr, sizeof(uint32_t)); 868 869 return (t); 870 871} 872 873token_t * 874au_to_sock_inet128(struct sockaddr_in6 *so) 875{ 876 token_t *t; 877 u_char *dptr = NULL; 878 879 GET_TOKEN_AREA(t, dptr, 3 * sizeof(u_char) + sizeof(u_int16_t) + 880 4 * sizeof(u_int32_t)); 881 if (t == NULL) 882 return (NULL); 883 884 ADD_U_CHAR(dptr, AUT_SOCKINET128); 885 /* 886 * In Darwin, sin6_family is one octet, but BSM defines the token 887 * to store two. So we copy in a 0 first. 888 */ 889 ADD_U_CHAR(dptr, 0); 890 ADD_U_CHAR(dptr, so->sin6_family); 891 892 ADD_U_INT16(dptr, so->sin6_port); 893 ADD_MEM(dptr, &so->sin6_addr, 4 * sizeof(uint32_t)); 894 895 return (t); 896 897} 898 899token_t * 900au_to_sock_inet(struct sockaddr_in *so) 901{ 902 903 return (au_to_sock_inet32(so)); 904} 905 906/* 907 * token ID 1 byte 908 * audit ID 4 bytes 909 * effective user ID 4 bytes 910 * effective group ID 4 bytes 911 * real user ID 4 bytes 912 * real group ID 4 bytes 913 * process ID 4 bytes 914 * session ID 4 bytes 915 * terminal ID 916 * port ID 4 bytes/8 bytes (32-bit/64-bit value) 917 * machine address 4 bytes 918 */ 919token_t * 920au_to_subject32(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid, 921 pid_t pid, au_asid_t sid, au_tid_t *tid) 922{ 923 token_t *t; 924 u_char *dptr = NULL; 925 926 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 9 * sizeof(u_int32_t)); 927 if (t == NULL) 928 return (NULL); 929 930 ADD_U_CHAR(dptr, AUT_SUBJECT32); 931 ADD_U_INT32(dptr, auid); 932 ADD_U_INT32(dptr, euid); 933 ADD_U_INT32(dptr, egid); 934 ADD_U_INT32(dptr, ruid); 935 ADD_U_INT32(dptr, rgid); 936 ADD_U_INT32(dptr, pid); 937 ADD_U_INT32(dptr, sid); 938 ADD_U_INT32(dptr, tid->port); 939 ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t)); 940 941 return (t); 942} 943 944token_t * 945au_to_subject64(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid, 946 pid_t pid, au_asid_t sid, au_tid_t *tid) 947{ 948 949 errno = ENOTSUP; 950 return (NULL); 951} 952 953token_t * 954au_to_subject(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid, 955 pid_t pid, au_asid_t sid, au_tid_t *tid) 956{ 957 958 return (au_to_subject32(auid, euid, egid, ruid, rgid, pid, sid, 959 tid)); 960} 961 962/* 963 * token ID 1 byte 964 * audit ID 4 bytes 965 * effective user ID 4 bytes 966 * effective group ID 4 bytes 967 * real user ID 4 bytes 968 * real group ID 4 bytes 969 * process ID 4 bytes 970 * session ID 4 bytes 971 * terminal ID 972 * port ID 4 bytes/8 bytes (32-bit/64-bit value) 973 * address type/length 4 bytes 974 * machine address 16 bytes 975 */ 976token_t * 977au_to_subject32_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, 978 gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid) 979{ 980 token_t *t; 981 u_char *dptr = NULL; 982 983 if (tid->at_type == AU_IPv4) 984 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 10 * 985 sizeof(u_int32_t)); 986 else if (tid->at_type == AU_IPv6) 987 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 13 * 988 sizeof(u_int32_t)); 989 else { 990 errno = EINVAL; 991 return (NULL); 992 } 993 if (t == NULL) 994 return (NULL); 995 996 ADD_U_CHAR(dptr, AUT_SUBJECT32_EX); 997 ADD_U_INT32(dptr, auid); 998 ADD_U_INT32(dptr, euid); 999 ADD_U_INT32(dptr, egid); 1000 ADD_U_INT32(dptr, ruid); 1001 ADD_U_INT32(dptr, rgid); 1002 ADD_U_INT32(dptr, pid); 1003 ADD_U_INT32(dptr, sid); 1004 ADD_U_INT32(dptr, tid->at_port); 1005 ADD_U_INT32(dptr, tid->at_type); 1006 ADD_U_INT32(dptr, tid->at_addr[0]); 1007 if (tid->at_type == AU_IPv6) { 1008 ADD_U_INT32(dptr, tid->at_addr[1]); 1009 ADD_U_INT32(dptr, tid->at_addr[2]); 1010 ADD_U_INT32(dptr, tid->at_addr[3]); 1011 } 1012 1013 return (t); 1014} 1015 1016token_t * 1017au_to_subject64_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, 1018 gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid) 1019{ 1020 1021 errno = ENOTSUP; 1022 return (NULL); 1023} 1024 1025token_t * 1026au_to_subject_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, 1027 gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid) 1028{ 1029 1030 return (au_to_subject32_ex(auid, euid, egid, ruid, rgid, pid, sid, 1031 tid)); 1032} 1033 1034#if !defined(_KERNEL) && !defined(KERNEL) && defined(HAVE_AUDIT_SYSCALLS) 1035/* 1036 * Collects audit information for the current process 1037 * and creates a subject token from it 1038 */ 1039token_t * 1040au_to_me(void) 1041{ 1042 auditinfo_t auinfo; 1043 1044 if (getaudit(&auinfo) != 0) 1045 return (NULL); 1046 1047 return (au_to_subject32(auinfo.ai_auid, geteuid(), getegid(), 1048 getuid(), getgid(), getpid(), auinfo.ai_asid, &auinfo.ai_termid)); 1049} 1050#endif 1051 1052/* 1053 * token ID 1 byte 1054 * count 4 bytes 1055 * text count null-terminated strings 1056 */ 1057token_t * 1058au_to_exec_args(char **argv) 1059{ 1060 token_t *t; 1061 u_char *dptr = NULL; 1062 const char *nextarg; 1063 int i, count = 0; 1064 size_t totlen = 0; 1065 1066 nextarg = *argv; 1067 1068 while (nextarg != NULL) { 1069 int nextlen; 1070 1071 nextlen = strlen(nextarg); 1072 totlen += nextlen + 1; 1073 count++; 1074 nextarg = *(argv + count); 1075 } 1076 1077 totlen += count * sizeof(char); /* nul terminations. */ 1078 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) + totlen); 1079 if (t == NULL) 1080 return (NULL); 1081 1082 ADD_U_CHAR(dptr, AUT_EXEC_ARGS); 1083 ADD_U_INT32(dptr, count); 1084 1085 for (i = 0; i < count; i++) { 1086 nextarg = *(argv + i); 1087 ADD_MEM(dptr, nextarg, strlen(nextarg) + 1); 1088 } 1089 1090 return (t); 1091} 1092 1093/* 1094 * token ID 1 byte 1095 * count 4 bytes 1096 * text count null-terminated strings 1097 */ 1098token_t * 1099au_to_exec_env(char **envp) 1100{ 1101 token_t *t; 1102 u_char *dptr = NULL; 1103 int i, count = 0; 1104 size_t totlen = 0; 1105 const char *nextenv; 1106 1107 nextenv = *envp; 1108 1109 while (nextenv != NULL) { 1110 int nextlen; 1111 1112 nextlen = strlen(nextenv); 1113 totlen += nextlen + 1; 1114 count++; 1115 nextenv = *(envp + count); 1116 } 1117 1118 totlen += sizeof(char) * count; 1119 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) + totlen); 1120 if (t == NULL) 1121 return (NULL); 1122 1123 ADD_U_CHAR(dptr, AUT_EXEC_ENV); 1124 ADD_U_INT32(dptr, count); 1125 1126 for (i = 0; i < count; i++) { 1127 nextenv = *(envp + i); 1128 ADD_MEM(dptr, nextenv, strlen(nextenv) + 1); 1129 } 1130 1131 return (t); 1132} 1133 1134/* 1135 * token ID 1 byte 1136 * record byte count 4 bytes 1137 * version # 1 byte [2] 1138 * event type 2 bytes 1139 * event modifier 2 bytes 1140 * seconds of time 4 bytes/8 bytes (32-bit/64-bit value) 1141 * milliseconds of time 4 bytes/8 bytes (32-bit/64-bit value) 1142 */ 1143token_t * 1144au_to_header32_tm(int rec_size, au_event_t e_type, au_emod_t e_mod, 1145 struct timeval tm) 1146{ 1147 token_t *t; 1148 u_char *dptr = NULL; 1149 u_int32_t timems; 1150 1151 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) + 1152 sizeof(u_char) + 2 * sizeof(u_int16_t) + 2 * sizeof(u_int32_t)); 1153 if (t == NULL) 1154 return (NULL); 1155 1156 ADD_U_CHAR(dptr, AUT_HEADER32); 1157 ADD_U_INT32(dptr, rec_size); 1158 ADD_U_CHAR(dptr, AUDIT_HEADER_VERSION_OPENBSM); 1159 ADD_U_INT16(dptr, e_type); 1160 ADD_U_INT16(dptr, e_mod); 1161 1162 timems = tm.tv_usec/1000; 1163 /* Add the timestamp */ 1164 ADD_U_INT32(dptr, tm.tv_sec); 1165 ADD_U_INT32(dptr, timems); /* We need time in ms. */ 1166 1167 return (t); 1168} 1169 1170#if !defined(KERNEL) && !defined(_KERNEL) 1171token_t * 1172au_to_header32(int rec_size, au_event_t e_type, au_emod_t e_mod) 1173{ 1174 struct timeval tm; 1175 1176 if (gettimeofday(&tm, NULL) == -1) 1177 return (NULL); 1178 return (au_to_header32_tm(rec_size, e_type, e_mod, tm)); 1179} 1180 1181token_t * 1182au_to_header64(__unused int rec_size, __unused au_event_t e_type, 1183 __unused au_emod_t e_mod) 1184{ 1185 1186 errno = ENOTSUP; 1187 return (NULL); 1188} 1189 1190token_t * 1191au_to_header(int rec_size, au_event_t e_type, au_emod_t e_mod) 1192{ 1193 1194 return (au_to_header32(rec_size, e_type, e_mod)); 1195} 1196#endif 1197 1198/* 1199 * token ID 1 byte 1200 * trailer magic number 2 bytes 1201 * record byte count 4 bytes 1202 */ 1203token_t * 1204au_to_trailer(int rec_size) 1205{ 1206 token_t *t; 1207 u_char *dptr = NULL; 1208 u_int16_t magic = TRAILER_PAD_MAGIC; 1209 1210 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + 1211 sizeof(u_int32_t)); 1212 if (t == NULL) 1213 return (NULL); 1214 1215 ADD_U_CHAR(dptr, AUT_TRAILER); 1216 ADD_U_INT16(dptr, magic); 1217 ADD_U_INT32(dptr, rec_size); 1218 1219 return (t); 1220} 1221