xref: /titanic_44/usr/src/cmd/audit/audit.c (revision 6a634c9dca3093f3922e4b7ab826d7bdf17bf78e)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
56d59ee37Spaulson  * Common Development and Distribution License (the "License").
66d59ee37Spaulson  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
211b2d1c94SMarek Pospisil 
227c478bd9Sstevel@tonic-gate /*
231b2d1c94SMarek Pospisil  * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate #include <fcntl.h>
277c478bd9Sstevel@tonic-gate #include <libscf.h>
287c478bd9Sstevel@tonic-gate #include <secdb.h>
297c478bd9Sstevel@tonic-gate #include <stdlib.h>
307c478bd9Sstevel@tonic-gate #include <stdio.h>
317c478bd9Sstevel@tonic-gate #include <string.h>
327c478bd9Sstevel@tonic-gate #include <sys/file.h>
33*f8994074SJan Friedel #include <sys/stat.h>
347c478bd9Sstevel@tonic-gate #include <sys/types.h>
357c478bd9Sstevel@tonic-gate #include <sys/wait.h>
367c478bd9Sstevel@tonic-gate #include <signal.h>
377c478bd9Sstevel@tonic-gate #include <sys/param.h>
387c478bd9Sstevel@tonic-gate #include <unistd.h>
397c478bd9Sstevel@tonic-gate #include <bsm/audit.h>
407c478bd9Sstevel@tonic-gate #include <bsm/libbsm.h>
417c478bd9Sstevel@tonic-gate #include <locale.h>
427c478bd9Sstevel@tonic-gate #include <zone.h>
43*f8994074SJan Friedel #include <audit_scf.h>
447c478bd9Sstevel@tonic-gate 
457c478bd9Sstevel@tonic-gate #if !defined(TEXT_DOMAIN)
467c478bd9Sstevel@tonic-gate #define	TEXT_DOMAIN "SUNW_OST_OSCMD"
477c478bd9Sstevel@tonic-gate #endif
487c478bd9Sstevel@tonic-gate 
497c478bd9Sstevel@tonic-gate #define	VERIFY -1
507c478bd9Sstevel@tonic-gate 
517c478bd9Sstevel@tonic-gate /* GLOBALS */
527c478bd9Sstevel@tonic-gate static char	*progname = "audit";
53*f8994074SJan Friedel static char	*usage = "audit [-n] | [-s] | [-t] | [-v]";
541b2d1c94SMarek Pospisil static int	silent = 0;
557c478bd9Sstevel@tonic-gate 
567c478bd9Sstevel@tonic-gate static void	display_smf_error();
577c478bd9Sstevel@tonic-gate 
58*f8994074SJan Friedel static boolean_t is_audit_config_ok();		/* config validation  */
597c478bd9Sstevel@tonic-gate static boolean_t is_valid_zone(boolean_t);	/* operation ok in this zone? */
60*f8994074SJan Friedel static boolean_t contains_valid_dirs(char *);	/* p_dir contents validation */
61*f8994074SJan Friedel static boolean_t validate_path(char *);		/* is it path to dir? */
62*f8994074SJan Friedel static void	start_auditd();			/* start audit daemon */
634c17c04fSgww static int	sig_auditd(int);		/* send signal to auditd */
647c478bd9Sstevel@tonic-gate 
657c478bd9Sstevel@tonic-gate /*
667c478bd9Sstevel@tonic-gate  * audit() - This program serves as a general administrator's interface to
677c478bd9Sstevel@tonic-gate  *	the audit trail.  Only one option is valid at a time.
687c478bd9Sstevel@tonic-gate  *
697c478bd9Sstevel@tonic-gate  * input:
707c478bd9Sstevel@tonic-gate  *	audit -s
71*f8994074SJan Friedel  *		- signal audit daemon to read audit configuration and
727c478bd9Sstevel@tonic-gate  *		  start auditd if needed.
737c478bd9Sstevel@tonic-gate  *	audit -n
74*f8994074SJan Friedel  *		- signal audit daemon to use next audit_binfile directory.
757c478bd9Sstevel@tonic-gate  *	audit -t
761b2d1c94SMarek Pospisil  *		- signal audit daemon to disable auditing.
771b2d1c94SMarek Pospisil  *	audit -T
781b2d1c94SMarek Pospisil  *		- signal audit daemon to temporarily disable auditing reporting
791b2d1c94SMarek Pospisil  *		  no errors.
80*f8994074SJan Friedel  *	audit -v
81*f8994074SJan Friedel  *		- validate audit configuration parameters;
82*f8994074SJan Friedel  *		  Print errors or "configuration ok".
837c478bd9Sstevel@tonic-gate  *
847c478bd9Sstevel@tonic-gate  *
857c478bd9Sstevel@tonic-gate  * output:
867c478bd9Sstevel@tonic-gate  *
877c478bd9Sstevel@tonic-gate  * returns:	0 - command successful
887c478bd9Sstevel@tonic-gate  *		>0 - command failed
897c478bd9Sstevel@tonic-gate  */
907c478bd9Sstevel@tonic-gate 
917883e825Spaulson int
main(int argc,char * argv[])927c478bd9Sstevel@tonic-gate main(int argc, char *argv[])
937c478bd9Sstevel@tonic-gate {
94*f8994074SJan Friedel 	int	c;
957c478bd9Sstevel@tonic-gate 
967c478bd9Sstevel@tonic-gate 	/* Internationalization */
977c478bd9Sstevel@tonic-gate 	(void) setlocale(LC_ALL, "");
987c478bd9Sstevel@tonic-gate 	(void) textdomain(TEXT_DOMAIN);
997c478bd9Sstevel@tonic-gate 
1007c478bd9Sstevel@tonic-gate 	/* second or more options not allowed; please pick one */
101*f8994074SJan Friedel 	if (argc > 2) {
1027c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, gettext("usage: %s\n"), usage);
103*f8994074SJan Friedel 		exit(1);
1047c478bd9Sstevel@tonic-gate 	}
105*f8994074SJan Friedel 
106*f8994074SJan Friedel 	/* first option required */
107*f8994074SJan Friedel 	if ((c = getopt(argc, argv, "nstTv")) == -1) {
108*f8994074SJan Friedel 		(void) fprintf(stderr, gettext("usage: %s\n"), usage);
109*f8994074SJan Friedel 		exit(1);
110*f8994074SJan Friedel 	}
111*f8994074SJan Friedel 
1127c478bd9Sstevel@tonic-gate 	switch (c) {
1137c478bd9Sstevel@tonic-gate 	case 'n':
1147c478bd9Sstevel@tonic-gate 		if (!is_valid_zone(1))	/* 1 == display error if any */
115*f8994074SJan Friedel 			exit(1);
1167c478bd9Sstevel@tonic-gate 
117*f8994074SJan Friedel 		if (sig_auditd(SIGUSR1) != 0)
1184c17c04fSgww 			exit(1);
1197c478bd9Sstevel@tonic-gate 		break;
1207c478bd9Sstevel@tonic-gate 	case 's':
1217c478bd9Sstevel@tonic-gate 		if (!is_valid_zone(1))	/* 1 == display error if any */
122*f8994074SJan Friedel 			exit(1);
123*f8994074SJan Friedel 		else if (!is_audit_config_ok())
124*f8994074SJan Friedel 			exit(1);
1257c478bd9Sstevel@tonic-gate 
126*f8994074SJan Friedel 		start_auditd();
127*f8994074SJan Friedel 		return (0);
1287c478bd9Sstevel@tonic-gate 	case 't':
1297c478bd9Sstevel@tonic-gate 		if (!is_valid_zone(0))	/* 0 == no error message display */
130*f8994074SJan Friedel 			exit(1);
131005d3febSMarek Pospisil 		if (smf_disable_instance(AUDITD_FMRI, 0) != 0) {
1327c478bd9Sstevel@tonic-gate 			display_smf_error();
133*f8994074SJan Friedel 			exit(1);
1346d59ee37Spaulson 		}
1357c478bd9Sstevel@tonic-gate 		break;
1361b2d1c94SMarek Pospisil 	case 'T':
1371b2d1c94SMarek Pospisil 		silent = 1;
1381b2d1c94SMarek Pospisil 		if (!is_valid_zone(0))	/* 0 == no error message display */
139*f8994074SJan Friedel 			exit(1);
1401b2d1c94SMarek Pospisil 		if (smf_disable_instance(AUDITD_FMRI, SMF_TEMPORARY) != 0) {
141*f8994074SJan Friedel 			exit(1);
1421b2d1c94SMarek Pospisil 		}
1431b2d1c94SMarek Pospisil 		break;
1447c478bd9Sstevel@tonic-gate 	case 'v':
145*f8994074SJan Friedel 		if (is_audit_config_ok()) {
146*f8994074SJan Friedel 			(void) fprintf(stderr, gettext("configuration ok\n"));
1477c478bd9Sstevel@tonic-gate 			exit(0);
1487c478bd9Sstevel@tonic-gate 		} else {
149*f8994074SJan Friedel 			exit(1);
1507c478bd9Sstevel@tonic-gate 		}
1517c478bd9Sstevel@tonic-gate 		break;
1527c478bd9Sstevel@tonic-gate 	default:
1537c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, gettext("usage: %s\n"), usage);
154*f8994074SJan Friedel 		exit(1);
1557c478bd9Sstevel@tonic-gate 	}
1567c478bd9Sstevel@tonic-gate 
1577c478bd9Sstevel@tonic-gate 	return (0);
1587c478bd9Sstevel@tonic-gate }
1597c478bd9Sstevel@tonic-gate 
1607c478bd9Sstevel@tonic-gate /*
1614c17c04fSgww  * sig_auditd(sig)
1627c478bd9Sstevel@tonic-gate  *
1634c17c04fSgww  * send a signal to auditd service
1647c478bd9Sstevel@tonic-gate  *
1657c478bd9Sstevel@tonic-gate  * returns:	0 - successful
1667c478bd9Sstevel@tonic-gate  *		1 - error
1677c478bd9Sstevel@tonic-gate  */
1687c478bd9Sstevel@tonic-gate 
1697c478bd9Sstevel@tonic-gate static int
sig_auditd(int sig)1704c17c04fSgww sig_auditd(int sig)
1717c478bd9Sstevel@tonic-gate {
1724c17c04fSgww 	scf_simple_prop_t *prop = NULL;
1734c17c04fSgww 	uint64_t	*cid = NULL;
1747c478bd9Sstevel@tonic-gate 
1754c17c04fSgww 	if ((prop = scf_simple_prop_get(NULL, AUDITD_FMRI, SCF_PG_RESTARTER,
1764c17c04fSgww 	    SCF_PROPERTY_CONTRACT)) == NULL) {
1774c17c04fSgww 		display_smf_error();
1787c478bd9Sstevel@tonic-gate 		return (1);
1797c478bd9Sstevel@tonic-gate 	}
1804c17c04fSgww 	if ((scf_simple_prop_numvalues(prop) < 0) ||
1814c17c04fSgww 	    (cid = scf_simple_prop_next_count(prop)) == NULL) {
1824c17c04fSgww 		scf_simple_prop_free(prop);
1834c17c04fSgww 		display_smf_error();
1844c17c04fSgww 		return (1);
1854c17c04fSgww 	}
1864c17c04fSgww 	if (sigsend(P_CTID, (ctid_t)*cid, sig) != 0) {
1874c17c04fSgww 		perror("audit: can't signal auditd");
1884c17c04fSgww 		scf_simple_prop_free(prop);
1894c17c04fSgww 		return (1);
1904c17c04fSgww 	}
1914c17c04fSgww 	scf_simple_prop_free(prop);
1924c17c04fSgww 	return (0);
1937c478bd9Sstevel@tonic-gate }
1947c478bd9Sstevel@tonic-gate 
1957c478bd9Sstevel@tonic-gate /*
196*f8994074SJan Friedel  * perform reasonableness check on audit configuration
1977c478bd9Sstevel@tonic-gate  */
1987c478bd9Sstevel@tonic-gate 
1997c478bd9Sstevel@tonic-gate static boolean_t
is_audit_config_ok()200*f8994074SJan Friedel is_audit_config_ok() {
201*f8994074SJan Friedel 	int			state = B_TRUE;	/* B_TRUE/B_FALSE = ok/not_ok */
202*f8994074SJan Friedel 	char			*cval_str;
203*f8994074SJan Friedel 	int			cval_int;
2047c478bd9Sstevel@tonic-gate 	kva_t			*kvlist;
205*f8994074SJan Friedel 	scf_plugin_kva_node_t   *plugin_kva_ll;
206*f8994074SJan Friedel 	scf_plugin_kva_node_t   *plugin_kva_ll_head;
207*f8994074SJan Friedel 	boolean_t		one_plugin_enabled = B_FALSE;
2087c478bd9Sstevel@tonic-gate 
2097c478bd9Sstevel@tonic-gate 	/*
210*f8994074SJan Friedel 	 * There must be at least one active plugin configured; if the
211*f8994074SJan Friedel 	 * configured plugin is audit_binfile(5), then the p_dir must not be
212*f8994074SJan Friedel 	 * empty.
2137c478bd9Sstevel@tonic-gate 	 */
214*f8994074SJan Friedel 	if (!do_getpluginconfig_scf(NULL, &plugin_kva_ll)) {
2151a578a15Spaulson 		(void) fprintf(stderr,
216*f8994074SJan Friedel 		    gettext("Could not get plugin configuration.\n"));
217*f8994074SJan Friedel 		exit(1);
218*f8994074SJan Friedel 	}
219*f8994074SJan Friedel 
220*f8994074SJan Friedel 	plugin_kva_ll_head = plugin_kva_ll;
221*f8994074SJan Friedel 
222*f8994074SJan Friedel 	while (plugin_kva_ll != NULL) {
223*f8994074SJan Friedel 		kvlist = plugin_kva_ll->plugin_kva;
224*f8994074SJan Friedel 
225*f8994074SJan Friedel 		if (!one_plugin_enabled) {
226*f8994074SJan Friedel 			cval_str = kva_match(kvlist, "active");
227*f8994074SJan Friedel 			if (atoi(cval_str) == 1) {
228*f8994074SJan Friedel 				one_plugin_enabled = B_TRUE;
2291a578a15Spaulson 			}
2301a578a15Spaulson 		}
231*f8994074SJan Friedel 
232*f8994074SJan Friedel 		if (strcmp((char *)&(*plugin_kva_ll).plugin_name,
233*f8994074SJan Friedel 		    "audit_binfile") == 0) {
234*f8994074SJan Friedel 			cval_str = kva_match(kvlist, "p_dir");
235*f8994074SJan Friedel 			if (*cval_str == '\0' || cval_str == NULL) {
2367c478bd9Sstevel@tonic-gate 				(void) fprintf(stderr,
237*f8994074SJan Friedel 				    gettext("%s: audit_binfile(5) \"p_dir:\" "
238*f8994074SJan Friedel 				    "attribute empty\n"), progname);
239*f8994074SJan Friedel 				state = B_FALSE;
240*f8994074SJan Friedel 			} else if (!contains_valid_dirs(cval_str)) {
2417c478bd9Sstevel@tonic-gate 				(void) fprintf(stderr,
242*f8994074SJan Friedel 				    gettext("%s: audit_binfile(5) \"p_dir:\" "
243*f8994074SJan Friedel 				    "attribute invalid\n"), progname);
244*f8994074SJan Friedel 				state = B_FALSE;
2457c478bd9Sstevel@tonic-gate 			}
246*f8994074SJan Friedel 
247*f8994074SJan Friedel 			cval_str = kva_match(kvlist, "p_minfree");
248*f8994074SJan Friedel 			cval_int = atoi(cval_str);
249*f8994074SJan Friedel 			if (cval_int < 0 || cval_int > 100) {
2507c478bd9Sstevel@tonic-gate 				(void) fprintf(stderr,
251*f8994074SJan Friedel 				    gettext("%s: audit_binfile(5) "
252*f8994074SJan Friedel 				    "\"p_minfree:\" attribute invalid\n"),
2537c478bd9Sstevel@tonic-gate 				    progname);
254*f8994074SJan Friedel 				state = B_FALSE;
2557c478bd9Sstevel@tonic-gate 			}
256*f8994074SJan Friedel 		}
257*f8994074SJan Friedel 
258*f8994074SJan Friedel 		plugin_kva_ll = plugin_kva_ll->next;
259*f8994074SJan Friedel 	}
260*f8994074SJan Friedel 
261*f8994074SJan Friedel 	plugin_kva_ll_free(plugin_kva_ll_head);
262*f8994074SJan Friedel 
263*f8994074SJan Friedel 	if (!one_plugin_enabled) {
264*f8994074SJan Friedel 		(void) fprintf(stderr, gettext("%s: no active plugin found\n"),
2657c478bd9Sstevel@tonic-gate 		    progname);
266*f8994074SJan Friedel 		state = B_FALSE;
2677c478bd9Sstevel@tonic-gate 	}
268*f8994074SJan Friedel 
2697c478bd9Sstevel@tonic-gate 	return (state);
2707c478bd9Sstevel@tonic-gate }
2717c478bd9Sstevel@tonic-gate 
2727c478bd9Sstevel@tonic-gate /*
2737c478bd9Sstevel@tonic-gate  * The operations that call this function are only valid in the global
2747c478bd9Sstevel@tonic-gate  * zone unless the perzone audit policy is set.
2751b2d1c94SMarek Pospisil  *
2761b2d1c94SMarek Pospisil  * "!silent" and "show_err" are slightly different; silent is from
2771b2d1c94SMarek Pospisil  * -T for which no error messages should be displayed and show_err
2781b2d1c94SMarek Pospisil  * applies to more options (including -T)
2791b2d1c94SMarek Pospisil  *
2807c478bd9Sstevel@tonic-gate  */
2817c478bd9Sstevel@tonic-gate 
2827c478bd9Sstevel@tonic-gate static boolean_t
is_valid_zone(boolean_t show_err)2837c478bd9Sstevel@tonic-gate is_valid_zone(boolean_t show_err)
2847c478bd9Sstevel@tonic-gate {
28596093503SMarek Pospisil 	uint32_t	policy;
2867c478bd9Sstevel@tonic-gate 
2877c478bd9Sstevel@tonic-gate 	if (auditon(A_GETPOLICY, (char *)&policy, 0) == -1) {
2881b2d1c94SMarek Pospisil 		if (!silent) {
2897c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr, gettext(
2907c478bd9Sstevel@tonic-gate 			    "%s: Cannot read audit policy:  %s\n"),
2917c478bd9Sstevel@tonic-gate 			    progname, strerror(errno));
2921b2d1c94SMarek Pospisil 		}
2937c478bd9Sstevel@tonic-gate 		return (0);
2947c478bd9Sstevel@tonic-gate 	}
2957c478bd9Sstevel@tonic-gate 	if (policy & AUDIT_PERZONE)
2967c478bd9Sstevel@tonic-gate 		return (1);
2977c478bd9Sstevel@tonic-gate 
2987c478bd9Sstevel@tonic-gate 	if (getzoneid() != GLOBAL_ZONEID) {
2997c478bd9Sstevel@tonic-gate 		if (show_err)
3007c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr,
3017c478bd9Sstevel@tonic-gate 			    gettext("%s: Not valid in a local zone.\n"),
3027c478bd9Sstevel@tonic-gate 			    progname);
3037c478bd9Sstevel@tonic-gate 		return (0);
3047c478bd9Sstevel@tonic-gate 	} else {
3057c478bd9Sstevel@tonic-gate 		return (1);
3067c478bd9Sstevel@tonic-gate 	}
3077c478bd9Sstevel@tonic-gate }
3087c478bd9Sstevel@tonic-gate 
3097c478bd9Sstevel@tonic-gate /*
310*f8994074SJan Friedel  * Verify, whether the dirs_str contains at least one currently valid path to
311*f8994074SJan Friedel  * the directory. All invalid paths are reported. In case no valid directory
312*f8994074SJan Friedel  * path is found function returns B_FALSE, otherwise B_TRUE.
313*f8994074SJan Friedel  */
314*f8994074SJan Friedel 
315*f8994074SJan Friedel static boolean_t
contains_valid_dirs(char * dirs_str)316*f8994074SJan Friedel contains_valid_dirs(char *dirs_str)
317*f8994074SJan Friedel {
318*f8994074SJan Friedel 	boolean_t	rc = B_FALSE;
319*f8994074SJan Friedel 	boolean_t	rc_validate_path = B_TRUE;
320*f8994074SJan Friedel 	char		*tok_ptr;
321*f8994074SJan Friedel 	char		*tok_lasts;
322*f8994074SJan Friedel 
323*f8994074SJan Friedel 	if (dirs_str == NULL) {
324*f8994074SJan Friedel 		return (rc);
325*f8994074SJan Friedel 	}
326*f8994074SJan Friedel 
327*f8994074SJan Friedel 	if ((tok_ptr = strtok_r(dirs_str, ",", &tok_lasts)) != NULL) {
328*f8994074SJan Friedel 		if (validate_path(tok_ptr)) {
329*f8994074SJan Friedel 			rc = B_TRUE;
330*f8994074SJan Friedel 		} else {
331*f8994074SJan Friedel 			rc_validate_path = B_FALSE;
332*f8994074SJan Friedel 		}
333*f8994074SJan Friedel 		while ((tok_ptr = strtok_r(NULL, ",", &tok_lasts)) != NULL) {
334*f8994074SJan Friedel 			if (validate_path(tok_ptr)) {
335*f8994074SJan Friedel 				rc = B_TRUE;
336*f8994074SJan Friedel 			} else {
337*f8994074SJan Friedel 				rc_validate_path = B_FALSE;
338*f8994074SJan Friedel 			}
339*f8994074SJan Friedel 		}
340*f8994074SJan Friedel 	}
341*f8994074SJan Friedel 
342*f8994074SJan Friedel 	if (rc && !rc_validate_path) {
343*f8994074SJan Friedel 		(void) fprintf(stderr, gettext("%s: at least one valid "
344*f8994074SJan Friedel 		    "directory path found\n"), progname);
345*f8994074SJan Friedel 	}
346*f8994074SJan Friedel 
347*f8994074SJan Friedel 	return (rc);
348*f8994074SJan Friedel }
349*f8994074SJan Friedel 
350*f8994074SJan Friedel /*
351*f8994074SJan Friedel  * Verify, that the dir_path is path to a directory.
352*f8994074SJan Friedel  */
353*f8994074SJan Friedel 
354*f8994074SJan Friedel static boolean_t
validate_path(char * dir_path)355*f8994074SJan Friedel validate_path(char *dir_path)
356*f8994074SJan Friedel {
357*f8994074SJan Friedel 	boolean_t	rc = B_FALSE;
358*f8994074SJan Friedel 	struct stat	statbuf;
359*f8994074SJan Friedel 
360*f8994074SJan Friedel 	if (dir_path == NULL) {
361*f8994074SJan Friedel 		return (rc);
362*f8994074SJan Friedel 	}
363*f8994074SJan Friedel 
364*f8994074SJan Friedel 	if (stat(dir_path, &statbuf) == -1) {
365*f8994074SJan Friedel 		(void) fprintf(stderr, gettext("%s: %s error: %s\n"), progname,
366*f8994074SJan Friedel 		    dir_path, strerror(errno));
367*f8994074SJan Friedel 	} else if (statbuf.st_mode & S_IFDIR) {
368*f8994074SJan Friedel 			rc = B_TRUE;
369*f8994074SJan Friedel 	} else {
370*f8994074SJan Friedel 		(void) fprintf(stderr, gettext("%s: %s is not a directory\n"),
371*f8994074SJan Friedel 		    progname, dir_path);
372*f8994074SJan Friedel 	}
373*f8994074SJan Friedel 
374*f8994074SJan Friedel 	return (rc);
375*f8994074SJan Friedel }
376*f8994074SJan Friedel 
377*f8994074SJan Friedel /*
3787c478bd9Sstevel@tonic-gate  * if auditd isn't running, start it.  Otherwise refresh.
3797c478bd9Sstevel@tonic-gate  * First check to see if c2audit is loaded via the auditon()
3807c478bd9Sstevel@tonic-gate  * system call, then check SMF state.
3817c478bd9Sstevel@tonic-gate  */
382*f8994074SJan Friedel static void
start_auditd()3837c478bd9Sstevel@tonic-gate start_auditd()
3847c478bd9Sstevel@tonic-gate {
3857c478bd9Sstevel@tonic-gate 	int	audit_state;
3867c478bd9Sstevel@tonic-gate 	char	*state;
3877c478bd9Sstevel@tonic-gate 
3887c478bd9Sstevel@tonic-gate 	if (auditon(A_GETCOND, (caddr_t)&audit_state,
3897c478bd9Sstevel@tonic-gate 	    sizeof (audit_state)) != 0)
390*f8994074SJan Friedel 		exit(1);
3917c478bd9Sstevel@tonic-gate 
3924c17c04fSgww 	if ((state = smf_get_state(AUDITD_FMRI)) == NULL) {
3937c478bd9Sstevel@tonic-gate 		display_smf_error();
394*f8994074SJan Friedel 		exit(1);
3957c478bd9Sstevel@tonic-gate 	}
3967c478bd9Sstevel@tonic-gate 	if (strcmp(SCF_STATE_STRING_ONLINE, state) != 0) {
3974c17c04fSgww 		if (smf_enable_instance(AUDITD_FMRI, 0) != 0) {
3987c478bd9Sstevel@tonic-gate 			display_smf_error();
3996d59ee37Spaulson 			free(state);
400*f8994074SJan Friedel 			exit(1);
4016d59ee37Spaulson 		}
4027c478bd9Sstevel@tonic-gate 	} else {
4034c17c04fSgww 		if (smf_refresh_instance(AUDITD_FMRI) != 0) {
4047c478bd9Sstevel@tonic-gate 			display_smf_error();
4056d59ee37Spaulson 			free(state);
406*f8994074SJan Friedel 			exit(1);
4076d59ee37Spaulson 		}
4087c478bd9Sstevel@tonic-gate 	}
4097c478bd9Sstevel@tonic-gate 	free(state);
4107c478bd9Sstevel@tonic-gate }
4117c478bd9Sstevel@tonic-gate 
4127c478bd9Sstevel@tonic-gate static void
display_smf_error()4137c478bd9Sstevel@tonic-gate display_smf_error()
4147c478bd9Sstevel@tonic-gate {
4154c17c04fSgww 	scf_error_t	rc = scf_error();
4167c478bd9Sstevel@tonic-gate 
4177c478bd9Sstevel@tonic-gate 	switch (rc) {
4187c478bd9Sstevel@tonic-gate 	case SCF_ERROR_NOT_FOUND:
4197c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr,
4207c478bd9Sstevel@tonic-gate 		    "SMF error: \"%s\" not found.\n",
4214c17c04fSgww 		    AUDITD_FMRI);
4227c478bd9Sstevel@tonic-gate 		break;
4237c478bd9Sstevel@tonic-gate 	default:
4246d59ee37Spaulson 		(void) fprintf(stderr, "SMF error: %s\n", scf_strerror(rc));
4257c478bd9Sstevel@tonic-gate 		break;
4267c478bd9Sstevel@tonic-gate 	}
4277c478bd9Sstevel@tonic-gate }
428