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