xref: /titanic_54/usr/src/cmd/audit/audit.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate  *
4*7c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate  * with the License.
8*7c478bd9Sstevel@tonic-gate  *
9*7c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate  * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate  *
14*7c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate  *
20*7c478bd9Sstevel@tonic-gate  * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate  */
22*7c478bd9Sstevel@tonic-gate /*
23*7c478bd9Sstevel@tonic-gate  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24*7c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
25*7c478bd9Sstevel@tonic-gate  */
26*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
27*7c478bd9Sstevel@tonic-gate 
28*7c478bd9Sstevel@tonic-gate #include <fcntl.h>
29*7c478bd9Sstevel@tonic-gate #include <libscf.h>
30*7c478bd9Sstevel@tonic-gate #include <secdb.h>
31*7c478bd9Sstevel@tonic-gate #include <stdlib.h>
32*7c478bd9Sstevel@tonic-gate #include <stdio.h>
33*7c478bd9Sstevel@tonic-gate #include <string.h>
34*7c478bd9Sstevel@tonic-gate #include <sys/file.h>
35*7c478bd9Sstevel@tonic-gate #include <sys/types.h>
36*7c478bd9Sstevel@tonic-gate #include <sys/wait.h>
37*7c478bd9Sstevel@tonic-gate #include <signal.h>
38*7c478bd9Sstevel@tonic-gate #include <sys/param.h>
39*7c478bd9Sstevel@tonic-gate #include <unistd.h>
40*7c478bd9Sstevel@tonic-gate #include <bsm/audit.h>
41*7c478bd9Sstevel@tonic-gate #include <bsm/libbsm.h>
42*7c478bd9Sstevel@tonic-gate #include <locale.h>
43*7c478bd9Sstevel@tonic-gate #include <audit_sig_infc.h>
44*7c478bd9Sstevel@tonic-gate #include <zone.h>
45*7c478bd9Sstevel@tonic-gate 
46*7c478bd9Sstevel@tonic-gate #if !defined(TEXT_DOMAIN)
47*7c478bd9Sstevel@tonic-gate #define	TEXT_DOMAIN "SUNW_OST_OSCMD"
48*7c478bd9Sstevel@tonic-gate #endif
49*7c478bd9Sstevel@tonic-gate 
50*7c478bd9Sstevel@tonic-gate #define	VERIFY -1
51*7c478bd9Sstevel@tonic-gate 
52*7c478bd9Sstevel@tonic-gate /* GLOBALS */
53*7c478bd9Sstevel@tonic-gate static char	*auditdatafile = AUDITDATAFILE;
54*7c478bd9Sstevel@tonic-gate static char	*progname = "audit";
55*7c478bd9Sstevel@tonic-gate static char	*usage = "audit [-n] | [-s] | [-t] | [-v filepath]";
56*7c478bd9Sstevel@tonic-gate static int	silent = 0;
57*7c478bd9Sstevel@tonic-gate static char	*instance_name = "svc:/system/auditd:default";
58*7c478bd9Sstevel@tonic-gate 
59*7c478bd9Sstevel@tonic-gate static int	get_auditd_pid();
60*7c478bd9Sstevel@tonic-gate static void	display_smf_error();
61*7c478bd9Sstevel@tonic-gate 
62*7c478bd9Sstevel@tonic-gate static boolean_t is_audit_control_ok(char *);	/* file validation  */
63*7c478bd9Sstevel@tonic-gate static boolean_t is_valid_zone(boolean_t);	/* operation ok in this zone? */
64*7c478bd9Sstevel@tonic-gate static void	start_auditd();			/* start audit daemon */
65*7c478bd9Sstevel@tonic-gate 
66*7c478bd9Sstevel@tonic-gate /*
67*7c478bd9Sstevel@tonic-gate  * audit() - This program serves as a general administrator's interface to
68*7c478bd9Sstevel@tonic-gate  *	the audit trail.  Only one option is valid at a time.
69*7c478bd9Sstevel@tonic-gate  *
70*7c478bd9Sstevel@tonic-gate  * input:
71*7c478bd9Sstevel@tonic-gate  *	audit -s
72*7c478bd9Sstevel@tonic-gate  *		- signal audit daemon to read audit_control file and
73*7c478bd9Sstevel@tonic-gate  *		  start auditd if needed.
74*7c478bd9Sstevel@tonic-gate  *	audit -n
75*7c478bd9Sstevel@tonic-gate  *		- signal audit daemon to use next audit_control audit directory.
76*7c478bd9Sstevel@tonic-gate  *	audit -t
77*7c478bd9Sstevel@tonic-gate  *		- signal audit daemon to disable auditing.
78*7c478bd9Sstevel@tonic-gate  *	audit -T
79*7c478bd9Sstevel@tonic-gate  *		- signal audit daemon to disable auditing report no errors.
80*7c478bd9Sstevel@tonic-gate  *	audit -v filepath
81*7c478bd9Sstevel@tonic-gate  *		- validate audit_control parameters but use filepath for
82*7c478bd9Sstevel@tonic-gate  *		  the name.  Emit errors or "syntax ok"
83*7c478bd9Sstevel@tonic-gate  *
84*7c478bd9Sstevel@tonic-gate  *
85*7c478bd9Sstevel@tonic-gate  * output:
86*7c478bd9Sstevel@tonic-gate  *
87*7c478bd9Sstevel@tonic-gate  * returns:	0 - command successful
88*7c478bd9Sstevel@tonic-gate  *		>0 - command failed
89*7c478bd9Sstevel@tonic-gate  */
90*7c478bd9Sstevel@tonic-gate 
91*7c478bd9Sstevel@tonic-gate main(int argc, char *argv[])
92*7c478bd9Sstevel@tonic-gate {
93*7c478bd9Sstevel@tonic-gate 	pid_t pid; /* process id of auditd read from auditdatafile */
94*7c478bd9Sstevel@tonic-gate 	int	sig = 0; /* signal to send auditd */
95*7c478bd9Sstevel@tonic-gate 	char	c;
96*7c478bd9Sstevel@tonic-gate 	char	*first_option;
97*7c478bd9Sstevel@tonic-gate 
98*7c478bd9Sstevel@tonic-gate 	/* Internationalization */
99*7c478bd9Sstevel@tonic-gate 	(void) setlocale(LC_ALL, "");
100*7c478bd9Sstevel@tonic-gate 	(void) textdomain(TEXT_DOMAIN);
101*7c478bd9Sstevel@tonic-gate 
102*7c478bd9Sstevel@tonic-gate 	if (getuid() != 0) {
103*7c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, gettext("%s: not super-user\n"),
104*7c478bd9Sstevel@tonic-gate 			progname);
105*7c478bd9Sstevel@tonic-gate 		exit(2);
106*7c478bd9Sstevel@tonic-gate 	}
107*7c478bd9Sstevel@tonic-gate 	/* first option required */
108*7c478bd9Sstevel@tonic-gate 	if ((c = getopt(argc, argv, "nstTv:")) == -1) {
109*7c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, gettext("usage: %s\n"), usage);
110*7c478bd9Sstevel@tonic-gate 		exit(3);
111*7c478bd9Sstevel@tonic-gate 	}
112*7c478bd9Sstevel@tonic-gate 	first_option = optarg;
113*7c478bd9Sstevel@tonic-gate 	/* second or more options not allowed; please pick one */
114*7c478bd9Sstevel@tonic-gate 	if (getopt(argc, argv, "nstTv:") != -1) {
115*7c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, gettext("usage: %s\n"), usage);
116*7c478bd9Sstevel@tonic-gate 		exit(5);
117*7c478bd9Sstevel@tonic-gate 	}
118*7c478bd9Sstevel@tonic-gate 	switch (c) {
119*7c478bd9Sstevel@tonic-gate 	case 'n':
120*7c478bd9Sstevel@tonic-gate 		if (!is_valid_zone(1))	/* 1 == display error if any */
121*7c478bd9Sstevel@tonic-gate 			exit(10);
122*7c478bd9Sstevel@tonic-gate 
123*7c478bd9Sstevel@tonic-gate 		sig = AU_SIG_NEXT_DIR;
124*7c478bd9Sstevel@tonic-gate 		break;
125*7c478bd9Sstevel@tonic-gate 	case 's':
126*7c478bd9Sstevel@tonic-gate 		if (!is_valid_zone(1))	/* 1 == display error if any */
127*7c478bd9Sstevel@tonic-gate 			exit(10);
128*7c478bd9Sstevel@tonic-gate 		else if (!is_audit_control_ok(NULL))
129*7c478bd9Sstevel@tonic-gate 			exit(7);
130*7c478bd9Sstevel@tonic-gate 
131*7c478bd9Sstevel@tonic-gate 		start_auditd();
132*7c478bd9Sstevel@tonic-gate 		break;
133*7c478bd9Sstevel@tonic-gate 	case 't':
134*7c478bd9Sstevel@tonic-gate 		if (!is_valid_zone(0))	/* 0 == no error message display */
135*7c478bd9Sstevel@tonic-gate 			exit(0);
136*7c478bd9Sstevel@tonic-gate 		/* use  bmsunconv to permanently disable, -t for temporary */
137*7c478bd9Sstevel@tonic-gate 		if (smf_disable_instance(instance_name, SMF_TEMPORARY) != 0)
138*7c478bd9Sstevel@tonic-gate 			display_smf_error();
139*7c478bd9Sstevel@tonic-gate 		break;
140*7c478bd9Sstevel@tonic-gate 	case 'T':
141*7c478bd9Sstevel@tonic-gate 		if (!is_valid_zone(0))	/* 0 == no error message display */
142*7c478bd9Sstevel@tonic-gate 			exit(0);
143*7c478bd9Sstevel@tonic-gate 
144*7c478bd9Sstevel@tonic-gate 		(void) smf_disable_instance(instance_name, SMF_TEMPORARY);
145*7c478bd9Sstevel@tonic-gate 		silent = 1;
146*7c478bd9Sstevel@tonic-gate 		break;
147*7c478bd9Sstevel@tonic-gate 	case 'v':
148*7c478bd9Sstevel@tonic-gate 		if (is_audit_control_ok(first_option)) {
149*7c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr, gettext("syntax ok\n"));
150*7c478bd9Sstevel@tonic-gate 			exit(0);
151*7c478bd9Sstevel@tonic-gate 		} else {
152*7c478bd9Sstevel@tonic-gate 			exit(8);
153*7c478bd9Sstevel@tonic-gate 		}
154*7c478bd9Sstevel@tonic-gate 		break;
155*7c478bd9Sstevel@tonic-gate 	default:
156*7c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, gettext("usage: %s\n"), usage);
157*7c478bd9Sstevel@tonic-gate 		exit(6);
158*7c478bd9Sstevel@tonic-gate 	}
159*7c478bd9Sstevel@tonic-gate 
160*7c478bd9Sstevel@tonic-gate 	if (get_auditd_pid(&pid) != 0) {
161*7c478bd9Sstevel@tonic-gate 		if (silent) {
162*7c478bd9Sstevel@tonic-gate 			exit(0);
163*7c478bd9Sstevel@tonic-gate 		} else {
164*7c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr, "%s: %s\n", progname, gettext(
165*7c478bd9Sstevel@tonic-gate 			"can't get process id of auditd from audit_data(4)"));
166*7c478bd9Sstevel@tonic-gate 			exit(4);
167*7c478bd9Sstevel@tonic-gate 		}
168*7c478bd9Sstevel@tonic-gate 	}
169*7c478bd9Sstevel@tonic-gate 
170*7c478bd9Sstevel@tonic-gate 	if ((sig != 0) && (kill(pid, sig) != 0)) {
171*7c478bd9Sstevel@tonic-gate 		if (silent) {
172*7c478bd9Sstevel@tonic-gate 			exit(0);
173*7c478bd9Sstevel@tonic-gate 		} else {
174*7c478bd9Sstevel@tonic-gate 			perror(progname);
175*7c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr,
176*7c478bd9Sstevel@tonic-gate 			    gettext("%s: cannot signal auditd\n"), progname);
177*7c478bd9Sstevel@tonic-gate 			exit(1);
178*7c478bd9Sstevel@tonic-gate 		}
179*7c478bd9Sstevel@tonic-gate 	}
180*7c478bd9Sstevel@tonic-gate 	return (0);
181*7c478bd9Sstevel@tonic-gate }
182*7c478bd9Sstevel@tonic-gate 
183*7c478bd9Sstevel@tonic-gate 
184*7c478bd9Sstevel@tonic-gate /*
185*7c478bd9Sstevel@tonic-gate  * get_auditd_pid(&pid):
186*7c478bd9Sstevel@tonic-gate  *
187*7c478bd9Sstevel@tonic-gate  * reads PID from audit_data
188*7c478bd9Sstevel@tonic-gate  *
189*7c478bd9Sstevel@tonic-gate  * returns:	0 - successful
190*7c478bd9Sstevel@tonic-gate  *		1 - error
191*7c478bd9Sstevel@tonic-gate  */
192*7c478bd9Sstevel@tonic-gate 
193*7c478bd9Sstevel@tonic-gate static int
194*7c478bd9Sstevel@tonic-gate get_auditd_pid(pid_t *p_pid)
195*7c478bd9Sstevel@tonic-gate {
196*7c478bd9Sstevel@tonic-gate 	FILE	*adp;		/* audit_data file pointer */
197*7c478bd9Sstevel@tonic-gate 	int	retstat;
198*7c478bd9Sstevel@tonic-gate 
199*7c478bd9Sstevel@tonic-gate 	if ((adp = fopen(auditdatafile, "r")) == NULL) {
200*7c478bd9Sstevel@tonic-gate 		if (!silent)
201*7c478bd9Sstevel@tonic-gate 			perror(progname);
202*7c478bd9Sstevel@tonic-gate 		return (1);
203*7c478bd9Sstevel@tonic-gate 	}
204*7c478bd9Sstevel@tonic-gate 	retstat = (fscanf(adp, "%ld", p_pid) != 1);
205*7c478bd9Sstevel@tonic-gate 	(void) fclose(adp);
206*7c478bd9Sstevel@tonic-gate 	return (retstat);
207*7c478bd9Sstevel@tonic-gate }
208*7c478bd9Sstevel@tonic-gate 
209*7c478bd9Sstevel@tonic-gate /*
210*7c478bd9Sstevel@tonic-gate  * perform reasonableness check on audit_control or its standin; goal
211*7c478bd9Sstevel@tonic-gate  * is that "audit -s" (1) not crash the system and (2) c2audit/auditd
212*7c478bd9Sstevel@tonic-gate  * actually generates data.
213*7c478bd9Sstevel@tonic-gate  *
214*7c478bd9Sstevel@tonic-gate  * A NULL input is ok -- it is used to tell _openac() to use the
215*7c478bd9Sstevel@tonic-gate  * real audit_control file, not a substitute.
216*7c478bd9Sstevel@tonic-gate  */
217*7c478bd9Sstevel@tonic-gate #define	TRADITIONAL_MAX	1024
218*7c478bd9Sstevel@tonic-gate 
219*7c478bd9Sstevel@tonic-gate static boolean_t
220*7c478bd9Sstevel@tonic-gate is_audit_control_ok(char *filename) {
221*7c478bd9Sstevel@tonic-gate 	char		buf[TRADITIONAL_MAX];
222*7c478bd9Sstevel@tonic-gate 	int		outputs = 0;
223*7c478bd9Sstevel@tonic-gate 	int		state = 1;	/* 1 is ok, 0 is not */
224*7c478bd9Sstevel@tonic-gate 	int		rc;
225*7c478bd9Sstevel@tonic-gate 	int		min;
226*7c478bd9Sstevel@tonic-gate 	kva_t		*kvlist;
227*7c478bd9Sstevel@tonic-gate 	char		*value;
228*7c478bd9Sstevel@tonic-gate 	au_acinfo_t	*ach;
229*7c478bd9Sstevel@tonic-gate 
230*7c478bd9Sstevel@tonic-gate 	ach = _openac(filename);	/* open audit_control */
231*7c478bd9Sstevel@tonic-gate 	if (ach == NULL) {
232*7c478bd9Sstevel@tonic-gate 		perror(progname);
233*7c478bd9Sstevel@tonic-gate 		exit(9);
234*7c478bd9Sstevel@tonic-gate 	}
235*7c478bd9Sstevel@tonic-gate 	/*
236*7c478bd9Sstevel@tonic-gate 	 * There must be at least one directory or one plugin
237*7c478bd9Sstevel@tonic-gate 	 * defined.
238*7c478bd9Sstevel@tonic-gate 	 */
239*7c478bd9Sstevel@tonic-gate 	if ((rc = _getacdir(ach, buf, TRADITIONAL_MAX)) == 0) {
240*7c478bd9Sstevel@tonic-gate 		outputs++;
241*7c478bd9Sstevel@tonic-gate 	} else if (rc < -1) {	/* -1 is not found, others are errors */
242*7c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr,
243*7c478bd9Sstevel@tonic-gate 			gettext("%s: audit_control \"dir:\" spec invalid\n"),
244*7c478bd9Sstevel@tonic-gate 				progname);
245*7c478bd9Sstevel@tonic-gate 		state = 0;	/* is_not_ok */
246*7c478bd9Sstevel@tonic-gate 	}
247*7c478bd9Sstevel@tonic-gate 
248*7c478bd9Sstevel@tonic-gate 	/*
249*7c478bd9Sstevel@tonic-gate 	 * _getacplug -- all that is of interest is the return code.
250*7c478bd9Sstevel@tonic-gate 	 */
251*7c478bd9Sstevel@tonic-gate 	_rewindac(ach);	/* rewind audit_control */
252*7c478bd9Sstevel@tonic-gate 	if ((rc = _getacplug(ach, &kvlist)) == 0) {
253*7c478bd9Sstevel@tonic-gate 		value = kva_match(kvlist, "name");
254*7c478bd9Sstevel@tonic-gate 		if (value == NULL) {
255*7c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr, gettext("%s: audit_control "
256*7c478bd9Sstevel@tonic-gate 			    "\"plugin:\" missing name\n"), progname);
257*7c478bd9Sstevel@tonic-gate 			state = 0;	/* is_not_ok */
258*7c478bd9Sstevel@tonic-gate 		}
259*7c478bd9Sstevel@tonic-gate 		else
260*7c478bd9Sstevel@tonic-gate 			outputs++;
261*7c478bd9Sstevel@tonic-gate 
262*7c478bd9Sstevel@tonic-gate 		_kva_free(kvlist);
263*7c478bd9Sstevel@tonic-gate 	} else if (rc < -1) {
264*7c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr,
265*7c478bd9Sstevel@tonic-gate 			gettext("%s: audit_control \"plugin:\" spec invalid\n"),
266*7c478bd9Sstevel@tonic-gate 				progname);
267*7c478bd9Sstevel@tonic-gate 		state = 0;	/* is_not_ok */
268*7c478bd9Sstevel@tonic-gate 	}
269*7c478bd9Sstevel@tonic-gate 	if (outputs == 0) {
270*7c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr,
271*7c478bd9Sstevel@tonic-gate 			gettext("%s: audit_control must have either a "
272*7c478bd9Sstevel@tonic-gate 				"\"dir:\" or a \"plugin:\" specified.\n"),
273*7c478bd9Sstevel@tonic-gate 				progname);
274*7c478bd9Sstevel@tonic-gate 		state = 0;	/* is_not_ok */
275*7c478bd9Sstevel@tonic-gate 	}
276*7c478bd9Sstevel@tonic-gate 	/* minfree is not required */
277*7c478bd9Sstevel@tonic-gate 	_rewindac(ach);
278*7c478bd9Sstevel@tonic-gate 	if ((rc = _getacmin(ach, &min)) < -1) {
279*7c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr,
280*7c478bd9Sstevel@tonic-gate 			gettext(
281*7c478bd9Sstevel@tonic-gate 			    "%s: audit_control \"minfree:\" spec invalid\n"),
282*7c478bd9Sstevel@tonic-gate 			    progname);
283*7c478bd9Sstevel@tonic-gate 		state = 0;	/* is_not_ok */
284*7c478bd9Sstevel@tonic-gate 	}
285*7c478bd9Sstevel@tonic-gate 	/* flags is not required */
286*7c478bd9Sstevel@tonic-gate 	_rewindac(ach);
287*7c478bd9Sstevel@tonic-gate 	if ((rc = _getacflg(ach, buf, TRADITIONAL_MAX)) < -1) {
288*7c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr,
289*7c478bd9Sstevel@tonic-gate 			gettext("%s: audit_control \"flags:\" spec invalid\n"),
290*7c478bd9Sstevel@tonic-gate 				progname);
291*7c478bd9Sstevel@tonic-gate 		state = 0;	/* is_not_ok */
292*7c478bd9Sstevel@tonic-gate 	}
293*7c478bd9Sstevel@tonic-gate 	/* naflags is not required */
294*7c478bd9Sstevel@tonic-gate 	_rewindac(ach);
295*7c478bd9Sstevel@tonic-gate 	if ((rc = _getacna(ach, buf, TRADITIONAL_MAX)) < -1) {
296*7c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr,
297*7c478bd9Sstevel@tonic-gate 			gettext(
298*7c478bd9Sstevel@tonic-gate 			    "%s: audit_control \"naflags:\" spec invalid\n"),
299*7c478bd9Sstevel@tonic-gate 			    progname);
300*7c478bd9Sstevel@tonic-gate 		state = 0;	/* is_not_ok */
301*7c478bd9Sstevel@tonic-gate 	}
302*7c478bd9Sstevel@tonic-gate 	_endac(ach);
303*7c478bd9Sstevel@tonic-gate 	return (state);
304*7c478bd9Sstevel@tonic-gate }
305*7c478bd9Sstevel@tonic-gate 
306*7c478bd9Sstevel@tonic-gate /*
307*7c478bd9Sstevel@tonic-gate  * The operations that call this function are only valid in the global
308*7c478bd9Sstevel@tonic-gate  * zone unless the perzone audit policy is set.
309*7c478bd9Sstevel@tonic-gate  *
310*7c478bd9Sstevel@tonic-gate  * "!silent" and "show_err" are slightly different; silent is from
311*7c478bd9Sstevel@tonic-gate  * -T for which no error messages should be displayed and show_err
312*7c478bd9Sstevel@tonic-gate  * applies to more options (including -T)
313*7c478bd9Sstevel@tonic-gate  *
314*7c478bd9Sstevel@tonic-gate  */
315*7c478bd9Sstevel@tonic-gate 
316*7c478bd9Sstevel@tonic-gate static boolean_t
317*7c478bd9Sstevel@tonic-gate is_valid_zone(boolean_t show_err)
318*7c478bd9Sstevel@tonic-gate {
319*7c478bd9Sstevel@tonic-gate 	long	policy;
320*7c478bd9Sstevel@tonic-gate 
321*7c478bd9Sstevel@tonic-gate 	if (auditon(A_GETPOLICY, (char *)&policy, 0) == -1) {
322*7c478bd9Sstevel@tonic-gate 		if (!silent)
323*7c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr, gettext(
324*7c478bd9Sstevel@tonic-gate 			    "%s: Cannot read audit policy:  %s\n"),
325*7c478bd9Sstevel@tonic-gate 			    progname, strerror(errno));
326*7c478bd9Sstevel@tonic-gate 		return (0);
327*7c478bd9Sstevel@tonic-gate 	}
328*7c478bd9Sstevel@tonic-gate 	if (policy & AUDIT_PERZONE)
329*7c478bd9Sstevel@tonic-gate 		return (1);
330*7c478bd9Sstevel@tonic-gate 
331*7c478bd9Sstevel@tonic-gate 	if (getzoneid() != GLOBAL_ZONEID) {
332*7c478bd9Sstevel@tonic-gate 		if (show_err)
333*7c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr,
334*7c478bd9Sstevel@tonic-gate 			    gettext("%s: Not valid in a local zone.\n"),
335*7c478bd9Sstevel@tonic-gate 			    progname);
336*7c478bd9Sstevel@tonic-gate 		return (0);
337*7c478bd9Sstevel@tonic-gate 	} else {
338*7c478bd9Sstevel@tonic-gate 		return (1);
339*7c478bd9Sstevel@tonic-gate 	}
340*7c478bd9Sstevel@tonic-gate }
341*7c478bd9Sstevel@tonic-gate 
342*7c478bd9Sstevel@tonic-gate /*
343*7c478bd9Sstevel@tonic-gate  * if auditd isn't running, start it.  Otherwise refresh.
344*7c478bd9Sstevel@tonic-gate  * First check to see if c2audit is loaded via the auditon()
345*7c478bd9Sstevel@tonic-gate  * system call, then check SMF state.
346*7c478bd9Sstevel@tonic-gate  */
347*7c478bd9Sstevel@tonic-gate static void
348*7c478bd9Sstevel@tonic-gate start_auditd()
349*7c478bd9Sstevel@tonic-gate {
350*7c478bd9Sstevel@tonic-gate 	int	audit_state;
351*7c478bd9Sstevel@tonic-gate 	char	*state;
352*7c478bd9Sstevel@tonic-gate 
353*7c478bd9Sstevel@tonic-gate 	if (auditon(A_GETCOND, (caddr_t)&audit_state,
354*7c478bd9Sstevel@tonic-gate 	    sizeof (audit_state)) != 0)
355*7c478bd9Sstevel@tonic-gate 		return;
356*7c478bd9Sstevel@tonic-gate 
357*7c478bd9Sstevel@tonic-gate 	if ((state = smf_get_state(instance_name)) == NULL) {
358*7c478bd9Sstevel@tonic-gate 		display_smf_error();
359*7c478bd9Sstevel@tonic-gate 		return;
360*7c478bd9Sstevel@tonic-gate 	}
361*7c478bd9Sstevel@tonic-gate 	if (strcmp(SCF_STATE_STRING_ONLINE, state) != 0) {
362*7c478bd9Sstevel@tonic-gate 		if (smf_enable_instance(instance_name, 0) != 0)
363*7c478bd9Sstevel@tonic-gate 			display_smf_error();
364*7c478bd9Sstevel@tonic-gate 	} else {
365*7c478bd9Sstevel@tonic-gate 		if (smf_refresh_instance(instance_name) != 0)
366*7c478bd9Sstevel@tonic-gate 			display_smf_error();
367*7c478bd9Sstevel@tonic-gate 	}
368*7c478bd9Sstevel@tonic-gate 	free(state);
369*7c478bd9Sstevel@tonic-gate }
370*7c478bd9Sstevel@tonic-gate 
371*7c478bd9Sstevel@tonic-gate static void
372*7c478bd9Sstevel@tonic-gate display_smf_error()
373*7c478bd9Sstevel@tonic-gate {
374*7c478bd9Sstevel@tonic-gate 	int	rc = scf_error();
375*7c478bd9Sstevel@tonic-gate 
376*7c478bd9Sstevel@tonic-gate 	switch (rc) {
377*7c478bd9Sstevel@tonic-gate 	case SCF_ERROR_NOT_FOUND:
378*7c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr,
379*7c478bd9Sstevel@tonic-gate 		    "SMF error: \"%s\" not found.\n",
380*7c478bd9Sstevel@tonic-gate 		    instance_name);
381*7c478bd9Sstevel@tonic-gate 		break;
382*7c478bd9Sstevel@tonic-gate 	default:
383*7c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, "SMF error %d\n", rc);
384*7c478bd9Sstevel@tonic-gate 		break;
385*7c478bd9Sstevel@tonic-gate 	}
386*7c478bd9Sstevel@tonic-gate }
387