1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 /* Audit daemon server */ 27 /* 28 * These routines make up the audit daemon server. This daemon, called 29 * auditd, handles the user level parts of auditing. It receives buffered 30 * audit records (usually one or more per buffer, potentially less than 31 * one) and passes them to one or more plugins for processing. 32 * 33 * The major interrupts are AU_SIG_READ_CONTROL (start over), 34 * AU_SIG_DISABLE (start shutting down), SIGALRM (quit), and 35 * AU_SIG_NEXT_DIR (start a new audit log file). SIGTERM (the implementation 36 * value of AU_SIG_DISABLE) is also used for the child to tell the parent 37 * that audit is ready. 38 * 39 * Configuration data comes from /etc/security/audit_control and the auditon 40 * system call. 41 * 42 * The major errors are EBUSY (auditing is already in use) and EINTR 43 * (one of the above signals was received). File space errors are 44 * handled by the audit_binfile plugin 45 */ 46 47 /* #define DEBUG - define for debug messages to be generated */ 48 /* #define MEM_TEST - define to generate core dump on exit */ 49 #define DEBUG 0 50 #define MEM_TEST 0 51 52 #include <assert.h> 53 #include <bsm/adt.h> 54 #include <bsm/audit.h> 55 #include <bsm/audit_record.h> 56 #include <bsm/libbsm.h> 57 #include <fcntl.h> 58 #include <libintl.h> 59 #include <locale.h> 60 #include <netdb.h> 61 #include <pwd.h> 62 #include <secdb.h> 63 #include <signal.h> 64 #include <stdio.h> 65 #include <stdlib.h> 66 #include <string.h> 67 #include <syslog.h> 68 #include <errno.h> 69 #include <sys/file.h> 70 #include <sys/param.h> 71 #include <sys/stat.h> 72 #include <sys/statvfs.h> 73 #include <sys/time.h> 74 #include <sys/types.h> 75 #include <sys/wait.h> 76 #include <termios.h> 77 #include <unistd.h> 78 #include "plugin.h" 79 #include "audit_sig_infc.h" 80 #include <audit_plugin.h> 81 #include <audit_scf.h> 82 83 #if !defined(TEXT_DOMAIN) 84 #define TEXT_DOMAIN "SUNW_OST_OSCMD" 85 #endif 86 /* 87 * After we get a AU_SIG_DISABLE, we want to set a timer for 2 seconds 88 * and let c2audit write as many records as it can until the timer 89 * goes off(at which point it returns to auditd with SIGALRM). If any 90 * other signals are received during that time, we call 91 * __audit_dowarn() to indicate that the queue may not have been fully 92 * flushed. 93 */ 94 #define ALRM_TIME 2 95 #define SLEEP_TIME 20 /* # of seconds to sleep in all hard loop */ 96 97 static plugin_t *binfile = NULL; 98 99 static int turn_audit_on = AUC_AUDITING; 100 static int turn_audit_off = AUC_NOAUDIT; 101 102 static int running = 1; 103 104 /* 105 * GLOBALS: 106 */ 107 plugin_t *plugin_head = NULL; 108 static thr_data_t main_thr; /* auditd thread (0) */ 109 pthread_mutex_t plugin_mutex; /* for plugin_t list */ 110 111 static int caught_alrm = 0; /* number of SIGALRMs pending */ 112 static int caught_readc = 0; /* number of AU_SIG_READ_CONTROLs */ 113 static int caught_term = 0; /* number of AU_SIG_DISABLEs pending */ 114 static int caught_nextd = 0; /* number of AU_SIG_NEXT_DIRs pending */ 115 116 static int reset_list = 1; /* 1 to re-read audit_control */ 117 static int reset_file = 1; /* 1 to close/open binary log */ 118 119 static int auditing_set = 0; /* 1 if auditon(A_SETCOND, on... */ 120 121 static void my_sleep(); 122 static void signal_thread(); 123 static void loadauditlist(); 124 static void block_signals(); 125 static int do_sethost(); 126 127 static void conf_to_kernel(); 128 static void aconf_to_kernel(); 129 static void scf_to_kernel_qctrl(); 130 static void scf_to_kernel_policy(); 131 132 /* 133 * err_exit() - exit function after the unsuccessful call to auditon(); 134 * prints_out / saves_via_syslog the necessary error messages. 135 */ 136 static void 137 err_exit(int rc, char *msg) 138 { 139 if (msg != NULL) { 140 DPRINT((dbfp, "%s\n", msg)); 141 __audit_syslog("auditd", LOG_PID | LOG_CONS | LOG_NOWAIT, 142 LOG_DAEMON, LOG_ALERT, msg); 143 free(msg); 144 } else { 145 DPRINT((dbfp, "the memory allocation failed\n")); 146 __audit_syslog("auditd", LOG_PID | LOG_CONS | LOG_NOWAIT, 147 LOG_DAEMON, LOG_ALERT, gettext("no memory")); 148 } 149 auditd_thread_close(); 150 auditd_exit(rc); 151 } 152 153 /* common exit function */ 154 void 155 auditd_exit(int status) 156 { 157 #if MEM_TEST 158 sigset_t set; 159 160 DPRINT((dbfp, "mem_test intentional abort (status=%d)\n", 161 status)); 162 abort(); 163 #endif 164 DPRINT((dbfp, "%ld exit status = %d auditing_set = %d\n", 165 getpid(), status, auditing_set)); 166 167 if (auditing_set) 168 (void) auditon(A_SETCOND, (caddr_t)&turn_audit_off, 169 (int)sizeof (int)); 170 171 #if DEBUG 172 (void) fclose(dbfp); 173 #endif 174 175 exit(status); 176 } 177 178 /* ARGSUSED */ 179 int 180 main(int argc, char *argv[]) 181 { 182 auditinfo_addr_t as_null; /* audit state to set */ 183 au_id_t auid; 184 pthread_t tid; 185 plugin_t *p; 186 pid_t pid; 187 188 #if DEBUG 189 /* LINTED */ 190 char *envp; 191 if (dbfp == NULL) { 192 dbfp = __auditd_debug_file_open(); 193 } 194 #endif 195 (void) setsid(); 196 197 /* Internationalization */ 198 (void) setlocale(LC_ALL, ""); 199 (void) textdomain(TEXT_DOMAIN); 200 201 /* 202 * Set the audit host-id. 203 */ 204 if (do_sethost() != 0) { 205 __audit_dowarn("nostart", "", 0); 206 auditd_exit(1); 207 } 208 209 /* 210 * Turn off all auditing for this process. 211 */ 212 if (getaudit_addr(&as_null, sizeof (as_null)) == -1) { 213 __audit_dowarn("nostart", "", 0); 214 auditd_exit(2); 215 } 216 as_null.ai_mask.as_success = 0; 217 as_null.ai_mask.as_failure = 0; 218 (void) setaudit_addr(&as_null, sizeof (as_null)); 219 auid = AU_NOAUDITID; 220 (void) setauid(&auid); 221 /* 222 * Set the audit state flag to AUDITING. 223 */ 224 if (auditon(A_SETCOND, (caddr_t)&turn_audit_on, (int)sizeof (int)) != 225 0) { 226 DPRINT((dbfp, "auditon(A_SETCOND...) failed (exit)\n")); 227 __audit_dowarn("nostart", "", 0); 228 auditd_exit(7); 229 } 230 231 block_signals(); 232 233 /* 234 * wait for "ready" signal before exit -- for greenline 235 */ 236 if (fork()) { 237 sigset_t set; 238 int signal_caught = 0; 239 240 (void) sigemptyset(&set); 241 (void) sigaddset(&set, AU_SIG_DISABLE); 242 243 while (signal_caught != AU_SIG_DISABLE) 244 signal_caught = sigwait(&set); 245 246 DPRINT((dbfp, "init complete: parent can now exit\n")); 247 248 auditd_exit(0); 249 } 250 pid = getppid(); 251 252 auditing_set = 1; 253 254 #if DEBUG && MEM_TEST 255 envp = getenv("UMEM_DEBUG"); 256 if (envp != NULL) 257 DPRINT((dbfp, "UMEM_DEBUG=%s\n", envp)); 258 envp = getenv("UMEM_LOGGING"); 259 if (envp != NULL) 260 DPRINT((dbfp, "UMEM_LOGGING=%s\n", envp)); 261 #endif 262 DPRINT((dbfp, "auditd pid=%ld\n", getpid())); 263 264 /* thread 0 sync */ 265 (void) pthread_mutex_init(&(main_thr.thd_mutex), NULL); 266 (void) pthread_cond_init(&(main_thr.thd_cv), NULL); 267 (void) pthread_mutex_init(&plugin_mutex, NULL); 268 /* 269 * Set up a separate thread for signal handling. 270 */ 271 if (pthread_create(&tid, NULL, (void *(*)(void *))signal_thread, 272 NULL)) { 273 (void) fprintf(stderr, gettext( 274 "auditd can't create a thread\n")); 275 auditd_exit(3); 276 } 277 /* 278 * Set the umask so that only audit or other users in the audit group 279 * can get to the files created by auditd. 280 */ 281 (void) umask(007); 282 283 if (__logpost("")) { /* Open the audit_data file. */ 284 DPRINT((dbfp, "logpost failed\n")); 285 auditd_exit(4); 286 } 287 /* 288 * Here is the main body of the audit daemon. running == 0 means that 289 * after flushing out the audit queue, it is time to exit in response to 290 * AU_SIG_DISABLE 291 */ 292 while (running) { 293 /* 294 * Read audit_control and create plugin lists. 295 * 296 * loadauditlist() and auditd_thread_init() are called 297 * while under the plugin_mutex lock to avoid a race 298 * with unload_plugin(). 299 */ 300 if (reset_list || reset_file) { 301 if (reset_list) { 302 conf_to_kernel(); 303 aconf_to_kernel(); 304 scf_to_kernel_qctrl(); 305 scf_to_kernel_policy(); 306 (void) pthread_mutex_lock(&plugin_mutex); 307 loadauditlist(); 308 } else { 309 (void) pthread_mutex_lock(&plugin_mutex); 310 } 311 312 if (auditd_thread_init()) { 313 auditd_thread_close(); 314 /* continue; wait for audit -s */ 315 } 316 (void) pthread_mutex_unlock(&plugin_mutex); 317 reset_list = 0; 318 319 if (reset_list && reset_file) { 320 (void) printf(gettext("auditd started\n")); 321 } else { 322 (void) printf(gettext("auditd refreshed\n")); 323 } 324 } 325 /* 326 * tell parent I'm running whether or not the initialization 327 * actually worked. The failure case is to wait for an 328 * audit -n or audit -s to fix the problem. 329 */ 330 if (pid != 0) { 331 (void) kill(pid, AU_SIG_DISABLE); 332 pid = 0; 333 } 334 /* 335 * thread_signal() signals main (this thread) when 336 * it has received a signal. 337 */ 338 DPRINT((dbfp, "main thread is waiting\n")); 339 (void) pthread_mutex_lock(&(main_thr.thd_mutex)); 340 341 if (!(caught_readc || caught_term || caught_alrm || 342 caught_nextd)) 343 (void) pthread_cond_wait(&(main_thr.thd_cv), 344 &(main_thr.thd_mutex)); 345 (void) pthread_mutex_unlock(&(main_thr.thd_mutex)); 346 /* 347 * Got here because a signal came in. 348 * Since we may have gotten more than one, we assume a 349 * priority scheme with SIGALRM being the most 350 * significant. 351 */ 352 if (caught_alrm) { 353 /* 354 * We have returned from our timed wait for 355 * c2audit to calm down. We need to really shut 356 * down here. 357 */ 358 caught_alrm = 0; 359 running = 0; /* shut down now */ 360 } else if (caught_term) { 361 /* 362 * we are going to shut down, but need to 363 * allow time for the audit queues in 364 * c2audit and for the threads to empty. 365 */ 366 367 p = plugin_head; 368 while (p != NULL) { 369 DPRINT((dbfp, "signalling thread %d\n", 370 p->plg_tid)); 371 (void) pthread_mutex_lock(&(p->plg_mutex)); 372 p->plg_removed = 1; 373 374 if (p->plg_initialized) 375 (void) pthread_cond_signal( 376 &(p->plg_cv)); 377 378 (void) pthread_mutex_unlock(&(p->plg_mutex)); 379 p = p->plg_next; 380 } 381 382 caught_alrm = 0; 383 caught_readc = 0; 384 caught_term = 0; 385 caught_nextd = 0; 386 387 DPRINT((dbfp, 388 "main thread is pausing before exit.\n")); 389 (void) pthread_mutex_lock(&(main_thr.thd_mutex)); 390 caught_alrm = 0; 391 (void) alarm(ALRM_TIME); 392 while (!caught_alrm) 393 (void) pthread_cond_wait(&(main_thr.thd_cv), 394 &(main_thr.thd_mutex)); 395 396 (void) pthread_mutex_unlock(&(main_thr.thd_mutex)); 397 398 running = 0; /* Close down auditing and exit */ 399 } else if (caught_readc) { 400 /* 401 * if both hup and usr1 are caught, the logic in 402 * loadauditlist() results in hup winning. The 403 * result will be that the audit file is not rolled 404 * over unless audit_control actually changed. 405 * 406 * They want to reread the audit_control file. 407 * Set reset_list which will return us to the 408 * main while loop in the main routine. 409 */ 410 caught_readc = 0; 411 reset_list = 1; 412 } else if (caught_nextd) { 413 /* 414 * This is a special case for the binfile 415 * plugin. (audit -n) NULL out kvlist 416 * so binfile won't re-read audit_control 417 */ 418 caught_nextd = 0; 419 reset_file = 1; 420 if (binfile != NULL) { 421 _kva_free(binfile->plg_kvlist); 422 binfile->plg_kvlist = NULL; 423 binfile->plg_reopen = 1; 424 } 425 } 426 } /* end while (running) */ 427 auditd_thread_close(); 428 429 auditd_exit(0); 430 return (0); 431 } 432 433 /* 434 * my_sleep - sleep for SLEEP_TIME seconds but only accept the signals 435 * that we want to accept. (Premature termination just means the 436 * caller retries more often, not a big deal.) 437 */ 438 439 static void 440 my_sleep() 441 { 442 DPRINT((dbfp, "auditd: sleeping for 20 seconds\n")); 443 /* 444 * Set timer to "sleep" 445 */ 446 (void) alarm(SLEEP_TIME); 447 448 DPRINT((dbfp, "main thread is waiting for SIGALRM before exit.\n")); 449 (void) pthread_mutex_lock(&(main_thr.thd_mutex)); 450 (void) pthread_cond_wait(&(main_thr.thd_cv), &(main_thr.thd_mutex)); 451 (void) pthread_mutex_unlock(&(main_thr.thd_mutex)); 452 453 if (caught_term) { 454 DPRINT((dbfp, "normal AU_SIG_DISABLE exit\n")); 455 /* 456 * Exit, as requested. 457 */ 458 auditd_thread_close(); 459 } 460 if (caught_readc) 461 reset_list = 1; /* Reread the audit_control file */ 462 463 caught_readc = 0; 464 caught_nextd = 0; 465 } 466 467 /* 468 * search for $ISA/ in path and replace it with "" if auditd 469 * is 32 bit, else "sparcv9/" The plugin $ISA must match however 470 * auditd was compiled. 471 */ 472 473 static void 474 isa_ified(char *path, char **newpath) 475 { 476 char *p, *q; 477 478 if (((p = strchr(path, '$')) != NULL) && 479 (strncmp("$ISA/", p, 5) == 0)) { 480 (void) memcpy(*newpath, path, p - path); 481 q = *newpath + (p - path); 482 #ifdef __sparcv9 483 q += strlcpy(q, "sparcv9/", avail_length); 484 #endif 485 (void) strcpy(q, p + 5); 486 } else 487 *newpath = path; 488 } 489 490 /* 491 * init_plugin first searches the existing plugin list to see 492 * if the plugin already has been defined; if not, it creates it 493 * and links it into the list. It returns a pointer to the found 494 * or created struct. A change of path in audit_control for a 495 * given plugin will cause a miss. 496 */ 497 /* 498 * for 64 bits, the path name can grow 3 bytes (minus 5 for the 499 * removed "$ISA" and plus 8 for the added "sparcv9/" 500 */ 501 502 #define ISA_GROW 8 - 5 503 504 static plugin_t * 505 init_plugin(char *name, kva_t *list, int cnt_flag) 506 { 507 plugin_t *p, *q; 508 char filepath[MAXPATHLEN + 1 + ISA_GROW]; 509 char *path = filepath; 510 511 if (*name != '/') { 512 #ifdef __sparcv9 513 (void) strcpy(filepath, "/usr/lib/security/sparcv9/"); 514 #else 515 (void) strcpy(filepath, "/usr/lib/security/"); 516 #endif 517 if (strlcat(filepath, name, MAXPATHLEN) >= MAXPATHLEN) 518 return (NULL); 519 } else { 520 if (strlen(name) > MAXPATHLEN + ISA_GROW) 521 return (NULL); 522 isa_ified(name, &path); 523 } 524 p = plugin_head; 525 q = plugin_head; 526 while (p != NULL) { 527 if (p->plg_path != NULL) { 528 if (strcmp(p->plg_path, path) == 0) { 529 p->plg_removed = 0; 530 p->plg_to_be_removed = 0; 531 p->plg_cnt = cnt_flag; 532 533 _kva_free(p->plg_kvlist); 534 p->plg_kvlist = list; 535 p->plg_reopen = 1; 536 DPRINT((dbfp, "reusing %s\n", p->plg_path)); 537 return (p); 538 } 539 } 540 q = p; 541 p = p->plg_next; 542 } 543 DPRINT((dbfp, "creating new plugin structure for %s\n", path)); 544 545 p = malloc(sizeof (plugin_t)); 546 547 if (p == NULL) { 548 perror("auditd"); 549 return (NULL); 550 } 551 if (q == NULL) 552 plugin_head = p; 553 else 554 q->plg_next = p; 555 556 p->plg_next = NULL; 557 p->plg_initialized = 0; 558 p->plg_reopen = 1; 559 p->plg_tid = 0; 560 p->plg_removed = 0; 561 p->plg_to_be_removed = 0; 562 p->plg_tossed = 0; 563 p->plg_queued = 0; 564 p->plg_output = 0; 565 p->plg_sequence = 1; 566 p->plg_last_seq_out = 0; 567 p->plg_path = strdup(path); 568 p->plg_kvlist = list; 569 p->plg_cnt = cnt_flag; 570 p->plg_retry_time = SLEEP_TIME; 571 p->plg_qmax = 0; 572 p->plg_save_q_copy = NULL; 573 574 DPRINT((dbfp, "created plugin: %s\n", path)); 575 return (p); 576 } 577 578 /* 579 * loadauditlist - read the directory list from the audit_control file. 580 * to determine if a binary file is to be written. 581 * - read the plugin entries from the audit_control file 582 * 583 * globals - 584 * 585 * plugin queues 586 * 587 * success is when at least one plug in is defined. 588 * 589 * set cnt policy here based on auditconfig setting. future could 590 * have a policy = {+|-}cnt entry per plugin with auditconfig providing the 591 * default. 592 */ 593 594 static void 595 loadauditlist() 596 { 597 char buf[MAXPATHLEN]; 598 char *value; 599 plugin_t *p; 600 int acresult; 601 int wait_count = 0; 602 kva_t *kvlist; 603 long policy; 604 int cnt_flag; 605 struct au_qctrl kqmax; 606 au_acinfo_t *ach = NULL; 607 int got_dir = 0; 608 int have_plugin = 0; 609 char *endptr; 610 611 if (auditon(A_GETPOLICY, (char *)&policy, 0) == -1) { 612 DPRINT((dbfp, "auditon(A_GETPOLICY...) failed (exit)\n")); 613 __audit_dowarn("auditoff", "", 0); 614 auditd_thread_close(); 615 auditd_exit(5); 616 } 617 cnt_flag = ((policy & AUDIT_CNT) != 0) ? 1 : 0; 618 DPRINT((dbfp, "loadauditlist: policy is to %s\n", (cnt_flag == 1) ? 619 "continue" : "block")); 620 621 #if DEBUG 622 if (auditon(A_GETCOND, (caddr_t)&acresult, (int)sizeof (int)) != 0) 623 DPRINT((dbfp, "auditon(A_GETCOND...) failed (exit)\n")); 624 625 DPRINT((dbfp, "audit cond = %d (1 is on)\n", acresult)); 626 #endif 627 628 629 if (auditon(A_GETQCTRL, (char *)&kqmax, sizeof (struct au_qctrl)) != 630 0) { 631 DPRINT((dbfp, "auditon(A_GETQCTRL...) failed (exit)\n")); 632 __audit_dowarn("auditoff", "", 0); 633 auditd_thread_close(); 634 auditd_exit(6); 635 } 636 kqmax.aq_hiwater *= 5; /* RAM is cheaper in userspace */ 637 DPRINT((dbfp, "auditd: reading audit_control\n")); 638 639 p = plugin_head; 640 /* 641 * two-step on setting p->plg_removed because the input thread 642 * in doorway.c uses p->plg_removed to decide if the plugin is 643 * active. 644 */ 645 while (p != NULL) { 646 DPRINT((dbfp, "loadauditlist: %p, %s previously created\n", 647 (void *)p, p->plg_path)); 648 p->plg_to_be_removed = 1; /* tentative removal */ 649 p = p->plg_next; 650 } 651 /* 652 * have_plugin may over count by one if both a "dir" entry 653 * and a "plugin" entry for binfile are found. All that 654 * matters is that it be zero if no plugin or dir entries 655 * are found. 656 */ 657 have_plugin = 0; 658 for (;;) { 659 /* NULL == use standard path for audit_control */ 660 ach = _openac(NULL); 661 /* 662 * loop until a directory entry is found (0) or eof (-1) 663 */ 664 while (((acresult = _getacdir(ach, buf, sizeof (buf))) != 0) && 665 acresult != -1) { 666 } 667 if (acresult == 0) { 668 DPRINT((dbfp, 669 "loadauditlist: " 670 "got binfile via old config syntax\n")); 671 /* 672 * A directory entry was found. 673 */ 674 got_dir = 1; 675 kvlist = _str2kva("name=audit_binfile.so.1", 676 "=", ";"); 677 678 p = init_plugin("audit_binfile.so.1", kvlist, cnt_flag); 679 680 if (p != NULL) { 681 binfile = p; 682 p->plg_qmax = kqmax.aq_hiwater; 683 have_plugin++; 684 } 685 } 686 /* 687 * collect plugin entries. If there is an entry for 688 * binfile.so.1, the parameters from the plugin line 689 * override those set above. For binfile, p_dir is 690 * required only if dir wasn't specified elsewhere in 691 * audit_control 692 */ 693 _rewindac(ach); 694 while ((acresult = _getacplug(ach, &kvlist)) == 0) { 695 value = kva_match(kvlist, "name"); 696 if (value == NULL) 697 break; 698 DPRINT((dbfp, "loadauditlist: have an entry for %s\n", 699 value)); 700 p = init_plugin(value, kvlist, cnt_flag); 701 if (p == NULL) 702 continue; 703 704 if (strstr(value, "/audit_binfile.so") != NULL) { 705 binfile = p; 706 if (!got_dir && 707 (kva_match(kvlist, "p_dir") == 708 NULL)) { 709 __audit_dowarn("getacdir", "", 710 wait_count); 711 } 712 } 713 p->plg_qmax = kqmax.aq_hiwater; /* default */ 714 value = kva_match(kvlist, "qsize"); 715 if (value != NULL) { 716 long tmp; 717 718 tmp = strtol(value, &endptr, 10); 719 if (*endptr == '\0') 720 p->plg_qmax = tmp; 721 } 722 DPRINT((dbfp, "%s queue max = %d\n", p->plg_path, 723 p->plg_qmax)); 724 725 have_plugin++; 726 } 727 _endac(ach); 728 if (have_plugin != 0) 729 break; 730 /* 731 * there was a problem getting the directory 732 * list or remote host info from the audit_control file 733 */ 734 wait_count++; 735 #if DEBUG 736 if (wait_count < 2) 737 DPRINT((dbfp, 738 "auditd: problem getting directory " 739 "/ or plugin list from audit_control.\n")); 740 #endif /* DEBUG */ 741 __audit_dowarn("getacdir", "", wait_count); 742 /* 743 * sleep for SLEEP_TIME seconds. 744 */ 745 my_sleep(); 746 } /* end for(;;) */ 747 748 p = plugin_head; 749 while (p != NULL) { 750 DPRINT((dbfp, "loadauditlist: %s remove flag=%d; cnt=%d\n", 751 p->plg_path, p->plg_to_be_removed, p->plg_cnt)); 752 p->plg_removed = p->plg_to_be_removed; 753 p = p->plg_next; 754 } 755 } 756 757 /* 758 * block signals -- thread-specific blocking of the signals expected 759 * by the main thread. 760 */ 761 762 static void 763 block_signals() 764 { 765 sigset_t set; 766 767 (void) sigfillset(&set); 768 (void) pthread_sigmask(SIG_BLOCK, &set, NULL); 769 } 770 771 /* 772 * signal_thread is the designated signal catcher. It wakes up the 773 * main thread whenever it receives a signal and then goes back to 774 * sleep; it does not exit. The global variables caught_* let 775 * the main thread which signal was received. 776 * 777 * The thread is created with all signals blocked. 778 */ 779 780 static void 781 signal_thread() 782 { 783 sigset_t set; 784 int signal_caught; 785 786 DPRINT((dbfp, "the signal thread is thread %d\n", 787 pthread_self())); 788 789 (void) sigemptyset(&set); 790 (void) sigaddset(&set, SIGALRM); 791 (void) sigaddset(&set, AU_SIG_DISABLE); 792 (void) sigaddset(&set, AU_SIG_READ_CONTROL); 793 (void) sigaddset(&set, AU_SIG_NEXT_DIR); 794 795 for (;;) { 796 signal_caught = sigwait(&set); 797 switch (signal_caught) { 798 case SIGALRM: 799 caught_alrm++; 800 DPRINT((dbfp, "caught SIGALRM\n")); 801 break; 802 case AU_SIG_DISABLE: 803 caught_term++; 804 DPRINT((dbfp, "caught AU_SIG_DISABLE\n")); 805 break; 806 case AU_SIG_READ_CONTROL: 807 caught_readc++; 808 DPRINT((dbfp, "caught AU_SIG_READ_CONTROL\n")); 809 break; 810 case AU_SIG_NEXT_DIR: 811 caught_nextd++; 812 DPRINT((dbfp, "caught AU_SIG_NEXT_DIR\n")); 813 break; 814 default: 815 DPRINT((dbfp, "caught unexpected signal: %d\n", 816 signal_caught)); 817 break; 818 } 819 (void) pthread_cond_signal(&(main_thr.thd_cv)); 820 } 821 } 822 823 /* 824 * do_sethost - do auditon(2) to set the audit host-id. 825 * Returns 0 if success or -1 otherwise. 826 */ 827 static int 828 do_sethost(void) 829 { 830 au_tid_addr_t *termid; 831 auditinfo_addr_t audit_info; 832 char msg[512]; 833 834 if (adt_load_hostname(NULL, (adt_termid_t **)&termid) < 0) { 835 (void) snprintf(msg, sizeof (msg), "unable to get local " 836 "IP address: %s", strerror(errno)); 837 goto fail; 838 } 839 /* Get current kernel audit info, and fill in the IP address */ 840 if (auditon(A_GETKAUDIT, (caddr_t)&audit_info, 841 sizeof (audit_info)) < 0) { 842 (void) snprintf(msg, sizeof (msg), "unable to get kernel " 843 "audit info: %s", strerror(errno)); 844 goto fail; 845 } 846 847 audit_info.ai_termid = *termid; 848 849 /* Update the kernel audit info with new IP address */ 850 if (auditon(A_SETKAUDIT, (caddr_t)&audit_info, 851 sizeof (audit_info)) < 0) { 852 (void) snprintf(msg, sizeof (msg), "unable to set kernel " 853 "audit info: %s", strerror(errno)); 854 goto fail; 855 } 856 857 free(termid); 858 return (0); 859 860 fail: 861 free(termid); 862 __audit_syslog("auditd", LOG_PID | LOG_CONS | LOG_NOWAIT, LOG_DAEMON, 863 LOG_ALERT, msg); 864 return (-1); 865 } 866 867 /* 868 * conf_to_kernel() - configure the event to class mapping; see also 869 * auditconfig(1M) -conf option. 870 */ 871 static void 872 conf_to_kernel(void) 873 { 874 register au_event_ent_t *evp; 875 register int i; 876 char *msg; 877 au_evclass_map_t ec; 878 au_stat_t as; 879 880 if (auditon(A_GETSTAT, (caddr_t)&as, 0) != 0) { 881 (void) asprintf(&msg, gettext("Audit module does not appear " 882 "to be loaded.")); 883 err_exit(1, msg); 884 } 885 886 i = 0; 887 setauevent(); 888 while ((evp = getauevent()) != NULL) { 889 if (evp->ae_number <= as.as_numevent) { 890 ++i; 891 ec.ec_number = evp->ae_number; 892 ec.ec_class = evp->ae_class; 893 894 if (auditon(A_SETCLASS, (caddr_t)&ec, 895 (int)sizeof (ec)) != 0) { 896 (void) asprintf(&msg, 897 gettext("Could not configure kernel audit " 898 "event to class mappings.")); 899 err_exit(1, msg); 900 } 901 } 902 } 903 endauevent(); 904 905 DPRINT((dbfp, "configured %d kernel events.\n", i)); 906 } 907 908 /* 909 * aconf_to_kernel() - set the non-attributable audit mask from the 910 * audit_control(4); see also auditconfig(1M) -aconf option. 911 */ 912 static void 913 aconf_to_kernel(void) 914 { 915 char *msg; 916 char buf[2048]; 917 au_mask_t pmask; 918 919 if (getacna(buf, sizeof (buf)) < 0) { 920 (void) asprintf(&msg, 921 gettext("bad non-attributable flags in audit_control(4)")); 922 err_exit(1, msg); 923 } 924 925 if (getauditflagsbin(buf, &pmask) < 0) { 926 (void) asprintf(&msg, 927 gettext("bad audit flag value encountered")); 928 err_exit(1, msg); 929 } 930 931 if (auditon(A_SETKMASK, (caddr_t)&pmask, (int)sizeof (pmask)) != 0) { 932 (void) asprintf(&msg, 933 gettext("Could not configure non-attributable events.")); 934 err_exit(1, msg); 935 } 936 937 DPRINT((dbfp, "configured non-attributable events.\n")); 938 } 939 940 /* 941 * scf_to_kernel_qctrl() - update the kernel queue control parameters 942 */ 943 static void 944 scf_to_kernel_qctrl(void) 945 { 946 struct au_qctrl act_qctrl; 947 struct au_qctrl cfg_qctrl; 948 char *msg; 949 950 if (!do_getqctrl_scf(&cfg_qctrl)) { 951 (void) asprintf(&msg, gettext("Unable to gather audit queue " 952 "control parameters from the SMF repository.")); 953 err_exit(1, msg); 954 } 955 956 DPRINT((dbfp, "will check and set qctrl parameters:\n")); 957 DPRINT((dbfp, "\thiwater: %d\n", cfg_qctrl.aq_hiwater)); 958 DPRINT((dbfp, "\tlowater: %d\n", cfg_qctrl.aq_lowater)); 959 DPRINT((dbfp, "\tbufsz: %d\n", cfg_qctrl.aq_bufsz)); 960 DPRINT((dbfp, "\tdelay: %ld\n", cfg_qctrl.aq_delay)); 961 962 if (auditon(A_GETQCTRL, (caddr_t)&act_qctrl, 0) != 0) { 963 (void) asprintf(&msg, gettext("Could not retrieve " 964 "audit queue controls from kernel.")); 965 err_exit(1, msg); 966 } 967 968 /* overwrite the default (zeros) from the qctrl configuration */ 969 if (cfg_qctrl.aq_hiwater == 0) { 970 cfg_qctrl.aq_hiwater = act_qctrl.aq_hiwater; 971 DPRINT((dbfp, "hiwater changed to active value: %u\n", 972 cfg_qctrl.aq_hiwater)); 973 } 974 if (cfg_qctrl.aq_lowater == 0) { 975 cfg_qctrl.aq_lowater = act_qctrl.aq_lowater; 976 DPRINT((dbfp, "lowater changed to active value: %u\n", 977 cfg_qctrl.aq_lowater)); 978 } 979 if (cfg_qctrl.aq_bufsz == 0) { 980 cfg_qctrl.aq_bufsz = act_qctrl.aq_bufsz; 981 DPRINT((dbfp, "bufsz changed to active value: %u\n", 982 cfg_qctrl.aq_bufsz)); 983 } 984 if (cfg_qctrl.aq_delay == 0) { 985 cfg_qctrl.aq_delay = act_qctrl.aq_delay; 986 DPRINT((dbfp, "delay changed to active value: %ld\n", 987 cfg_qctrl.aq_delay)); 988 } 989 990 if (auditon(A_SETQCTRL, (caddr_t)&cfg_qctrl, 0) != 0) { 991 (void) asprintf(&msg, 992 gettext("Could not configure audit queue controls.")); 993 err_exit(1, msg); 994 } 995 996 DPRINT((dbfp, "qctrl parameters set\n")); 997 } 998 999 /* 1000 * scf_to_kernel_policy() - update the audit service policies 1001 */ 1002 static void 1003 scf_to_kernel_policy(void) 1004 { 1005 uint32_t policy; 1006 char *msg; 1007 1008 if (!do_getpolicy_scf(&policy)) { 1009 (void) asprintf(&msg, gettext("Unable to get audit policy " 1010 "configuration from the SMF repository.")); 1011 err_exit(1, msg); 1012 } 1013 1014 if (auditon(A_SETPOLICY, (caddr_t)&policy, 0) != 0) { 1015 (void) asprintf(&msg, 1016 gettext("Could not update active policy settings.")); 1017 err_exit(1, msg); 1018 } 1019 1020 DPRINT((dbfp, "kernel policy settings updated\n")); 1021 } 1022