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