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