xref: /titanic_51/usr/src/cmd/auditd/auditd.c (revision 8c95159466b445c16660b550063d080ca9868cb5)
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 	uint32_t	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