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