1 /*
   2  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
   3  * Copyright 2015 Nexenta Systems, Inc.  All rights reserved.
   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         "zfs-force-override",
 109         "drive-type",
 110         "debug-mode"
 111 };
 112 
 113 #define NDMPADM_NPROP   (sizeof (prop_table) / sizeof (prop_table[0]))
 114 
 115 typedef struct ndmp_auth {
 116         const char *auth_type;
 117         const char *username;
 118         const char *password;
 119 } ndmp_auth_t;
 120 
 121 static ndmp_auth_t ndmp_auth_table[] = {
 122         { "cram-md5", "cram-md5-username", "cram-md5-password" },
 123         { "cleartext", "cleartext-username", "cleartext-password" }
 124 };
 125 #define NAUTH   (sizeof (ndmp_auth_table) / sizeof (ndmp_auth_table[0]))
 126 #define NDMP_PASSWORD_RETRIES   3
 127 
 128 #if !defined(TEXT_DOMAIN)
 129 #define TEXT_DOMAIN     "SYS_TEST"
 130 #endif
 131 
 132 static const char *
 133 get_usage(ndmp_help_t idx)
 134 {
 135         switch (idx) {
 136         case HELP_SET_CONFIG:
 137                 return ("\tset [-p] <property=value> [[-p] property=value] "
 138                     "...\n");
 139         case HELP_GET_CONFIG:
 140                 return ("\tget [-p] [property] [[-p] property] ...\n");
 141         case HELP_SHOW_DEVICES:
 142                 return ("\tshow-devices\n");
 143         case HELP_SHOW_SESSIONS:
 144                 return ("\tshow-sessions [-i tape,scsi,data,mover] [id] ...\n");
 145         case HELP_KILL_SESSIONS:
 146                 return ("\tkill-sessions <id ...>\n");
 147         case HELP_ENABLE_AUTH:
 148                 return ("\tenable <-a auth-type> <-u username>\n");
 149         case HELP_DISABLE_AUTH:
 150                 return ("\tdisable <-a auth-type>\n");
 151         }
 152 
 153         return (NULL);
 154 }
 155 
 156 /*
 157  * Display usage message.  If we're inside a command, display only the usage for
 158  * that command.  Otherwise, iterate over the entire command table and display
 159  * a complete usage message.
 160  */
 161 static void
 162 usage(boolean_t requested, ndmp_command_t *current_command)
 163 {
 164         int i;
 165         boolean_t show_properties = B_FALSE;
 166         FILE *fp = requested ? stdout : stderr;
 167 
 168         if (current_command == NULL) {
 169                 (void) fprintf(fp,
 170                     gettext("Usage: ndmpadm subcommand args ...\n"));
 171                 (void) fprintf(fp,
 172                     gettext("where 'command' is one of the following:\n\n"));
 173 
 174                 for (i = 0; i < NCOMMAND; i++) {
 175                         (void) fprintf(fp, "%s",
 176                             get_usage(command_table[i].nc_usage));
 177                 }
 178                 (void) fprintf(fp, gettext("\t\twhere %s can be either "
 179                     "%s or %s\n"), "'auth-type'", "'cram-md5'", "'cleartext'");
 180         } else {
 181                 (void) fprintf(fp, gettext("Usage:\n"));
 182                 (void) fprintf(fp, "%s", get_usage(current_command->nc_usage));
 183                 if ((current_command->nc_usage == HELP_ENABLE_AUTH) ||
 184                     (current_command->nc_usage == HELP_DISABLE_AUTH))
 185                         (void) fprintf(fp, gettext("\t\twhere %s can be either "
 186                             "%s or %s\n"),
 187                             "'auth-type'", "'cram-md5'", "'cleartext'");
 188         }
 189 
 190         if (current_command != NULL &&
 191             (strcmp(current_command->nc_name, "set") == 0))
 192                 show_properties = B_TRUE;
 193 
 194         if (show_properties) {
 195                 (void) fprintf(fp,
 196                     gettext("\nThe following properties are supported:\n"));
 197 
 198                 (void) fprintf(fp, gettext("\n\tPROPERTY"));
 199                 (void) fprintf(fp, "\n\t%s", "-------------");
 200                 for (i = 0; i < NDMPADM_NPROP; i++)
 201                         (void) fprintf(fp, "\n\t%s", prop_table[i]);
 202                 (void) fprintf(fp, "\n");
 203         }
 204 
 205         exit(requested ? 0 : 2);
 206 }
 207 
 208 /*ARGSUSED*/
 209 static int
 210 ndmp_get_config(int argc, char **argv, ndmp_command_t *cur_cmd)
 211 {
 212         char *propval;
 213         int i, c;
 214 
 215         if (argc == 1) {
 216                 /*
 217                  * Get all the properties and variables ndmpadm is allowed
 218                  * to see.
 219                  */
 220                 for (i = 0; i < NDMPADM_NPROP; i++) {
 221                         if (ndmp_get_prop(prop_table[i], &propval)) {
 222                                 (void) fprintf(stdout, "\t%s=\n",
 223                                     prop_table[i]);
 224                         } else {
 225                                 (void) fprintf(stdout, "\t%s=%s\n",
 226                                     prop_table[i], propval);
 227                                 free(propval);
 228                         }
 229                 }
 230         } else if (argc > 1) {
 231                 while ((c = getopt(argc, argv, ":p:")) != -1) {
 232                         switch (c) {
 233                         case 'p':
 234                                 ndmp_get_config_process(optarg);
 235                                 break;
 236                         case ':':
 237                                 (void) fprintf(stderr, gettext("Option -%c "
 238                                     "requires an operand\n"), optopt);
 239                                 break;
 240                         case '?':
 241                                 (void) fprintf(stderr, gettext("Unrecognized "
 242                                     "option: -%c\n"), optopt);
 243                         }
 244                 }
 245                 /*
 246                  * optind is initialized to 1 if the -p option is not used,
 247                  * otherwise index to argv.
 248                  */
 249                 argc -= optind;
 250                 argv += optind;
 251 
 252                 for (i = 0; i < argc; i++) {
 253                         if (strncmp(argv[i], "-p", 2) == 0)
 254                                 continue;
 255 
 256                         ndmp_get_config_process(argv[i]);
 257                 }
 258         }
 259         return (0);
 260 }
 261 
 262 static void
 263 ndmp_get_config_process(char *arg)
 264 {
 265         int j;
 266         char *propval;
 267 
 268         for (j = 0; j < NDMPADM_NPROP; j++) {
 269                 if (strcmp(arg, prop_table[j]) == 0) {
 270                         if (ndmp_get_prop(arg, &propval)) {
 271                                 (void) fprintf(stdout, "\t%s=\n", arg);
 272                         } else {
 273                                 (void) fprintf(stdout, "\t%s=%s\n",
 274                                     arg, propval);
 275                                 free(propval);
 276                         }
 277                         break;
 278                 }
 279         }
 280         if (j == NDMPADM_NPROP) {
 281                 (void) fprintf(stdout, gettext("\t%s is invalid property "
 282                     "or variable\n"), arg);
 283         }
 284 }
 285 
 286 /*ARGSUSED*/
 287 static int
 288 ndmp_set_config(int argc, char **argv, ndmp_command_t *cur_cmd)
 289 {
 290         int c, i;
 291 
 292         if (argc < 2) {
 293                 (void) fprintf(stderr, gettext("Missing property=value "
 294                     "argument\n"));
 295                 usage(B_FALSE, cur_cmd);
 296         }
 297         while ((c = getopt(argc, argv, ":p:")) != -1) {
 298                 switch (c) {
 299                 case 'p':
 300                         ndmp_set_config_process(optarg);
 301                         break;
 302                 case ':':
 303                         (void) fprintf(stderr, gettext("Option -%c "
 304                             "requires an operand\n"), optopt);
 305                         break;
 306                 case '?':
 307                         (void) fprintf(stderr, gettext("Unrecognized "
 308                             "option: -%c\n"), optopt);
 309                 }
 310         }
 311         /*
 312          * optind is initialized to 1 if the -p option is not used,
 313          * otherwise index to argv.
 314          */
 315         argc -= optind;
 316         argv += optind;
 317 
 318         for (i = 0; i < argc; i++) {
 319                 if (strncmp(argv[i], "-p", 2) == 0)
 320                         continue;
 321 
 322                 ndmp_set_config_process(argv[i]);
 323         }
 324         return (0);
 325 }
 326 
 327 static void
 328 ndmp_set_config_process(char *propname)
 329 {
 330         char *propvalue;
 331         int ret, j;
 332 
 333         if ((propvalue = strchr(propname, '=')) == NULL) {
 334                 (void) fprintf(stderr, gettext("Missing value in "
 335                     "property=value argument for %s\n"), propname);
 336                         return;
 337         }
 338         *propvalue = '\0';
 339         propvalue++;
 340 
 341         if (*propname == '\0') {
 342                 (void) fprintf(stderr, gettext("Missing property in "
 343                     "property=value argument for %s\n"), propname);
 344                         return;
 345         }
 346         for (j = 0; j < NDMPADM_NPROP; j++) {
 347                 if (strcmp(propname, prop_table[j]) == 0)
 348                         break;
 349         }
 350         if (j == NDMPADM_NPROP) {
 351                 (void) fprintf(stdout, gettext("%s is invalid property or "
 352                     "variable\n"), propname);
 353                 return;
 354         }
 355         ret = ndmp_set_prop(propname, propvalue);
 356         if (ret != -1) {
 357                 if (!ndmp_door_status()) {
 358                         if (ndmp_service_refresh() != 0)
 359                                 (void) fprintf(stdout, gettext("Could not "
 360                                     "refesh property of service ndmpd\n"));
 361                 }
 362         } else {
 363                 (void) fprintf(stdout, gettext("Could not set property for "
 364                     "%s - %s\n"), propname, ndmp_strerror(ndmp_errno));
 365         }
 366 }
 367 
 368 /*ARGSUSED*/
 369 static int
 370 ndmp_show_devices(int argc, char **argv, ndmp_command_t *cur_cmd)
 371 {
 372         int ret;
 373         ndmp_devinfo_t *dip = NULL;
 374         size_t size;
 375 
 376         if (ndmp_door_status()) {
 377                 (void) fprintf(stdout,
 378                     gettext("Service ndmpd not running\n"));
 379                 return (-1);
 380         }
 381 
 382         ret = ndmp_get_devinfo(&dip, &size);
 383 
 384         if (ret == -1)
 385                 (void) fprintf(stdout,
 386                     gettext("Could not get device information\n"));
 387         else
 388                 ndmp_devinfo_print(dip, size);
 389 
 390         ndmp_get_devinfo_free(dip, size);
 391         return (0);
 392 }
 393 
 394 static int
 395 ndmp_show_sessions(int argc, char **argv, ndmp_command_t *cur_cmd)
 396 {
 397         ndmp_session_info_t *sinfo = NULL;
 398         ndmp_session_info_t *sp = NULL;
 399         uint_t num;
 400         int c, ret, i, j;
 401         int statarg = 0;
 402         char *value;
 403         char *type_subopts[] = { "tape", "scsi", "data", "mover", NULL };
 404 
 405         if (ndmp_door_status()) {
 406                 (void) fprintf(stdout,
 407                     gettext("Service ndmpd not running\n"));
 408                 return (-1);
 409         }
 410 
 411         /* Detail output if no option is specified */
 412         if (argc == 1) {
 413                 statarg = NDMP_CAT_ALL;
 414         } else {
 415                 statarg = 0;
 416                 while ((c = getopt(argc, argv, ":i:")) != -1) {
 417                         switch (c) {
 418                         case 'i':
 419                                 while (*optarg != '\0') {
 420                                         switch (getsubopt(&optarg, type_subopts,
 421                                             &value)) {
 422                                         case 0:
 423                                                 statarg |= NDMP_CAT_TAPE;
 424                                                 break;
 425                                         case 1:
 426                                                 statarg |= NDMP_CAT_SCSI;
 427                                                 break;
 428                                         case 2:
 429                                                 statarg |= NDMP_CAT_DATA;
 430                                                 break;
 431                                         case 3:
 432                                                 statarg |= NDMP_CAT_MOVER;
 433                                                 break;
 434                                         default:
 435                                                 (void) fprintf(stderr,
 436                                                     gettext("Invalid object "
 437                                                     "type '%s'\n"), value);
 438                                                 usage(B_FALSE, cur_cmd);
 439                                         }
 440                                 }
 441                                 break;
 442                         case ':':
 443                                 (void) fprintf(stderr,
 444                                     gettext("Missing argument for "
 445                                     "'%c' option\n"), optopt);
 446                                 usage(B_FALSE, cur_cmd);
 447                                 break;
 448                         case '?':
 449                                 (void) fprintf(stderr,
 450                                     gettext("Invalid option '%c'\n"), optopt);
 451                                 usage(B_FALSE, cur_cmd);
 452                         }
 453                 }
 454                 /* if -i and its argument are not specified, display all */
 455                 if (statarg == 0)
 456                         statarg = NDMP_CAT_ALL;
 457         }
 458         /*
 459          * optind is initialized to 1 if the -i option is not used, otherwise
 460          * index to argv.
 461          */
 462         argc -= optind;
 463         argv += optind;
 464 
 465         ret = ndmp_get_session_info(&sinfo, &num);
 466         if (ret == -1) {
 467                 (void) fprintf(stdout,
 468                     gettext("Could not get session information\n"));
 469         } else {
 470                 if (argc == 0) {
 471                         ndmp_session_all_print(statarg, sinfo, num);
 472                 } else {
 473                         for (i = 0; i < argc; i++) {
 474                                 sp = sinfo;
 475                                 for (j = 0; j < num; j++, sp++) {
 476                                         if (sp->nsi_sid == atoi(argv[i])) {
 477                                                 ndmp_session_print(statarg, sp);
 478                                                 (void) fprintf(stdout, "\n");
 479                                                 break;
 480                                         }
 481                                 }
 482                                 if (j == num) {
 483                                         (void) fprintf(stdout,
 484                                             gettext("Session %d not "
 485                                             "found\n"), atoi(argv[i]));
 486                                 }
 487                         }
 488                 }
 489                 ndmp_get_session_info_free(sinfo, num);
 490         }
 491         return (0);
 492 }
 493 
 494 /*ARGSUSED*/
 495 static int
 496 ndmp_kill_sessions(int argc, char **argv, ndmp_command_t *cur_cmd)
 497 {
 498         int ret, i;
 499 
 500         if (ndmp_door_status()) {
 501                 (void) fprintf(stdout,
 502                     gettext("Service ndmpd not running.\n"));
 503                 return (-1);
 504         }
 505 
 506         /* If no arg is specified, print the usage and exit */
 507         if (argc == 1)
 508                 usage(B_FALSE, cur_cmd);
 509 
 510         for (i = 1; i < argc; i++) {
 511                 if (atoi(argv[i]) > 0) {
 512                         ret = ndmp_terminate_session(atoi(argv[i]));
 513                 } else {
 514                         (void) fprintf(stderr,
 515                             gettext("Invalid argument %s\n"), argv[i]);
 516                                 continue;
 517                 }
 518                 if (ret == -1)
 519                         (void) fprintf(stdout,
 520                             gettext("Session id %d not found.\n"),
 521                             atoi(argv[i]));
 522         }
 523         return (0);
 524 }
 525 
 526 static int
 527 ndmp_get_password(char **password)
 528 {
 529         char *pw1, pw2[257];
 530         int i;
 531 
 532         for (i = 0; i < NDMP_PASSWORD_RETRIES; i++) {
 533                 /*
 534                  * getpassphrase use the same buffer to return password, so
 535                  * copy the result in different buffer, before calling the
 536                  * getpassphrase again.
 537                  */
 538                 if ((pw1 =
 539                     getpassphrase(gettext("Enter new password: "))) != NULL) {
 540                         (void) strlcpy(pw2, pw1, sizeof (pw2));
 541                         if ((pw1 =
 542                             getpassphrase(gettext("Re-enter  password: ")))
 543                             != NULL) {
 544                                 if (strncmp(pw1, pw2, strlen(pw1)) == 0) {
 545                                         *password = pw1;
 546                                         return (0);
 547                                 } else {
 548                                         (void) fprintf(stderr,
 549                                             gettext("Both password did not "
 550                                             "match.\n"));
 551                                 }
 552                         }
 553                 }
 554         }
 555         return (-1);
 556 }
 557 
 558 static int
 559 ndmp_enable_auth(int argc, char **argv, ndmp_command_t *cur_cmd)
 560 {
 561         char *auth_type, *username, *password;
 562         int c, i, auth_type_flag = 0;
 563         char *enc_password;
 564 
 565         /* enable <-a auth-type> <-u username> */
 566         if (argc != 5) {
 567                 usage(B_FALSE, cur_cmd);
 568         }
 569 
 570         while ((c = getopt(argc, argv, ":a:u:")) != -1) {
 571                 switch (c) {
 572                 case 'a':
 573                         auth_type = strdup(optarg);
 574                         break;
 575                 case 'u':
 576                         username = strdup(optarg);
 577                         break;
 578                 case ':':
 579                         (void) fprintf(stderr, gettext("Option -%c "
 580                             "requires an operand\n"), optopt);
 581                         usage(B_FALSE, cur_cmd);
 582                         break;
 583                 case '?':
 584                         (void) fprintf(stderr, gettext("Unrecognized "
 585                             "option: -%c\n"), optopt);
 586                         usage(B_FALSE, cur_cmd);
 587                 }
 588         }
 589 
 590         if ((auth_type) && (username)) {
 591                 if (ndmp_get_password(&password)) {
 592                         (void) fprintf(stderr, gettext("Could not get correct "
 593                             "password, exiting..."));
 594                         free(auth_type);
 595                         free(username);
 596                         exit(-1);
 597                 }
 598         } else {
 599                 (void) fprintf(stderr, gettext("%s or %s can not be blank"),
 600                     "'auth-type'", "'username'");
 601                 free(auth_type);
 602                 free(username);
 603                 exit(-1);
 604         }
 605 
 606         if ((enc_password = ndmp_base64_encode(password)) == NULL) {
 607                 (void) fprintf(stdout,
 608                     gettext("Could not encode password - %s\n"),
 609                     ndmp_strerror(ndmp_errno));
 610                 free(auth_type);
 611                 free(username);
 612                 exit(-1);
 613         }
 614 
 615         for (i = 0; i < NAUTH; i++) {
 616                 if (strncmp(auth_type, ndmp_auth_table[i].auth_type,
 617                     strlen(ndmp_auth_table[i].auth_type)) == 0) {
 618                         auth_type_flag = 1;
 619                         if ((ndmp_set_prop(ndmp_auth_table[i].username,
 620                             username)) == -1) {
 621                                 (void) fprintf(stdout,
 622                                     gettext("Could not set username - %s\n"),
 623                                     ndmp_strerror(ndmp_errno));
 624                                 continue;
 625                         }
 626                         if ((ndmp_set_prop(ndmp_auth_table[i].password,
 627                             enc_password)) == -1) {
 628                                 (void) fprintf(stdout,
 629                                     gettext("Could not set password - %s\n"),
 630                                     ndmp_strerror(ndmp_errno));
 631                                 continue;
 632                         }
 633                         if (!ndmp_door_status() &&
 634                             (ndmp_service_refresh()) != 0) {
 635                                 (void) fprintf(stdout,
 636                                     gettext("Could not refesh ndmpd service "
 637                                     "properties\n"));
 638                         }
 639                 }
 640         }
 641         free(auth_type);
 642         free(username);
 643         free(enc_password);
 644 
 645         if (!auth_type_flag)
 646                 usage(B_FALSE, cur_cmd);
 647 
 648         return (0);
 649 }
 650 
 651 static int
 652 ndmp_disable_auth(int argc, char **argv, ndmp_command_t *cur_cmd)
 653 {
 654         char *auth_type;
 655         int c, i, auth_type_flag = 0;
 656 
 657         /* disable <-a auth-type> */
 658         if (argc != 3) {
 659                 usage(B_FALSE, cur_cmd);
 660         }
 661 
 662         while ((c = getopt(argc, argv, ":a:")) != -1) {
 663                 switch (c) {
 664                 case 'a':
 665                         auth_type = strdup(optarg);
 666                         break;
 667                 case ':':
 668                         (void) fprintf(stderr, gettext("Option -%c "
 669                             "requires an operand\n"), optopt);
 670                         break;
 671                 case '?':
 672                         (void) fprintf(stderr, gettext("Unrecognized "
 673                             "option: -%c\n"), optopt);
 674                 }
 675         }
 676         for (i = 0; i < NAUTH; i++) {
 677                 if (strncmp(auth_type, ndmp_auth_table[i].auth_type,
 678                     strlen(ndmp_auth_table[i].auth_type)) == 0) {
 679                         auth_type_flag = 1;
 680                         if ((ndmp_set_prop(ndmp_auth_table[i].username,
 681                             "")) == -1) {
 682                                 (void) fprintf(stdout,
 683                                     gettext("Could not clear username - %s\n"),
 684                                     ndmp_strerror(ndmp_errno));
 685                                 continue;
 686                         }
 687                         if ((ndmp_set_prop(ndmp_auth_table[i].password,
 688                             "")) == -1) {
 689                                 (void) fprintf(stdout,
 690                                     gettext("Could not clear password - %s\n"),
 691                                     ndmp_strerror(ndmp_errno));
 692                                 continue;
 693                         }
 694                         if (!ndmp_door_status() &&
 695                             (ndmp_service_refresh()) != 0) {
 696                                 (void) fprintf(stdout, gettext("Could not "
 697                                     "refesh ndmpd service properties\n"));
 698                         }
 699                 }
 700         }
 701         free(auth_type);
 702 
 703         if (!auth_type_flag)
 704                 usage(B_FALSE, cur_cmd);
 705 
 706         return (0);
 707 }
 708 
 709 int
 710 main(int argc, char **argv)
 711 {
 712         int ret;
 713         int i;
 714         char *cmdname;
 715         ndmp_command_t  *current_command = NULL;
 716 
 717         (void) setlocale(LC_ALL, "");
 718         (void) textdomain(TEXT_DOMAIN);
 719 
 720         opterr = 0;
 721 
 722         /* Make sure the user has specified some command. */
 723         if (argc < 2) {
 724                 (void) fprintf(stderr, gettext("Missing command.\n"));
 725                 usage(B_FALSE, current_command);
 726         }
 727 
 728         cmdname = argv[1];
 729 
 730         /*
 731          * Special case '-?'
 732          */
 733         if (strcmp(cmdname, "-?") == 0)
 734                 usage(B_TRUE, current_command);
 735 
 736         /*
 737          * Run the appropriate sub-command.
 738          */
 739         for (i = 0; i < NCOMMAND; i++) {
 740                 if (strcmp(cmdname, command_table[i].nc_name) == 0) {
 741                         current_command = &command_table[i];
 742                         ret = command_table[i].func(argc - 1, argv + 1,
 743                             current_command);
 744                         break;
 745                 }
 746         }
 747 
 748         if (i == NCOMMAND) {
 749                 (void) fprintf(stderr, gettext("Unrecognized "
 750                     "command '%s'\n"), cmdname);
 751                 usage(B_FALSE, current_command);
 752         }
 753 
 754         return (ret);
 755 }