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(void *); 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, signal_thread, NULL)) { 266 (void) fprintf(stderr, gettext( 267 "auditd can't create a thread\n")); 268 auditd_exit(1); 269 } 270 /* 271 * Set the umask so that only audit or other users in the audit group 272 * can get to the files created by auditd. 273 */ 274 (void) umask(007); 275 276 if (__logpost("")) { /* Cannot unlink pointer to audit.log(4) file */ 277 DPRINT((dbfp, "logpost failed\n")); 278 auditd_exit(1); 279 } 280 /* 281 * Here is the main body of the audit daemon. running == 0 means that 282 * after flushing out the audit queue, it is time to exit in response 283 * to SIGTERM. 284 */ 285 while (running) { 286 /* 287 * Read auditd / auditd plugins related configuration from 288 * smf(5) repository and create plugin lists. 289 * 290 * loadauditlist() and auditd_thread_init() are called 291 * while under the plugin_mutex lock to avoid a race 292 * with unload_plugin(). 293 */ 294 if (reset_list || reset_file) { 295 if (reset_list) { 296 conf_to_kernel(); 297 scf_to_kernel_qctrl(); 298 scf_to_kernel_policy(); 299 (void) pthread_mutex_lock(&plugin_mutex); 300 loadauditlist(); 301 } else { 302 (void) pthread_mutex_lock(&plugin_mutex); 303 } 304 305 if (auditd_thread_init()) { 306 auditd_thread_close(); 307 /* continue; wait for audit -s */ 308 } 309 (void) pthread_mutex_unlock(&plugin_mutex); 310 311 if (reset_list && reset_file) { 312 (void) printf(gettext("auditd started\n")); 313 } else { 314 (void) printf(gettext("auditd refreshed\n")); 315 } 316 317 reset_list = 0; 318 reset_file = 0; 319 } 320 /* 321 * tell parent I'm running whether or not the initialization 322 * actually worked. The failure case is to wait for an 323 * audit -n or audit -s to fix the problem. 324 */ 325 if (pid != 0) { 326 (void) kill(pid, SIGTERM); 327 pid = 0; 328 } 329 /* 330 * thread_signal() signals main (this thread) when 331 * it has received a signal. 332 */ 333 DPRINT((dbfp, "main thread is waiting for signal\n")); 334 (void) pthread_mutex_lock(&(main_thr.thd_mutex)); 335 336 if (!(caught_readc || caught_term || caught_alrm || 337 caught_nextd)) 338 (void) pthread_cond_wait(&(main_thr.thd_cv), 339 &(main_thr.thd_mutex)); 340 (void) pthread_mutex_unlock(&(main_thr.thd_mutex)); 341 /* 342 * Got here because a signal came in. 343 * Since we may have gotten more than one, we assume a 344 * priority scheme with SIGALRM being the most 345 * significant. 346 */ 347 if (caught_alrm) { 348 /* 349 * We have returned from our timed wait for 350 * c2audit to calm down. We need to really shut 351 * down here. 352 */ 353 caught_alrm = 0; 354 running = 0; /* shut down now */ 355 } else if (caught_term) { 356 /* 357 * we are going to shut down, but need to 358 * allow time for the audit queues in 359 * c2audit and for the threads to empty. 360 */ 361 362 p = plugin_head; 363 while (p != NULL) { 364 DPRINT((dbfp, "signalling thread %d\n", 365 p->plg_tid)); 366 (void) pthread_mutex_lock(&(p->plg_mutex)); 367 p->plg_removed = 1; 368 369 if (p->plg_initialized) 370 (void) pthread_cond_signal( 371 &(p->plg_cv)); 372 373 (void) pthread_mutex_unlock(&(p->plg_mutex)); 374 p = p->plg_next; 375 } 376 377 caught_alrm = 0; 378 caught_readc = 0; 379 caught_term = 0; 380 caught_nextd = 0; 381 382 DPRINT((dbfp, 383 "main thread is pausing before exit.\n")); 384 (void) pthread_mutex_lock(&(main_thr.thd_mutex)); 385 caught_alrm = 0; 386 (void) alarm(ALRM_TIME); 387 while (!caught_alrm) 388 (void) pthread_cond_wait(&(main_thr.thd_cv), 389 &(main_thr.thd_mutex)); 390 391 (void) pthread_mutex_unlock(&(main_thr.thd_mutex)); 392 393 running = 0; /* Close down auditing and exit */ 394 } else if (caught_readc) { 395 /* 396 * if both hup and usr1 are caught, the logic in 397 * loadauditlist() results in hup winning. The 398 * result will be that the audit file is not rolled 399 * over unless audit configuration actually changed. 400 * 401 * They want to reread the audit configuration from 402 * smf(5) repository (AUDITD_FMRI). Set reset_list 403 * which will return us to the main while loop in the 404 * main routine. 405 */ 406 caught_readc = 0; 407 reset_list = 1; 408 } else if (caught_nextd) { 409 /* 410 * This is a special case for the binfile plugin. 411 * (audit -n) NULL out kvlist so binfile won't 412 * re-read audit configuration. 413 */ 414 caught_nextd = 0; 415 reset_file = 1; 416 if (binfile != NULL) { 417 _kva_free(binfile->plg_kvlist); 418 binfile->plg_kvlist = NULL; 419 binfile->plg_reopen = 1; 420 } 421 } 422 } /* end while (running) */ 423 auditd_thread_close(); 424 425 auditd_exit(0); 426 return (0); 427 } 428 429 /* 430 * my_sleep - sleep for SLEEP_TIME seconds but only accept the signals 431 * that we want to accept. (Premature termination just means the 432 * caller retries more often, not a big deal.) 433 */ 434 435 static void 436 my_sleep() 437 { 438 DPRINT((dbfp, "auditd: sleeping for 20 seconds\n")); 439 /* 440 * Set timer to "sleep" 441 */ 442 (void) alarm(SLEEP_TIME); 443 444 DPRINT((dbfp, "main thread is waiting for SIGALRM before exit.\n")); 445 (void) pthread_mutex_lock(&(main_thr.thd_mutex)); 446 (void) pthread_cond_wait(&(main_thr.thd_cv), &(main_thr.thd_mutex)); 447 (void) pthread_mutex_unlock(&(main_thr.thd_mutex)); 448 449 if (caught_term) { 450 DPRINT((dbfp, "normal SIGTERM exit\n")); 451 /* 452 * Exit, as requested. 453 */ 454 auditd_thread_close(); 455 } 456 if (caught_readc) 457 reset_list = 1; /* Reread the audit configuration */ 458 459 caught_readc = 0; 460 caught_nextd = 0; 461 } 462 463 /* 464 * search for $ISA/ in path and replace it with "" if auditd 465 * is 32 bit, else "sparcv9/" The plugin $ISA must match however 466 * auditd was compiled. 467 */ 468 469 static void 470 isa_ified(char *path, char **newpath) 471 { 472 char *p, *q; 473 474 if (((p = strchr(path, '$')) != NULL) && 475 (strncmp("$ISA/", p, 5) == 0)) { 476 (void) memcpy(*newpath, path, p - path); 477 q = *newpath + (p - path); 478 #ifdef __sparcv9 479 q += strlcpy(q, "sparcv9/", avail_length); 480 #endif 481 (void) strcpy(q, p + 5); 482 } else 483 *newpath = path; 484 } 485 486 /* 487 * init_plugin first searches the existing plugin list to see if the plugin 488 * already has been defined; if not, it creates it and links it into the list. 489 * It returns a pointer to the found or created struct. Note, that 490 * (manual/unsupported) change of path property in audit service configuration 491 * for given plugin will cause a miss. 492 */ 493 /* 494 * for 64 bits, the path name can grow 3 bytes (minus 5 for the 495 * removed "$ISA" and plus 8 for the added "sparcv9/" 496 */ 497 498 #define ISA_GROW 8 - 5 499 500 static plugin_t * 501 init_plugin(char *name, kva_t *list, int cnt_flag) 502 { 503 plugin_t *p, *q; 504 char filepath[MAXPATHLEN + 1 + ISA_GROW]; 505 char *path = filepath; 506 507 if (*name != '/') { 508 #ifdef __sparcv9 509 (void) strcpy(filepath, "/usr/lib/security/sparcv9/"); 510 #else 511 (void) strcpy(filepath, "/usr/lib/security/"); 512 #endif 513 if (strlcat(filepath, name, MAXPATHLEN) >= MAXPATHLEN) 514 return (NULL); 515 } else { 516 if (strlen(name) > MAXPATHLEN + ISA_GROW) 517 return (NULL); 518 isa_ified(name, &path); 519 } 520 p = plugin_head; 521 q = plugin_head; 522 while (p != NULL) { 523 if (p->plg_path != NULL) { 524 if (strcmp(p->plg_path, path) == 0) { 525 p->plg_removed = 0; 526 p->plg_to_be_removed = 0; 527 p->plg_cnt = cnt_flag; 528 529 _kva_free(p->plg_kvlist); 530 p->plg_kvlist = _kva_dup(list); 531 if (list != NULL && p->plg_kvlist == NULL) { 532 err_exit(NULL); 533 } 534 p->plg_reopen = 1; 535 DPRINT((dbfp, "reusing %s\n", p->plg_path)); 536 return (p); 537 } 538 } 539 q = p; 540 p = p->plg_next; 541 } 542 DPRINT((dbfp, "creating new plugin structure for %s\n", path)); 543 544 p = malloc(sizeof (plugin_t)); 545 546 if (p == NULL) { 547 perror("auditd"); 548 return (NULL); 549 } 550 if (q == NULL) 551 plugin_head = p; 552 else 553 q->plg_next = p; 554 555 p->plg_next = NULL; 556 p->plg_initialized = 0; 557 p->plg_reopen = 1; 558 p->plg_tid = 0; 559 p->plg_removed = 0; 560 p->plg_to_be_removed = 0; 561 p->plg_tossed = 0; 562 p->plg_queued = 0; 563 p->plg_output = 0; 564 p->plg_sequence = 1; 565 p->plg_last_seq_out = 0; 566 p->plg_path = strdup(path); 567 p->plg_kvlist = _kva_dup(list); 568 p->plg_cnt = cnt_flag; 569 p->plg_retry_time = SLEEP_TIME; 570 p->plg_qmax = 0; 571 p->plg_save_q_copy = NULL; 572 573 if (list != NULL && p->plg_kvlist == NULL || p->plg_path == NULL) { 574 err_exit(NULL); 575 } 576 577 DPRINT((dbfp, "created plugin: %s\n", path)); 578 return (p); 579 } 580 581 /* 582 * loadauditlist() - read the auditd plugin configuration from smf(5) and 583 * prepare appropriate plugin related structures (plugin_t). Set cnt policy here 584 * based on currently active policy settings. (future could have a policy = 585 * {+|-}cnt entry per plugin with auditconfig providing the default) 586 */ 587 static void 588 loadauditlist() 589 { 590 char *value; 591 char *endptr; 592 plugin_t *p; 593 uint32_t policy; 594 int cnt_flag; 595 struct au_qctrl kqmax; 596 scf_plugin_kva_node_t *plugin_kva_ll; 597 scf_plugin_kva_node_t *plugin_kva_ll_head; 598 599 if (auditon(A_GETPOLICY, (char *)&policy, 0) == -1) { 600 DPRINT((dbfp, "auditon(A_GETPOLICY...) failed (exit)\n")); 601 __audit_dowarn("auditoff", "", 0); 602 auditd_thread_close(); 603 auditd_exit(1); 604 } 605 cnt_flag = ((policy & AUDIT_CNT) != 0) ? 1 : 0; 606 DPRINT((dbfp, "loadauditlist: policy is to %s\n", (cnt_flag == 1) ? 607 "continue" : "block")); 608 609 #if DEBUG 610 { 611 int acresult; 612 if (auditon(A_GETCOND, (caddr_t)&acresult, sizeof (int)) != 0) { 613 DPRINT((dbfp, "auditon(A_GETCOND...) failed (exit)\n")); 614 } 615 DPRINT((dbfp, "audit cond = %d (1 is on)\n", acresult)); 616 } 617 #endif 618 619 620 if (auditon(A_GETQCTRL, (char *)&kqmax, sizeof (struct au_qctrl)) != 621 0) { 622 DPRINT((dbfp, "auditon(A_GETQCTRL...) failed (exit)\n")); 623 __audit_dowarn("auditoff", "", 0); 624 auditd_thread_close(); 625 auditd_exit(1); 626 } 627 kqmax.aq_hiwater *= 5; /* RAM is cheaper in userspace */ 628 DPRINT((dbfp, "auditd: reading audit configuration\n")); 629 630 p = plugin_head; 631 /* 632 * two-step on setting p->plg_removed because the input thread 633 * in doorway.c uses p->plg_removed to decide if the plugin is 634 * active. 635 */ 636 while (p != NULL) { 637 DPRINT((dbfp, "loadauditlist: %p, %s previously created\n", 638 (void *)p, p->plg_path)); 639 p->plg_to_be_removed = 1; /* tentative removal */ 640 p = p->plg_next; 641 } 642 643 if (!do_getpluginconfig_scf(NULL, &plugin_kva_ll)) { 644 DPRINT((dbfp, "Could not get plugin configuration.\n")); 645 auditd_thread_close(); 646 auditd_exit(1); 647 } 648 plugin_kva_ll_head = plugin_kva_ll; 649 650 while (plugin_kva_ll != NULL) { 651 DPRINT((dbfp, "loadauditlist: starting with %s", 652 plugin_kva_ll->plugin_name)); 653 654 /* skip inactive plugins */ 655 value = kva_match(plugin_kva_ll->plugin_kva, PLUGIN_ACTIVE); 656 if (strcmp(value, "1") != 0) { 657 DPRINT((dbfp, " (inactive:%s) skipping..\n", value)); 658 plugin_kva_ll = plugin_kva_ll->next; 659 continue; 660 } 661 DPRINT((dbfp, " (active)\n")); 662 663 value = kva_match(plugin_kva_ll->plugin_kva, PLUGIN_PATH); 664 DPRINT((dbfp, "loadauditlist: have an entry for %s (%s)\n", 665 plugin_kva_ll->plugin_name, value)); 666 667 p = init_plugin(value, plugin_kva_ll->plugin_kva, cnt_flag); 668 if (p == NULL) { 669 DPRINT((dbfp, "Unsuccessful plugin_t " 670 "initialization.\n")); 671 my_sleep(); 672 continue; 673 } 674 675 if (strcmp(plugin_kva_ll->plugin_name, "audit_binfile") == 0) { 676 binfile = p; 677 } 678 679 p->plg_qmax = kqmax.aq_hiwater; /* default */ 680 value = kva_match(plugin_kva_ll->plugin_kva, PLUGIN_QSIZE); 681 if (value != NULL) { 682 long tmp; 683 tmp = strtol(value, &endptr, 10); 684 if (*endptr == '\0' && tmp != 0) { 685 p->plg_qmax = tmp; 686 } 687 } 688 DPRINT((dbfp, "%s queue max = %d\n", p->plg_path, p->plg_qmax)); 689 690 plugin_kva_ll = plugin_kva_ll->next; 691 } 692 693 p = plugin_head; 694 while (p != NULL) { 695 DPRINT((dbfp, "loadauditlist: %s remove flag=%d; cnt=%d\n", 696 p->plg_path, p->plg_to_be_removed, p->plg_cnt)); 697 p->plg_removed = p->plg_to_be_removed; 698 p = p->plg_next; 699 } 700 701 plugin_kva_ll_free(plugin_kva_ll_head); 702 } 703 704 /* 705 * block signals -- thread-specific blocking of the signals expected 706 * by the main thread. 707 */ 708 709 static void 710 block_signals() 711 { 712 sigset_t set; 713 714 (void) sigfillset(&set); 715 (void) pthread_sigmask(SIG_BLOCK, &set, NULL); 716 } 717 718 /* 719 * signal_thread is the designated signal catcher. It wakes up the 720 * main thread whenever it receives a signal and then goes back to 721 * sleep; it does not exit. The global variables caught_* let 722 * the main thread which signal was received. 723 * 724 * The thread is created with all signals blocked. 725 */ 726 727 static void * 728 signal_thread(void *arg __unused) 729 { 730 sigset_t set; 731 int signal_caught; 732 733 DPRINT((dbfp, "the signal thread is thread %d\n", 734 pthread_self())); 735 736 (void) sigemptyset(&set); 737 (void) sigaddset(&set, SIGALRM); 738 (void) sigaddset(&set, SIGTERM); 739 (void) sigaddset(&set, SIGHUP); 740 (void) sigaddset(&set, SIGUSR1); 741 742 for (;;) { 743 signal_caught = sigwait(&set); 744 switch (signal_caught) { 745 case SIGALRM: 746 caught_alrm++; 747 DPRINT((dbfp, "caught SIGALRM\n")); 748 break; 749 case SIGTERM: 750 caught_term++; 751 DPRINT((dbfp, "caught SIGTERM\n")); 752 break; 753 case SIGHUP: 754 caught_readc++; 755 DPRINT((dbfp, "caught SIGHUP\n")); 756 break; 757 case SIGUSR1: 758 caught_nextd++; 759 DPRINT((dbfp, "caught SIGUSR1\n")); 760 break; 761 default: 762 DPRINT((dbfp, "caught unexpected signal: %d\n", 763 signal_caught)); 764 break; 765 } 766 (void) pthread_cond_signal(&(main_thr.thd_cv)); 767 } 768 return (NULL); 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 au_event_ent_t *evp; 823 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