17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*45916cd2Sjpk * Common Development and Distribution License (the "License"). 6*45916cd2Sjpk * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 21*45916cd2Sjpk 227c478bd9Sstevel@tonic-gate /* 2340e2b7c9Spaulson * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 247c478bd9Sstevel@tonic-gate * Use is subject to license terms. 257c478bd9Sstevel@tonic-gate */ 267c478bd9Sstevel@tonic-gate 277c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 287c478bd9Sstevel@tonic-gate 297c478bd9Sstevel@tonic-gate #include <errno.h> 307c478bd9Sstevel@tonic-gate #include <locale.h> 317c478bd9Sstevel@tonic-gate #include <pwd.h> 327c478bd9Sstevel@tonic-gate #include <unistd.h> 337c478bd9Sstevel@tonic-gate #include <stdio.h> 347c478bd9Sstevel@tonic-gate #include <stdlib.h> 357c478bd9Sstevel@tonic-gate #include <string.h> 36*45916cd2Sjpk #include <ctype.h> 37*45916cd2Sjpk #include <nss_dbdefs.h> 387c478bd9Sstevel@tonic-gate #include <sys/types.h> 39*45916cd2Sjpk #include <sys/wait.h> 40*45916cd2Sjpk #include <tsol/label.h> 41*45916cd2Sjpk #include <zone.h> 42*45916cd2Sjpk #include <bsm/devalloc.h> 437c478bd9Sstevel@tonic-gate #include "allocate.h" 447c478bd9Sstevel@tonic-gate 457c478bd9Sstevel@tonic-gate #if !defined(TEXT_DOMAIN) 467c478bd9Sstevel@tonic-gate #define TEXT_DOMAIN "SUNW_OST_OSCMD" 477c478bd9Sstevel@tonic-gate #endif 487c478bd9Sstevel@tonic-gate 49*45916cd2Sjpk #define ALLOC "allocate" 50*45916cd2Sjpk #define DEALLOC "deallocate" 51*45916cd2Sjpk #define LIST "list_devices" 52*45916cd2Sjpk 537c478bd9Sstevel@tonic-gate extern void audit_allocate_argv(int, int, char *[]); 547c478bd9Sstevel@tonic-gate extern int audit_allocate_record(int); 557c478bd9Sstevel@tonic-gate 56*45916cd2Sjpk int system_labeled = 0; 57*45916cd2Sjpk static int windowing = 0; 58*45916cd2Sjpk static int wdwmsg(char *name, char *msg); 59*45916cd2Sjpk 607c478bd9Sstevel@tonic-gate static void 617c478bd9Sstevel@tonic-gate usage(int func) 627c478bd9Sstevel@tonic-gate { 63*45916cd2Sjpk if (system_labeled) { 64*45916cd2Sjpk char *use[9]; 65*45916cd2Sjpk 66*45916cd2Sjpk use[0] = gettext("allocate [-s] [-w] [-U uname] [-z zonename] " 67*45916cd2Sjpk "[-F] device"); 68*45916cd2Sjpk use[1] = gettext("allocate [-s] [-w] [-U uname] [-z zonename] " 69*45916cd2Sjpk "[-F] -g dev_type"); 70*45916cd2Sjpk use[2] = gettext("deallocate [-s] [-w] [-z zonename] " 71*45916cd2Sjpk "[-F] device"); 72*45916cd2Sjpk use[3] = gettext("deallocate [-s] [-w] [-z zonename] " 73*45916cd2Sjpk "[-F] -g dev_type"); 74*45916cd2Sjpk use[4] = gettext("deallocate [-s] [-w] [-z zonename] -I"); 75*45916cd2Sjpk use[5] = gettext("list_devices [-s] [-U uid] [-z zonename] " 76*45916cd2Sjpk "[-a] -l [device]"); 77*45916cd2Sjpk use[6] = gettext("list_devices [-s] [-U uid] [-z zonename] " 78*45916cd2Sjpk "[-a] -n [device]"); 79*45916cd2Sjpk use[7] = gettext("list_devices [-s] [-U uid] [-z zonename] " 80*45916cd2Sjpk "[-a] -u [device]"); 81*45916cd2Sjpk use[8] = gettext("list_devices [-s] -d dev_type"); 82*45916cd2Sjpk 83*45916cd2Sjpk switch (func) { 84*45916cd2Sjpk case 0: 85*45916cd2Sjpk (void) fprintf(stderr, "%s\n%s\n", 86*45916cd2Sjpk use[0], use[1]); 87*45916cd2Sjpk break; 88*45916cd2Sjpk case 1: 89*45916cd2Sjpk (void) fprintf(stderr, "%s\n%s\n%s\n", 90*45916cd2Sjpk use[2], use[3], use[4]); 91*45916cd2Sjpk break; 92*45916cd2Sjpk case 2: 93*45916cd2Sjpk (void) fprintf(stderr, "%s\n%s\n%s\n%s\n", 94*45916cd2Sjpk use[5], use[6], use[7], use[8]); 95*45916cd2Sjpk break; 96*45916cd2Sjpk default: 97*45916cd2Sjpk (void) fprintf(stderr, 98*45916cd2Sjpk "%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n", 99*45916cd2Sjpk use[0], use[1], use[2], use[3], use[4], 100*45916cd2Sjpk use[5], use[6], use[7], use[8]); 101*45916cd2Sjpk } 102*45916cd2Sjpk } else { 10340e2b7c9Spaulson char *use[7]; 1047c478bd9Sstevel@tonic-gate 1057c478bd9Sstevel@tonic-gate use[0] = gettext("allocate [-s] [-U uname] [-F] device"); 1067c478bd9Sstevel@tonic-gate use[1] = gettext("allocate [-s] [-U uname] -g dev_type"); 1077c478bd9Sstevel@tonic-gate use[2] = gettext("deallocate [-s] [-F] device"); 10840e2b7c9Spaulson use[3] = gettext("deallocate [-s] -I"); 10940e2b7c9Spaulson use[4] = gettext("list_devices [-s] [-U uid] -l [device]"); 11040e2b7c9Spaulson use[5] = gettext("list_devices [-s] [-U uid] -n [device]"); 11140e2b7c9Spaulson use[6] = gettext("list_devices [-s] [-U uid] -u [device]"); 1127c478bd9Sstevel@tonic-gate 1137c478bd9Sstevel@tonic-gate switch (func) { 1147c478bd9Sstevel@tonic-gate case 0: 115*45916cd2Sjpk (void) fprintf(stderr, "%s\n%s\n", 116*45916cd2Sjpk use[0], use[1]); 1177c478bd9Sstevel@tonic-gate break; 1187c478bd9Sstevel@tonic-gate case 1: 119*45916cd2Sjpk (void) fprintf(stderr, "%s\n%s\n", 120*45916cd2Sjpk use[2], use[3]); 1217c478bd9Sstevel@tonic-gate break; 1227c478bd9Sstevel@tonic-gate case 2: 123*45916cd2Sjpk (void) fprintf(stderr, "%s\n%s\n%s\n", 124*45916cd2Sjpk use[4], use[5], use[6]); 1257c478bd9Sstevel@tonic-gate break; 1267c478bd9Sstevel@tonic-gate default: 127*45916cd2Sjpk (void) fprintf(stderr, 128*45916cd2Sjpk "%s\n%s\n%s\n%s\n%s\n%s\n%s\n", 129*45916cd2Sjpk use[0], use[1], use[2], use[3], use[4], 130*45916cd2Sjpk use[5], use[6]); 131*45916cd2Sjpk } 1327c478bd9Sstevel@tonic-gate } 13340e2b7c9Spaulson exit(1); 1347c478bd9Sstevel@tonic-gate } 1357c478bd9Sstevel@tonic-gate 136*45916cd2Sjpk void 1377c478bd9Sstevel@tonic-gate print_error(int error, char *name) 1387c478bd9Sstevel@tonic-gate { 1397c478bd9Sstevel@tonic-gate char *msg; 140*45916cd2Sjpk char msgbuf[200]; 1417c478bd9Sstevel@tonic-gate 1427c478bd9Sstevel@tonic-gate switch (error) { 143*45916cd2Sjpk case ALLOCUERR: 1447c478bd9Sstevel@tonic-gate msg = gettext("Specified device is allocated to another user."); 1457c478bd9Sstevel@tonic-gate break; 146*45916cd2Sjpk case CHOWNERR: 147*45916cd2Sjpk msg = gettext("Failed to chown."); 1487c478bd9Sstevel@tonic-gate break; 149*45916cd2Sjpk case CLEANERR: 150*45916cd2Sjpk msg = gettext("Unable to clean up device."); 1517c478bd9Sstevel@tonic-gate break; 152*45916cd2Sjpk case CNTDEXECERR: 1537c478bd9Sstevel@tonic-gate msg = gettext( 1547c478bd9Sstevel@tonic-gate "Can't exec device-clean program for specified device."); 1557c478bd9Sstevel@tonic-gate break; 156*45916cd2Sjpk case CNTFRCERR: 157*45916cd2Sjpk msg = gettext("Can't force deallocate specified device."); 1587c478bd9Sstevel@tonic-gate break; 159*45916cd2Sjpk case DACACCERR: 160*45916cd2Sjpk msg = gettext( 161*45916cd2Sjpk "Can't access DAC file for the device specified."); 162*45916cd2Sjpk break; 163*45916cd2Sjpk case DAOFFERR: 164*45916cd2Sjpk msg = gettext( 165*45916cd2Sjpk "Device allocation feature is not activated " 166*45916cd2Sjpk "on this system."); 167*45916cd2Sjpk break; 168*45916cd2Sjpk case DAUTHERR: 169*45916cd2Sjpk msg = gettext("Device not allocatable."); 170*45916cd2Sjpk break; 171*45916cd2Sjpk case DEFATTRSERR: 172*45916cd2Sjpk msg = gettext("No default attributes for specified " 173*45916cd2Sjpk "device type."); 174*45916cd2Sjpk break; 175*45916cd2Sjpk case DEVLKERR: 176*45916cd2Sjpk msg = gettext("Concurrent operations for specified device, " 177*45916cd2Sjpk "try later."); 178*45916cd2Sjpk break; 179*45916cd2Sjpk case DEVLONGERR: 180*45916cd2Sjpk msg = gettext("Device name is too long."); 181*45916cd2Sjpk break; 182*45916cd2Sjpk case DEVNALLOCERR: 183*45916cd2Sjpk msg = gettext("Device not allocated."); 184*45916cd2Sjpk break; 185*45916cd2Sjpk case DEVNAMEERR: 186*45916cd2Sjpk msg = gettext("Device name error."); 187*45916cd2Sjpk break; 188*45916cd2Sjpk case DEVSTATEERR: 189*45916cd2Sjpk msg = gettext("Device specified is in allocate error state."); 190*45916cd2Sjpk break; 191*45916cd2Sjpk case DEVZONEERR: 192*45916cd2Sjpk msg = gettext("Can't find name of the zone to which " 193*45916cd2Sjpk "device is allocated."); 194*45916cd2Sjpk break; 195*45916cd2Sjpk case DSPMISSERR: 1967c478bd9Sstevel@tonic-gate msg = gettext( 1977c478bd9Sstevel@tonic-gate "Device special file(s) missing for specified device."); 1987c478bd9Sstevel@tonic-gate break; 199*45916cd2Sjpk case LABELRNGERR: 200*45916cd2Sjpk msg = gettext( 201*45916cd2Sjpk "Operation inconsistent with device's label range."); 2027c478bd9Sstevel@tonic-gate break; 203*45916cd2Sjpk case LOGINDEVPERMERR: 204*45916cd2Sjpk msg = gettext("Device controlled by logindevperm(4)"); 2057c478bd9Sstevel@tonic-gate break; 206*45916cd2Sjpk case NODAERR: 207*45916cd2Sjpk msg = gettext("No entry for specified device."); 208*45916cd2Sjpk break; 209*45916cd2Sjpk case NODMAPERR: 210*45916cd2Sjpk msg = gettext("No entry for specified device."); 211*45916cd2Sjpk break; 212*45916cd2Sjpk case PREALLOCERR: 2137c478bd9Sstevel@tonic-gate msg = gettext("Device already allocated."); 2147c478bd9Sstevel@tonic-gate break; 215*45916cd2Sjpk case SETACLERR: 216*45916cd2Sjpk msg = gettext("Failed to set ACL."); 2177c478bd9Sstevel@tonic-gate break; 218*45916cd2Sjpk case UAUTHERR: 219*45916cd2Sjpk msg = gettext( 220*45916cd2Sjpk "User lacks authorization required for this operation."); 2217c478bd9Sstevel@tonic-gate break; 222*45916cd2Sjpk case ZONEERR: 223*45916cd2Sjpk msg = gettext("Failed to configure device in zone."); 2247c478bd9Sstevel@tonic-gate break; 2257c478bd9Sstevel@tonic-gate default: 2267c478bd9Sstevel@tonic-gate msg = gettext("Unknown error code."); 2277c478bd9Sstevel@tonic-gate break; 2287c478bd9Sstevel@tonic-gate } 2297c478bd9Sstevel@tonic-gate 230*45916cd2Sjpk if (windowing) { 231*45916cd2Sjpk (void) snprintf(msgbuf, sizeof (msgbuf), "%s: %s\n", name, msg); 232*45916cd2Sjpk (void) wdwmsg(name, msgbuf); 233*45916cd2Sjpk } else { 2347c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "%s: %s\n", name, msg); 2357c478bd9Sstevel@tonic-gate (void) fflush(stderr); 2367c478bd9Sstevel@tonic-gate } 237*45916cd2Sjpk } 2387c478bd9Sstevel@tonic-gate 2397c478bd9Sstevel@tonic-gate char *newenv[] = {"PATH=/usr/bin:/usr/sbin", 2407c478bd9Sstevel@tonic-gate NULL, /* for LC_ALL */ 2417c478bd9Sstevel@tonic-gate NULL, /* for LC_COLLATE */ 2427c478bd9Sstevel@tonic-gate NULL, /* for LC_CTYPE */ 2437c478bd9Sstevel@tonic-gate NULL, /* for LC_MESSAGES */ 2447c478bd9Sstevel@tonic-gate NULL, /* for LC_NUMERIC */ 2457c478bd9Sstevel@tonic-gate NULL, /* for LC_TIME */ 2467c478bd9Sstevel@tonic-gate NULL, /* for LANG */ 2477c478bd9Sstevel@tonic-gate NULL 2487c478bd9Sstevel@tonic-gate }; 2497c478bd9Sstevel@tonic-gate 2507c478bd9Sstevel@tonic-gate static char * 2517c478bd9Sstevel@tonic-gate getenvent(char *name, char *env[]) 2527c478bd9Sstevel@tonic-gate { 2537c478bd9Sstevel@tonic-gate for (; *env != NULL; env++) { 2547c478bd9Sstevel@tonic-gate if (strncmp(*env, name, strlen(name)) == 0) 2557c478bd9Sstevel@tonic-gate return (*env); 2567c478bd9Sstevel@tonic-gate } 2577c478bd9Sstevel@tonic-gate return (NULL); 2587c478bd9Sstevel@tonic-gate } 2597c478bd9Sstevel@tonic-gate 2607c478bd9Sstevel@tonic-gate int 2617c478bd9Sstevel@tonic-gate main(int argc, char *argv[], char *envp[]) 2627c478bd9Sstevel@tonic-gate { 2637c478bd9Sstevel@tonic-gate char *name, *env; 26440e2b7c9Spaulson int func = -1, optflg = 0, error = 0, c; 265*45916cd2Sjpk zoneid_t zoneid; 266*45916cd2Sjpk uid_t uid; 267*45916cd2Sjpk char *uname = NULL, *device = NULL, *zonename = NULL; 268*45916cd2Sjpk char *zname; 269*45916cd2Sjpk char pw_buf[NSS_BUFLEN_PASSWD]; 270*45916cd2Sjpk struct passwd pw_ent; 2717c478bd9Sstevel@tonic-gate int env_num = 1; /* PATH= is 0 entry */ 2727c478bd9Sstevel@tonic-gate 2737c478bd9Sstevel@tonic-gate (void) setlocale(LC_ALL, ""); 2747c478bd9Sstevel@tonic-gate (void) textdomain(TEXT_DOMAIN); 2757c478bd9Sstevel@tonic-gate 276*45916cd2Sjpk system_labeled = is_system_labeled(); 277*45916cd2Sjpk 2787c478bd9Sstevel@tonic-gate /* 2797c478bd9Sstevel@tonic-gate * get all enviroment variables 2807c478bd9Sstevel@tonic-gate * which affect on internationalization. 2817c478bd9Sstevel@tonic-gate */ 2827c478bd9Sstevel@tonic-gate env = getenvent("LC_ALL=", envp); 2837c478bd9Sstevel@tonic-gate if (env != NULL) 2847c478bd9Sstevel@tonic-gate newenv[env_num++] = env; 2857c478bd9Sstevel@tonic-gate env = getenvent("LC_COLLATE=", envp); 2867c478bd9Sstevel@tonic-gate if (env != NULL) 2877c478bd9Sstevel@tonic-gate newenv[env_num++] = env; 2887c478bd9Sstevel@tonic-gate env = getenvent("LC_CTYPE=", envp); 2897c478bd9Sstevel@tonic-gate if (env != NULL) 2907c478bd9Sstevel@tonic-gate newenv[env_num++] = env; 2917c478bd9Sstevel@tonic-gate env = getenvent("LC_MESSAGES=", envp); 2927c478bd9Sstevel@tonic-gate if (env != NULL) 2937c478bd9Sstevel@tonic-gate newenv[env_num++] = env; 2947c478bd9Sstevel@tonic-gate env = getenvent("LC_NUMERIC=", envp); 2957c478bd9Sstevel@tonic-gate if (env != NULL) 2967c478bd9Sstevel@tonic-gate newenv[env_num++] = env; 2977c478bd9Sstevel@tonic-gate env = getenvent("LC_TIME=", envp); 2987c478bd9Sstevel@tonic-gate if (env != NULL) 2997c478bd9Sstevel@tonic-gate newenv[env_num++] = env; 3007c478bd9Sstevel@tonic-gate env = getenvent("LANG=", envp); 3017c478bd9Sstevel@tonic-gate if (env != NULL) 3027c478bd9Sstevel@tonic-gate newenv[env_num] = env; 3037c478bd9Sstevel@tonic-gate 3047c478bd9Sstevel@tonic-gate if ((name = strrchr(argv[0], '/')) == NULL) 3057c478bd9Sstevel@tonic-gate name = argv[0]; 3067c478bd9Sstevel@tonic-gate else 3077c478bd9Sstevel@tonic-gate name++; 3087c478bd9Sstevel@tonic-gate 309*45916cd2Sjpk if (strcmp(name, ALLOC) == 0) 3107c478bd9Sstevel@tonic-gate func = 0; 311*45916cd2Sjpk else if (strcmp(name, DEALLOC) == 0) 3127c478bd9Sstevel@tonic-gate func = 1; 313*45916cd2Sjpk else if (strcmp(name, LIST) == 0) 3147c478bd9Sstevel@tonic-gate func = 2; 315*45916cd2Sjpk else 316*45916cd2Sjpk usage(-1); 3177c478bd9Sstevel@tonic-gate 3187c478bd9Sstevel@tonic-gate audit_allocate_argv(func, argc, argv); 3197c478bd9Sstevel@tonic-gate 320*45916cd2Sjpk if (system_labeled) { 321*45916cd2Sjpk /* 322*45916cd2Sjpk * allocate, deallocate, list_devices run in 323*45916cd2Sjpk * global zone only. 324*45916cd2Sjpk */ 325*45916cd2Sjpk zoneid = getzoneid(); 326*45916cd2Sjpk if (zoneid != GLOBAL_ZONEID) 327*45916cd2Sjpk exit(GLOBALERR); 328*45916cd2Sjpk zname = GLOBAL_ZONENAME; 329*45916cd2Sjpk /* 330*45916cd2Sjpk * check if device allocation is activated. 331*45916cd2Sjpk */ 332*45916cd2Sjpk if (da_is_on() == 0) { 333*45916cd2Sjpk (void) fprintf(stderr, "%s%s", 334*45916cd2Sjpk gettext("Turn device allocation on"), 335*45916cd2Sjpk gettext(" to use this feature.\n")); 336*45916cd2Sjpk exit(DAOFFERR); 337*45916cd2Sjpk } 338*45916cd2Sjpk } 339*45916cd2Sjpk 34040e2b7c9Spaulson if (func == 0) { /* allocate */ 341*45916cd2Sjpk while ((c = getopt(argc, argv, "gswz:FU:")) != -1) { 34240e2b7c9Spaulson switch (c) { 343*45916cd2Sjpk case 'g': 344*45916cd2Sjpk optflg |= TYPE; 345*45916cd2Sjpk break; 34640e2b7c9Spaulson case 's': 34740e2b7c9Spaulson optflg |= SILENT; 34840e2b7c9Spaulson break; 349*45916cd2Sjpk case 'w': 350*45916cd2Sjpk if (system_labeled) { 351*45916cd2Sjpk optflg |= WINDOWING; 352*45916cd2Sjpk windowing = 1; 353*45916cd2Sjpk } else { 354*45916cd2Sjpk usage(func); 355*45916cd2Sjpk } 356*45916cd2Sjpk break; 357*45916cd2Sjpk case 'z': 358*45916cd2Sjpk if (system_labeled) { 359*45916cd2Sjpk optflg |= ZONENAME; 360*45916cd2Sjpk zonename = optarg; 361*45916cd2Sjpk } else { 362*45916cd2Sjpk usage(func); 363*45916cd2Sjpk } 364*45916cd2Sjpk break; 365*45916cd2Sjpk case 'F': 366*45916cd2Sjpk optflg |= FORCE; 367*45916cd2Sjpk break; 36840e2b7c9Spaulson case 'U': 36940e2b7c9Spaulson optflg |= USERNAME; 37040e2b7c9Spaulson uname = optarg; 37140e2b7c9Spaulson break; 37240e2b7c9Spaulson case '?': 37340e2b7c9Spaulson default : 37440e2b7c9Spaulson usage(func); 37540e2b7c9Spaulson } 37640e2b7c9Spaulson } 37740e2b7c9Spaulson 37840e2b7c9Spaulson /* 37940e2b7c9Spaulson * allocate(1) must be supplied with one device argument 38040e2b7c9Spaulson */ 38140e2b7c9Spaulson if ((argc - optind) != 1) { 38240e2b7c9Spaulson usage(func); 38340e2b7c9Spaulson } else { 38440e2b7c9Spaulson device = argv[optind]; 38540e2b7c9Spaulson } 38640e2b7c9Spaulson } 38740e2b7c9Spaulson 38840e2b7c9Spaulson else if (func == 1) { /* deallocate */ 389*45916cd2Sjpk while ((c = getopt(argc, argv, "gswz:FI")) != -1) { 39040e2b7c9Spaulson switch (c) { 391*45916cd2Sjpk case 'g': 392*45916cd2Sjpk if (system_labeled) 393*45916cd2Sjpk optflg |= TYPE; 394*45916cd2Sjpk else 395*45916cd2Sjpk usage(func); 396*45916cd2Sjpk break; 39740e2b7c9Spaulson case 's': 39840e2b7c9Spaulson optflg |= SILENT; 39940e2b7c9Spaulson break; 400*45916cd2Sjpk case 'w': 401*45916cd2Sjpk if (system_labeled) { 402*45916cd2Sjpk optflg |= WINDOWING; 403*45916cd2Sjpk windowing = 1; 404*45916cd2Sjpk } else { 405*45916cd2Sjpk usage(func); 406*45916cd2Sjpk } 407*45916cd2Sjpk break; 408*45916cd2Sjpk case 'z': 409*45916cd2Sjpk if (system_labeled) { 410*45916cd2Sjpk optflg |= ZONENAME; 411*45916cd2Sjpk zonename = optarg; 412*45916cd2Sjpk } else { 413*45916cd2Sjpk usage(func); 414*45916cd2Sjpk } 415*45916cd2Sjpk break; 41640e2b7c9Spaulson case 'F': 41740e2b7c9Spaulson optflg |= FORCE; 41840e2b7c9Spaulson break; 41940e2b7c9Spaulson case 'I': 42040e2b7c9Spaulson optflg |= FORCE_ALL; 42140e2b7c9Spaulson break; 42240e2b7c9Spaulson case '?': 42340e2b7c9Spaulson default : 42440e2b7c9Spaulson usage(func); 42540e2b7c9Spaulson } 42640e2b7c9Spaulson } 42740e2b7c9Spaulson 42840e2b7c9Spaulson if ((optflg & FORCE) && (optflg & FORCE_ALL)) 42940e2b7c9Spaulson usage(func); 43040e2b7c9Spaulson 431*45916cd2Sjpk if (system_labeled && ((optflg & FORCE_ALL) && (optflg & TYPE))) 432*45916cd2Sjpk usage(func); 433*45916cd2Sjpk 43440e2b7c9Spaulson /* 43540e2b7c9Spaulson * deallocate(1) must be supplied with one device 43640e2b7c9Spaulson * argument unless the '-I' argument is supplied 43740e2b7c9Spaulson */ 43840e2b7c9Spaulson if (!(optflg & FORCE_ALL)) { 43940e2b7c9Spaulson if ((argc - optind) != 1) { 44040e2b7c9Spaulson usage(func); 44140e2b7c9Spaulson } else { 44240e2b7c9Spaulson device = argv[optind]; 44340e2b7c9Spaulson } 44440e2b7c9Spaulson } else { 44540e2b7c9Spaulson if ((argc - optind) >= 1) { 44640e2b7c9Spaulson usage(func); 44740e2b7c9Spaulson } 44840e2b7c9Spaulson } 44940e2b7c9Spaulson } 45040e2b7c9Spaulson 45140e2b7c9Spaulson else if (func == 2) { /* list_devices */ 452*45916cd2Sjpk while ((c = getopt(argc, argv, "adlnsuwz:U:")) != -1) { 4537c478bd9Sstevel@tonic-gate switch (c) { 454*45916cd2Sjpk case 'a': 455*45916cd2Sjpk if (system_labeled) { 456*45916cd2Sjpk /* 457*45916cd2Sjpk * list auths, cleaning programs, 458*45916cd2Sjpk * labels. 459*45916cd2Sjpk */ 460*45916cd2Sjpk optflg |= LISTATTRS; 461*45916cd2Sjpk } else { 462*45916cd2Sjpk usage(func); 463*45916cd2Sjpk } 464*45916cd2Sjpk break; 465*45916cd2Sjpk case 'd': 466*45916cd2Sjpk if (system_labeled) { 467*45916cd2Sjpk /* 468*45916cd2Sjpk * list devalloc_defaults 469*45916cd2Sjpk */ 470*45916cd2Sjpk optflg |= LISTDEFS; 471*45916cd2Sjpk } else { 472*45916cd2Sjpk usage(func); 473*45916cd2Sjpk } 474*45916cd2Sjpk break; 475*45916cd2Sjpk case 'l': 476*45916cd2Sjpk optflg |= LISTALL; 477*45916cd2Sjpk break; 478*45916cd2Sjpk case 'n': 479*45916cd2Sjpk optflg |= LISTFREE; 480*45916cd2Sjpk break; 4817c478bd9Sstevel@tonic-gate case 's': 4827c478bd9Sstevel@tonic-gate optflg |= SILENT; 4837c478bd9Sstevel@tonic-gate break; 484*45916cd2Sjpk case 'u': 485*45916cd2Sjpk optflg |= LISTALLOC; 486*45916cd2Sjpk break; 487*45916cd2Sjpk case 'w': 488*45916cd2Sjpk if (system_labeled) { 489*45916cd2Sjpk /* 490*45916cd2Sjpk * Private interface for use by 491*45916cd2Sjpk * list_devices GUI 492*45916cd2Sjpk */ 493*45916cd2Sjpk optflg |= WINDOWING; 494*45916cd2Sjpk } else { 495*45916cd2Sjpk usage(func); 496*45916cd2Sjpk } 497*45916cd2Sjpk break; 498*45916cd2Sjpk case 'z': 499*45916cd2Sjpk if (system_labeled) { 500*45916cd2Sjpk optflg |= ZONENAME; 501*45916cd2Sjpk zonename = optarg; 502*45916cd2Sjpk } else { 503*45916cd2Sjpk usage(func); 504*45916cd2Sjpk } 505*45916cd2Sjpk break; 5067c478bd9Sstevel@tonic-gate case 'U': 5077c478bd9Sstevel@tonic-gate optflg |= USERID; 50840e2b7c9Spaulson uid = atoi(optarg); 5097c478bd9Sstevel@tonic-gate break; 5107c478bd9Sstevel@tonic-gate case '?': 5117c478bd9Sstevel@tonic-gate default : 5127c478bd9Sstevel@tonic-gate usage(func); 51340e2b7c9Spaulson } 5147c478bd9Sstevel@tonic-gate } 5157c478bd9Sstevel@tonic-gate 516*45916cd2Sjpk if (system_labeled) { 517*45916cd2Sjpk if (((optflg & LISTALL) && (optflg & LISTFREE)) || 518*45916cd2Sjpk ((optflg & LISTALL) && (optflg & LISTALLOC)) || 519*45916cd2Sjpk ((optflg & LISTFREE) && (optflg & LISTALLOC)) || 520*45916cd2Sjpk ((optflg & LISTDEFS) && 521*45916cd2Sjpk (optflg & (LISTATTRS | LISTALL | LISTFREE | 522*45916cd2Sjpk LISTALLOC | USERID | WINDOWING | ZONENAME))) || 523*45916cd2Sjpk (!(optflg & (LISTALL | LISTFREE | LISTALLOC | 524*45916cd2Sjpk LISTDEFS | WINDOWING)))) 52540e2b7c9Spaulson usage(func); 526*45916cd2Sjpk } else if (((optflg & LISTALL) && (optflg & LISTFREE)) || 527*45916cd2Sjpk ((optflg & LISTALL) && (optflg & LISTALLOC)) || 528*45916cd2Sjpk ((optflg & LISTFREE) && (optflg & LISTALLOC)) || 529*45916cd2Sjpk (!(optflg & (LISTALL | LISTFREE | LISTALLOC)))) { 530*45916cd2Sjpk usage(func); 531*45916cd2Sjpk } 53240e2b7c9Spaulson 53340e2b7c9Spaulson /* 53440e2b7c9Spaulson * list_devices(1) takes an optional device argument 53540e2b7c9Spaulson */ 53640e2b7c9Spaulson if ((argc - optind) == 1) { 53740e2b7c9Spaulson device = argv[optind]; 53840e2b7c9Spaulson } else { 53940e2b7c9Spaulson if ((argc - optind) > 1) { 54040e2b7c9Spaulson usage(func); 54140e2b7c9Spaulson } 54240e2b7c9Spaulson } 54340e2b7c9Spaulson } 54440e2b7c9Spaulson 54540e2b7c9Spaulson if (optflg & USERNAME) { 546*45916cd2Sjpk if (getpwnam_r(uname, &pw_ent, pw_buf, sizeof (pw_buf)) == 547*45916cd2Sjpk NULL) { 548*45916cd2Sjpk (void) fprintf(stderr, 549*45916cd2Sjpk gettext("Invalid user name -- %s -- \n"), uname); 55040e2b7c9Spaulson exit(1); 55140e2b7c9Spaulson } 552*45916cd2Sjpk uid = pw_ent.pw_uid; 553*45916cd2Sjpk } else if (optflg & USERID) { 554*45916cd2Sjpk if (getpwuid_r(uid, &pw_ent, pw_buf, sizeof (pw_buf)) == NULL) { 555*45916cd2Sjpk (void) fprintf(stderr, 556*45916cd2Sjpk gettext("Invalid user ID -- %d -- \n"), uid); 55740e2b7c9Spaulson exit(1); 5587c478bd9Sstevel@tonic-gate } 559*45916cd2Sjpk uid = pw_ent.pw_uid; 560*45916cd2Sjpk } else { 561*45916cd2Sjpk /* 562*45916cd2Sjpk * caller's uid is the default if no user specified. 563*45916cd2Sjpk */ 564*45916cd2Sjpk uid = getuid(); 5657c478bd9Sstevel@tonic-gate } 5667c478bd9Sstevel@tonic-gate 567*45916cd2Sjpk /* 568*45916cd2Sjpk * global zone is the default if no zonename specified. 569*45916cd2Sjpk */ 570*45916cd2Sjpk if (zonename == NULL) { 571*45916cd2Sjpk zonename = zname; 572*45916cd2Sjpk } else { 573*45916cd2Sjpk if (zone_get_id(zonename, &zoneid) != 0) { 574*45916cd2Sjpk (void) fprintf(stderr, 575*45916cd2Sjpk gettext("Invalid zone name -- %s -- \n"), zonename); 576*45916cd2Sjpk exit(1); 5777c478bd9Sstevel@tonic-gate } 578*45916cd2Sjpk } 579*45916cd2Sjpk 580*45916cd2Sjpk if (func == 0) 581*45916cd2Sjpk error = allocate(optflg, uid, device, zonename); 582*45916cd2Sjpk else if (func == 1) 583*45916cd2Sjpk error = deallocate(optflg, uid, device, zonename); 584*45916cd2Sjpk else if (func == 2) 585*45916cd2Sjpk error = list_devices(optflg, uid, device, zonename); 58640e2b7c9Spaulson 5877c478bd9Sstevel@tonic-gate (void) audit_allocate_record(error); 5887c478bd9Sstevel@tonic-gate 5897c478bd9Sstevel@tonic-gate if (error) { 5907c478bd9Sstevel@tonic-gate if (!(optflg & SILENT)) 5917c478bd9Sstevel@tonic-gate print_error(error, name); 5927c478bd9Sstevel@tonic-gate exit(error); 5937c478bd9Sstevel@tonic-gate } 5947c478bd9Sstevel@tonic-gate 5957c478bd9Sstevel@tonic-gate return (0); 5967c478bd9Sstevel@tonic-gate } 597*45916cd2Sjpk 598*45916cd2Sjpk /* 599*45916cd2Sjpk * Display error message via /etc/security/lib/wdwmsg script 600*45916cd2Sjpk */ 601*45916cd2Sjpk static int 602*45916cd2Sjpk wdwmsg(char *name, char *msg) 603*45916cd2Sjpk { 604*45916cd2Sjpk pid_t child_pid; 605*45916cd2Sjpk pid_t wait_pid; 606*45916cd2Sjpk int child_status; 607*45916cd2Sjpk 608*45916cd2Sjpk /* Fork a child */ 609*45916cd2Sjpk switch (child_pid = fork()) { 610*45916cd2Sjpk case -1: /* FAILURE */ 611*45916cd2Sjpk return (-1); 612*45916cd2Sjpk break; 613*45916cd2Sjpk 614*45916cd2Sjpk case 0: /* CHILD */ 615*45916cd2Sjpk (void) execl("/etc/security/lib/wdwmsg", "wdwmsg", msg, 616*45916cd2Sjpk name, "OK", NULL); 617*45916cd2Sjpk /* If exec failed, send message to stderr */ 618*45916cd2Sjpk (void) fprintf(stderr, "%s", msg); 619*45916cd2Sjpk return (-1); 620*45916cd2Sjpk 621*45916cd2Sjpk default: /* PARENT */ 622*45916cd2Sjpk /* Wait for child to exit */ 623*45916cd2Sjpk wait_pid = waitpid(child_pid, &child_status, 0); 624*45916cd2Sjpk if ((wait_pid < 0) && (errno == ECHILD)) 625*45916cd2Sjpk return (0); 626*45916cd2Sjpk if ((wait_pid < 0) || (wait_pid != child_pid)) 627*45916cd2Sjpk return (-1); 628*45916cd2Sjpk if (WIFEXITED(child_status)) 629*45916cd2Sjpk return (WEXITSTATUS(child_status)); 630*45916cd2Sjpk if (WIFSIGNALED(child_status)) 631*45916cd2Sjpk return (WTERMSIG(child_status)); 632*45916cd2Sjpk return (0); 633*45916cd2Sjpk } 634*45916cd2Sjpk } 635