bsm_token.c revision 171066
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 * $FreeBSD: head/sys/security/audit/audit_bsm_token.c 171066 2007-06-27 17:01:15Z csjp $ 34 */ 35 36#include <sys/types.h> 37#include <sys/endian.h> 38#include <sys/queue.h> 39#include <sys/socket.h> 40#include <sys/time.h> 41 42#include <sys/ipc.h> 43#include <sys/libkern.h> 44#include <sys/malloc.h> 45#include <sys/un.h> 46 47#include <netinet/in.h> 48#include <netinet/in_systm.h> 49#include <netinet/ip.h> 50 51 52#include <bsm/audit.h> 53#include <bsm/audit_internal.h> 54#include <bsm/audit_record.h> 55#include <security/audit/audit.h> 56#include <security/audit/audit_private.h> 57 58#define GET_TOKEN_AREA(t, dptr, length) do { \ 59 t = malloc(sizeof(token_t), M_AUDITBSM, M_WAITOK); \ 60 t->t_data = malloc(length, M_AUDITBSM, M_WAITOK | M_ZERO); \ 61 t->len = length; \ 62 dptr = t->t_data; \ 63} while (0) 64 65/* 66 * token ID 1 byte 67 * argument # 1 byte 68 * argument value 4 bytes/8 bytes (32-bit/64-bit value) 69 * text length 2 bytes 70 * text N bytes + 1 terminating NULL byte 71 */ 72token_t * 73au_to_arg32(char n, char *text, u_int32_t v) 74{ 75 token_t *t; 76 u_char *dptr = NULL; 77 u_int16_t textlen; 78 79 textlen = strlen(text); 80 textlen += 1; 81 82 GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int32_t) + 83 sizeof(u_int16_t) + textlen); 84 85 ADD_U_CHAR(dptr, AUT_ARG32); 86 ADD_U_CHAR(dptr, n); 87 ADD_U_INT32(dptr, v); 88 ADD_U_INT16(dptr, textlen); 89 ADD_STRING(dptr, text, textlen); 90 91 return (t); 92 93} 94 95token_t * 96au_to_arg64(char n, char *text, u_int64_t v) 97{ 98 token_t *t; 99 u_char *dptr = NULL; 100 u_int16_t textlen; 101 102 textlen = strlen(text); 103 textlen += 1; 104 105 GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int64_t) + 106 sizeof(u_int16_t) + textlen); 107 108 ADD_U_CHAR(dptr, AUT_ARG64); 109 ADD_U_CHAR(dptr, n); 110 ADD_U_INT64(dptr, v); 111 ADD_U_INT16(dptr, textlen); 112 ADD_STRING(dptr, text, textlen); 113 114 return (t); 115 116} 117 118token_t * 119au_to_arg(char n, char *text, u_int32_t v) 120{ 121 122 return (au_to_arg32(n, text, v)); 123} 124 125#if defined(_KERNEL) || defined(KERNEL) 126/* 127 * token ID 1 byte 128 * file access mode 4 bytes 129 * owner user ID 4 bytes 130 * owner group ID 4 bytes 131 * file system ID 4 bytes 132 * node ID 8 bytes 133 * device 4 bytes/8 bytes (32-bit/64-bit) 134 */ 135token_t * 136au_to_attr32(struct vnode_au_info *vni) 137{ 138 token_t *t; 139 u_char *dptr = NULL; 140 u_int16_t pad0_16 = 0; 141 u_int16_t pad0_32 = 0; 142 143 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int16_t) + 144 3 * sizeof(u_int32_t) + sizeof(u_int64_t) + sizeof(u_int32_t)); 145 146 ADD_U_CHAR(dptr, AUT_ATTR32); 147 148 /* 149 * Darwin defines the size for the file mode 150 * as 2 bytes; BSM defines 4 so pad with 0 151 */ 152 ADD_U_INT16(dptr, pad0_16); 153 ADD_U_INT16(dptr, vni->vn_mode); 154 155 ADD_U_INT32(dptr, vni->vn_uid); 156 ADD_U_INT32(dptr, vni->vn_gid); 157 ADD_U_INT32(dptr, vni->vn_fsid); 158 159 /* 160 * Some systems use 32-bit file ID's, other's use 64-bit file IDs. 161 * Attempt to handle both, and let the compiler sort it out. If we 162 * could pick this out at compile-time, it would be better, so as to 163 * avoid the else case below. 164 */ 165 if (sizeof(vni->vn_fileid) == sizeof(uint32_t)) { 166 ADD_U_INT32(dptr, pad0_32); 167 ADD_U_INT32(dptr, vni->vn_fileid); 168 } else if (sizeof(vni->vn_fileid) == sizeof(uint64_t)) 169 ADD_U_INT64(dptr, vni->vn_fileid); 170 else 171 ADD_U_INT64(dptr, 0LL); 172 173 ADD_U_INT32(dptr, vni->vn_dev); 174 175 return (t); 176} 177 178token_t * 179au_to_attr64(struct vnode_au_info *vni) 180{ 181 token_t *t; 182 u_char *dptr = NULL; 183 u_int16_t pad0_16 = 0; 184 u_int16_t pad0_32 = 0; 185 186 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int16_t) + 187 3 * sizeof(u_int32_t) + sizeof(u_int64_t) * 2); 188 189 ADD_U_CHAR(dptr, AUT_ATTR64); 190 191 /* 192 * Darwin defines the size for the file mode 193 * as 2 bytes; BSM defines 4 so pad with 0 194 */ 195 ADD_U_INT16(dptr, pad0_16); 196 ADD_U_INT16(dptr, vni->vn_mode); 197 198 ADD_U_INT32(dptr, vni->vn_uid); 199 ADD_U_INT32(dptr, vni->vn_gid); 200 ADD_U_INT32(dptr, vni->vn_fsid); 201 202 /* 203 * Some systems use 32-bit file ID's, other's use 64-bit file IDs. 204 * Attempt to handle both, and let the compiler sort it out. If we 205 * could pick this out at compile-time, it would be better, so as to 206 * avoid the else case below. 207 */ 208 if (sizeof(vni->vn_fileid) == sizeof(uint32_t)) { 209 ADD_U_INT32(dptr, pad0_32); 210 ADD_U_INT32(dptr, vni->vn_fileid); 211 } else if (sizeof(vni->vn_fileid) == sizeof(uint64_t)) 212 ADD_U_INT64(dptr, vni->vn_fileid); 213 else 214 ADD_U_INT64(dptr, 0LL); 215 216 ADD_U_INT64(dptr, vni->vn_dev); 217 218 return (t); 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 return (NULL); 265 } 266 267 totdata = datasize * unit_count; 268 269 GET_TOKEN_AREA(t, dptr, 4 * sizeof(u_char) + totdata); 270 271 ADD_U_CHAR(dptr, AUT_DATA); 272 ADD_U_CHAR(dptr, unit_print); 273 ADD_U_CHAR(dptr, unit_type); 274 ADD_U_CHAR(dptr, unit_count); 275 ADD_MEM(dptr, p, totdata); 276 277 return (t); 278} 279 280 281/* 282 * token ID 1 byte 283 * status 4 bytes 284 * return value 4 bytes 285 */ 286token_t * 287au_to_exit(int retval, int err) 288{ 289 token_t *t; 290 u_char *dptr = NULL; 291 292 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int32_t)); 293 294 ADD_U_CHAR(dptr, AUT_EXIT); 295 ADD_U_INT32(dptr, err); 296 ADD_U_INT32(dptr, retval); 297 298 return (t); 299} 300 301/* 302 */ 303token_t * 304au_to_groups(int *groups) 305{ 306 307 return (au_to_newgroups(AUDIT_MAX_GROUPS, (gid_t*)groups)); 308} 309 310/* 311 * token ID 1 byte 312 * number groups 2 bytes 313 * group list count * 4 bytes 314 */ 315token_t * 316au_to_newgroups(u_int16_t n, gid_t *groups) 317{ 318 token_t *t; 319 u_char *dptr = NULL; 320 int i; 321 322 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + 323 n * sizeof(u_int32_t)); 324 325 ADD_U_CHAR(dptr, AUT_NEWGROUPS); 326 ADD_U_INT16(dptr, n); 327 for (i = 0; i < n; i++) 328 ADD_U_INT32(dptr, groups[i]); 329 330 return (t); 331} 332 333/* 334 * token ID 1 byte 335 * internet address 4 bytes 336 */ 337token_t * 338au_to_in_addr(struct in_addr *internet_addr) 339{ 340 token_t *t; 341 u_char *dptr = NULL; 342 343 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(uint32_t)); 344 345 ADD_U_CHAR(dptr, AUT_IN_ADDR); 346 ADD_MEM(dptr, &internet_addr->s_addr, sizeof(uint32_t)); 347 348 return (t); 349} 350 351/* 352 * token ID 1 byte 353 * address type/length 4 bytes 354 * Address 16 bytes 355 */ 356token_t * 357au_to_in_addr_ex(struct in6_addr *internet_addr) 358{ 359 token_t *t; 360 u_char *dptr = NULL; 361 u_int32_t type = AU_IPv6; 362 363 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 5 * sizeof(uint32_t)); 364 365 ADD_U_CHAR(dptr, AUT_IN_ADDR_EX); 366 ADD_U_INT32(dptr, type); 367 ADD_MEM(dptr, internet_addr, 4 * sizeof(uint32_t)); 368 369 return (t); 370} 371 372/* 373 * token ID 1 byte 374 * ip header 20 bytes 375 * 376 * The IP header should be submitted in network byte order. 377 */ 378token_t * 379au_to_ip(struct ip *ip) 380{ 381 token_t *t; 382 u_char *dptr = NULL; 383 384 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(struct ip)); 385 386 ADD_U_CHAR(dptr, AUT_IP); 387 ADD_MEM(dptr, ip, sizeof(struct ip)); 388 389 return (t); 390} 391 392/* 393 * token ID 1 byte 394 * object ID type 1 byte 395 * object ID 4 bytes 396 */ 397token_t * 398au_to_ipc(char type, int id) 399{ 400 token_t *t; 401 u_char *dptr = NULL; 402 403 GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int32_t)); 404 405 ADD_U_CHAR(dptr, AUT_IPC); 406 ADD_U_CHAR(dptr, type); 407 ADD_U_INT32(dptr, id); 408 409 return (t); 410} 411 412/* 413 * token ID 1 byte 414 * owner user ID 4 bytes 415 * owner group ID 4 bytes 416 * creator user ID 4 bytes 417 * creator group ID 4 bytes 418 * access mode 4 bytes 419 * slot sequence # 4 bytes 420 * key 4 bytes 421 */ 422token_t * 423au_to_ipc_perm(struct ipc_perm *perm) 424{ 425 token_t *t; 426 u_char *dptr = NULL; 427 u_int16_t pad0 = 0; 428 429 GET_TOKEN_AREA(t, dptr, 12 * sizeof(u_int16_t) + sizeof(u_int32_t)); 430 431 ADD_U_CHAR(dptr, AUT_IPC_PERM); 432 433 /* 434 * Darwin defines the sizes for ipc_perm members 435 * as 2 bytes; BSM defines 4 so pad with 0 436 */ 437 ADD_U_INT16(dptr, pad0); 438 ADD_U_INT16(dptr, perm->uid); 439 440 ADD_U_INT16(dptr, pad0); 441 ADD_U_INT16(dptr, perm->gid); 442 443 ADD_U_INT16(dptr, pad0); 444 ADD_U_INT16(dptr, perm->cuid); 445 446 ADD_U_INT16(dptr, pad0); 447 ADD_U_INT16(dptr, perm->cgid); 448 449 ADD_U_INT16(dptr, pad0); 450 ADD_U_INT16(dptr, perm->mode); 451 452 ADD_U_INT16(dptr, pad0); 453 ADD_U_INT16(dptr, perm->seq); 454 455 ADD_U_INT32(dptr, perm->key); 456 457 return (t); 458} 459 460/* 461 * token ID 1 byte 462 * port IP address 2 bytes 463 */ 464token_t * 465au_to_iport(u_int16_t iport) 466{ 467 token_t *t; 468 u_char *dptr = NULL; 469 470 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t)); 471 472 ADD_U_CHAR(dptr, AUT_IPORT); 473 ADD_U_INT16(dptr, iport); 474 475 return (t); 476} 477 478/* 479 * token ID 1 byte 480 * size 2 bytes 481 * data size bytes 482 */ 483token_t * 484au_to_opaque(char *data, u_int16_t bytes) 485{ 486 token_t *t; 487 u_char *dptr = NULL; 488 489 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + bytes); 490 491 ADD_U_CHAR(dptr, AUT_OPAQUE); 492 ADD_U_INT16(dptr, bytes); 493 ADD_MEM(dptr, data, bytes); 494 495 return (t); 496} 497 498/* 499 * token ID 1 byte 500 * seconds of time 4 bytes 501 * milliseconds of time 4 bytes 502 * file name len 2 bytes 503 * file pathname N bytes + 1 terminating NULL byte 504 */ 505token_t * 506au_to_file(char *file, struct timeval tm) 507{ 508 token_t *t; 509 u_char *dptr = NULL; 510 u_int16_t filelen; 511 u_int32_t timems; 512 513 filelen = strlen(file); 514 filelen += 1; 515 516 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int32_t) + 517 sizeof(u_int16_t) + filelen); 518 519 timems = tm.tv_usec/1000; 520 521 ADD_U_CHAR(dptr, AUT_OTHER_FILE32); 522 ADD_U_INT32(dptr, tm.tv_sec); 523 ADD_U_INT32(dptr, timems); /* We need time in ms. */ 524 ADD_U_INT16(dptr, filelen); 525 ADD_STRING(dptr, file, filelen); 526 527 return (t); 528} 529 530/* 531 * token ID 1 byte 532 * text length 2 bytes 533 * text N bytes + 1 terminating NULL byte 534 */ 535token_t * 536au_to_text(char *text) 537{ 538 token_t *t; 539 u_char *dptr = NULL; 540 u_int16_t textlen; 541 542 textlen = strlen(text); 543 textlen += 1; 544 545 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + textlen); 546 547 ADD_U_CHAR(dptr, AUT_TEXT); 548 ADD_U_INT16(dptr, textlen); 549 ADD_STRING(dptr, text, textlen); 550 551 return (t); 552} 553 554/* 555 * token ID 1 byte 556 * path length 2 bytes 557 * path N bytes + 1 terminating NULL byte 558 */ 559token_t * 560au_to_path(char *text) 561{ 562 token_t *t; 563 u_char *dptr = NULL; 564 u_int16_t textlen; 565 566 textlen = strlen(text); 567 textlen += 1; 568 569 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + textlen); 570 571 ADD_U_CHAR(dptr, AUT_PATH); 572 ADD_U_INT16(dptr, textlen); 573 ADD_STRING(dptr, text, textlen); 574 575 return (t); 576} 577 578/* 579 * token ID 1 byte 580 * audit ID 4 bytes 581 * effective user ID 4 bytes 582 * effective group ID 4 bytes 583 * real user ID 4 bytes 584 * real group ID 4 bytes 585 * process ID 4 bytes 586 * session ID 4 bytes 587 * terminal ID 588 * port ID 4 bytes/8 bytes (32-bit/64-bit value) 589 * machine address 4 bytes 590 */ 591token_t * 592au_to_process32(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid, 593 pid_t pid, au_asid_t sid, au_tid_t *tid) 594{ 595 token_t *t; 596 u_char *dptr = NULL; 597 598 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 9 * sizeof(u_int32_t)); 599 600 ADD_U_CHAR(dptr, AUT_PROCESS32); 601 ADD_U_INT32(dptr, auid); 602 ADD_U_INT32(dptr, euid); 603 ADD_U_INT32(dptr, egid); 604 ADD_U_INT32(dptr, ruid); 605 ADD_U_INT32(dptr, rgid); 606 ADD_U_INT32(dptr, pid); 607 ADD_U_INT32(dptr, sid); 608 ADD_U_INT32(dptr, tid->port); 609 ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t)); 610 611 return (t); 612} 613 614token_t * 615au_to_process64(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid, 616 pid_t pid, au_asid_t sid, au_tid_t *tid) 617{ 618 token_t *t; 619 u_char *dptr = NULL; 620 621 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 8 * sizeof(u_int32_t) + 622 sizeof(u_int64_t)); 623 624 ADD_U_CHAR(dptr, AUT_PROCESS64); 625 ADD_U_INT32(dptr, auid); 626 ADD_U_INT32(dptr, euid); 627 ADD_U_INT32(dptr, egid); 628 ADD_U_INT32(dptr, ruid); 629 ADD_U_INT32(dptr, rgid); 630 ADD_U_INT32(dptr, pid); 631 ADD_U_INT32(dptr, sid); 632 ADD_U_INT64(dptr, tid->port); 633 ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t)); 634 635 return (t); 636} 637 638token_t * 639au_to_process(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid, 640 pid_t pid, au_asid_t sid, au_tid_t *tid) 641{ 642 643 return (au_to_process32(auid, euid, egid, ruid, rgid, pid, sid, 644 tid)); 645} 646 647/* 648 * token ID 1 byte 649 * audit ID 4 bytes 650 * effective user ID 4 bytes 651 * effective group ID 4 bytes 652 * real user ID 4 bytes 653 * real group ID 4 bytes 654 * process ID 4 bytes 655 * session ID 4 bytes 656 * terminal ID 657 * port ID 4 bytes/8 bytes (32-bit/64-bit value) 658 * address type-len 4 bytes 659 * machine address 4/16 bytes 660 */ 661token_t * 662au_to_process32_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, 663 gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid) 664{ 665 token_t *t; 666 u_char *dptr = NULL; 667 668 KASSERT((tid->at_type == AU_IPv4) || (tid->at_type == AU_IPv6), 669 ("au_to_process32_ex: type %u", (unsigned int)tid->at_type)); 670 if (tid->at_type == AU_IPv6) 671 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 13 * 672 sizeof(u_int32_t)); 673 else 674 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 10 * 675 sizeof(u_int32_t)); 676 677 ADD_U_CHAR(dptr, AUT_PROCESS32_EX); 678 ADD_U_INT32(dptr, auid); 679 ADD_U_INT32(dptr, euid); 680 ADD_U_INT32(dptr, egid); 681 ADD_U_INT32(dptr, ruid); 682 ADD_U_INT32(dptr, rgid); 683 ADD_U_INT32(dptr, pid); 684 ADD_U_INT32(dptr, sid); 685 ADD_U_INT32(dptr, tid->at_port); 686 ADD_U_INT32(dptr, tid->at_type); 687 if (tid->at_type == AU_IPv6) 688 ADD_MEM(dptr, &tid->at_addr[0], 4 * sizeof(u_int32_t)); 689 else 690 ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t)); 691 692 return (t); 693} 694 695token_t * 696au_to_process64_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, 697 gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid) 698{ 699 token_t *t; 700 u_char *dptr = NULL; 701 702 if (tid->at_type == AU_IPv4) 703 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 704 7 * sizeof(u_int32_t) + sizeof(u_int64_t) + 705 2 * sizeof(u_int32_t)); 706 else if (tid->at_type == AU_IPv6) 707 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 708 7 * sizeof(u_int32_t) + sizeof(u_int64_t) + 709 5 * sizeof(u_int32_t)); 710 else 711 panic("au_to_process64_ex: invalidate at_type (%d)", 712 tid->at_type); 713 714 ADD_U_CHAR(dptr, AUT_PROCESS64_EX); 715 ADD_U_INT32(dptr, auid); 716 ADD_U_INT32(dptr, euid); 717 ADD_U_INT32(dptr, egid); 718 ADD_U_INT32(dptr, ruid); 719 ADD_U_INT32(dptr, rgid); 720 ADD_U_INT32(dptr, pid); 721 ADD_U_INT32(dptr, sid); 722 ADD_U_INT64(dptr, tid->at_port); 723 ADD_U_INT32(dptr, tid->at_type); 724 ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t)); 725 if (tid->at_type == AU_IPv6) { 726 ADD_MEM(dptr, &tid->at_addr[1], sizeof(u_int32_t)); 727 ADD_MEM(dptr, &tid->at_addr[2], sizeof(u_int32_t)); 728 ADD_MEM(dptr, &tid->at_addr[3], sizeof(u_int32_t)); 729 } 730 731 return (t); 732} 733 734token_t * 735au_to_process_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, 736 gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid) 737{ 738 739 return (au_to_process32_ex(auid, euid, egid, ruid, rgid, pid, sid, 740 tid)); 741} 742 743/* 744 * token ID 1 byte 745 * error status 1 byte 746 * return value 4 bytes/8 bytes (32-bit/64-bit value) 747 */ 748token_t * 749au_to_return32(char status, u_int32_t ret) 750{ 751 token_t *t; 752 u_char *dptr = NULL; 753 754 GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int32_t)); 755 756 ADD_U_CHAR(dptr, AUT_RETURN32); 757 ADD_U_CHAR(dptr, status); 758 ADD_U_INT32(dptr, ret); 759 760 return (t); 761} 762 763token_t * 764au_to_return64(char status, u_int64_t ret) 765{ 766 token_t *t; 767 u_char *dptr = NULL; 768 769 GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int64_t)); 770 771 ADD_U_CHAR(dptr, AUT_RETURN64); 772 ADD_U_CHAR(dptr, status); 773 ADD_U_INT64(dptr, ret); 774 775 return (t); 776} 777 778token_t * 779au_to_return(char status, u_int32_t ret) 780{ 781 782 return (au_to_return32(status, ret)); 783} 784 785/* 786 * token ID 1 byte 787 * sequence number 4 bytes 788 */ 789token_t * 790au_to_seq(long audit_count) 791{ 792 token_t *t; 793 u_char *dptr = NULL; 794 795 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t)); 796 797 ADD_U_CHAR(dptr, AUT_SEQ); 798 ADD_U_INT32(dptr, audit_count); 799 800 return (t); 801} 802 803/* 804 * token ID 1 byte 805 * socket type 2 bytes 806 * local port 2 bytes 807 * local Internet address 4 bytes 808 * remote port 2 bytes 809 * remote Internet address 4 bytes 810 */ 811token_t * 812au_to_socket(struct socket *so) 813{ 814 815 /* XXXRW ... */ 816 return (NULL); 817} 818 819/* 820 * Kernel-specific version of the above function. 821 */ 822#ifdef _KERNEL 823token_t * 824kau_to_socket(struct socket_au_info *soi) 825{ 826 token_t *t; 827 u_char *dptr; 828 u_int16_t so_type; 829 830 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int16_t) + 831 sizeof(u_int32_t) + sizeof(u_int16_t) + sizeof(u_int32_t)); 832 833 ADD_U_CHAR(dptr, AU_SOCK_TOKEN); 834 /* Coerce the socket type into a short value */ 835 so_type = soi->so_type; 836 ADD_U_INT16(dptr, so_type); 837 ADD_U_INT16(dptr, soi->so_lport); 838 ADD_U_INT32(dptr, soi->so_laddr); 839 ADD_U_INT16(dptr, soi->so_rport); 840 ADD_U_INT32(dptr, soi->so_raddr); 841 842 return (t); 843} 844#endif 845 846/* 847 * token ID 1 byte 848 * socket type 2 bytes 849 * local port 2 bytes 850 * address type/length 4 bytes 851 * local Internet address 4 bytes/16 bytes (IPv4/IPv6 address) 852 * remote port 4 bytes 853 * address type/length 4 bytes 854 * remote Internet address 4 bytes/16 bytes (IPv4/IPv6 address) 855 */ 856token_t * 857au_to_socket_ex_32(u_int16_t lp, u_int16_t rp, struct sockaddr *la, 858 struct sockaddr *ra) 859{ 860 861 return (NULL); 862} 863 864token_t * 865au_to_socket_ex_128(u_int16_t lp, u_int16_t rp, struct sockaddr *la, 866 struct sockaddr *ra) 867{ 868 869 return (NULL); 870} 871 872/* 873 * token ID 1 byte 874 * socket family 2 bytes 875 * path 104 bytes 876 */ 877token_t * 878au_to_sock_unix(struct sockaddr_un *so) 879{ 880 token_t *t; 881 u_char *dptr; 882 883 GET_TOKEN_AREA(t, dptr, 3 * sizeof(u_char) + strlen(so->sun_path) + 1); 884 885 ADD_U_CHAR(dptr, AU_SOCK_UNIX_TOKEN); 886 /* BSM token has two bytes for family */ 887 ADD_U_CHAR(dptr, 0); 888 ADD_U_CHAR(dptr, so->sun_family); 889 ADD_STRING(dptr, so->sun_path, strlen(so->sun_path) + 1); 890 891 return (t); 892} 893 894/* 895 * token ID 1 byte 896 * socket family 2 bytes 897 * local port 2 bytes 898 * socket address 4 bytes 899 */ 900token_t * 901au_to_sock_inet32(struct sockaddr_in *so) 902{ 903 token_t *t; 904 u_char *dptr = NULL; 905 uint16_t family; 906 907 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(uint16_t) + 908 sizeof(uint32_t)); 909 910 ADD_U_CHAR(dptr, AUT_SOCKINET32); 911 /* 912 * BSM defines the family field as 16 bits, but many operating 913 * systems have an 8-bit sin_family field. Extend to 16 bits before 914 * writing into the token. Assume that both the port and the address 915 * in the sockaddr_in are already in network byte order, but family 916 * is in local byte order. 917 * 918 * XXXRW: Should a name space conversion be taking place on the value 919 * of sin_family? 920 */ 921 family = so->sin_family; 922 ADD_U_INT16(dptr, family); 923 ADD_MEM(dptr, &so->sin_port, sizeof(uint16_t)); 924 ADD_MEM(dptr, &so->sin_addr.s_addr, sizeof(uint32_t)); 925 926 return (t); 927 928} 929 930token_t * 931au_to_sock_inet128(struct sockaddr_in6 *so) 932{ 933 token_t *t; 934 u_char *dptr = NULL; 935 936 GET_TOKEN_AREA(t, dptr, 3 * sizeof(u_char) + sizeof(u_int16_t) + 937 4 * sizeof(u_int32_t)); 938 939 ADD_U_CHAR(dptr, AUT_SOCKINET128); 940 /* 941 * In Darwin, sin6_family is one octet, but BSM defines the token 942 * to store two. So we copy in a 0 first. 943 */ 944 ADD_U_CHAR(dptr, 0); 945 ADD_U_CHAR(dptr, so->sin6_family); 946 947 ADD_U_INT16(dptr, so->sin6_port); 948 ADD_MEM(dptr, &so->sin6_addr, 4 * sizeof(uint32_t)); 949 950 return (t); 951 952} 953 954token_t * 955au_to_sock_inet(struct sockaddr_in *so) 956{ 957 958 return (au_to_sock_inet32(so)); 959} 960 961/* 962 * token ID 1 byte 963 * audit ID 4 bytes 964 * effective user ID 4 bytes 965 * effective group ID 4 bytes 966 * real user ID 4 bytes 967 * real group ID 4 bytes 968 * process ID 4 bytes 969 * session ID 4 bytes 970 * terminal ID 971 * port ID 4 bytes/8 bytes (32-bit/64-bit value) 972 * machine address 4 bytes 973 */ 974token_t * 975au_to_subject32(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid, 976 pid_t pid, au_asid_t sid, au_tid_t *tid) 977{ 978 token_t *t; 979 u_char *dptr = NULL; 980 981 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 9 * sizeof(u_int32_t)); 982 983 ADD_U_CHAR(dptr, AUT_SUBJECT32); 984 ADD_U_INT32(dptr, auid); 985 ADD_U_INT32(dptr, euid); 986 ADD_U_INT32(dptr, egid); 987 ADD_U_INT32(dptr, ruid); 988 ADD_U_INT32(dptr, rgid); 989 ADD_U_INT32(dptr, pid); 990 ADD_U_INT32(dptr, sid); 991 ADD_U_INT32(dptr, tid->port); 992 ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t)); 993 994 return (t); 995} 996 997token_t * 998au_to_subject64(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid, 999 pid_t pid, au_asid_t sid, au_tid_t *tid) 1000{ 1001 token_t *t; 1002 u_char *dptr = NULL; 1003 1004 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 7 * sizeof(u_int32_t) + 1005 sizeof(u_int64_t) + sizeof(u_int32_t)); 1006 1007 ADD_U_CHAR(dptr, AUT_SUBJECT64); 1008 ADD_U_INT32(dptr, auid); 1009 ADD_U_INT32(dptr, euid); 1010 ADD_U_INT32(dptr, egid); 1011 ADD_U_INT32(dptr, ruid); 1012 ADD_U_INT32(dptr, rgid); 1013 ADD_U_INT32(dptr, pid); 1014 ADD_U_INT32(dptr, sid); 1015 ADD_U_INT64(dptr, tid->port); 1016 ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t)); 1017 1018 return (t); 1019} 1020 1021token_t * 1022au_to_subject(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid, 1023 pid_t pid, au_asid_t sid, au_tid_t *tid) 1024{ 1025 1026 return (au_to_subject32(auid, euid, egid, ruid, rgid, pid, sid, 1027 tid)); 1028} 1029 1030/* 1031 * token ID 1 byte 1032 * audit ID 4 bytes 1033 * effective user ID 4 bytes 1034 * effective group ID 4 bytes 1035 * real user ID 4 bytes 1036 * real group ID 4 bytes 1037 * process ID 4 bytes 1038 * session ID 4 bytes 1039 * terminal ID 1040 * port ID 4 bytes/8 bytes (32-bit/64-bit value) 1041 * address type/length 4 bytes 1042 * machine address 4/16 bytes 1043 */ 1044token_t * 1045au_to_subject32_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, 1046 gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid) 1047{ 1048 token_t *t; 1049 u_char *dptr = NULL; 1050 1051 KASSERT((tid->at_type == AU_IPv4) || (tid->at_type == AU_IPv6), 1052 ("au_to_subject32_ex: type %u", (unsigned int)tid->at_type)); 1053 if (tid->at_type == AU_IPv6) 1054 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 13 * 1055 sizeof(u_int32_t)); 1056 else 1057 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 10 * 1058 sizeof(u_int32_t)); 1059 1060 ADD_U_CHAR(dptr, AUT_SUBJECT32_EX); 1061 ADD_U_INT32(dptr, auid); 1062 ADD_U_INT32(dptr, euid); 1063 ADD_U_INT32(dptr, egid); 1064 ADD_U_INT32(dptr, ruid); 1065 ADD_U_INT32(dptr, rgid); 1066 ADD_U_INT32(dptr, pid); 1067 ADD_U_INT32(dptr, sid); 1068 ADD_U_INT32(dptr, tid->at_port); 1069 ADD_U_INT32(dptr, tid->at_type); 1070 if (tid->at_type == AU_IPv6) 1071 ADD_MEM(dptr, &tid->at_addr[0], 4 * sizeof(u_int32_t)); 1072 else 1073 ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t)); 1074 1075 return (t); 1076} 1077 1078token_t * 1079au_to_subject64_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, 1080 gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid) 1081{ 1082 token_t *t; 1083 u_char *dptr = NULL; 1084 1085 if (tid->at_type == AU_IPv4) 1086 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 1087 7 * sizeof(u_int32_t) + sizeof(u_int64_t) + 1088 2 * sizeof(u_int32_t)); 1089 else if (tid->at_type == AU_IPv6) 1090 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 1091 7 * sizeof(u_int32_t) + sizeof(u_int64_t) + 1092 5 * sizeof(u_int32_t)); 1093 else 1094 panic("au_to_subject64_ex: invalid at_type (%d)", 1095 tid->at_type); 1096 1097 ADD_U_CHAR(dptr, AUT_SUBJECT64_EX); 1098 ADD_U_INT32(dptr, auid); 1099 ADD_U_INT32(dptr, euid); 1100 ADD_U_INT32(dptr, egid); 1101 ADD_U_INT32(dptr, ruid); 1102 ADD_U_INT32(dptr, rgid); 1103 ADD_U_INT32(dptr, pid); 1104 ADD_U_INT32(dptr, sid); 1105 ADD_U_INT64(dptr, tid->at_port); 1106 ADD_U_INT32(dptr, tid->at_type); 1107 if (tid->at_type == AU_IPv6) 1108 ADD_MEM(dptr, &tid->at_addr[0], 4 * sizeof(u_int32_t)); 1109 else 1110 ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t)); 1111 1112 return (t); 1113} 1114 1115token_t * 1116au_to_subject_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, 1117 gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid) 1118{ 1119 1120 return (au_to_subject32_ex(auid, euid, egid, ruid, rgid, pid, sid, 1121 tid)); 1122} 1123 1124#if !defined(_KERNEL) && !defined(KERNEL) && defined(HAVE_AUDIT_SYSCALLS) 1125/* 1126 * Collects audit information for the current process 1127 * and creates a subject token from it 1128 */ 1129token_t * 1130au_to_me(void) 1131{ 1132 auditinfo_t auinfo; 1133 1134 if (getaudit(&auinfo) != 0) 1135 return (NULL); 1136 1137 return (au_to_subject32(auinfo.ai_auid, geteuid(), getegid(), 1138 getuid(), getgid(), getpid(), auinfo.ai_asid, &auinfo.ai_termid)); 1139} 1140#endif 1141 1142#if defined(_KERNEL) || defined(KERNEL) 1143static token_t * 1144au_to_exec_strings(char *strs, int count, u_char type) 1145{ 1146 token_t *t; 1147 u_char *dptr = NULL; 1148 u_int32_t totlen; 1149 int ctr; 1150 char *p; 1151 1152 totlen = 0; 1153 ctr = count; 1154 p = strs; 1155 while (ctr-- > 0) { 1156 totlen += strlen(p) + 1; 1157 p = strs + totlen; 1158 } 1159 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) + totlen); 1160 ADD_U_CHAR(dptr, type); 1161 ADD_U_INT32(dptr, count); 1162 ADD_STRING(dptr, strs, totlen); 1163 1164 return (t); 1165} 1166 1167/* 1168 * token ID 1 byte 1169 * count 4 bytes 1170 * text count null-terminated strings 1171 */ 1172token_t * 1173au_to_exec_args(char *args, int argc) 1174{ 1175 1176 return (au_to_exec_strings(args, argc, AUT_EXEC_ARGS)); 1177} 1178 1179/* 1180 * token ID 1 byte 1181 * count 4 bytes 1182 * text count null-terminated strings 1183 */ 1184token_t * 1185au_to_exec_env(char *envs, int envc) 1186{ 1187 1188 return (au_to_exec_strings(envs, envc, AUT_EXEC_ENV)); 1189} 1190#else 1191/* 1192 * token ID 1 byte 1193 * count 4 bytes 1194 * text count null-terminated strings 1195 */ 1196token_t * 1197au_to_exec_args(char **argv) 1198{ 1199 token_t *t; 1200 u_char *dptr = NULL; 1201 const char *nextarg; 1202 int i, count = 0; 1203 size_t totlen = 0; 1204 1205 nextarg = *argv; 1206 1207 while (nextarg != NULL) { 1208 int nextlen; 1209 1210 nextlen = strlen(nextarg); 1211 totlen += nextlen + 1; 1212 count++; 1213 nextarg = *(argv + count); 1214 } 1215 1216 totlen += count * sizeof(char); /* nul terminations. */ 1217 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) + totlen); 1218 1219 ADD_U_CHAR(dptr, AUT_EXEC_ARGS); 1220 ADD_U_INT32(dptr, count); 1221 1222 for (i = 0; i < count; i++) { 1223 nextarg = *(argv + i); 1224 ADD_MEM(dptr, nextarg, strlen(nextarg) + 1); 1225 } 1226 1227 return (t); 1228} 1229 1230/* 1231 * token ID 1 byte 1232 * zonename length 2 bytes 1233 * zonename N bytes + 1 terminating NULL byte 1234 */ 1235token_t * 1236au_to_zonename(char *zonename) 1237{ 1238 u_char *dptr = NULL; 1239 u_int16_t textlen; 1240 token_t *t; 1241 1242 textlen = strlen(zonename); 1243 textlen += 1; 1244 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + textlen); 1245 ADD_U_CHAR(dptr, AUT_ZONENAME); 1246 ADD_U_INT16(dptr, textlen); 1247 ADD_STRING(dptr, zonename, textlen); 1248 return (t); 1249} 1250 1251/* 1252 * token ID 1 byte 1253 * count 4 bytes 1254 * text count null-terminated strings 1255 */ 1256token_t * 1257au_to_exec_env(char **envp) 1258{ 1259 token_t *t; 1260 u_char *dptr = NULL; 1261 int i, count = 0; 1262 size_t totlen = 0; 1263 const char *nextenv; 1264 1265 nextenv = *envp; 1266 1267 while (nextenv != NULL) { 1268 int nextlen; 1269 1270 nextlen = strlen(nextenv); 1271 totlen += nextlen + 1; 1272 count++; 1273 nextenv = *(envp + count); 1274 } 1275 1276 totlen += sizeof(char) * count; 1277 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) + totlen); 1278 1279 ADD_U_CHAR(dptr, AUT_EXEC_ENV); 1280 ADD_U_INT32(dptr, count); 1281 1282 for (i = 0; i < count; i++) { 1283 nextenv = *(envp + i); 1284 ADD_MEM(dptr, nextenv, strlen(nextenv) + 1); 1285 } 1286 1287 return (t); 1288} 1289#endif 1290 1291/* 1292 * token ID 1 byte 1293 * record byte count 4 bytes 1294 * version # 1 byte [2] 1295 * event type 2 bytes 1296 * event modifier 2 bytes 1297 * seconds of time 4 bytes/8 bytes (32-bit/64-bit value) 1298 * milliseconds of time 4 bytes/8 bytes (32-bit/64-bit value) 1299 */ 1300token_t * 1301au_to_header32_tm(int rec_size, au_event_t e_type, au_emod_t e_mod, 1302 struct timeval tm) 1303{ 1304 token_t *t; 1305 u_char *dptr = NULL; 1306 u_int32_t timems; 1307 1308 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) + 1309 sizeof(u_char) + 2 * sizeof(u_int16_t) + 2 * sizeof(u_int32_t)); 1310 1311 ADD_U_CHAR(dptr, AUT_HEADER32); 1312 ADD_U_INT32(dptr, rec_size); 1313 ADD_U_CHAR(dptr, AUDIT_HEADER_VERSION_OPENBSM); 1314 ADD_U_INT16(dptr, e_type); 1315 ADD_U_INT16(dptr, e_mod); 1316 1317 timems = tm.tv_usec/1000; 1318 /* Add the timestamp */ 1319 ADD_U_INT32(dptr, tm.tv_sec); 1320 ADD_U_INT32(dptr, timems); /* We need time in ms. */ 1321 1322 return (t); 1323} 1324 1325token_t * 1326au_to_header64_tm(int rec_size, au_event_t e_type, au_emod_t e_mod, 1327 struct timeval tm) 1328{ 1329 token_t *t; 1330 u_char *dptr = NULL; 1331 u_int32_t timems; 1332 1333 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) + 1334 sizeof(u_char) + 2 * sizeof(u_int16_t) + 2 * sizeof(u_int64_t)); 1335 1336 ADD_U_CHAR(dptr, AUT_HEADER64); 1337 ADD_U_INT32(dptr, rec_size); 1338 ADD_U_CHAR(dptr, AUDIT_HEADER_VERSION_OPENBSM); 1339 ADD_U_INT16(dptr, e_type); 1340 ADD_U_INT16(dptr, e_mod); 1341 1342 timems = tm.tv_usec/1000; 1343 /* Add the timestamp */ 1344 ADD_U_INT64(dptr, tm.tv_sec); 1345 ADD_U_INT64(dptr, timems); /* We need time in ms. */ 1346 1347 return (t); 1348} 1349 1350/* 1351 * token ID 1 byte 1352 * trailer magic number 2 bytes 1353 * record byte count 4 bytes 1354 */ 1355token_t * 1356au_to_trailer(int rec_size) 1357{ 1358 token_t *t; 1359 u_char *dptr = NULL; 1360 u_int16_t magic = TRAILER_PAD_MAGIC; 1361 1362 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + 1363 sizeof(u_int32_t)); 1364 1365 ADD_U_CHAR(dptr, AUT_TRAILER); 1366 ADD_U_INT16(dptr, magic); 1367 ADD_U_INT32(dptr, rec_size); 1368 1369 return (t); 1370} 1371