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