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.
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.
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]
22 * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
25 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
26 /* All Rights Reserved */
39 #include <libscf_priv.h>
43 #include <bsm/adt_event.h>
45 #include <sys/types.h>
46 #include <sys/uadmin.h>
49 #define SMF_RST "/etc/svc/volatile/resetting"
50 #define RETRY_COUNT 15 /* number of 1 sec retries for audit(1M) to complete */
52 static const char *Usage
= "Usage: %s cmd fcn [mdep]\n";
54 static int closeout_audit(int, int);
55 static int turnoff_auditd(void);
56 static void wait_for_auqueue();
57 static int change_audit_file(void);
60 main(int argc
, char *argv
[])
63 uintptr_t mdep
= NULL
;
65 adt_session_data_t
*ah
; /* audit session handle */
66 adt_event_data_t
*event
= NULL
; /* event to be generated */
68 enum adt_uadmin_fcn fcn_id
;
70 if (argc
< 3 || argc
> 4) {
71 (void) fprintf(stderr
, Usage
, argv
[0]);
75 (void) sigfillset(&set
);
76 (void) sigprocmask(SIG_BLOCK
, &set
, NULL
);
80 if (argc
== 4) { /* mdep argument given */
81 if (cmd
!= A_REBOOT
&& cmd
!= A_SHUTDOWN
&& cmd
!= A_DUMP
&&
83 (void) fprintf(stderr
, "%s: mdep argument not "
84 "allowed for this cmd value\n", argv
[0]);
85 (void) fprintf(stderr
, Usage
, argv
[0]);
88 mdep
= (uintptr_t)argv
[3];
92 /* set up audit session and event */
93 if (adt_start_session(&ah
, NULL
, ADT_USE_PROC_DATA
) != 0) {
94 (void) fprintf(stderr
, "%s: can't start audit session\n",
99 event_id
= ADT_uadmin_shutdown
;
102 event_id
= ADT_uadmin_reboot
;
105 event_id
= ADT_uadmin_dump
;
108 event_id
= ADT_uadmin_remount
;
111 event_id
= ADT_uadmin_freeze
;
114 event_id
= ADT_uadmin_ftrace
;
117 event_id
= ADT_uadmin_config
;
120 event_id
= ADT_uadmin_swapctl
;
125 if ((event_id
!= 0) &&
126 (event
= adt_alloc_event(ah
, event_id
)) == NULL
) {
127 (void) fprintf(stderr
, "%s: can't allocate audit event\n",
132 fcn_id
= ADT_UADMIN_FCN_AD_HALT
;
135 fcn_id
= ADT_UADMIN_FCN_AD_POWEROFF
;
138 fcn_id
= ADT_UADMIN_FCN_AD_BOOT
;
141 fcn_id
= ADT_UADMIN_FCN_AD_IBOOT
;
144 fcn_id
= ADT_UADMIN_FCN_AD_SBOOT
;
147 fcn_id
= ADT_UADMIN_FCN_AD_SIBOOT
;
150 fcn_id
= ADT_UADMIN_FCN_AD_NOSYNC
;
154 fcn_id
= ADT_UADMIN_FCN_AD_FASTREBOOT
;
155 mdep
= NULL
; /* Ignore all arguments */
158 fcn_id
= ADT_UADMIN_FCN_AD_BOOT
;
161 case AD_FASTREBOOT_DRYRUN
:
162 fcn_id
= ADT_UADMIN_FCN_AD_FASTREBOOT_DRYRUN
;
163 mdep
= NULL
; /* Ignore all arguments */
168 if (cmd
== A_FREEZE
) {
170 case AD_SUSPEND_TO_DISK
:
171 fcn_id
= ADT_UADMIN_FCN_AD_SUSPEND_TO_DISK
;
173 case AD_CHECK_SUSPEND_TO_DISK
:
174 fcn_id
= ADT_UADMIN_FCN_AD_CHECK_SUSPEND_TO_DISK
;
177 fcn_id
= ADT_UADMIN_FCN_AD_FORCE
;
179 case AD_SUSPEND_TO_RAM
:
180 fcn_id
= ADT_UADMIN_FCN_AD_SUSPEND_TO_RAM
;
182 case AD_CHECK_SUSPEND_TO_RAM
:
183 fcn_id
= ADT_UADMIN_FCN_AD_CHECK_SUSPEND_TO_RAM
;
186 fcn_id
= ADT_UADMIN_FCN_AD_REUSEINIT
;
189 fcn_id
= ADT_UADMIN_FCN_AD_REUSABLE
;
192 fcn_id
= ADT_UADMIN_FCN_AD_REUSEFINI
;
195 } else if (cmd
== A_FTRACE
) {
197 case AD_FTRACE_START
:
198 fcn_id
= ADT_UADMIN_FCN_AD_FTRACE_START
;
201 fcn_id
= ADT_UADMIN_FCN_AD_FTRACE_STOP
;
205 } else if (cmd
== A_CONFIG
) {
206 uint8_t boot_config
= 0;
207 uint8_t boot_config_ovr
= 0;
210 case AD_UPDATE_BOOT_CONFIG
:
211 fcn_id
= ADT_UADMIN_FCN_AD_UPDATE_BOOT_CONFIG
;
212 scf_get_boot_config(&boot_config
);
213 boot_config_ovr
= boot_config
;
214 scf_get_boot_config_ovr(&boot_config_ovr
);
215 boot_config
&= boot_config_ovr
;
216 mdep
= (uintptr_t)(&boot_config
);
222 if (geteuid() == 0) {
226 event
->adt_uadmin_shutdown
.fcn
= fcn_id
;
227 event
->adt_uadmin_shutdown
.mdep
= (char *)mdep
;
230 event
->adt_uadmin_reboot
.fcn
= fcn_id
;
231 event
->adt_uadmin_reboot
.mdep
= (char *)mdep
;
234 event
->adt_uadmin_dump
.fcn
= fcn_id
;
235 event
->adt_uadmin_dump
.mdep
= (char *)mdep
;
241 event
->adt_uadmin_freeze
.fcn
= fcn_id
;
242 event
->adt_uadmin_freeze
.mdep
= (char *)mdep
;
245 event
->adt_uadmin_ftrace
.fcn
= fcn_id
;
246 event
->adt_uadmin_ftrace
.mdep
= (char *)mdep
;
249 event
->adt_uadmin_config
.fcn
= fcn_id
;
250 event
->adt_uadmin_config
.mdep
= (char *)mdep
;
253 event
->adt_uadmin_swapctl
.fcn
= fcn_id
;
257 if (adt_put_event(event
, ADT_SUCCESS
, 0) != 0) {
258 (void) fprintf(stderr
,
259 "%s: can't put audit event\n", argv
[0]);
262 * allow audit record to be processed in the kernel
268 if (closeout_audit(cmd
, fcn
) == -1)
269 (void) fprintf(stderr
, "%s: can't turn off auditd\n",
272 if (cmd
== A_SHUTDOWN
|| cmd
== A_REBOOT
)
273 (void) creat(SMF_RST
, 0777);
276 (void) adt_free_event(event
);
277 if (uadmin(cmd
, fcn
, mdep
) < 0) {
280 (void) unlink(SMF_RST
);
285 /* If returning from a suspend, audit thaw */
286 if ((cmd
== A_FREEZE
) &&
287 ((fcn
== AD_FORCE
) ||
288 (fcn
== AD_REUSABLE
) ||
289 (fcn
== AD_SUSPEND_TO_DISK
) ||
290 (fcn
== AD_SUSPEND_TO_RAM
))) {
291 if ((event
= adt_alloc_event(ah
, ADT_uadmin_thaw
)) == NULL
) {
292 (void) fprintf(stderr
, "%s: can't allocate thaw audit "
295 event
->adt_uadmin_thaw
.fcn
= fcn_id
;
296 if (adt_put_event(event
, ADT_SUCCESS
, 0) != 0) {
297 (void) fprintf(stderr
, "%s: can't put thaw audit "
300 (void) adt_free_event(event
);
302 (void) adt_end_session(ah
);
308 closeout_audit(int cmd
, int fcn
)
310 if (!adt_audit_state(AUC_AUDITING
)) {
311 /* auditd not running, just return */
317 case AD_FASTREBOOT_DRYRUN
:
318 /* No system discontinuity, don't turn off auditd */
321 break; /* For all the other shutdown functions */
326 /* system shutting down, turn off auditd */
327 return (turnoff_auditd());
332 /* No system discontinuity, don't turn off auditd */
336 case AD_CHECK_SUSPEND_TO_DISK
: /* AD_CHECK */
337 case AD_CHECK_SUSPEND_TO_RAM
:
340 /* No system discontinuity, don't turn off auditd */
343 case AD_SUSPEND_TO_DISK
: /* AD_COMPRESS */
344 case AD_SUSPEND_TO_RAM
:
346 /* suspend the system, change audit files */
347 return (change_audit_file());
349 return (0); /* not an audit error */
352 return (0); /* not an audit error */
360 int retries
= RETRY_COUNT
;
362 if ((rc
= (int)fork()) == 0) {
363 (void) execl("/usr/sbin/audit", "audit", "-T", NULL
);
364 (void) fprintf(stderr
, "error disabling auditd: %s\n",
367 } else if (rc
== -1) {
368 (void) fprintf(stderr
, "error disabling auditd: %s\n",
374 * wait for auditd to finish its work. auditd will change the
375 * auditstart from AUC_AUDITING (auditd up and running) to
376 * AUC_NOAUDIT. Other states are errors, so we're done as well.
382 if ((auditon(A_GETCOND
, (caddr_t
)&auditstate
,
383 sizeof (auditstate
)) == 0) &&
384 (auditstate
== AUC_AUDITING
)) {
390 } while ((rc
!= 0) && (retries
!= 0));
396 change_audit_file(void)
400 if ((pid
= fork()) == 0) {
401 (void) execl("/usr/sbin/audit", "audit", "-n", NULL
);
402 (void) fprintf(stderr
, "error changing audit files: %s\n",
405 } else if (pid
== -1) {
406 (void) fprintf(stderr
, "error changing audit files: %s\n",
411 int retries
= RETRY_COUNT
;
414 * Wait for audit(1M) -n process to complete
418 if ((rc
= waitpid(pid
, NULL
, WNOHANG
)) == pid
) {
420 } else if (rc
== -1) {
427 } while (retries
!= 0);
438 while (retries
-- && auditon(A_GETSTAT
, (caddr_t
)&au_stat
, NULL
) == 0) {
439 if (au_stat
.as_enqueue
== au_stat
.as_written
) {