bsm_token.c revision 186647
1/*- 2 * Copyright (c) 2004-2008 Apple 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 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#85 $ 34 */ 35 36#include <sys/types.h> 37 38#include <config/config.h> 39#if defined(HAVE_SYS_ENDIAN_H) && defined(HAVE_BE32ENC) 40#include <sys/endian.h> 41#else /* !HAVE_SYS_ENDIAN_H || !HAVE_BE32ENC */ 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 || !HAVE_BE32ENC */ 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 75#include <bsm/audit_internal.h> 76#include <bsm/libbsm.h> 77 78#define GET_TOKEN_AREA(t, dptr, length) do { \ 79 (t) = malloc(sizeof(token_t)); \ 80 if ((t) != NULL) { \ 81 (t)->len = (length); \ 82 (dptr) = (t->t_data) = malloc((length) * sizeof(u_char)); \ 83 if ((dptr) == NULL) { \ 84 free(t); \ 85 (t) = NULL; \ 86 } else \ 87 memset((dptr), 0, (length)); \ 88 } else \ 89 (dptr) = NULL; \ 90 assert((t) == NULL || (dptr) != NULL); \ 91} while (0) 92 93/* 94 * token ID 1 byte 95 * argument # 1 byte 96 * argument value 4 bytes/8 bytes (32-bit/64-bit value) 97 * text length 2 bytes 98 * text N bytes + 1 terminating NULL byte 99 */ 100token_t * 101au_to_arg32(char n, const char *text, u_int32_t v) 102{ 103 token_t *t; 104 u_char *dptr = NULL; 105 u_int16_t textlen; 106 107 textlen = strlen(text); 108 textlen += 1; 109 110 GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int32_t) + 111 sizeof(u_int16_t) + textlen); 112 if (t == NULL) 113 return (NULL); 114 115 ADD_U_CHAR(dptr, AUT_ARG32); 116 ADD_U_CHAR(dptr, n); 117 ADD_U_INT32(dptr, v); 118 ADD_U_INT16(dptr, textlen); 119 ADD_STRING(dptr, text, textlen); 120 121 return (t); 122} 123 124token_t * 125au_to_arg64(char n, const char *text, u_int64_t v) 126{ 127 token_t *t; 128 u_char *dptr = NULL; 129 u_int16_t textlen; 130 131 textlen = strlen(text); 132 textlen += 1; 133 134 GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int64_t) + 135 sizeof(u_int16_t) + textlen); 136 if (t == NULL) 137 return (NULL); 138 139 ADD_U_CHAR(dptr, AUT_ARG64); 140 ADD_U_CHAR(dptr, n); 141 ADD_U_INT64(dptr, v); 142 ADD_U_INT16(dptr, textlen); 143 ADD_STRING(dptr, text, textlen); 144 145 return (t); 146} 147 148token_t * 149au_to_arg(char n, const char *text, u_int32_t v) 150{ 151 152 return (au_to_arg32(n, text, v)); 153} 154 155#if defined(_KERNEL) || defined(KERNEL) 156/* 157 * token ID 1 byte 158 * file access mode 4 bytes 159 * owner user ID 4 bytes 160 * owner group ID 4 bytes 161 * file system ID 4 bytes 162 * node ID 8 bytes 163 * device 4 bytes/8 bytes (32-bit/64-bit) 164 */ 165token_t * 166au_to_attr32(struct vnode_au_info *vni) 167{ 168 token_t *t; 169 u_char *dptr = NULL; 170 u_int16_t pad0_16 = 0; 171 u_int16_t pad0_32 = 0; 172 173 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int16_t) + 174 3 * sizeof(u_int32_t) + sizeof(u_int64_t) + sizeof(u_int32_t)); 175 if (t == NULL) 176 return (NULL); 177 178 ADD_U_CHAR(dptr, AUT_ATTR32); 179 180 /* 181 * BSD defines the size for the file mode as 2 bytes; BSM defines 4 182 * so pad with 0. 183 * 184 * XXXRW: Possibly should be conditionally compiled. 185 * 186 * XXXRW: Should any conversions take place on the mode? 187 */ 188 ADD_U_INT16(dptr, pad0_16); 189 ADD_U_INT16(dptr, vni->vn_mode); 190 191 ADD_U_INT32(dptr, vni->vn_uid); 192 ADD_U_INT32(dptr, vni->vn_gid); 193 ADD_U_INT32(dptr, vni->vn_fsid); 194 195 /* 196 * Some systems use 32-bit file ID's, others use 64-bit file IDs. 197 * Attempt to handle both, and let the compiler sort it out. If we 198 * could pick this out at compile-time, it would be better, so as to 199 * avoid the else case below. 200 */ 201 if (sizeof(vni->vn_fileid) == sizeof(uint32_t)) { 202 ADD_U_INT32(dptr, pad0_32); 203 ADD_U_INT32(dptr, vni->vn_fileid); 204 } else if (sizeof(vni->vn_fileid) == sizeof(uint64_t)) 205 ADD_U_INT64(dptr, vni->vn_fileid); 206 else 207 ADD_U_INT64(dptr, 0LL); 208 209 ADD_U_INT32(dptr, vni->vn_dev); 210 211 return (t); 212} 213 214token_t * 215au_to_attr64(struct vnode_au_info *vni) 216{ 217 token_t *t; 218 u_char *dptr = NULL; 219 u_int16_t pad0_16 = 0; 220 u_int16_t pad0_32 = 0; 221 222 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int16_t) + 223 3 * sizeof(u_int32_t) + sizeof(u_int64_t) * 2); 224 if (t == NULL) 225 return (NULL); 226 227 ADD_U_CHAR(dptr, AUT_ATTR64); 228 229 /* 230 * BSD defines the size for the file mode as 2 bytes; BSM defines 4 231 * so pad with 0. 232 * 233 * XXXRW: Possibly should be conditionally compiled. 234 * 235 * XXXRW: Should any conversions take place on the mode? 236 */ 237 ADD_U_INT16(dptr, pad0_16); 238 ADD_U_INT16(dptr, vni->vn_mode); 239 240 ADD_U_INT32(dptr, vni->vn_uid); 241 ADD_U_INT32(dptr, vni->vn_gid); 242 ADD_U_INT32(dptr, vni->vn_fsid); 243 244 /* 245 * Some systems use 32-bit file ID's, other's use 64-bit file IDs. 246 * Attempt to handle both, and let the compiler sort it out. If we 247 * could pick this out at compile-time, it would be better, so as to 248 * avoid the else case below. 249 */ 250 if (sizeof(vni->vn_fileid) == sizeof(uint32_t)) { 251 ADD_U_INT32(dptr, pad0_32); 252 ADD_U_INT32(dptr, vni->vn_fileid); 253 } else if (sizeof(vni->vn_fileid) == sizeof(uint64_t)) 254 ADD_U_INT64(dptr, vni->vn_fileid); 255 else 256 ADD_U_INT64(dptr, 0LL); 257 258 ADD_U_INT64(dptr, vni->vn_dev); 259 260 return (t); 261} 262 263token_t * 264au_to_attr(struct vnode_au_info *vni) 265{ 266 267 return (au_to_attr32(vni)); 268} 269#endif /* !(defined(_KERNEL) || defined(KERNEL) */ 270 271/* 272 * token ID 1 byte 273 * how to print 1 byte 274 * basic unit 1 byte 275 * unit count 1 byte 276 * data items (depends on basic unit) 277 */ 278token_t * 279au_to_data(char unit_print, char unit_type, char unit_count, const char *p) 280{ 281 token_t *t; 282 u_char *dptr = NULL; 283 size_t datasize, totdata; 284 285 /* Determine the size of the basic unit. */ 286 switch (unit_type) { 287 case AUR_BYTE: 288 /* case AUR_CHAR: */ 289 datasize = AUR_BYTE_SIZE; 290 break; 291 292 case AUR_SHORT: 293 datasize = AUR_SHORT_SIZE; 294 break; 295 296 case AUR_INT32: 297 /* case AUR_INT: */ 298 datasize = AUR_INT32_SIZE; 299 break; 300 301 case AUR_INT64: 302 datasize = AUR_INT64_SIZE; 303 break; 304 305 default: 306 errno = EINVAL; 307 return (NULL); 308 } 309 310 totdata = datasize * unit_count; 311 312 GET_TOKEN_AREA(t, dptr, 4 * sizeof(u_char) + totdata); 313 if (t == NULL) 314 return (NULL); 315 316 /* 317 * XXXRW: We should be byte-swapping each data item for multi-byte 318 * types. 319 */ 320 ADD_U_CHAR(dptr, AUT_DATA); 321 ADD_U_CHAR(dptr, unit_print); 322 ADD_U_CHAR(dptr, unit_type); 323 ADD_U_CHAR(dptr, unit_count); 324 ADD_MEM(dptr, p, totdata); 325 326 return (t); 327} 328 329 330/* 331 * token ID 1 byte 332 * status 4 bytes 333 * return value 4 bytes 334 */ 335token_t * 336au_to_exit(int retval, int err) 337{ 338 token_t *t; 339 u_char *dptr = NULL; 340 341 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int32_t)); 342 if (t == NULL) 343 return (NULL); 344 345 ADD_U_CHAR(dptr, AUT_EXIT); 346 ADD_U_INT32(dptr, err); 347 ADD_U_INT32(dptr, retval); 348 349 return (t); 350} 351 352/* 353 */ 354token_t * 355au_to_groups(int *groups) 356{ 357 358 return (au_to_newgroups(AUDIT_MAX_GROUPS, (gid_t *)groups)); 359} 360 361/* 362 * token ID 1 byte 363 * number groups 2 bytes 364 * group list count * 4 bytes 365 */ 366token_t * 367au_to_newgroups(u_int16_t n, gid_t *groups) 368{ 369 token_t *t; 370 u_char *dptr = NULL; 371 int i; 372 373 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + 374 n * sizeof(u_int32_t)); 375 if (t == NULL) 376 return (NULL); 377 378 ADD_U_CHAR(dptr, AUT_NEWGROUPS); 379 ADD_U_INT16(dptr, n); 380 for (i = 0; i < n; i++) 381 ADD_U_INT32(dptr, groups[i]); 382 383 return (t); 384} 385 386/* 387 * token ID 1 byte 388 * internet address 4 bytes 389 */ 390token_t * 391au_to_in_addr(struct in_addr *internet_addr) 392{ 393 token_t *t; 394 u_char *dptr = NULL; 395 396 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(uint32_t)); 397 if (t == NULL) 398 return (NULL); 399 400 ADD_U_CHAR(dptr, AUT_IN_ADDR); 401 ADD_MEM(dptr, &internet_addr->s_addr, sizeof(uint32_t)); 402 403 return (t); 404} 405 406/* 407 * token ID 1 byte 408 * address type/length 4 bytes 409 * address 16 bytes 410 */ 411token_t * 412au_to_in_addr_ex(struct in6_addr *internet_addr) 413{ 414 token_t *t; 415 u_char *dptr = NULL; 416 u_int32_t type = AU_IPv6; 417 418 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 5 * sizeof(uint32_t)); 419 if (t == NULL) 420 return (NULL); 421 422 ADD_U_CHAR(dptr, AUT_IN_ADDR_EX); 423 ADD_U_INT32(dptr, type); 424 ADD_MEM(dptr, internet_addr, 4 * sizeof(uint32_t)); 425 426 return (t); 427} 428 429/* 430 * token ID 1 byte 431 * ip header 20 bytes 432 * 433 * The IP header should be submitted in network byte order. 434 */ 435token_t * 436au_to_ip(struct ip *ip) 437{ 438 token_t *t; 439 u_char *dptr = NULL; 440 441 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(struct ip)); 442 if (t == NULL) 443 return (NULL); 444 445 ADD_U_CHAR(dptr, AUT_IP); 446 ADD_MEM(dptr, ip, sizeof(struct ip)); 447 448 return (t); 449} 450 451/* 452 * token ID 1 byte 453 * object ID type 1 byte 454 * object ID 4 bytes 455 */ 456token_t * 457au_to_ipc(char type, int id) 458{ 459 token_t *t; 460 u_char *dptr = NULL; 461 462 GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int32_t)); 463 if (t == NULL) 464 return (NULL); 465 466 ADD_U_CHAR(dptr, AUT_IPC); 467 ADD_U_CHAR(dptr, type); 468 ADD_U_INT32(dptr, id); 469 470 return (t); 471} 472 473/* 474 * token ID 1 byte 475 * owner user ID 4 bytes 476 * owner group ID 4 bytes 477 * creator user ID 4 bytes 478 * creator group ID 4 bytes 479 * access mode 4 bytes 480 * slot sequence # 4 bytes 481 * key 4 bytes 482 */ 483token_t * 484au_to_ipc_perm(struct ipc_perm *perm) 485{ 486 token_t *t; 487 u_char *dptr = NULL; 488 u_int16_t pad0 = 0; 489 490 GET_TOKEN_AREA(t, dptr, 12 * sizeof(u_int16_t) + sizeof(u_int32_t)); 491 if (t == NULL) 492 return (NULL); 493 494 ADD_U_CHAR(dptr, AUT_IPC_PERM); 495 496 /* 497 * Systems vary significantly in what types they use in struct 498 * ipc_perm; at least a few still use 16-bit uid's and gid's, so 499 * allow for that, as BSM define 32-bit values here. 500 * Some systems define the sizes for ipc_perm members as 2 bytes; 501 * BSM defines 4 so pad with 0. 502 * 503 * XXXRW: Possibly shoulid be conditionally compiled, and more cases 504 * need to be handled. 505 */ 506 if (sizeof(perm->uid) != sizeof(u_int32_t)) { 507 ADD_U_INT16(dptr, pad0); 508 ADD_U_INT16(dptr, perm->uid); 509 ADD_U_INT16(dptr, pad0); 510 ADD_U_INT16(dptr, perm->gid); 511 ADD_U_INT16(dptr, pad0); 512 ADD_U_INT16(dptr, perm->cuid); 513 ADD_U_INT16(dptr, pad0); 514 ADD_U_INT16(dptr, perm->cgid); 515 } else { 516 ADD_U_INT32(dptr, perm->uid); 517 ADD_U_INT32(dptr, perm->gid); 518 ADD_U_INT32(dptr, perm->cuid); 519 ADD_U_INT32(dptr, perm->cgid); 520 } 521 522 ADD_U_INT16(dptr, pad0); 523 ADD_U_INT16(dptr, perm->mode); 524 525 ADD_U_INT16(dptr, pad0); 526 527#ifdef HAVE_IPC_PERM___SEQ 528 ADD_U_INT16(dptr, perm->__seq); 529#else /* HAVE_IPC_PERM___SEQ */ 530#ifdef HAVE_IPC_PERM__SEQ 531 ADD_U_INT16(dptr, perm->_seq); 532#else /* HAVE_IPC_PERM__SEQ */ 533 ADD_U_INT16(dptr, perm->seq); 534#endif /* HAVE_IPC_PERM__SEQ */ 535#endif /* HAVE_IPC_PERM___SEQ */ 536 537#ifdef HAVE_IPC_PERM___KEY 538 ADD_U_INT32(dptr, perm->__key); 539#else /* HAVE_IPC_PERM___KEY */ 540#ifdef HAVE_IPC_PERM__KEY 541 ADD_U_INT32(dptr, perm->_key); 542#else /* HAVE_IPC_PERM__KEY */ 543 ADD_U_INT32(dptr, perm->key); 544#endif /* HAVE_IPC_PERM__KEY */ 545#endif /* HAVE_IPC_PERM___KEY */ 546 547 return (t); 548} 549 550/* 551 * token ID 1 byte 552 * port IP address 2 bytes 553 */ 554token_t * 555au_to_iport(u_int16_t iport) 556{ 557 token_t *t; 558 u_char *dptr = NULL; 559 560 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t)); 561 if (t == NULL) 562 return (NULL); 563 564 ADD_U_CHAR(dptr, AUT_IPORT); 565 ADD_U_INT16(dptr, iport); 566 567 return (t); 568} 569 570/* 571 * token ID 1 byte 572 * size 2 bytes 573 * data size bytes 574 */ 575token_t * 576au_to_opaque(const char *data, u_int16_t bytes) 577{ 578 token_t *t; 579 u_char *dptr = NULL; 580 581 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + bytes); 582 if (t == NULL) 583 return (NULL); 584 585 ADD_U_CHAR(dptr, AUT_OPAQUE); 586 ADD_U_INT16(dptr, bytes); 587 ADD_MEM(dptr, data, bytes); 588 589 return (t); 590} 591 592/* 593 * token ID 1 byte 594 * seconds of time 4 bytes 595 * milliseconds of time 4 bytes 596 * file name len 2 bytes 597 * file pathname N bytes + 1 terminating NULL byte 598 */ 599token_t * 600au_to_file(const char *file, struct timeval tm) 601{ 602 token_t *t; 603 u_char *dptr = NULL; 604 u_int16_t filelen; 605 u_int32_t timems; 606 607 filelen = strlen(file); 608 filelen += 1; 609 610 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int32_t) + 611 sizeof(u_int16_t) + filelen); 612 if (t == NULL) 613 return (NULL); 614 615 timems = tm.tv_usec/1000; 616 617 ADD_U_CHAR(dptr, AUT_OTHER_FILE32); 618 ADD_U_INT32(dptr, tm.tv_sec); 619 ADD_U_INT32(dptr, timems); /* We need time in ms. */ 620 ADD_U_INT16(dptr, filelen); 621 ADD_STRING(dptr, file, filelen); 622 623 return (t); 624} 625 626/* 627 * token ID 1 byte 628 * text length 2 bytes 629 * text N bytes + 1 terminating NULL byte 630 */ 631token_t * 632au_to_text(const char *text) 633{ 634 token_t *t; 635 u_char *dptr = NULL; 636 u_int16_t textlen; 637 638 textlen = strlen(text); 639 textlen += 1; 640 641 /* XXXRW: Should validate length against token size limit. */ 642 643 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + textlen); 644 if (t == NULL) 645 return (NULL); 646 647 ADD_U_CHAR(dptr, AUT_TEXT); 648 ADD_U_INT16(dptr, textlen); 649 ADD_STRING(dptr, text, textlen); 650 651 return (t); 652} 653 654/* 655 * token ID 1 byte 656 * path length 2 bytes 657 * path N bytes + 1 terminating NULL byte 658 */ 659token_t * 660au_to_path(const char *text) 661{ 662 token_t *t; 663 u_char *dptr = NULL; 664 u_int16_t textlen; 665 666 textlen = strlen(text); 667 textlen += 1; 668 669 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + textlen); 670 if (t == NULL) 671 return (NULL); 672 673 ADD_U_CHAR(dptr, AUT_PATH); 674 ADD_U_INT16(dptr, textlen); 675 ADD_STRING(dptr, text, textlen); 676 677 return (t); 678} 679 680/* 681 * token ID 1 byte 682 * audit ID 4 bytes 683 * effective user ID 4 bytes 684 * effective group ID 4 bytes 685 * real user ID 4 bytes 686 * real group ID 4 bytes 687 * process ID 4 bytes 688 * session ID 4 bytes 689 * terminal ID 690 * port ID 4 bytes/8 bytes (32-bit/64-bit value) 691 * machine address 4 bytes 692 */ 693token_t * 694au_to_process32(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid, 695 pid_t pid, au_asid_t sid, au_tid_t *tid) 696{ 697 token_t *t; 698 u_char *dptr = NULL; 699 700 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 9 * sizeof(u_int32_t)); 701 if (t == NULL) 702 return (NULL); 703 704 ADD_U_CHAR(dptr, AUT_PROCESS32); 705 ADD_U_INT32(dptr, auid); 706 ADD_U_INT32(dptr, euid); 707 ADD_U_INT32(dptr, egid); 708 ADD_U_INT32(dptr, ruid); 709 ADD_U_INT32(dptr, rgid); 710 ADD_U_INT32(dptr, pid); 711 ADD_U_INT32(dptr, sid); 712 ADD_U_INT32(dptr, tid->port); 713 714 /* 715 * Note: Solaris will write out IPv6 addresses here as a 32-bit 716 * address type and 16 bytes of address, but for IPv4 addresses it 717 * simply writes the 4-byte address directly. We support only IPv4 718 * addresses for process32 tokens. 719 */ 720 ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t)); 721 722 return (t); 723} 724 725token_t * 726au_to_process64(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid, 727 pid_t pid, au_asid_t sid, au_tid_t *tid) 728{ 729 token_t *t; 730 u_char *dptr = NULL; 731 732 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 8 * sizeof(u_int32_t) + 733 sizeof(u_int64_t)); 734 if (t == NULL) 735 return (NULL); 736 737 ADD_U_CHAR(dptr, AUT_PROCESS64); 738 ADD_U_INT32(dptr, auid); 739 ADD_U_INT32(dptr, euid); 740 ADD_U_INT32(dptr, egid); 741 ADD_U_INT32(dptr, ruid); 742 ADD_U_INT32(dptr, rgid); 743 ADD_U_INT32(dptr, pid); 744 ADD_U_INT32(dptr, sid); 745 ADD_U_INT64(dptr, tid->port); 746 747 /* 748 * Note: Solaris will write out IPv6 addresses here as a 32-bit 749 * address type and 16 bytes of address, but for IPv4 addresses it 750 * simply writes the 4-byte address directly. We support only IPv4 751 * addresses for process64 tokens. 752 */ 753 ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t)); 754 755 return (t); 756} 757 758token_t * 759au_to_process(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid, 760 pid_t pid, au_asid_t sid, au_tid_t *tid) 761{ 762 763 return (au_to_process32(auid, euid, egid, ruid, rgid, pid, sid, 764 tid)); 765} 766 767/* 768 * token ID 1 byte 769 * audit ID 4 bytes 770 * effective user ID 4 bytes 771 * effective group ID 4 bytes 772 * real user ID 4 bytes 773 * real group ID 4 bytes 774 * process ID 4 bytes 775 * session ID 4 bytes 776 * terminal ID 777 * port ID 4 bytes/8 bytes (32-bit/64-bit value) 778 * address type-len 4 bytes 779 * machine address 16 bytes 780 */ 781token_t * 782au_to_process32_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, 783 gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid) 784{ 785 token_t *t; 786 u_char *dptr = NULL; 787 788 if (tid->at_type == AU_IPv4) 789 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 790 10 * sizeof(u_int32_t)); 791 else if (tid->at_type == AU_IPv6) 792 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 793 13 * sizeof(u_int32_t)); 794 else { 795 errno = EINVAL; 796 return (NULL); 797 } 798 if (t == NULL) 799 return (NULL); 800 801 ADD_U_CHAR(dptr, AUT_PROCESS32_EX); 802 ADD_U_INT32(dptr, auid); 803 ADD_U_INT32(dptr, euid); 804 ADD_U_INT32(dptr, egid); 805 ADD_U_INT32(dptr, ruid); 806 ADD_U_INT32(dptr, rgid); 807 ADD_U_INT32(dptr, pid); 808 ADD_U_INT32(dptr, sid); 809 ADD_U_INT32(dptr, tid->at_port); 810 ADD_U_INT32(dptr, tid->at_type); 811 ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t)); 812 if (tid->at_type == AU_IPv6) { 813 ADD_MEM(dptr, &tid->at_addr[1], sizeof(u_int32_t)); 814 ADD_MEM(dptr, &tid->at_addr[2], sizeof(u_int32_t)); 815 ADD_MEM(dptr, &tid->at_addr[3], sizeof(u_int32_t)); 816 } 817 818 return (t); 819} 820 821token_t * 822au_to_process64_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, 823 gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid) 824{ 825 token_t *t; 826 u_char *dptr = NULL; 827 828 if (tid->at_type == AU_IPv4) 829 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 830 7 * sizeof(u_int32_t) + sizeof(u_int64_t) + 831 2 * sizeof(u_int32_t)); 832 else if (tid->at_type == AU_IPv6) 833 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 834 7 * sizeof(u_int32_t) + sizeof(u_int64_t) + 835 5 * sizeof(u_int32_t)); 836 else { 837 errno = EINVAL; 838 return (NULL); 839 } 840 if (t == NULL) 841 return (NULL); 842 843 ADD_U_CHAR(dptr, AUT_PROCESS64_EX); 844 ADD_U_INT32(dptr, auid); 845 ADD_U_INT32(dptr, euid); 846 ADD_U_INT32(dptr, egid); 847 ADD_U_INT32(dptr, ruid); 848 ADD_U_INT32(dptr, rgid); 849 ADD_U_INT32(dptr, pid); 850 ADD_U_INT32(dptr, sid); 851 ADD_U_INT64(dptr, tid->at_port); 852 ADD_U_INT32(dptr, tid->at_type); 853 ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t)); 854 if (tid->at_type == AU_IPv6) { 855 ADD_MEM(dptr, &tid->at_addr[1], sizeof(u_int32_t)); 856 ADD_MEM(dptr, &tid->at_addr[2], sizeof(u_int32_t)); 857 ADD_MEM(dptr, &tid->at_addr[3], sizeof(u_int32_t)); 858 } 859 860 return (t); 861} 862 863token_t * 864au_to_process_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, 865 gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid) 866{ 867 868 return (au_to_process32_ex(auid, euid, egid, ruid, rgid, pid, sid, 869 tid)); 870} 871 872/* 873 * token ID 1 byte 874 * error status 1 byte 875 * return value 4 bytes/8 bytes (32-bit/64-bit value) 876 */ 877token_t * 878au_to_return32(char status, u_int32_t ret) 879{ 880 token_t *t; 881 u_char *dptr = NULL; 882 883 GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int32_t)); 884 if (t == NULL) 885 return (NULL); 886 887 ADD_U_CHAR(dptr, AUT_RETURN32); 888 ADD_U_CHAR(dptr, status); 889 ADD_U_INT32(dptr, ret); 890 891 return (t); 892} 893 894token_t * 895au_to_return64(char status, u_int64_t ret) 896{ 897 token_t *t; 898 u_char *dptr = NULL; 899 900 GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int64_t)); 901 if (t == NULL) 902 return (NULL); 903 904 ADD_U_CHAR(dptr, AUT_RETURN64); 905 ADD_U_CHAR(dptr, status); 906 ADD_U_INT64(dptr, ret); 907 908 return (t); 909} 910 911token_t * 912au_to_return(char status, u_int32_t ret) 913{ 914 915 return (au_to_return32(status, ret)); 916} 917 918/* 919 * token ID 1 byte 920 * sequence number 4 bytes 921 */ 922token_t * 923au_to_seq(long audit_count) 924{ 925 token_t *t; 926 u_char *dptr = NULL; 927 928 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t)); 929 if (t == NULL) 930 return (NULL); 931 932 ADD_U_CHAR(dptr, AUT_SEQ); 933 ADD_U_INT32(dptr, audit_count); 934 935 return (t); 936} 937 938/* 939 * token ID 1 byte 940 * socket domain 2 bytes 941 * socket type 2 bytes 942 * address type 2 byte 943 * local port 2 bytes 944 * local address 4 bytes/16 bytes (IPv4/IPv6 address) 945 * remote port 2 bytes 946 * remote address 4 bytes/16 bytes (IPv4/IPv6 address) 947 */ 948token_t * 949au_to_socket_ex(u_short so_domain, u_short so_type, 950 struct sockaddr *sa_local, struct sockaddr *sa_remote) 951{ 952 token_t *t; 953 u_char *dptr = NULL; 954 struct sockaddr_in *sin; 955 struct sockaddr_in6 *sin6; 956 957 if (so_domain == AF_INET) 958 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 959 5 * sizeof(u_int16_t) + 2 * sizeof(u_int32_t)); 960 else if (so_domain == AF_INET6) 961 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 962 5 * sizeof(u_int16_t) + 16 * sizeof(u_int32_t)); 963 else { 964 errno = EINVAL; 965 return (NULL); 966 } 967 968 ADD_U_CHAR(dptr, AUT_SOCKET_EX); 969 ADD_U_INT16(dptr, so_domain); /* XXXRW: explicitly convert? */ 970 ADD_U_INT16(dptr, so_type); /* XXXRW: explicitly convert? */ 971 if (so_domain == AF_INET) { 972 ADD_U_INT16(dptr, AU_IPv4); 973 sin = (struct sockaddr_in *)sa_local; 974 ADD_MEM(dptr, &sin->sin_port, sizeof(uint16_t)); 975 ADD_MEM(dptr, &sin->sin_addr.s_addr, sizeof(uint32_t)); 976 sin = (struct sockaddr_in *)sa_remote; 977 ADD_MEM(dptr, &sin->sin_port, sizeof(uint16_t)); 978 ADD_MEM(dptr, &sin->sin_addr.s_addr, sizeof(uint32_t)); 979 } else { 980 ADD_U_INT16(dptr, AU_IPv6); 981 sin6 = (struct sockaddr_in6 *)sa_local; 982 ADD_MEM(dptr, &sin6->sin6_port, sizeof(uint16_t)); 983 ADD_MEM(dptr, &sin6->sin6_addr, 4 * sizeof(uint32_t)); 984 sin6 = (struct sockaddr_in6 *)sa_remote; 985 ADD_MEM(dptr, &sin6->sin6_port, sizeof(uint16_t)); 986 ADD_MEM(dptr, &sin6->sin6_addr, 4 * sizeof(uint32_t)); 987 } 988 989 return (t); 990} 991 992/* 993 * token ID 1 byte 994 * socket family 2 bytes 995 * path 104 bytes 996 */ 997token_t * 998au_to_sock_unix(struct sockaddr_un *so) 999{ 1000 token_t *t; 1001 u_char *dptr; 1002 1003 GET_TOKEN_AREA(t, dptr, 3 * sizeof(u_char) + strlen(so->sun_path) + 1); 1004 if (t == NULL) 1005 return (NULL); 1006 1007 ADD_U_CHAR(dptr, AUT_SOCKUNIX); 1008 /* BSM token has two bytes for family */ 1009 ADD_U_CHAR(dptr, 0); 1010 ADD_U_CHAR(dptr, so->sun_family); 1011 ADD_STRING(dptr, so->sun_path, strlen(so->sun_path) + 1); 1012 1013 return (t); 1014} 1015 1016/* 1017 * token ID 1 byte 1018 * socket family 2 bytes 1019 * local port 2 bytes 1020 * socket address 4 bytes 1021 */ 1022token_t * 1023au_to_sock_inet32(struct sockaddr_in *so) 1024{ 1025 token_t *t; 1026 u_char *dptr = NULL; 1027 uint16_t family; 1028 1029 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(uint16_t) + 1030 sizeof(uint32_t)); 1031 if (t == NULL) 1032 return (NULL); 1033 1034 ADD_U_CHAR(dptr, AUT_SOCKINET32); 1035 /* 1036 * BSM defines the family field as 16 bits, but many operating 1037 * systems have an 8-bit sin_family field. Extend to 16 bits before 1038 * writing into the token. Assume that both the port and the address 1039 * in the sockaddr_in are already in network byte order, but family 1040 * is in local byte order. 1041 * 1042 * XXXRW: Should a name space conversion be taking place on the value 1043 * of sin_family? 1044 */ 1045 family = so->sin_family; 1046 ADD_U_INT16(dptr, family); 1047 ADD_MEM(dptr, &so->sin_port, sizeof(uint16_t)); 1048 ADD_MEM(dptr, &so->sin_addr.s_addr, sizeof(uint32_t)); 1049 1050 return (t); 1051} 1052 1053token_t * 1054au_to_sock_inet128(struct sockaddr_in6 *so) 1055{ 1056 token_t *t; 1057 u_char *dptr = NULL; 1058 1059 GET_TOKEN_AREA(t, dptr, 3 * sizeof(u_char) + sizeof(u_int16_t) + 1060 4 * sizeof(u_int32_t)); 1061 if (t == NULL) 1062 return (NULL); 1063 1064 ADD_U_CHAR(dptr, AUT_SOCKINET128); 1065 /* 1066 * In BSD, sin6_family is one octet, but BSM defines the token to 1067 * store two. So we copy in a 0 first. XXXRW: Possibly should be 1068 * conditionally compiled. 1069 */ 1070 ADD_U_CHAR(dptr, 0); 1071 ADD_U_CHAR(dptr, so->sin6_family); 1072 1073 ADD_U_INT16(dptr, so->sin6_port); 1074 ADD_MEM(dptr, &so->sin6_addr, 4 * sizeof(uint32_t)); 1075 1076 return (t); 1077} 1078 1079token_t * 1080au_to_sock_inet(struct sockaddr_in *so) 1081{ 1082 1083 return (au_to_sock_inet32(so)); 1084} 1085 1086/* 1087 * token ID 1 byte 1088 * audit ID 4 bytes 1089 * effective user ID 4 bytes 1090 * effective group ID 4 bytes 1091 * real user ID 4 bytes 1092 * real group ID 4 bytes 1093 * process ID 4 bytes 1094 * session ID 4 bytes 1095 * terminal ID 1096 * port ID 4 bytes/8 bytes (32-bit/64-bit value) 1097 * machine address 4 bytes 1098 */ 1099token_t * 1100au_to_subject32(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid, 1101 pid_t pid, au_asid_t sid, au_tid_t *tid) 1102{ 1103 token_t *t; 1104 u_char *dptr = NULL; 1105 1106 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 9 * sizeof(u_int32_t)); 1107 if (t == NULL) 1108 return (NULL); 1109 1110 ADD_U_CHAR(dptr, AUT_SUBJECT32); 1111 ADD_U_INT32(dptr, auid); 1112 ADD_U_INT32(dptr, euid); 1113 ADD_U_INT32(dptr, egid); 1114 ADD_U_INT32(dptr, ruid); 1115 ADD_U_INT32(dptr, rgid); 1116 ADD_U_INT32(dptr, pid); 1117 ADD_U_INT32(dptr, sid); 1118 ADD_U_INT32(dptr, tid->port); 1119 ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t)); 1120 1121 return (t); 1122} 1123 1124token_t * 1125au_to_subject64(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid, 1126 pid_t pid, au_asid_t sid, au_tid_t *tid) 1127{ 1128 token_t *t; 1129 u_char *dptr = NULL; 1130 1131 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 7 * sizeof(u_int32_t) + 1132 sizeof(u_int64_t) + sizeof(u_int32_t)); 1133 if (t == NULL) 1134 return (NULL); 1135 1136 ADD_U_CHAR(dptr, AUT_SUBJECT64); 1137 ADD_U_INT32(dptr, auid); 1138 ADD_U_INT32(dptr, euid); 1139 ADD_U_INT32(dptr, egid); 1140 ADD_U_INT32(dptr, ruid); 1141 ADD_U_INT32(dptr, rgid); 1142 ADD_U_INT32(dptr, pid); 1143 ADD_U_INT32(dptr, sid); 1144 ADD_U_INT64(dptr, tid->port); 1145 ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t)); 1146 1147 return (t); 1148} 1149 1150token_t * 1151au_to_subject(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid, 1152 pid_t pid, au_asid_t sid, au_tid_t *tid) 1153{ 1154 1155 return (au_to_subject32(auid, euid, egid, ruid, rgid, pid, sid, 1156 tid)); 1157} 1158 1159/* 1160 * token ID 1 byte 1161 * audit ID 4 bytes 1162 * effective user ID 4 bytes 1163 * effective group ID 4 bytes 1164 * real user ID 4 bytes 1165 * real group ID 4 bytes 1166 * process ID 4 bytes 1167 * session ID 4 bytes 1168 * terminal ID 1169 * port ID 4 bytes/8 bytes (32-bit/64-bit value) 1170 * address type/length 4 bytes 1171 * machine address 16 bytes 1172 */ 1173token_t * 1174au_to_subject32_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, 1175 gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid) 1176{ 1177 token_t *t; 1178 u_char *dptr = NULL; 1179 1180 if (tid->at_type == AU_IPv4) 1181 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 10 * 1182 sizeof(u_int32_t)); 1183 else if (tid->at_type == AU_IPv6) 1184 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 13 * 1185 sizeof(u_int32_t)); 1186 else { 1187 errno = EINVAL; 1188 return (NULL); 1189 } 1190 if (t == NULL) 1191 return (NULL); 1192 1193 ADD_U_CHAR(dptr, AUT_SUBJECT32_EX); 1194 ADD_U_INT32(dptr, auid); 1195 ADD_U_INT32(dptr, euid); 1196 ADD_U_INT32(dptr, egid); 1197 ADD_U_INT32(dptr, ruid); 1198 ADD_U_INT32(dptr, rgid); 1199 ADD_U_INT32(dptr, pid); 1200 ADD_U_INT32(dptr, sid); 1201 ADD_U_INT32(dptr, tid->at_port); 1202 ADD_U_INT32(dptr, tid->at_type); 1203 if (tid->at_type == AU_IPv6) 1204 ADD_MEM(dptr, &tid->at_addr[0], 4 * sizeof(u_int32_t)); 1205 else 1206 ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t)); 1207 1208 return (t); 1209} 1210 1211token_t * 1212au_to_subject64_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, 1213 gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid) 1214{ 1215 token_t *t; 1216 u_char *dptr = NULL; 1217 1218 if (tid->at_type == AU_IPv4) 1219 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 1220 7 * sizeof(u_int32_t) + sizeof(u_int64_t) + 1221 2 * sizeof(u_int32_t)); 1222 else if (tid->at_type == AU_IPv6) 1223 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 1224 7 * sizeof(u_int32_t) + sizeof(u_int64_t) + 1225 5 * sizeof(u_int32_t)); 1226 else { 1227 errno = EINVAL; 1228 return (NULL); 1229 } 1230 if (t == NULL) 1231 return (NULL); 1232 1233 ADD_U_CHAR(dptr, AUT_SUBJECT64_EX); 1234 ADD_U_INT32(dptr, auid); 1235 ADD_U_INT32(dptr, euid); 1236 ADD_U_INT32(dptr, egid); 1237 ADD_U_INT32(dptr, ruid); 1238 ADD_U_INT32(dptr, rgid); 1239 ADD_U_INT32(dptr, pid); 1240 ADD_U_INT32(dptr, sid); 1241 ADD_U_INT64(dptr, tid->at_port); 1242 ADD_U_INT32(dptr, tid->at_type); 1243 if (tid->at_type == AU_IPv6) 1244 ADD_MEM(dptr, &tid->at_addr[0], 4 * sizeof(u_int32_t)); 1245 else 1246 ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t)); 1247 1248 return (t); 1249} 1250 1251token_t * 1252au_to_subject_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, 1253 gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid) 1254{ 1255 1256 return (au_to_subject32_ex(auid, euid, egid, ruid, rgid, pid, sid, 1257 tid)); 1258} 1259 1260#if !defined(_KERNEL) && !defined(KERNEL) && defined(HAVE_AUDIT_SYSCALLS) 1261/* 1262 * Collects audit information for the current process and creates a subject 1263 * token from it. 1264 */ 1265token_t * 1266au_to_me(void) 1267{ 1268 auditinfo_t auinfo; 1269 1270 if (getaudit(&auinfo) != 0) 1271 return (NULL); 1272 1273 return (au_to_subject32(auinfo.ai_auid, geteuid(), getegid(), 1274 getuid(), getgid(), getpid(), auinfo.ai_asid, &auinfo.ai_termid)); 1275} 1276#endif 1277 1278/* 1279 * token ID 1 byte 1280 * count 4 bytes 1281 * text count null-terminated strings 1282 */ 1283token_t * 1284au_to_exec_args(char **argv) 1285{ 1286 token_t *t; 1287 u_char *dptr = NULL; 1288 const char *nextarg; 1289 int i, count = 0; 1290 size_t totlen = 0; 1291 1292 nextarg = *argv; 1293 1294 while (nextarg != NULL) { 1295 int nextlen; 1296 1297 nextlen = strlen(nextarg); 1298 totlen += nextlen + 1; 1299 count++; 1300 nextarg = *(argv + count); 1301 } 1302 1303 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) + totlen); 1304 if (t == NULL) 1305 return (NULL); 1306 1307 ADD_U_CHAR(dptr, AUT_EXEC_ARGS); 1308 ADD_U_INT32(dptr, count); 1309 1310 for (i = 0; i < count; i++) { 1311 nextarg = *(argv + i); 1312 ADD_MEM(dptr, nextarg, strlen(nextarg) + 1); 1313 } 1314 1315 return (t); 1316} 1317 1318/* 1319 * token ID 1 byte 1320 * count 4 bytes 1321 * text count null-terminated strings 1322 */ 1323token_t * 1324au_to_exec_env(char **envp) 1325{ 1326 token_t *t; 1327 u_char *dptr = NULL; 1328 int i, count = 0; 1329 size_t totlen = 0; 1330 const char *nextenv; 1331 1332 nextenv = *envp; 1333 1334 while (nextenv != NULL) { 1335 int nextlen; 1336 1337 nextlen = strlen(nextenv); 1338 totlen += nextlen + 1; 1339 count++; 1340 nextenv = *(envp + count); 1341 } 1342 1343 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) + totlen); 1344 if (t == NULL) 1345 return (NULL); 1346 1347 ADD_U_CHAR(dptr, AUT_EXEC_ENV); 1348 ADD_U_INT32(dptr, count); 1349 1350 for (i = 0; i < count; i++) { 1351 nextenv = *(envp + i); 1352 ADD_MEM(dptr, nextenv, strlen(nextenv) + 1); 1353 } 1354 1355 return (t); 1356} 1357 1358/* 1359 * token ID 1 byte 1360 * zonename length 2 bytes 1361 * zonename N bytes + 1 terminating NULL byte 1362 */ 1363token_t * 1364au_to_zonename(const char *zonename) 1365{ 1366 u_char *dptr = NULL; 1367 u_int16_t textlen; 1368 token_t *t; 1369 1370 textlen = strlen(zonename) + 1; 1371 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + textlen); 1372 if (t == NULL) 1373 return (NULL); 1374 1375 ADD_U_CHAR(dptr, AUT_ZONENAME); 1376 ADD_U_INT16(dptr, textlen); 1377 ADD_STRING(dptr, zonename, textlen); 1378 return (t); 1379} 1380 1381/* 1382 * token ID 1 byte 1383 * record byte count 4 bytes 1384 * version # 1 byte [2] 1385 * event type 2 bytes 1386 * event modifier 2 bytes 1387 * seconds of time 4 bytes/8 bytes (32-bit/64-bit value) 1388 * milliseconds of time 4 bytes/8 bytes (32-bit/64-bit value) 1389 */ 1390token_t * 1391au_to_header32_tm(int rec_size, au_event_t e_type, au_emod_t e_mod, 1392 struct timeval tm) 1393{ 1394 token_t *t; 1395 u_char *dptr = NULL; 1396 u_int32_t timems; 1397 1398 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) + 1399 sizeof(u_char) + 2 * sizeof(u_int16_t) + 2 * sizeof(u_int32_t)); 1400 if (t == NULL) 1401 return (NULL); 1402 1403 ADD_U_CHAR(dptr, AUT_HEADER32); 1404 ADD_U_INT32(dptr, rec_size); 1405 ADD_U_CHAR(dptr, AUDIT_HEADER_VERSION_OPENBSM); 1406 ADD_U_INT16(dptr, e_type); 1407 ADD_U_INT16(dptr, e_mod); 1408 1409 timems = tm.tv_usec/1000; 1410 /* Add the timestamp */ 1411 ADD_U_INT32(dptr, tm.tv_sec); 1412 ADD_U_INT32(dptr, timems); /* We need time in ms. */ 1413 1414 return (t); 1415} 1416 1417/* 1418 * token ID 1 byte 1419 * record byte count 4 bytes 1420 * version # 1 byte [2] 1421 * event type 2 bytes 1422 * event modifier 2 bytes 1423 * address type/length 4 bytes 1424 * machine address 4 bytes/16 bytes (IPv4/IPv6 address) 1425 * seconds of time 4 bytes/8 bytes (32-bit/64-bit value) 1426 * milliseconds of time 4 bytes/8 bytes (32-bit/64-bit value) 1427 */ 1428token_t * 1429au_to_header32_ex_tm(int rec_size, au_event_t e_type, au_emod_t e_mod, 1430 struct timeval tm, struct auditinfo_addr *aia) 1431{ 1432 token_t *t; 1433 u_char *dptr = NULL; 1434 u_int32_t timems; 1435 au_tid_addr_t *tid; 1436 1437 tid = &aia->ai_termid; 1438 if (tid->at_type != AU_IPv4 && tid->at_type != AU_IPv6) 1439 return (NULL); 1440 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) + 1441 sizeof(u_char) + 2 * sizeof(u_int16_t) + 3 * 1442 sizeof(u_int32_t) + tid->at_type); 1443 if (t == NULL) 1444 return (NULL); 1445 1446 ADD_U_CHAR(dptr, AUT_HEADER32_EX); 1447 ADD_U_INT32(dptr, rec_size); 1448 ADD_U_CHAR(dptr, AUDIT_HEADER_VERSION_OPENBSM); 1449 ADD_U_INT16(dptr, e_type); 1450 ADD_U_INT16(dptr, e_mod); 1451 1452 ADD_U_INT32(dptr, tid->at_type); 1453 if (tid->at_type == AU_IPv6) 1454 ADD_MEM(dptr, &tid->at_addr[0], 4 * sizeof(u_int32_t)); 1455 else 1456 ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t)); 1457 timems = tm.tv_usec/1000; 1458 /* Add the timestamp */ 1459 ADD_U_INT32(dptr, tm.tv_sec); 1460 ADD_U_INT32(dptr, timems); /* We need time in ms. */ 1461 1462 return (t); 1463} 1464 1465token_t * 1466au_to_header64_tm(int rec_size, au_event_t e_type, au_emod_t e_mod, 1467 struct timeval tm) 1468{ 1469 token_t *t; 1470 u_char *dptr = NULL; 1471 u_int32_t timems; 1472 1473 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) + 1474 sizeof(u_char) + 2 * sizeof(u_int16_t) + 2 * sizeof(u_int64_t)); 1475 if (t == NULL) 1476 return (NULL); 1477 1478 ADD_U_CHAR(dptr, AUT_HEADER64); 1479 ADD_U_INT32(dptr, rec_size); 1480 ADD_U_CHAR(dptr, AUDIT_HEADER_VERSION_OPENBSM); 1481 ADD_U_INT16(dptr, e_type); 1482 ADD_U_INT16(dptr, e_mod); 1483 1484 timems = tm.tv_usec/1000; 1485 /* Add the timestamp */ 1486 ADD_U_INT64(dptr, tm.tv_sec); 1487 ADD_U_INT64(dptr, timems); /* We need time in ms. */ 1488 1489 return (t); 1490} 1491 1492#if !defined(KERNEL) && !defined(_KERNEL) 1493#ifdef HAVE_AUDIT_SYSCALLS 1494token_t * 1495au_to_header32_ex(int rec_size, au_event_t e_type, au_emod_t e_mod) 1496{ 1497 struct timeval tm; 1498 struct auditinfo_addr aia; 1499 1500 if (gettimeofday(&tm, NULL) == -1) 1501 return (NULL); 1502 if (auditon(A_GETKAUDIT, &aia, sizeof(aia)) < 0) { 1503 if (errno != ENOSYS) 1504 return (NULL); 1505 return (au_to_header32_tm(rec_size, e_type, e_mod, tm)); 1506 } 1507 return (au_to_header32_ex_tm(rec_size, e_type, e_mod, tm, &aia)); 1508} 1509#endif /* HAVE_AUDIT_SYSCALLS */ 1510 1511token_t * 1512au_to_header32(int rec_size, au_event_t e_type, au_emod_t e_mod) 1513{ 1514 struct timeval tm; 1515 1516 if (gettimeofday(&tm, NULL) == -1) 1517 return (NULL); 1518 return (au_to_header32_tm(rec_size, e_type, e_mod, tm)); 1519} 1520 1521token_t * 1522au_to_header64(__unused int rec_size, __unused au_event_t e_type, 1523 __unused au_emod_t e_mod) 1524{ 1525 struct timeval tm; 1526 1527 if (gettimeofday(&tm, NULL) == -1) 1528 return (NULL); 1529 return (au_to_header64_tm(rec_size, e_type, e_mod, tm)); 1530} 1531 1532token_t * 1533au_to_header(int rec_size, au_event_t e_type, au_emod_t e_mod) 1534{ 1535 1536 return (au_to_header32(rec_size, e_type, e_mod)); 1537} 1538 1539#ifdef HAVE_AUDIT_SYSCALLS 1540token_t * 1541au_to_header_ex(int rec_size, au_event_t e_type, au_emod_t e_mod) 1542{ 1543 1544 return (au_to_header32_ex(rec_size, e_type, e_mod)); 1545} 1546#endif /* HAVE_AUDIT_SYSCALLS */ 1547#endif /* !defined(KERNEL) && !defined(_KERNEL) */ 1548 1549/* 1550 * token ID 1 byte 1551 * trailer magic number 2 bytes 1552 * record byte count 4 bytes 1553 */ 1554token_t * 1555au_to_trailer(int rec_size) 1556{ 1557 token_t *t; 1558 u_char *dptr = NULL; 1559 u_int16_t magic = AUT_TRAILER_MAGIC; 1560 1561 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + 1562 sizeof(u_int32_t)); 1563 if (t == NULL) 1564 return (NULL); 1565 1566 ADD_U_CHAR(dptr, AUT_TRAILER); 1567 ADD_U_INT16(dptr, magic); 1568 ADD_U_INT32(dptr, rec_size); 1569 1570 return (t); 1571} 1572