xref: /titanic_52/usr/src/cmd/ndmpadm/ndmpadm_main.c (revision f093add7b63e274f746dd55365f052cded44cc16)
12654012fSReza Sabdar /*
2d0194491SJanice Chang  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
3*f093add7SJan Kryl  * Copyright 2015 Nexenta Systems, Inc.  All rights reserved.
42654012fSReza Sabdar  */
52654012fSReza Sabdar 
62654012fSReza Sabdar /*
72654012fSReza Sabdar  * BSD 3 Clause License
82654012fSReza Sabdar  *
92654012fSReza Sabdar  * Copyright (c) 2007, The Storage Networking Industry Association.
102654012fSReza Sabdar  *
112654012fSReza Sabdar  * Redistribution and use in source and binary forms, with or without
122654012fSReza Sabdar  * modification, are permitted provided that the following conditions
132654012fSReza Sabdar  * are met:
142654012fSReza Sabdar  * 	- Redistributions of source code must retain the above copyright
152654012fSReza Sabdar  *	  notice, this list of conditions and the following disclaimer.
162654012fSReza Sabdar  *
172654012fSReza Sabdar  * 	- Redistributions in binary form must reproduce the above copyright
182654012fSReza Sabdar  *	  notice, this list of conditions and the following disclaimer in
192654012fSReza Sabdar  *	  the documentation and/or other materials provided with the
202654012fSReza Sabdar  *	  distribution.
212654012fSReza Sabdar  *
222654012fSReza Sabdar  *	- Neither the name of The Storage Networking Industry Association (SNIA)
232654012fSReza Sabdar  *	  nor the names of its contributors may be used to endorse or promote
242654012fSReza Sabdar  *	  products derived from this software without specific prior written
252654012fSReza Sabdar  *	  permission.
262654012fSReza Sabdar  *
272654012fSReza Sabdar  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
282654012fSReza Sabdar  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
292654012fSReza Sabdar  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
302654012fSReza Sabdar  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
312654012fSReza Sabdar  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
322654012fSReza Sabdar  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
332654012fSReza Sabdar  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
342654012fSReza Sabdar  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
352654012fSReza Sabdar  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
362654012fSReza Sabdar  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
372654012fSReza Sabdar  * POSSIBILITY OF SUCH DAMAGE.
382654012fSReza Sabdar  */
392654012fSReza Sabdar #include <assert.h>
402654012fSReza Sabdar #include <ctype.h>
412654012fSReza Sabdar #include <libgen.h>
422654012fSReza Sabdar #include <libintl.h>
432654012fSReza Sabdar #include <locale.h>
442654012fSReza Sabdar #include <stddef.h>
452654012fSReza Sabdar #include <stdio.h>
462654012fSReza Sabdar #include <stdlib.h>
472654012fSReza Sabdar #include <strings.h>
482654012fSReza Sabdar #include <unistd.h>
492654012fSReza Sabdar #include <fcntl.h>
502654012fSReza Sabdar #include <sys/stat.h>
512654012fSReza Sabdar #include <door.h>
522654012fSReza Sabdar #include <sys/mman.h>
532654012fSReza Sabdar #include <libndmp.h>
542654012fSReza Sabdar #include "ndmpadm.h"
552654012fSReza Sabdar 
562654012fSReza Sabdar typedef enum {
572654012fSReza Sabdar 	HELP_GET_CONFIG,
582654012fSReza Sabdar 	HELP_SET_CONFIG,
592654012fSReza Sabdar 	HELP_SHOW_DEVICES,
602654012fSReza Sabdar 	HELP_SHOW_SESSIONS,
612654012fSReza Sabdar 	HELP_KILL_SESSIONS,
622654012fSReza Sabdar 	HELP_ENABLE_AUTH,
632654012fSReza Sabdar 	HELP_DISABLE_AUTH
642654012fSReza Sabdar } ndmp_help_t;
652654012fSReza Sabdar 
662654012fSReza Sabdar typedef struct ndmp_command {
672654012fSReza Sabdar 	const char	*nc_name;
682654012fSReza Sabdar 	int		(*func)(int argc, char **argv,
692654012fSReza Sabdar 			    struct ndmp_command *cur_cmd);
702654012fSReza Sabdar 	ndmp_help_t	nc_usage;
712654012fSReza Sabdar } ndmp_command_t;
722654012fSReza Sabdar 
732654012fSReza Sabdar static int ndmp_get_config(int, char **, ndmp_command_t *);
742654012fSReza Sabdar static int ndmp_set_config(int, char **, ndmp_command_t *);
752654012fSReza Sabdar static int ndmp_show_devices(int, char **, ndmp_command_t *);
762654012fSReza Sabdar static int ndmp_show_sessions(int, char **, ndmp_command_t *);
772654012fSReza Sabdar static int ndmp_kill_sessions(int, char **, ndmp_command_t *);
782654012fSReza Sabdar static int ndmp_enable_auth(int, char **, ndmp_command_t *);
792654012fSReza Sabdar static int ndmp_disable_auth(int, char **, ndmp_command_t *);
802654012fSReza Sabdar static void ndmp_get_config_process(char *);
812654012fSReza Sabdar static void ndmp_set_config_process(char *arg);
822654012fSReza Sabdar static int ndmp_get_password(char **);
832654012fSReza Sabdar 
842654012fSReza Sabdar static ndmp_command_t command_table[] = {
852654012fSReza Sabdar 	{ "get",		ndmp_get_config,	HELP_GET_CONFIG	},
862654012fSReza Sabdar 	{ "set",		ndmp_set_config,	HELP_SET_CONFIG	},
872654012fSReza Sabdar 	{ "show-devices",	ndmp_show_devices,	HELP_SHOW_DEVICES },
882654012fSReza Sabdar 	{ "show-sessions",	ndmp_show_sessions,	HELP_SHOW_SESSIONS },
892654012fSReza Sabdar 	{ "kill-sessions",	ndmp_kill_sessions,	HELP_KILL_SESSIONS },
902654012fSReza Sabdar 	{ "enable",		ndmp_enable_auth,	HELP_ENABLE_AUTH },
912654012fSReza Sabdar 	{ "disable",		ndmp_disable_auth,	HELP_DISABLE_AUTH }
922654012fSReza Sabdar };
932654012fSReza Sabdar 
942654012fSReza Sabdar #define	NCOMMAND	(sizeof (command_table) / sizeof (command_table[0]))
952654012fSReza Sabdar 
962654012fSReza Sabdar static char *prop_table[] = {
972654012fSReza Sabdar 	"debug-path",
982654012fSReza Sabdar 	"dump-pathnode",
992654012fSReza Sabdar 	"tar-pathnode",
1002654012fSReza Sabdar 	"ignore-ctime",
1012654012fSReza Sabdar 	"token-maxseq",
1022654012fSReza Sabdar 	"version",
1032654012fSReza Sabdar 	"dar-support",
1042654012fSReza Sabdar 	"tcp-port",
1052654012fSReza Sabdar 	"backup-quarantine",
1062654012fSReza Sabdar 	"restore-quarantine",
107d0194491SJanice Chang 	"overwrite-quarantine",
1081e05b03fSJanice Chang 	"zfs-force-override",
109faac71c0SJan Kryl 	"drive-type",
110faac71c0SJan Kryl 	"debug-mode"
1112654012fSReza Sabdar };
1122654012fSReza Sabdar 
1132654012fSReza Sabdar #define	NDMPADM_NPROP	(sizeof (prop_table) / sizeof (prop_table[0]))
1142654012fSReza Sabdar 
1152654012fSReza Sabdar typedef struct ndmp_auth {
1162654012fSReza Sabdar 	const char *auth_type;
1172654012fSReza Sabdar 	const char *username;
1182654012fSReza Sabdar 	const char *password;
1192654012fSReza Sabdar } ndmp_auth_t;
1202654012fSReza Sabdar 
1212654012fSReza Sabdar static ndmp_auth_t ndmp_auth_table[] = {
1222654012fSReza Sabdar 	{ "cram-md5", "cram-md5-username", "cram-md5-password" },
1232654012fSReza Sabdar 	{ "cleartext", "cleartext-username", "cleartext-password" }
1242654012fSReza Sabdar };
1252654012fSReza Sabdar #define	NAUTH	(sizeof (ndmp_auth_table) / sizeof (ndmp_auth_table[0]))
1262654012fSReza Sabdar #define	NDMP_PASSWORD_RETRIES	3
1272654012fSReza Sabdar 
1282654012fSReza Sabdar #if !defined(TEXT_DOMAIN)
1292654012fSReza Sabdar #define	TEXT_DOMAIN	"SYS_TEST"
1302654012fSReza Sabdar #endif
1312654012fSReza Sabdar 
1322654012fSReza Sabdar static const char *
1332654012fSReza Sabdar get_usage(ndmp_help_t idx)
1342654012fSReza Sabdar {
1352654012fSReza Sabdar 	switch (idx) {
1362654012fSReza Sabdar 	case HELP_SET_CONFIG:
1372654012fSReza Sabdar 		return ("\tset [-p] <property=value> [[-p] property=value] "
1382654012fSReza Sabdar 		    "...\n");
1392654012fSReza Sabdar 	case HELP_GET_CONFIG:
1402654012fSReza Sabdar 		return ("\tget [-p] [property] [[-p] property] ...\n");
1412654012fSReza Sabdar 	case HELP_SHOW_DEVICES:
1422654012fSReza Sabdar 		return ("\tshow-devices\n");
1432654012fSReza Sabdar 	case HELP_SHOW_SESSIONS:
1442654012fSReza Sabdar 		return ("\tshow-sessions [-i tape,scsi,data,mover] [id] ...\n");
1452654012fSReza Sabdar 	case HELP_KILL_SESSIONS:
1462654012fSReza Sabdar 		return ("\tkill-sessions <id ...>\n");
1472654012fSReza Sabdar 	case HELP_ENABLE_AUTH:
1482654012fSReza Sabdar 		return ("\tenable <-a auth-type> <-u username>\n");
1492654012fSReza Sabdar 	case HELP_DISABLE_AUTH:
1502654012fSReza Sabdar 		return ("\tdisable <-a auth-type>\n");
1512654012fSReza Sabdar 	}
1522654012fSReza Sabdar 
1532654012fSReza Sabdar 	return (NULL);
1542654012fSReza Sabdar }
1552654012fSReza Sabdar 
1562654012fSReza Sabdar /*
1572654012fSReza Sabdar  * Display usage message.  If we're inside a command, display only the usage for
1582654012fSReza Sabdar  * that command.  Otherwise, iterate over the entire command table and display
1592654012fSReza Sabdar  * a complete usage message.
1602654012fSReza Sabdar  */
1612654012fSReza Sabdar static void
1622654012fSReza Sabdar usage(boolean_t requested, ndmp_command_t *current_command)
1632654012fSReza Sabdar {
1642654012fSReza Sabdar 	int i;
1652654012fSReza Sabdar 	boolean_t show_properties = B_FALSE;
1662654012fSReza Sabdar 	FILE *fp = requested ? stdout : stderr;
1672654012fSReza Sabdar 
1682654012fSReza Sabdar 	if (current_command == NULL) {
1692654012fSReza Sabdar 		(void) fprintf(fp,
1702654012fSReza Sabdar 		    gettext("Usage: ndmpadm subcommand args ...\n"));
1712654012fSReza Sabdar 		(void) fprintf(fp,
1722654012fSReza Sabdar 		    gettext("where 'command' is one of the following:\n\n"));
1732654012fSReza Sabdar 
1742654012fSReza Sabdar 		for (i = 0; i < NCOMMAND; i++) {
1752654012fSReza Sabdar 			(void) fprintf(fp, "%s",
1762654012fSReza Sabdar 			    get_usage(command_table[i].nc_usage));
1772654012fSReza Sabdar 		}
1782654012fSReza Sabdar 		(void) fprintf(fp, gettext("\t\twhere %s can be either "
1792654012fSReza Sabdar 		    "%s or %s\n"), "'auth-type'", "'cram-md5'", "'cleartext'");
1802654012fSReza Sabdar 	} else {
1812654012fSReza Sabdar 		(void) fprintf(fp, gettext("Usage:\n"));
1822654012fSReza Sabdar 		(void) fprintf(fp, "%s", get_usage(current_command->nc_usage));
1832654012fSReza Sabdar 		if ((current_command->nc_usage == HELP_ENABLE_AUTH) ||
1842654012fSReza Sabdar 		    (current_command->nc_usage == HELP_DISABLE_AUTH))
1852654012fSReza Sabdar 			(void) fprintf(fp, gettext("\t\twhere %s can be either "
1862654012fSReza Sabdar 			    "%s or %s\n"),
1872654012fSReza Sabdar 			    "'auth-type'", "'cram-md5'", "'cleartext'");
1882654012fSReza Sabdar 	}
1892654012fSReza Sabdar 
1902654012fSReza Sabdar 	if (current_command != NULL &&
1912654012fSReza Sabdar 	    (strcmp(current_command->nc_name, "set") == 0))
1922654012fSReza Sabdar 		show_properties = B_TRUE;
1932654012fSReza Sabdar 
1942654012fSReza Sabdar 	if (show_properties) {
1952654012fSReza Sabdar 		(void) fprintf(fp,
1962654012fSReza Sabdar 		    gettext("\nThe following properties are supported:\n"));
1972654012fSReza Sabdar 
1982654012fSReza Sabdar 		(void) fprintf(fp, gettext("\n\tPROPERTY"));
1992654012fSReza Sabdar 		(void) fprintf(fp, "\n\t%s", "-------------");
2002654012fSReza Sabdar 		for (i = 0; i < NDMPADM_NPROP; i++)
2012654012fSReza Sabdar 			(void) fprintf(fp, "\n\t%s", prop_table[i]);
2022654012fSReza Sabdar 		(void) fprintf(fp, "\n");
2032654012fSReza Sabdar 	}
2042654012fSReza Sabdar 
2052654012fSReza Sabdar 	exit(requested ? 0 : 2);
2062654012fSReza Sabdar }
2072654012fSReza Sabdar 
2082654012fSReza Sabdar /*ARGSUSED*/
2092654012fSReza Sabdar static int
2102654012fSReza Sabdar ndmp_get_config(int argc, char **argv, ndmp_command_t *cur_cmd)
2112654012fSReza Sabdar {
2122654012fSReza Sabdar 	char *propval;
2132654012fSReza Sabdar 	int i, c;
2142654012fSReza Sabdar 
2152654012fSReza Sabdar 	if (argc == 1) {
2162654012fSReza Sabdar 		/*
2172654012fSReza Sabdar 		 * Get all the properties and variables ndmpadm is allowed
2182654012fSReza Sabdar 		 * to see.
2192654012fSReza Sabdar 		 */
2202654012fSReza Sabdar 		for (i = 0; i < NDMPADM_NPROP; i++) {
2212654012fSReza Sabdar 			if (ndmp_get_prop(prop_table[i], &propval)) {
2222654012fSReza Sabdar 				(void) fprintf(stdout, "\t%s=\n",
2232654012fSReza Sabdar 				    prop_table[i]);
2242654012fSReza Sabdar 			} else {
2252654012fSReza Sabdar 				(void) fprintf(stdout, "\t%s=%s\n",
2262654012fSReza Sabdar 				    prop_table[i], propval);
2272654012fSReza Sabdar 				free(propval);
2282654012fSReza Sabdar 			}
2292654012fSReza Sabdar 		}
2302654012fSReza Sabdar 	} else if (argc > 1) {
2312654012fSReza Sabdar 		while ((c = getopt(argc, argv, ":p:")) != -1) {
2322654012fSReza Sabdar 			switch (c) {
2332654012fSReza Sabdar 			case 'p':
2342654012fSReza Sabdar 				ndmp_get_config_process(optarg);
2352654012fSReza Sabdar 				break;
2362654012fSReza Sabdar 			case ':':
2372654012fSReza Sabdar 				(void) fprintf(stderr, gettext("Option -%c "
2382654012fSReza Sabdar 				    "requires an operand\n"), optopt);
2392654012fSReza Sabdar 				break;
2402654012fSReza Sabdar 			case '?':
2412654012fSReza Sabdar 				(void) fprintf(stderr, gettext("Unrecognized "
2422654012fSReza Sabdar 				    "option: -%c\n"), optopt);
2432654012fSReza Sabdar 			}
2442654012fSReza Sabdar 		}
2452654012fSReza Sabdar 		/*
2462654012fSReza Sabdar 		 * optind is initialized to 1 if the -p option is not used,
2472654012fSReza Sabdar 		 * otherwise index to argv.
2482654012fSReza Sabdar 		 */
2492654012fSReza Sabdar 		argc -= optind;
2502654012fSReza Sabdar 		argv += optind;
2512654012fSReza Sabdar 
2522654012fSReza Sabdar 		for (i = 0; i < argc; i++) {
2532654012fSReza Sabdar 			if (strncmp(argv[i], "-p", 2) == 0)
2542654012fSReza Sabdar 				continue;
2552654012fSReza Sabdar 
2562654012fSReza Sabdar 			ndmp_get_config_process(argv[i]);
2572654012fSReza Sabdar 		}
2582654012fSReza Sabdar 	}
2592654012fSReza Sabdar 	return (0);
2602654012fSReza Sabdar }
2612654012fSReza Sabdar 
2622654012fSReza Sabdar static void
2632654012fSReza Sabdar ndmp_get_config_process(char *arg)
2642654012fSReza Sabdar {
2652654012fSReza Sabdar 	int j;
2662654012fSReza Sabdar 	char *propval;
2672654012fSReza Sabdar 
2682654012fSReza Sabdar 	for (j = 0; j < NDMPADM_NPROP; j++) {
2692654012fSReza Sabdar 		if (strcmp(arg, prop_table[j]) == 0) {
2702654012fSReza Sabdar 			if (ndmp_get_prop(arg, &propval)) {
2712654012fSReza Sabdar 				(void) fprintf(stdout, "\t%s=\n", arg);
2722654012fSReza Sabdar 			} else {
2732654012fSReza Sabdar 				(void) fprintf(stdout, "\t%s=%s\n",
2742654012fSReza Sabdar 				    arg, propval);
2752654012fSReza Sabdar 				free(propval);
2762654012fSReza Sabdar 			}
2772654012fSReza Sabdar 			break;
2782654012fSReza Sabdar 		}
2792654012fSReza Sabdar 	}
2802654012fSReza Sabdar 	if (j == NDMPADM_NPROP) {
2812654012fSReza Sabdar 		(void) fprintf(stdout, gettext("\t%s is invalid property "
2822654012fSReza Sabdar 		    "or variable\n"), arg);
2832654012fSReza Sabdar 	}
2842654012fSReza Sabdar }
2852654012fSReza Sabdar 
2862654012fSReza Sabdar /*ARGSUSED*/
2872654012fSReza Sabdar static int
2882654012fSReza Sabdar ndmp_set_config(int argc, char **argv, ndmp_command_t *cur_cmd)
2892654012fSReza Sabdar {
2902654012fSReza Sabdar 	int c, i;
2912654012fSReza Sabdar 
2922654012fSReza Sabdar 	if (argc < 2) {
2932654012fSReza Sabdar 		(void) fprintf(stderr, gettext("Missing property=value "
2942654012fSReza Sabdar 		    "argument\n"));
2952654012fSReza Sabdar 		usage(B_FALSE, cur_cmd);
2962654012fSReza Sabdar 	}
2972654012fSReza Sabdar 	while ((c = getopt(argc, argv, ":p:")) != -1) {
2982654012fSReza Sabdar 		switch (c) {
2992654012fSReza Sabdar 		case 'p':
3002654012fSReza Sabdar 			ndmp_set_config_process(optarg);
3012654012fSReza Sabdar 			break;
3022654012fSReza Sabdar 		case ':':
3032654012fSReza Sabdar 			(void) fprintf(stderr, gettext("Option -%c "
3042654012fSReza Sabdar 			    "requires an operand\n"), optopt);
3052654012fSReza Sabdar 			break;
3062654012fSReza Sabdar 		case '?':
3072654012fSReza Sabdar 			(void) fprintf(stderr, gettext("Unrecognized "
3082654012fSReza Sabdar 			    "option: -%c\n"), optopt);
3092654012fSReza Sabdar 		}
3102654012fSReza Sabdar 	}
3112654012fSReza Sabdar 	/*
3122654012fSReza Sabdar 	 * optind is initialized to 1 if the -p option is not used,
3132654012fSReza Sabdar 	 * otherwise index to argv.
3142654012fSReza Sabdar 	 */
3152654012fSReza Sabdar 	argc -= optind;
3162654012fSReza Sabdar 	argv += optind;
3172654012fSReza Sabdar 
3182654012fSReza Sabdar 	for (i = 0; i < argc; i++) {
3192654012fSReza Sabdar 		if (strncmp(argv[i], "-p", 2) == 0)
3202654012fSReza Sabdar 			continue;
3212654012fSReza Sabdar 
3222654012fSReza Sabdar 		ndmp_set_config_process(argv[i]);
3232654012fSReza Sabdar 	}
3242654012fSReza Sabdar 	return (0);
3252654012fSReza Sabdar }
3262654012fSReza Sabdar 
3272654012fSReza Sabdar static void
3282654012fSReza Sabdar ndmp_set_config_process(char *propname)
3292654012fSReza Sabdar {
3302654012fSReza Sabdar 	char *propvalue;
3312654012fSReza Sabdar 	int ret, j;
3322654012fSReza Sabdar 
3332654012fSReza Sabdar 	if ((propvalue = strchr(propname, '=')) == NULL) {
3342654012fSReza Sabdar 		(void) fprintf(stderr, gettext("Missing value in "
3352654012fSReza Sabdar 		    "property=value argument for %s\n"), propname);
3362654012fSReza Sabdar 			return;
3372654012fSReza Sabdar 	}
3382654012fSReza Sabdar 	*propvalue = '\0';
3392654012fSReza Sabdar 	propvalue++;
3402654012fSReza Sabdar 
3412654012fSReza Sabdar 	if (*propname == '\0') {
3422654012fSReza Sabdar 		(void) fprintf(stderr, gettext("Missing property in "
3432654012fSReza Sabdar 		    "property=value argument for %s\n"), propname);
3442654012fSReza Sabdar 			return;
3452654012fSReza Sabdar 	}
3462654012fSReza Sabdar 	for (j = 0; j < NDMPADM_NPROP; j++) {
3472654012fSReza Sabdar 		if (strcmp(propname, prop_table[j]) == 0)
3482654012fSReza Sabdar 			break;
3492654012fSReza Sabdar 	}
3502654012fSReza Sabdar 	if (j == NDMPADM_NPROP) {
3512654012fSReza Sabdar 		(void) fprintf(stdout, gettext("%s is invalid property or "
3522654012fSReza Sabdar 		    "variable\n"), propname);
3532654012fSReza Sabdar 		return;
3542654012fSReza Sabdar 	}
3552654012fSReza Sabdar 	ret = ndmp_set_prop(propname, propvalue);
3562654012fSReza Sabdar 	if (ret != -1) {
3572654012fSReza Sabdar 		if (!ndmp_door_status()) {
358*f093add7SJan Kryl 			if (ndmp_service_refresh() != 0)
3592654012fSReza Sabdar 				(void) fprintf(stdout, gettext("Could not "
3602654012fSReza Sabdar 				    "refesh property of service ndmpd\n"));
3612654012fSReza Sabdar 		}
3622654012fSReza Sabdar 	} else {
3632654012fSReza Sabdar 		(void) fprintf(stdout, gettext("Could not set property for "
3642654012fSReza Sabdar 		    "%s - %s\n"), propname, ndmp_strerror(ndmp_errno));
3652654012fSReza Sabdar 	}
3662654012fSReza Sabdar }
3672654012fSReza Sabdar 
3682654012fSReza Sabdar /*ARGSUSED*/
3692654012fSReza Sabdar static int
3702654012fSReza Sabdar ndmp_show_devices(int argc, char **argv, ndmp_command_t *cur_cmd)
3712654012fSReza Sabdar {
3722654012fSReza Sabdar 	int ret;
3732654012fSReza Sabdar 	ndmp_devinfo_t *dip = NULL;
3742654012fSReza Sabdar 	size_t size;
3752654012fSReza Sabdar 
3762654012fSReza Sabdar 	if (ndmp_door_status()) {
3772654012fSReza Sabdar 		(void) fprintf(stdout,
3782654012fSReza Sabdar 		    gettext("Service ndmpd not running\n"));
3792654012fSReza Sabdar 		return (-1);
3802654012fSReza Sabdar 	}
3812654012fSReza Sabdar 
3822654012fSReza Sabdar 	ret = ndmp_get_devinfo(&dip, &size);
3832654012fSReza Sabdar 
3842654012fSReza Sabdar 	if (ret == -1)
3852654012fSReza Sabdar 		(void) fprintf(stdout,
3862654012fSReza Sabdar 		    gettext("Could not get device information\n"));
3872654012fSReza Sabdar 	else
3882654012fSReza Sabdar 		ndmp_devinfo_print(dip, size);
3892654012fSReza Sabdar 
3902654012fSReza Sabdar 	ndmp_get_devinfo_free(dip, size);
3912654012fSReza Sabdar 	return (0);
3922654012fSReza Sabdar }
3932654012fSReza Sabdar 
3942654012fSReza Sabdar static int
3952654012fSReza Sabdar ndmp_show_sessions(int argc, char **argv, ndmp_command_t *cur_cmd)
3962654012fSReza Sabdar {
3972654012fSReza Sabdar 	ndmp_session_info_t *sinfo = NULL;
3982654012fSReza Sabdar 	ndmp_session_info_t *sp = NULL;
3992654012fSReza Sabdar 	uint_t num;
4002654012fSReza Sabdar 	int c, ret, i, j;
4012654012fSReza Sabdar 	int statarg = 0;
4022654012fSReza Sabdar 	char *value;
4032654012fSReza Sabdar 	char *type_subopts[] = { "tape", "scsi", "data", "mover", NULL };
4042654012fSReza Sabdar 
4052654012fSReza Sabdar 	if (ndmp_door_status()) {
4062654012fSReza Sabdar 		(void) fprintf(stdout,
4072654012fSReza Sabdar 		    gettext("Service ndmpd not running\n"));
4082654012fSReza Sabdar 		return (-1);
4092654012fSReza Sabdar 	}
4102654012fSReza Sabdar 
4112654012fSReza Sabdar 	/* Detail output if no option is specified */
4122654012fSReza Sabdar 	if (argc == 1) {
4132654012fSReza Sabdar 		statarg = NDMP_CAT_ALL;
4142654012fSReza Sabdar 	} else {
4152654012fSReza Sabdar 		statarg = 0;
4162654012fSReza Sabdar 		while ((c = getopt(argc, argv, ":i:")) != -1) {
4172654012fSReza Sabdar 			switch (c) {
4182654012fSReza Sabdar 			case 'i':
4192654012fSReza Sabdar 				while (*optarg != '\0') {
4202654012fSReza Sabdar 					switch (getsubopt(&optarg, type_subopts,
4212654012fSReza Sabdar 					    &value)) {
4222654012fSReza Sabdar 					case 0:
4232654012fSReza Sabdar 						statarg |= NDMP_CAT_TAPE;
4242654012fSReza Sabdar 						break;
4252654012fSReza Sabdar 					case 1:
4262654012fSReza Sabdar 						statarg |= NDMP_CAT_SCSI;
4272654012fSReza Sabdar 						break;
4282654012fSReza Sabdar 					case 2:
4292654012fSReza Sabdar 						statarg |= NDMP_CAT_DATA;
4302654012fSReza Sabdar 						break;
4312654012fSReza Sabdar 					case 3:
4322654012fSReza Sabdar 						statarg |= NDMP_CAT_MOVER;
4332654012fSReza Sabdar 						break;
4342654012fSReza Sabdar 					default:
4352654012fSReza Sabdar 						(void) fprintf(stderr,
4362654012fSReza Sabdar 						    gettext("Invalid object "
4372654012fSReza Sabdar 						    "type '%s'\n"), value);
4382654012fSReza Sabdar 						usage(B_FALSE, cur_cmd);
4392654012fSReza Sabdar 					}
4402654012fSReza Sabdar 				}
4412654012fSReza Sabdar 				break;
4422654012fSReza Sabdar 			case ':':
4432654012fSReza Sabdar 				(void) fprintf(stderr,
4442654012fSReza Sabdar 				    gettext("Missing argument for "
4452654012fSReza Sabdar 				    "'%c' option\n"), optopt);
4462654012fSReza Sabdar 				usage(B_FALSE, cur_cmd);
4472654012fSReza Sabdar 				break;
4482654012fSReza Sabdar 			case '?':
4492654012fSReza Sabdar 				(void) fprintf(stderr,
4502654012fSReza Sabdar 				    gettext("Invalid option '%c'\n"), optopt);
4512654012fSReza Sabdar 				usage(B_FALSE, cur_cmd);
4522654012fSReza Sabdar 			}
4532654012fSReza Sabdar 		}
4542654012fSReza Sabdar 		/* if -i and its argument are not specified, display all */
4552654012fSReza Sabdar 		if (statarg == 0)
4562654012fSReza Sabdar 			statarg = NDMP_CAT_ALL;
4572654012fSReza Sabdar 	}
4582654012fSReza Sabdar 	/*
4592654012fSReza Sabdar 	 * optind is initialized to 1 if the -i option is not used, otherwise
4602654012fSReza Sabdar 	 * index to argv.
4612654012fSReza Sabdar 	 */
4622654012fSReza Sabdar 	argc -= optind;
4632654012fSReza Sabdar 	argv += optind;
4642654012fSReza Sabdar 
4652654012fSReza Sabdar 	ret = ndmp_get_session_info(&sinfo, &num);
4662654012fSReza Sabdar 	if (ret == -1) {
4672654012fSReza Sabdar 		(void) fprintf(stdout,
4682654012fSReza Sabdar 		    gettext("Could not get session information\n"));
4692654012fSReza Sabdar 	} else {
4702654012fSReza Sabdar 		if (argc == 0) {
4712654012fSReza Sabdar 			ndmp_session_all_print(statarg, sinfo, num);
4722654012fSReza Sabdar 		} else {
4732654012fSReza Sabdar 			for (i = 0; i < argc; i++) {
4742654012fSReza Sabdar 				sp = sinfo;
4752654012fSReza Sabdar 				for (j = 0; j < num; j++, sp++) {
4762654012fSReza Sabdar 					if (sp->nsi_sid == atoi(argv[i])) {
4772654012fSReza Sabdar 						ndmp_session_print(statarg, sp);
4782654012fSReza Sabdar 						(void) fprintf(stdout, "\n");
4792654012fSReza Sabdar 						break;
4802654012fSReza Sabdar 					}
4812654012fSReza Sabdar 				}
4822654012fSReza Sabdar 				if (j == num) {
4832654012fSReza Sabdar 					(void) fprintf(stdout,
4842654012fSReza Sabdar 					    gettext("Session %d not "
4852654012fSReza Sabdar 					    "found\n"), atoi(argv[i]));
4862654012fSReza Sabdar 				}
4872654012fSReza Sabdar 			}
4882654012fSReza Sabdar 		}
4892654012fSReza Sabdar 		ndmp_get_session_info_free(sinfo, num);
4902654012fSReza Sabdar 	}
4912654012fSReza Sabdar 	return (0);
4922654012fSReza Sabdar }
4932654012fSReza Sabdar 
4942654012fSReza Sabdar /*ARGSUSED*/
4952654012fSReza Sabdar static int
4962654012fSReza Sabdar ndmp_kill_sessions(int argc, char **argv, ndmp_command_t *cur_cmd)
4972654012fSReza Sabdar {
4982654012fSReza Sabdar 	int ret, i;
4992654012fSReza Sabdar 
5002654012fSReza Sabdar 	if (ndmp_door_status()) {
5012654012fSReza Sabdar 		(void) fprintf(stdout,
5022654012fSReza Sabdar 		    gettext("Service ndmpd not running.\n"));
5032654012fSReza Sabdar 		return (-1);
5042654012fSReza Sabdar 	}
5052654012fSReza Sabdar 
5062654012fSReza Sabdar 	/* If no arg is specified, print the usage and exit */
5072654012fSReza Sabdar 	if (argc == 1)
5082654012fSReza Sabdar 		usage(B_FALSE, cur_cmd);
5092654012fSReza Sabdar 
5102654012fSReza Sabdar 	for (i = 1; i < argc; i++) {
5112654012fSReza Sabdar 		if (atoi(argv[i]) > 0) {
5122654012fSReza Sabdar 			ret = ndmp_terminate_session(atoi(argv[i]));
5132654012fSReza Sabdar 		} else {
5142654012fSReza Sabdar 			(void) fprintf(stderr,
5152654012fSReza Sabdar 			    gettext("Invalid argument %s\n"), argv[i]);
5162654012fSReza Sabdar 				continue;
5172654012fSReza Sabdar 		}
5182654012fSReza Sabdar 		if (ret == -1)
5192654012fSReza Sabdar 			(void) fprintf(stdout,
5202654012fSReza Sabdar 			    gettext("Session id %d not found.\n"),
5212654012fSReza Sabdar 			    atoi(argv[i]));
5222654012fSReza Sabdar 	}
5232654012fSReza Sabdar 	return (0);
5242654012fSReza Sabdar }
5252654012fSReza Sabdar 
5262654012fSReza Sabdar static int
5272654012fSReza Sabdar ndmp_get_password(char **password)
5282654012fSReza Sabdar {
5292654012fSReza Sabdar 	char *pw1, pw2[257];
5302654012fSReza Sabdar 	int i;
5312654012fSReza Sabdar 
5322654012fSReza Sabdar 	for (i = 0; i < NDMP_PASSWORD_RETRIES; i++) {
5332654012fSReza Sabdar 		/*
5342654012fSReza Sabdar 		 * getpassphrase use the same buffer to return password, so
5352654012fSReza Sabdar 		 * copy the result in different buffer, before calling the
5362654012fSReza Sabdar 		 * getpassphrase again.
5372654012fSReza Sabdar 		 */
5382654012fSReza Sabdar 		if ((pw1 =
5392654012fSReza Sabdar 		    getpassphrase(gettext("Enter new password: "))) != NULL) {
5402654012fSReza Sabdar 			(void) strlcpy(pw2, pw1, sizeof (pw2));
5412654012fSReza Sabdar 			if ((pw1 =
5422654012fSReza Sabdar 			    getpassphrase(gettext("Re-enter  password: ")))
5432654012fSReza Sabdar 			    != NULL) {
5442654012fSReza Sabdar 				if (strncmp(pw1, pw2, strlen(pw1)) == 0) {
5452654012fSReza Sabdar 					*password = pw1;
5462654012fSReza Sabdar 					return (0);
5472654012fSReza Sabdar 				} else {
5482654012fSReza Sabdar 					(void) fprintf(stderr,
5492654012fSReza Sabdar 					    gettext("Both password did not "
5502654012fSReza Sabdar 					    "match.\n"));
5512654012fSReza Sabdar 				}
5522654012fSReza Sabdar 			}
5532654012fSReza Sabdar 		}
5542654012fSReza Sabdar 	}
5552654012fSReza Sabdar 	return (-1);
5562654012fSReza Sabdar }
5572654012fSReza Sabdar 
5582654012fSReza Sabdar static int
5592654012fSReza Sabdar ndmp_enable_auth(int argc, char **argv, ndmp_command_t *cur_cmd)
5602654012fSReza Sabdar {
5612654012fSReza Sabdar 	char *auth_type, *username, *password;
5622654012fSReza Sabdar 	int c, i, auth_type_flag = 0;
5632654012fSReza Sabdar 	char *enc_password;
5642654012fSReza Sabdar 
5652654012fSReza Sabdar 	/* enable <-a auth-type> <-u username> */
5662654012fSReza Sabdar 	if (argc != 5) {
5672654012fSReza Sabdar 		usage(B_FALSE, cur_cmd);
5682654012fSReza Sabdar 	}
5692654012fSReza Sabdar 
5702654012fSReza Sabdar 	while ((c = getopt(argc, argv, ":a:u:")) != -1) {
5712654012fSReza Sabdar 		switch (c) {
5722654012fSReza Sabdar 		case 'a':
5732654012fSReza Sabdar 			auth_type = strdup(optarg);
5742654012fSReza Sabdar 			break;
5752654012fSReza Sabdar 		case 'u':
5762654012fSReza Sabdar 			username = strdup(optarg);
5772654012fSReza Sabdar 			break;
5782654012fSReza Sabdar 		case ':':
5792654012fSReza Sabdar 			(void) fprintf(stderr, gettext("Option -%c "
5802654012fSReza Sabdar 			    "requires an operand\n"), optopt);
5812654012fSReza Sabdar 			usage(B_FALSE, cur_cmd);
5822654012fSReza Sabdar 			break;
5832654012fSReza Sabdar 		case '?':
5842654012fSReza Sabdar 			(void) fprintf(stderr, gettext("Unrecognized "
5852654012fSReza Sabdar 			    "option: -%c\n"), optopt);
5862654012fSReza Sabdar 			usage(B_FALSE, cur_cmd);
5872654012fSReza Sabdar 		}
5882654012fSReza Sabdar 	}
5892654012fSReza Sabdar 
5902654012fSReza Sabdar 	if ((auth_type) && (username)) {
5912654012fSReza Sabdar 		if (ndmp_get_password(&password)) {
5922654012fSReza Sabdar 			(void) fprintf(stderr, gettext("Could not get correct "
5932654012fSReza Sabdar 			    "password, exiting..."));
5942654012fSReza Sabdar 			free(auth_type);
5952654012fSReza Sabdar 			free(username);
5962654012fSReza Sabdar 			exit(-1);
5972654012fSReza Sabdar 		}
5982654012fSReza Sabdar 	} else {
5992654012fSReza Sabdar 		(void) fprintf(stderr, gettext("%s or %s can not be blank"),
6002654012fSReza Sabdar 		    "'auth-type'", "'username'");
6012654012fSReza Sabdar 		free(auth_type);
6022654012fSReza Sabdar 		free(username);
6032654012fSReza Sabdar 		exit(-1);
6042654012fSReza Sabdar 	}
6052654012fSReza Sabdar 
6062654012fSReza Sabdar 	if ((enc_password = ndmp_base64_encode(password)) == NULL) {
6072654012fSReza Sabdar 		(void) fprintf(stdout,
6082654012fSReza Sabdar 		    gettext("Could not encode password - %s\n"),
6092654012fSReza Sabdar 		    ndmp_strerror(ndmp_errno));
6102654012fSReza Sabdar 		free(auth_type);
6112654012fSReza Sabdar 		free(username);
6122654012fSReza Sabdar 		exit(-1);
6132654012fSReza Sabdar 	}
6142654012fSReza Sabdar 
6152654012fSReza Sabdar 	for (i = 0; i < NAUTH; i++) {
6162654012fSReza Sabdar 		if (strncmp(auth_type, ndmp_auth_table[i].auth_type,
6172654012fSReza Sabdar 		    strlen(ndmp_auth_table[i].auth_type)) == 0) {
6182654012fSReza Sabdar 			auth_type_flag = 1;
6198b87c155SJan Kryl 			if ((ndmp_set_prop(ndmp_auth_table[i].username,
6202654012fSReza Sabdar 			    username)) == -1) {
6212654012fSReza Sabdar 				(void) fprintf(stdout,
6222654012fSReza Sabdar 				    gettext("Could not set username - %s\n"),
6232654012fSReza Sabdar 				    ndmp_strerror(ndmp_errno));
6242654012fSReza Sabdar 				continue;
6252654012fSReza Sabdar 			}
6268b87c155SJan Kryl 			if ((ndmp_set_prop(ndmp_auth_table[i].password,
6272654012fSReza Sabdar 			    enc_password)) == -1) {
6282654012fSReza Sabdar 				(void) fprintf(stdout,
6292654012fSReza Sabdar 				    gettext("Could not set password - %s\n"),
6302654012fSReza Sabdar 				    ndmp_strerror(ndmp_errno));
6312654012fSReza Sabdar 				continue;
6322654012fSReza Sabdar 			}
6332654012fSReza Sabdar 			if (!ndmp_door_status() &&
634*f093add7SJan Kryl 			    (ndmp_service_refresh()) != 0) {
6352654012fSReza Sabdar 				(void) fprintf(stdout,
6362654012fSReza Sabdar 				    gettext("Could not refesh ndmpd service "
6372654012fSReza Sabdar 				    "properties\n"));
6382654012fSReza Sabdar 			}
6392654012fSReza Sabdar 		}
6402654012fSReza Sabdar 	}
6412654012fSReza Sabdar 	free(auth_type);
6422654012fSReza Sabdar 	free(username);
6432654012fSReza Sabdar 	free(enc_password);
6442654012fSReza Sabdar 
6452654012fSReza Sabdar 	if (!auth_type_flag)
6462654012fSReza Sabdar 		usage(B_FALSE, cur_cmd);
6472654012fSReza Sabdar 
6482654012fSReza Sabdar 	return (0);
6492654012fSReza Sabdar }
6502654012fSReza Sabdar 
6512654012fSReza Sabdar static int
6522654012fSReza Sabdar ndmp_disable_auth(int argc, char **argv, ndmp_command_t *cur_cmd)
6532654012fSReza Sabdar {
6542654012fSReza Sabdar 	char *auth_type;
6552654012fSReza Sabdar 	int c, i, auth_type_flag = 0;
6562654012fSReza Sabdar 
6572654012fSReza Sabdar 	/* disable <-a auth-type> */
6582654012fSReza Sabdar 	if (argc != 3) {
6592654012fSReza Sabdar 		usage(B_FALSE, cur_cmd);
6602654012fSReza Sabdar 	}
6612654012fSReza Sabdar 
6622654012fSReza Sabdar 	while ((c = getopt(argc, argv, ":a:")) != -1) {
6632654012fSReza Sabdar 		switch (c) {
6642654012fSReza Sabdar 		case 'a':
6652654012fSReza Sabdar 			auth_type = strdup(optarg);
6662654012fSReza Sabdar 			break;
6672654012fSReza Sabdar 		case ':':
6682654012fSReza Sabdar 			(void) fprintf(stderr, gettext("Option -%c "
6692654012fSReza Sabdar 			    "requires an operand\n"), optopt);
6702654012fSReza Sabdar 			break;
6712654012fSReza Sabdar 		case '?':
6722654012fSReza Sabdar 			(void) fprintf(stderr, gettext("Unrecognized "
6732654012fSReza Sabdar 			    "option: -%c\n"), optopt);
6742654012fSReza Sabdar 		}
6752654012fSReza Sabdar 	}
6762654012fSReza Sabdar 	for (i = 0; i < NAUTH; i++) {
6772654012fSReza Sabdar 		if (strncmp(auth_type, ndmp_auth_table[i].auth_type,
6782654012fSReza Sabdar 		    strlen(ndmp_auth_table[i].auth_type)) == 0) {
6792654012fSReza Sabdar 			auth_type_flag = 1;
6808b87c155SJan Kryl 			if ((ndmp_set_prop(ndmp_auth_table[i].username,
6812654012fSReza Sabdar 			    "")) == -1) {
6822654012fSReza Sabdar 				(void) fprintf(stdout,
6832654012fSReza Sabdar 				    gettext("Could not clear username - %s\n"),
6842654012fSReza Sabdar 				    ndmp_strerror(ndmp_errno));
6852654012fSReza Sabdar 				continue;
6862654012fSReza Sabdar 			}
6878b87c155SJan Kryl 			if ((ndmp_set_prop(ndmp_auth_table[i].password,
6882654012fSReza Sabdar 			    "")) == -1) {
6892654012fSReza Sabdar 				(void) fprintf(stdout,
6902654012fSReza Sabdar 				    gettext("Could not clear password - %s\n"),
6912654012fSReza Sabdar 				    ndmp_strerror(ndmp_errno));
6922654012fSReza Sabdar 				continue;
6932654012fSReza Sabdar 			}
6942654012fSReza Sabdar 			if (!ndmp_door_status() &&
695*f093add7SJan Kryl 			    (ndmp_service_refresh()) != 0) {
6962654012fSReza Sabdar 				(void) fprintf(stdout, gettext("Could not "
6972654012fSReza Sabdar 				    "refesh ndmpd service properties\n"));
6982654012fSReza Sabdar 			}
6992654012fSReza Sabdar 		}
7002654012fSReza Sabdar 	}
7012654012fSReza Sabdar 	free(auth_type);
7022654012fSReza Sabdar 
7032654012fSReza Sabdar 	if (!auth_type_flag)
7042654012fSReza Sabdar 		usage(B_FALSE, cur_cmd);
7052654012fSReza Sabdar 
7062654012fSReza Sabdar 	return (0);
7072654012fSReza Sabdar }
7082654012fSReza Sabdar 
7092654012fSReza Sabdar int
7102654012fSReza Sabdar main(int argc, char **argv)
7112654012fSReza Sabdar {
7122654012fSReza Sabdar 	int ret;
7132654012fSReza Sabdar 	int i;
7142654012fSReza Sabdar 	char *cmdname;
7152654012fSReza Sabdar 	ndmp_command_t	*current_command = NULL;
7162654012fSReza Sabdar 
7172654012fSReza Sabdar 	(void) setlocale(LC_ALL, "");
7182654012fSReza Sabdar 	(void) textdomain(TEXT_DOMAIN);
7192654012fSReza Sabdar 
7202654012fSReza Sabdar 	opterr = 0;
7212654012fSReza Sabdar 
7222654012fSReza Sabdar 	/* Make sure the user has specified some command. */
7232654012fSReza Sabdar 	if (argc < 2) {
7242654012fSReza Sabdar 		(void) fprintf(stderr, gettext("Missing command.\n"));
7252654012fSReza Sabdar 		usage(B_FALSE, current_command);
7262654012fSReza Sabdar 	}
7272654012fSReza Sabdar 
7282654012fSReza Sabdar 	cmdname = argv[1];
7292654012fSReza Sabdar 
7302654012fSReza Sabdar 	/*
7312654012fSReza Sabdar 	 * Special case '-?'
7322654012fSReza Sabdar 	 */
7332654012fSReza Sabdar 	if (strcmp(cmdname, "-?") == 0)
7342654012fSReza Sabdar 		usage(B_TRUE, current_command);
7352654012fSReza Sabdar 
7362654012fSReza Sabdar 	/*
7372654012fSReza Sabdar 	 * Run the appropriate sub-command.
7382654012fSReza Sabdar 	 */
7392654012fSReza Sabdar 	for (i = 0; i < NCOMMAND; i++) {
7402654012fSReza Sabdar 		if (strcmp(cmdname, command_table[i].nc_name) == 0) {
7412654012fSReza Sabdar 			current_command = &command_table[i];
7422654012fSReza Sabdar 			ret = command_table[i].func(argc - 1, argv + 1,
7432654012fSReza Sabdar 			    current_command);
7442654012fSReza Sabdar 			break;
7452654012fSReza Sabdar 		}
7462654012fSReza Sabdar 	}
7472654012fSReza Sabdar 
7482654012fSReza Sabdar 	if (i == NCOMMAND) {
7492654012fSReza Sabdar 		(void) fprintf(stderr, gettext("Unrecognized "
7502654012fSReza Sabdar 		    "command '%s'\n"), cmdname);
7512654012fSReza Sabdar 		usage(B_FALSE, current_command);
7522654012fSReza Sabdar 	}
7532654012fSReza Sabdar 
7542654012fSReza Sabdar 	return (ret);
7552654012fSReza Sabdar }
756