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 (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
  23  */
  24 
  25 /*
  26  * auditconfig - set and display audit parameters
  27  */
  28 
  29 #include <locale.h>
  30 #include <sys/types.h>
  31 #include <ctype.h>
  32 #include <stdlib.h>
  33 #include <stdarg.h>
  34 #include <unistd.h>
  35 #include <errno.h>
  36 #include <sys/param.h>
  37 #include <stdio.h>
  38 #include <string.h>
  39 #include <strings.h>
  40 #include <nlist.h>
  41 #include <fcntl.h>
  42 #include <sys/socket.h>
  43 #include <netdb.h>
  44 #include <netinet/in.h>
  45 #include <arpa/inet.h>
  46 #include <sys/mkdev.h>
  47 #include <sys/param.h>
  48 #include <pwd.h>
  49 #include <libintl.h>
  50 #include <zone.h>
  51 #include <libscf_priv.h>
  52 #include <tsol/label.h>
  53 #include <bsm/libbsm.h>
  54 #include <audit_policy.h>
  55 #include <audit_scf.h>
  56 
  57 enum    commands {
  58         AC_ARG_ACONF,
  59         AC_ARG_AUDIT,
  60         AC_ARG_CHKACONF,
  61         AC_ARG_CHKCONF,
  62         AC_ARG_CONF,
  63         AC_ARG_GETASID,
  64         AC_ARG_GETAUDIT,
  65         AC_ARG_GETAUID,
  66         AC_ARG_GETCAR,
  67         AC_ARG_GETCLASS,
  68         AC_ARG_GETCOND,
  69         AC_ARG_GETCWD,
  70         AC_ARG_GETESTATE,
  71         AC_ARG_GETFLAGS,
  72         AC_ARG_GETKAUDIT,
  73         AC_ARG_GETKMASK,
  74         AC_ARG_GETNAFLAGS,
  75         AC_ARG_GETPINFO,
  76         AC_ARG_GETPLUGIN,
  77         AC_ARG_GETPOLICY,
  78         AC_ARG_GETQBUFSZ,
  79         AC_ARG_GETQCTRL,
  80         AC_ARG_GETQDELAY,
  81         AC_ARG_GETQHIWATER,
  82         AC_ARG_GETQLOWATER,
  83         AC_ARG_GETSTAT,
  84         AC_ARG_GETTERMID,
  85         AC_ARG_LSEVENT,
  86         AC_ARG_LSPOLICY,
  87         AC_ARG_SETASID,
  88         AC_ARG_SETAUDIT,
  89         AC_ARG_SETAUID,
  90         AC_ARG_SETCLASS,
  91         AC_ARG_SETFLAGS,
  92         AC_ARG_SETKAUDIT,
  93         AC_ARG_SETKMASK,
  94         AC_ARG_SETNAFLAGS,
  95         AC_ARG_SETPLUGIN,
  96         AC_ARG_SETPMASK,
  97         AC_ARG_SETPOLICY,
  98         AC_ARG_SETQBUFSZ,
  99         AC_ARG_SETQCTRL,
 100         AC_ARG_SETQDELAY,
 101         AC_ARG_SETQHIWATER,
 102         AC_ARG_SETQLOWATER,
 103         AC_ARG_SETSMASK,
 104         AC_ARG_SETSTAT,
 105         AC_ARG_SETUMASK,
 106         AC_ARG_SET_TEMPORARY
 107 };
 108 
 109 #define AC_KERN_EVENT           0
 110 #define AC_USER_EVENT           1
 111 
 112 #define NONE(s) (!strlen(s) ? gettext("none") : s)
 113 
 114 #define ONEK 1024
 115 
 116 /*
 117  * remove this after the audit.h is fixed
 118  */
 119 struct arg_entry {
 120         char            *arg_str;
 121         char            *arg_opts;
 122         enum commands   auditconfig_cmd;
 123         boolean_t       temporary_allowed;      /* -t allowed for the option */
 124 };
 125 typedef struct arg_entry arg_entry_t;
 126 
 127 /* arg_table - command option and usage message table */
 128 static arg_entry_t arg_table[] = {
 129         { "-aconf",     "",                     AC_ARG_ACONF,   B_FALSE},
 130         { "-audit",     " event sorf retval string", AC_ARG_AUDIT, B_FALSE},
 131         { "-chkaconf",  "",                     AC_ARG_CHKACONF, B_FALSE},
 132         { "-chkconf",   "",                     AC_ARG_CHKCONF, B_FALSE},
 133         { "-conf",      "",                     AC_ARG_CONF,    B_FALSE},
 134         { "-getasid",   "",                     AC_ARG_GETASID, B_FALSE},
 135         { "-getaudit",  "",                     AC_ARG_GETAUDIT, B_FALSE},
 136         { "-getauid",   "",                     AC_ARG_GETAUID, B_FALSE},
 137         { "-getcar",    "",                     AC_ARG_GETCAR,  B_FALSE},
 138         { "-getclass",  " event",               AC_ARG_GETCLASS, B_FALSE},
 139         { "-getcond",   "",                     AC_ARG_GETCOND, B_FALSE},
 140         { "-getcwd",    "",                     AC_ARG_GETCWD,  B_FALSE},
 141         { "-getestate", " event",               AC_ARG_GETESTATE, B_FALSE},
 142         { "-getflags",  "",                     AC_ARG_GETFLAGS, B_FALSE},
 143         { "-getkaudit", "",                     AC_ARG_GETKAUDIT, B_FALSE},
 144         { "-getkmask",  "",                     AC_ARG_GETKMASK, B_FALSE},
 145         { "-getnaflags", "",                    AC_ARG_GETNAFLAGS, B_FALSE},
 146         { "-getpinfo",  " pid",                 AC_ARG_GETPINFO, B_FALSE},
 147         { "-getplugin", " [plugin]",            AC_ARG_GETPLUGIN, B_FALSE},
 148         { "-getpolicy", "",                     AC_ARG_GETPOLICY, B_TRUE},
 149         { "-getqbufsz", "",                     AC_ARG_GETQBUFSZ, B_TRUE},
 150         { "-getqctrl",  "",                     AC_ARG_GETQCTRL, B_TRUE},
 151         { "-getqdelay", "",                     AC_ARG_GETQDELAY, B_TRUE},
 152         { "-getqhiwater", "",                   AC_ARG_GETQHIWATER, B_TRUE},
 153         { "-getqlowater", "",                   AC_ARG_GETQLOWATER, B_TRUE},
 154         { "-getstat",   "",                     AC_ARG_GETSTAT, B_FALSE},
 155         { "-gettid",    "",                     AC_ARG_GETTERMID, B_FALSE},
 156         { "-lsevent",   "",                     AC_ARG_LSEVENT, B_FALSE},
 157         { "-lspolicy",  "",                     AC_ARG_LSPOLICY, B_FALSE},
 158         { "-setasid",   " asid [cmd]",          AC_ARG_SETASID, B_FALSE},
 159         { "-setaudit",  " auid audit_flags termid asid [cmd]",
 160                                                 AC_ARG_SETAUDIT, B_FALSE},
 161         { "-setauid",   " auid [cmd]",          AC_ARG_SETAUID, B_FALSE},
 162         { "-setclass",  " event audit_flags",   AC_ARG_SETCLASS, B_FALSE},
 163         { "-setflags",  " audit_flags",         AC_ARG_SETFLAGS, B_FALSE},
 164         { "-setkaudit", " type IP_address",     AC_ARG_SETKAUDIT, B_FALSE},
 165         { "-setkmask",  " audit_flags",         AC_ARG_SETKMASK, B_FALSE},
 166         { "-setnaflags", " audit_naflags",      AC_ARG_SETNAFLAGS, B_FALSE},
 167         { "-setplugin", " name active|inactive [attributes [qsize]]",
 168                                                 AC_ARG_SETPLUGIN, B_FALSE},
 169         { "-setpmask",  " pid audit_flags",     AC_ARG_SETPMASK, B_FALSE},
 170         { "-setpolicy", " [+|-]policy_flags",   AC_ARG_SETPOLICY, B_TRUE},
 171         { "-setqbufsz", " bufsz",               AC_ARG_SETQBUFSZ, B_TRUE},
 172         { "-setqctrl",  " hiwater lowater bufsz delay",
 173                                                 AC_ARG_SETQCTRL, B_TRUE},
 174         { "-setqdelay", " delay",               AC_ARG_SETQDELAY, B_TRUE},
 175         { "-setqhiwater", " hiwater",           AC_ARG_SETQHIWATER, B_TRUE},
 176         { "-setqlowater", " lowater",           AC_ARG_SETQLOWATER, B_TRUE},
 177         { "-setsmask",  " asid audit_flags",    AC_ARG_SETSMASK, B_FALSE},
 178         { "-setstat",   "",                     AC_ARG_SETSTAT, B_FALSE},
 179         { "-setumask",  " user audit_flags",    AC_ARG_SETUMASK, B_FALSE},
 180         { "-t",         "",                     AC_ARG_SET_TEMPORARY, B_FALSE},
 181 };
 182 
 183 #define ARG_TBL_SZ (sizeof (arg_table) / sizeof (arg_entry_t))
 184 
 185 char    *progname = "auditconfig";
 186 
 187 /*
 188  * temporary_set true to get/set only kernel settings,
 189  *               false to get/set kernel settings and service properties
 190  */
 191 static boolean_t temporary_set = B_FALSE;
 192 
 193 static au_event_ent_t *egetauevnam(char *event_name);
 194 static au_event_ent_t *egetauevnum(au_event_t event_number);
 195 static int arg_ent_compare(const void *aep1, const void *aep2);
 196 static char *cond2str(void);
 197 static int policy2str(uint32_t policy, char *policy_str, size_t len);
 198 static int str2type(char *s, uint_t *type);
 199 static int str2policy(char *policy_str, uint32_t *policy_mask);
 200 static int str2ipaddr(char *s, uint32_t *addr, uint32_t type);
 201 static int strisipaddr(char *s);
 202 static int strisnum(char *s);
 203 static arg_entry_t *get_arg_ent(char *arg_str);
 204 static uid_t get_user_id(char *user);
 205 static void chk_arg_len(char *argv, uint_t len);
 206 static void chk_event_num(int etype, au_event_t event);
 207 static void chk_event_str(int etype, char *event_str);
 208 static void chk_known_plugin(char *plugin_str);
 209 static void chk_retval(char *retval_str);
 210 static void chk_sorf(char *sorf_str);
 211 static void do_aconf(void);
 212 static void do_args(char **argv, au_mask_t *mask);
 213 static void do_audit(char *, char, int, char *);
 214 static void do_chkaconf(void);
 215 static void do_chkconf(void);
 216 static void do_conf(void);
 217 static void do_getasid(void);
 218 static void do_getaudit(void);
 219 static void do_getkaudit(void);
 220 static void do_setkaudit(char *t, char *s);
 221 static void do_getauid(void);
 222 static void do_getcar(void);
 223 static void do_getclass(char *event_str);
 224 static void do_getcond(void);
 225 static void do_getcwd(void);
 226 static void do_getflags(void);
 227 static void do_getkmask(void);
 228 static void do_getnaflags(void);
 229 static void do_getpinfo(char *pid_str);
 230 static void do_getplugin(char *plugin_str);
 231 static void do_getpolicy(void);
 232 static void do_getqbufsz(void);
 233 static void do_getqctrl(void);
 234 static void do_getqdelay(void);
 235 static void do_getqhiwater(void);
 236 static void do_getqlowater(void);
 237 static void do_getstat(void);
 238 static void do_gettermid(void);
 239 static void do_lsevent(void);
 240 static void do_lspolicy(void);
 241 static void do_setasid(char *sid_str, char **argv);
 242 static void do_setaudit(char *user_str, char *mask_str, char *tid_str,
 243     char *sid_str, char **argv);
 244 static void do_setauid(char *user, char **argv);
 245 static void do_setclass(char *event_str, au_mask_t *mask);
 246 static void do_setflags(char *audit_flags, au_mask_t *amask);
 247 static void do_setkmask(au_mask_t *pmask);
 248 static void do_setnaflags(char *audit_naflags, au_mask_t *namask);
 249 static void do_setpmask(char *pid_str, au_mask_t *mask);
 250 static void do_setsmask(char *asid_str, au_mask_t *mask);
 251 static void do_setumask(char *auid_str, au_mask_t *mask);
 252 static void do_setplugin(char *plugin_str, boolean_t plugin_state,
 253     char *plugin_attr, int plugin_qsize);
 254 static void do_setpolicy(char *policy_str);
 255 static void do_setqbufsz(char *bufsz);
 256 static void do_setqctrl(char *hiwater, char *lowater, char *bufsz, char *delay);
 257 static void do_setqdelay(char *delay);
 258 static void do_setqhiwater(char *hiwater);
 259 static void do_setqlowater(char *lowater);
 260 static void do_setstat(void);
 261 static void str2tid(char *tid_str, au_tid_addr_t *tp);
 262 
 263 static void eauditon(int cmd, caddr_t data, int length);
 264 static void echkflags(char *auditflags, au_mask_t *mask);
 265 static void egetaudit(auditinfo_addr_t *ai, int size);
 266 static void egetauditflagsbin(char *auditflags, au_mask_t *pmask);
 267 static void egetauid(au_id_t *auid);
 268 static void egetkaudit(auditinfo_addr_t *ai, int size);
 269 static void esetaudit(auditinfo_addr_t *ai, int size);
 270 static void esetauid(au_id_t *auid);
 271 static void esetkaudit(auditinfo_addr_t *ai, int size);
 272 static void execit(char **argv);
 273 static void exit_error(char *fmt, ...);
 274 static void exit_usage(int status);
 275 static void parse_args(int argc, char **argv, au_mask_t *mask);
 276 static void print_asid(au_asid_t asid);
 277 static void print_auid(au_id_t auid);
 278 static void print_mask(char *desc, au_mask_t *pmp);
 279 static void print_plugin(char *plugin_name, kva_t *plugin_kva);
 280 static void print_tid_ex(au_tid_addr_t *tidp);
 281 
 282 #if !defined(TEXT_DOMAIN)
 283 #define TEXT_DOMAIN     "SUNW_OST_OSCMD"
 284 #endif
 285 
 286 int
 287 main(int argc, char **argv)
 288 {
 289         au_mask_t mask;                 /* for options manipulating flags */
 290 
 291         (void) setlocale(LC_ALL, "");
 292         (void) textdomain(TEXT_DOMAIN);
 293 
 294         if (argc == 1) {
 295                 exit_usage(0);
 296         }
 297 
 298         if (argc == 2 &&
 299             (argv[1][0] == '?' ||
 300             strcmp(argv[1], "-h") == 0 ||
 301             strcmp(argv[1], "-?") == 0)) {
 302                 exit_usage(0);
 303         }
 304 
 305         parse_args(argc, argv, &mask);
 306         do_args(argv, &mask);
 307 
 308         return (0);
 309 }
 310 
 311 /*
 312  * parse_args()
 313  *     Desc: Checks command line argument syntax.
 314  *     Inputs: Command line argv;
 315  *     Returns: If a syntax error is detected, a usage message is printed
 316  *              and exit() is called. If a syntax error is not detected,
 317  *              parse_args() returns without a value.
 318  */
 319 static void
 320 parse_args(int argc, char **argv, au_mask_t *mask)
 321 {
 322         arg_entry_t *ae;
 323 
 324         uint_t type;
 325         uint_t addr[4];
 326 
 327         for (++argv; *argv; argv++) {
 328                 if ((ae = get_arg_ent(*argv)) == NULL) {
 329                         exit_usage(1);
 330                 }
 331 
 332                 switch (ae->auditconfig_cmd) {
 333 
 334                 case AC_ARG_AUDIT:
 335                         ++argv;
 336                         if (!*argv)
 337                                 exit_usage(1);
 338                         if (strisnum(*argv)) {
 339                                 chk_event_num(AC_USER_EVENT,
 340                                     (au_event_t)atol(*argv));
 341                         } else {
 342                                 chk_event_str(AC_USER_EVENT, *argv);
 343                         }
 344                         ++argv;
 345                         if (!*argv)
 346                                 exit_usage(1);
 347                         chk_sorf(*argv);
 348                         ++argv;
 349                         if (!*argv)
 350                                 exit_usage(1);
 351                         chk_retval(*argv);
 352                         ++argv;
 353                         if (!*argv)
 354                                 exit_usage(1);
 355                         break;
 356 
 357                 case AC_ARG_CHKCONF:
 358                 case AC_ARG_CONF:
 359                 case AC_ARG_ACONF:
 360                 case AC_ARG_CHKACONF:
 361                 case AC_ARG_GETASID:
 362                 case AC_ARG_GETAUID:
 363                 case AC_ARG_GETAUDIT:
 364                 case AC_ARG_GETKAUDIT:
 365                         break;
 366 
 367                 case AC_ARG_GETCLASS:
 368                 case AC_ARG_GETESTATE:
 369                         ++argv;
 370                         if (!*argv)
 371                                 exit_usage(1);
 372                         if (strisnum(*argv)) {
 373                                 chk_event_num(AC_KERN_EVENT,
 374                                     (au_event_t)atol(*argv));
 375                         } else {
 376                                 chk_event_str(AC_KERN_EVENT, *argv);
 377                         }
 378                         break;
 379 
 380                 case AC_ARG_GETCAR:
 381                 case AC_ARG_GETCOND:
 382                 case AC_ARG_GETCWD:
 383                 case AC_ARG_GETFLAGS:
 384                 case AC_ARG_GETKMASK:
 385                 case AC_ARG_GETNAFLAGS:
 386                         break;
 387 
 388                 case AC_ARG_GETPLUGIN:
 389                         if (*++argv == NULL) {
 390                                 --argv;
 391                                 break;
 392                         }
 393                         if (get_arg_ent(*argv) != NULL) {
 394                                 --argv;
 395                         } else {
 396                                 chk_arg_len(*argv, PLUGIN_MAXBUF);
 397                                 chk_known_plugin(*argv);
 398                         }
 399                         break;
 400 
 401                 case AC_ARG_GETPOLICY:
 402                 case AC_ARG_GETQBUFSZ:
 403                 case AC_ARG_GETQCTRL:
 404                 case AC_ARG_GETQDELAY:
 405                 case AC_ARG_GETQHIWATER:
 406                 case AC_ARG_GETQLOWATER:
 407                 case AC_ARG_GETSTAT:
 408                 case AC_ARG_GETTERMID:
 409                 case AC_ARG_LSEVENT:
 410                 case AC_ARG_LSPOLICY:
 411                         break;
 412 
 413                 case AC_ARG_SETASID:
 414                 case AC_ARG_SETAUID:
 415                 case AC_ARG_SETAUDIT:
 416                         ++argv;
 417                         if (!*argv)
 418                                 exit_usage(1);
 419 
 420                         while (*argv)
 421                                 ++argv;
 422                         --argv;
 423 
 424                         break;
 425 
 426                 case AC_ARG_SETKAUDIT:
 427                         ++argv;
 428                         if (!*argv)
 429                                 exit_usage(1);
 430                         if (str2type (*argv, &type))
 431                                 exit_error(gettext(
 432                                     "Invalid IP address type specified."));
 433                         ++argv;
 434                         if (!*argv)
 435                                 exit_usage(1);
 436 
 437                         if (str2ipaddr(*argv, addr, type))
 438                                 exit_error(
 439                                     gettext("Invalid IP address specified."));
 440                         break;
 441 
 442                 case AC_ARG_SETCLASS:
 443                         ++argv;
 444                         if (!*argv)
 445                                 exit_usage(1);
 446                         if (strisnum(*argv))
 447                                 chk_event_num(AC_KERN_EVENT,
 448                                     (au_event_t)atol(*argv));
 449                         else
 450                                 chk_event_str(AC_KERN_EVENT, *argv);
 451                         ++argv;
 452                         if (!*argv)
 453                                 exit_usage(1);
 454                         echkflags(*argv, mask);
 455                         break;
 456 
 457                 case AC_ARG_SETFLAGS:
 458                         ++argv;
 459                         if (!*argv)
 460                                 exit_usage(1);
 461                         chk_arg_len(*argv, PRESELECTION_MAXBUF);
 462                         echkflags(*argv, mask);
 463                         break;
 464 
 465                 case AC_ARG_SETKMASK:
 466                         ++argv;
 467                         if (!*argv)
 468                                 exit_usage(1);
 469                         echkflags(*argv, mask);
 470                         break;
 471 
 472                 case AC_ARG_SETNAFLAGS:
 473                         ++argv;
 474                         if (!*argv)
 475                                 exit_usage(1);
 476                         chk_arg_len(*argv, PRESELECTION_MAXBUF);
 477                         echkflags(*argv, mask);
 478                         break;
 479 
 480                 case AC_ARG_SETPLUGIN:
 481                         if (*++argv == NULL || get_arg_ent(*argv) != NULL) {
 482                                 exit_usage(1);
 483                         }
 484                         chk_known_plugin(*argv);
 485                         chk_arg_len(*argv, PLUGIN_MAXBUF);
 486                         if (*++argv == NULL || strcmp(*argv, "active") != 0 &&
 487                             strcmp(*argv, "inactive") != 0) {
 488                                 exit_usage(1);
 489                         }
 490                         if (*++argv == NULL || get_arg_ent(*argv) != NULL) {
 491                                 --argv;
 492                                 break;
 493                         }
 494                         chk_arg_len(*argv, PLUGIN_MAXATT);
 495                         if (*++argv == NULL || get_arg_ent(*argv) != NULL) {
 496                                 --argv;
 497                                 break;
 498                         }
 499                         if (atoi(*argv) < 0) {
 500                                 exit_error(gettext("Incorrect qsize specified "
 501                                     "(%s)."), *argv);
 502                         }
 503                         break;
 504 
 505                 case AC_ARG_SETPOLICY:
 506                         ++argv;
 507                         if (!*argv)
 508                                 exit_usage(1);
 509                         break;
 510 
 511                 case AC_ARG_SETSTAT:
 512                         break;
 513 
 514                 case AC_ARG_GETPINFO:
 515                         ++argv;
 516                         if (!*argv)
 517                                 exit_usage(1);
 518                         break;
 519 
 520                 case AC_ARG_SETPMASK:
 521                         ++argv;
 522                         if (!*argv)
 523                                 exit_usage(1);
 524                         ++argv;
 525                         if (!*argv)
 526                                 exit_usage(1);
 527                         echkflags(*argv, mask);
 528                         break;
 529 
 530                 case AC_ARG_SETQBUFSZ:
 531                         ++argv;
 532                         if (!*argv)
 533                                 exit_usage(1);
 534                         if (!strisnum(*argv))
 535                                 exit_error(gettext("Invalid bufsz specified."));
 536                         break;
 537 
 538                 case AC_ARG_SETQCTRL:
 539                         ++argv;
 540                         if (!*argv)
 541                                 exit_usage(1);
 542                         if (!strisnum(*argv))
 543                                 exit_error(
 544                                     gettext("Invalid hiwater specified."));
 545                         ++argv;
 546                         if (!*argv)
 547                                 exit_usage(1);
 548                         if (!strisnum(*argv))
 549                                 exit_error(
 550                                     gettext("Invalid lowater specified."));
 551                         ++argv;
 552                         if (!*argv)
 553                                 exit_usage(1);
 554                         if (!strisnum(*argv))
 555                                 exit_error(gettext("Invalid bufsz specified."));
 556                         ++argv;
 557                         if (!*argv)
 558                                 exit_usage(1);
 559                         if (!strisnum(*argv))
 560                                 exit_error(gettext("Invalid delay specified."));
 561                         break;
 562 
 563                 case AC_ARG_SETQDELAY:
 564                         ++argv;
 565                         if (!*argv)
 566                                 exit_usage(1);
 567                         if (!strisnum(*argv))
 568                                 exit_error(gettext("Invalid delay specified."));
 569                         break;
 570 
 571                 case AC_ARG_SETQHIWATER:
 572                         ++argv;
 573                         if (!*argv)
 574                                 exit_usage(1);
 575                         if (!strisnum(*argv)) {
 576                                 exit_error(
 577                                     gettext("Invalid hiwater specified."));
 578                         }
 579                         break;
 580 
 581                 case AC_ARG_SETQLOWATER:
 582                         ++argv;
 583                         if (!*argv)
 584                                 exit_usage(1);
 585                         if (!strisnum(*argv)) {
 586                                 exit_error(
 587                                     gettext("Invalid lowater specified."));
 588                         }
 589                         break;
 590 
 591                 case AC_ARG_SETSMASK:
 592                 case AC_ARG_SETUMASK:
 593                         ++argv;
 594                         if (!*argv)
 595                                 exit_usage(1);
 596                         ++argv;
 597                         if (!*argv)
 598                                 exit_usage(1);
 599                         echkflags(*argv, mask);
 600                         break;
 601 
 602                 case AC_ARG_SET_TEMPORARY:
 603                         /* Do not accept single -t option. */
 604                         if (argc == 2) {
 605                                 exit_error(
 606                                     gettext("Only the -t option specified "
 607                                     "(it is not a standalone option)."));
 608                         }
 609                         temporary_set = B_TRUE;
 610                         break;
 611 
 612                 default:
 613                         exit_error(gettext("Internal error #1."));
 614                         break;
 615                 }
 616         }
 617 }
 618 
 619 
 620 /*
 621  * do_args() - do command line arguments in the order in which they appear.
 622  * Function return values returned by the underlying functions; the semantics
 623  * they should follow is to return B_TRUE on successful execution, B_FALSE
 624  * otherwise.
 625  */
 626 static void
 627 do_args(char **argv, au_mask_t *mask)
 628 {
 629         arg_entry_t     *ae;
 630 
 631         for (++argv; *argv; argv++) {
 632                 ae = get_arg_ent(*argv);
 633 
 634                 switch (ae->auditconfig_cmd) {
 635 
 636                 case AC_ARG_AUDIT:
 637                         {
 638                                 char sorf;
 639                                 int  retval;
 640                                 char *event_name;
 641                                 char *audit_str;
 642 
 643                                 ++argv;
 644                                 event_name = *argv;
 645                                 ++argv;
 646                                 sorf = (char)atoi(*argv);
 647                                 ++argv;
 648                                 retval = atoi(*argv);
 649                                 ++argv;
 650                                 audit_str = *argv;
 651                                 do_audit(event_name, sorf, retval, audit_str);
 652                         }
 653                         break;
 654 
 655                 case AC_ARG_CHKCONF:
 656                         do_chkconf();
 657                         break;
 658 
 659                 case AC_ARG_CONF:
 660                         do_conf();
 661                         break;
 662 
 663                 case AC_ARG_CHKACONF:
 664                         do_chkaconf();
 665                         break;
 666 
 667                 case AC_ARG_ACONF:
 668                         do_aconf();
 669                         break;
 670 
 671                 case AC_ARG_GETASID:
 672                         do_getasid();
 673                         break;
 674 
 675                 case AC_ARG_GETAUID:
 676                         do_getauid();
 677                         break;
 678 
 679                 case AC_ARG_GETAUDIT:
 680                         do_getaudit();
 681                         break;
 682 
 683                 case AC_ARG_GETKAUDIT:
 684                         do_getkaudit();
 685                         break;
 686 
 687                 case AC_ARG_GETCLASS:
 688                 case AC_ARG_GETESTATE:
 689                         ++argv;
 690                         do_getclass(*argv);
 691                         break;
 692 
 693                 case AC_ARG_GETCAR:
 694                         do_getcar();
 695                         break;
 696 
 697                 case AC_ARG_GETCOND:
 698                         do_getcond();
 699                         break;
 700 
 701                 case AC_ARG_GETCWD:
 702                         do_getcwd();
 703                         break;
 704 
 705                 case AC_ARG_GETFLAGS:
 706                         do_getflags();
 707                         break;
 708 
 709                 case AC_ARG_GETKMASK:
 710                         do_getkmask();
 711                         break;
 712 
 713                 case AC_ARG_GETNAFLAGS:
 714                         do_getnaflags();
 715                         break;
 716 
 717                 case AC_ARG_GETPLUGIN:
 718                         {
 719                                 char    *plugin_str = NULL;
 720 
 721                                 ++argv;
 722                                 if (*argv != NULL) {
 723                                         if (get_arg_ent(*argv) != NULL) {
 724                                                 --argv;
 725                                         } else {
 726                                                 plugin_str = *argv;
 727                                         }
 728                                 } else {
 729                                         --argv;
 730                                 }
 731 
 732                                 do_getplugin(plugin_str);
 733                         }
 734                         break;
 735 
 736                 case AC_ARG_GETPOLICY:
 737                         do_getpolicy();
 738                         break;
 739 
 740                 case AC_ARG_GETQBUFSZ:
 741                         do_getqbufsz();
 742                         break;
 743 
 744                 case AC_ARG_GETQCTRL:
 745                         do_getqctrl();
 746                         break;
 747 
 748                 case AC_ARG_GETQDELAY:
 749                         do_getqdelay();
 750                         break;
 751 
 752                 case AC_ARG_GETQHIWATER:
 753                         do_getqhiwater();
 754                         break;
 755 
 756                 case AC_ARG_GETQLOWATER:
 757                         do_getqlowater();
 758                         break;
 759 
 760                 case AC_ARG_GETSTAT:
 761                         do_getstat();
 762                         break;
 763 
 764                 case AC_ARG_GETTERMID:
 765                         do_gettermid();
 766                         break;
 767 
 768                 case AC_ARG_LSEVENT:
 769                         do_lsevent();
 770                         break;
 771 
 772                 case AC_ARG_LSPOLICY:
 773                         do_lspolicy();
 774                         break;
 775 
 776                 case AC_ARG_SETASID:
 777                         {
 778                                 char *sid_str;
 779 
 780                                 ++argv;
 781                                 sid_str = *argv;
 782                                 ++argv;
 783                                 do_setasid(sid_str, argv);
 784                         }
 785                         break;
 786 
 787                 case AC_ARG_SETAUID:
 788                         {
 789                                 char *user;
 790 
 791                                 ++argv;
 792                                 user = *argv;
 793                                 ++argv;
 794                                 do_setauid(user, argv);
 795                         }
 796                         break;
 797 
 798                 case AC_ARG_SETAUDIT:
 799                         {
 800                                 char *user_str;
 801                                 char *mask_str;
 802                                 char *tid_str;
 803                                 char *sid_str;
 804 
 805                                 ++argv;
 806                                 user_str = *argv;
 807                                 ++argv;
 808                                 mask_str = *argv;
 809                                 ++argv;
 810                                 tid_str = *argv;
 811                                 ++argv;
 812                                 sid_str = *argv;
 813                                 ++argv;
 814                                 do_setaudit(user_str, mask_str, tid_str,
 815                                     sid_str, argv);
 816                         }
 817                         break;
 818 
 819                 case AC_ARG_SETKAUDIT:
 820                         {
 821                                 char *address_type, *address;
 822 
 823                                 ++argv; address_type = *argv;
 824                                 ++argv; address = *argv;
 825                                 do_setkaudit(address_type, address);
 826                         }
 827                         break;
 828 
 829                 case AC_ARG_SETCLASS:
 830                         {
 831                                 char *event_str;
 832 
 833                                 ++argv;
 834                                 event_str = *argv;
 835                                 do_setclass(event_str, mask);
 836 
 837                                 ++argv;
 838                         }
 839                         break;
 840 
 841                 case AC_ARG_SETFLAGS:
 842                         ++argv;
 843                         do_setflags(*argv, mask);
 844                         break;
 845 
 846                 case AC_ARG_SETKMASK:
 847                         ++argv;
 848                         do_setkmask(mask);
 849                         break;
 850 
 851                 case AC_ARG_SETNAFLAGS:
 852                         ++argv;
 853                         do_setnaflags(*argv, mask);
 854                         break;
 855 
 856                 case AC_ARG_SETPLUGIN:
 857                         {
 858                                 char            *plugin_str = NULL;
 859                                 boolean_t       plugin_state = B_FALSE;
 860                                 char            *plugin_att = NULL;
 861                                 int             plugin_qsize = -1;
 862 
 863                                 plugin_str = *++argv;
 864                                 if (strcmp(*++argv, "active") == 0) {
 865                                         plugin_state = B_TRUE;
 866                                 }
 867                                 if (*++argv != NULL &&
 868                                     get_arg_ent(*argv) == NULL) {
 869                                         plugin_att = *argv;
 870                                         if (*++argv != NULL &&
 871                                             get_arg_ent(*argv) == NULL) {
 872                                                 plugin_qsize = atoi(*argv);
 873                                         } else {
 874                                                 --argv;
 875                                         }
 876                                 } else {
 877                                         --argv;
 878                                 }
 879 
 880                                 do_setplugin(plugin_str, plugin_state,
 881                                     plugin_att, plugin_qsize);
 882                         }
 883                         break;
 884 
 885                 case AC_ARG_SETPOLICY:
 886                         ++argv;
 887                         do_setpolicy(*argv);
 888                         break;
 889 
 890                 case AC_ARG_GETPINFO:
 891                         {
 892                                 char *pid_str;
 893 
 894                                 ++argv;
 895                                 pid_str = *argv;
 896                                 do_getpinfo(pid_str);
 897                         }
 898                         break;
 899 
 900                 case AC_ARG_SETPMASK:
 901                         {
 902                                 char *pid_str;
 903 
 904                                 ++argv;
 905                                 pid_str = *argv;
 906                                 do_setpmask(pid_str, mask);
 907 
 908                                 ++argv;
 909                         }
 910                         break;
 911 
 912                 case AC_ARG_SETSTAT:
 913                         do_setstat();
 914                         break;
 915 
 916                 case AC_ARG_SETQBUFSZ:
 917                         ++argv;
 918                         do_setqbufsz(*argv);
 919                         break;
 920 
 921                 case AC_ARG_SETQCTRL:
 922                         {
 923                                 char *hiwater, *lowater, *bufsz, *delay;
 924 
 925                                 ++argv; hiwater = *argv;
 926                                 ++argv; lowater = *argv;
 927                                 ++argv; bufsz = *argv;
 928                                 ++argv; delay = *argv;
 929                                 do_setqctrl(hiwater, lowater, bufsz, delay);
 930                         }
 931                         break;
 932                 case AC_ARG_SETQDELAY:
 933                         ++argv;
 934                         do_setqdelay(*argv);
 935                         break;
 936 
 937                 case AC_ARG_SETQHIWATER:
 938                         ++argv;
 939                         do_setqhiwater(*argv);
 940                         break;
 941 
 942                 case AC_ARG_SETQLOWATER:
 943                         ++argv;
 944                         do_setqlowater(*argv);
 945                         break;
 946 
 947                 case AC_ARG_SETSMASK:
 948                         {
 949                                 char *asid_str;
 950 
 951                                 ++argv;
 952                                 asid_str = *argv;
 953                                 do_setsmask(asid_str, mask);
 954 
 955                                 ++argv;
 956                         }
 957                         break;
 958                 case AC_ARG_SETUMASK:
 959                         {
 960                                 char *auid_str;
 961 
 962                                 ++argv;
 963                                 auid_str = *argv;
 964                                 do_setumask(auid_str, mask);
 965 
 966                                 ++argv;
 967                         }
 968                         break;
 969                 case AC_ARG_SET_TEMPORARY:
 970                         break;
 971 
 972                 default:
 973                         exit_error(gettext("Internal error #2."));
 974                         break;
 975                 }
 976         }
 977 }
 978 
 979 /*
 980  * do_chkconf() - the returned value is for the global zone unless AUDIT_PERZONE
 981  * is set.
 982  */
 983 static void
 984 do_chkconf(void)
 985 {
 986         register au_event_ent_t *evp;
 987         au_mask_t pmask;
 988         char conf_aflags[256];
 989         char run_aflags[256];
 990         au_stat_t as;
 991         int class;
 992         int                     len;
 993         struct au_evclass_map   cmap;
 994 
 995         pmask.am_success = pmask.am_failure = 0;
 996         eauditon(A_GETSTAT, (caddr_t)&as, 0);
 997 
 998         setauevent();
 999         if (getauevent() == NULL) {
1000                 exit_error(gettext("NO AUDIT EVENTS: Could not read %s\n."),
1001                     AUDITEVENTFILE);
1002         }
1003 
1004         setauevent();
1005         while ((evp = getauevent()) != NULL) {
1006                 cmap.ec_number = evp->ae_number;
1007                 len = sizeof (struct au_evclass_map);
1008                 if (evp->ae_number <= as.as_numevent) {
1009                         if (auditon(A_GETCLASS, (caddr_t)&cmap, len) == -1) {
1010                                 (void) printf("%s(%hu):%s",
1011                                     evp->ae_name, evp->ae_number,
1012                                     gettext("UNKNOWN EVENT: Could not get "
1013                                     "class for event. Configuration may "
1014                                     "be bad.\n"));
1015                         } else {
1016                                 class = cmap.ec_class;
1017                                 if (class != evp->ae_class) {
1018                                         conf_aflags[0] = run_aflags[0] = '\0';
1019                                         pmask.am_success = class;
1020                                         pmask.am_failure = class;
1021                                         (void) getauditflagschar(run_aflags,
1022                                             &pmask, 0);
1023                                         pmask.am_success = evp->ae_class;
1024                                         pmask.am_failure = evp->ae_class;
1025                                         (void) getauditflagschar(conf_aflags,
1026                                             &pmask, 0);
1027 
1028                                         (void) printf(gettext(
1029                                             "%s(%hu): CLASS MISMATCH: "
1030                                             "runtime class (%s) != "
1031                                             "configured class (%s)\n"),
1032                                             evp->ae_name, evp->ae_number,
1033                                             NONE(run_aflags),
1034                                             NONE(conf_aflags));
1035                                 }
1036                         }
1037                 }
1038         }
1039         endauevent();
1040 }
1041 
1042 /*
1043  * do_conf() - configure the kernel events. The value returned to the user is
1044  * for the global zone unless AUDIT_PERZONE is set.
1045  */
1046 static void
1047 do_conf(void)
1048 {
1049         register au_event_ent_t *evp;
1050         register int i;
1051         au_evclass_map_t ec;
1052         au_stat_t as;
1053 
1054         eauditon(A_GETSTAT, (caddr_t)&as, 0);
1055 
1056         i = 0;
1057         setauevent();
1058         while ((evp = getauevent()) != NULL) {
1059                 if (evp->ae_number <= as.as_numevent) {
1060                         ++i;
1061                         ec.ec_number = evp->ae_number;
1062                         ec.ec_class = evp->ae_class;
1063                         eauditon(A_SETCLASS, (caddr_t)&ec, sizeof (ec));
1064                 }
1065         }
1066         endauevent();
1067         (void) printf(gettext("Configured %d kernel events.\n"), i);
1068 
1069 }
1070 
1071 /*
1072  * do_chkaconf() - report a mismatch if the runtime class mask of a kernel audit
1073  * event does not match the configured class mask. The value returned to the
1074  * user is for the global zone unless AUDIT_PERZONE is set.
1075  */
1076 static void
1077 do_chkaconf(void)
1078 {
1079         char            *namask_cfg;
1080         au_mask_t       pmask, kmask;
1081 
1082         if (!do_getnaflags_scf(&namask_cfg) || namask_cfg == NULL) {
1083                 exit_error(gettext("Could not get configured value."));
1084         }
1085         egetauditflagsbin(namask_cfg, &pmask);
1086 
1087         eauditon(A_GETKMASK, (caddr_t)&kmask, sizeof (kmask));
1088 
1089         if ((pmask.am_success != kmask.am_success) ||
1090             (pmask.am_failure != kmask.am_failure)) {
1091                 char kbuf[2048];
1092                 if (getauditflagschar(kbuf, &kmask, 0) < 0) {
1093                         free(namask_cfg);
1094                         (void) fprintf(stderr,
1095                             gettext("bad kernel non-attributable mask\n"));
1096                         exit(1);
1097                 }
1098                 (void) printf(
1099                     gettext("non-attributable event flags mismatch:\n"));
1100                 (void) printf(gettext("active non-attributable audit flags "
1101                     "= %s\n"), kbuf);
1102                 (void) printf(gettext("configured non-attributable audit flags "
1103                     "= %s\n"), namask_cfg);
1104         }
1105         free(namask_cfg);
1106 }
1107 
1108 /*
1109  * do_aconf - configures the non-attributable events. The value returned to the
1110  * user is for the global zone unless AUDIT_PERZONE is set.
1111  */
1112 static void
1113 do_aconf(void)
1114 {
1115         au_mask_t       namask;
1116         char            *namask_cfg;
1117 
1118         if (!do_getnaflags_scf(&namask_cfg) || namask_cfg == NULL) {
1119                 exit_error(gettext("Could not get configured value."));
1120         }
1121         egetauditflagsbin(namask_cfg, &namask);
1122         free(namask_cfg);
1123 
1124         eauditon(A_SETKMASK, (caddr_t)&namask, sizeof (namask));
1125         (void) printf(gettext("Configured non-attributable event mask.\n"));
1126 }
1127 
1128 /*
1129  * do_audit() - construct an audit record for audit event event using the
1130  * process's audit characteristics containing a text token string audit_str. The
1131  * return token is constructed from the success/failure flag sort. Returned
1132  * value retval is an errno value.
1133  */
1134 static void
1135 do_audit(char *event, char sorf, int retval, char *audit_str)
1136 {
1137         int rtn;
1138         int rd;
1139         au_event_t event_num;
1140         au_event_ent_t *evp;
1141         auditinfo_addr_t ai;
1142         token_t *tokp;
1143 
1144         egetaudit(&ai, sizeof (ai));
1145 
1146         if (strisnum(event)) {
1147                 event_num = (au_event_t)atoi(event);
1148                 evp = egetauevnum(event_num);
1149         } else {
1150                 evp = egetauevnam(event);
1151         }
1152 
1153         rtn = au_preselect(evp->ae_number, &ai.ai_mask, (int)sorf,
1154             AU_PRS_USECACHE);
1155 
1156         if (rtn == -1) {
1157                 exit_error("%s\n%s %hu\n",
1158                     gettext("Check audit event configuration."),
1159                     gettext("Could not get audit class for event number"),
1160                     evp->ae_number);
1161         }
1162 
1163         /* record is preselected */
1164         if (rtn == 1) {
1165                 if ((rd = au_open()) == -1) {
1166                         exit_error(gettext(
1167                             "Could not get and audit record descriptor\n"));
1168                 }
1169                 if ((tokp = au_to_me()) == NULL) {
1170                         exit_error(
1171                             gettext("Could not allocate subject token\n"));
1172                 }
1173                 if (au_write(rd, tokp) == -1) {
1174                         exit_error(gettext("Could not construct subject token "
1175                             "of audit record\n"));
1176                 }
1177                 if (is_system_labeled()) {
1178                         if ((tokp = au_to_mylabel()) == NULL) {
1179                                 exit_error(gettext(
1180                                     "Could not allocate label token\n"));
1181                         }
1182                         if (au_write(rd, tokp) == -1) {
1183                                 exit_error(gettext("Could not "
1184                                     "construct label token of audit record\n"));
1185                         }
1186                 }
1187 
1188                 if ((tokp = au_to_text(audit_str)) == NULL)
1189                         exit_error(gettext("Could not allocate text token\n"));
1190                 if (au_write(rd, tokp) == -1)
1191                         exit_error(gettext("Could not construct text token of "
1192                             "audit record\n"));
1193 #ifdef _LP64
1194                 if ((tokp = au_to_return64(sorf, retval)) == NULL)
1195 #else
1196                 if ((tokp = au_to_return32(sorf, retval)) == NULL)
1197 #endif
1198                         exit_error(
1199                             gettext("Could not allocate return token\n"));
1200                 if (au_write(rd, tokp) == -1) {
1201                         exit_error(gettext("Could not construct return token "
1202                             "of audit record\n"));
1203                 }
1204                 if (au_close(rd, 1, evp->ae_number) == -1) {
1205                         exit_error(
1206                             gettext("Could not write audit record: %s\n"),
1207                             strerror(errno));
1208                 }
1209         }
1210 }
1211 
1212 /*
1213  * do_getauid() - print the audit id of the current process.
1214  */
1215 static void
1216 do_getauid(void)
1217 {
1218         au_id_t auid;
1219 
1220         egetauid(&auid);
1221         print_auid(auid);
1222 }
1223 
1224 /*
1225  * do_getaudit() - print the audit characteristics of the current process.
1226  */
1227 static void
1228 do_getaudit(void)
1229 {
1230         auditinfo_addr_t ai;
1231 
1232         egetaudit(&ai, sizeof (ai));
1233         print_auid(ai.ai_auid);
1234         print_mask(gettext("process preselection mask"), &ai.ai_mask);
1235         print_tid_ex(&ai.ai_termid);
1236         print_asid(ai.ai_asid);
1237 }
1238 
1239 /*
1240  * do_getkaudit() - print the audit characteristics of the current zone.
1241  */
1242 static void
1243 do_getkaudit(void)
1244 {
1245         auditinfo_addr_t ai;
1246 
1247         egetkaudit(&ai, sizeof (ai));
1248         print_auid(ai.ai_auid);
1249         print_mask(gettext("process preselection mask"), &ai.ai_mask);
1250         print_tid_ex(&ai.ai_termid);
1251         print_asid(ai.ai_asid);
1252 }
1253 
1254 /*
1255  * do_setkaudit() - set IP address_type/address of machine to specified values;
1256  * valid per zone if AUDIT_PERZONE is set, else only in global zone.
1257  */
1258 static void
1259 do_setkaudit(char *t, char *s)
1260 {
1261         uint_t type;
1262         auditinfo_addr_t ai;
1263 
1264         egetkaudit(&ai, sizeof (ai));
1265         (void) str2type(t, &type);
1266         (void) str2ipaddr(s, &ai.ai_termid.at_addr[0], type);
1267         ai.ai_termid.at_type = type;
1268         esetkaudit(&ai, sizeof (ai));
1269 }
1270 
1271 /*
1272  * do_getcar() - print the zone-relative root
1273  */
1274 static void
1275 do_getcar(void)
1276 {
1277         char path[MAXPATHLEN];
1278 
1279         eauditon(A_GETCAR, (caddr_t)path, sizeof (path));
1280         (void) printf(gettext("current active root = %s\n"), path);
1281 }
1282 
1283 /*
1284  * do_getclass() - print the preselection mask associated with the specified
1285  * kernel audit event. The displayed value is for the global zone unless
1286  * AUDIT_PERZONE is set.
1287  */
1288 static void
1289 do_getclass(char *event_str)
1290 {
1291         au_evclass_map_t ec;
1292         au_event_ent_t *evp;
1293         au_event_t event_number;
1294         char *event_name;
1295 
1296         if (strisnum(event_str)) {
1297                 event_number = atol(event_str);
1298                 if ((evp = egetauevnum(event_number)) != NULL) {
1299                         event_number = evp->ae_number;
1300                         event_name = evp->ae_name;
1301                 } else {
1302                         event_name = gettext("unknown");
1303                 }
1304         } else {
1305                 event_name = event_str;
1306                 if ((evp = egetauevnam(event_str)) != NULL) {
1307                         event_number = evp->ae_number;
1308                 }
1309         }
1310 
1311         ec.ec_number = event_number;
1312         eauditon(A_GETCLASS, (caddr_t)&ec, 0);
1313 
1314         (void) printf(gettext("audit class mask for event %s(%hu) = 0x%x\n"),
1315             event_name, event_number, ec.ec_class);
1316 }
1317 
1318 /*
1319  * do_getcond() - the printed value is for the global zone unless
1320  * AUDIT_PERZONE is set. (AUC_DISABLED is always global, the other states are
1321  * per zone if AUDIT_PERZONE is set)
1322  */
1323 static void
1324 do_getcond(void)
1325 {
1326         (void) printf(gettext("audit condition = %s\n"), cond2str());
1327 }
1328 
1329 /*
1330  * do_getcwd() - the printed path is relative to the current zone root
1331  */
1332 static void
1333 do_getcwd(void)
1334 {
1335         char path[MAXPATHLEN];
1336 
1337         eauditon(A_GETCWD, (caddr_t)path, sizeof (path));
1338         (void) printf(gettext("current working directory = %s\n"), path);
1339 }
1340 
1341 /*
1342  * do_getflags() - the printed value is for the global zone unless AUDIT_PERZONE
1343  * is set.
1344  */
1345 static void
1346 do_getflags(void)
1347 {
1348         au_mask_t       amask;
1349         char            *amask_cfg;
1350 
1351         eauditon(A_GETAMASK, (caddr_t)&amask, sizeof (amask));
1352         print_mask(gettext("active user default audit flags"), &amask);
1353 
1354         if (!do_getflags_scf(&amask_cfg) || amask_cfg == NULL) {
1355                 exit_error(gettext("Could not get configured value."));
1356         }
1357         egetauditflagsbin(amask_cfg, &amask);
1358         print_mask(gettext("configured user default audit flags"), &amask);
1359         free(amask_cfg);
1360 }
1361 
1362 /*
1363  * do_getkmask() - the printed value is for the global zone unless AUDIT_PERZONE
1364  * is set.
1365  */
1366 static void
1367 do_getkmask(void)
1368 {
1369         au_mask_t pmask;
1370 
1371         eauditon(A_GETKMASK, (caddr_t)&pmask, sizeof (pmask));
1372         print_mask(gettext("active non-attributable audit flags"), &pmask);
1373 }
1374 
1375 /*
1376  * do_getnaflags() - the printed value is for the global zone unless
1377  * AUDIT_PERZONE is set.
1378  */
1379 static void
1380 do_getnaflags(void)
1381 {
1382         au_mask_t       namask;
1383         char            *namask_cfg;
1384 
1385         eauditon(A_GETKMASK, (caddr_t)&namask, sizeof (namask));
1386         print_mask(gettext("active non-attributable audit flags"), &namask);
1387 
1388         if (!do_getnaflags_scf(&namask_cfg) || namask_cfg == NULL) {
1389                 exit_error(gettext("Could not get configured value."));
1390         }
1391         egetauditflagsbin(namask_cfg, &namask);
1392         print_mask(gettext("configured non-attributable audit flags"), &namask);
1393         free(namask_cfg);
1394 }
1395 
1396 /*
1397  * do_getpolicy() - print active and configured kernel audit policy relative to
1398  * the current zone.
1399  */
1400 static void
1401 do_getpolicy(void)
1402 {
1403         char                    policy_str[1024];
1404         uint32_t                policy;
1405 
1406         if (!temporary_set) {
1407                 if (!do_getpolicy_scf(&policy)) {
1408                         exit_error(gettext("Could not get configured values."));
1409                 }
1410                 (void) policy2str(policy, policy_str, sizeof (policy_str));
1411                 (void) printf(gettext("configured audit policies = %s\n"),
1412                     policy_str);
1413         }
1414 
1415         eauditon(A_GETPOLICY, (caddr_t)&policy, 0);
1416         (void) policy2str(policy, policy_str, sizeof (policy_str));
1417         (void) printf(gettext("active audit policies = %s\n"), policy_str);
1418 }
1419 
1420 
1421 /*
1422  * do_getpinfo() - print the audit ID, preselection mask, terminal ID, and
1423  * audit session ID for the specified process.
1424  */
1425 static void
1426 do_getpinfo(char *pid_str)
1427 {
1428         struct auditpinfo_addr ap;
1429 
1430         if (strisnum(pid_str))
1431                 ap.ap_pid = (pid_t)atoi(pid_str);
1432         else
1433                 exit_usage(1);
1434 
1435         eauditon(A_GETPINFO_ADDR, (caddr_t)&ap, sizeof (ap));
1436 
1437         print_auid(ap.ap_auid);
1438         print_mask(gettext("process preselection mask"), &(ap.ap_mask));
1439         print_tid_ex(&(ap.ap_termid));
1440         print_asid(ap.ap_asid);
1441 }
1442 
1443 /*
1444  * do_getplugin() - print plugin configuration.
1445  */
1446 static void
1447 do_getplugin(char *plugin_str)
1448 {
1449         scf_plugin_kva_node_t   *plugin_kva_ll;
1450         scf_plugin_kva_node_t   *plugin_kva_ll_head;
1451 
1452         if (!do_getpluginconfig_scf(plugin_str, &plugin_kva_ll)) {
1453                 exit_error(gettext("Could not get plugin configuration."));
1454         }
1455 
1456         plugin_kva_ll_head = plugin_kva_ll;
1457 
1458         while (plugin_kva_ll != NULL) {
1459                 print_plugin(plugin_kva_ll->plugin_name,
1460                     plugin_kva_ll->plugin_kva);
1461                 plugin_kva_ll = plugin_kva_ll->next;
1462                 if (plugin_kva_ll != NULL) {
1463                         (void) printf("\n");
1464                 }
1465         }
1466         plugin_kva_ll_free(plugin_kva_ll_head);
1467 }
1468 
1469 /*
1470  * do_getqbufsz() - print the active and configured audit queue write buffer
1471  * size relative to the current zone.
1472  */
1473 static void
1474 do_getqbufsz(void)
1475 {
1476         struct au_qctrl qctrl;
1477 
1478         if (!temporary_set) {
1479                 if (!do_getqbufsz_scf(&qctrl.aq_bufsz)) {
1480                         exit_error(gettext("Could not get configured value."));
1481                 }
1482 
1483                 if (qctrl.aq_bufsz == 0) {
1484                         (void) printf(gettext(
1485                             "no configured audit queue buffer size\n"));
1486                 } else {
1487                         (void) printf(gettext("configured audit queue "
1488                             "buffer size (bytes) = %d\n"), qctrl.aq_bufsz);
1489                 }
1490         }
1491 
1492         eauditon(A_GETQCTRL, (caddr_t)&qctrl, 0);
1493         (void) printf(gettext("active audit queue buffer size (bytes) = %d\n"),
1494             qctrl.aq_bufsz);
1495 }
1496 
1497 /*
1498  * do_getqctrl() - print the configured and active audit queue write buffer
1499  * size, audit queue hiwater mark, audit queue lowater mark, audit queue prod
1500  * interval (ticks) relative to the current zone.
1501  */
1502 static void
1503 do_getqctrl(void)
1504 {
1505         struct au_qctrl qctrl;
1506 
1507         if (!temporary_set) {
1508                 if (!do_getqctrl_scf(&qctrl)) {
1509                         exit_error(gettext("Could not get configured values."));
1510                 }
1511 
1512                 if (qctrl.aq_hiwater == 0) {
1513                         (void) printf(gettext(
1514                             "no configured audit queue hiwater mark\n"));
1515                 } else {
1516                         (void) printf(gettext("configured audit queue "
1517                             "hiwater mark (records) = %d\n"), qctrl.aq_hiwater);
1518                 }
1519                 if (qctrl.aq_lowater == 0) {
1520                         (void) printf(gettext(
1521                             "no configured audit queue lowater mark\n"));
1522                 } else {
1523                         (void) printf(gettext("configured audit queue "
1524                             "lowater mark (records) = %d\n"), qctrl.aq_lowater);
1525                 }
1526                 if (qctrl.aq_bufsz == 0) {
1527                         (void) printf(gettext(
1528                             "no configured audit queue buffer size\n"));
1529                 } else {
1530                         (void) printf(gettext("configured audit queue "
1531                             "buffer size (bytes) = %d\n"), qctrl.aq_bufsz);
1532                 }
1533                 if (qctrl.aq_delay == 0) {
1534                         (void) printf(gettext(
1535                             "no configured audit queue delay\n"));
1536                 } else {
1537                         (void) printf(gettext("configured audit queue "
1538                             "delay (ticks) = %ld\n"), qctrl.aq_delay);
1539                 }
1540         }
1541 
1542         eauditon(A_GETQCTRL, (caddr_t)&qctrl, 0);
1543         (void) printf(gettext("active audit queue hiwater mark "
1544             "(records) = %d\n"), qctrl.aq_hiwater);
1545         (void) printf(gettext("active audit queue lowater mark "
1546             "(records) = %d\n"), qctrl.aq_lowater);
1547         (void) printf(gettext("active audit queue buffer size (bytes) = %d\n"),
1548             qctrl.aq_bufsz);
1549         (void) printf(gettext("active audit queue delay (ticks) = %ld\n"),
1550             qctrl.aq_delay);
1551 }
1552 
1553 /*
1554  * do_getqdelay() - print, relative to the current zone, the configured and
1555  * active interval at which audit queue is prodded to start output.
1556  */
1557 static void
1558 do_getqdelay(void)
1559 {
1560         struct au_qctrl qctrl;
1561 
1562         if (!temporary_set) {
1563                 if (!do_getqdelay_scf(&qctrl.aq_delay)) {
1564                         exit_error(gettext("Could not get configured value."));
1565                 }
1566 
1567                 if (qctrl.aq_delay == 0) {
1568                         (void) printf(gettext(
1569                             "no configured audit queue delay\n"));
1570                 } else {
1571                         (void) printf(gettext("configured audit queue "
1572                             "delay (ticks) = %ld\n"), qctrl.aq_delay);
1573                 }
1574         }
1575 
1576         eauditon(A_GETQCTRL, (caddr_t)&qctrl, 0);
1577         (void) printf(gettext("active audit queue delay (ticks) = %ld\n"),
1578             qctrl.aq_delay);
1579 }
1580 
1581 /*
1582  * do_getqhiwater() - print, relative to the current zone, the high water
1583  * point in undelivered audit records when audit generation will block.
1584  */
1585 static void
1586 do_getqhiwater(void)
1587 {
1588         struct au_qctrl qctrl;
1589 
1590         if (!temporary_set) {
1591                 if (!do_getqhiwater_scf(&qctrl.aq_hiwater)) {
1592                         exit_error(gettext("Could not get configured value."));
1593                 }
1594 
1595                 if (qctrl.aq_hiwater == 0) {
1596                         (void) printf(gettext(
1597                             "no configured audit queue hiwater mark\n"));
1598                 } else {
1599                         (void) printf(gettext("configured audit queue "
1600                             "hiwater mark (records) = %d\n"), qctrl.aq_hiwater);
1601                 }
1602         }
1603 
1604         eauditon(A_GETQCTRL, (caddr_t)&qctrl, 0);
1605         (void) printf(gettext("active audit queue hiwater mark "
1606             "(records) = %d\n"), qctrl.aq_hiwater);
1607 }
1608 
1609 /*
1610  * do_getqlowater() - print, relative to the current zone, the low water point
1611  * in undelivered audit records where blocked processes will resume.
1612  */
1613 static void
1614 do_getqlowater(void)
1615 {
1616         struct au_qctrl qctrl;
1617 
1618         if (!temporary_set) {
1619                 if (!do_getqlowater_scf(&qctrl.aq_lowater)) {
1620                         exit_error(gettext("Could not get configured value."));
1621                 }
1622 
1623                 if (qctrl.aq_lowater == 0) {
1624                         (void) printf(gettext(
1625                             "no configured audit queue lowater mark\n"));
1626                 } else {
1627                         (void) printf(gettext("configured audit queue "
1628                             "lowater mark (records) = %d\n"), qctrl.aq_lowater);
1629                 }
1630         }
1631 
1632         eauditon(A_GETQCTRL, (caddr_t)&qctrl, 0);
1633         (void) printf(gettext("active audit queue lowater mark "
1634             "(records) = %d\n"), qctrl.aq_lowater);
1635 }
1636 
1637 /*
1638  * do_getasid() - print out the audit session-ID.
1639  */
1640 static void
1641 do_getasid(void)
1642 {
1643         auditinfo_addr_t ai;
1644 
1645         if (getaudit_addr(&ai, sizeof (ai))) {
1646                 exit_error(gettext("getaudit_addr(2) failed"));
1647         }
1648         print_asid(ai.ai_asid);
1649 }
1650 
1651 /*
1652  * do_getstat() - the printed statistics are for the entire system unless
1653  * AUDIT_PERZONE is set.
1654  */
1655 static void
1656 do_getstat(void)
1657 {
1658         au_stat_t as;
1659         int offset[12];   /* used to line the header up correctly */
1660         char buf[512];
1661 
1662         eauditon(A_GETSTAT, (caddr_t)&as, 0);
1663         (void) sprintf(buf, "%4lu %n%4lu %n%4lu %n%4lu %n%4lu %n%4lu %n%4lu "
1664             "%n%4lu %n%4lu %n%4lu %n%4lu %n%4lu%n",
1665             (ulong_t)as.as_generated,   &(offset[0]),
1666             (ulong_t)as.as_nonattrib,   &(offset[1]),
1667             (ulong_t)as.as_kernel,      &(offset[2]),
1668             (ulong_t)as.as_audit,       &(offset[3]),
1669             (ulong_t)as.as_auditctl,    &(offset[4]),
1670             (ulong_t)as.as_enqueue,     &(offset[5]),
1671             (ulong_t)as.as_written,     &(offset[6]),
1672             (ulong_t)as.as_wblocked,    &(offset[7]),
1673             (ulong_t)as.as_rblocked,    &(offset[8]),
1674             (ulong_t)as.as_dropped,     &(offset[9]),
1675             (ulong_t)as.as_totalsize / ONEK, &(offset[10]),
1676             (ulong_t)as.as_memused / ONEK, &(offset[11]));
1677 
1678         /*
1679          * TRANSLATION_NOTE
1680          *      Print a properly aligned header.
1681          */
1682         (void) printf("%*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s\n",
1683             offset[0] - 1,              gettext("gen"),
1684             offset[1] - offset[0] -1,   gettext("nona"),
1685             offset[2] - offset[1] -1,   gettext("kern"),
1686             offset[3] - offset[2] -1,   gettext("aud"),
1687             offset[4] - offset[3] -1,   gettext("ctl"),
1688             offset[5] - offset[4] -1,   gettext("enq"),
1689             offset[6] - offset[5] -1,   gettext("wrtn"),
1690             offset[7] - offset[6] -1,   gettext("wblk"),
1691             offset[8] - offset[7] -1,   gettext("rblk"),
1692             offset[9] - offset[8] -1,   gettext("drop"),
1693             offset[10] - offset[9] -1,  gettext("tot"),
1694             offset[11] - offset[10],    gettext("mem"));
1695 
1696         (void) printf("%s\n", buf);
1697 }
1698 
1699 /*
1700  * do_gettermid() - print audit terminal ID for current process.
1701  */
1702 static void
1703 do_gettermid(void)
1704 {
1705         auditinfo_addr_t ai;
1706 
1707         if (getaudit_addr(&ai, sizeof (ai))) {
1708                 exit_error(gettext("getaudit_addr(2) failed"));
1709         }
1710         print_tid_ex(&ai.ai_termid);
1711 }
1712 
1713 /*
1714  * do_lsevent() - display the active kernel and user level audit event
1715  * information. The printed events are for the global zone unless AUDIT_PERZONE
1716  * is set.
1717  */
1718 static void
1719 do_lsevent(void)
1720 {
1721         register au_event_ent_t *evp;
1722         au_mask_t pmask;
1723         char auflags[256];
1724 
1725         setauevent();
1726         if (getauevent() == NULL) {
1727                 exit_error(gettext("NO AUDIT EVENTS: Could not read %s\n."),
1728                     AUDITEVENTFILE);
1729         }
1730 
1731         setauevent();
1732         while ((evp = getauevent()) != NULL) {
1733                 pmask.am_success = pmask.am_failure = evp->ae_class;
1734                 if (getauditflagschar(auflags, &pmask, 0) == -1)
1735                         (void) strcpy(auflags, "unknown");
1736                 (void) printf("%-30s %5hu %s %s\n",
1737                     evp->ae_name, evp->ae_number, auflags, evp->ae_desc);
1738         }
1739         endauevent();
1740 }
1741 
1742 /*
1743  * do_lspolicy() - display the kernel audit policies with a description  of each
1744  * policy. The printed value is for the global zone unless AUDIT_PERZONE is set.
1745  */
1746 static void
1747 do_lspolicy(void)
1748 {
1749         int i;
1750 
1751         /*
1752          * TRANSLATION_NOTE
1753          *      Print a properly aligned header.
1754          */
1755         (void) printf(gettext("policy string    description:\n"));
1756         for (i = 0; i < POLICY_TBL_SZ; i++) {
1757                 (void) printf("%-17s%s\n", policy_table[i].policy_str,
1758                     gettext(policy_table[i].policy_desc));
1759         }
1760 }
1761 
1762 /*
1763  * do_setasid() - execute shell or cmd with specified session-ID.
1764  */
1765 static void
1766 do_setasid(char *sid_str, char **argv)
1767 {
1768         struct auditinfo_addr ai;
1769 
1770         if (getaudit_addr(&ai, sizeof (ai))) {
1771                 exit_error(gettext("getaudit_addr(2) failed"));
1772         }
1773         ai.ai_asid = (au_asid_t)atol(sid_str);
1774         if (setaudit_addr(&ai, sizeof (ai))) {
1775                 exit_error(gettext("setaudit_addr(2) failed"));
1776         }
1777         execit(argv);
1778 }
1779 
1780 /*
1781  * do_setaudit() - execute shell or cmd with specified audit characteristics.
1782  */
1783 static void
1784 do_setaudit(char *user_str, char *mask_str, char *tid_str, char *sid_str,
1785     char **argv)
1786 {
1787         auditinfo_addr_t ai;
1788 
1789         ai.ai_auid = (au_id_t)get_user_id(user_str);
1790         egetauditflagsbin(mask_str, &ai.ai_mask),
1791             str2tid(tid_str, &ai.ai_termid);
1792         ai.ai_asid = (au_asid_t)atol(sid_str);
1793 
1794         esetaudit(&ai, sizeof (ai));
1795         execit(argv);
1796 }
1797 
1798 /*
1799  * do_setauid() - execute shell or cmd with specified audit-ID.
1800  */
1801 static void
1802 do_setauid(char *user, char **argv)
1803 {
1804         au_id_t auid;
1805 
1806         auid = get_user_id(user);
1807         esetauid(&auid);
1808         execit(argv);
1809 }
1810 
1811 /*
1812  * do_setpmask() - set the preselection mask of the specified process; valid
1813  * per zone if AUDIT_PERZONE is set, else only in global zone.
1814  */
1815 static void
1816 do_setpmask(char *pid_str, au_mask_t *mask)
1817 {
1818         struct auditpinfo ap;
1819 
1820         if (strisnum(pid_str)) {
1821                 ap.ap_pid = (pid_t)atoi(pid_str);
1822         } else {
1823                 exit_usage(1);
1824         }
1825 
1826         ap.ap_mask.am_success = mask->am_success;
1827         ap.ap_mask.am_failure = mask->am_failure;
1828 
1829         eauditon(A_SETPMASK, (caddr_t)&ap, sizeof (ap));
1830 }
1831 
1832 /*
1833  * do_setsmask() - set the preselection mask of all processes with the specified
1834  * audit session-ID; valid per zone if AUDIT_PERZONE is set, else only in global
1835  * zone.
1836  */
1837 static void
1838 do_setsmask(char *asid_str, au_mask_t *mask)
1839 {
1840         struct auditinfo ainfo;
1841 
1842         if (strisnum(asid_str)) {
1843                 ainfo.ai_asid = (au_asid_t)atoi(asid_str);
1844         } else {
1845                 exit_usage(1);
1846         }
1847 
1848         ainfo.ai_mask.am_success = mask->am_success;
1849         ainfo.ai_mask.am_failure = mask->am_failure;
1850 
1851         eauditon(A_SETSMASK, (caddr_t)&ainfo, sizeof (ainfo));
1852 }
1853 
1854 /*
1855  * do_setumask() -  set the preselection mask of all processes with the
1856  * specified audit-ID; valid per zone if AUDIT_PERZONE is set, else only in
1857  * global zone.
1858  */
1859 static void
1860 do_setumask(char *auid_str, au_mask_t *mask)
1861 {
1862         struct auditinfo ainfo;
1863 
1864         if (strisnum(auid_str)) {
1865                 ainfo.ai_auid = (au_id_t)atoi(auid_str);
1866         } else {
1867                 exit_usage(1);
1868         }
1869 
1870         ainfo.ai_mask.am_success = mask->am_success;
1871         ainfo.ai_mask.am_failure = mask->am_failure;
1872 
1873         eauditon(A_SETUMASK, (caddr_t)&ainfo, sizeof (ainfo));
1874 }
1875 
1876 /*
1877  * do_setstat() - reset audit statistics counters; local zone use is valid if
1878  * AUDIT_PERZONE is set, otherwise the syscall returns EPERM.
1879  */
1880 static void
1881 do_setstat(void)
1882 {
1883         au_stat_t as;
1884 
1885         as.as_audit     = (uint_t)-1;
1886         as.as_auditctl  = (uint_t)-1;
1887         as.as_dropped   = (uint_t)-1;
1888         as.as_enqueue   = (uint_t)-1;
1889         as.as_generated = (uint_t)-1;
1890         as.as_kernel    = (uint_t)-1;
1891         as.as_nonattrib = (uint_t)-1;
1892         as.as_rblocked  = (uint_t)-1;
1893         as.as_totalsize = (uint_t)-1;
1894         as.as_wblocked  = (uint_t)-1;
1895         as.as_written   = (uint_t)-1;
1896 
1897         eauditon(A_SETSTAT, (caddr_t)&as, sizeof (as));
1898         (void) printf("%s\n", gettext("audit stats reset"));
1899 }
1900 
1901 /*
1902  * do_setclass() - map the kernel event event_str to the classes specified by
1903  * audit flags (mask); valid per zone if AUDIT_PERZONE is set, else only in
1904  * global zone.
1905  */
1906 static void
1907 do_setclass(char *event_str, au_mask_t *mask)
1908 {
1909         au_event_t event;
1910         au_evclass_map_t ec;
1911         au_event_ent_t *evp;
1912 
1913         if (strisnum(event_str)) {
1914                 event = (uint_t)atol(event_str);
1915         } else {
1916                 if ((evp = egetauevnam(event_str)) != NULL) {
1917                         event = evp->ae_number;
1918                 }
1919         }
1920 
1921         ec.ec_number = event;
1922         ec.ec_class = (mask->am_success | mask->am_failure);
1923 
1924         eauditon(A_SETCLASS, (caddr_t)&ec, sizeof (ec));
1925 }
1926 
1927 /*
1928  * do_setflags() - set configured and active default user preselection masks;
1929  * valid per zone if AUDIT_PERZONE is set, else only in global zone.
1930  */
1931 static void
1932 do_setflags(char *audit_flags, au_mask_t *amask)
1933 {
1934         eauditon(A_SETAMASK, (caddr_t)amask, sizeof (*amask));
1935 
1936         if (!do_setflags_scf(audit_flags)) {
1937                 print_mask(gettext("active user default audit flags"), amask);
1938                 exit_error(gettext("Could not store configuration value."));
1939         }
1940         print_mask(gettext("user default audit flags"), amask);
1941 }
1942 
1943 /*
1944  * do_setkmask() - set non-attributable audit flags of machine; valid per zone
1945  * if AUDIT_PERZONE is set, else only in global zone.
1946  */
1947 static void
1948 do_setkmask(au_mask_t *pmask)
1949 {
1950         eauditon(A_SETKMASK, (caddr_t)pmask, sizeof (*pmask));
1951         print_mask(gettext("active non-attributable audit flags"), pmask);
1952 }
1953 
1954 /*
1955  * do_setnaflags() - set configured and active non-attributable selection flags
1956  * of machine; valid per zone if AUDIT_PERZONE is set, else only in global zone.
1957  */
1958 static void
1959 do_setnaflags(char *audit_naflags, au_mask_t *namask)
1960 {
1961         eauditon(A_SETKMASK, (caddr_t)namask, sizeof (*namask));
1962 
1963         if (!do_setnaflags_scf(audit_naflags)) {
1964                 print_mask(
1965                     gettext("active non-attributable audit flags"), namask);
1966                 exit_error(gettext("Could not store configuration value."));
1967         }
1968         print_mask(gettext("non-attributable audit flags"), namask);
1969 }
1970 
1971 /*
1972  * do_setplugin() - set the given plugin plugin_str configuration values.
1973  */
1974 static void
1975 do_setplugin(char *plugin_str, boolean_t plugin_state, char *plugin_attr,
1976     int plugin_qsize)
1977 {
1978         if (!do_setpluginconfig_scf(plugin_str, plugin_state, plugin_attr,
1979             plugin_qsize)) {
1980                 exit_error(gettext("Could not set plugin configuration."));
1981         }
1982 }
1983 
1984 /*
1985  * do_setpolicy() - set the active and configured kernel audit policy; active
1986  * values can be changed per zone if AUDIT_PERZONE is set, else only in global
1987  * zone.
1988  *
1989  * ahlt and perzone are global zone only. The kernel ensures that a local zone
1990  * can't change ahlt and perzone (EINVAL).
1991  */
1992 static void
1993 do_setpolicy(char *policy_str)
1994 {
1995         uint32_t        policy = 0;
1996 
1997         switch (str2policy(policy_str, &policy)) {
1998         case 0:
1999                 if (!temporary_set) {
2000                         if (!do_getpolicy_scf(&policy)) {
2001                                 exit_error(gettext("Unable to get current "
2002                                     "policy values from the SMF repository"));
2003                         }
2004                         (void) str2policy(policy_str, &policy);
2005 
2006                         if (!do_setpolicy_scf(policy)) {
2007                                 exit_error(gettext("Could not store "
2008                                     "configuration values."));
2009                         }
2010                 }
2011                 eauditon(A_SETPOLICY, (caddr_t)&policy, 0);
2012                 break;
2013         case 2:
2014                 exit_error(gettext("policy (%s) invalid in a local zone."),
2015                     policy_str);
2016                 break;
2017         default:
2018                 exit_error(gettext("Invalid policy (%s) specified."),
2019                     policy_str);
2020                 break;
2021         }
2022 }
2023 
2024 /*
2025  * do_setqbufsz() - set the active and configured audit queue write buffer size
2026  * (bytes); active values can be changed per zone if AUDIT_PERZONE is set, else
2027  * only in global zone.
2028  */
2029 static void
2030 do_setqbufsz(char *bufsz)
2031 {
2032         struct au_qctrl qctrl;
2033 
2034         if (!temporary_set) {
2035                 qctrl.aq_bufsz = (size_t)atol(bufsz);
2036                 if (!do_setqbufsz_scf(&qctrl.aq_bufsz)) {
2037                         exit_error(gettext(
2038                             "Could not store configuration value."));
2039                 }
2040                 if (qctrl.aq_bufsz == 0) {
2041                         return;
2042                 }
2043         }
2044 
2045         eauditon(A_GETQCTRL, (caddr_t)&qctrl, 0);
2046         qctrl.aq_bufsz = (size_t)atol(bufsz);
2047         eauditon(A_SETQCTRL, (caddr_t)&qctrl, 0);
2048 }
2049 
2050 /*
2051  * do_setqctrl() - set the active and configured audit queue write buffer size
2052  * (bytes), hiwater audit record count, lowater audit record count, and wakeup
2053  * interval (ticks); active values can be changed per zone if AUDIT_PERZONE is
2054  * set, else only in global zone.
2055  */
2056 static void
2057 do_setqctrl(char *hiwater, char *lowater, char *bufsz, char *delay)
2058 {
2059         struct au_qctrl qctrl;
2060 
2061         qctrl.aq_hiwater = (size_t)atol(hiwater);
2062         qctrl.aq_lowater = (size_t)atol(lowater);
2063         qctrl.aq_bufsz = (size_t)atol(bufsz);
2064         qctrl.aq_delay = (clock_t)atol(delay);
2065 
2066         if (!temporary_set) {
2067                 struct au_qctrl qctrl_act;
2068 
2069                 if (!do_setqctrl_scf(&qctrl)) {
2070                         exit_error(gettext(
2071                             "Could not store configuration values."));
2072                 }
2073 
2074                 eauditon(A_GETQCTRL, (caddr_t)&qctrl_act, 0);
2075                 if (qctrl.aq_hiwater == 0) {
2076                         qctrl.aq_hiwater = qctrl_act.aq_hiwater;
2077                 }
2078                 if (qctrl.aq_lowater == 0) {
2079                         qctrl.aq_lowater = qctrl_act.aq_lowater;
2080                 }
2081                 if (qctrl.aq_bufsz == 0) {
2082                         qctrl.aq_bufsz = qctrl_act.aq_bufsz;
2083                 }
2084                 if (qctrl.aq_delay == 0) {
2085                         qctrl.aq_delay = qctrl_act.aq_delay;
2086                 }
2087         }
2088 
2089         eauditon(A_SETQCTRL, (caddr_t)&qctrl, 0);
2090 }
2091 
2092 /*
2093  * do_setqdelay() - set the active and configured audit queue wakeup interval
2094  * (ticks); active values can be changed per zone if AUDIT_PERZONE is set, else
2095  * only in global zone.
2096  */
2097 static void
2098 do_setqdelay(char *delay)
2099 {
2100         struct au_qctrl qctrl;
2101 
2102         if (!temporary_set) {
2103                 qctrl.aq_delay = (clock_t)atol(delay);
2104                 if (!do_setqdelay_scf(&qctrl.aq_delay)) {
2105                         exit_error(gettext(
2106                             "Could not store configuration value."));
2107                 }
2108                 if (qctrl.aq_delay == 0) {
2109                         return;
2110                 }
2111         }
2112 
2113         eauditon(A_GETQCTRL, (caddr_t)&qctrl, 0);
2114         qctrl.aq_delay = (clock_t)atol(delay);
2115         eauditon(A_SETQCTRL, (caddr_t)&qctrl, 0);
2116 }
2117 
2118 /*
2119  * do_setqhiwater() - sets the active and configured number of undelivered audit
2120  * records in the audit queue at which audit record generation blocks; active
2121  * values can be changed per zone if AUDIT_PERZONE is set, else only in global
2122  * zone.
2123  */
2124 static void
2125 do_setqhiwater(char *hiwater)
2126 {
2127         struct au_qctrl qctrl;
2128 
2129         if (!temporary_set) {
2130                 qctrl.aq_hiwater = (size_t)atol(hiwater);
2131                 if (!do_setqhiwater_scf(&qctrl.aq_hiwater)) {
2132                         exit_error(gettext(
2133                             "Could not store configuration value."));
2134                 }
2135                 if (qctrl.aq_hiwater == 0) {
2136                         return;
2137                 }
2138         }
2139 
2140         eauditon(A_GETQCTRL, (caddr_t)&qctrl, 0);
2141         qctrl.aq_hiwater = (size_t)atol(hiwater);
2142         eauditon(A_SETQCTRL, (caddr_t)&qctrl, 0);
2143 }
2144 
2145 /*
2146  * do_setqlowater() - set the active and configured number of undelivered audit
2147  * records in the audit queue at which blocked auditing processes unblock;
2148  * active values can be changed per zone if AUDIT_PERZONE is set, else only in
2149  * global zone.
2150  */
2151 static void
2152 do_setqlowater(char *lowater)
2153 {
2154         struct au_qctrl qctrl;
2155 
2156         if (!temporary_set) {
2157                 qctrl.aq_lowater = (size_t)atol(lowater);
2158                 if (!do_setqlowater_scf(&qctrl.aq_lowater)) {
2159                         exit_error(gettext(
2160                             "Could not store configuration value."));
2161                 }
2162                 if (qctrl.aq_lowater == 0) {
2163                         return;
2164                 }
2165         }
2166 
2167         eauditon(A_GETQCTRL, (caddr_t)&qctrl, 0);
2168         qctrl.aq_lowater = (size_t)atol(lowater);
2169         eauditon(A_SETQCTRL, (caddr_t)&qctrl, 0);
2170 }
2171 
2172 static void
2173 eauditon(int cmd, caddr_t data, int length)
2174 {
2175         if (auditon(cmd, data, length) == -1)
2176                 exit_error(gettext("auditon(2) failed."));
2177 }
2178 
2179 static void
2180 egetauid(au_id_t *auid)
2181 {
2182         if (getauid(auid) == -1)
2183                 exit_error(gettext("getauid(2) failed."));
2184 }
2185 
2186 static void
2187 egetaudit(auditinfo_addr_t *ai, int size)
2188 {
2189         if (getaudit_addr(ai, size) == -1)
2190                 exit_error(gettext("getaudit_addr(2) failed."));
2191 }
2192 
2193 static void
2194 egetkaudit(auditinfo_addr_t *ai, int size)
2195 {
2196         if (auditon(A_GETKAUDIT, (char *)ai, size) < 0)
2197                 exit_error(gettext("auditon: A_GETKAUDIT failed."));
2198 }
2199 
2200 static void
2201 esetkaudit(auditinfo_addr_t *ai, int size)
2202 {
2203         if (auditon(A_SETKAUDIT, (char *)ai, size) < 0)
2204                 exit_error(gettext("auditon: A_SETKAUDIT failed."));
2205 }
2206 
2207 static void
2208 egetauditflagsbin(char *auditflags, au_mask_t *pmask)
2209 {
2210         if (strcmp(auditflags, "none") == 0) {
2211                 pmask->am_success = pmask->am_failure = 0;
2212                 return;
2213         }
2214 
2215         if (getauditflagsbin(auditflags, pmask) < 0) {
2216                 exit_error(gettext("Could not get audit flags (%s)"),
2217                     auditflags);
2218         }
2219 }
2220 
2221 static void
2222 echkflags(char *auditflags, au_mask_t *mask)
2223 {
2224         char            *err = "";
2225         char            *err_ptr;
2226 
2227         if (!__chkflags(auditflags, mask, B_FALSE, &err)) {
2228                 err_ptr = err;
2229                 while (*err_ptr != ',' && *err_ptr != '\0') {
2230                         err_ptr++;
2231                 }
2232                 *err_ptr = '\0';
2233                 exit_error(gettext("Unknown audit flags and/or prefixes "
2234                     "encountered: %s"), err);
2235         }
2236 }
2237 
2238 static au_event_ent_t *
2239 egetauevnum(au_event_t event_number)
2240 {
2241         au_event_ent_t *evp;
2242 
2243         if ((evp = getauevnum(event_number)) == NULL) {
2244                 exit_error(gettext("Could not get audit event %hu"),
2245                     event_number);
2246         }
2247 
2248         return (evp);
2249 }
2250 
2251 static au_event_ent_t *
2252 egetauevnam(char *event_name)
2253 {
2254         register au_event_ent_t *evp;
2255 
2256         if ((evp = getauevnam(event_name)) == NULL)
2257                 exit_error(gettext("Could not get audit event %s"), event_name);
2258 
2259         return (evp);
2260 }
2261 
2262 static void
2263 esetauid(au_id_t *auid)
2264 {
2265         if (setauid(auid) == -1)
2266                 exit_error(gettext("setauid(2) failed."));
2267 }
2268 
2269 static void
2270 esetaudit(auditinfo_addr_t *ai, int size)
2271 {
2272         if (setaudit_addr(ai, size) == -1)
2273                 exit_error(gettext("setaudit_addr(2) failed."));
2274 }
2275 
2276 static uid_t
2277 get_user_id(char *user)
2278 {
2279         struct passwd *pwd;
2280         uid_t uid;
2281 
2282         if (isdigit(*user)) {
2283                 uid = atoi(user);
2284                 if ((pwd = getpwuid(uid)) == NULL) {
2285                         exit_error(gettext("Invalid user: %s"), user);
2286                 }
2287         } else {
2288                 if ((pwd = getpwnam(user)) == NULL) {
2289                         exit_error(gettext("Invalid user: %s"), user);
2290                 }
2291         }
2292 
2293         return (pwd->pw_uid);
2294 }
2295 
2296 /*
2297  * get_arg_ent()
2298  *     Inputs: command line argument string
2299  *     Returns ptr to struct arg_entry if found; null, if not found
2300  */
2301 static arg_entry_t *
2302 get_arg_ent(char *arg_str)
2303 {
2304         arg_entry_t key;
2305 
2306         key.arg_str = arg_str;
2307 
2308         return ((arg_entry_t *)bsearch((char *)&key, (char *)arg_table,
2309             ARG_TBL_SZ, sizeof (arg_entry_t), arg_ent_compare));
2310 }
2311 
2312 /*
2313  * arg_ent_compare()
2314  *     Compares two command line arguments to determine which is
2315  *       lexicographically greater.
2316  *     Inputs: two argument map table entry pointers
2317  *     Returns: > 1: aep1->arg_str > aep2->arg_str
2318  *              < 1: aep1->arg_str < aep2->arg_str
2319  *                0: aep1->arg_str = aep->arg_str2
2320  */
2321 static int
2322 arg_ent_compare(const void *aep1, const void *aep2)
2323 {
2324         return (strcmp(((arg_entry_t *)aep1)->arg_str,
2325             ((arg_entry_t *)aep2)->arg_str));
2326 }
2327 
2328 /*
2329  * tid_str is major,minor,host  -- host is a name or an ip address
2330  */
2331 static void
2332 str2tid(char *tid_str, au_tid_addr_t *tp)
2333 {
2334         char *major_str;
2335         char *minor_str;
2336         char *host_str = NULL;
2337         major_t major = 0;
2338         major_t minor = 0;
2339         dev_t dev = 0;
2340         struct hostent *phe;
2341         int err;
2342         uint32_t ibuf;
2343         uint32_t ibuf6[4];
2344 
2345         tp->at_port = 0;
2346         tp->at_type = 0;
2347         bzero(tp->at_addr, 16);
2348 
2349         major_str = tid_str;
2350         if ((minor_str = strchr(tid_str, ',')) != NULL) {
2351                 *minor_str = '\0';
2352                 minor_str++;
2353         }
2354 
2355         if (minor_str) {
2356                 if ((host_str = strchr(minor_str, ',')) != NULL) {
2357                         *host_str = '\0';
2358                         host_str++;
2359                 }
2360         }
2361 
2362         if (major_str)
2363                 major = (major_t)atoi(major_str);
2364 
2365         if (minor_str)
2366                 minor = (minor_t)atoi(minor_str);
2367 
2368         if ((dev = makedev(major, minor)) != NODEV)
2369                 tp->at_port = dev;
2370 
2371         if (host_str) {
2372                 if (strisipaddr(host_str)) {
2373                         if (inet_pton(AF_INET, host_str, &ibuf)) {
2374                                 tp->at_addr[0] = ibuf;
2375                                 tp->at_type = AU_IPv4;
2376                         } else if (inet_pton(AF_INET6, host_str, ibuf6)) {
2377                                 tp->at_addr[0] = ibuf6[0];
2378                                 tp->at_addr[1] = ibuf6[1];
2379                                 tp->at_addr[2] = ibuf6[2];
2380                                 tp->at_addr[3] = ibuf6[3];
2381                                 tp->at_type = AU_IPv6;
2382                         }
2383                 } else {
2384                         phe = getipnodebyname((const void *)host_str,
2385                             AF_INET, 0, &err);
2386                         if (phe == 0) {
2387                                 phe = getipnodebyname((const void *)host_str,
2388                                     AF_INET6, 0, &err);
2389                         }
2390 
2391                         if (phe != NULL) {
2392                                 if (phe->h_addrtype == AF_INET6) {
2393                                         /* address is IPv6 (128 bits) */
2394                                         (void) memcpy(&tp->at_addr[0],
2395                                             phe->h_addr_list[0], 16);
2396                                         tp->at_type = AU_IPv6;
2397                                 } else {
2398                                         /* address is IPv4 (32 bits) */
2399                                         (void) memcpy(&tp->at_addr[0],
2400                                             phe->h_addr_list[0], 4);
2401                                         tp->at_type = AU_IPv4;
2402                                 }
2403                                 freehostent(phe);
2404                         }
2405                 }
2406         }
2407 }
2408 
2409 static char *
2410 cond2str(void)
2411 {
2412         uint_t cond;
2413 
2414         eauditon(A_GETCOND, (caddr_t)&cond, sizeof (cond));
2415 
2416         switch (cond) {
2417 
2418         case AUC_AUDITING:
2419                 return ("auditing");
2420 
2421         case AUC_NOAUDIT:
2422         case AUC_INIT_AUDIT:
2423                 return ("noaudit");
2424 
2425         case AUC_UNSET:
2426                 return ("unset");
2427 
2428         case AUC_NOSPACE:
2429                 return ("nospace");
2430 
2431         default:
2432                 return ("");
2433         }
2434 }
2435 
2436 /*
2437  *      exit = 0, success
2438  *             1, error
2439  *             2, bad zone
2440  */
2441 static int
2442 str2policy(char *policy_str, uint32_t *policy_mask)
2443 {
2444         char            *buf;
2445         char            *tok;
2446         char            pfix;
2447         boolean_t       is_all = B_FALSE;
2448         uint32_t        pm = 0;
2449         uint32_t        curp;
2450 
2451         pfix = *policy_str;
2452 
2453         if (pfix == '-' || pfix == '+' || pfix == '=')
2454                 ++policy_str;
2455 
2456         if ((buf = strdup(policy_str)) == NULL)
2457                 return (1);
2458 
2459         for (tok = strtok(buf, ","); tok != NULL; tok = strtok(NULL, ",")) {
2460                 uint32_t tok_pm;
2461                 if (((tok_pm = get_policy(tok)) == 0) &&
2462                     ((strcasecmp(tok, "none") != 0))) {
2463                         free(buf);
2464                         return (1);
2465                 } else {
2466                         pm |= tok_pm;
2467                         if (tok_pm == ALL_POLICIES) {
2468                                 is_all = B_TRUE;
2469                         }
2470                 }
2471         }
2472         free(buf);
2473 
2474         /* reuse policy mask if already set to some value */
2475         if (*policy_mask != 0) {
2476                 curp = *policy_mask;
2477         } else {
2478                 (void) auditon(A_GETPOLICY, (caddr_t)&curp, 0);
2479         }
2480 
2481         if (pfix == '-') {
2482                 if (!is_all &&
2483                     (getzoneid() != GLOBAL_ZONEID) &&
2484                     (pm & ~AUDIT_LOCAL)) {
2485                         return (2);
2486                 }
2487 
2488                 if (getzoneid() != GLOBAL_ZONEID)
2489                         curp &= AUDIT_LOCAL;
2490                 *policy_mask = curp & ~pm;
2491 
2492         } else if (pfix == '+') {
2493                 /*
2494                  * In a local zone, accept specifying "all", but not
2495                  * individually specifying global-zone only policies.
2496                  * Limit to all locally allowed, so system call doesn't
2497                  * fail.
2498                  */
2499                 if (!is_all &&
2500                     (getzoneid() != GLOBAL_ZONEID) &&
2501                     (pm & ~AUDIT_LOCAL)) {
2502                         return (2);
2503                 }
2504 
2505                 if (getzoneid() != GLOBAL_ZONEID) {
2506                         curp &= AUDIT_LOCAL;
2507                         if (is_all) {
2508                                 pm &= AUDIT_LOCAL;
2509                         }
2510                 }
2511                 *policy_mask = curp | pm;
2512 
2513         } else {
2514                 /*
2515                  * In a local zone, accept specifying "all", but not
2516                  * individually specifying global-zone only policies.
2517                  * Limit to all locally allowed, so system call doesn't
2518                  * fail.
2519                  */
2520                 if (!is_all &&
2521                     (getzoneid() != GLOBAL_ZONEID) &&
2522                     (pm & ~AUDIT_LOCAL)) {
2523                         return (2);
2524                 }
2525 
2526                 if (is_all && (getzoneid() != GLOBAL_ZONEID)) {
2527                         pm &= AUDIT_LOCAL;
2528                 }
2529                 *policy_mask = pm;
2530         }
2531         return (0);
2532 }
2533 
2534 static int
2535 policy2str(uint32_t policy, char *policy_str, size_t len)
2536 {
2537         int i, j;
2538 
2539         if (policy == ALL_POLICIES) {
2540                 (void) strcpy(policy_str, "all");
2541                 return (1);
2542         }
2543 
2544         if (policy == NO_POLICIES) {
2545                 (void) strcpy(policy_str, "none");
2546                 return (1);
2547         }
2548 
2549         *policy_str = '\0';
2550 
2551         for (i = 0, j = 0; i < POLICY_TBL_SZ; i++) {
2552                 if (policy & policy_table[i].policy_mask &&
2553                     policy_table[i].policy_mask != ALL_POLICIES) {
2554                         if (j++) {
2555                                 (void) strcat(policy_str, ",");
2556                         }
2557                         (void) strlcat(policy_str, policy_table[i].policy_str,
2558                             len);
2559                 }
2560         }
2561 
2562         if (*policy_str)
2563                 return (0);
2564 
2565         return (1);
2566 }
2567 
2568 
2569 static int
2570 strisnum(char *s)
2571 {
2572         if (s == NULL || !*s)
2573                 return (0);
2574 
2575         for (; *s == '-' || *s == '+'; s++)
2576 
2577         if (!*s)
2578                 return (0);
2579 
2580         for (; *s; s++)
2581                 if (!isdigit(*s))
2582                         return (0);
2583 
2584         return (1);
2585 }
2586 
2587 static int
2588 strisipaddr(char *s)
2589 {
2590         int dot = 0;
2591         int colon = 0;
2592 
2593         /* no string */
2594         if ((s == NULL) || (!*s))
2595                 return (0);
2596 
2597         for (; *s; s++) {
2598                 if (!(isxdigit(*s) || *s != '.' || *s != ':'))
2599                         return (0);
2600                 if (*s == '.')
2601                         dot++;
2602                 if (*s == ':')
2603                         colon++;
2604         }
2605 
2606         if (dot && colon)
2607                 return (0);
2608 
2609         if (!dot && !colon)
2610                 return (0);
2611 
2612         return (1);
2613 }
2614 
2615 static void
2616 chk_arg_len(char *argv, uint_t len)
2617 {
2618         if ((strlen(argv) + 1) > len) {
2619                 *(argv + len - 1) = '\0';
2620                 exit_error(gettext("Argument too long (%s..)."), argv);
2621         }
2622 }
2623 
2624 static void
2625 chk_event_num(int etype, au_event_t event)
2626 {
2627         au_stat_t as;
2628 
2629         eauditon(A_GETSTAT, (caddr_t)&as, 0);
2630 
2631         if (etype == AC_KERN_EVENT) {
2632                 if (event > as.as_numevent) {
2633                         exit_error(gettext(
2634                             "Invalid kernel audit event number specified.\n"
2635                             "\t%hu is outside allowable range 0-%d."),
2636                             event, as.as_numevent);
2637                 }
2638         } else  {
2639                 /* user event */
2640                 if (event <= as.as_numevent) {
2641                         exit_error(gettext("Invalid user level audit event "
2642                             "number specified %hu."), event);
2643                 }
2644         }
2645 }
2646 
2647 static void
2648 chk_event_str(int etype, char *event_str)
2649 {
2650         au_event_ent_t *evp;
2651         au_stat_t as;
2652 
2653         eauditon(A_GETSTAT, (caddr_t)&as, 0);
2654 
2655         evp = egetauevnam(event_str);
2656         if (etype == AC_KERN_EVENT && (evp->ae_number > as.as_numevent)) {
2657                 exit_error(gettext(
2658                     "Invalid kernel audit event string specified.\n"
2659                     "\t\"%s\" appears to be a user level event. "
2660                     "Check configuration."), event_str);
2661         } else if (etype == AC_USER_EVENT &&
2662             (evp->ae_number < as.as_numevent)) {
2663                 exit_error(gettext(
2664                     "Invalid user audit event string specified.\n"
2665                     "\t\"%s\" appears to be a kernel event. "
2666                     "Check configuration."), event_str);
2667         }
2668 }
2669 
2670 static void
2671 chk_known_plugin(char *plugin_str)
2672 {
2673         if ((strlen(plugin_str) + 1) > PLUGIN_MAXBUF) {
2674                 exit_error(gettext("Plugin name too long.\n"));
2675         }
2676 
2677         if (!plugin_avail_scf(plugin_str)) {
2678                 exit_error(gettext("No such plugin configured: %s"),
2679                     plugin_str);
2680         }
2681 }
2682 
2683 static void
2684 chk_sorf(char *sorf_str)
2685 {
2686         if (!strisnum(sorf_str))
2687                 exit_error(gettext("Invalid sorf specified: %s"), sorf_str);
2688 }
2689 
2690 static void
2691 chk_retval(char *retval_str)
2692 {
2693         if (!strisnum(retval_str))
2694                 exit_error(gettext("Invalid retval specified: %s"), retval_str);
2695 }
2696 
2697 static void
2698 execit(char **argv)
2699 {
2700         char *args, *args_pos;
2701         size_t len = 0;
2702         size_t n = 0;
2703         char **argv_pos;
2704 
2705         if (*argv) {
2706                 /* concatenate argument array to be passed to sh -c "..." */
2707                 for (argv_pos = argv; *argv_pos; argv_pos++)
2708                         len += strlen(*argv_pos) + 1;
2709 
2710                 if ((args = malloc(len + 1)) == NULL)
2711                         exit_error(
2712                             gettext("Allocation for command/arguments failed"));
2713 
2714                 args_pos = args;
2715                 for (argv_pos = argv; *argv_pos; argv_pos++) {
2716                         n += snprintf(args_pos, len - n, "%s ", *argv_pos);
2717                         args_pos = args + n;
2718                 }
2719                 /* strip the last space */
2720                 args[strlen(args)] = '\0';
2721 
2722                 (void) execl("/bin/sh", "sh", "-c", args, NULL);
2723         } else {
2724                 (void) execl("/bin/sh", "sh", NULL);
2725         }
2726 
2727         exit_error(gettext("exec(2) failed"));
2728 }
2729 
2730 static void
2731 exit_usage(int status)
2732 {
2733         FILE *fp;
2734         int i;
2735 
2736         fp = (status ? stderr : stdout);
2737         (void) fprintf(fp, gettext("usage: %s option ...\n"), progname);
2738 
2739         for (i = 0; i < ARG_TBL_SZ; i++) {
2740                 /* skip the -t option; it's not a standalone option */
2741                 if (arg_table[i].auditconfig_cmd == AC_ARG_SET_TEMPORARY) {
2742                         continue;
2743                 }
2744 
2745                 (void) fprintf(fp, " %s%s%s\n",
2746                     arg_table[i].arg_str, arg_table[i].arg_opts,
2747                     (arg_table[i].temporary_allowed ? " [-t]" : ""));
2748         }
2749 
2750         exit(status);
2751 }
2752 
2753 static void
2754 print_asid(au_asid_t asid)
2755 {
2756         (void) printf(gettext("audit session id = %u\n"), asid);
2757 }
2758 
2759 static void
2760 print_auid(au_id_t auid)
2761 {
2762         struct passwd *pwd;
2763         char *username;
2764 
2765         if ((pwd = getpwuid((uid_t)auid)) != NULL)
2766                 username = pwd->pw_name;
2767         else
2768                 username = gettext("unknown");
2769 
2770         (void) printf(gettext("audit id = %s(%d)\n"), username, auid);
2771 }
2772 
2773 static void
2774 print_mask(char *desc, au_mask_t *pmp)
2775 {
2776         char auflags[512];
2777 
2778         if (getauditflagschar(auflags, pmp, 0) < 0)
2779                 (void) strlcpy(auflags, gettext("unknown"), sizeof (auflags));
2780 
2781         (void) printf("%s = %s(0x%x,0x%x)\n",
2782             desc, auflags, pmp->am_success, pmp->am_failure);
2783 }
2784 
2785 static void
2786 print_plugin(char *plugin_name, kva_t *plugin_kva)
2787 {
2788         char            att_str[PLUGIN_MAXATT];
2789         boolean_t       plugin_active;
2790         char            *active_str;
2791         char            *qsize_ptr;
2792         int             qsize;
2793 
2794         if ((active_str = kva_match(plugin_kva, "active")) == NULL) {
2795                 (void) printf(gettext("Audit service configuration error: "
2796                     "\"active\" property not found\n"));
2797                 return;
2798         }
2799 
2800         plugin_active = (boolean_t)atoi(active_str);
2801         qsize_ptr = kva_match(plugin_kva, "qsize");
2802         qsize = atoi(qsize_ptr == NULL ? "-1" : qsize_ptr);
2803 
2804         (void) printf(gettext("Plugin: %s (%s)\n"), plugin_name,
2805             plugin_active ? "active" : "inactive");
2806 
2807         free_static_att_kva(plugin_kva);
2808 
2809         switch (_kva2str(plugin_kva, att_str, PLUGIN_MAXATT, "=", ";")) {
2810         case 0:
2811                 (void) printf(gettext("\tAttributes: %s\n"), att_str);
2812                 break;
2813         case 1:
2814                 exit_error(gettext("Internal error - buffer size too small."));
2815                 break;
2816         default:
2817                 exit_error(gettext("Internal error."));
2818                 break;
2819         }
2820 
2821         if (qsize != 0) {
2822                 (void) printf(gettext("\tQueue size: %d %s\n"), qsize,
2823                     qsize == -1 ? "(internal error: value not available)" : "");
2824         }
2825 }
2826 
2827 static void
2828 print_tid_ex(au_tid_addr_t *tidp)
2829 {
2830         struct hostent *phe;
2831         char *hostname;
2832         struct in_addr ia;
2833         uint32_t *addr;
2834         int err;
2835         char buf[INET6_ADDRSTRLEN];
2836         char *bufp;
2837 
2838 
2839         /* IPV6 or IPV4 address */
2840         if (tidp->at_type == AU_IPv4) {
2841                 if ((phe = gethostbyaddr((char *)&tidp->at_addr[0],
2842                     sizeof (tidp->at_addr[0]), AF_INET)) != NULL) {
2843                         hostname = phe->h_name;
2844                 } else {
2845                         hostname = gettext("unknown");
2846                 }
2847 
2848                 ia.s_addr = tidp->at_addr[0];
2849 
2850                 (void) printf(gettext(
2851                     "terminal id (maj,min,host) = %lu,%lu,%s(%s)\n"),
2852                     major(tidp->at_port), minor(tidp->at_port),
2853                     hostname, inet_ntoa(ia));
2854         } else {
2855                 addr = &tidp->at_addr[0];
2856                 phe = getipnodebyaddr((const void *)addr, 16, AF_INET6, &err);
2857 
2858                 bzero(buf, sizeof (buf));
2859 
2860                 (void) inet_ntop(AF_INET6, (void *)addr, buf, sizeof (buf));
2861                 if (phe == NULL) {
2862                         bufp = gettext("unknown");
2863                 } else {
2864                         bufp = phe->h_name;
2865                 }
2866 
2867                 (void) printf(gettext(
2868                     "terminal id (maj,min,host) = %lu,%lu,%s(%s)\n"),
2869                     major(tidp->at_port), minor(tidp->at_port),
2870                     bufp, buf);
2871                 if (phe) {
2872                         freehostent(phe);
2873                 }
2874         }
2875 }
2876 
2877 static int
2878 str2ipaddr(char *s, uint32_t *addr, uint32_t type)
2879 {
2880         int j, sl;
2881         char *ss;
2882         unsigned int v;
2883 
2884         bzero(addr, 16);
2885         if (strisipaddr(s)) {
2886                 if (type == AU_IPv4) {
2887                         if (inet_pton(AF_INET, s, addr)) {
2888                                 return (0);
2889                         }
2890                         return (1);
2891                 } else if (type == AU_IPv6) {
2892                         if (inet_pton(AF_INET6, s, addr))
2893                                 return (0);
2894                         return (1);
2895                 }
2896                 return (1);
2897         } else {
2898                 if (type == AU_IPv4) {
2899                         (void) sscanf(s, "%x", &addr[0]);
2900                         return (0);
2901                 } else if (type == AU_IPv6) {
2902                         sl = strlen(s);
2903                         ss = s;
2904                         for (j = 3; j >= 0; j--) {
2905                                 if ((sl - 8) <= 0) {
2906                                         (void) sscanf(s, "%x", &v);
2907                                         addr[j] = v;
2908                                         return (0);
2909                                 }
2910                                 ss = &s[sl-8];
2911                                 (void) sscanf(ss, "%x", &v);
2912                                 addr[j] = v;
2913                                 sl -= 8;
2914                                 *ss = '\0';
2915                         }
2916                 }
2917                 return (0);
2918         }
2919 }
2920 
2921 static int
2922 str2type(char *s, uint_t *type)
2923 {
2924         if (strcmp(s, "ipv6") == 0) {
2925                 *type = AU_IPv6;
2926                 return (0);
2927         }
2928         if (strcmp(s, "ipv4") == 0) {
2929                 *type = AU_IPv4;
2930                 return (0);
2931         }
2932 
2933         return (1);
2934 }
2935 
2936 /*
2937  * exit_error() - print an error message along with corresponding system error
2938  * number and error message, then exit. Inputs - program error format and
2939  * message.
2940  */
2941 /*PRINTFLIKE1*/
2942 static void
2943 exit_error(char *fmt, ...)
2944 {
2945         va_list args;
2946 
2947         va_start(args, fmt);
2948         prt_error_va(fmt, args);
2949         va_end(args);
2950 
2951         exit(1);
2952 }