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