1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 #include <bsm/adt.h> 29 #include <bsm/adt_event.h> 30 #include <assert.h> 31 #include <bsm/audit.h> 32 #include <bsm/audit_record.h> 33 #include <bsm/libbsm.h> 34 #include <door.h> 35 #include <errno.h> 36 #include <generic.h> 37 #include <md5.h> 38 #include <sys/mkdev.h> 39 #include <netdb.h> 40 #include <nss_dbdefs.h> 41 #include <pwd.h> 42 #include <sys/stat.h> 43 #include <time.h> 44 #include <stdlib.h> 45 #include <string.h> 46 #include <synch.h> 47 #include <sys/systeminfo.h> 48 #include <syslog.h> 49 #include <thread.h> 50 #include <unistd.h> 51 #include <adt_xlate.h> 52 #include <adt_ucred.h> 53 54 static int adt_selected(struct adt_event_state *, au_event_t, int); 55 static int adt_init(adt_internal_state_t *, int); 56 static int adt_import(adt_internal_state_t *, const adt_export_data_t *); 57 58 #ifdef C2_DEBUG 59 #define DPRINTF(x) {printf x; } 60 #define DFLUSH fflush(stdout); 61 #else 62 #define DPRINTF(x) 63 #define DFLUSH 64 #endif 65 66 extern int _mutex_lock(mutex_t *); 67 extern int _mutex_unlock(mutex_t *); 68 69 static int auditstate = AUC_DISABLED; /* default state */ 70 71 /* 72 * adt_write_syslog 73 * 74 * errors that are not the user's fault (bugs or whatever in 75 * the underlying audit code are noted in syslog.) 76 * 77 * Avoid calling adt_write_syslog for things that can happen 78 * at high volume. 79 * 80 * syslog's open (openlog) and close (closelog) are interesting; 81 * openlog *may* create a file descriptor and is optional. closelog 82 * *will* close any open file descriptors and is also optional. 83 * 84 * Since syslog may also be used by the calling application, the 85 * choice is to avoid openlog, which sets some otherwise useful 86 * parameters, and to embed "Solaris_audit" in the log message. 87 */ 88 89 void 90 adt_write_syslog(const char *message, int err) 91 { 92 int save_errno; 93 int mask_priority; 94 95 save_errno = errno; 96 errno = err; 97 98 DPRINTF(("syslog called: %s\n", message)); 99 100 mask_priority = setlogmask(LOG_MASK(LOG_ALERT)); 101 syslog(LOG_ALERT, "Solaris_audit %s: %m", message, err); 102 (void) setlogmask(mask_priority); 103 errno = save_errno; 104 } 105 106 /* 107 * return true if audit is enabled. "Enabled" is any state 108 * other than AUC_DISABLED. 109 * 110 * states are 111 * AUC_INIT_AUDIT -- c2audit queuing enabled. 112 * AUC_AUDITING -- up and running 113 * AUC_DISABLED -- no audit subsystem loaded 114 * AUC_UNSET -- early boot state 115 * AUC_NOAUDIT -- subsystem loaded, turned off via 116 * auditon(A_SETCOND...) 117 * AUC_NOSPACE -- up and running, but log partitions are full 118 * 119 * For purpose of this API, anything but AUC_DISABLED or 120 * AUC_UNSET is enabled; however one never actually sees 121 * AUC_DISABLED since auditon returns EINVAL in that case. Any 122 * auditon error is considered the same as EINVAL for our 123 * purpose. auditstate is not changed by auditon if an error 124 * is returned. 125 */ 126 127 boolean_t 128 adt_audit_enabled(void) { 129 130 (void) auditon(A_GETCOND, (caddr_t)&auditstate, sizeof (auditstate)); 131 132 return (auditstate != AUC_DISABLED); 133 } 134 135 /* 136 * The man page for getpwuid_r says the buffer must be big enough 137 * or ERANGE will be returned, but offers no guidance for how big 138 * the buffer should be or a way to calculate it. If you get 139 * ERANGE, double pwd_buff's size. 140 * 141 * This may be called even when auditing is off. 142 */ 143 144 #define NAFLAG_LEN 512 145 146 static int 147 adt_get_mask_from_user(uid_t uid, au_mask_t *mask) 148 { 149 struct passwd pwd; 150 char pwd_buff[NSS_BUFSIZ]; 151 char naflag_buf[NAFLAG_LEN]; 152 153 if (auditstate == AUC_DISABLED) { 154 mask->am_success = 0; 155 mask->am_failure = 0; 156 } else if (uid >= 0) { 157 if (getpwuid_r(uid, &pwd, pwd_buff, NSS_BUFSIZ) == NULL) { 158 /* 159 * getpwuid_r returns NULL without setting 160 * errno if the user does not exist; only 161 * if the input is the wrong length does it 162 * set errno. 163 */ 164 if (errno != ERANGE) 165 errno = EINVAL; 166 return (-1); 167 } 168 if (au_user_mask(pwd.pw_name, mask)) { 169 errno = EFAULT; /* undetermined failure */ 170 return (-1); 171 } 172 } else if (getacna(naflag_buf, NAFLAG_LEN - 1) == 0) { 173 if (getauditflagsbin(naflag_buf, mask)) 174 return (-1); 175 } else { 176 return (-1); 177 } 178 return (0); 179 } 180 181 /* 182 * adt_get_unique_id -- generate a hopefully unique 32 bit value 183 * 184 * there will be a follow up to replace this with the use of /dev/random 185 * 186 * An MD5 hash is taken on a buffer of 187 * hostname . audit id . unix time . pid . count 188 * 189 * "count = noise++;" is subject to a race condition but I don't 190 * see a need to put a lock around it. 191 */ 192 193 static au_id_t 194 adt_get_unique_id(uid_t uid) 195 { 196 char hostname[MAXHOSTNAMELEN]; 197 union { 198 au_id_t v[4]; 199 unsigned char obuff[128/8]; 200 } output; 201 MD5_CTX context; 202 203 static int noise = 0; 204 205 int count = noise++; 206 time_t timebits = time(NULL); 207 pid_t pidbits = getpid(); 208 au_id_t retval = 0; 209 210 if (gethostname(hostname, MAXHOSTNAMELEN)) { 211 adt_write_syslog("gethostname call failed", errno); 212 (void) strncpy(hostname, "invalidHostName", MAXHOSTNAMELEN); 213 } 214 215 while (retval == 0) { /* 0 is the only invalid result */ 216 MD5Init(&context); 217 218 MD5Update(&context, (unsigned char *)hostname, 219 (unsigned int) strlen((const char *)hostname)); 220 221 MD5Update(&context, (unsigned char *) &uid, sizeof (uid_t)); 222 223 MD5Update(&context, 224 (unsigned char *) &timebits, sizeof (time_t)); 225 226 MD5Update(&context, (unsigned char *) &pidbits, 227 sizeof (pid_t)); 228 229 MD5Update(&context, (unsigned char *) &(count), sizeof (int)); 230 MD5Final(output.obuff, &context); 231 232 retval = output.v[count % 4]; 233 } 234 return (retval); 235 } 236 237 /* 238 * the following "port" function deals with the following issues: 239 * 240 * 1 the kernel and ucred deal with a dev_t as a 64 bit value made 241 * up from a 32 bit major and 32 bit minor. 242 * 2 User space deals with a dev_t as either the above 64 bit value 243 * or a 32 bit value made from a 14 bit major and an 18 bit minor. 244 * 3 The various audit interfaces (except ucred) pass the 32 or 245 * 64 bit version depending the architecture of the userspace 246 * application. If you get a port value from ucred and pass it 247 * to the kernel via auditon(), it must be squeezed into a 32 248 * bit value because the kernel knows the userspace app's bit 249 * size. 250 * 251 * The internal state structure for adt (adt_internal_state_t) uses 252 * dev_t, so adt converts data from ucred to fit. The import/export 253 * functions, however, can't know if they are importing/exporting 254 * from 64 or 32 bit applications, so they always send 64 bits and 255 * the 32 bit end(s) are responsible to convert 32 -> 64 -> 32 as 256 * appropriate. 257 */ 258 259 /* 260 * adt_cpy_tid() -- if lib is 64 bit, just copy it (dev_t and port are 261 * both 64 bits). If lib is 32 bits, squeeze the two-int port into 262 * a 32 bit dev_t. A port fits in the "minor" part of au_port_t, 263 * so it isn't broken up into pieces. (When it goes to the kernel 264 * and back, however, it will have been split into major/minor 265 * pieces.) 266 */ 267 268 static void 269 adt_cpy_tid(au_tid_addr_t *dest, const au_tid64_addr_t *src) 270 { 271 #ifdef _LP64 272 (void) memcpy(dest, src, sizeof (au_tid_addr_t)); 273 #else 274 dest->at_type = src->at_type; 275 276 dest->at_port = src->at_port.at_minor & MAXMIN32; 277 dest->at_port |= (src->at_port.at_major & MAXMAJ32) << 278 NBITSMINOR32; 279 280 (void) memcpy(dest->at_addr, src->at_addr, 4 * sizeof (uint32_t)); 281 #endif 282 } 283 284 /* 285 * adt_start_session -- create interface handle, create context 286 * 287 * The imported_state input is normally NULL, if not, it represents 288 * a continued session; its values obviate the need for a subsequent 289 * call to adt_set_user(). 290 * 291 * The flag ADT_USE_PROC_DATA is used to decide how to set the initial 292 * state of the session. If 0, the session is "no audit" until a call 293 * to adt_set_user; if 1, the session is built from the process audit 294 * characteristics obtained from the kernel. If imported_state is 295 * not NULL, the resulting audit mask is an OR of the current process 296 * audit mask and that passed in. 297 * 298 * The basic model is that the caller can use the pointer returned 299 * by adt_start_session whether or not auditing is enabled or an 300 * error was returned. The functions that take the session handle 301 * as input generally return without doing anything if auditing is 302 * disabled. 303 */ 304 305 int 306 adt_start_session(adt_session_data_t **new_session, 307 const adt_export_data_t *imported_state, 308 adt_session_flags_t flags) 309 { 310 adt_internal_state_t *state; 311 adt_session_flags_t flgmask = ADT_FLAGS_ALL; 312 313 *new_session = NULL; /* assume failure */ 314 315 /* ensure that auditstate is set */ 316 (void) adt_audit_enabled(); 317 318 if ((flags & ~flgmask) != 0) { 319 errno = EINVAL; 320 goto return_err; 321 } 322 state = calloc(1, sizeof (adt_internal_state_t)); 323 324 if (state == NULL) 325 goto return_err; 326 327 if (adt_init(state, flags & ADT_USE_PROC_DATA) != 0) 328 goto return_err_free; /* errno from adt_init() */ 329 330 /* 331 * The imported state overwrites the initial state if the 332 * imported state represents a valid audit trail 333 */ 334 335 if (imported_state != NULL) { 336 if (adt_import(state, imported_state) != 0) 337 goto return_err_free; 338 } 339 state->as_flags = flags; 340 DPRINTF(("(%d) Starting session id = %08X\n", 341 getpid(), state->as_info.ai_asid)); 342 343 if (state->as_audit_enabled) 344 *new_session = (adt_session_data_t *)state; 345 else 346 free(state); 347 348 return (0); 349 return_err_free: 350 free(state); 351 return_err: 352 adt_write_syslog("audit session create failed", errno); 353 return (-1); 354 } 355 356 /* 357 * adt_get_asid() and adt_set_asid() 358 * 359 * if you use this interface, you are responsible to insure that the 360 * rest of the session data is populated correctly before calling 361 * adt_proccess_attr() 362 * 363 * neither of these are intended for general use and will likely 364 * remain private interfaces for a long time. Forever is a long 365 * time. In the case of adt_set_asid(), you should have a very, 366 * very good reason for setting your own session id. The process 367 * audit characteristics are not changed by put, use adt_set_proc(). 368 * 369 * These are "volatile" (more changable than "evolving") and will 370 * probably change in the S10 period. 371 */ 372 void 373 adt_get_asid(const adt_session_data_t *session_data, au_asid_t *asid) 374 { 375 376 if (session_data == NULL) { 377 *asid = 0; 378 } else { 379 assert(((adt_internal_state_t *)session_data)->as_check == 380 ADT_VALID); 381 382 *asid = ((adt_internal_state_t *)session_data)->as_info.ai_asid; 383 } 384 } 385 386 void 387 adt_set_asid(const adt_session_data_t *session_data, 388 const au_asid_t session_id) 389 { 390 391 if (session_data != NULL) { 392 assert(((adt_internal_state_t *)session_data)->as_check == 393 ADT_VALID); 394 395 ((adt_internal_state_t *)session_data)->as_have_user_data |= 396 ADT_HAVE_ASID; 397 ((adt_internal_state_t *)session_data)->as_info.ai_asid = 398 session_id; 399 } 400 } 401 402 /* 403 * adt_get_auid() and adt_set_auid() 404 * 405 * neither of these are intended for general use and will likely 406 * remain private interfaces for a long time. Forever is a long 407 * time. In the case of adt_set_auid(), you should have a very, 408 * very good reason for setting your own audit id. The process 409 * audit characteristics are not changed by put, use adt_set_proc(). 410 */ 411 void 412 adt_get_auid(const adt_session_data_t *session_data, au_id_t *auid) 413 { 414 415 if (session_data == NULL) { 416 *auid = AU_NOAUDITID; 417 } else { 418 assert(((adt_internal_state_t *)session_data)->as_check == 419 ADT_VALID); 420 421 *auid = ((adt_internal_state_t *)session_data)->as_info.ai_auid; 422 } 423 } 424 425 void 426 adt_set_auid(const adt_session_data_t *session_data, const au_id_t audit_id) 427 { 428 429 if (session_data != NULL) { 430 assert(((adt_internal_state_t *)session_data)->as_check == 431 ADT_VALID); 432 433 ((adt_internal_state_t *)session_data)->as_have_user_data |= 434 ADT_HAVE_AUID; 435 ((adt_internal_state_t *)session_data)->as_info.ai_auid = 436 audit_id; 437 } 438 } 439 440 /* 441 * adt_get_termid(), adt_set_termid() 442 * 443 * if you use this interface, you are responsible to insure that the 444 * rest of the session data is populated correctly before calling 445 * adt_proccess_attr() 446 * 447 * The process audit characteristics are not changed by put, use 448 * adt_set_proc(). 449 */ 450 void 451 adt_get_termid(const adt_session_data_t *session_data, au_tid_addr_t *termid) 452 { 453 454 if (session_data == NULL) { 455 (void) memset(termid, 0, sizeof (au_tid_addr_t)); 456 termid->at_type = AU_IPv4; 457 } else { 458 assert(((adt_internal_state_t *)session_data)->as_check == 459 ADT_VALID); 460 461 *termid = 462 ((adt_internal_state_t *)session_data)->as_info.ai_termid; 463 } 464 } 465 466 void 467 adt_set_termid(const adt_session_data_t *session_data, 468 const au_tid_addr_t *termid) 469 { 470 471 if (session_data != NULL) { 472 assert(((adt_internal_state_t *)session_data)->as_check == 473 ADT_VALID); 474 475 ((adt_internal_state_t *)session_data)->as_info.ai_termid = 476 *termid; 477 478 ((adt_internal_state_t *)session_data)->as_have_user_data |= 479 ADT_HAVE_TID; 480 } 481 } 482 483 /* 484 * adt_get_mask(), adt_set_mask() 485 * 486 * if you use this interface, you are responsible to insure that the 487 * rest of the session data is populated correctly before calling 488 * adt_proccess_attr() 489 * 490 * The process audit characteristics are not changed by put, use 491 * adt_set_proc(). 492 */ 493 void 494 adt_get_mask(const adt_session_data_t *session_data, au_mask_t *mask) 495 { 496 497 if (session_data == NULL) { 498 mask->am_success = 0; 499 mask->am_failure = 0; 500 } else { 501 assert(((adt_internal_state_t *)session_data)->as_check == 502 ADT_VALID); 503 504 *mask = ((adt_internal_state_t *)session_data)->as_info.ai_mask; 505 } 506 } 507 508 void 509 adt_set_mask(const adt_session_data_t *session_data, const au_mask_t *mask) 510 { 511 512 if (session_data != NULL) { 513 assert(((adt_internal_state_t *)session_data)->as_check == 514 ADT_VALID); 515 516 ((adt_internal_state_t *)session_data)->as_info.ai_mask = *mask; 517 518 ((adt_internal_state_t *)session_data)->as_have_user_data |= 519 ADT_HAVE_MASK; 520 } 521 } 522 523 /* 524 * helpers for adt_load_termid 525 */ 526 static void 527 adt_do_ipv6_address(struct sockaddr_in6 *peer, struct sockaddr_in6 *sock, 528 au_tid_addr_t *termid) 529 { 530 531 termid->at_port = ((peer->sin6_port<<16) | (sock->sin6_port)); 532 termid->at_type = AU_IPv6; 533 (void) memcpy(termid->at_addr, &peer->sin6_addr, 4 * sizeof (uint_t)); 534 } 535 536 static void 537 adt_do_ipv4_address(struct sockaddr_in *peer, struct sockaddr_in *sock, 538 au_tid_addr_t *termid) 539 { 540 541 termid->at_port = ((peer->sin_port<<16) | (sock->sin_port)); 542 543 termid->at_type = AU_IPv4; 544 termid->at_addr[0] = (uint32_t)peer->sin_addr.s_addr; 545 (void) memset(&(termid->at_addr[1]), 0, 3 * sizeof (uint_t)); 546 } 547 548 /* 549 * adt_load_termid: convenience function; inputs file handle and 550 * outputs an au_tid_addr struct. 551 * 552 * This code was stolen from audit_settid.c; it differs from audit_settid() 553 * in that it does not write the terminal id to the process. 554 */ 555 556 int 557 adt_load_termid(int fd, adt_termid_t **termid) 558 { 559 au_tid_addr_t *p_term; 560 struct sockaddr_in6 peer; 561 struct sockaddr_in6 sock; 562 int peerlen = sizeof (peer); 563 int socklen = sizeof (sock); 564 565 *termid = NULL; 566 567 /* get peer name if its a socket, else assume local terminal */ 568 569 if (getpeername(fd, (struct sockaddr *)&peer, (socklen_t *)&peerlen) 570 < 0) { 571 if (errno == ENOTSOCK) 572 return (adt_load_hostname(NULL, termid)); 573 goto return_err; 574 } 575 576 if ((p_term = calloc(1, sizeof (au_tid_addr_t))) == NULL) 577 goto return_err; 578 579 /* get sock name */ 580 if (getsockname(fd, (struct sockaddr *)&sock, 581 (socklen_t *)&socklen) < 0) 582 goto return_err_free; 583 584 if (peer.sin6_family == AF_INET6) { 585 adt_do_ipv6_address(&peer, &sock, p_term); 586 } else { 587 adt_do_ipv4_address((struct sockaddr_in *)&peer, 588 (struct sockaddr_in *)&sock, p_term); 589 } 590 *termid = (adt_termid_t *)p_term; 591 592 return (0); 593 594 return_err_free: 595 free(p_term); 596 return_err: 597 return (-1); 598 } 599 600 static boolean_t 601 adt_have_termid(au_tid_addr_t *dest) 602 { 603 struct auditinfo_addr audit_data; 604 605 if (getaudit_addr(&audit_data, sizeof (audit_data)) < 0) { 606 adt_write_syslog("getaudit failed", errno); 607 return (B_FALSE); 608 } 609 610 if ((audit_data.ai_termid.at_type == 0) || 611 (audit_data.ai_termid.at_addr[0] | 612 audit_data.ai_termid.at_addr[1] | 613 audit_data.ai_termid.at_addr[2] | 614 audit_data.ai_termid.at_addr[3]) == 0) 615 return (B_FALSE); 616 617 (void) memcpy(dest, &(audit_data.ai_termid), 618 sizeof (au_tid_addr_t)); 619 620 return (B_TRUE); 621 } 622 623 static int 624 adt_get_hostIP(const char *hostname, au_tid_addr_t *p_term) 625 { 626 struct addrinfo *ai; 627 void *p; 628 629 if (getaddrinfo(hostname, NULL, NULL, &ai) != 0) 630 return (-1); 631 632 switch (ai->ai_family) { 633 case AF_INET: 634 /* LINTED */ 635 p = &((struct sockaddr_in *)ai->ai_addr)->sin_addr; 636 (void) memcpy(p_term->at_addr, p, 637 sizeof (((struct sockaddr_in *)NULL)->sin_addr)); 638 p_term->at_type = AU_IPv4; 639 break; 640 case AF_INET6: 641 /* LINTED */ 642 p = &((struct sockaddr_in6 *)ai->ai_addr)->sin6_addr, 643 (void) memcpy(p_term->at_addr, p, 644 sizeof (((struct sockaddr_in6 *)NULL)->sin6_addr)); 645 p_term->at_type = AU_IPv6; 646 break; 647 default: 648 return (-1); 649 } 650 651 freeaddrinfo(ai); 652 653 return (0); 654 } 655 656 /* 657 * adt_load_hostname() is called when the caller does not have a file 658 * handle that gives access to the socket info or any other way to 659 * pass in both port and ip address. The hostname input is ignored if 660 * the terminal id has already been set; instead it returns the 661 * existing terminal id. 662 * 663 * If audit is off and the hostname lookup fails, no error is 664 * returned, since an error may be interpreted by the caller 665 * as grounds for denying a login. Otherwise the caller would 666 * need to be aware of the audit state. 667 */ 668 int 669 adt_load_hostname(const char *hostname, adt_termid_t **termid) 670 { 671 char localhost[ADT_STRING_MAX + 1]; 672 au_tid_addr_t *p_term; 673 674 *termid = NULL; 675 676 if (!adt_audit_enabled()) 677 return (0); 678 679 if ((p_term = calloc(1, sizeof (au_tid_addr_t))) == NULL) 680 goto return_err; 681 682 if (adt_have_termid(p_term)) { 683 *termid = (adt_termid_t *)p_term; 684 return (0); 685 } 686 p_term->at_port = 0; 687 688 if (hostname == NULL || *hostname == '\0') { 689 (void) sysinfo(SI_HOSTNAME, localhost, ADT_STRING_MAX); 690 hostname = localhost; 691 } 692 if (adt_get_hostIP(hostname, p_term)) 693 goto return_err_free; 694 695 *termid = (adt_termid_t *)p_term; 696 return (0); 697 698 return_err_free: 699 free(p_term); 700 701 return_err: 702 if ((auditstate == AUC_DISABLED) || 703 (auditstate == AUC_NOAUDIT)) 704 return (0); 705 706 return (-1); 707 } 708 709 /* 710 * adt_load_ttyname() is called when the caller does not have a file 711 * handle that gives access to the local terminal or any other way 712 * of determining the device id. The ttyname input is ignored if 713 * the terminal id has already been set; instead it returns the 714 * existing terminal id. 715 * 716 * If audit is off and the ttyname lookup fails, no error is 717 * returned, since an error may be interpreted by the caller 718 * as grounds for denying a login. Otherwise the caller would 719 * need to be aware of the audit state. 720 */ 721 int 722 adt_load_ttyname(const char *ttyname, adt_termid_t **termid) 723 { 724 char localhost[ADT_STRING_MAX + 1]; 725 au_tid_addr_t *p_term; 726 struct stat stat_buf; 727 728 *termid = NULL; 729 730 if (!adt_audit_enabled()) 731 return (0); 732 733 if ((p_term = calloc(1, sizeof (au_tid_addr_t))) == NULL) 734 goto return_err; 735 736 if (adt_have_termid(p_term)) { 737 *termid = (adt_termid_t *)p_term; 738 return (0); 739 } 740 741 p_term->at_port = 0; 742 743 if (sysinfo(SI_HOSTNAME, localhost, ADT_STRING_MAX) < 0) 744 goto return_err_free; /* errno from sysinfo */ 745 746 if (ttyname != NULL) { 747 if (stat(ttyname, &stat_buf) < 0) 748 goto return_err_free; 749 750 p_term->at_port = stat_buf.st_rdev; 751 } 752 753 if (adt_get_hostIP(localhost, p_term)) 754 goto return_err_free; 755 756 *termid = (adt_termid_t *)p_term; 757 return (0); 758 759 return_err_free: 760 free(p_term); 761 762 return_err: 763 if ((auditstate == AUC_DISABLED) || 764 (auditstate == AUC_NOAUDIT)) 765 return (0); 766 767 return (-1); 768 } 769 770 /* 771 * adt_get_session_id returns a stringified representation of 772 * the audit session id. See also adt_get_asid() for how to 773 * get the unexpurgated version. No guarantees as to how long 774 * the returned string will be or its general form; hex for now. 775 * 776 * An empty string is returned if auditing is off; length = 1 777 * and the pointer is valid. 778 * 779 * returns strlen + 1 if buffer is valid; else 0 and errno. 780 */ 781 782 size_t 783 adt_get_session_id(const adt_session_data_t *session_data, char **buff) 784 { 785 au_asid_t session_id; 786 size_t length; 787 /* 788 * output is 0x followed by 789 * two characters per byte 790 * plus terminator, 791 * except leading 0's are suppressed, so a few bytes may 792 * be unused. 793 */ 794 length = 2 + (2 * sizeof (session_id)) + 1; 795 *buff = malloc(length); 796 797 if (*buff == NULL) { 798 length = 0; 799 goto return_length; 800 } 801 if (session_data == NULL) { /* NULL is not an error */ 802 **buff = '\0'; 803 length = 1; 804 goto return_length; /* empty string */ 805 } 806 adt_get_asid(session_data, &session_id); 807 808 length = snprintf(*buff, length, "0x%X", (int)session_id); 809 810 /* length < 1 is a bug: the session data type may have changed */ 811 assert(length > 0); 812 813 return_length: 814 return (length); 815 } 816 817 /* 818 * adt_end_session -- close handle, clear context 819 * 820 * if as_check is invalid, no harm, no foul, EXCEPT that this could 821 * be an attempt to free data already free'd, so output to syslog 822 * to help explain why the process cored dumped. 823 */ 824 825 int 826 adt_end_session(adt_session_data_t *session_data) 827 { 828 adt_internal_state_t *state; 829 830 if (session_data != NULL) { 831 state = (adt_internal_state_t *)session_data; 832 if (state->as_check != ADT_VALID) 833 adt_write_syslog("freeing invalid data", EINVAL); 834 else { 835 state->as_check = 0; 836 free(session_data); 837 } 838 } 839 /* no errors yet defined */ 840 return (0); 841 } 842 843 /* 844 * adt_dup_session -- copy the session data 845 */ 846 847 int 848 adt_dup_session(const adt_session_data_t *source, adt_session_data_t **dest) 849 { 850 adt_internal_state_t *source_state; 851 adt_session_data_t *dest_state = NULL; 852 int rc = 0; 853 854 if (source != NULL) { 855 source_state = (adt_internal_state_t *)source; 856 assert(source_state->as_check == ADT_VALID); 857 858 dest_state = malloc(sizeof (adt_internal_state_t)); 859 if (dest_state == NULL) { 860 rc = -1; 861 goto return_rc; 862 } 863 (void) memcpy(dest_state, source, 864 sizeof (struct adt_internal_state)); 865 } 866 return_rc: 867 *dest = dest_state; 868 return (rc); 869 } 870 871 /* 872 * from_export_format() 873 * read from a network order buffer into struct adt_session_data 874 */ 875 static size_t 876 adt_from_export_format(adt_internal_state_t *internal, 877 const adt_export_data_t *external) 878 { 879 struct export_header head; 880 struct export_link link; 881 adr_t context; 882 int32_t offset; 883 int32_t length; 884 int32_t version; 885 char *p = (char *)external; 886 887 adrm_start(&context, (char *)external); 888 adrm_int32(&context, (int *)&head, 4); 889 890 if ((internal->as_check = head.ax_check) != ADT_VALID) { 891 errno = EINVAL; 892 return (0); 893 } 894 offset = head.ax_link.ax_offset; 895 version = head.ax_link.ax_version; 896 length = head.ax_buffer_length; 897 898 /* 899 * adjust buffer pointer to the first data item (euid) 900 * if versions mismatch; otherwise it's ok as is. 901 */ 902 while (version != PROTOCOL_VERSION) { 903 if (offset < 1) 904 return (0); /* failed to match version */ 905 p += offset; /* point to next version # */ 906 907 if (p > (char *)external + length) { 908 return (0); 909 } 910 adrm_start(&context, p); 911 adrm_int32(&context, (int *)&link, 2); 912 offset = link.ax_offset; 913 version = link.ax_version; 914 assert(version != 0); 915 } 916 if (p == (char *)external) 917 adrm_start(&context, (char *)(p + sizeof (head))); 918 else 919 adrm_start(&context, (char *)(p + sizeof (link))); 920 921 adrm_int32(&context, (int *)&(internal->as_euid), 1); 922 adrm_int32(&context, (int *)&(internal->as_ruid), 1); 923 adrm_int32(&context, (int *)&(internal->as_egid), 1); 924 adrm_int32(&context, (int *)&(internal->as_rgid), 1); 925 adrm_int32(&context, (int *)&(internal->as_info.ai_auid), 1); 926 adrm_int32(&context, (int *)&(internal->as_info.ai_mask.am_success), 2); 927 adrm_int32(&context, (int *)&(internal->as_info.ai_termid.at_port), 1); 928 adrm_int32(&context, (int *)&(internal->as_info.ai_termid.at_type), 1); 929 adrm_int32(&context, (int *)&(internal->as_info.ai_termid.at_addr[0]), 930 4); 931 adrm_int32(&context, (int *)&(internal->as_info.ai_asid), 1); 932 adrm_int32(&context, (int *)&(internal->as_audit_enabled), 1); 933 934 /* ax_size_of_tsol_data intentionally ignored */ 935 936 return (sizeof (struct adt_export_data)); 937 } 938 939 /* 940 * to_export_format 941 * read from struct adt_session_data into a network order buffer. 942 * 943 * (network order 'cause this data may be shared with a remote host.) 944 */ 945 946 static size_t 947 adt_to_export_format(adt_export_data_t *external, 948 adt_internal_state_t *internal) 949 { 950 struct export_header head; 951 struct export_link tail; 952 adr_t context; 953 size_t tsol_size = 0; 954 955 adrm_start(&context, (char *)external); 956 957 head.ax_check = ADT_VALID; 958 head.ax_buffer_length = sizeof (struct adt_export_data); 959 head.ax_link.ax_version = PROTOCOL_VERSION; 960 head.ax_link.ax_offset = 0; 961 adrm_putint32(&context, (int *)&head, 4); 962 963 adrm_putint32(&context, (int *)&(internal->as_euid), 1); 964 adrm_putint32(&context, (int *)&(internal->as_ruid), 1); 965 adrm_putint32(&context, (int *)&(internal->as_egid), 1); 966 adrm_putint32(&context, (int *)&(internal->as_rgid), 1); 967 adrm_putint32(&context, (int *)&(internal->as_info.ai_auid), 1); 968 adrm_putint32(&context, 969 (int *)&(internal->as_info.ai_mask.am_success), 2); 970 adrm_putint32(&context, 971 (int *)&(internal->as_info.ai_termid.at_port), 1); 972 adrm_putint32(&context, 973 (int *)&(internal->as_info.ai_termid.at_type), 1); 974 adrm_putint32(&context, 975 (int *)&(internal->as_info.ai_termid.at_addr[0]), 4); 976 adrm_putint32(&context, (int *)&(internal->as_info.ai_asid), 1); 977 adrm_putint32(&context, (int *)&(internal->as_audit_enabled), 1); 978 adrm_putint32(&context, (int *)&tsol_size, 1); 979 980 /* terminator */ 981 tail.ax_version = 0; /* invalid version number */ 982 tail.ax_offset = 0; 983 984 adrm_putint32(&context, (int *)&tail, 2); 985 986 return (sizeof (struct adt_export_data)); 987 } 988 989 /* 990 * adt_import_proc() is used by a server acting on behalf 991 * of a client which has connected via an ipc mechanism such as 992 * a door. 993 * 994 * Since the interface is via ucred, the info.ap_termid.port 995 * value is always the 64 bit version. What is stored depends 996 * on how libbsm is compiled. 997 */ 998 size_t 999 adt_import_proc(pid_t pid, uid_t euid, gid_t egid, uid_t ruid, 1000 gid_t rgid, adt_export_data_t **external) 1001 { 1002 size_t length = 0; 1003 adt_internal_state_t *state; 1004 ucred_t *ucred; 1005 const au_tid64_addr_t *tid; 1006 1007 state = calloc(1, sizeof (adt_internal_state_t)); 1008 1009 if (state == NULL) 1010 goto return_length; 1011 1012 if (adt_init(state, 0) != 0) 1013 goto return_length_free; /* errno from adt_init() */ 1014 1015 /* 1016 * ucred_getauid() returns AU_NOAUDITID if audit is off, which 1017 * is the right answer for adt_import_proc(). 1018 * 1019 * Create a local context as near as possible. 1020 */ 1021 1022 ucred = ucred_get(pid); 1023 1024 if (ucred == NULL) 1025 goto return_length_free; 1026 1027 state->as_ruid = ruid != ADT_NO_CHANGE ? ruid : ucred_getruid(ucred); 1028 state->as_euid = euid != ADT_NO_CHANGE ? euid : ucred_geteuid(ucred); 1029 state->as_rgid = rgid != ADT_NO_CHANGE ? rgid : ucred_getrgid(ucred); 1030 state->as_egid = egid != ADT_NO_CHANGE ? egid : ucred_getegid(ucred); 1031 1032 state->as_info.ai_auid = ucred_getauid(ucred); 1033 1034 if (state->as_info.ai_auid == AU_NOAUDITID) { 1035 state->as_info.ai_asid = adt_get_unique_id(ruid); 1036 1037 if (adt_get_mask_from_user(ruid, &(state->as_info.ai_mask))) 1038 goto return_all_free; 1039 } else { 1040 const au_mask_t *mask = ucred_getamask(ucred); 1041 1042 if (mask != NULL) 1043 state->as_info.ai_mask = *mask; 1044 else 1045 goto return_all_free; 1046 1047 state->as_info.ai_asid = ucred_getasid(ucred); 1048 } 1049 1050 tid = ucred_getatid(ucred); 1051 1052 if (tid != NULL) { 1053 adt_cpy_tid(&(state->as_info.ai_termid), tid); 1054 } else { 1055 (void) memset((void *)&(state->as_info.ai_termid), 0, 1056 sizeof (au_tid_addr_t)); 1057 state->as_info.ai_termid.at_type = AU_IPv4; 1058 } 1059 1060 DPRINTF(("import_proc/asid = %X %u\n", state->as_info.ai_asid, 1061 state->as_info.ai_asid)); 1062 1063 DPRINTF(("import_proc/masks = %X %X\n", 1064 state->as_info.ai_mask.am_success, 1065 state->as_info.ai_mask.am_failure)); 1066 1067 *external = malloc(sizeof (adt_export_data_t)); 1068 1069 if (*external == NULL) 1070 goto return_all_free; 1071 1072 length = adt_to_export_format(*external, state); 1073 /* 1074 * yes, state is supposed to be free'd for both pass and fail 1075 */ 1076 return_all_free: 1077 ucred_free(ucred); 1078 return_length_free: 1079 free(state); 1080 return_length: 1081 return (length); 1082 } 1083 1084 /* 1085 * adt_import() -- convert from network order to machine-specific order 1086 */ 1087 static int 1088 adt_import(adt_internal_state_t *internal, const adt_export_data_t *external) 1089 { 1090 au_mask_t mask; 1091 1092 /* save local audit enabled state */ 1093 int local_audit_enabled = internal->as_audit_enabled; 1094 1095 if (adt_from_export_format(internal, external) < 1) 1096 return (-1); /* errno from adt_from_export_format */ 1097 1098 /* 1099 * If audit isn't enabled on the remote, they were unable 1100 * to generate the audit mask, so generate it based on 1101 * local configuration. If the user id has changed, the 1102 * resulting mask may miss some subtleties that occurred 1103 * on the remote system. 1104 * 1105 * If the remote failed to generate a terminal id, it is not 1106 * recoverable. 1107 */ 1108 1109 if (!internal->as_audit_enabled) { 1110 if (adt_get_mask_from_user(internal->as_info.ai_auid, 1111 &(internal->as_info.ai_mask))) 1112 return (-1); 1113 if (internal->as_info.ai_auid != internal->as_ruid) { 1114 if (adt_get_mask_from_user(internal->as_info.ai_auid, 1115 &mask)) 1116 return (-1); 1117 internal->as_info.ai_mask.am_success |= 1118 mask.am_success; 1119 internal->as_info.ai_mask.am_failure |= 1120 mask.am_failure; 1121 } 1122 } 1123 internal->as_audit_enabled = local_audit_enabled; 1124 1125 DPRINTF(("(%d)imported asid = %X %u\n", getpid(), 1126 internal->as_info.ai_asid, 1127 internal->as_info.ai_asid)); 1128 1129 internal->as_have_user_data = ADT_HAVE_ALL; 1130 1131 return (0); 1132 } 1133 1134 /* 1135 * adt_export_session_data() 1136 * copies a adt_session_data struct into a network order buffer 1137 * 1138 * In a misconfigured network, the local host may have auditing 1139 * off while the destination may have auditing on, so if there 1140 * is sufficient memory, a buffer will be returned even in the 1141 * audit off case. 1142 */ 1143 size_t 1144 adt_export_session_data(const adt_session_data_t *internal, 1145 adt_export_data_t **external) 1146 { 1147 adt_internal_state_t *dummy; 1148 size_t length = 0; 1149 1150 *external = malloc(sizeof (adt_export_data_t)); 1151 1152 if (*external == NULL) 1153 goto return_length; 1154 1155 if (internal == NULL) { 1156 dummy = malloc(sizeof (adt_internal_state_t)); 1157 if (dummy == NULL) 1158 goto return_length_free; 1159 1160 if (adt_init(dummy, 0)) { /* 0 == don't copy from proc */ 1161 free(dummy); 1162 goto return_length_free; 1163 } 1164 length = adt_to_export_format(*external, dummy); 1165 free(dummy); 1166 } else { 1167 length = adt_to_export_format(*external, 1168 (adt_internal_state_t *)internal); 1169 } 1170 1171 return_length: 1172 return (length); 1173 1174 return_length_free: 1175 free(*external); 1176 *external = NULL; 1177 return (length); 1178 } 1179 1180 static void 1181 adt_setto_unaudited(adt_internal_state_t *state) 1182 { 1183 state->as_ruid = AU_NOAUDITID; 1184 state->as_euid = AU_NOAUDITID; 1185 state->as_rgid = AU_NOAUDITID; 1186 state->as_egid = AU_NOAUDITID; 1187 1188 if (state->as_audit_enabled) { 1189 state->as_info.ai_asid = 0; 1190 state->as_info.ai_auid = AU_NOAUDITID; 1191 1192 (void) memset((void *)&(state->as_info.ai_termid), 0, 1193 sizeof (au_tid_addr_t)); 1194 state->as_info.ai_termid.at_type = AU_IPv4; 1195 1196 (void) memset((void *)&(state->as_info.ai_mask), 0, 1197 sizeof (au_mask_t)); 1198 state->as_have_user_data = 0; 1199 } 1200 } 1201 1202 /* 1203 * adt_init -- set session context by copying the audit characteristics 1204 * from the proc and picking up current uid/tid information. 1205 * 1206 * By default, an audit session is based on the process; the default 1207 * is overriden by adt_set_user() 1208 */ 1209 static int 1210 adt_init(adt_internal_state_t *state, int use_proc_data) 1211 { 1212 1213 state->as_audit_enabled = (auditstate == AUC_DISABLED) ? 0 : 1; 1214 1215 if (use_proc_data) { 1216 state->as_ruid = getuid(); 1217 state->as_euid = geteuid(); 1218 state->as_rgid = getgid(); 1219 state->as_egid = getegid(); 1220 1221 if (state->as_audit_enabled) { 1222 const au_tid64_addr_t *tid; 1223 const au_mask_t *mask; 1224 ucred_t *ucred = ucred_get(getpid()); 1225 1226 /* 1227 * Even if the ucred is NULL, the underlying 1228 * credential may have a valid terminal id; if the 1229 * terminal id is set, then that's good enough. An 1230 * example of where this matters is failed login, 1231 * where rlogin/telnet sets the terminal id before 1232 * calling login; login does not load the credential 1233 * since auth failed. 1234 */ 1235 if (ucred == NULL) { 1236 if (!adt_have_termid( 1237 &(state->as_info.ai_termid))) 1238 return (-1); 1239 } else { 1240 mask = ucred_getamask(ucred); 1241 if (mask != NULL) { 1242 state->as_info.ai_mask = *mask; 1243 } else { 1244 ucred_free(ucred); 1245 return (-1); 1246 } 1247 tid = ucred_getatid(ucred); 1248 if (tid != NULL) { 1249 adt_cpy_tid(&(state->as_info.ai_termid), 1250 tid); 1251 } else { 1252 ucred_free(ucred); 1253 return (-1); 1254 } 1255 state->as_info.ai_asid = ucred_getasid(ucred); 1256 state->as_info.ai_auid = ucred_getauid(ucred); 1257 ucred_free(ucred); 1258 } 1259 state->as_have_user_data = ADT_HAVE_ALL; 1260 } 1261 } else { 1262 adt_setto_unaudited(state); 1263 } 1264 state->as_session_model = ADT_SESSION_MODEL; /* default */ 1265 1266 if (state->as_audit_enabled && 1267 auditon(A_GETPOLICY, (caddr_t)&(state->as_kernel_audit_policy), 1268 sizeof (state->as_kernel_audit_policy))) { 1269 return (-1); /* errno set by auditon */ 1270 } 1271 state->as_check = ADT_VALID; 1272 return (0); 1273 } 1274 1275 /* 1276 * adt_set_proc 1277 * 1278 * Copy the current session state to the process. If this function 1279 * is called, the model becomes a process model rather than a 1280 * session model. 1281 * 1282 * In the current implementation, the value state->as_have_user_data 1283 * must contain all of: ADT_HAVE_{AUID,MASK,TID,ASID}. These are all set 1284 * by adt_set_user() when the ADT_SETTID or ADT_NEW flag is passed in. 1285 * 1286 */ 1287 1288 int 1289 adt_set_proc(const adt_session_data_t *session_data) 1290 { 1291 int rc; 1292 adt_internal_state_t *state; 1293 1294 if (auditstate == AUC_DISABLED || (session_data == NULL)) 1295 return (0); 1296 1297 state = (adt_internal_state_t *)session_data; 1298 1299 assert(state->as_check == ADT_VALID); 1300 1301 if ((state->as_have_user_data & (ADT_HAVE_ALL & ~ADT_HAVE_IDS)) != 1302 (ADT_HAVE_ALL & ~ADT_HAVE_IDS)) { 1303 errno = EINVAL; 1304 goto return_err; 1305 } 1306 1307 rc = setaudit_addr((auditinfo_addr_t *)&(state->as_info), 1308 sizeof (auditinfo_addr_t)); 1309 1310 if (rc < 0) 1311 goto return_err; /* errno set by setaudit_addr() */ 1312 1313 state->as_session_model = ADT_PROCESS_MODEL; 1314 1315 return (0); 1316 1317 return_err: 1318 adt_write_syslog("failed to set process audit characteristics", errno); 1319 return (-1); 1320 } 1321 1322 static int 1323 adt_newuser(adt_internal_state_t *state, uid_t ruid, au_tid_addr_t *termid) 1324 { 1325 au_tid_addr_t no_tid = {0, AU_IPv4, 0, 0, 0, 0}; 1326 au_mask_t no_mask = {0, 0}; 1327 1328 if (ruid == ADT_NO_AUDIT) { 1329 state->as_info.ai_auid = AU_NOAUDITID; 1330 state->as_info.ai_asid = 0; 1331 state->as_info.ai_termid = no_tid; 1332 state->as_info.ai_mask = no_mask; 1333 return (0); 1334 } 1335 state->as_info.ai_auid = ruid; 1336 state->as_info.ai_asid = adt_get_unique_id(ruid); 1337 if (termid != NULL) 1338 state->as_info.ai_termid = *termid; 1339 1340 if (adt_get_mask_from_user(ruid, &(state->as_info.ai_mask))) 1341 return (-1); 1342 1343 return (0); 1344 } 1345 static int 1346 adt_changeuser(adt_internal_state_t *state, uid_t ruid) 1347 { 1348 au_mask_t mask; 1349 1350 if (!(state->as_have_user_data & ADT_HAVE_AUID)) 1351 state->as_info.ai_auid = ruid; 1352 if (!(state->as_have_user_data & ADT_HAVE_ASID)) 1353 state->as_info.ai_asid = adt_get_unique_id(ruid); 1354 1355 if (ruid >= 0) { 1356 if (adt_get_mask_from_user(ruid, &mask)) 1357 return (-1); 1358 1359 state->as_info.ai_mask.am_success |= mask.am_success; 1360 state->as_info.ai_mask.am_failure |= mask.am_failure; 1361 } 1362 DPRINTF(("changed mask to %08X/%08X for ruid=%d\n", 1363 state->as_info.ai_mask.am_success, 1364 state->as_info.ai_mask.am_failure, 1365 ruid)); 1366 return (0); 1367 } 1368 /* 1369 * adt_set_user -- see also adt_set_from_ucred() 1370 * 1371 * ADT_NO_ATTRIB is a valid uid/gid meaning "not known" or 1372 * "unattributed." 1373 * 1374 * ADT_NO_CHANGE is a valid uid/gid meaning "do not change this value" 1375 * only valid with ADT_UPDATE. 1376 * 1377 * ADT_NO_AUDIT is the external equivalent to AU_NOAUDITIT -- there 1378 * isn't a good reason to call adt_set_user() with it unless you don't 1379 * have a good value yet and intend to replace it later; auid will be 1380 * AU_NOAUDITID. 1381 * 1382 * adt_set_user should be called even if auditing is not enabled 1383 * so that adt_export_session_data() will have useful stuff to 1384 * work with. 1385 * 1386 * See the note preceding adt_set_proc() about the use of ADT_HAVE_TID 1387 * and ADT_HAVE_ALL. 1388 */ 1389 int 1390 adt_set_user(const adt_session_data_t *session_data, 1391 uid_t euid, 1392 gid_t egid, 1393 uid_t ruid, 1394 gid_t rgid, 1395 const adt_termid_t *termid, 1396 enum adt_user_context user_context) 1397 { 1398 adt_internal_state_t *state; 1399 int rc; 1400 1401 if (session_data == NULL) /* no session exists to audit */ 1402 return (0); 1403 1404 state = (adt_internal_state_t *)session_data; 1405 assert(state->as_check == ADT_VALID); 1406 1407 switch (user_context) { 1408 case ADT_NEW: 1409 if (ruid == ADT_NO_CHANGE || euid == ADT_NO_CHANGE || 1410 rgid == ADT_NO_CHANGE || egid == ADT_NO_CHANGE) { 1411 errno = EINVAL; 1412 return (-1); 1413 } 1414 if ((rc = adt_newuser(state, ruid, 1415 (au_tid_addr_t *)termid)) != 0) 1416 return (rc); 1417 1418 state->as_have_user_data = ADT_HAVE_ALL; 1419 break; 1420 case ADT_UPDATE: 1421 if (state->as_have_user_data != ADT_HAVE_ALL) { 1422 errno = EINVAL; 1423 return (-1); 1424 } 1425 1426 if (ruid != ADT_NO_CHANGE) 1427 if ((rc = adt_changeuser(state, ruid)) != 0) 1428 return (rc); 1429 break; 1430 case ADT_USER: 1431 if (state->as_have_user_data != ADT_HAVE_ALL) { 1432 errno = EINVAL; 1433 return (-1); 1434 } 1435 break; 1436 case ADT_SETTID: 1437 assert(termid != NULL); 1438 state->as_info.ai_termid = *((au_tid_addr_t *)termid); 1439 /* avoid fooling pam_setcred()... */ 1440 state->as_info.ai_auid = AU_NOAUDITID; 1441 state->as_info.ai_asid = 0; 1442 state->as_info.ai_mask.am_failure = 0; 1443 state->as_info.ai_mask.am_success = 0; 1444 state->as_have_user_data = ADT_HAVE_TID | 1445 ADT_HAVE_AUID | ADT_HAVE_ASID | ADT_HAVE_MASK; 1446 return (0); 1447 break; 1448 1449 default: 1450 errno = EINVAL; 1451 return (-1); 1452 } 1453 1454 if (ruid == ADT_NO_AUDIT) { 1455 state->as_ruid = AU_NOAUDITID; 1456 state->as_euid = AU_NOAUDITID; 1457 state->as_rgid = AU_NOAUDITID; 1458 state->as_egid = AU_NOAUDITID; 1459 } else { 1460 if (ruid != ADT_NO_CHANGE) 1461 state->as_ruid = ruid; 1462 if (euid != ADT_NO_CHANGE) 1463 state->as_euid = euid; 1464 if (rgid != ADT_NO_CHANGE) 1465 state->as_rgid = rgid; 1466 if (egid != ADT_NO_CHANGE) 1467 state->as_egid = egid; 1468 } 1469 1470 return (0); 1471 } 1472 /* 1473 * adt_set_from_ucred() 1474 * 1475 * an alternate to adt_set_user that fills the same role but uses 1476 * a pointer to a ucred rather than a list of id's. If the ucred 1477 * pointer is NULL, use the credential from the this process. 1478 * 1479 * A key difference is that for ADT_NEW, adt_set_from_ucred() does 1480 * not overwrite the asid and auid unless auid has not been set. 1481 * ADT_NEW differs from ADT_UPDATE in that it does not OR together 1482 * the incoming audit mask with the one that already exists. 1483 * 1484 * adt_set_from_ucred should be called even if auditing is not enabled 1485 * so that adt_export_session_data() will have useful stuff to 1486 * work with. 1487 */ 1488 int 1489 adt_set_from_ucred(const adt_session_data_t *session_data, 1490 const ucred_t *uc, enum adt_user_context user_context) 1491 { 1492 adt_internal_state_t *state; 1493 int rc = -1; 1494 const au_tid64_addr_t *tid64; 1495 au_tid_addr_t termid, *tid; 1496 ucred_t *ucred = (ucred_t *)uc; 1497 boolean_t local_uc = B_FALSE; 1498 1499 if (session_data == NULL) /* no session exists to audit */ 1500 return (0); 1501 1502 state = (adt_internal_state_t *)session_data; 1503 assert(state->as_check == ADT_VALID); 1504 1505 if (ucred == NULL) { 1506 ucred = ucred_get(getpid()); 1507 1508 if (ucred == NULL) 1509 goto return_rc; 1510 local_uc = B_TRUE; 1511 } 1512 1513 switch (user_context) { 1514 case ADT_NEW: 1515 tid64 = ucred_getatid(ucred); 1516 if (tid64 != NULL) { 1517 adt_cpy_tid(&termid, tid64); 1518 tid = &termid; 1519 } else { 1520 tid = NULL; 1521 } 1522 /* if unaudited, adt_newuser cleans up */ 1523 if (ucred_getauid(ucred) == AU_NOAUDITID) { 1524 if ((rc = adt_newuser(state, ucred_getruid(ucred), 1525 tid)) != 0) 1526 goto return_rc; 1527 } else { 1528 state->as_info.ai_auid = ucred_getauid(ucred); 1529 state->as_info.ai_asid = ucred_getasid(ucred); 1530 state->as_info.ai_mask = *ucred_getamask(ucred); 1531 state->as_info.ai_termid = *tid; 1532 } 1533 state->as_have_user_data = ADT_HAVE_ALL; 1534 break; 1535 case ADT_UPDATE: 1536 if (state->as_have_user_data != ADT_HAVE_ALL) { 1537 errno = EINVAL; 1538 goto return_rc; 1539 } 1540 1541 if ((rc = adt_changeuser(state, ucred_getruid(ucred))) != 0) 1542 goto return_rc; 1543 break; 1544 case ADT_USER: 1545 if (state->as_have_user_data != ADT_HAVE_ALL) { 1546 errno = EINVAL; 1547 goto return_rc; 1548 } 1549 break; 1550 default: 1551 errno = EINVAL; 1552 goto return_rc; 1553 } 1554 rc = 0; 1555 1556 state->as_ruid = ucred_getruid(ucred); 1557 state->as_euid = ucred_geteuid(ucred); 1558 state->as_rgid = ucred_getrgid(ucred); 1559 state->as_egid = ucred_getegid(ucred); 1560 1561 return_rc: 1562 if (local_uc) { 1563 ucred_free(ucred); 1564 } 1565 return (rc); 1566 } 1567 1568 /* 1569 * adt_alloc_event() returns a pointer to allocated memory 1570 * 1571 */ 1572 1573 adt_event_data_t 1574 *adt_alloc_event(const adt_session_data_t *session_data, au_event_t event_id) 1575 { 1576 struct adt_event_state *event_state; 1577 adt_internal_state_t *session_state; 1578 adt_event_data_t *return_event = NULL; 1579 /* 1580 * need to return a valid event pointer even if audit is 1581 * off, else the caller will end up either (1) keeping its 1582 * own flags for on/off or (2) writing to a NULL pointer. 1583 * If auditing is on, the session data must be valid; otherwise 1584 * we don't care. 1585 */ 1586 if (session_data != NULL) { 1587 session_state = (adt_internal_state_t *)session_data; 1588 assert(session_state->as_check == ADT_VALID); 1589 } 1590 event_state = calloc(1, sizeof (struct adt_event_state)); 1591 if (event_state == NULL) 1592 goto return_ptr; 1593 1594 event_state->ae_check = ADT_VALID; 1595 1596 event_state->ae_event_id = event_id; 1597 event_state->ae_session = (struct adt_internal_state *)session_data; 1598 1599 return_event = (adt_event_data_t *)&(event_state->ae_event_data); 1600 1601 /* 1602 * preload data so the adt_au_*() functions can detect un-supplied 1603 * values (0 and NULL are free via calloc()). 1604 */ 1605 adt_preload(event_id, return_event); 1606 1607 return_ptr: 1608 return (return_event); 1609 } 1610 1611 /* 1612 * adt_getXlateTable -- look up translation table address for event id 1613 */ 1614 1615 static struct translation * 1616 adt_getXlateTable(au_event_t event_id) 1617 { 1618 /* xlate_table is global in adt_xlate.c */ 1619 struct translation **p_xlate = &xlate_table[0]; 1620 struct translation *p_event; 1621 1622 while (*p_xlate != NULL) { 1623 p_event = *p_xlate; 1624 if (event_id == p_event->tx_external_event) 1625 return (p_event); 1626 p_xlate++; 1627 } 1628 return (NULL); 1629 } 1630 1631 /* 1632 * adt_calcOffsets 1633 * 1634 * the call to this function is surrounded by a mutex. 1635 * 1636 * i walks down the table picking up next_token. j walks again to 1637 * calculate the offset to the input data. k points to the next 1638 * token's row. Finally, l, is used to sum the values in the 1639 * datadef array. 1640 * 1641 * What's going on? The entry array is in the order of the input 1642 * fields but the processing of array entries is in the order of 1643 * the output (see next_token). Calculating the offset to the 1644 * "next" input can't be done in the outer loop (i) since i doesn't 1645 * point to the current entry and it can't be done with the k index 1646 * because it doesn't represent the order of input fields. 1647 * 1648 * While the resulting algorithm is n**2, it is only done once per 1649 * event type. 1650 */ 1651 1652 /* 1653 * adt_calcOffsets is only called once per event type, but it uses 1654 * the address alignment of memory allocated for that event as if it 1655 * were the same for all subsequently allocated memory. This is 1656 * guaranteed by calloc/malloc. Arrays take special handling since 1657 * what matters for figuring out the correct alignment is the size 1658 * of the array element. 1659 */ 1660 1661 static void 1662 adt_calcOffsets(struct entry *p_entry, int tablesize, void *p_data) 1663 { 1664 int i, j; 1665 size_t this_size, prev_size; 1666 void *struct_start = p_data; 1667 1668 for (i = 0; i < tablesize; i++) { 1669 if (p_entry[i].en_type_def == NULL) { 1670 p_entry[i].en_offset = 0; 1671 continue; 1672 } 1673 prev_size = 0; 1674 p_entry[i].en_offset = (char *)p_data - (char *)struct_start; 1675 1676 for (j = 0; j < p_entry[i].en_count_types; j++) { 1677 if (p_entry[i].en_type_def[j].dd_datatype == ADT_MSG) 1678 this_size = sizeof (enum adt_generic); 1679 else 1680 this_size = 1681 p_entry[i].en_type_def[j].dd_input_size; 1682 1683 /* adj for first entry */ 1684 if (prev_size == 0) 1685 prev_size = this_size; 1686 1687 if (p_entry[i].en_type_def[j].dd_datatype == 1688 ADT_UINT32ARRAY) { 1689 p_data = (char *)adt_adjust_address(p_data, 1690 prev_size, sizeof (uint32_t)) + 1691 this_size - sizeof (uint32_t); 1692 1693 prev_size = sizeof (uint32_t); 1694 } else { 1695 p_data = adt_adjust_address(p_data, prev_size, 1696 this_size); 1697 prev_size = this_size; 1698 } 1699 } 1700 } 1701 } 1702 1703 /* 1704 * adt_generate_event 1705 * generate event record from external struct. The order is based on 1706 * the output tokens, allowing for the possibility that the input data 1707 * is in a different order. 1708 * 1709 */ 1710 1711 static void 1712 adt_generate_event(const adt_event_data_t *p_extdata, 1713 struct adt_event_state *p_event, 1714 struct translation *p_xlate) 1715 { 1716 struct entry *p_entry; 1717 static mutex_t lock = DEFAULTMUTEX; 1718 1719 p_entry = p_xlate->tx_first_entry; 1720 assert(p_entry != NULL); 1721 1722 p_event->ae_internal_id = p_xlate->tx_internal_event; 1723 adt_token_open(p_event); 1724 1725 /* 1726 * offsets are not pre-calculated; the initial offsets are all 1727 * 0; valid offsets are >= 0. Offsets for no-input tokens such 1728 * as subject are set to -1 by adt_calcOffset() 1729 */ 1730 if (p_xlate->tx_offsetsCalculated == 0) { 1731 (void) _mutex_lock(&lock); 1732 p_xlate->tx_offsetsCalculated = 1; 1733 1734 adt_calcOffsets(p_xlate->tx_top_entry, p_xlate->tx_entries, 1735 (void *)p_extdata); 1736 (void) _mutex_unlock(&lock); 1737 } 1738 while (p_entry != NULL) { 1739 adt_generate_token(p_entry, (char *)p_extdata, 1740 p_event); 1741 1742 p_entry = p_entry->en_next_token; 1743 } 1744 adt_token_close(p_event); 1745 } 1746 1747 /* 1748 * adt_put_event -- main event generation function. 1749 * The input "event" is the address of the struct containing 1750 * event-specific data. 1751 * 1752 * However if auditing is off or the session handle 1753 * is NULL, no attempt to write a record is made. 1754 */ 1755 1756 int 1757 adt_put_event(const adt_event_data_t *event, int status, 1758 int return_val) 1759 { 1760 struct adt_event_state *event_state; 1761 struct translation *xlate; 1762 int rc = 0; 1763 1764 if (event == NULL) { 1765 errno = EINVAL; 1766 rc = -1; 1767 goto return_rc; 1768 } 1769 event_state = (struct adt_event_state *)event; 1770 1771 /* if audit off or this is a broken session, exit */ 1772 if (auditstate == AUC_DISABLED || (event_state->ae_session == NULL)) 1773 goto return_rc; 1774 1775 assert(event_state->ae_check == ADT_VALID); 1776 1777 event_state->ae_rc = status; 1778 event_state->ae_type = return_val; 1779 1780 /* look up the event */ 1781 1782 xlate = adt_getXlateTable(event_state->ae_event_id); 1783 1784 if (xlate == NULL) { 1785 errno = EINVAL; 1786 rc = -1; 1787 goto return_rc; 1788 } 1789 DPRINTF(("got event %d\n", xlate->tx_internal_event)); 1790 1791 if (adt_selected(event_state, xlate->tx_internal_event, status)) 1792 adt_generate_event(event, event_state, xlate); 1793 1794 return_rc: 1795 return (rc); 1796 } 1797 1798 /* 1799 * adt_free_event -- invalidate and free 1800 */ 1801 1802 void 1803 adt_free_event(adt_event_data_t *event) 1804 { 1805 struct adt_event_state *event_state; 1806 1807 if (event == NULL) 1808 return; 1809 1810 event_state = (struct adt_event_state *)event; 1811 1812 assert(event_state->ae_check == ADT_VALID); 1813 1814 event_state->ae_check = 0; 1815 1816 free(event_state); 1817 } 1818 1819 /* 1820 * adt_is_selected -- helper to adt_selected(), below. 1821 * 1822 * "sorf" is "success or fail" status; au_preselect compares 1823 * that with success, fail, or both. 1824 */ 1825 1826 static int 1827 adt_is_selected(au_event_t e, au_mask_t *m, int sorf) 1828 { 1829 int prs_sorf; 1830 1831 if (sorf == 0) 1832 prs_sorf = AU_PRS_SUCCESS; 1833 else 1834 prs_sorf = AU_PRS_FAILURE; 1835 1836 return (au_preselect(e, m, prs_sorf, AU_PRS_REREAD)); 1837 } 1838 1839 /* 1840 * selected -- see if this event is preselected. 1841 * 1842 * if errors are encountered trying to check a preselection mask 1843 * or look up a user name, the event is selected. Otherwise, the 1844 * preselection mask is used for the job. 1845 */ 1846 1847 static int 1848 adt_selected(struct adt_event_state *event, au_event_t actual_id, int status) 1849 { 1850 adt_internal_state_t *sp; 1851 au_mask_t namask; 1852 1853 sp = event->ae_session; 1854 1855 if ((sp->as_have_user_data & ADT_HAVE_IDS) == 0) { 1856 adt_write_syslog("No user data available", EINVAL); 1857 return (1); /* default is "selected" */ 1858 } 1859 1860 /* non-attributable? */ 1861 if ((sp->as_info.ai_auid == AU_NOAUDITID) || 1862 (sp->as_info.ai_auid == ADT_NO_AUDIT)) { 1863 if (auditon(A_GETKMASK, (caddr_t)&namask, 1864 sizeof (namask)) != 0) { 1865 adt_write_syslog("auditon failure", errno); 1866 return (1); 1867 } 1868 return (adt_is_selected(actual_id, &namask, status)); 1869 } else { 1870 return (adt_is_selected(actual_id, &(sp->as_info.ai_mask), 1871 status)); 1872 } 1873 } 1874