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