From 4f5791ebd03eaec1c7da0865a383175b05102712 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 5 May 2024 19:47:29 +0200 Subject: Adding upstream version 2:4.17.12+dfsg. Signed-off-by: Daniel Baumann --- source4/torture/shell.c | 326 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 326 insertions(+) create mode 100644 source4/torture/shell.c (limited to 'source4/torture/shell.c') diff --git a/source4/torture/shell.c b/source4/torture/shell.c new file mode 100644 index 0000000..d34267d --- /dev/null +++ b/source4/torture/shell.c @@ -0,0 +1,326 @@ +/* + Unix SMB/CIFS implementation. + SMB torture tester + Copyright (C) Andrew Tridgell 1997-2003 + Copyright (C) Jelmer Vernooij 2006-2008 + Copyright (C) James Peach 2010 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "includes.h" +#include "system/readline.h" +#include "../libcli/smbreadline/smbreadline.h" +#include "lib/cmdline/cmdline.h" +#include "auth/credentials/credentials.h" +#include "torture/smbtorture.h" +#include "param/param.h" + +struct shell_command; + +typedef void (*shell_function)(const struct shell_command *, + struct torture_context *, int, const char **); + +static void shell_quit(const struct shell_command *, + struct torture_context *, int, const char **); +static void shell_help(const struct shell_command *, + struct torture_context *, int, const char **); +static void shell_set(const struct shell_command *, + struct torture_context *, int, const char **); +static void shell_run(const struct shell_command *, + struct torture_context *, int, const char **); +static void shell_list(const struct shell_command *, + struct torture_context *, int, const char **); +static void shell_auth(const struct shell_command *, + struct torture_context *, int, const char **); +static void shell_target(const struct shell_command *, + struct torture_context *, int, const char **); + +static void shell_usage(const struct shell_command *); +static bool match_command(const char *, const struct shell_command *); + +struct shell_command +{ + shell_function handler; + const char * name; + const char * usage; + const char * help; +} shell_command; + +static const struct shell_command commands[] = +{ + { + shell_auth, "auth", + "[[username | principal | domain | realm | password] STRING]", + "set authentication parameters" + }, + + { + shell_help, "help", NULL, + "print this help message" + }, + + { + shell_list, "list", NULL, + "list the available tests" + }, + + { + shell_quit, "quit", NULL, + "exit smbtorture" + }, + + { + shell_run, "run", "[TESTNAME]", + "run the specified test" + }, + + { + shell_set, "set", "[NAME VALUE]", + "print or set test configuration parameters" + }, + + { + shell_target, "target", "[TARGET]", + "print or set the test target" + } + +}; + +void torture_shell(struct torture_context *tctx) +{ + char *cline; + int argc; + const char **argv; + int ret; + int i; + + /* If we don't have a specified password, specify it as empty. This + * stops the credentials system prompting when we use the "auth" + * command to display the current auth parameters. + */ + cli_credentials_set_password(samba_cmdline_get_creds(), + "", CRED_GUESS_ENV); + + while (1) { + cline = smb_readline("torture> ", NULL, NULL); + + if (cline == NULL) + return; + +#ifdef HAVE_ADD_HISTORY + add_history(cline); +#endif + + ret = poptParseArgvString(cline, &argc, &argv); + if (ret != 0) { + fprintf(stderr, "Error parsing line\n"); + continue; + } + + for (i = 0; i < ARRAY_SIZE(commands); i++) { + if (match_command(argv[0], &commands[i])) { + argc--; + argv++; + commands[i].handler(&commands[i], + tctx, argc, argv); + break; + } + } + + free(cline); + } +} + +static void shell_quit(const struct shell_command * command, + struct torture_context *tctx, int argc, const char **argv) +{ + exit(0); +} + +static void shell_help(const struct shell_command * command, + struct torture_context *tctx, int argc, const char **argv) +{ + int i; + + if (argc == 1) { + for (i = 0; i < ARRAY_SIZE(commands); i++) { + if (match_command(argv[0], &commands[i])) { + shell_usage(&commands[i]); + return; + } + } + } else { + fprintf(stdout, "Available commands:\n"); + for (i = 0; i < ARRAY_SIZE(commands); i++) { + fprintf(stdout, "\t%s - %s\n", + commands[i].name, commands[i].help); + } + } +} + +static void shell_set(const struct shell_command *command, + struct torture_context *tctx, int argc, const char **argv) +{ + switch (argc) { + case 0: + lpcfg_dump(tctx->lp_ctx, stdout, + false /* show_defaults */, + 0 /* skip services */); + break; + + case 2: + /* We want to allow users to set any config option. Top level + * options will get checked against their static definition, but + * parametric options can't be checked and will just get stashed + * as they are provided. + */ + lpcfg_set_cmdline(tctx->lp_ctx, argv[0], argv[1]); + break; + + default: + shell_usage(command); + } +} + +static void shell_run(const struct shell_command * command, + struct torture_context *tctx, int argc, const char **argv) +{ + if (argc != 1) { + shell_usage(command); + return; + } + + torture_run_named_tests(tctx, argv[0], NULL /* restricted */); +} + +static void shell_list(const struct shell_command * command, + struct torture_context *tctx, int argc, const char **argv) +{ + if (argc != 0) { + shell_usage(command); + return; + } + + torture_print_testsuites(true); +} + +static void shell_auth(const struct shell_command * command, + struct torture_context *tctx, int argc, const char **argv) +{ + + if (argc == 0) { + const char * username; + const char * domain; + const char * realm; + const char * password; + const char * principal; + + username = cli_credentials_get_username( + samba_cmdline_get_creds()); + principal = cli_credentials_get_principal( + samba_cmdline_get_creds(), tctx); + domain = cli_credentials_get_domain(samba_cmdline_get_creds()); + realm = cli_credentials_get_realm(samba_cmdline_get_creds()); + password = cli_credentials_get_password( + samba_cmdline_get_creds()); + + printf("Username: %s\n", username ? username : ""); + printf("User Principal: %s\n", principal ? principal : ""); + printf("Domain: %s\n", domain ? domain : ""); + printf("Realm: %s\n", realm ? realm : ""); + printf("Password: %s\n", password ? password : ""); + } else if (argc == 2) { + bool result; + + if (!strcmp(argv[0], "username")) { + result = cli_credentials_set_username( + samba_cmdline_get_creds(), + argv[1], CRED_SPECIFIED); + } else if (!strcmp(argv[0], "principal")) { + result = cli_credentials_set_principal( + samba_cmdline_get_creds(), + argv[1], CRED_SPECIFIED); + } else if (!strcmp(argv[0], "domain")) { + result = cli_credentials_set_domain( + samba_cmdline_get_creds(), + argv[1], CRED_SPECIFIED); + } else if (!strcmp(argv[0], "realm")) { + result = cli_credentials_set_realm( + samba_cmdline_get_creds(), + argv[1], CRED_SPECIFIED); + } else if (!strcmp(argv[0], "password")) { + result = cli_credentials_set_password( + samba_cmdline_get_creds(), + argv[1], CRED_SPECIFIED); + } else { + shell_usage(command); + return; + } + + if (!result) { + printf("failed to set %s\n", argv[0]); + } + } else { + shell_usage(command); + } + +} + +static void shell_target(const struct shell_command *command, + struct torture_context *tctx, int argc, const char **argv) +{ + if (argc == 0) { + const char * host; + const char * share; + const char * binding; + + host = torture_setting_string(tctx, "host", NULL); + share = torture_setting_string(tctx, "share", NULL); + binding = torture_setting_string(tctx, "binding", NULL); + + printf("Target host: %s\n", host ? host : ""); + printf("Target share: %s\n", share ? share : ""); + printf("Target binding: %s\n", binding ? binding : ""); + } else if (argc == 1) { + torture_parse_target(tctx, tctx->lp_ctx, argv[0]); + } else { + shell_usage(command); + } +} + +static void shell_usage(const struct shell_command * command) +{ + if (command->usage) { + fprintf(stderr, "Usage: %s %s\n", + command->name, command->usage); + } else { + fprintf(stderr, "Usage: %s\n", + command->name); + } +} + +static bool match_command(const char * name, + const struct shell_command * command) +{ + if (!strcmp(name, command->name)) { + return true; + } + + if (name[0] == command->name[0] && name[1] == '\0') { + return true; + } + + return false; +} -- cgit v1.2.3