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 2009 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #include <bsm/adt.h> 28 #include <bsm/adt_event.h> 29 #include <assert.h> 30 #include <bsm/audit.h> 31 #include <bsm/audit_record.h> 32 #include <bsm/libbsm.h> 33 #include <door.h> 34 #include <errno.h> 35 #include <generic.h> 36 #include <md5.h> 37 #include <sys/mkdev.h> 38 #include <netdb.h> 39 #include <nss_dbdefs.h> 40 #include <pwd.h> 41 #include <sys/stat.h> 42 #include <time.h> 43 #include <stdlib.h> 44 #include <string.h> 45 #include <synch.h> 46 #include <sys/systeminfo.h> 47 #include <syslog.h> 48 #include <thread.h> 49 #include <unistd.h> 50 #include <adt_xlate.h> 51 #include <adt_ucred.h> 52 #include <arpa/inet.h> 53 #include <net/if.h> 54 #include <libinetutil.h> 55 56 static int adt_selected(struct adt_event_state *, au_event_t, int); 57 static int adt_init(adt_internal_state_t *, int); 58 static int adt_import(adt_internal_state_t *, const adt_export_data_t *); 59 static m_label_t *adt_ucred_label(ucred_t *); 60 static void adt_setto_unaudited(adt_internal_state_t *); 61 static int adt_get_local_address(int, struct ifaddrlist *); 62 63 #ifdef C2_DEBUG 64 #define DPRINTF(x) {printf x; } 65 #define DFLUSH fflush(stdout); 66 #else 67 #define DPRINTF(x) 68 #define DFLUSH 69 #endif 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 = errno; 95 int mask_priority; 96 97 DPRINTF(("syslog called: %s\n", message)); 98 99 mask_priority = setlogmask(LOG_MASK(LOG_ALERT)); 100 errno = err; 101 syslog(LOG_ALERT, "Solaris_audit %s: %m", message); 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_asid_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_asid_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 /* _LP64 */ 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 /* _LP64 */ 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_load_table() 387 * 388 * loads the event translation table into the audit session. 389 */ 390 391 void 392 adt_load_table(const adt_session_data_t *session_data, 393 adt_translation_t **xlate, void (*preload)(au_event_t, adt_event_data_t *)) 394 { 395 adt_internal_state_t *state = (adt_internal_state_t *)session_data; 396 397 if (state != NULL) { 398 assert(state->as_check == ADT_VALID); 399 state->as_xlate = xlate; 400 state->as_preload = preload; 401 } 402 } 403 404 /* 405 * adt_get_asid() and adt_set_asid() 406 * 407 * if you use this interface, you are responsible to insure that the 408 * rest of the session data is populated correctly before calling 409 * adt_proccess_attr() 410 * 411 * neither of these are intended for general use and will likely 412 * remain private interfaces for a long time. Forever is a long 413 * time. In the case of adt_set_asid(), you should have a very, 414 * very good reason for setting your own session id. The process 415 * audit characteristics are not changed by put, use adt_set_proc(). 416 * 417 * These are "volatile" (more changable than "evolving") and will 418 * probably change in the S10 period. 419 */ 420 421 void 422 adt_get_asid(const adt_session_data_t *session_data, au_asid_t *asid) 423 { 424 425 if (session_data == NULL) { 426 *asid = 0; 427 } else { 428 assert(((adt_internal_state_t *)session_data)->as_check == 429 ADT_VALID); 430 431 *asid = ((adt_internal_state_t *)session_data)->as_info.ai_asid; 432 } 433 } 434 435 void 436 adt_set_asid(const adt_session_data_t *session_data, const au_asid_t session_id) 437 { 438 439 if (session_data != NULL) { 440 assert(((adt_internal_state_t *)session_data)->as_check == 441 ADT_VALID); 442 443 ((adt_internal_state_t *)session_data)->as_have_user_data |= 444 ADT_HAVE_ASID; 445 ((adt_internal_state_t *)session_data)->as_info.ai_asid = 446 session_id; 447 } 448 } 449 450 /* 451 * adt_get_auid() and adt_set_auid() 452 * 453 * neither of these are intended for general use and will likely 454 * remain private interfaces for a long time. Forever is a long 455 * time. In the case of adt_set_auid(), you should have a very, 456 * very good reason for setting your own audit id. The process 457 * audit characteristics are not changed by put, use adt_set_proc(). 458 */ 459 460 void 461 adt_get_auid(const adt_session_data_t *session_data, au_id_t *auid) 462 { 463 464 if (session_data == NULL) { 465 *auid = AU_NOAUDITID; 466 } else { 467 assert(((adt_internal_state_t *)session_data)->as_check == 468 ADT_VALID); 469 470 *auid = ((adt_internal_state_t *)session_data)->as_info.ai_auid; 471 } 472 } 473 474 void 475 adt_set_auid(const adt_session_data_t *session_data, const au_id_t audit_id) 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_have_user_data |= 483 ADT_HAVE_AUID; 484 ((adt_internal_state_t *)session_data)->as_info.ai_auid = 485 audit_id; 486 } 487 } 488 489 /* 490 * adt_get_termid(), adt_set_termid() 491 * 492 * if you use this interface, you are responsible to insure that the 493 * rest of the session data is populated correctly before calling 494 * adt_proccess_attr() 495 * 496 * The process audit characteristics are not changed by put, use 497 * adt_set_proc(). 498 */ 499 500 void 501 adt_get_termid(const adt_session_data_t *session_data, au_tid_addr_t *termid) 502 { 503 504 if (session_data == NULL) { 505 (void) memset(termid, 0, sizeof (au_tid_addr_t)); 506 termid->at_type = AU_IPv4; 507 } else { 508 assert(((adt_internal_state_t *)session_data)->as_check == 509 ADT_VALID); 510 511 *termid = 512 ((adt_internal_state_t *)session_data)->as_info.ai_termid; 513 } 514 } 515 516 void 517 adt_set_termid(const adt_session_data_t *session_data, 518 const au_tid_addr_t *termid) 519 { 520 521 if (session_data != NULL) { 522 assert(((adt_internal_state_t *)session_data)->as_check == 523 ADT_VALID); 524 525 ((adt_internal_state_t *)session_data)->as_info.ai_termid = 526 *termid; 527 528 ((adt_internal_state_t *)session_data)->as_have_user_data |= 529 ADT_HAVE_TID; 530 } 531 } 532 533 /* 534 * adt_get_mask(), adt_set_mask() 535 * 536 * if you use this interface, you are responsible to insure that the 537 * rest of the session data is populated correctly before calling 538 * adt_proccess_attr() 539 * 540 * The process audit characteristics are not changed by put, use 541 * adt_set_proc(). 542 */ 543 544 void 545 adt_get_mask(const adt_session_data_t *session_data, au_mask_t *mask) 546 { 547 548 if (session_data == NULL) { 549 mask->am_success = 0; 550 mask->am_failure = 0; 551 } else { 552 assert(((adt_internal_state_t *)session_data)->as_check == 553 ADT_VALID); 554 555 *mask = ((adt_internal_state_t *)session_data)->as_info.ai_mask; 556 } 557 } 558 559 void 560 adt_set_mask(const adt_session_data_t *session_data, const au_mask_t *mask) 561 { 562 563 if (session_data != NULL) { 564 assert(((adt_internal_state_t *)session_data)->as_check == 565 ADT_VALID); 566 567 ((adt_internal_state_t *)session_data)->as_info.ai_mask = *mask; 568 569 ((adt_internal_state_t *)session_data)->as_have_user_data |= 570 ADT_HAVE_MASK; 571 } 572 } 573 574 /* 575 * helpers for adt_load_termid 576 */ 577 578 static void 579 adt_do_ipv6_address(struct sockaddr_in6 *peer, struct sockaddr_in6 *sock, 580 au_tid_addr_t *termid) 581 { 582 583 termid->at_port = ((peer->sin6_port<<16) | (sock->sin6_port)); 584 termid->at_type = AU_IPv6; 585 (void) memcpy(termid->at_addr, &peer->sin6_addr, 4 * sizeof (uint_t)); 586 } 587 588 static void 589 adt_do_ipv4_address(struct sockaddr_in *peer, struct sockaddr_in *sock, 590 au_tid_addr_t *termid) 591 { 592 593 termid->at_port = ((peer->sin_port<<16) | (sock->sin_port)); 594 595 termid->at_type = AU_IPv4; 596 termid->at_addr[0] = (uint32_t)peer->sin_addr.s_addr; 597 (void) memset(&(termid->at_addr[1]), 0, 3 * sizeof (uint_t)); 598 } 599 600 /* 601 * adt_load_termid: convenience function; inputs file handle and 602 * outputs an au_tid_addr struct. 603 * 604 * This code was stolen from audit_settid.c; it differs from audit_settid() 605 * in that it does not write the terminal id to the process. 606 */ 607 608 int 609 adt_load_termid(int fd, adt_termid_t **termid) 610 { 611 au_tid_addr_t *p_term; 612 struct sockaddr_in6 peer; 613 struct sockaddr_in6 sock; 614 int peerlen = sizeof (peer); 615 int socklen = sizeof (sock); 616 617 *termid = NULL; 618 619 /* get peer name if its a socket, else assume local terminal */ 620 621 if (getpeername(fd, (struct sockaddr *)&peer, (socklen_t *)&peerlen) 622 < 0) { 623 if (errno == ENOTSOCK) 624 return (adt_load_hostname(NULL, termid)); 625 goto return_err; 626 } 627 628 if ((p_term = calloc(1, sizeof (au_tid_addr_t))) == NULL) 629 goto return_err; 630 631 /* get sock name */ 632 if (getsockname(fd, (struct sockaddr *)&sock, 633 (socklen_t *)&socklen) < 0) 634 goto return_err_free; 635 636 if (peer.sin6_family == AF_INET6) { 637 adt_do_ipv6_address(&peer, &sock, p_term); 638 } else { 639 adt_do_ipv4_address((struct sockaddr_in *)&peer, 640 (struct sockaddr_in *)&sock, p_term); 641 } 642 *termid = (adt_termid_t *)p_term; 643 644 return (0); 645 646 return_err_free: 647 free(p_term); 648 return_err: 649 return (-1); 650 } 651 652 static boolean_t 653 adt_have_termid(au_tid_addr_t *dest) 654 { 655 struct auditinfo_addr audit_data; 656 657 if (getaudit_addr(&audit_data, sizeof (audit_data)) < 0) { 658 adt_write_syslog("getaudit failed", errno); 659 return (B_FALSE); 660 } 661 662 if ((audit_data.ai_termid.at_type == 0) || 663 (audit_data.ai_termid.at_addr[0] | 664 audit_data.ai_termid.at_addr[1] | 665 audit_data.ai_termid.at_addr[2] | 666 audit_data.ai_termid.at_addr[3]) == 0) 667 return (B_FALSE); 668 669 (void) memcpy(dest, &(audit_data.ai_termid), 670 sizeof (au_tid_addr_t)); 671 672 return (B_TRUE); 673 } 674 675 static int 676 adt_get_hostIP(const char *hostname, au_tid_addr_t *p_term) 677 { 678 struct addrinfo *ai = NULL; 679 int tries = 3; 680 char msg[512]; 681 int eai_err; 682 683 while ((tries-- > 0) && 684 ((eai_err = getaddrinfo(hostname, NULL, NULL, &ai)) != 0)) { 685 /* 686 * getaddrinfo returns its own set of errors. 687 * Log them here, so any subsequent syslogs will 688 * have a context. adt_get_hostIP callers can only 689 * return errno, so subsequent syslogs may be lacking 690 * that getaddrinfo failed. 691 */ 692 (void) snprintf(msg, sizeof (msg), "getaddrinfo(%s) " 693 "failed[%s]", hostname, gai_strerror(eai_err)); 694 adt_write_syslog(msg, 0); 695 696 if (eai_err != EAI_AGAIN) { 697 698 break; 699 } 700 /* see if resolution becomes available */ 701 (void) sleep(1); 702 } 703 if (ai != NULL) { 704 if (ai->ai_family == AF_INET) { 705 p_term->at_type = AU_IPv4; 706 (void) memcpy(p_term->at_addr, 707 /* LINTED */ 708 &((struct sockaddr_in *)ai->ai_addr)->sin_addr, 709 AU_IPv4); 710 } else { 711 p_term->at_type = AU_IPv6; 712 (void) memcpy(p_term->at_addr, 713 /* LINTED */ 714 &((struct sockaddr_in6 *)ai->ai_addr)->sin6_addr, 715 AU_IPv6); 716 } 717 freeaddrinfo(ai); 718 return (0); 719 } else { 720 struct ifaddrlist al; 721 int family; 722 char ntop[INET6_ADDRSTRLEN]; 723 724 /* 725 * getaddrinfo has failed to map the hostname 726 * to an IP address, try to get an IP address 727 * from a local interface. 728 */ 729 family = AF_INET6; 730 if (adt_get_local_address(family, &al) != 0) { 731 family = AF_INET; 732 733 if (adt_get_local_address(family, &al) != 0) { 734 adt_write_syslog("adt_get_local_address " 735 "failed, no Audit IP address available", 736 errno); 737 return (-1); 738 } 739 } 740 if (family == AF_INET) { 741 p_term->at_type = AU_IPv4; 742 (void) memcpy(p_term->at_addr, &al.addr.addr, AU_IPv4); 743 } else { 744 p_term->at_type = AU_IPv6; 745 (void) memcpy(p_term->at_addr, &al.addr.addr6, AU_IPv6); 746 } 747 748 (void) snprintf(msg, sizeof (msg), "mapping %s to %s", 749 hostname, inet_ntop(family, &(al.addr), ntop, 750 sizeof (ntop))); 751 adt_write_syslog(msg, 0); 752 return (0); 753 } 754 } 755 756 /* 757 * adt_load_hostname() is called when the caller does not have a file 758 * handle that gives access to the socket info or any other way to 759 * pass in both port and ip address. The hostname input is ignored if 760 * the terminal id has already been set; instead it returns the 761 * existing terminal id. 762 * 763 * If audit is off and the hostname lookup fails, no error is 764 * returned, since an error may be interpreted by the caller 765 * as grounds for denying a login. Otherwise the caller would 766 * need to be aware of the audit state. 767 */ 768 769 int 770 adt_load_hostname(const char *hostname, adt_termid_t **termid) 771 { 772 char localhost[MAXHOSTNAMELEN + 1]; 773 au_tid_addr_t *p_term; 774 775 *termid = NULL; 776 777 if (!adt_audit_enabled()) 778 return (0); 779 780 if ((p_term = calloc(1, sizeof (au_tid_addr_t))) == NULL) 781 goto return_err; 782 783 if (adt_have_termid(p_term)) { 784 *termid = (adt_termid_t *)p_term; 785 return (0); 786 } 787 p_term->at_port = 0; 788 789 if (hostname == NULL || *hostname == '\0') { 790 (void) sysinfo(SI_HOSTNAME, localhost, MAXHOSTNAMELEN); 791 hostname = localhost; 792 } 793 if (adt_get_hostIP(hostname, p_term)) 794 goto return_err_free; 795 796 *termid = (adt_termid_t *)p_term; 797 return (0); 798 799 return_err_free: 800 free(p_term); 801 802 return_err: 803 if ((auditstate == AUC_DISABLED) || 804 (auditstate == AUC_NOAUDIT)) 805 return (0); 806 807 return (-1); 808 } 809 810 /* 811 * adt_load_ttyname() is called when the caller does not have a file 812 * handle that gives access to the local terminal or any other way 813 * of determining the device id. The ttyname input is ignored if 814 * the terminal id has already been set; instead it returns the 815 * existing terminal id. 816 * 817 * If audit is off and the ttyname lookup fails, no error is 818 * returned, since an error may be interpreted by the caller 819 * as grounds for denying a login. Otherwise the caller would 820 * need to be aware of the audit state. 821 */ 822 823 int 824 adt_load_ttyname(const char *ttyname, adt_termid_t **termid) 825 { 826 char localhost[MAXHOSTNAMELEN + 1]; 827 au_tid_addr_t *p_term; 828 struct stat stat_buf; 829 830 *termid = NULL; 831 832 if (!adt_audit_enabled()) 833 return (0); 834 835 if ((p_term = calloc(1, sizeof (au_tid_addr_t))) == NULL) 836 goto return_err; 837 838 if (adt_have_termid(p_term)) { 839 *termid = (adt_termid_t *)p_term; 840 return (0); 841 } 842 843 p_term->at_port = 0; 844 845 if (sysinfo(SI_HOSTNAME, localhost, MAXHOSTNAMELEN) < 0) 846 goto return_err_free; /* errno from sysinfo */ 847 848 if (ttyname != NULL && *ttyname != '\0') { 849 if (stat(ttyname, &stat_buf) < 0) 850 goto return_err_free; 851 852 p_term->at_port = stat_buf.st_rdev; 853 } 854 855 if (adt_get_hostIP(localhost, p_term)) 856 goto return_err_free; 857 858 *termid = (adt_termid_t *)p_term; 859 return (0); 860 861 return_err_free: 862 free(p_term); 863 864 return_err: 865 if ((auditstate == AUC_DISABLED) || 866 (auditstate == AUC_NOAUDIT)) 867 return (0); 868 869 return (-1); 870 } 871 872 /* 873 * adt_get_session_id returns a stringified representation of 874 * the audit session id. See also adt_get_asid() for how to 875 * get the unexpurgated version. No guarantees as to how long 876 * the returned string will be or its general form; hex for now. 877 * 878 * An empty string is returned if auditing is off; length = 1 879 * and the pointer is valid. 880 * 881 * returns strlen + 1 if buffer is valid; else 0 and errno. 882 */ 883 884 size_t 885 adt_get_session_id(const adt_session_data_t *session_data, char **buff) 886 { 887 au_asid_t session_id; 888 size_t length; 889 /* 890 * output is 0x followed by 891 * two characters per byte 892 * plus terminator, 893 * except leading 0's are suppressed, so a few bytes may 894 * be unused. 895 */ 896 length = 2 + (2 * sizeof (session_id)) + 1; 897 *buff = malloc(length); 898 899 if (*buff == NULL) { 900 return (0); 901 } 902 if (session_data == NULL) { /* NULL is not an error */ 903 **buff = '\0'; 904 return (1); 905 } 906 adt_get_asid(session_data, &session_id); 907 908 length = snprintf(*buff, length, "0x%X", (int)session_id); 909 910 /* length < 1 is a bug: the session data type may have changed */ 911 assert(length > 0); 912 913 return (length); 914 } 915 916 /* 917 * adt_end_session -- close handle, clear context 918 * 919 * if as_check is invalid, no harm, no foul, EXCEPT that this could 920 * be an attempt to free data already free'd, so output to syslog 921 * to help explain why the process cored dumped. 922 */ 923 924 int 925 adt_end_session(adt_session_data_t *session_data) 926 { 927 adt_internal_state_t *state; 928 929 if (session_data != NULL) { 930 state = (adt_internal_state_t *)session_data; 931 if (state->as_check != ADT_VALID) { 932 adt_write_syslog("freeing invalid data", EINVAL); 933 } else { 934 state->as_check = 0; 935 m_label_free(state->as_label); 936 free(session_data); 937 } 938 } 939 /* no errors yet defined */ 940 return (0); 941 } 942 943 /* 944 * adt_dup_session -- copy the session data 945 */ 946 947 int 948 adt_dup_session(const adt_session_data_t *source, adt_session_data_t **dest) 949 { 950 adt_internal_state_t *source_state; 951 adt_internal_state_t *dest_state = NULL; 952 int rc = 0; 953 954 if (source != NULL) { 955 source_state = (adt_internal_state_t *)source; 956 assert(source_state->as_check == ADT_VALID); 957 958 dest_state = malloc(sizeof (adt_internal_state_t)); 959 if (dest_state == NULL) { 960 rc = -1; 961 goto return_rc; 962 } 963 (void) memcpy(dest_state, source, 964 sizeof (struct adt_internal_state)); 965 966 if (source_state->as_label != NULL) { 967 dest_state->as_label = NULL; 968 if ((rc = m_label_dup(&dest_state->as_label, 969 source_state->as_label)) != 0) { 970 free(dest_state); 971 dest_state = NULL; 972 } 973 } 974 } 975 return_rc: 976 *dest = (adt_session_data_t *)dest_state; 977 return (rc); 978 } 979 980 /* 981 * from_export_format() 982 * read from a network order buffer into struct adt_session_data 983 */ 984 985 static size_t 986 adt_from_export_format(adt_internal_state_t *internal, 987 const adt_export_data_t *external) 988 { 989 struct export_header head; 990 struct export_link link; 991 adr_t context; 992 int32_t offset; 993 int32_t length; 994 int32_t version; 995 size_t label_len; 996 char *p = (char *)external; 997 998 adrm_start(&context, (char *)external); 999 adrm_int32(&context, (int *)&head, 4); 1000 1001 if ((internal->as_check = head.ax_check) != ADT_VALID) { 1002 errno = EINVAL; 1003 return (0); 1004 } 1005 offset = head.ax_link.ax_offset; 1006 version = head.ax_link.ax_version; 1007 length = head.ax_buffer_length; 1008 1009 /* 1010 * Skip newer versions. 1011 */ 1012 while (version > PROTOCOL_VERSION_2) { 1013 if (offset < 1) { 1014 return (0); /* failed to match version */ 1015 } 1016 p += offset; /* point to next version # */ 1017 1018 if (p > (char *)external + length) { 1019 return (0); 1020 } 1021 adrm_start(&context, p); 1022 adrm_int32(&context, (int *)&link, 2); 1023 offset = link.ax_offset; 1024 version = link.ax_version; 1025 assert(version != 0); 1026 } 1027 /* 1028 * Adjust buffer pointer to the first data item (euid). 1029 */ 1030 if (p == (char *)external) { 1031 adrm_start(&context, (char *)(p + sizeof (head))); 1032 } else { 1033 adrm_start(&context, (char *)(p + sizeof (link))); 1034 } 1035 /* 1036 * if down rev version, neither pid nor label are included 1037 * in v1 ax_size_of_tsol_data intentionally ignored 1038 */ 1039 if (version == PROTOCOL_VERSION_1) { 1040 adrm_int32(&context, (int *)&(internal->as_euid), 1); 1041 adrm_int32(&context, (int *)&(internal->as_ruid), 1); 1042 adrm_int32(&context, (int *)&(internal->as_egid), 1); 1043 adrm_int32(&context, (int *)&(internal->as_rgid), 1); 1044 adrm_int32(&context, (int *)&(internal->as_info.ai_auid), 1); 1045 adrm_int32(&context, 1046 (int *)&(internal->as_info.ai_mask.am_success), 2); 1047 adrm_int32(&context, 1048 (int *)&(internal->as_info.ai_termid.at_port), 1); 1049 adrm_int32(&context, 1050 (int *)&(internal->as_info.ai_termid.at_type), 1); 1051 adrm_int32(&context, 1052 (int *)&(internal->as_info.ai_termid.at_addr[0]), 4); 1053 adrm_int32(&context, (int *)&(internal->as_info.ai_asid), 1); 1054 adrm_int32(&context, (int *)&(internal->as_audit_enabled), 1); 1055 internal->as_pid = (pid_t)-1; 1056 internal->as_label = NULL; 1057 } else if (version == PROTOCOL_VERSION_2) { 1058 adrm_int32(&context, (int *)&(internal->as_euid), 1); 1059 adrm_int32(&context, (int *)&(internal->as_ruid), 1); 1060 adrm_int32(&context, (int *)&(internal->as_egid), 1); 1061 adrm_int32(&context, (int *)&(internal->as_rgid), 1); 1062 adrm_int32(&context, (int *)&(internal->as_info.ai_auid), 1); 1063 adrm_int32(&context, 1064 (int *)&(internal->as_info.ai_mask.am_success), 2); 1065 adrm_int32(&context, 1066 (int *)&(internal->as_info.ai_termid.at_port), 1); 1067 adrm_int32(&context, 1068 (int *)&(internal->as_info.ai_termid.at_type), 1); 1069 adrm_int32(&context, 1070 (int *)&(internal->as_info.ai_termid.at_addr[0]), 4); 1071 adrm_int32(&context, (int *)&(internal->as_info.ai_asid), 1); 1072 adrm_int32(&context, (int *)&(internal->as_audit_enabled), 1); 1073 adrm_int32(&context, (int *)&(internal->as_pid), 1); 1074 adrm_int32(&context, (int *)&label_len, 1); 1075 if (label_len > 0) { 1076 /* read in and deal with different sized labels. */ 1077 size32_t my_label_len = blabel_size(); 1078 1079 if ((internal->as_label = 1080 m_label_alloc(MAC_LABEL)) == NULL) { 1081 return (0); 1082 } 1083 if (label_len > my_label_len) { 1084 errno = EINVAL; 1085 m_label_free(internal->as_label); 1086 return (0); 1087 } 1088 (void) memset(internal->as_label, 0, my_label_len); 1089 adrm_int32(&context, (int *)(internal->as_label), 1090 label_len / sizeof (int32_t)); 1091 } else { 1092 internal->as_label = NULL; 1093 } 1094 } 1095 1096 return (length); 1097 } 1098 1099 /* 1100 * adt_to_export_format 1101 * read from struct adt_session_data into a network order buffer. 1102 * 1103 * (network order 'cause this data may be shared with a remote host.) 1104 */ 1105 1106 static size_t 1107 adt_to_export_format(adt_export_data_t *external, 1108 adt_internal_state_t *internal) 1109 { 1110 struct export_header head; 1111 struct export_link tail; 1112 adr_t context; 1113 size32_t label_len = 0; 1114 1115 adrm_start(&context, (char *)external); 1116 1117 if (internal->as_label != NULL) { 1118 label_len = blabel_size(); 1119 } 1120 1121 head.ax_check = ADT_VALID; 1122 head.ax_buffer_length = sizeof (struct adt_export_data) + label_len; 1123 1124 /* version 2 first */ 1125 1126 head.ax_link.ax_version = PROTOCOL_VERSION_2; 1127 head.ax_link.ax_offset = sizeof (struct export_header) + 1128 sizeof (struct adt_export_v2) + label_len; 1129 1130 adrm_putint32(&context, (int *)&head, 4); 1131 1132 adrm_putint32(&context, (int *)&(internal->as_euid), 1); 1133 adrm_putint32(&context, (int *)&(internal->as_ruid), 1); 1134 adrm_putint32(&context, (int *)&(internal->as_egid), 1); 1135 adrm_putint32(&context, (int *)&(internal->as_rgid), 1); 1136 adrm_putint32(&context, (int *)&(internal->as_info.ai_auid), 1); 1137 adrm_putint32(&context, 1138 (int *)&(internal->as_info.ai_mask.am_success), 2); 1139 adrm_putint32(&context, 1140 (int *)&(internal->as_info.ai_termid.at_port), 1); 1141 adrm_putint32(&context, 1142 (int *)&(internal->as_info.ai_termid.at_type), 1); 1143 adrm_putint32(&context, 1144 (int *)&(internal->as_info.ai_termid.at_addr[0]), 4); 1145 adrm_putint32(&context, (int *)&(internal->as_info.ai_asid), 1); 1146 adrm_putint32(&context, (int *)&(internal->as_audit_enabled), 1); 1147 adrm_putint32(&context, (int *)&(internal->as_pid), 1); 1148 adrm_putint32(&context, (int *)&label_len, 1); 1149 if (internal->as_label != NULL) { 1150 /* serialize the label */ 1151 adrm_putint32(&context, (int *)(internal->as_label), 1152 (label_len / sizeof (int32_t))); 1153 } 1154 1155 /* now version 1 */ 1156 1157 tail.ax_version = PROTOCOL_VERSION_1; 1158 tail.ax_offset = 0; 1159 1160 adrm_putint32(&context, (int *)&tail, 2); 1161 1162 adrm_putint32(&context, (int *)&(internal->as_euid), 1); 1163 adrm_putint32(&context, (int *)&(internal->as_ruid), 1); 1164 adrm_putint32(&context, (int *)&(internal->as_egid), 1); 1165 adrm_putint32(&context, (int *)&(internal->as_rgid), 1); 1166 adrm_putint32(&context, (int *)&(internal->as_info.ai_auid), 1); 1167 adrm_putint32(&context, 1168 (int *)&(internal->as_info.ai_mask.am_success), 2); 1169 adrm_putint32(&context, 1170 (int *)&(internal->as_info.ai_termid.at_port), 1); 1171 adrm_putint32(&context, 1172 (int *)&(internal->as_info.ai_termid.at_type), 1); 1173 adrm_putint32(&context, 1174 (int *)&(internal->as_info.ai_termid.at_addr[0]), 4); 1175 adrm_putint32(&context, (int *)&(internal->as_info.ai_asid), 1); 1176 adrm_putint32(&context, (int *)&(internal->as_audit_enabled), 1); 1177 /* ignored in v1 */ 1178 adrm_putint32(&context, (int *)&label_len, 1); 1179 1180 /* finally terminator */ 1181 1182 tail.ax_version = 0; /* invalid version number */ 1183 tail.ax_offset = 0; 1184 1185 adrm_putint32(&context, (int *)&tail, 2); 1186 1187 return (head.ax_buffer_length); 1188 } 1189 1190 1191 /* 1192 * adt_import_proc() is used by a server acting on behalf 1193 * of a client which has connected via an ipc mechanism such as 1194 * a door. 1195 * 1196 * Since the interface is via ucred, the info.ap_termid.port 1197 * value is always the 64 bit version. What is stored depends 1198 * on how libbsm is compiled. 1199 */ 1200 1201 size_t 1202 adt_import_proc(pid_t pid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid, 1203 adt_export_data_t **external) 1204 { 1205 size_t length = 0; 1206 adt_internal_state_t *state; 1207 ucred_t *ucred; 1208 const au_tid64_addr_t *tid; 1209 1210 state = calloc(1, sizeof (adt_internal_state_t)); 1211 1212 if (state == NULL) 1213 return (0); 1214 1215 if (adt_init(state, 0) != 0) 1216 goto return_length_free; /* errno from adt_init() */ 1217 1218 /* 1219 * ucred_getauid() returns AU_NOAUDITID if audit is off, which 1220 * is the right answer for adt_import_proc(). 1221 * 1222 * Create a local context as near as possible. 1223 */ 1224 1225 ucred = ucred_get(pid); 1226 1227 if (ucred == NULL) 1228 goto return_length_free; 1229 1230 state->as_ruid = ruid != ADT_NO_CHANGE ? ruid : ucred_getruid(ucred); 1231 state->as_euid = euid != ADT_NO_CHANGE ? euid : ucred_geteuid(ucred); 1232 state->as_rgid = rgid != ADT_NO_CHANGE ? rgid : ucred_getrgid(ucred); 1233 state->as_egid = egid != ADT_NO_CHANGE ? egid : ucred_getegid(ucred); 1234 1235 state->as_info.ai_auid = ucred_getauid(ucred); 1236 1237 if (state->as_info.ai_auid == AU_NOAUDITID) { 1238 state->as_info.ai_asid = adt_get_unique_id(ruid); 1239 1240 if (adt_get_mask_from_user(ruid, &(state->as_info.ai_mask))) 1241 goto return_all_free; 1242 } else { 1243 const au_mask_t *mask = ucred_getamask(ucred); 1244 1245 if (mask != NULL) 1246 state->as_info.ai_mask = *mask; 1247 else 1248 goto return_all_free; 1249 1250 state->as_info.ai_asid = ucred_getasid(ucred); 1251 } 1252 1253 tid = ucred_getatid(ucred); 1254 1255 if (tid != NULL) { 1256 adt_cpy_tid(&(state->as_info.ai_termid), tid); 1257 } else { 1258 (void) memset((void *)&(state->as_info.ai_termid), 0, 1259 sizeof (au_tid_addr_t)); 1260 state->as_info.ai_termid.at_type = AU_IPv4; 1261 } 1262 1263 DPRINTF(("import_proc/asid = %X %u\n", state->as_info.ai_asid, 1264 state->as_info.ai_asid)); 1265 1266 DPRINTF(("import_proc/masks = %X %X\n", 1267 state->as_info.ai_mask.am_success, 1268 state->as_info.ai_mask.am_failure)); 1269 1270 if (state->as_label == NULL) { 1271 *external = malloc(sizeof (adt_export_data_t)); 1272 } else { 1273 *external = malloc(sizeof (adt_export_data_t) + blabel_size()); 1274 } 1275 1276 if (*external == NULL) 1277 goto return_all_free; 1278 1279 length = adt_to_export_format(*external, state); 1280 /* 1281 * yes, state is supposed to be free'd for both pass and fail 1282 */ 1283 return_all_free: 1284 ucred_free(ucred); 1285 return_length_free: 1286 free(state); 1287 return (length); 1288 } 1289 1290 /* 1291 * adt_ucred_label() -- if label is available, duplicate it. 1292 */ 1293 1294 static m_label_t * 1295 adt_ucred_label(ucred_t *uc) 1296 { 1297 m_label_t *ul = NULL; 1298 1299 if (ucred_getlabel(uc) != NULL) { 1300 (void) m_label_dup(&ul, ucred_getlabel(uc)); 1301 } 1302 1303 return (ul); 1304 } 1305 1306 /* 1307 * adt_import() -- convert from network order to machine-specific order 1308 */ 1309 1310 static int 1311 adt_import(adt_internal_state_t *internal, const adt_export_data_t *external) 1312 { 1313 au_mask_t mask; 1314 1315 /* save local audit enabled state */ 1316 int local_audit_enabled = internal->as_audit_enabled; 1317 1318 if (adt_from_export_format(internal, external) < 1) 1319 return (-1); /* errno from adt_from_export_format */ 1320 1321 /* 1322 * If audit isn't enabled on the remote, they were unable 1323 * to generate the audit mask, so generate it based on 1324 * local configuration. If the user id has changed, the 1325 * resulting mask may miss some subtleties that occurred 1326 * on the remote system. 1327 * 1328 * If the remote failed to generate a terminal id, it is not 1329 * recoverable. 1330 */ 1331 1332 if (!internal->as_audit_enabled) { 1333 if (adt_get_mask_from_user(internal->as_info.ai_auid, 1334 &(internal->as_info.ai_mask))) 1335 return (-1); 1336 if (internal->as_info.ai_auid != internal->as_ruid) { 1337 if (adt_get_mask_from_user(internal->as_info.ai_auid, 1338 &mask)) 1339 return (-1); 1340 internal->as_info.ai_mask.am_success |= 1341 mask.am_success; 1342 internal->as_info.ai_mask.am_failure |= 1343 mask.am_failure; 1344 } 1345 } 1346 internal->as_audit_enabled = local_audit_enabled; 1347 1348 DPRINTF(("(%d)imported asid = %X %u\n", getpid(), 1349 internal->as_info.ai_asid, 1350 internal->as_info.ai_asid)); 1351 1352 internal->as_have_user_data = ADT_HAVE_ALL; 1353 1354 return (0); 1355 } 1356 1357 /* 1358 * adt_export_session_data() 1359 * copies a adt_session_data struct into a network order buffer 1360 * 1361 * In a misconfigured network, the local host may have auditing 1362 * off while the destination may have auditing on, so if there 1363 * is sufficient memory, a buffer will be returned even in the 1364 * audit off case. 1365 */ 1366 1367 size_t 1368 adt_export_session_data(const adt_session_data_t *internal, 1369 adt_export_data_t **external) 1370 { 1371 size32_t length = 0; 1372 1373 if ((internal != NULL) && 1374 ((adt_internal_state_t *)internal)->as_label != NULL) { 1375 length = blabel_size(); 1376 } 1377 1378 *external = malloc(sizeof (adt_export_data_t) + length); 1379 1380 if (*external == NULL) 1381 return (0); 1382 1383 if (internal == NULL) { 1384 adt_internal_state_t *dummy; 1385 1386 dummy = malloc(sizeof (adt_internal_state_t)); 1387 if (dummy == NULL) 1388 goto return_length_free; 1389 1390 if (adt_init(dummy, 0)) { /* 0 == don't copy from proc */ 1391 free(dummy); 1392 goto return_length_free; 1393 } 1394 length = adt_to_export_format(*external, dummy); 1395 free(dummy); 1396 } else { 1397 length = adt_to_export_format(*external, 1398 (adt_internal_state_t *)internal); 1399 } 1400 return (length); 1401 1402 return_length_free: 1403 free(*external); 1404 *external = NULL; 1405 return (0); 1406 } 1407 1408 static void 1409 adt_setto_unaudited(adt_internal_state_t *state) 1410 { 1411 state->as_ruid = AU_NOAUDITID; 1412 state->as_euid = AU_NOAUDITID; 1413 state->as_rgid = AU_NOAUDITID; 1414 state->as_egid = AU_NOAUDITID; 1415 state->as_pid = (pid_t)-1; 1416 state->as_label = NULL; 1417 1418 if (state->as_audit_enabled) { 1419 state->as_info.ai_asid = 0; 1420 state->as_info.ai_auid = AU_NOAUDITID; 1421 1422 (void) memset((void *)&(state->as_info.ai_termid), 0, 1423 sizeof (au_tid_addr_t)); 1424 state->as_info.ai_termid.at_type = AU_IPv4; 1425 1426 (void) memset((void *)&(state->as_info.ai_mask), 0, 1427 sizeof (au_mask_t)); 1428 state->as_have_user_data = 0; 1429 } 1430 } 1431 1432 /* 1433 * adt_init -- set session context by copying the audit characteristics 1434 * from the proc and picking up current uid/tid information. 1435 * 1436 * By default, an audit session is based on the process; the default 1437 * is overriden by adt_set_user() 1438 */ 1439 1440 static int 1441 adt_init(adt_internal_state_t *state, int use_proc_data) 1442 { 1443 1444 state->as_audit_enabled = (auditstate == AUC_DISABLED) ? 0 : 1; 1445 1446 if (use_proc_data) { 1447 state->as_ruid = getuid(); 1448 state->as_euid = geteuid(); 1449 state->as_rgid = getgid(); 1450 state->as_egid = getegid(); 1451 state->as_pid = getpid(); 1452 1453 if (state->as_audit_enabled) { 1454 const au_tid64_addr_t *tid; 1455 const au_mask_t *mask; 1456 ucred_t *ucred = ucred_get(P_MYID); 1457 1458 /* 1459 * Even if the ucred is NULL, the underlying 1460 * credential may have a valid terminal id; if the 1461 * terminal id is set, then that's good enough. An 1462 * example of where this matters is failed login, 1463 * where rlogin/telnet sets the terminal id before 1464 * calling login; login does not load the credential 1465 * since auth failed. 1466 */ 1467 if (ucred == NULL) { 1468 if (!adt_have_termid( 1469 &(state->as_info.ai_termid))) 1470 return (-1); 1471 } else { 1472 mask = ucred_getamask(ucred); 1473 if (mask != NULL) { 1474 state->as_info.ai_mask = *mask; 1475 } else { 1476 ucred_free(ucred); 1477 return (-1); 1478 } 1479 tid = ucred_getatid(ucred); 1480 if (tid != NULL) { 1481 adt_cpy_tid(&(state->as_info.ai_termid), 1482 tid); 1483 } else { 1484 ucred_free(ucred); 1485 return (-1); 1486 } 1487 state->as_info.ai_asid = ucred_getasid(ucred); 1488 state->as_info.ai_auid = ucred_getauid(ucred); 1489 state->as_label = adt_ucred_label(ucred); 1490 ucred_free(ucred); 1491 } 1492 state->as_have_user_data = ADT_HAVE_ALL; 1493 } 1494 } else { 1495 adt_setto_unaudited(state); 1496 } 1497 state->as_session_model = ADT_SESSION_MODEL; /* default */ 1498 1499 if (state->as_audit_enabled && 1500 auditon(A_GETPOLICY, (caddr_t)&(state->as_kernel_audit_policy), 1501 sizeof (state->as_kernel_audit_policy))) { 1502 return (-1); /* errno set by auditon */ 1503 } 1504 state->as_check = ADT_VALID; 1505 adt_load_table((adt_session_data_t *)state, &adt_xlate_table[0], 1506 &adt_preload); 1507 return (0); 1508 } 1509 1510 /* 1511 * adt_set_proc 1512 * 1513 * Copy the current session state to the process. If this function 1514 * is called, the model becomes a process model rather than a 1515 * session model. 1516 * 1517 * In the current implementation, the value state->as_have_user_data 1518 * must contain all of: ADT_HAVE_{AUID,MASK,TID,ASID}. These are all set 1519 * by adt_set_user() when the ADT_SETTID or ADT_NEW flag is passed in. 1520 * 1521 */ 1522 1523 int 1524 adt_set_proc(const adt_session_data_t *session_data) 1525 { 1526 adt_internal_state_t *state; 1527 1528 if (auditstate == AUC_DISABLED || (session_data == NULL)) 1529 return (0); 1530 1531 state = (adt_internal_state_t *)session_data; 1532 1533 assert(state->as_check == ADT_VALID); 1534 1535 if ((state->as_have_user_data & (ADT_HAVE_ALL & ~ADT_HAVE_IDS)) != 1536 (ADT_HAVE_ALL & ~ADT_HAVE_IDS)) { 1537 errno = EINVAL; 1538 goto return_err; 1539 } 1540 1541 if (setaudit_addr((auditinfo_addr_t *)&(state->as_info), 1542 sizeof (auditinfo_addr_t)) < 0) { 1543 goto return_err; /* errno set by setaudit_addr() */ 1544 } 1545 1546 state->as_session_model = ADT_PROCESS_MODEL; 1547 1548 return (0); 1549 1550 return_err: 1551 adt_write_syslog("failed to set process audit characteristics", errno); 1552 return (-1); 1553 } 1554 1555 static int 1556 adt_newuser(adt_internal_state_t *state, uid_t ruid, au_tid_addr_t *termid) 1557 { 1558 au_tid_addr_t no_tid = {0, AU_IPv4, 0, 0, 0, 0}; 1559 au_mask_t no_mask = {0, 0}; 1560 1561 if (ruid == ADT_NO_AUDIT) { 1562 state->as_info.ai_auid = AU_NOAUDITID; 1563 state->as_info.ai_asid = 0; 1564 state->as_info.ai_termid = no_tid; 1565 state->as_info.ai_mask = no_mask; 1566 return (0); 1567 } 1568 state->as_info.ai_auid = ruid; 1569 state->as_info.ai_asid = adt_get_unique_id(ruid); 1570 if (termid != NULL) 1571 state->as_info.ai_termid = *termid; 1572 1573 if (adt_get_mask_from_user(ruid, &(state->as_info.ai_mask))) 1574 return (-1); 1575 1576 /* Assume intending to audit as this process */ 1577 1578 if (state->as_pid == (pid_t)-1) 1579 state->as_pid = getpid(); 1580 1581 if (is_system_labeled() && state->as_label == NULL) { 1582 ucred_t *ucred = ucred_get(P_MYID); 1583 1584 state->as_label = adt_ucred_label(ucred); 1585 ucred_free(ucred); 1586 } 1587 1588 return (0); 1589 } 1590 1591 static int 1592 adt_changeuser(adt_internal_state_t *state, uid_t ruid) 1593 { 1594 au_mask_t mask; 1595 1596 if (!(state->as_have_user_data & ADT_HAVE_AUID)) 1597 state->as_info.ai_auid = ruid; 1598 if (!(state->as_have_user_data & ADT_HAVE_ASID)) 1599 state->as_info.ai_asid = adt_get_unique_id(ruid); 1600 1601 if (ruid <= MAXEPHUID) { 1602 if (adt_get_mask_from_user(ruid, &mask)) 1603 return (-1); 1604 1605 state->as_info.ai_mask.am_success |= mask.am_success; 1606 state->as_info.ai_mask.am_failure |= mask.am_failure; 1607 } 1608 DPRINTF(("changed mask to %08X/%08X for ruid=%d\n", 1609 state->as_info.ai_mask.am_success, 1610 state->as_info.ai_mask.am_failure, 1611 ruid)); 1612 return (0); 1613 } 1614 1615 /* 1616 * adt_set_user -- see also adt_set_from_ucred() 1617 * 1618 * ADT_NO_ATTRIB is a valid uid/gid meaning "not known" or 1619 * "unattributed." If ruid, change the model to session. 1620 * 1621 * ADT_NO_CHANGE is a valid uid/gid meaning "do not change this value" 1622 * only valid with ADT_UPDATE. 1623 * 1624 * ADT_NO_AUDIT is the external equivalent to AU_NOAUDITID -- there 1625 * isn't a good reason to call adt_set_user() with it unless you don't 1626 * have a good value yet and intend to replace it later; auid will be 1627 * AU_NOAUDITID. 1628 * 1629 * adt_set_user should be called even if auditing is not enabled 1630 * so that adt_export_session_data() will have useful stuff to 1631 * work with. 1632 * 1633 * See the note preceding adt_set_proc() about the use of ADT_HAVE_TID 1634 * and ADT_HAVE_ALL. 1635 */ 1636 1637 int 1638 adt_set_user(const adt_session_data_t *session_data, uid_t euid, gid_t egid, 1639 uid_t ruid, gid_t rgid, const adt_termid_t *termid, 1640 enum adt_user_context user_context) 1641 { 1642 adt_internal_state_t *state; 1643 int rc; 1644 1645 if (session_data == NULL) /* no session exists to audit */ 1646 return (0); 1647 1648 state = (adt_internal_state_t *)session_data; 1649 assert(state->as_check == ADT_VALID); 1650 1651 switch (user_context) { 1652 case ADT_NEW: 1653 if (ruid == ADT_NO_CHANGE || euid == ADT_NO_CHANGE || 1654 rgid == ADT_NO_CHANGE || egid == ADT_NO_CHANGE) { 1655 errno = EINVAL; 1656 return (-1); 1657 } 1658 if ((rc = adt_newuser(state, ruid, 1659 (au_tid_addr_t *)termid)) != 0) 1660 return (rc); 1661 1662 state->as_have_user_data = ADT_HAVE_ALL; 1663 break; 1664 case ADT_UPDATE: 1665 if (state->as_have_user_data != ADT_HAVE_ALL) { 1666 errno = EINVAL; 1667 return (-1); 1668 } 1669 1670 if (ruid != ADT_NO_CHANGE) 1671 if ((rc = adt_changeuser(state, ruid)) != 0) 1672 return (rc); 1673 break; 1674 case ADT_USER: 1675 if (state->as_have_user_data != ADT_HAVE_ALL) { 1676 errno = EINVAL; 1677 return (-1); 1678 } 1679 break; 1680 case ADT_SETTID: 1681 assert(termid != NULL); 1682 state->as_info.ai_termid = *((au_tid_addr_t *)termid); 1683 /* avoid fooling pam_setcred()... */ 1684 state->as_info.ai_auid = AU_NOAUDITID; 1685 state->as_info.ai_asid = 0; 1686 state->as_info.ai_mask.am_failure = 0; 1687 state->as_info.ai_mask.am_success = 0; 1688 state->as_have_user_data = ADT_HAVE_TID | 1689 ADT_HAVE_AUID | ADT_HAVE_ASID | ADT_HAVE_MASK; 1690 return (0); 1691 default: 1692 errno = EINVAL; 1693 return (-1); 1694 } 1695 1696 if (ruid == ADT_NO_AUDIT) { 1697 state->as_ruid = AU_NOAUDITID; 1698 state->as_euid = AU_NOAUDITID; 1699 state->as_rgid = AU_NOAUDITID; 1700 state->as_egid = AU_NOAUDITID; 1701 } else { 1702 if (ruid != ADT_NO_CHANGE) 1703 state->as_ruid = ruid; 1704 if (euid != ADT_NO_CHANGE) 1705 state->as_euid = euid; 1706 if (rgid != ADT_NO_CHANGE) 1707 state->as_rgid = rgid; 1708 if (egid != ADT_NO_CHANGE) 1709 state->as_egid = egid; 1710 } 1711 1712 if (ruid == ADT_NO_ATTRIB) { 1713 state->as_session_model = ADT_SESSION_MODEL; 1714 } 1715 1716 return (0); 1717 } 1718 1719 /* 1720 * adt_set_from_ucred() 1721 * 1722 * an alternate to adt_set_user that fills the same role but uses 1723 * a pointer to a ucred rather than a list of id's. If the ucred 1724 * pointer is NULL, use the credential from the this process. 1725 * 1726 * A key difference is that for ADT_NEW, adt_set_from_ucred() does 1727 * not overwrite the asid and auid unless auid has not been set. 1728 * ADT_NEW differs from ADT_UPDATE in that it does not OR together 1729 * the incoming audit mask with the one that already exists. 1730 * 1731 * adt_set_from_ucred should be called even if auditing is not enabled 1732 * so that adt_export_session_data() will have useful stuff to 1733 * work with. 1734 */ 1735 1736 int 1737 adt_set_from_ucred(const adt_session_data_t *session_data, const ucred_t *uc, 1738 enum adt_user_context user_context) 1739 { 1740 adt_internal_state_t *state; 1741 int rc = -1; 1742 const au_tid64_addr_t *tid64; 1743 au_tid_addr_t termid, *tid; 1744 ucred_t *ucred = (ucred_t *)uc; 1745 boolean_t local_uc = B_FALSE; 1746 1747 if (session_data == NULL) /* no session exists to audit */ 1748 return (0); 1749 1750 state = (adt_internal_state_t *)session_data; 1751 assert(state->as_check == ADT_VALID); 1752 1753 if (ucred == NULL) { 1754 ucred = ucred_get(P_MYID); 1755 1756 if (ucred == NULL) 1757 goto return_rc; 1758 local_uc = B_TRUE; 1759 } 1760 1761 switch (user_context) { 1762 case ADT_NEW: 1763 tid64 = ucred_getatid(ucred); 1764 if (tid64 != NULL) { 1765 adt_cpy_tid(&termid, tid64); 1766 tid = &termid; 1767 } else { 1768 tid = NULL; 1769 } 1770 if (ucred_getauid(ucred) == AU_NOAUDITID) { 1771 adt_setto_unaudited(state); 1772 state->as_have_user_data = ADT_HAVE_ALL; 1773 rc = 0; 1774 goto return_rc; 1775 } else { 1776 state->as_info.ai_auid = ucred_getauid(ucred); 1777 state->as_info.ai_asid = ucred_getasid(ucred); 1778 state->as_info.ai_mask = *ucred_getamask(ucred); 1779 state->as_info.ai_termid = *tid; 1780 } 1781 state->as_have_user_data = ADT_HAVE_ALL; 1782 break; 1783 case ADT_UPDATE: 1784 if (state->as_have_user_data != ADT_HAVE_ALL) { 1785 errno = EINVAL; 1786 goto return_rc; 1787 } 1788 1789 if ((rc = adt_changeuser(state, ucred_getruid(ucred))) != 0) 1790 goto return_rc; 1791 break; 1792 case ADT_USER: 1793 if (state->as_have_user_data != ADT_HAVE_ALL) { 1794 errno = EINVAL; 1795 goto return_rc; 1796 } 1797 break; 1798 default: 1799 errno = EINVAL; 1800 goto return_rc; 1801 } 1802 rc = 0; 1803 1804 state->as_ruid = ucred_getruid(ucred); 1805 state->as_euid = ucred_geteuid(ucred); 1806 state->as_rgid = ucred_getrgid(ucred); 1807 state->as_egid = ucred_getegid(ucred); 1808 state->as_pid = ucred_getpid(ucred); 1809 state->as_label = adt_ucred_label(ucred); 1810 1811 return_rc: 1812 if (local_uc) { 1813 ucred_free(ucred); 1814 } 1815 return (rc); 1816 } 1817 1818 /* 1819 * adt_alloc_event() returns a pointer to allocated memory 1820 * 1821 */ 1822 1823 adt_event_data_t 1824 *adt_alloc_event(const adt_session_data_t *session_data, au_event_t event_id) 1825 { 1826 struct adt_event_state *event_state; 1827 adt_internal_state_t *session_state; 1828 adt_event_data_t *return_event = NULL; 1829 /* 1830 * need to return a valid event pointer even if audit is 1831 * off, else the caller will end up either (1) keeping its 1832 * own flags for on/off or (2) writing to a NULL pointer. 1833 * If auditing is on, the session data must be valid; otherwise 1834 * we don't care. 1835 */ 1836 if (session_data != NULL) { 1837 session_state = (adt_internal_state_t *)session_data; 1838 assert(session_state->as_check == ADT_VALID); 1839 } 1840 event_state = calloc(1, sizeof (struct adt_event_state)); 1841 if (event_state == NULL) 1842 goto return_ptr; 1843 1844 event_state->ae_check = ADT_VALID; 1845 1846 event_state->ae_event_id = event_id; 1847 event_state->ae_session = (struct adt_internal_state *)session_data; 1848 1849 return_event = (adt_event_data_t *)&(event_state->ae_event_data); 1850 1851 /* 1852 * preload data so the adt_au_*() functions can detect un-supplied 1853 * values (0 and NULL are free via calloc()). 1854 */ 1855 if (session_data != NULL) { 1856 session_state->as_preload(event_id, return_event); 1857 } 1858 1859 return_ptr: 1860 return (return_event); 1861 } 1862 1863 /* 1864 * adt_getXlateTable -- look up translation table address for event id 1865 */ 1866 1867 static adt_translation_t * 1868 adt_getXlateTable(adt_translation_t **xlate, au_event_t event_id) 1869 { 1870 /* xlate_table is global in adt_xlate.c */ 1871 adt_translation_t **p_xlate = xlate; 1872 adt_translation_t *p_event; 1873 1874 while (*p_xlate != NULL) { 1875 p_event = *p_xlate; 1876 if (event_id == p_event->tx_external_event) 1877 return (p_event); 1878 p_xlate++; 1879 } 1880 return (NULL); 1881 } 1882 1883 /* 1884 * adt_calcOffsets 1885 * 1886 * the call to this function is surrounded by a mutex. 1887 * 1888 * i walks down the table picking up next_token. j walks again to 1889 * calculate the offset to the input data. k points to the next 1890 * token's row. Finally, l, is used to sum the values in the 1891 * datadef array. 1892 * 1893 * What's going on? The entry array is in the order of the input 1894 * fields but the processing of array entries is in the order of 1895 * the output (see next_token). Calculating the offset to the 1896 * "next" input can't be done in the outer loop (i) since i doesn't 1897 * point to the current entry and it can't be done with the k index 1898 * because it doesn't represent the order of input fields. 1899 * 1900 * While the resulting algorithm is n**2, it is only done once per 1901 * event type. 1902 */ 1903 1904 /* 1905 * adt_calcOffsets is only called once per event type, but it uses 1906 * the address alignment of memory allocated for that event as if it 1907 * were the same for all subsequently allocated memory. This is 1908 * guaranteed by calloc/malloc. Arrays take special handling since 1909 * what matters for figuring out the correct alignment is the size 1910 * of the array element. 1911 */ 1912 1913 static void 1914 adt_calcOffsets(struct entry *p_entry, int tablesize, void *p_data) 1915 { 1916 int i, j; 1917 size_t this_size, prev_size; 1918 void *struct_start = p_data; 1919 1920 for (i = 0; i < tablesize; i++) { 1921 if (p_entry[i].en_type_def == NULL) { 1922 p_entry[i].en_offset = 0; 1923 continue; 1924 } 1925 prev_size = 0; 1926 p_entry[i].en_offset = (char *)p_data - (char *)struct_start; 1927 1928 for (j = 0; j < p_entry[i].en_count_types; j++) { 1929 if (p_entry[i].en_type_def[j].dd_datatype == ADT_MSG) 1930 this_size = sizeof (enum adt_generic); 1931 else 1932 this_size = 1933 p_entry[i].en_type_def[j].dd_input_size; 1934 1935 /* adj for first entry */ 1936 if (prev_size == 0) 1937 prev_size = this_size; 1938 1939 if (p_entry[i].en_type_def[j].dd_datatype == 1940 ADT_UINT32ARRAY) { 1941 p_data = (char *)adt_adjust_address(p_data, 1942 prev_size, sizeof (uint32_t)) + 1943 this_size - sizeof (uint32_t); 1944 1945 prev_size = sizeof (uint32_t); 1946 } else { 1947 p_data = adt_adjust_address(p_data, prev_size, 1948 this_size); 1949 prev_size = this_size; 1950 } 1951 } 1952 } 1953 } 1954 1955 /* 1956 * adt_generate_event 1957 * generate event record from external struct. The order is based on 1958 * the output tokens, allowing for the possibility that the input data 1959 * is in a different order. 1960 * 1961 */ 1962 1963 static int 1964 adt_generate_event(const adt_event_data_t *p_extdata, 1965 struct adt_event_state *p_event, 1966 adt_translation_t *p_xlate) 1967 { 1968 struct entry *p_entry; 1969 static mutex_t lock = DEFAULTMUTEX; 1970 1971 p_entry = p_xlate->tx_first_entry; 1972 assert(p_entry != NULL); 1973 1974 p_event->ae_internal_id = p_xlate->tx_internal_event; 1975 adt_token_open(p_event); 1976 1977 /* 1978 * offsets are not pre-calculated; the initial offsets are all 1979 * 0; valid offsets are >= 0. Offsets for no-input tokens such 1980 * as subject are set to -1 by adt_calcOffset() 1981 */ 1982 if (p_xlate->tx_offsetsCalculated == 0) { 1983 (void) mutex_lock(&lock); 1984 p_xlate->tx_offsetsCalculated = 1; 1985 1986 adt_calcOffsets(p_xlate->tx_top_entry, p_xlate->tx_entries, 1987 (void *)p_extdata); 1988 (void) mutex_unlock(&lock); 1989 } 1990 while (p_entry != NULL) { 1991 adt_generate_token(p_entry, (char *)p_extdata, p_event); 1992 1993 p_entry = p_entry->en_next_token; 1994 } 1995 return (adt_token_close(p_event)); 1996 } 1997 1998 /* 1999 * adt_put_event -- main event generation function. 2000 * The input "event" is the address of the struct containing 2001 * event-specific data. 2002 * 2003 * However if auditing is off or the session handle 2004 * is NULL, no attempt to write a record is made. 2005 */ 2006 2007 int 2008 adt_put_event(const adt_event_data_t *event, int status, int return_val) 2009 { 2010 struct adt_event_state *event_state; 2011 adt_translation_t *xlate; 2012 2013 if (event == NULL) { 2014 errno = EINVAL; 2015 return (-1); 2016 } 2017 event_state = (struct adt_event_state *)event; 2018 2019 /* if audit off or this is a broken session, exit */ 2020 if (auditstate == AUC_DISABLED || 2021 (event_state->ae_session == NULL)) { 2022 return (0); 2023 } 2024 2025 assert(event_state->ae_check == ADT_VALID); 2026 2027 event_state->ae_rc = status; 2028 event_state->ae_type = return_val; 2029 2030 /* look up the event */ 2031 2032 xlate = adt_getXlateTable(event_state->ae_session->as_xlate, 2033 event_state->ae_event_id); 2034 2035 if (xlate == NULL) { 2036 errno = EINVAL; 2037 return (-1); 2038 } 2039 DPRINTF(("got event %d\n", xlate->tx_internal_event)); 2040 2041 if (adt_selected(event_state, xlate->tx_internal_event, status)) { 2042 return (adt_generate_event(event, event_state, xlate)); 2043 } 2044 2045 return (0); 2046 } 2047 2048 /* 2049 * adt_free_event -- invalidate and free 2050 */ 2051 2052 void 2053 adt_free_event(adt_event_data_t *event) 2054 { 2055 struct adt_event_state *event_state; 2056 2057 if (event == NULL) 2058 return; 2059 2060 event_state = (struct adt_event_state *)event; 2061 2062 assert(event_state->ae_check == ADT_VALID); 2063 2064 event_state->ae_check = 0; 2065 2066 free(event_state); 2067 } 2068 2069 /* 2070 * adt_is_selected -- helper to adt_selected(), below. 2071 * 2072 * "sorf" is "success or fail" status; au_preselect compares 2073 * that with success, fail, or both. 2074 */ 2075 2076 static int 2077 adt_is_selected(au_event_t e, au_mask_t *m, int sorf) 2078 { 2079 int prs_sorf; 2080 2081 if (sorf == 0) 2082 prs_sorf = AU_PRS_SUCCESS; 2083 else 2084 prs_sorf = AU_PRS_FAILURE; 2085 2086 return (au_preselect(e, m, prs_sorf, AU_PRS_REREAD)); 2087 } 2088 2089 /* 2090 * selected -- see if this event is preselected. 2091 * 2092 * if errors are encountered trying to check a preselection mask 2093 * or look up a user name, the event is selected. Otherwise, the 2094 * preselection mask is used for the job. 2095 */ 2096 2097 static int 2098 adt_selected(struct adt_event_state *event, au_event_t actual_id, int status) 2099 { 2100 adt_internal_state_t *sp; 2101 au_mask_t namask; 2102 2103 sp = event->ae_session; 2104 2105 if ((sp->as_have_user_data & ADT_HAVE_IDS) == 0) { 2106 adt_write_syslog("No user data available", EINVAL); 2107 return (1); /* default is "selected" */ 2108 } 2109 2110 /* non-attributable? */ 2111 if ((sp->as_info.ai_auid == AU_NOAUDITID) || 2112 (sp->as_info.ai_auid == ADT_NO_AUDIT)) { 2113 if (auditon(A_GETKMASK, (caddr_t)&namask, 2114 sizeof (namask)) != 0) { 2115 adt_write_syslog("auditon failure", errno); 2116 return (1); 2117 } 2118 return (adt_is_selected(actual_id, &namask, status)); 2119 } else { 2120 return (adt_is_selected(actual_id, &(sp->as_info.ai_mask), 2121 status)); 2122 } 2123 } 2124 2125 /* 2126 * Can't map the host name to an IP address in 2127 * adt_get_hostIP. Get something off an interface 2128 * to act as the hosts IP address for auditing. 2129 */ 2130 2131 int 2132 adt_get_local_address(int family, struct ifaddrlist *al) 2133 { 2134 struct ifaddrlist *ifal; 2135 char errbuf[ERRBUFSIZE] = "empty list"; 2136 char msg[ERRBUFSIZE + 512]; 2137 int ifal_count; 2138 int i; 2139 2140 if ((ifal_count = ifaddrlist(&ifal, family, 0, errbuf)) <= 0) { 2141 int serrno = errno; 2142 2143 (void) snprintf(msg, sizeof (msg), "adt_get_local_address " 2144 "couldn't get %d addrlist %s", family, errbuf); 2145 adt_write_syslog(msg, serrno); 2146 errno = serrno; 2147 return (-1); 2148 } 2149 2150 for (i = 0; i < ifal_count; i++) { 2151 /* 2152 * loopback always defined, 2153 * even if there is no real address 2154 */ 2155 if ((ifal[i].flags & (IFF_UP | IFF_LOOPBACK)) == IFF_UP) { 2156 break; 2157 } 2158 } 2159 if (i >= ifal_count) { 2160 free(ifal); 2161 /* 2162 * Callers of adt_get_hostIP() can only return 2163 * errno to their callers and eventually the application. 2164 * Picked one that seemed least worse for saying no 2165 * usable address for Audit terminal ID. 2166 */ 2167 errno = ENETDOWN; 2168 return (-1); 2169 } 2170 2171 *al = ifal[i]; 2172 free(ifal); 2173 return (0); 2174 } 2175