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 /*
23*10ddde3aSaj * Copyright 2007 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>
37facf4a8dSllai1 #include <fcntl.h>
3845916cd2Sjpk #include <nss_dbdefs.h>
397c478bd9Sstevel@tonic-gate #include <sys/types.h>
40facf4a8dSllai1 #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
usage(int func)637c478bd9Sstevel@tonic-gate usage(int func)
647c478bd9Sstevel@tonic-gate {
6545916cd2Sjpk if (system_labeled) {
66*10ddde3aSaj char *use[6];
6745916cd2Sjpk
6845916cd2Sjpk use[0] = gettext("allocate [-s] [-w] [-U uname] [-z zonename] "
69*10ddde3aSaj "[-F] device|-g dev-type");
70*10ddde3aSaj use[1] = gettext("deallocate [-s] [-w] [-z zonename] "
71*10ddde3aSaj "[-F] device|-c dev-class|-g dev-type");
72*10ddde3aSaj use[2] = gettext("deallocate [-s] [-w] [-z zonename] -I");
73*10ddde3aSaj use[3] = gettext("list_devices [-s] [-U uid] [-z zonename] "
74*10ddde3aSaj "[-a [-w]] -l|-n|-u [device]");
75*10ddde3aSaj use[4] = gettext("list_devices [-s] [-U uid] [-z zonename] "
76*10ddde3aSaj "[-a [-w]] [-l|-n|-u] -c dev-class");
77*10ddde3aSaj use[5] = gettext("list_devices [-s] -d [dev-type]");
7845916cd2Sjpk
7945916cd2Sjpk switch (func) {
8045916cd2Sjpk case 0:
81*10ddde3aSaj (void) fprintf(stderr, "%s\n", use[0]);
8245916cd2Sjpk break;
8345916cd2Sjpk case 1:
84*10ddde3aSaj (void) fprintf(stderr, "%s\n%s\n",
85*10ddde3aSaj use[1], use[2]);
8645916cd2Sjpk break;
8745916cd2Sjpk case 2:
88*10ddde3aSaj (void) fprintf(stderr, "%s\n%s\n%s\n",
89*10ddde3aSaj use[3], use[4], use[5]);
9045916cd2Sjpk break;
9145916cd2Sjpk default:
9245916cd2Sjpk (void) fprintf(stderr,
93*10ddde3aSaj "%s\n%s\n%s\n%s\n%s\n%s\n",
9445916cd2Sjpk use[0], use[1], use[2], use[3], use[4],
95*10ddde3aSaj use[5]);
9645916cd2Sjpk }
9745916cd2Sjpk } else {
98*10ddde3aSaj char *use[5];
997c478bd9Sstevel@tonic-gate
100*10ddde3aSaj use[0] = gettext("allocate "
101*10ddde3aSaj "[-s] [-U uname] [-F] device|-g dev-type");
102*10ddde3aSaj use[1] = gettext("deallocate [-s] [-F] device|-c dev-class");
103*10ddde3aSaj use[2] = gettext("deallocate [-s] -I");
104*10ddde3aSaj use[3] = gettext("list_devices "
105*10ddde3aSaj "[-s] [-U uid] -l|-n|-u [device]");
106*10ddde3aSaj use[4] = gettext("list_devices "
107*10ddde3aSaj "[-s] [-U uid] [-l|-n|-u] -c dev-class");
1087c478bd9Sstevel@tonic-gate
1097c478bd9Sstevel@tonic-gate switch (func) {
1107c478bd9Sstevel@tonic-gate case 0:
111*10ddde3aSaj (void) fprintf(stderr, "%s\n", use[0]);
1127c478bd9Sstevel@tonic-gate break;
1137c478bd9Sstevel@tonic-gate case 1:
11445916cd2Sjpk (void) fprintf(stderr, "%s\n%s\n",
115*10ddde3aSaj use[1], use[2]);
1167c478bd9Sstevel@tonic-gate break;
1177c478bd9Sstevel@tonic-gate case 2:
118*10ddde3aSaj (void) fprintf(stderr, "%s\n%s\n",
119*10ddde3aSaj use[3], use[4]);
1207c478bd9Sstevel@tonic-gate break;
1217c478bd9Sstevel@tonic-gate default:
122*10ddde3aSaj (void) fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n",
123*10ddde3aSaj use[0], use[1], use[2], use[3], use[4]);
12445916cd2Sjpk }
1257c478bd9Sstevel@tonic-gate }
12640e2b7c9Spaulson exit(1);
1277c478bd9Sstevel@tonic-gate }
1287c478bd9Sstevel@tonic-gate
12945916cd2Sjpk void
print_error(int error,char * name)1307c478bd9Sstevel@tonic-gate print_error(int error, char *name)
1317c478bd9Sstevel@tonic-gate {
1327c478bd9Sstevel@tonic-gate char *msg;
13345916cd2Sjpk char msgbuf[200];
1347c478bd9Sstevel@tonic-gate
1357c478bd9Sstevel@tonic-gate switch (error) {
13645916cd2Sjpk case ALLOCUERR:
1377c478bd9Sstevel@tonic-gate msg = gettext("Specified device is allocated to another user.");
1387c478bd9Sstevel@tonic-gate break;
13945916cd2Sjpk case CHOWNERR:
14045916cd2Sjpk msg = gettext("Failed to chown.");
1417c478bd9Sstevel@tonic-gate break;
14245916cd2Sjpk case CLEANERR:
14345916cd2Sjpk msg = gettext("Unable to clean up device.");
1447c478bd9Sstevel@tonic-gate break;
14545916cd2Sjpk case CNTDEXECERR:
1467c478bd9Sstevel@tonic-gate msg = gettext(
1477c478bd9Sstevel@tonic-gate "Can't exec device-clean program for specified device.");
1487c478bd9Sstevel@tonic-gate break;
14945916cd2Sjpk case CNTFRCERR:
15045916cd2Sjpk msg = gettext("Can't force deallocate specified device.");
1517c478bd9Sstevel@tonic-gate break;
15245916cd2Sjpk case DACACCERR:
15345916cd2Sjpk msg = gettext(
15445916cd2Sjpk "Can't access DAC file for the device specified.");
15545916cd2Sjpk break;
15645916cd2Sjpk case DAOFFERR:
15745916cd2Sjpk msg = gettext(
15845916cd2Sjpk "Device allocation feature is not activated "
15945916cd2Sjpk "on this system.");
16045916cd2Sjpk break;
16145916cd2Sjpk case DAUTHERR:
16245916cd2Sjpk msg = gettext("Device not allocatable.");
16345916cd2Sjpk break;
16445916cd2Sjpk case DEFATTRSERR:
16545916cd2Sjpk msg = gettext("No default attributes for specified "
16645916cd2Sjpk "device type.");
16745916cd2Sjpk break;
16845916cd2Sjpk case DEVLKERR:
16945916cd2Sjpk msg = gettext("Concurrent operations for specified device, "
17045916cd2Sjpk "try later.");
17145916cd2Sjpk break;
17245916cd2Sjpk case DEVLONGERR:
17345916cd2Sjpk msg = gettext("Device name is too long.");
17445916cd2Sjpk break;
17545916cd2Sjpk case DEVNALLOCERR:
17645916cd2Sjpk msg = gettext("Device not allocated.");
17745916cd2Sjpk break;
17845916cd2Sjpk case DEVNAMEERR:
17945916cd2Sjpk msg = gettext("Device name error.");
18045916cd2Sjpk break;
18145916cd2Sjpk case DEVSTATEERR:
18245916cd2Sjpk msg = gettext("Device specified is in allocate error state.");
18345916cd2Sjpk break;
18445916cd2Sjpk case DEVZONEERR:
18545916cd2Sjpk msg = gettext("Can't find name of the zone to which "
18645916cd2Sjpk "device is allocated.");
18745916cd2Sjpk break;
18845916cd2Sjpk case DSPMISSERR:
1897c478bd9Sstevel@tonic-gate msg = gettext(
1907c478bd9Sstevel@tonic-gate "Device special file(s) missing for specified device.");
1917c478bd9Sstevel@tonic-gate break;
19245916cd2Sjpk case LABELRNGERR:
19345916cd2Sjpk msg = gettext(
19445916cd2Sjpk "Operation inconsistent with device's label range.");
1957c478bd9Sstevel@tonic-gate break;
19645916cd2Sjpk case LOGINDEVPERMERR:
19745916cd2Sjpk msg = gettext("Device controlled by logindevperm(4)");
1987c478bd9Sstevel@tonic-gate break;
19945916cd2Sjpk case NODAERR:
20045916cd2Sjpk msg = gettext("No entry for specified device.");
20145916cd2Sjpk break;
20245916cd2Sjpk case NODMAPERR:
20345916cd2Sjpk msg = gettext("No entry for specified device.");
20445916cd2Sjpk break;
20545916cd2Sjpk case PREALLOCERR:
2067c478bd9Sstevel@tonic-gate msg = gettext("Device already allocated.");
2077c478bd9Sstevel@tonic-gate break;
20845916cd2Sjpk case SETACLERR:
20945916cd2Sjpk msg = gettext("Failed to set ACL.");
2107c478bd9Sstevel@tonic-gate break;
21145916cd2Sjpk case UAUTHERR:
21245916cd2Sjpk msg = gettext(
21345916cd2Sjpk "User lacks authorization required for this operation.");
2147c478bd9Sstevel@tonic-gate break;
21545916cd2Sjpk case ZONEERR:
21645916cd2Sjpk msg = gettext("Failed to configure device in zone.");
2177c478bd9Sstevel@tonic-gate break;
2187c478bd9Sstevel@tonic-gate default:
2197c478bd9Sstevel@tonic-gate msg = gettext("Unknown error code.");
2207c478bd9Sstevel@tonic-gate break;
2217c478bd9Sstevel@tonic-gate }
2227c478bd9Sstevel@tonic-gate
22345916cd2Sjpk if (windowing) {
22445916cd2Sjpk (void) snprintf(msgbuf, sizeof (msgbuf), "%s: %s\n", name, msg);
22545916cd2Sjpk (void) wdwmsg(name, msgbuf);
22645916cd2Sjpk } else {
2277c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "%s: %s\n", name, msg);
2287c478bd9Sstevel@tonic-gate (void) fflush(stderr);
2297c478bd9Sstevel@tonic-gate }
23045916cd2Sjpk }
2317c478bd9Sstevel@tonic-gate
2327c478bd9Sstevel@tonic-gate char *newenv[] = {"PATH=/usr/bin:/usr/sbin",
2337c478bd9Sstevel@tonic-gate NULL, /* for LC_ALL */
2347c478bd9Sstevel@tonic-gate NULL, /* for LC_COLLATE */
2357c478bd9Sstevel@tonic-gate NULL, /* for LC_CTYPE */
2367c478bd9Sstevel@tonic-gate NULL, /* for LC_MESSAGES */
2377c478bd9Sstevel@tonic-gate NULL, /* for LC_NUMERIC */
2387c478bd9Sstevel@tonic-gate NULL, /* for LC_TIME */
2397c478bd9Sstevel@tonic-gate NULL, /* for LANG */
2407c478bd9Sstevel@tonic-gate NULL
2417c478bd9Sstevel@tonic-gate };
2427c478bd9Sstevel@tonic-gate
2437c478bd9Sstevel@tonic-gate static char *
getenvent(char * name,char * env[])2447c478bd9Sstevel@tonic-gate getenvent(char *name, char *env[])
2457c478bd9Sstevel@tonic-gate {
2467c478bd9Sstevel@tonic-gate for (; *env != NULL; env++) {
2477c478bd9Sstevel@tonic-gate if (strncmp(*env, name, strlen(name)) == 0)
2487c478bd9Sstevel@tonic-gate return (*env);
2497c478bd9Sstevel@tonic-gate }
2507c478bd9Sstevel@tonic-gate return (NULL);
2517c478bd9Sstevel@tonic-gate }
2527c478bd9Sstevel@tonic-gate
2537c478bd9Sstevel@tonic-gate int
main(int argc,char * argv[],char * envp[])2547c478bd9Sstevel@tonic-gate main(int argc, char *argv[], char *envp[])
2557c478bd9Sstevel@tonic-gate {
2567c478bd9Sstevel@tonic-gate char *name, *env;
25740e2b7c9Spaulson int func = -1, optflg = 0, error = 0, c;
25845916cd2Sjpk zoneid_t zoneid;
25945916cd2Sjpk uid_t uid;
26045916cd2Sjpk char *uname = NULL, *device = NULL, *zonename = NULL;
26145916cd2Sjpk char *zname;
26245916cd2Sjpk char pw_buf[NSS_BUFLEN_PASSWD];
26345916cd2Sjpk struct passwd pw_ent;
2647c478bd9Sstevel@tonic-gate int env_num = 1; /* PATH= is 0 entry */
265facf4a8dSllai1 #ifdef DEBUG
266facf4a8dSllai1 struct stat statbuf;
267facf4a8dSllai1 #endif
2687c478bd9Sstevel@tonic-gate
2697c478bd9Sstevel@tonic-gate (void) setlocale(LC_ALL, "");
2707c478bd9Sstevel@tonic-gate (void) textdomain(TEXT_DOMAIN);
2717c478bd9Sstevel@tonic-gate
27245916cd2Sjpk system_labeled = is_system_labeled();
27345916cd2Sjpk
274facf4a8dSllai1 /* test hook: see also mkdevalloc.c and devfsadm.c */
275facf4a8dSllai1 if (!system_labeled) {
276facf4a8dSllai1 system_labeled = is_system_labeled_debug(&statbuf);
277facf4a8dSllai1 if (system_labeled) {
278facf4a8dSllai1 fprintf(stderr, "/ALLOCATE_FORCE_LABEL is set,\n"
279facf4a8dSllai1 "forcing system label on for testing...\n");
280facf4a8dSllai1 }
281facf4a8dSllai1 }
282facf4a8dSllai1
2837c478bd9Sstevel@tonic-gate /*
2847c478bd9Sstevel@tonic-gate * get all enviroment variables
2857c478bd9Sstevel@tonic-gate * which affect on internationalization.
2867c478bd9Sstevel@tonic-gate */
2877c478bd9Sstevel@tonic-gate env = getenvent("LC_ALL=", envp);
2887c478bd9Sstevel@tonic-gate if (env != NULL)
2897c478bd9Sstevel@tonic-gate newenv[env_num++] = env;
2907c478bd9Sstevel@tonic-gate env = getenvent("LC_COLLATE=", envp);
2917c478bd9Sstevel@tonic-gate if (env != NULL)
2927c478bd9Sstevel@tonic-gate newenv[env_num++] = env;
2937c478bd9Sstevel@tonic-gate env = getenvent("LC_CTYPE=", envp);
2947c478bd9Sstevel@tonic-gate if (env != NULL)
2957c478bd9Sstevel@tonic-gate newenv[env_num++] = env;
2967c478bd9Sstevel@tonic-gate env = getenvent("LC_MESSAGES=", envp);
2977c478bd9Sstevel@tonic-gate if (env != NULL)
2987c478bd9Sstevel@tonic-gate newenv[env_num++] = env;
2997c478bd9Sstevel@tonic-gate env = getenvent("LC_NUMERIC=", envp);
3007c478bd9Sstevel@tonic-gate if (env != NULL)
3017c478bd9Sstevel@tonic-gate newenv[env_num++] = env;
3027c478bd9Sstevel@tonic-gate env = getenvent("LC_TIME=", envp);
3037c478bd9Sstevel@tonic-gate if (env != NULL)
3047c478bd9Sstevel@tonic-gate newenv[env_num++] = env;
3057c478bd9Sstevel@tonic-gate env = getenvent("LANG=", envp);
3067c478bd9Sstevel@tonic-gate if (env != NULL)
3077c478bd9Sstevel@tonic-gate newenv[env_num] = env;
3087c478bd9Sstevel@tonic-gate
3097c478bd9Sstevel@tonic-gate if ((name = strrchr(argv[0], '/')) == NULL)
3107c478bd9Sstevel@tonic-gate name = argv[0];
3117c478bd9Sstevel@tonic-gate else
3127c478bd9Sstevel@tonic-gate name++;
3137c478bd9Sstevel@tonic-gate
31445916cd2Sjpk if (strcmp(name, ALLOC) == 0)
3157c478bd9Sstevel@tonic-gate func = 0;
31645916cd2Sjpk else if (strcmp(name, DEALLOC) == 0)
3177c478bd9Sstevel@tonic-gate func = 1;
31845916cd2Sjpk else if (strcmp(name, LIST) == 0)
3197c478bd9Sstevel@tonic-gate func = 2;
32045916cd2Sjpk else
32145916cd2Sjpk usage(-1);
3227c478bd9Sstevel@tonic-gate
3237c478bd9Sstevel@tonic-gate audit_allocate_argv(func, argc, argv);
3247c478bd9Sstevel@tonic-gate
32545916cd2Sjpk if (system_labeled) {
32645916cd2Sjpk /*
32745916cd2Sjpk * allocate, deallocate, list_devices run in
32845916cd2Sjpk * global zone only.
32945916cd2Sjpk */
33045916cd2Sjpk zoneid = getzoneid();
33145916cd2Sjpk if (zoneid != GLOBAL_ZONEID)
33245916cd2Sjpk exit(GLOBALERR);
33345916cd2Sjpk zname = GLOBAL_ZONENAME;
33445916cd2Sjpk /*
33545916cd2Sjpk * check if device allocation is activated.
33645916cd2Sjpk */
33745916cd2Sjpk if (da_is_on() == 0) {
33845916cd2Sjpk (void) fprintf(stderr, "%s%s",
33945916cd2Sjpk gettext("Turn device allocation on"),
34045916cd2Sjpk gettext(" to use this feature.\n"));
34145916cd2Sjpk exit(DAOFFERR);
34245916cd2Sjpk }
34345916cd2Sjpk }
34445916cd2Sjpk
34540e2b7c9Spaulson if (func == 0) { /* allocate */
346*10ddde3aSaj while ((c = getopt(argc, argv, "g:swz:FU:")) != -1) {
34740e2b7c9Spaulson switch (c) {
34845916cd2Sjpk case 'g':
34945916cd2Sjpk optflg |= TYPE;
350*10ddde3aSaj device = optarg;
35145916cd2Sjpk break;
35240e2b7c9Spaulson case 's':
35340e2b7c9Spaulson optflg |= SILENT;
35440e2b7c9Spaulson break;
35545916cd2Sjpk case 'w':
35645916cd2Sjpk if (system_labeled) {
35745916cd2Sjpk optflg |= WINDOWING;
35845916cd2Sjpk windowing = 1;
35945916cd2Sjpk } else {
36045916cd2Sjpk usage(func);
36145916cd2Sjpk }
36245916cd2Sjpk break;
36345916cd2Sjpk case 'z':
36445916cd2Sjpk if (system_labeled) {
36545916cd2Sjpk optflg |= ZONENAME;
36645916cd2Sjpk zonename = optarg;
36745916cd2Sjpk } else {
36845916cd2Sjpk usage(func);
36945916cd2Sjpk }
37045916cd2Sjpk break;
37145916cd2Sjpk case 'F':
37245916cd2Sjpk optflg |= FORCE;
37345916cd2Sjpk break;
37440e2b7c9Spaulson case 'U':
37540e2b7c9Spaulson optflg |= USERNAME;
37640e2b7c9Spaulson uname = optarg;
37740e2b7c9Spaulson break;
37840e2b7c9Spaulson case '?':
37940e2b7c9Spaulson default :
38040e2b7c9Spaulson usage(func);
38140e2b7c9Spaulson }
38240e2b7c9Spaulson }
38340e2b7c9Spaulson
38440e2b7c9Spaulson /*
38540e2b7c9Spaulson * allocate(1) must be supplied with one device argument
38640e2b7c9Spaulson */
387*10ddde3aSaj if (device && ((argc - optind) >= 1))
38840e2b7c9Spaulson usage(func);
389*10ddde3aSaj if (device == NULL) {
390*10ddde3aSaj if ((argc - optind) != 1)
391*10ddde3aSaj usage(func);
39240e2b7c9Spaulson device = argv[optind];
39340e2b7c9Spaulson }
39440e2b7c9Spaulson }
39540e2b7c9Spaulson
39640e2b7c9Spaulson else if (func == 1) { /* deallocate */
397*10ddde3aSaj while ((c = getopt(argc, argv, "c:g:swz:FI")) != -1) {
39840e2b7c9Spaulson switch (c) {
399*10ddde3aSaj case 'c':
400*10ddde3aSaj if (optflg & (TYPE | FORCE_ALL))
40145916cd2Sjpk usage(func);
402*10ddde3aSaj optflg |= CLASS;
403*10ddde3aSaj device = optarg;
404*10ddde3aSaj break;
405*10ddde3aSaj case 'g':
406*10ddde3aSaj if (system_labeled) {
407*10ddde3aSaj if (optflg & (CLASS | FORCE_ALL))
408*10ddde3aSaj usage(func);
409*10ddde3aSaj optflg |= TYPE;
410*10ddde3aSaj device = optarg;
411*10ddde3aSaj } else {
412*10ddde3aSaj usage(func);
413*10ddde3aSaj }
41445916cd2Sjpk break;
41540e2b7c9Spaulson case 's':
41640e2b7c9Spaulson optflg |= SILENT;
41740e2b7c9Spaulson break;
41845916cd2Sjpk case 'w':
41945916cd2Sjpk if (system_labeled) {
42045916cd2Sjpk optflg |= WINDOWING;
42145916cd2Sjpk windowing = 1;
42245916cd2Sjpk } else {
42345916cd2Sjpk usage(func);
42445916cd2Sjpk }
42545916cd2Sjpk break;
42645916cd2Sjpk case 'z':
42745916cd2Sjpk if (system_labeled) {
42845916cd2Sjpk optflg |= ZONENAME;
42945916cd2Sjpk zonename = optarg;
43045916cd2Sjpk } else {
43145916cd2Sjpk usage(func);
43245916cd2Sjpk }
43345916cd2Sjpk break;
43440e2b7c9Spaulson case 'F':
435*10ddde3aSaj if (optflg & FORCE_ALL)
436*10ddde3aSaj usage(func);
43740e2b7c9Spaulson optflg |= FORCE;
43840e2b7c9Spaulson break;
43940e2b7c9Spaulson case 'I':
440*10ddde3aSaj if (optflg & (CLASS | TYPE | FORCE))
441*10ddde3aSaj usage(func);
44240e2b7c9Spaulson optflg |= FORCE_ALL;
44340e2b7c9Spaulson break;
44440e2b7c9Spaulson case '?':
44540e2b7c9Spaulson default :
44640e2b7c9Spaulson usage(func);
44740e2b7c9Spaulson }
44840e2b7c9Spaulson }
44940e2b7c9Spaulson
45040e2b7c9Spaulson /*
45140e2b7c9Spaulson * deallocate(1) must be supplied with one device
45240e2b7c9Spaulson * argument unless the '-I' argument is supplied
45340e2b7c9Spaulson */
454*10ddde3aSaj if (device || (optflg & FORCE_ALL)) {
455*10ddde3aSaj if ((argc - optind) >= 1)
45640e2b7c9Spaulson usage(func);
457*10ddde3aSaj } else if (device == NULL) {
458*10ddde3aSaj if ((argc - optind) != 1)
459*10ddde3aSaj usage(func);
46040e2b7c9Spaulson device = argv[optind];
46140e2b7c9Spaulson }
46240e2b7c9Spaulson }
46340e2b7c9Spaulson
46440e2b7c9Spaulson else if (func == 2) { /* list_devices */
465*10ddde3aSaj while ((c = getopt(argc, argv, "ac:dlnsuwz:U:")) != -1) {
4667c478bd9Sstevel@tonic-gate switch (c) {
46745916cd2Sjpk case 'a':
46845916cd2Sjpk if (system_labeled) {
46945916cd2Sjpk /*
47045916cd2Sjpk * list auths, cleaning programs,
47145916cd2Sjpk * labels.
47245916cd2Sjpk */
473*10ddde3aSaj if (optflg & LISTDEFS)
474*10ddde3aSaj usage(func);
47545916cd2Sjpk optflg |= LISTATTRS;
47645916cd2Sjpk } else {
47745916cd2Sjpk usage(func);
47845916cd2Sjpk }
47945916cd2Sjpk break;
480*10ddde3aSaj case 'c':
481*10ddde3aSaj optflg |= CLASS;
482*10ddde3aSaj device = optarg;
483*10ddde3aSaj break;
48445916cd2Sjpk case 'd':
48545916cd2Sjpk if (system_labeled) {
48645916cd2Sjpk /*
487*10ddde3aSaj * List devalloc_defaults
488*10ddde3aSaj * This cannot used with anything other
489*10ddde3aSaj * than -s.
49045916cd2Sjpk */
491*10ddde3aSaj if (optflg & (LISTATTRS | CLASS |
492*10ddde3aSaj LISTALL | LISTFREE | LISTALLOC |
493*10ddde3aSaj WINDOWING | ZONENAME | USERID))
494*10ddde3aSaj usage(func);
49545916cd2Sjpk optflg |= LISTDEFS;
49645916cd2Sjpk } else {
49745916cd2Sjpk usage(func);
49845916cd2Sjpk }
49945916cd2Sjpk break;
50045916cd2Sjpk case 'l':
501*10ddde3aSaj if (optflg & (LISTFREE | LISTALLOC | LISTDEFS))
502*10ddde3aSaj usage(func);
50345916cd2Sjpk optflg |= LISTALL;
50445916cd2Sjpk break;
50545916cd2Sjpk case 'n':
506*10ddde3aSaj if (optflg & (LISTALL | LISTALLOC | LISTDEFS))
507*10ddde3aSaj usage(func);
50845916cd2Sjpk optflg |= LISTFREE;
50945916cd2Sjpk break;
5107c478bd9Sstevel@tonic-gate case 's':
5117c478bd9Sstevel@tonic-gate optflg |= SILENT;
5127c478bd9Sstevel@tonic-gate break;
51345916cd2Sjpk case 'u':
514*10ddde3aSaj if (optflg & (LISTALL | LISTFREE | LISTDEFS))
515*10ddde3aSaj usage(func);
51645916cd2Sjpk optflg |= LISTALLOC;
51745916cd2Sjpk break;
51845916cd2Sjpk case 'w':
51945916cd2Sjpk if (system_labeled) {
520*10ddde3aSaj if (optflg & LISTDEFS)
521*10ddde3aSaj usage(func);
52245916cd2Sjpk optflg |= WINDOWING;
52345916cd2Sjpk } else {
52445916cd2Sjpk usage(func);
52545916cd2Sjpk }
52645916cd2Sjpk break;
52745916cd2Sjpk case 'z':
52845916cd2Sjpk if (system_labeled) {
529*10ddde3aSaj if (optflg & LISTDEFS)
530*10ddde3aSaj usage(func);
53145916cd2Sjpk optflg |= ZONENAME;
53245916cd2Sjpk zonename = optarg;
53345916cd2Sjpk } else {
53445916cd2Sjpk usage(func);
53545916cd2Sjpk }
53645916cd2Sjpk break;
5377c478bd9Sstevel@tonic-gate case 'U':
538*10ddde3aSaj if (optflg & LISTDEFS)
539*10ddde3aSaj usage(func);
5407c478bd9Sstevel@tonic-gate optflg |= USERID;
54140e2b7c9Spaulson uid = atoi(optarg);
5427c478bd9Sstevel@tonic-gate break;
5437c478bd9Sstevel@tonic-gate case '?':
5447c478bd9Sstevel@tonic-gate default :
5457c478bd9Sstevel@tonic-gate usage(func);
54640e2b7c9Spaulson }
5477c478bd9Sstevel@tonic-gate }
5487c478bd9Sstevel@tonic-gate
54945916cd2Sjpk if (system_labeled) {
550*10ddde3aSaj if (!(optflg & (LISTALL | LISTFREE | LISTALLOC |
551*10ddde3aSaj LISTDEFS | WINDOWING))) {
552*10ddde3aSaj if (!(optflg & CLASS))
55340e2b7c9Spaulson usage(func);
554*10ddde3aSaj }
555*10ddde3aSaj } else if (!(optflg & (LISTALL | LISTFREE | LISTALLOC))) {
556*10ddde3aSaj if (!(optflg & CLASS))
55745916cd2Sjpk usage(func);
55845916cd2Sjpk }
55940e2b7c9Spaulson
56040e2b7c9Spaulson /*
561*10ddde3aSaj * list_devices(1) takes an optional device argument.
56240e2b7c9Spaulson */
563*10ddde3aSaj if (device && ((argc - optind) >= 1))
56440e2b7c9Spaulson usage(func);
565*10ddde3aSaj if (device == NULL) {
566*10ddde3aSaj if ((argc - optind) == 1)
567*10ddde3aSaj device = argv[optind];
568*10ddde3aSaj else if ((argc - optind) > 1)
569*10ddde3aSaj usage(func);
57040e2b7c9Spaulson }
57140e2b7c9Spaulson }
57240e2b7c9Spaulson
57340e2b7c9Spaulson if (optflg & USERNAME) {
57445916cd2Sjpk if (getpwnam_r(uname, &pw_ent, pw_buf, sizeof (pw_buf)) ==
57545916cd2Sjpk NULL) {
57645916cd2Sjpk (void) fprintf(stderr,
57745916cd2Sjpk gettext("Invalid user name -- %s -- \n"), uname);
57840e2b7c9Spaulson exit(1);
57940e2b7c9Spaulson }
58045916cd2Sjpk uid = pw_ent.pw_uid;
58145916cd2Sjpk } else if (optflg & USERID) {
58245916cd2Sjpk if (getpwuid_r(uid, &pw_ent, pw_buf, sizeof (pw_buf)) == NULL) {
58345916cd2Sjpk (void) fprintf(stderr,
58445916cd2Sjpk gettext("Invalid user ID -- %d -- \n"), uid);
58540e2b7c9Spaulson exit(1);
5867c478bd9Sstevel@tonic-gate }
58745916cd2Sjpk uid = pw_ent.pw_uid;
58845916cd2Sjpk } else {
58945916cd2Sjpk /*
59045916cd2Sjpk * caller's uid is the default if no user specified.
59145916cd2Sjpk */
59245916cd2Sjpk uid = getuid();
5937c478bd9Sstevel@tonic-gate }
5947c478bd9Sstevel@tonic-gate
59545916cd2Sjpk /*
59645916cd2Sjpk * global zone is the default if no zonename specified.
59745916cd2Sjpk */
59845916cd2Sjpk if (zonename == NULL) {
59945916cd2Sjpk zonename = zname;
60045916cd2Sjpk } else {
60145916cd2Sjpk if (zone_get_id(zonename, &zoneid) != 0) {
60245916cd2Sjpk (void) fprintf(stderr,
60345916cd2Sjpk gettext("Invalid zone name -- %s -- \n"), zonename);
60445916cd2Sjpk exit(1);
6057c478bd9Sstevel@tonic-gate }
60645916cd2Sjpk }
60745916cd2Sjpk
60845916cd2Sjpk if (func == 0)
60945916cd2Sjpk error = allocate(optflg, uid, device, zonename);
61045916cd2Sjpk else if (func == 1)
61145916cd2Sjpk error = deallocate(optflg, uid, device, zonename);
61245916cd2Sjpk else if (func == 2)
61345916cd2Sjpk error = list_devices(optflg, uid, device, zonename);
61440e2b7c9Spaulson
6157c478bd9Sstevel@tonic-gate (void) audit_allocate_record(error);
6167c478bd9Sstevel@tonic-gate
6177c478bd9Sstevel@tonic-gate if (error) {
6187c478bd9Sstevel@tonic-gate if (!(optflg & SILENT))
6197c478bd9Sstevel@tonic-gate print_error(error, name);
6207c478bd9Sstevel@tonic-gate exit(error);
6217c478bd9Sstevel@tonic-gate }
6227c478bd9Sstevel@tonic-gate
6237c478bd9Sstevel@tonic-gate return (0);
6247c478bd9Sstevel@tonic-gate }
62545916cd2Sjpk
62645916cd2Sjpk /*
62745916cd2Sjpk * Display error message via /etc/security/lib/wdwmsg script
62845916cd2Sjpk */
62945916cd2Sjpk static int
wdwmsg(char * name,char * msg)63045916cd2Sjpk wdwmsg(char *name, char *msg)
63145916cd2Sjpk {
63245916cd2Sjpk pid_t child_pid;
63345916cd2Sjpk pid_t wait_pid;
63445916cd2Sjpk int child_status;
63545916cd2Sjpk
63645916cd2Sjpk /* Fork a child */
63745916cd2Sjpk switch (child_pid = fork()) {
63845916cd2Sjpk case -1: /* FAILURE */
63945916cd2Sjpk return (-1);
64045916cd2Sjpk break;
64145916cd2Sjpk
64245916cd2Sjpk case 0: /* CHILD */
64345916cd2Sjpk (void) execl("/etc/security/lib/wdwmsg", "wdwmsg", msg,
64445916cd2Sjpk name, "OK", NULL);
64545916cd2Sjpk /* If exec failed, send message to stderr */
64645916cd2Sjpk (void) fprintf(stderr, "%s", msg);
64745916cd2Sjpk return (-1);
64845916cd2Sjpk
64945916cd2Sjpk default: /* PARENT */
65045916cd2Sjpk /* Wait for child to exit */
65145916cd2Sjpk wait_pid = waitpid(child_pid, &child_status, 0);
65245916cd2Sjpk if ((wait_pid < 0) && (errno == ECHILD))
65345916cd2Sjpk return (0);
65445916cd2Sjpk if ((wait_pid < 0) || (wait_pid != child_pid))
65545916cd2Sjpk return (-1);
65645916cd2Sjpk if (WIFEXITED(child_status))
65745916cd2Sjpk return (WEXITSTATUS(child_status));
65845916cd2Sjpk if (WIFSIGNALED(child_status))
65945916cd2Sjpk return (WTERMSIG(child_status));
66045916cd2Sjpk return (0);
66145916cd2Sjpk }
66245916cd2Sjpk }
663