lib:util: Fix size types in debug.c
[vlendec/samba-autobuild/.git] / source4 / torture / shell.c
1 /*
2    Unix SMB/CIFS implementation.
3    SMB torture tester
4    Copyright (C) Andrew Tridgell 1997-2003
5    Copyright (C) Jelmer Vernooij 2006-2008
6    Copyright (C) James Peach 2010
7
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 of the License, or
11    (at your option) any later version.
12
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 #include "includes.h"
23 #include "system/readline.h"
24 #include "../libcli/smbreadline/smbreadline.h"
25 #include "lib/cmdline/popt_common.h"
26 #include "auth/credentials/credentials.h"
27 #include "torture/smbtorture.h"
28 #include "param/param.h"
29
30 struct shell_command;
31
32 typedef void (*shell_function)(const struct shell_command *,
33         struct torture_context *, int, const char **);
34
35 static void shell_quit(const struct shell_command *,
36         struct torture_context *, int, const char **);
37 static void shell_help(const struct shell_command *,
38         struct torture_context *, int, const char **);
39 static void shell_set(const struct shell_command *,
40         struct torture_context *, int, const char **);
41 static void shell_run(const struct shell_command *,
42         struct torture_context *, int, const char **);
43 static void shell_list(const struct shell_command *,
44         struct torture_context *, int, const char **);
45 static void shell_auth(const struct shell_command *,
46         struct torture_context *, int, const char **);
47 static void shell_target(const struct shell_command *,
48         struct torture_context *, int, const char **);
49
50 static void shell_usage(const struct shell_command *);
51 static bool match_command(const char *, const struct shell_command *);
52
53 struct shell_command
54 {
55     shell_function  handler;
56     const char *    name;
57     const char *    usage;
58     const char *    help;
59 } shell_command;
60
61 static const struct shell_command commands[] =
62 {
63     {
64         shell_auth, "auth",
65         "[[username | principal | domain | realm | password] STRING]",
66         "set authentication parameters"
67     },
68
69     {
70         shell_help, "help", NULL,
71         "print this help message"
72     },
73
74     {
75         shell_list, "list", NULL,
76         "list the available tests"
77     },
78
79     {
80         shell_quit, "quit", NULL,
81         "exit smbtorture"
82     },
83
84     {
85         shell_run, "run", "[TESTNAME]",
86         "run the specified test"
87     },
88
89     {
90         shell_set, "set", "[NAME VALUE]",
91         "print or set test configuration parameters"
92     },
93
94     {
95         shell_target, "target", "[TARGET]",
96         "print or set the test target"
97     }
98
99 };
100
101 void torture_shell(struct torture_context *tctx)
102 {
103         char *cline;
104         int argc;
105         const char **argv;
106         int ret;
107         int i;
108
109         /* If we don't have a specified password, specify it as empty. This
110          * stops the credentials system prompting when we use the "auth"
111          * command to display the current auth parameters.
112          */
113         cli_credentials_set_password(popt_get_cmdline_credentials(),
114                         "", CRED_GUESS_ENV);
115
116         while (1) {
117                 cline = smb_readline("torture> ", NULL, NULL);
118
119                 if (cline == NULL)
120                         return;
121
122 #if HAVE_ADD_HISTORY
123                 add_history(cline);
124 #endif
125
126                 ret = poptParseArgvString(cline, &argc, &argv);
127                 if (ret != 0) {
128                         fprintf(stderr, "Error parsing line\n");
129                         continue;
130                 }
131
132                 for (i = 0; i < ARRAY_SIZE(commands); i++) {
133                         if (match_command(argv[0], &commands[i])) {
134                                 argc--;
135                                 argv++;
136                                 commands[i].handler(&commands[i],
137                                         tctx, argc, argv);
138                                 break;
139                         }
140                 }
141
142                 free(cline);
143         }
144 }
145
146 static void shell_quit(const struct shell_command * command,
147         struct torture_context *tctx, int argc, const char **argv)
148 {
149     exit(0);
150 }
151
152 static void shell_help(const struct shell_command * command,
153         struct torture_context *tctx, int argc, const char **argv)
154 {
155     int i;
156
157     if (argc == 1) {
158             for (i = 0; i < ARRAY_SIZE(commands); i++) {
159                     if (match_command(argv[0], &commands[i])) {
160                             shell_usage(&commands[i]);
161                             return;
162                     }
163             }
164     } else {
165             fprintf(stdout, "Available commands:\n");
166             for (i = 0; i < ARRAY_SIZE(commands); i++) {
167                     fprintf(stdout, "\t%s - %s\n",
168                             commands[i].name, commands[i].help);
169             }
170     }
171 }
172
173 static void shell_set(const struct shell_command *command,
174         struct torture_context *tctx, int argc, const char **argv)
175 {
176         switch (argc) {
177         case 0:
178             lpcfg_dump(tctx->lp_ctx, stdout,
179                     false /* show_defaults */,
180                     0 /* skip services */);
181             break;
182
183         case 2:
184             /* We want to allow users to set any config option. Top level
185              * options will get checked against their static definition, but
186              * parametric options can't be checked and will just get stashed
187              * as they are provided.
188              */
189             lpcfg_set_cmdline(tctx->lp_ctx, argv[0], argv[1]);
190             break;
191
192         default:
193             shell_usage(command);
194         }
195 }
196
197 static void shell_run(const struct shell_command * command,
198         struct torture_context *tctx, int argc, const char **argv)
199 {
200     if (argc != 1) {
201         shell_usage(command);
202         return;
203     }
204
205     torture_run_named_tests(tctx, argv[0], NULL /* restricted */);
206 }
207
208 static void shell_list(const struct shell_command * command,
209         struct torture_context *tctx, int argc, const char **argv)
210 {
211     if (argc != 0) {
212         shell_usage(command);
213         return;
214     }
215
216     torture_print_testsuites(true);
217 }
218
219 static void shell_auth(const struct shell_command * command,
220         struct torture_context *tctx, int argc, const char **argv)
221 {
222
223     if (argc == 0) {
224             const char * username;
225             const char * domain;
226             const char * realm;
227             const char * password;
228             const char * principal;
229
230             username = cli_credentials_get_username(
231                         popt_get_cmdline_credentials());
232             principal = cli_credentials_get_principal(
233                                 popt_get_cmdline_credentials(), tctx);
234             domain = cli_credentials_get_domain(popt_get_cmdline_credentials());
235             realm = cli_credentials_get_realm(popt_get_cmdline_credentials());
236             password = cli_credentials_get_password(
237                                 popt_get_cmdline_credentials());
238
239             printf("Username: %s\n", username ? username : "");
240             printf("User Principal: %s\n", principal ? principal : "");
241             printf("Domain: %s\n", domain ? domain : "");
242             printf("Realm: %s\n", realm ? realm : "");
243             printf("Password: %s\n", password ? password : "");
244     } else if (argc == 2) {
245             bool result;
246
247             if (!strcmp(argv[0], "username")) {
248                     result = cli_credentials_set_username(
249                         popt_get_cmdline_credentials(),
250                         argv[1], CRED_SPECIFIED);
251             } else if (!strcmp(argv[0], "principal")) {
252                     result = cli_credentials_set_principal(
253                         popt_get_cmdline_credentials(),
254                         argv[1], CRED_SPECIFIED);
255             } else if (!strcmp(argv[0], "domain")) {
256                     result = cli_credentials_set_domain(
257                         popt_get_cmdline_credentials(),
258                         argv[1], CRED_SPECIFIED);
259             } else if (!strcmp(argv[0], "realm")) {
260                     result = cli_credentials_set_realm(
261                         popt_get_cmdline_credentials(),
262                         argv[1], CRED_SPECIFIED);
263             } else if (!strcmp(argv[0], "password")) {
264                     result = cli_credentials_set_password(
265                         popt_get_cmdline_credentials(),
266                         argv[1], CRED_SPECIFIED);
267             } else {
268                     shell_usage(command);
269                     return;
270             }
271
272             if (!result) {
273                     printf("failed to set %s\n", argv[0]);
274             }
275     } else {
276             shell_usage(command);
277     }
278
279 }
280
281 static void shell_target(const struct shell_command *command,
282         struct torture_context *tctx, int argc, const char **argv)
283 {
284         if (argc == 0) {
285                 const char * host;
286                 const char * share;
287                 const char * binding;
288
289                 host = torture_setting_string(tctx, "host", NULL);
290                 share = torture_setting_string(tctx, "share", NULL);
291                 binding = torture_setting_string(tctx, "binding", NULL);
292
293                 printf("Target host: %s\n", host ? host : "");
294                 printf("Target share: %s\n", share ? share : "");
295                 printf("Target binding: %s\n", binding ? binding : "");
296         } else if (argc == 1) {
297                 torture_parse_target(tctx, tctx->lp_ctx, argv[0]);
298         } else {
299                 shell_usage(command);
300         }
301 }
302
303 static void shell_usage(const struct shell_command * command)
304 {
305     if (command->usage) {
306             fprintf(stderr, "Usage: %s %s\n",
307                     command->name, command->usage);
308     } else {
309             fprintf(stderr, "Usage: %s\n",
310                     command->name);
311     }
312 }
313
314 static bool match_command(const char * name,
315         const struct shell_command * command)
316 {
317         if (!strcmp(name, command->name)) {
318                 return true;
319         }
320
321         if (name[0] == command->name[0] && name[1] == '\0') {
322             return true;
323         }
324
325         return false;
326 }