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