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 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 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 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 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 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 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 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 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