/*
* Copyright 2015 Nexenta Systems, Inc. All rights reserved.
*/
/*
* BSD 3 Clause License
*
* Copyright (c) 2007, The Storage Networking Industry Association.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* distribution.
*
* - Neither the name of The Storage Networking Industry Association (SNIA)
* nor the names of its contributors may be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <assert.h>
#include <ctype.h>
#include <libgen.h>
#include <libintl.h>
#include <locale.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <unistd.h>
#include <fcntl.h>
#include <door.h>
#include <libndmp.h>
#include "ndmpadm.h"
typedef enum {
} ndmp_help_t;
typedef struct ndmp_command {
const char *nc_name;
struct ndmp_command *cur_cmd);
static int ndmp_get_config(int, char **, ndmp_command_t *);
static int ndmp_set_config(int, char **, ndmp_command_t *);
static int ndmp_show_devices(int, char **, ndmp_command_t *);
static int ndmp_show_sessions(int, char **, ndmp_command_t *);
static int ndmp_kill_sessions(int, char **, ndmp_command_t *);
static int ndmp_enable_auth(int, char **, ndmp_command_t *);
static int ndmp_disable_auth(int, char **, ndmp_command_t *);
static void ndmp_get_config_process(char *);
static void ndmp_set_config_process(char *arg);
static int ndmp_get_password(char **);
};
static char *prop_table[] = {
"debug-path",
"dump-pathnode",
"tar-pathnode",
"ignore-ctime",
"token-maxseq",
"version",
"dar-support",
"tcp-port",
"backup-quarantine",
"restore-quarantine",
"overwrite-quarantine",
"zfs-force-override",
"drive-type",
"debug-mode"
};
typedef struct ndmp_auth {
const char *auth_type;
const char *username;
const char *password;
} ndmp_auth_t;
{ "cram-md5", "cram-md5-username", "cram-md5-password" },
{ "cleartext", "cleartext-username", "cleartext-password" }
};
#if !defined(TEXT_DOMAIN)
#endif
static const char *
{
switch (idx) {
case HELP_SET_CONFIG:
return ("\tset [-p] <property=value> [[-p] property=value] "
"...\n");
case HELP_GET_CONFIG:
return ("\tget [-p] [property] [[-p] property] ...\n");
case HELP_SHOW_DEVICES:
return ("\tshow-devices\n");
case HELP_SHOW_SESSIONS:
return ("\tshow-sessions [-i tape,scsi,data,mover] [id] ...\n");
case HELP_KILL_SESSIONS:
return ("\tkill-sessions <id ...>\n");
case HELP_ENABLE_AUTH:
return ("\tenable <-a auth-type> <-u username>\n");
case HELP_DISABLE_AUTH:
return ("\tdisable <-a auth-type>\n");
}
return (NULL);
}
/*
* Display usage message. If we're inside a command, display only the usage for
* that command. Otherwise, iterate over the entire command table and display
* a complete usage message.
*/
static void
{
int i;
if (current_command == NULL) {
gettext("Usage: ndmpadm subcommand args ...\n"));
gettext("where 'command' is one of the following:\n\n"));
for (i = 0; i < NCOMMAND; i++) {
}
"%s or %s\n"), "'auth-type'", "'cram-md5'", "'cleartext'");
} else {
"%s or %s\n"),
"'auth-type'", "'cram-md5'", "'cleartext'");
}
if (current_command != NULL &&
if (show_properties) {
gettext("\nThe following properties are supported:\n"));
for (i = 0; i < NDMPADM_NPROP; i++)
}
}
/*ARGSUSED*/
static int
{
char *propval;
int i, c;
if (argc == 1) {
/*
* Get all the properties and variables ndmpadm is allowed
* to see.
*/
for (i = 0; i < NDMPADM_NPROP; i++) {
prop_table[i]);
} else {
prop_table[i], propval);
}
}
} else if (argc > 1) {
switch (c) {
case 'p':
break;
case ':':
"requires an operand\n"), optopt);
break;
case '?':
"option: -%c\n"), optopt);
}
}
/*
* optind is initialized to 1 if the -p option is not used,
* otherwise index to argv.
*/
for (i = 0; i < argc; i++) {
continue;
}
}
return (0);
}
static void
{
int j;
char *propval;
for (j = 0; j < NDMPADM_NPROP; j++) {
} else {
}
break;
}
}
if (j == NDMPADM_NPROP) {
"or variable\n"), arg);
}
}
/*ARGSUSED*/
static int
{
int c, i;
if (argc < 2) {
"argument\n"));
}
switch (c) {
case 'p':
break;
case ':':
"requires an operand\n"), optopt);
break;
case '?':
"option: -%c\n"), optopt);
}
}
/*
* optind is initialized to 1 if the -p option is not used,
* otherwise index to argv.
*/
for (i = 0; i < argc; i++) {
continue;
}
return (0);
}
static void
{
char *propvalue;
int ret, j;
"property=value argument for %s\n"), propname);
return;
}
*propvalue = '\0';
propvalue++;
if (*propname == '\0') {
"property=value argument for %s\n"), propname);
return;
}
for (j = 0; j < NDMPADM_NPROP; j++) {
break;
}
if (j == NDMPADM_NPROP) {
"variable\n"), propname);
return;
}
if (ret != -1) {
if (!ndmp_door_status()) {
if (ndmp_service_refresh() != 0)
"refesh property of service ndmpd\n"));
}
} else {
}
}
/*ARGSUSED*/
static int
{
int ret;
if (ndmp_door_status()) {
gettext("Service ndmpd not running\n"));
return (-1);
}
if (ret == -1)
gettext("Could not get device information\n"));
else
return (0);
}
static int
{
int c, ret, i, j;
int statarg = 0;
char *value;
if (ndmp_door_status()) {
gettext("Service ndmpd not running\n"));
return (-1);
}
/* Detail output if no option is specified */
if (argc == 1) {
} else {
statarg = 0;
switch (c) {
case 'i':
while (*optarg != '\0') {
&value)) {
case 0:
statarg |= NDMP_CAT_TAPE;
break;
case 1:
statarg |= NDMP_CAT_SCSI;
break;
case 2:
statarg |= NDMP_CAT_DATA;
break;
case 3:
break;
default:
gettext("Invalid object "
"type '%s'\n"), value);
}
}
break;
case ':':
gettext("Missing argument for "
"'%c' option\n"), optopt);
break;
case '?':
}
}
/* if -i and its argument are not specified, display all */
if (statarg == 0)
}
/*
* optind is initialized to 1 if the -i option is not used, otherwise
* index to argv.
*/
if (ret == -1) {
gettext("Could not get session information\n"));
} else {
if (argc == 0) {
} else {
for (i = 0; i < argc; i++) {
break;
}
}
if (j == num) {
gettext("Session %d not "
}
}
}
}
return (0);
}
/*ARGSUSED*/
static int
{
int ret, i;
if (ndmp_door_status()) {
gettext("Service ndmpd not running.\n"));
return (-1);
}
/* If no arg is specified, print the usage and exit */
if (argc == 1)
for (i = 1; i < argc; i++) {
} else {
continue;
}
if (ret == -1)
gettext("Session id %d not found.\n"),
}
return (0);
}
static int
{
int i;
for (i = 0; i < NDMP_PASSWORD_RETRIES; i++) {
/*
* getpassphrase use the same buffer to return password, so
* copy the result in different buffer, before calling the
* getpassphrase again.
*/
if ((pw1 =
if ((pw1 =
!= NULL) {
return (0);
} else {
gettext("Both password did not "
"match.\n"));
}
}
}
}
return (-1);
}
static int
{
int c, i, auth_type_flag = 0;
char *enc_password;
/* enable <-a auth-type> <-u username> */
if (argc != 5) {
}
switch (c) {
case 'a':
break;
case 'u':
break;
case ':':
"requires an operand\n"), optopt);
break;
case '?':
"option: -%c\n"), optopt);
}
}
if (ndmp_get_password(&password)) {
"password, exiting..."));
exit(-1);
}
} else {
"'auth-type'", "'username'");
exit(-1);
}
gettext("Could not encode password - %s\n"),
exit(-1);
}
for (i = 0; i < NAUTH; i++) {
auth_type_flag = 1;
username)) == -1) {
gettext("Could not set username - %s\n"),
continue;
}
enc_password)) == -1) {
gettext("Could not set password - %s\n"),
continue;
}
if (!ndmp_door_status() &&
(ndmp_service_refresh()) != 0) {
gettext("Could not refesh ndmpd service "
"properties\n"));
}
}
}
if (!auth_type_flag)
return (0);
}
static int
{
char *auth_type;
int c, i, auth_type_flag = 0;
/* disable <-a auth-type> */
if (argc != 3) {
}
switch (c) {
case 'a':
break;
case ':':
"requires an operand\n"), optopt);
break;
case '?':
"option: -%c\n"), optopt);
}
}
for (i = 0; i < NAUTH; i++) {
auth_type_flag = 1;
"")) == -1) {
gettext("Could not clear username - %s\n"),
continue;
}
"")) == -1) {
gettext("Could not clear password - %s\n"),
continue;
}
if (!ndmp_door_status() &&
(ndmp_service_refresh()) != 0) {
"refesh ndmpd service properties\n"));
}
}
}
if (!auth_type_flag)
return (0);
}
int
{
int ret;
int i;
char *cmdname;
(void) textdomain(TEXT_DOMAIN);
opterr = 0;
/* Make sure the user has specified some command. */
if (argc < 2) {
}
/*
* Special case '-?'
*/
/*
* Run the appropriate sub-command.
*/
for (i = 0; i < NCOMMAND; i++) {
current_command = &command_table[i];
break;
}
}
if (i == NCOMMAND) {
"command '%s'\n"), cmdname);
}
return (ret);
}