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