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 545916cd2Sjpk * Common Development and Distribution License (the "License"). 645916cd2Sjpk * 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 */ 2145916cd2Sjpk 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> 3645916cd2Sjpk #include <ctype.h> 37*facf4a8dSllai1 #include <fcntl.h> 3845916cd2Sjpk #include <nss_dbdefs.h> 397c478bd9Sstevel@tonic-gate #include <sys/types.h> 40*facf4a8dSllai1 #include <sys/stat.h> 4145916cd2Sjpk #include <sys/wait.h> 4245916cd2Sjpk #include <tsol/label.h> 4345916cd2Sjpk #include <zone.h> 4445916cd2Sjpk #include <bsm/devalloc.h> 457c478bd9Sstevel@tonic-gate #include "allocate.h" 467c478bd9Sstevel@tonic-gate 477c478bd9Sstevel@tonic-gate #if !defined(TEXT_DOMAIN) 487c478bd9Sstevel@tonic-gate #define TEXT_DOMAIN "SUNW_OST_OSCMD" 497c478bd9Sstevel@tonic-gate #endif 507c478bd9Sstevel@tonic-gate 5145916cd2Sjpk #define ALLOC "allocate" 5245916cd2Sjpk #define DEALLOC "deallocate" 5345916cd2Sjpk #define LIST "list_devices" 5445916cd2Sjpk 557c478bd9Sstevel@tonic-gate extern void audit_allocate_argv(int, int, char *[]); 567c478bd9Sstevel@tonic-gate extern int audit_allocate_record(int); 577c478bd9Sstevel@tonic-gate 5845916cd2Sjpk int system_labeled = 0; 5945916cd2Sjpk static int windowing = 0; 6045916cd2Sjpk static int wdwmsg(char *name, char *msg); 6145916cd2Sjpk 627c478bd9Sstevel@tonic-gate static void 637c478bd9Sstevel@tonic-gate usage(int func) 647c478bd9Sstevel@tonic-gate { 6545916cd2Sjpk if (system_labeled) { 6645916cd2Sjpk char *use[9]; 6745916cd2Sjpk 6845916cd2Sjpk use[0] = gettext("allocate [-s] [-w] [-U uname] [-z zonename] " 6945916cd2Sjpk "[-F] device"); 7045916cd2Sjpk use[1] = gettext("allocate [-s] [-w] [-U uname] [-z zonename] " 7145916cd2Sjpk "[-F] -g dev_type"); 7245916cd2Sjpk use[2] = gettext("deallocate [-s] [-w] [-z zonename] " 7345916cd2Sjpk "[-F] device"); 7445916cd2Sjpk use[3] = gettext("deallocate [-s] [-w] [-z zonename] " 7545916cd2Sjpk "[-F] -g dev_type"); 7645916cd2Sjpk use[4] = gettext("deallocate [-s] [-w] [-z zonename] -I"); 7745916cd2Sjpk use[5] = gettext("list_devices [-s] [-U uid] [-z zonename] " 7845916cd2Sjpk "[-a] -l [device]"); 7945916cd2Sjpk use[6] = gettext("list_devices [-s] [-U uid] [-z zonename] " 8045916cd2Sjpk "[-a] -n [device]"); 8145916cd2Sjpk use[7] = gettext("list_devices [-s] [-U uid] [-z zonename] " 8245916cd2Sjpk "[-a] -u [device]"); 8345916cd2Sjpk use[8] = gettext("list_devices [-s] -d dev_type"); 8445916cd2Sjpk 8545916cd2Sjpk switch (func) { 8645916cd2Sjpk case 0: 8745916cd2Sjpk (void) fprintf(stderr, "%s\n%s\n", 8845916cd2Sjpk use[0], use[1]); 8945916cd2Sjpk break; 9045916cd2Sjpk case 1: 9145916cd2Sjpk (void) fprintf(stderr, "%s\n%s\n%s\n", 9245916cd2Sjpk use[2], use[3], use[4]); 9345916cd2Sjpk break; 9445916cd2Sjpk case 2: 9545916cd2Sjpk (void) fprintf(stderr, "%s\n%s\n%s\n%s\n", 9645916cd2Sjpk use[5], use[6], use[7], use[8]); 9745916cd2Sjpk break; 9845916cd2Sjpk default: 9945916cd2Sjpk (void) fprintf(stderr, 10045916cd2Sjpk "%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n", 10145916cd2Sjpk use[0], use[1], use[2], use[3], use[4], 10245916cd2Sjpk use[5], use[6], use[7], use[8]); 10345916cd2Sjpk } 10445916cd2Sjpk } else { 10540e2b7c9Spaulson char *use[7]; 1067c478bd9Sstevel@tonic-gate 1077c478bd9Sstevel@tonic-gate use[0] = gettext("allocate [-s] [-U uname] [-F] device"); 1087c478bd9Sstevel@tonic-gate use[1] = gettext("allocate [-s] [-U uname] -g dev_type"); 1097c478bd9Sstevel@tonic-gate use[2] = gettext("deallocate [-s] [-F] device"); 11040e2b7c9Spaulson use[3] = gettext("deallocate [-s] -I"); 11140e2b7c9Spaulson use[4] = gettext("list_devices [-s] [-U uid] -l [device]"); 11240e2b7c9Spaulson use[5] = gettext("list_devices [-s] [-U uid] -n [device]"); 11340e2b7c9Spaulson use[6] = gettext("list_devices [-s] [-U uid] -u [device]"); 1147c478bd9Sstevel@tonic-gate 1157c478bd9Sstevel@tonic-gate switch (func) { 1167c478bd9Sstevel@tonic-gate case 0: 11745916cd2Sjpk (void) fprintf(stderr, "%s\n%s\n", 11845916cd2Sjpk use[0], use[1]); 1197c478bd9Sstevel@tonic-gate break; 1207c478bd9Sstevel@tonic-gate case 1: 12145916cd2Sjpk (void) fprintf(stderr, "%s\n%s\n", 12245916cd2Sjpk use[2], use[3]); 1237c478bd9Sstevel@tonic-gate break; 1247c478bd9Sstevel@tonic-gate case 2: 12545916cd2Sjpk (void) fprintf(stderr, "%s\n%s\n%s\n", 12645916cd2Sjpk use[4], use[5], use[6]); 1277c478bd9Sstevel@tonic-gate break; 1287c478bd9Sstevel@tonic-gate default: 12945916cd2Sjpk (void) fprintf(stderr, 13045916cd2Sjpk "%s\n%s\n%s\n%s\n%s\n%s\n%s\n", 13145916cd2Sjpk use[0], use[1], use[2], use[3], use[4], 13245916cd2Sjpk use[5], use[6]); 13345916cd2Sjpk } 1347c478bd9Sstevel@tonic-gate } 13540e2b7c9Spaulson exit(1); 1367c478bd9Sstevel@tonic-gate } 1377c478bd9Sstevel@tonic-gate 13845916cd2Sjpk void 1397c478bd9Sstevel@tonic-gate print_error(int error, char *name) 1407c478bd9Sstevel@tonic-gate { 1417c478bd9Sstevel@tonic-gate char *msg; 14245916cd2Sjpk char msgbuf[200]; 1437c478bd9Sstevel@tonic-gate 1447c478bd9Sstevel@tonic-gate switch (error) { 14545916cd2Sjpk case ALLOCUERR: 1467c478bd9Sstevel@tonic-gate msg = gettext("Specified device is allocated to another user."); 1477c478bd9Sstevel@tonic-gate break; 14845916cd2Sjpk case CHOWNERR: 14945916cd2Sjpk msg = gettext("Failed to chown."); 1507c478bd9Sstevel@tonic-gate break; 15145916cd2Sjpk case CLEANERR: 15245916cd2Sjpk msg = gettext("Unable to clean up device."); 1537c478bd9Sstevel@tonic-gate break; 15445916cd2Sjpk case CNTDEXECERR: 1557c478bd9Sstevel@tonic-gate msg = gettext( 1567c478bd9Sstevel@tonic-gate "Can't exec device-clean program for specified device."); 1577c478bd9Sstevel@tonic-gate break; 15845916cd2Sjpk case CNTFRCERR: 15945916cd2Sjpk msg = gettext("Can't force deallocate specified device."); 1607c478bd9Sstevel@tonic-gate break; 16145916cd2Sjpk case DACACCERR: 16245916cd2Sjpk msg = gettext( 16345916cd2Sjpk "Can't access DAC file for the device specified."); 16445916cd2Sjpk break; 16545916cd2Sjpk case DAOFFERR: 16645916cd2Sjpk msg = gettext( 16745916cd2Sjpk "Device allocation feature is not activated " 16845916cd2Sjpk "on this system."); 16945916cd2Sjpk break; 17045916cd2Sjpk case DAUTHERR: 17145916cd2Sjpk msg = gettext("Device not allocatable."); 17245916cd2Sjpk break; 17345916cd2Sjpk case DEFATTRSERR: 17445916cd2Sjpk msg = gettext("No default attributes for specified " 17545916cd2Sjpk "device type."); 17645916cd2Sjpk break; 17745916cd2Sjpk case DEVLKERR: 17845916cd2Sjpk msg = gettext("Concurrent operations for specified device, " 17945916cd2Sjpk "try later."); 18045916cd2Sjpk break; 18145916cd2Sjpk case DEVLONGERR: 18245916cd2Sjpk msg = gettext("Device name is too long."); 18345916cd2Sjpk break; 18445916cd2Sjpk case DEVNALLOCERR: 18545916cd2Sjpk msg = gettext("Device not allocated."); 18645916cd2Sjpk break; 18745916cd2Sjpk case DEVNAMEERR: 18845916cd2Sjpk msg = gettext("Device name error."); 18945916cd2Sjpk break; 19045916cd2Sjpk case DEVSTATEERR: 19145916cd2Sjpk msg = gettext("Device specified is in allocate error state."); 19245916cd2Sjpk break; 19345916cd2Sjpk case DEVZONEERR: 19445916cd2Sjpk msg = gettext("Can't find name of the zone to which " 19545916cd2Sjpk "device is allocated."); 19645916cd2Sjpk break; 19745916cd2Sjpk case DSPMISSERR: 1987c478bd9Sstevel@tonic-gate msg = gettext( 1997c478bd9Sstevel@tonic-gate "Device special file(s) missing for specified device."); 2007c478bd9Sstevel@tonic-gate break; 20145916cd2Sjpk case LABELRNGERR: 20245916cd2Sjpk msg = gettext( 20345916cd2Sjpk "Operation inconsistent with device's label range."); 2047c478bd9Sstevel@tonic-gate break; 20545916cd2Sjpk case LOGINDEVPERMERR: 20645916cd2Sjpk msg = gettext("Device controlled by logindevperm(4)"); 2077c478bd9Sstevel@tonic-gate break; 20845916cd2Sjpk case NODAERR: 20945916cd2Sjpk msg = gettext("No entry for specified device."); 21045916cd2Sjpk break; 21145916cd2Sjpk case NODMAPERR: 21245916cd2Sjpk msg = gettext("No entry for specified device."); 21345916cd2Sjpk break; 21445916cd2Sjpk case PREALLOCERR: 2157c478bd9Sstevel@tonic-gate msg = gettext("Device already allocated."); 2167c478bd9Sstevel@tonic-gate break; 21745916cd2Sjpk case SETACLERR: 21845916cd2Sjpk msg = gettext("Failed to set ACL."); 2197c478bd9Sstevel@tonic-gate break; 22045916cd2Sjpk case UAUTHERR: 22145916cd2Sjpk msg = gettext( 22245916cd2Sjpk "User lacks authorization required for this operation."); 2237c478bd9Sstevel@tonic-gate break; 22445916cd2Sjpk case ZONEERR: 22545916cd2Sjpk msg = gettext("Failed to configure device in zone."); 2267c478bd9Sstevel@tonic-gate break; 2277c478bd9Sstevel@tonic-gate default: 2287c478bd9Sstevel@tonic-gate msg = gettext("Unknown error code."); 2297c478bd9Sstevel@tonic-gate break; 2307c478bd9Sstevel@tonic-gate } 2317c478bd9Sstevel@tonic-gate 23245916cd2Sjpk if (windowing) { 23345916cd2Sjpk (void) snprintf(msgbuf, sizeof (msgbuf), "%s: %s\n", name, msg); 23445916cd2Sjpk (void) wdwmsg(name, msgbuf); 23545916cd2Sjpk } else { 2367c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "%s: %s\n", name, msg); 2377c478bd9Sstevel@tonic-gate (void) fflush(stderr); 2387c478bd9Sstevel@tonic-gate } 23945916cd2Sjpk } 2407c478bd9Sstevel@tonic-gate 2417c478bd9Sstevel@tonic-gate char *newenv[] = {"PATH=/usr/bin:/usr/sbin", 2427c478bd9Sstevel@tonic-gate NULL, /* for LC_ALL */ 2437c478bd9Sstevel@tonic-gate NULL, /* for LC_COLLATE */ 2447c478bd9Sstevel@tonic-gate NULL, /* for LC_CTYPE */ 2457c478bd9Sstevel@tonic-gate NULL, /* for LC_MESSAGES */ 2467c478bd9Sstevel@tonic-gate NULL, /* for LC_NUMERIC */ 2477c478bd9Sstevel@tonic-gate NULL, /* for LC_TIME */ 2487c478bd9Sstevel@tonic-gate NULL, /* for LANG */ 2497c478bd9Sstevel@tonic-gate NULL 2507c478bd9Sstevel@tonic-gate }; 2517c478bd9Sstevel@tonic-gate 2527c478bd9Sstevel@tonic-gate static char * 2537c478bd9Sstevel@tonic-gate getenvent(char *name, char *env[]) 2547c478bd9Sstevel@tonic-gate { 2557c478bd9Sstevel@tonic-gate for (; *env != NULL; env++) { 2567c478bd9Sstevel@tonic-gate if (strncmp(*env, name, strlen(name)) == 0) 2577c478bd9Sstevel@tonic-gate return (*env); 2587c478bd9Sstevel@tonic-gate } 2597c478bd9Sstevel@tonic-gate return (NULL); 2607c478bd9Sstevel@tonic-gate } 2617c478bd9Sstevel@tonic-gate 2627c478bd9Sstevel@tonic-gate int 2637c478bd9Sstevel@tonic-gate main(int argc, char *argv[], char *envp[]) 2647c478bd9Sstevel@tonic-gate { 2657c478bd9Sstevel@tonic-gate char *name, *env; 26640e2b7c9Spaulson int func = -1, optflg = 0, error = 0, c; 26745916cd2Sjpk zoneid_t zoneid; 26845916cd2Sjpk uid_t uid; 26945916cd2Sjpk char *uname = NULL, *device = NULL, *zonename = NULL; 27045916cd2Sjpk char *zname; 27145916cd2Sjpk char pw_buf[NSS_BUFLEN_PASSWD]; 27245916cd2Sjpk struct passwd pw_ent; 2737c478bd9Sstevel@tonic-gate int env_num = 1; /* PATH= is 0 entry */ 274*facf4a8dSllai1 #ifdef DEBUG 275*facf4a8dSllai1 struct stat statbuf; 276*facf4a8dSllai1 #endif 2777c478bd9Sstevel@tonic-gate 2787c478bd9Sstevel@tonic-gate (void) setlocale(LC_ALL, ""); 2797c478bd9Sstevel@tonic-gate (void) textdomain(TEXT_DOMAIN); 2807c478bd9Sstevel@tonic-gate 28145916cd2Sjpk system_labeled = is_system_labeled(); 28245916cd2Sjpk 283*facf4a8dSllai1 /* test hook: see also mkdevalloc.c and devfsadm.c */ 284*facf4a8dSllai1 if (!system_labeled) { 285*facf4a8dSllai1 system_labeled = is_system_labeled_debug(&statbuf); 286*facf4a8dSllai1 if (system_labeled) { 287*facf4a8dSllai1 fprintf(stderr, "/ALLOCATE_FORCE_LABEL is set,\n" 288*facf4a8dSllai1 "forcing system label on for testing...\n"); 289*facf4a8dSllai1 } 290*facf4a8dSllai1 } 291*facf4a8dSllai1 2927c478bd9Sstevel@tonic-gate /* 2937c478bd9Sstevel@tonic-gate * get all enviroment variables 2947c478bd9Sstevel@tonic-gate * which affect on internationalization. 2957c478bd9Sstevel@tonic-gate */ 2967c478bd9Sstevel@tonic-gate env = getenvent("LC_ALL=", envp); 2977c478bd9Sstevel@tonic-gate if (env != NULL) 2987c478bd9Sstevel@tonic-gate newenv[env_num++] = env; 2997c478bd9Sstevel@tonic-gate env = getenvent("LC_COLLATE=", envp); 3007c478bd9Sstevel@tonic-gate if (env != NULL) 3017c478bd9Sstevel@tonic-gate newenv[env_num++] = env; 3027c478bd9Sstevel@tonic-gate env = getenvent("LC_CTYPE=", envp); 3037c478bd9Sstevel@tonic-gate if (env != NULL) 3047c478bd9Sstevel@tonic-gate newenv[env_num++] = env; 3057c478bd9Sstevel@tonic-gate env = getenvent("LC_MESSAGES=", envp); 3067c478bd9Sstevel@tonic-gate if (env != NULL) 3077c478bd9Sstevel@tonic-gate newenv[env_num++] = env; 3087c478bd9Sstevel@tonic-gate env = getenvent("LC_NUMERIC=", envp); 3097c478bd9Sstevel@tonic-gate if (env != NULL) 3107c478bd9Sstevel@tonic-gate newenv[env_num++] = env; 3117c478bd9Sstevel@tonic-gate env = getenvent("LC_TIME=", envp); 3127c478bd9Sstevel@tonic-gate if (env != NULL) 3137c478bd9Sstevel@tonic-gate newenv[env_num++] = env; 3147c478bd9Sstevel@tonic-gate env = getenvent("LANG=", envp); 3157c478bd9Sstevel@tonic-gate if (env != NULL) 3167c478bd9Sstevel@tonic-gate newenv[env_num] = env; 3177c478bd9Sstevel@tonic-gate 3187c478bd9Sstevel@tonic-gate if ((name = strrchr(argv[0], '/')) == NULL) 3197c478bd9Sstevel@tonic-gate name = argv[0]; 3207c478bd9Sstevel@tonic-gate else 3217c478bd9Sstevel@tonic-gate name++; 3227c478bd9Sstevel@tonic-gate 32345916cd2Sjpk if (strcmp(name, ALLOC) == 0) 3247c478bd9Sstevel@tonic-gate func = 0; 32545916cd2Sjpk else if (strcmp(name, DEALLOC) == 0) 3267c478bd9Sstevel@tonic-gate func = 1; 32745916cd2Sjpk else if (strcmp(name, LIST) == 0) 3287c478bd9Sstevel@tonic-gate func = 2; 32945916cd2Sjpk else 33045916cd2Sjpk usage(-1); 3317c478bd9Sstevel@tonic-gate 3327c478bd9Sstevel@tonic-gate audit_allocate_argv(func, argc, argv); 3337c478bd9Sstevel@tonic-gate 33445916cd2Sjpk if (system_labeled) { 33545916cd2Sjpk /* 33645916cd2Sjpk * allocate, deallocate, list_devices run in 33745916cd2Sjpk * global zone only. 33845916cd2Sjpk */ 33945916cd2Sjpk zoneid = getzoneid(); 34045916cd2Sjpk if (zoneid != GLOBAL_ZONEID) 34145916cd2Sjpk exit(GLOBALERR); 34245916cd2Sjpk zname = GLOBAL_ZONENAME; 34345916cd2Sjpk /* 34445916cd2Sjpk * check if device allocation is activated. 34545916cd2Sjpk */ 34645916cd2Sjpk if (da_is_on() == 0) { 34745916cd2Sjpk (void) fprintf(stderr, "%s%s", 34845916cd2Sjpk gettext("Turn device allocation on"), 34945916cd2Sjpk gettext(" to use this feature.\n")); 35045916cd2Sjpk exit(DAOFFERR); 35145916cd2Sjpk } 35245916cd2Sjpk } 35345916cd2Sjpk 35440e2b7c9Spaulson if (func == 0) { /* allocate */ 35545916cd2Sjpk while ((c = getopt(argc, argv, "gswz:FU:")) != -1) { 35640e2b7c9Spaulson switch (c) { 35745916cd2Sjpk case 'g': 35845916cd2Sjpk optflg |= TYPE; 35945916cd2Sjpk break; 36040e2b7c9Spaulson case 's': 36140e2b7c9Spaulson optflg |= SILENT; 36240e2b7c9Spaulson break; 36345916cd2Sjpk case 'w': 36445916cd2Sjpk if (system_labeled) { 36545916cd2Sjpk optflg |= WINDOWING; 36645916cd2Sjpk windowing = 1; 36745916cd2Sjpk } else { 36845916cd2Sjpk usage(func); 36945916cd2Sjpk } 37045916cd2Sjpk break; 37145916cd2Sjpk case 'z': 37245916cd2Sjpk if (system_labeled) { 37345916cd2Sjpk optflg |= ZONENAME; 37445916cd2Sjpk zonename = optarg; 37545916cd2Sjpk } else { 37645916cd2Sjpk usage(func); 37745916cd2Sjpk } 37845916cd2Sjpk break; 37945916cd2Sjpk case 'F': 38045916cd2Sjpk optflg |= FORCE; 38145916cd2Sjpk break; 38240e2b7c9Spaulson case 'U': 38340e2b7c9Spaulson optflg |= USERNAME; 38440e2b7c9Spaulson uname = optarg; 38540e2b7c9Spaulson break; 38640e2b7c9Spaulson case '?': 38740e2b7c9Spaulson default : 38840e2b7c9Spaulson usage(func); 38940e2b7c9Spaulson } 39040e2b7c9Spaulson } 39140e2b7c9Spaulson 39240e2b7c9Spaulson /* 39340e2b7c9Spaulson * allocate(1) must be supplied with one device argument 39440e2b7c9Spaulson */ 39540e2b7c9Spaulson if ((argc - optind) != 1) { 39640e2b7c9Spaulson usage(func); 39740e2b7c9Spaulson } else { 39840e2b7c9Spaulson device = argv[optind]; 39940e2b7c9Spaulson } 40040e2b7c9Spaulson } 40140e2b7c9Spaulson 40240e2b7c9Spaulson else if (func == 1) { /* deallocate */ 40345916cd2Sjpk while ((c = getopt(argc, argv, "gswz:FI")) != -1) { 40440e2b7c9Spaulson switch (c) { 40545916cd2Sjpk case 'g': 40645916cd2Sjpk if (system_labeled) 40745916cd2Sjpk optflg |= TYPE; 40845916cd2Sjpk else 40945916cd2Sjpk usage(func); 41045916cd2Sjpk break; 41140e2b7c9Spaulson case 's': 41240e2b7c9Spaulson optflg |= SILENT; 41340e2b7c9Spaulson break; 41445916cd2Sjpk case 'w': 41545916cd2Sjpk if (system_labeled) { 41645916cd2Sjpk optflg |= WINDOWING; 41745916cd2Sjpk windowing = 1; 41845916cd2Sjpk } else { 41945916cd2Sjpk usage(func); 42045916cd2Sjpk } 42145916cd2Sjpk break; 42245916cd2Sjpk case 'z': 42345916cd2Sjpk if (system_labeled) { 42445916cd2Sjpk optflg |= ZONENAME; 42545916cd2Sjpk zonename = optarg; 42645916cd2Sjpk } else { 42745916cd2Sjpk usage(func); 42845916cd2Sjpk } 42945916cd2Sjpk break; 43040e2b7c9Spaulson case 'F': 43140e2b7c9Spaulson optflg |= FORCE; 43240e2b7c9Spaulson break; 43340e2b7c9Spaulson case 'I': 43440e2b7c9Spaulson optflg |= FORCE_ALL; 43540e2b7c9Spaulson break; 43640e2b7c9Spaulson case '?': 43740e2b7c9Spaulson default : 43840e2b7c9Spaulson usage(func); 43940e2b7c9Spaulson } 44040e2b7c9Spaulson } 44140e2b7c9Spaulson 44240e2b7c9Spaulson if ((optflg & FORCE) && (optflg & FORCE_ALL)) 44340e2b7c9Spaulson usage(func); 44440e2b7c9Spaulson 44545916cd2Sjpk if (system_labeled && ((optflg & FORCE_ALL) && (optflg & TYPE))) 44645916cd2Sjpk usage(func); 44745916cd2Sjpk 44840e2b7c9Spaulson /* 44940e2b7c9Spaulson * deallocate(1) must be supplied with one device 45040e2b7c9Spaulson * argument unless the '-I' argument is supplied 45140e2b7c9Spaulson */ 45240e2b7c9Spaulson if (!(optflg & FORCE_ALL)) { 45340e2b7c9Spaulson if ((argc - optind) != 1) { 45440e2b7c9Spaulson usage(func); 45540e2b7c9Spaulson } else { 45640e2b7c9Spaulson device = argv[optind]; 45740e2b7c9Spaulson } 45840e2b7c9Spaulson } else { 45940e2b7c9Spaulson if ((argc - optind) >= 1) { 46040e2b7c9Spaulson usage(func); 46140e2b7c9Spaulson } 46240e2b7c9Spaulson } 46340e2b7c9Spaulson } 46440e2b7c9Spaulson 46540e2b7c9Spaulson else if (func == 2) { /* list_devices */ 46645916cd2Sjpk while ((c = getopt(argc, argv, "adlnsuwz:U:")) != -1) { 4677c478bd9Sstevel@tonic-gate switch (c) { 46845916cd2Sjpk case 'a': 46945916cd2Sjpk if (system_labeled) { 47045916cd2Sjpk /* 47145916cd2Sjpk * list auths, cleaning programs, 47245916cd2Sjpk * labels. 47345916cd2Sjpk */ 47445916cd2Sjpk optflg |= LISTATTRS; 47545916cd2Sjpk } else { 47645916cd2Sjpk usage(func); 47745916cd2Sjpk } 47845916cd2Sjpk break; 47945916cd2Sjpk case 'd': 48045916cd2Sjpk if (system_labeled) { 48145916cd2Sjpk /* 48245916cd2Sjpk * list devalloc_defaults 48345916cd2Sjpk */ 48445916cd2Sjpk optflg |= LISTDEFS; 48545916cd2Sjpk } else { 48645916cd2Sjpk usage(func); 48745916cd2Sjpk } 48845916cd2Sjpk break; 48945916cd2Sjpk case 'l': 49045916cd2Sjpk optflg |= LISTALL; 49145916cd2Sjpk break; 49245916cd2Sjpk case 'n': 49345916cd2Sjpk optflg |= LISTFREE; 49445916cd2Sjpk break; 4957c478bd9Sstevel@tonic-gate case 's': 4967c478bd9Sstevel@tonic-gate optflg |= SILENT; 4977c478bd9Sstevel@tonic-gate break; 49845916cd2Sjpk case 'u': 49945916cd2Sjpk optflg |= LISTALLOC; 50045916cd2Sjpk break; 50145916cd2Sjpk case 'w': 50245916cd2Sjpk if (system_labeled) { 50345916cd2Sjpk /* 50445916cd2Sjpk * Private interface for use by 50545916cd2Sjpk * list_devices GUI 50645916cd2Sjpk */ 50745916cd2Sjpk optflg |= WINDOWING; 50845916cd2Sjpk } else { 50945916cd2Sjpk usage(func); 51045916cd2Sjpk } 51145916cd2Sjpk break; 51245916cd2Sjpk case 'z': 51345916cd2Sjpk if (system_labeled) { 51445916cd2Sjpk optflg |= ZONENAME; 51545916cd2Sjpk zonename = optarg; 51645916cd2Sjpk } else { 51745916cd2Sjpk usage(func); 51845916cd2Sjpk } 51945916cd2Sjpk break; 5207c478bd9Sstevel@tonic-gate case 'U': 5217c478bd9Sstevel@tonic-gate optflg |= USERID; 52240e2b7c9Spaulson uid = atoi(optarg); 5237c478bd9Sstevel@tonic-gate break; 5247c478bd9Sstevel@tonic-gate case '?': 5257c478bd9Sstevel@tonic-gate default : 5267c478bd9Sstevel@tonic-gate usage(func); 52740e2b7c9Spaulson } 5287c478bd9Sstevel@tonic-gate } 5297c478bd9Sstevel@tonic-gate 53045916cd2Sjpk if (system_labeled) { 53145916cd2Sjpk if (((optflg & LISTALL) && (optflg & LISTFREE)) || 53245916cd2Sjpk ((optflg & LISTALL) && (optflg & LISTALLOC)) || 53345916cd2Sjpk ((optflg & LISTFREE) && (optflg & LISTALLOC)) || 53445916cd2Sjpk ((optflg & LISTDEFS) && 53545916cd2Sjpk (optflg & (LISTATTRS | LISTALL | LISTFREE | 53645916cd2Sjpk LISTALLOC | USERID | WINDOWING | ZONENAME))) || 53745916cd2Sjpk (!(optflg & (LISTALL | LISTFREE | LISTALLOC | 53845916cd2Sjpk LISTDEFS | WINDOWING)))) 53940e2b7c9Spaulson usage(func); 54045916cd2Sjpk } else if (((optflg & LISTALL) && (optflg & LISTFREE)) || 54145916cd2Sjpk ((optflg & LISTALL) && (optflg & LISTALLOC)) || 54245916cd2Sjpk ((optflg & LISTFREE) && (optflg & LISTALLOC)) || 54345916cd2Sjpk (!(optflg & (LISTALL | LISTFREE | LISTALLOC)))) { 54445916cd2Sjpk usage(func); 54545916cd2Sjpk } 54640e2b7c9Spaulson 54740e2b7c9Spaulson /* 54840e2b7c9Spaulson * list_devices(1) takes an optional device argument 54940e2b7c9Spaulson */ 55040e2b7c9Spaulson if ((argc - optind) == 1) { 55140e2b7c9Spaulson device = argv[optind]; 55240e2b7c9Spaulson } else { 55340e2b7c9Spaulson if ((argc - optind) > 1) { 55440e2b7c9Spaulson usage(func); 55540e2b7c9Spaulson } 55640e2b7c9Spaulson } 55740e2b7c9Spaulson } 55840e2b7c9Spaulson 55940e2b7c9Spaulson if (optflg & USERNAME) { 56045916cd2Sjpk if (getpwnam_r(uname, &pw_ent, pw_buf, sizeof (pw_buf)) == 56145916cd2Sjpk NULL) { 56245916cd2Sjpk (void) fprintf(stderr, 56345916cd2Sjpk gettext("Invalid user name -- %s -- \n"), uname); 56440e2b7c9Spaulson exit(1); 56540e2b7c9Spaulson } 56645916cd2Sjpk uid = pw_ent.pw_uid; 56745916cd2Sjpk } else if (optflg & USERID) { 56845916cd2Sjpk if (getpwuid_r(uid, &pw_ent, pw_buf, sizeof (pw_buf)) == NULL) { 56945916cd2Sjpk (void) fprintf(stderr, 57045916cd2Sjpk gettext("Invalid user ID -- %d -- \n"), uid); 57140e2b7c9Spaulson exit(1); 5727c478bd9Sstevel@tonic-gate } 57345916cd2Sjpk uid = pw_ent.pw_uid; 57445916cd2Sjpk } else { 57545916cd2Sjpk /* 57645916cd2Sjpk * caller's uid is the default if no user specified. 57745916cd2Sjpk */ 57845916cd2Sjpk uid = getuid(); 5797c478bd9Sstevel@tonic-gate } 5807c478bd9Sstevel@tonic-gate 58145916cd2Sjpk /* 58245916cd2Sjpk * global zone is the default if no zonename specified. 58345916cd2Sjpk */ 58445916cd2Sjpk if (zonename == NULL) { 58545916cd2Sjpk zonename = zname; 58645916cd2Sjpk } else { 58745916cd2Sjpk if (zone_get_id(zonename, &zoneid) != 0) { 58845916cd2Sjpk (void) fprintf(stderr, 58945916cd2Sjpk gettext("Invalid zone name -- %s -- \n"), zonename); 59045916cd2Sjpk exit(1); 5917c478bd9Sstevel@tonic-gate } 59245916cd2Sjpk } 59345916cd2Sjpk 59445916cd2Sjpk if (func == 0) 59545916cd2Sjpk error = allocate(optflg, uid, device, zonename); 59645916cd2Sjpk else if (func == 1) 59745916cd2Sjpk error = deallocate(optflg, uid, device, zonename); 59845916cd2Sjpk else if (func == 2) 59945916cd2Sjpk error = list_devices(optflg, uid, device, zonename); 60040e2b7c9Spaulson 6017c478bd9Sstevel@tonic-gate (void) audit_allocate_record(error); 6027c478bd9Sstevel@tonic-gate 6037c478bd9Sstevel@tonic-gate if (error) { 6047c478bd9Sstevel@tonic-gate if (!(optflg & SILENT)) 6057c478bd9Sstevel@tonic-gate print_error(error, name); 6067c478bd9Sstevel@tonic-gate exit(error); 6077c478bd9Sstevel@tonic-gate } 6087c478bd9Sstevel@tonic-gate 6097c478bd9Sstevel@tonic-gate return (0); 6107c478bd9Sstevel@tonic-gate } 61145916cd2Sjpk 61245916cd2Sjpk /* 61345916cd2Sjpk * Display error message via /etc/security/lib/wdwmsg script 61445916cd2Sjpk */ 61545916cd2Sjpk static int 61645916cd2Sjpk wdwmsg(char *name, char *msg) 61745916cd2Sjpk { 61845916cd2Sjpk pid_t child_pid; 61945916cd2Sjpk pid_t wait_pid; 62045916cd2Sjpk int child_status; 62145916cd2Sjpk 62245916cd2Sjpk /* Fork a child */ 62345916cd2Sjpk switch (child_pid = fork()) { 62445916cd2Sjpk case -1: /* FAILURE */ 62545916cd2Sjpk return (-1); 62645916cd2Sjpk break; 62745916cd2Sjpk 62845916cd2Sjpk case 0: /* CHILD */ 62945916cd2Sjpk (void) execl("/etc/security/lib/wdwmsg", "wdwmsg", msg, 63045916cd2Sjpk name, "OK", NULL); 63145916cd2Sjpk /* If exec failed, send message to stderr */ 63245916cd2Sjpk (void) fprintf(stderr, "%s", msg); 63345916cd2Sjpk return (-1); 63445916cd2Sjpk 63545916cd2Sjpk default: /* PARENT */ 63645916cd2Sjpk /* Wait for child to exit */ 63745916cd2Sjpk wait_pid = waitpid(child_pid, &child_status, 0); 63845916cd2Sjpk if ((wait_pid < 0) && (errno == ECHILD)) 63945916cd2Sjpk return (0); 64045916cd2Sjpk if ((wait_pid < 0) || (wait_pid != child_pid)) 64145916cd2Sjpk return (-1); 64245916cd2Sjpk if (WIFEXITED(child_status)) 64345916cd2Sjpk return (WEXITSTATUS(child_status)); 64445916cd2Sjpk if (WIFSIGNALED(child_status)) 64545916cd2Sjpk return (WTERMSIG(child_status)); 64645916cd2Sjpk return (0); 64745916cd2Sjpk } 64845916cd2Sjpk } 649