summaryrefslogtreecommitdiffstats
path: root/source4/torture/shell.c
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 17:20:00 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 17:20:00 +0000
commit8daa83a594a2e98f39d764422bfbdbc62c9efd44 (patch)
tree4099e8021376c7d8c05bdf8503093d80e9c7bad0 /source4/torture/shell.c
parentInitial commit. (diff)
downloadsamba-8daa83a594a2e98f39d764422bfbdbc62c9efd44.tar.xz
samba-8daa83a594a2e98f39d764422bfbdbc62c9efd44.zip
Adding upstream version 2:4.20.0+dfsg.upstream/2%4.20.0+dfsg
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'source4/torture/shell.c')
-rw-r--r--source4/torture/shell.c326
1 files changed, 326 insertions, 0 deletions
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 <http://www.gnu.org/licenses/>.
+*/
+
+#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;
+}