Home | History | Annotate | Download | only in ndmpadm
      1 /*
      2  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
      3  * Use is subject to license terms.
      4  */
      5 
      6 /*
      7  * BSD 3 Clause License
      8  *
      9  * Copyright (c) 2007, The Storage Networking Industry Association.
     10  *
     11  * Redistribution and use in source and binary forms, with or without
     12  * modification, are permitted provided that the following conditions
     13  * are met:
     14  * 	- Redistributions of source code must retain the above copyright
     15  *	  notice, this list of conditions and the following disclaimer.
     16  *
     17  * 	- Redistributions in binary form must reproduce the above copyright
     18  *	  notice, this list of conditions and the following disclaimer in
     19  *	  the documentation and/or other materials provided with the
     20  *	  distribution.
     21  *
     22  *	- Neither the name of The Storage Networking Industry Association (SNIA)
     23  *	  nor the names of its contributors may be used to endorse or promote
     24  *	  products derived from this software without specific prior written
     25  *	  permission.
     26  *
     27  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     28  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     29  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     30  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
     31  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     32  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     33  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     34  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     35  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     36  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     37  * POSSIBILITY OF SUCH DAMAGE.
     38  */
     39 #include <assert.h>
     40 #include <ctype.h>
     41 #include <libgen.h>
     42 #include <libintl.h>
     43 #include <locale.h>
     44 #include <stddef.h>
     45 #include <stdio.h>
     46 #include <stdlib.h>
     47 #include <strings.h>
     48 #include <unistd.h>
     49 #include <fcntl.h>
     50 #include <sys/stat.h>
     51 #include <door.h>
     52 #include <sys/mman.h>
     53 #include <libndmp.h>
     54 #include "ndmpadm.h"
     55 
     56 typedef enum {
     57 	HELP_GET_CONFIG,
     58 	HELP_SET_CONFIG,
     59 	HELP_SHOW_DEVICES,
     60 	HELP_SHOW_SESSIONS,
     61 	HELP_KILL_SESSIONS,
     62 	HELP_ENABLE_AUTH,
     63 	HELP_DISABLE_AUTH
     64 } ndmp_help_t;
     65 
     66 typedef struct ndmp_command {
     67 	const char	*nc_name;
     68 	int		(*func)(int argc, char **argv,
     69 			    struct ndmp_command *cur_cmd);
     70 	ndmp_help_t	nc_usage;
     71 } ndmp_command_t;
     72 
     73 static int ndmp_get_config(int, char **, ndmp_command_t *);
     74 static int ndmp_set_config(int, char **, ndmp_command_t *);
     75 static int ndmp_show_devices(int, char **, ndmp_command_t *);
     76 static int ndmp_show_sessions(int, char **, ndmp_command_t *);
     77 static int ndmp_kill_sessions(int, char **, ndmp_command_t *);
     78 static int ndmp_enable_auth(int, char **, ndmp_command_t *);
     79 static int ndmp_disable_auth(int, char **, ndmp_command_t *);
     80 static void ndmp_get_config_process(char *);
     81 static void ndmp_set_config_process(char *arg);
     82 static int ndmp_get_password(char **);
     83 
     84 static ndmp_command_t command_table[] = {
     85 	{ "get",		ndmp_get_config,	HELP_GET_CONFIG	},
     86 	{ "set",		ndmp_set_config,	HELP_SET_CONFIG	},
     87 	{ "show-devices",	ndmp_show_devices,	HELP_SHOW_DEVICES },
     88 	{ "show-sessions",	ndmp_show_sessions,	HELP_SHOW_SESSIONS },
     89 	{ "kill-sessions",	ndmp_kill_sessions,	HELP_KILL_SESSIONS },
     90 	{ "enable",		ndmp_enable_auth,	HELP_ENABLE_AUTH },
     91 	{ "disable",		ndmp_disable_auth,	HELP_DISABLE_AUTH }
     92 };
     93 
     94 #define	NCOMMAND	(sizeof (command_table) / sizeof (command_table[0]))
     95 
     96 static char *prop_table[] = {
     97 	"debug-path",
     98 	"dump-pathnode",
     99 	"tar-pathnode",
    100 	"ignore-ctime",
    101 	"token-maxseq",
    102 	"version",
    103 	"dar-support",
    104 	"tcp-port",
    105 	"backup-quarantine",
    106 	"restore-quarantine",
    107 	"overwrite-quarantine"
    108 };
    109 
    110 #define	NDMPADM_NPROP	(sizeof (prop_table) / sizeof (prop_table[0]))
    111 
    112 typedef struct ndmp_auth {
    113 	const char *auth_type;
    114 	const char *username;
    115 	const char *password;
    116 } ndmp_auth_t;
    117 
    118 static ndmp_auth_t ndmp_auth_table[] = {
    119 	{ "cram-md5", "cram-md5-username", "cram-md5-password" },
    120 	{ "cleartext", "cleartext-username", "cleartext-password" }
    121 };
    122 #define	NAUTH	(sizeof (ndmp_auth_table) / sizeof (ndmp_auth_table[0]))
    123 #define	NDMP_PASSWORD_RETRIES	3
    124 
    125 #if !defined(TEXT_DOMAIN)
    126 #define	TEXT_DOMAIN	"SYS_TEST"
    127 #endif
    128 
    129 static const char *
    130 get_usage(ndmp_help_t idx)
    131 {
    132 	switch (idx) {
    133 	case HELP_SET_CONFIG:
    134 		return ("\tset [-p] <property=value> [[-p] property=value] "
    135 		    "...\n");
    136 	case HELP_GET_CONFIG:
    137 		return ("\tget [-p] [property] [[-p] property] ...\n");
    138 	case HELP_SHOW_DEVICES:
    139 		return ("\tshow-devices\n");
    140 	case HELP_SHOW_SESSIONS:
    141 		return ("\tshow-sessions [-i tape,scsi,data,mover] [id] ...\n");
    142 	case HELP_KILL_SESSIONS:
    143 		return ("\tkill-sessions <id ...>\n");
    144 	case HELP_ENABLE_AUTH:
    145 		return ("\tenable <-a auth-type> <-u username>\n");
    146 	case HELP_DISABLE_AUTH:
    147 		return ("\tdisable <-a auth-type>\n");
    148 	}
    149 
    150 	return (NULL);
    151 }
    152 
    153 /*
    154  * Display usage message.  If we're inside a command, display only the usage for
    155  * that command.  Otherwise, iterate over the entire command table and display
    156  * a complete usage message.
    157  */
    158 static void
    159 usage(boolean_t requested, ndmp_command_t *current_command)
    160 {
    161 	int i;
    162 	boolean_t show_properties = B_FALSE;
    163 	FILE *fp = requested ? stdout : stderr;
    164 
    165 	if (current_command == NULL) {
    166 		(void) fprintf(fp,
    167 		    gettext("Usage: ndmpadm subcommand args ...\n"));
    168 		(void) fprintf(fp,
    169 		    gettext("where 'command' is one of the following:\n\n"));
    170 
    171 		for (i = 0; i < NCOMMAND; i++) {
    172 			(void) fprintf(fp, "%s",
    173 			    get_usage(command_table[i].nc_usage));
    174 		}
    175 		(void) fprintf(fp, gettext("\t\twhere %s can be either "
    176 		    "%s or %s\n"), "'auth-type'", "'cram-md5'", "'cleartext'");
    177 	} else {
    178 		(void) fprintf(fp, gettext("Usage:\n"));
    179 		(void) fprintf(fp, "%s", get_usage(current_command->nc_usage));
    180 		if ((current_command->nc_usage == HELP_ENABLE_AUTH) ||
    181 		    (current_command->nc_usage == HELP_DISABLE_AUTH))
    182 			(void) fprintf(fp, gettext("\t\twhere %s can be either "
    183 			    "%s or %s\n"),
    184 			    "'auth-type'", "'cram-md5'", "'cleartext'");
    185 	}
    186 
    187 	if (current_command != NULL &&
    188 	    (strcmp(current_command->nc_name, "set") == 0))
    189 		show_properties = B_TRUE;
    190 
    191 	if (show_properties) {
    192 		(void) fprintf(fp,
    193 		    gettext("\nThe following properties are supported:\n"));
    194 
    195 		(void) fprintf(fp, gettext("\n\tPROPERTY"));
    196 		(void) fprintf(fp, "\n\t%s", "-------------");
    197 		for (i = 0; i < NDMPADM_NPROP; i++)
    198 			(void) fprintf(fp, "\n\t%s", prop_table[i]);
    199 		(void) fprintf(fp, "\n");
    200 	}
    201 
    202 	exit(requested ? 0 : 2);
    203 }
    204 
    205 /*ARGSUSED*/
    206 static int
    207 ndmp_get_config(int argc, char **argv, ndmp_command_t *cur_cmd)
    208 {
    209 	char *propval;
    210 	int i, c;
    211 
    212 	if (argc == 1) {
    213 		/*
    214 		 * Get all the properties and variables ndmpadm is allowed
    215 		 * to see.
    216 		 */
    217 		for (i = 0; i < NDMPADM_NPROP; i++) {
    218 			if (ndmp_get_prop(prop_table[i], &propval)) {
    219 				(void) fprintf(stdout, "\t%s=\n",
    220 				    prop_table[i]);
    221 			} else {
    222 				(void) fprintf(stdout, "\t%s=%s\n",
    223 				    prop_table[i], propval);
    224 				free(propval);
    225 			}
    226 		}
    227 	} else if (argc > 1) {
    228 		while ((c = getopt(argc, argv, ":p:")) != -1) {
    229 			switch (c) {
    230 			case 'p':
    231 				ndmp_get_config_process(optarg);
    232 				break;
    233 			case ':':
    234 				(void) fprintf(stderr, gettext("Option -%c "
    235 				    "requires an operand\n"), optopt);
    236 				break;
    237 			case '?':
    238 				(void) fprintf(stderr, gettext("Unrecognized "
    239 				    "option: -%c\n"), optopt);
    240 			}
    241 		}
    242 		/*
    243 		 * optind is initialized to 1 if the -p option is not used,
    244 		 * otherwise index to argv.
    245 		 */
    246 		argc -= optind;
    247 		argv += optind;
    248 
    249 		for (i = 0; i < argc; i++) {
    250 			if (strncmp(argv[i], "-p", 2) == 0)
    251 				continue;
    252 
    253 			ndmp_get_config_process(argv[i]);
    254 		}
    255 	}
    256 	return (0);
    257 }
    258 
    259 static void
    260 ndmp_get_config_process(char *arg)
    261 {
    262 	int j;
    263 	char *propval;
    264 
    265 	for (j = 0; j < NDMPADM_NPROP; j++) {
    266 		if (strcmp(arg, prop_table[j]) == 0) {
    267 			if (ndmp_get_prop(arg, &propval)) {
    268 				(void) fprintf(stdout, "\t%s=\n", arg);
    269 			} else {
    270 				(void) fprintf(stdout, "\t%s=%s\n",
    271 				    arg, propval);
    272 				free(propval);
    273 			}
    274 			break;
    275 		}
    276 	}
    277 	if (j == NDMPADM_NPROP) {
    278 		(void) fprintf(stdout, gettext("\t%s is invalid property "
    279 		    "or variable\n"), arg);
    280 	}
    281 }
    282 
    283 /*ARGSUSED*/
    284 static int
    285 ndmp_set_config(int argc, char **argv, ndmp_command_t *cur_cmd)
    286 {
    287 	int c, i;
    288 
    289 	if (argc < 2) {
    290 		(void) fprintf(stderr, gettext("Missing property=value "
    291 		    "argument\n"));
    292 		usage(B_FALSE, cur_cmd);
    293 	}
    294 	while ((c = getopt(argc, argv, ":p:")) != -1) {
    295 		switch (c) {
    296 		case 'p':
    297 			ndmp_set_config_process(optarg);
    298 			break;
    299 		case ':':
    300 			(void) fprintf(stderr, gettext("Option -%c "
    301 			    "requires an operand\n"), optopt);
    302 			break;
    303 		case '?':
    304 			(void) fprintf(stderr, gettext("Unrecognized "
    305 			    "option: -%c\n"), optopt);
    306 		}
    307 	}
    308 	/*
    309 	 * optind is initialized to 1 if the -p option is not used,
    310 	 * otherwise index to argv.
    311 	 */
    312 	argc -= optind;
    313 	argv += optind;
    314 
    315 	for (i = 0; i < argc; i++) {
    316 		if (strncmp(argv[i], "-p", 2) == 0)
    317 			continue;
    318 
    319 		ndmp_set_config_process(argv[i]);
    320 	}
    321 	return (0);
    322 }
    323 
    324 static void
    325 ndmp_set_config_process(char *propname)
    326 {
    327 	char *propvalue;
    328 	int ret, j;
    329 
    330 	if ((propvalue = strchr(propname, '=')) == NULL) {
    331 		(void) fprintf(stderr, gettext("Missing value in "
    332 		    "property=value argument for %s\n"), propname);
    333 			return;
    334 	}
    335 	*propvalue = '\0';
    336 	propvalue++;
    337 
    338 	if (*propname == '\0') {
    339 		(void) fprintf(stderr, gettext("Missing property in "
    340 		    "property=value argument for %s\n"), propname);
    341 			return;
    342 	}
    343 	for (j = 0; j < NDMPADM_NPROP; j++) {
    344 		if (strcmp(propname, prop_table[j]) == 0)
    345 			break;
    346 	}
    347 	if (j == NDMPADM_NPROP) {
    348 		(void) fprintf(stdout, gettext("%s is invalid property or "
    349 		    "variable\n"), propname);
    350 		return;
    351 	}
    352 	ret = ndmp_set_prop(propname, propvalue);
    353 	if (ret != -1) {
    354 		if (!ndmp_door_status()) {
    355 			if (ndmp_service_refresh() == -1)
    356 				(void) fprintf(stdout, gettext("Could not "
    357 				    "refesh property of service ndmpd\n"));
    358 		}
    359 	} else {
    360 		(void) fprintf(stdout, gettext("Could not set property for "
    361 		    "%s - %s\n"), propname, ndmp_strerror(ndmp_errno));
    362 	}
    363 }
    364 
    365 /*ARGSUSED*/
    366 static int
    367 ndmp_show_devices(int argc, char **argv, ndmp_command_t *cur_cmd)
    368 {
    369 	int ret;
    370 	ndmp_devinfo_t *dip = NULL;
    371 	size_t size;
    372 
    373 	if (ndmp_door_status()) {
    374 		(void) fprintf(stdout,
    375 		    gettext("Service ndmpd not running\n"));
    376 		return (-1);
    377 	}
    378 
    379 	ret = ndmp_get_devinfo(&dip, &size);
    380 
    381 	if (ret == -1)
    382 		(void) fprintf(stdout,
    383 		    gettext("Could not get device information\n"));
    384 	else
    385 		ndmp_devinfo_print(dip, size);
    386 
    387 	ndmp_get_devinfo_free(dip, size);
    388 	return (0);
    389 }
    390 
    391 static int
    392 ndmp_show_sessions(int argc, char **argv, ndmp_command_t *cur_cmd)
    393 {
    394 	ndmp_session_info_t *sinfo = NULL;
    395 	ndmp_session_info_t *sp = NULL;
    396 	uint_t num;
    397 	int c, ret, i, j;
    398 	int statarg = 0;
    399 	char *value;
    400 	char *type_subopts[] = { "tape", "scsi", "data", "mover", NULL };
    401 
    402 	if (ndmp_door_status()) {
    403 		(void) fprintf(stdout,
    404 		    gettext("Service ndmpd not running\n"));
    405 		return (-1);
    406 	}
    407 
    408 	/* Detail output if no option is specified */
    409 	if (argc == 1) {
    410 		statarg = NDMP_CAT_ALL;
    411 	} else {
    412 		statarg = 0;
    413 		while ((c = getopt(argc, argv, ":i:")) != -1) {
    414 			switch (c) {
    415 			case 'i':
    416 				while (*optarg != '\0') {
    417 					switch (getsubopt(&optarg, type_subopts,
    418 					    &value)) {
    419 					case 0:
    420 						statarg |= NDMP_CAT_TAPE;
    421 						break;
    422 					case 1:
    423 						statarg |= NDMP_CAT_SCSI;
    424 						break;
    425 					case 2:
    426 						statarg |= NDMP_CAT_DATA;
    427 						break;
    428 					case 3:
    429 						statarg |= NDMP_CAT_MOVER;
    430 						break;
    431 					default:
    432 						(void) fprintf(stderr,
    433 						    gettext("Invalid object "
    434 						    "type '%s'\n"), value);
    435 						usage(B_FALSE, cur_cmd);
    436 					}
    437 				}
    438 				break;
    439 			case ':':
    440 				(void) fprintf(stderr,
    441 				    gettext("Missing argument for "
    442 				    "'%c' option\n"), optopt);
    443 				usage(B_FALSE, cur_cmd);
    444 				break;
    445 			case '?':
    446 				(void) fprintf(stderr,
    447 				    gettext("Invalid option '%c'\n"), optopt);
    448 				usage(B_FALSE, cur_cmd);
    449 			}
    450 		}
    451 		/* if -i and its argument are not specified, display all */
    452 		if (statarg == 0)
    453 			statarg = NDMP_CAT_ALL;
    454 	}
    455 	/*
    456 	 * optind is initialized to 1 if the -i option is not used, otherwise
    457 	 * index to argv.
    458 	 */
    459 	argc -= optind;
    460 	argv += optind;
    461 
    462 	ret = ndmp_get_session_info(&sinfo, &num);
    463 	if (ret == -1) {
    464 		(void) fprintf(stdout,
    465 		    gettext("Could not get session information\n"));
    466 	} else {
    467 		if (argc == 0) {
    468 			ndmp_session_all_print(statarg, sinfo, num);
    469 		} else {
    470 			for (i = 0; i < argc; i++) {
    471 				sp = sinfo;
    472 				for (j = 0; j < num; j++, sp++) {
    473 					if (sp->nsi_sid == atoi(argv[i])) {
    474 						ndmp_session_print(statarg, sp);
    475 						(void) fprintf(stdout, "\n");
    476 						break;
    477 					}
    478 				}
    479 				if (j == num) {
    480 					(void) fprintf(stdout,
    481 					    gettext("Session %d not "
    482 					    "found\n"), atoi(argv[i]));
    483 				}
    484 			}
    485 		}
    486 		ndmp_get_session_info_free(sinfo, num);
    487 	}
    488 	return (0);
    489 }
    490 
    491 /*ARGSUSED*/
    492 static int
    493 ndmp_kill_sessions(int argc, char **argv, ndmp_command_t *cur_cmd)
    494 {
    495 	int ret, i;
    496 
    497 	if (ndmp_door_status()) {
    498 		(void) fprintf(stdout,
    499 		    gettext("Service ndmpd not running.\n"));
    500 		return (-1);
    501 	}
    502 
    503 	/* If no arg is specified, print the usage and exit */
    504 	if (argc == 1)
    505 		usage(B_FALSE, cur_cmd);
    506 
    507 	for (i = 1; i < argc; i++) {
    508 		if (atoi(argv[i]) > 0) {
    509 			ret = ndmp_terminate_session(atoi(argv[i]));
    510 		} else {
    511 			(void) fprintf(stderr,
    512 			    gettext("Invalid argument %s\n"), argv[i]);
    513 				continue;
    514 		}
    515 		if (ret == -1)
    516 			(void) fprintf(stdout,
    517 			    gettext("Session id %d not found.\n"),
    518 			    atoi(argv[i]));
    519 	}
    520 	return (0);
    521 }
    522 
    523 static int
    524 ndmp_get_password(char **password)
    525 {
    526 	char *pw1, pw2[257];
    527 	int i;
    528 
    529 	for (i = 0; i < NDMP_PASSWORD_RETRIES; i++) {
    530 		/*
    531 		 * getpassphrase use the same buffer to return password, so
    532 		 * copy the result in different buffer, before calling the
    533 		 * getpassphrase again.
    534 		 */
    535 		if ((pw1 =
    536 		    getpassphrase(gettext("Enter new password: "))) != NULL) {
    537 			(void) strlcpy(pw2, pw1, sizeof (pw2));
    538 			if ((pw1 =
    539 			    getpassphrase(gettext("Re-enter  password: ")))
    540 			    != NULL) {
    541 				if (strncmp(pw1, pw2, strlen(pw1)) == 0) {
    542 					*password = pw1;
    543 					return (0);
    544 				} else {
    545 					(void) fprintf(stderr,
    546 					    gettext("Both password did not "
    547 					    "match.\n"));
    548 				}
    549 			}
    550 		}
    551 	}
    552 	return (-1);
    553 }
    554 
    555 static int
    556 ndmp_enable_auth(int argc, char **argv, ndmp_command_t *cur_cmd)
    557 {
    558 	char *auth_type, *username, *password;
    559 	int c, i, auth_type_flag = 0;
    560 	char *enc_password;
    561 
    562 	/* enable <-a auth-type> <-u username> */
    563 	if (argc != 5) {
    564 		usage(B_FALSE, cur_cmd);
    565 	}
    566 
    567 	while ((c = getopt(argc, argv, ":a:u:")) != -1) {
    568 		switch (c) {
    569 		case 'a':
    570 			auth_type = strdup(optarg);
    571 			break;
    572 		case 'u':
    573 			username = strdup(optarg);
    574 			break;
    575 		case ':':
    576 			(void) fprintf(stderr, gettext("Option -%c "
    577 			    "requires an operand\n"), optopt);
    578 			usage(B_FALSE, cur_cmd);
    579 			break;
    580 		case '?':
    581 			(void) fprintf(stderr, gettext("Unrecognized "
    582 			    "option: -%c\n"), optopt);
    583 			usage(B_FALSE, cur_cmd);
    584 		}
    585 	}
    586 
    587 	if ((auth_type) && (username)) {
    588 		if (ndmp_get_password(&password)) {
    589 			(void) fprintf(stderr, gettext("Could not get correct "
    590 			    "password, exiting..."));
    591 			free(auth_type);
    592 			free(username);
    593 			exit(-1);
    594 		}
    595 	} else {
    596 		(void) fprintf(stderr, gettext("%s or %s can not be blank"),
    597 		    "'auth-type'", "'username'");
    598 		free(auth_type);
    599 		free(username);
    600 		exit(-1);
    601 	}
    602 
    603 	if ((enc_password = ndmp_base64_encode(password)) == NULL) {
    604 		(void) fprintf(stdout,
    605 		    gettext("Could not encode password - %s\n"),
    606 		    ndmp_strerror(ndmp_errno));
    607 		free(auth_type);
    608 		free(username);
    609 		exit(-1);
    610 	}
    611 
    612 	for (i = 0; i < NAUTH; i++) {
    613 		if (strncmp(auth_type, ndmp_auth_table[i].auth_type,
    614 		    strlen(ndmp_auth_table[i].auth_type)) == 0) {
    615 			auth_type_flag = 1;
    616 			if ((ndmp_set_prop((char *)ndmp_auth_table[i].username,
    617 			    username)) == -1) {
    618 				(void) fprintf(stdout,
    619 				    gettext("Could not set username - %s\n"),
    620 				    ndmp_strerror(ndmp_errno));
    621 				continue;
    622 			}
    623 			if ((ndmp_set_prop((char *)ndmp_auth_table[i].password,
    624 			    enc_password)) == -1) {
    625 				(void) fprintf(stdout,
    626 				    gettext("Could not set password - %s\n"),
    627 				    ndmp_strerror(ndmp_errno));
    628 				continue;
    629 			}
    630 			if (!ndmp_door_status() &&
    631 			    (ndmp_service_refresh()) == -1) {
    632 				(void) fprintf(stdout,
    633 				    gettext("Could not refesh ndmpd service "
    634 				    "properties\n"));
    635 			}
    636 		}
    637 	}
    638 	free(auth_type);
    639 	free(username);
    640 	free(enc_password);
    641 
    642 	if (!auth_type_flag)
    643 		usage(B_FALSE, cur_cmd);
    644 
    645 	return (0);
    646 }
    647 
    648 static int
    649 ndmp_disable_auth(int argc, char **argv, ndmp_command_t *cur_cmd)
    650 {
    651 	char *auth_type;
    652 	int c, i, auth_type_flag = 0;
    653 
    654 	/* disable <-a auth-type> */
    655 	if (argc != 3) {
    656 		usage(B_FALSE, cur_cmd);
    657 	}
    658 
    659 	while ((c = getopt(argc, argv, ":a:")) != -1) {
    660 		switch (c) {
    661 		case 'a':
    662 			auth_type = strdup(optarg);
    663 			break;
    664 		case ':':
    665 			(void) fprintf(stderr, gettext("Option -%c "
    666 			    "requires an operand\n"), optopt);
    667 			break;
    668 		case '?':
    669 			(void) fprintf(stderr, gettext("Unrecognized "
    670 			    "option: -%c\n"), optopt);
    671 		}
    672 	}
    673 	for (i = 0; i < NAUTH; i++) {
    674 		if (strncmp(auth_type, ndmp_auth_table[i].auth_type,
    675 		    strlen(ndmp_auth_table[i].auth_type)) == 0) {
    676 			auth_type_flag = 1;
    677 			if ((ndmp_set_prop((char *)ndmp_auth_table[i].username,
    678 			    "")) == -1) {
    679 				(void) fprintf(stdout,
    680 				    gettext("Could not clear username - %s\n"),
    681 				    ndmp_strerror(ndmp_errno));
    682 				continue;
    683 			}
    684 			if ((ndmp_set_prop((char *)ndmp_auth_table[i].password,
    685 			    "")) == -1) {
    686 				(void) fprintf(stdout,
    687 				    gettext("Could not clear password - %s\n"),
    688 				    ndmp_strerror(ndmp_errno));
    689 				continue;
    690 			}
    691 			if (!ndmp_door_status() &&
    692 			    (ndmp_service_refresh()) == -1) {
    693 				(void) fprintf(stdout, gettext("Could not "
    694 				    "refesh ndmpd service properties\n"));
    695 			}
    696 		}
    697 	}
    698 	free(auth_type);
    699 
    700 	if (!auth_type_flag)
    701 		usage(B_FALSE, cur_cmd);
    702 
    703 	return (0);
    704 }
    705 
    706 int
    707 main(int argc, char **argv)
    708 {
    709 	int ret;
    710 	int i;
    711 	char *cmdname;
    712 	ndmp_command_t	*current_command = NULL;
    713 
    714 	(void) setlocale(LC_ALL, "");
    715 	(void) textdomain(TEXT_DOMAIN);
    716 
    717 	opterr = 0;
    718 
    719 	/* Make sure the user has specified some command. */
    720 	if (argc < 2) {
    721 		(void) fprintf(stderr, gettext("Missing command.\n"));
    722 		usage(B_FALSE, current_command);
    723 	}
    724 
    725 	cmdname = argv[1];
    726 
    727 	/*
    728 	 * Special case '-?'
    729 	 */
    730 	if (strcmp(cmdname, "-?") == 0)
    731 		usage(B_TRUE, current_command);
    732 
    733 	/*
    734 	 * Run the appropriate sub-command.
    735 	 */
    736 	for (i = 0; i < NCOMMAND; i++) {
    737 		if (strcmp(cmdname, command_table[i].nc_name) == 0) {
    738 			current_command = &command_table[i];
    739 			ret = command_table[i].func(argc - 1, argv + 1,
    740 			    current_command);
    741 			break;
    742 		}
    743 	}
    744 
    745 	if (i == NCOMMAND) {
    746 		(void) fprintf(stderr, gettext("Unrecognized "
    747 		    "command '%s'\n"), cmdname);
    748 		usage(B_FALSE, current_command);
    749 	}
    750 
    751 	return (ret);
    752 }
    753