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