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(7)) 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
err_exit(char * msg)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
auditd_exit(int status)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
main(int argc,char * argv[])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(5) 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(7) 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(7) 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
my_sleep()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
isa_ified(char * path,char ** newpath)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 *
init_plugin(char * name,kva_t * list,int cnt_flag)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(7) 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
loadauditlist()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
block_signals()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 *
signal_thread(void * arg __unused)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
do_sethost(void)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(8) -conf option.
818 */
819 static void
conf_to_kernel(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
scf_to_kernel_qctrl(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
scf_to_kernel_policy(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