Line data Source code
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/cmdline.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 0 : void torture_shell(struct torture_context *tctx)
102 : {
103 0 : char *cline;
104 0 : int argc;
105 0 : const char **argv;
106 0 : int ret;
107 0 : 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 0 : cli_credentials_set_password(samba_cmdline_get_creds(),
114 : "", CRED_GUESS_ENV);
115 :
116 0 : while (1) {
117 0 : cline = smb_readline("torture> ", NULL, NULL);
118 :
119 0 : if (cline == NULL)
120 0 : return;
121 :
122 : #ifdef HAVE_ADD_HISTORY
123 : add_history(cline);
124 : #endif
125 :
126 0 : ret = poptParseArgvString(cline, &argc, &argv);
127 0 : if (ret != 0) {
128 0 : fprintf(stderr, "Error parsing line\n");
129 0 : continue;
130 : }
131 :
132 0 : for (i = 0; i < ARRAY_SIZE(commands); i++) {
133 0 : if (match_command(argv[0], &commands[i])) {
134 0 : argc--;
135 0 : argv++;
136 0 : commands[i].handler(&commands[i],
137 : tctx, argc, argv);
138 0 : break;
139 : }
140 : }
141 :
142 0 : free(cline);
143 : }
144 : }
145 :
146 0 : static void shell_quit(const struct shell_command * command,
147 : struct torture_context *tctx, int argc, const char **argv)
148 : {
149 0 : exit(0);
150 : }
151 :
152 0 : static void shell_help(const struct shell_command * command,
153 : struct torture_context *tctx, int argc, const char **argv)
154 : {
155 0 : int i;
156 :
157 0 : if (argc == 1) {
158 0 : for (i = 0; i < ARRAY_SIZE(commands); i++) {
159 0 : if (match_command(argv[0], &commands[i])) {
160 0 : shell_usage(&commands[i]);
161 0 : return;
162 : }
163 : }
164 : } else {
165 0 : fprintf(stdout, "Available commands:\n");
166 0 : for (i = 0; i < ARRAY_SIZE(commands); i++) {
167 0 : fprintf(stdout, "\t%s - %s\n",
168 0 : commands[i].name, commands[i].help);
169 : }
170 : }
171 : }
172 :
173 0 : static void shell_set(const struct shell_command *command,
174 : struct torture_context *tctx, int argc, const char **argv)
175 : {
176 0 : switch (argc) {
177 0 : case 0:
178 0 : lpcfg_dump(tctx->lp_ctx, stdout,
179 : false /* show_defaults */,
180 : 0 /* skip services */);
181 0 : break;
182 :
183 0 : 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 0 : lpcfg_set_cmdline(tctx->lp_ctx, argv[0], argv[1]);
190 0 : break;
191 :
192 0 : default:
193 0 : shell_usage(command);
194 : }
195 0 : }
196 :
197 0 : static void shell_run(const struct shell_command * command,
198 : struct torture_context *tctx, int argc, const char **argv)
199 : {
200 0 : if (argc != 1) {
201 0 : shell_usage(command);
202 0 : return;
203 : }
204 :
205 0 : torture_run_named_tests(tctx, argv[0], NULL /* restricted */);
206 : }
207 :
208 0 : static void shell_list(const struct shell_command * command,
209 : struct torture_context *tctx, int argc, const char **argv)
210 : {
211 0 : if (argc != 0) {
212 0 : shell_usage(command);
213 0 : return;
214 : }
215 :
216 0 : torture_print_testsuites(true);
217 : }
218 :
219 0 : static void shell_auth(const struct shell_command * command,
220 : struct torture_context *tctx, int argc, const char **argv)
221 : {
222 :
223 0 : if (argc == 0) {
224 0 : const char * username;
225 0 : const char * domain;
226 0 : const char * realm;
227 0 : const char * password;
228 0 : const char * principal;
229 :
230 0 : username = cli_credentials_get_username(
231 : samba_cmdline_get_creds());
232 0 : principal = cli_credentials_get_principal(
233 : samba_cmdline_get_creds(), tctx);
234 0 : domain = cli_credentials_get_domain(samba_cmdline_get_creds());
235 0 : realm = cli_credentials_get_realm(samba_cmdline_get_creds());
236 0 : password = cli_credentials_get_password(
237 : samba_cmdline_get_creds());
238 :
239 0 : printf("Username: %s\n", username ? username : "");
240 0 : printf("User Principal: %s\n", principal ? principal : "");
241 0 : printf("Domain: %s\n", domain ? domain : "");
242 0 : printf("Realm: %s\n", realm ? realm : "");
243 0 : printf("Password: %s\n", password ? password : "");
244 0 : } else if (argc == 2) {
245 0 : bool result;
246 :
247 0 : if (!strcmp(argv[0], "username")) {
248 0 : result = cli_credentials_set_username(
249 : samba_cmdline_get_creds(),
250 0 : argv[1], CRED_SPECIFIED);
251 0 : } else if (!strcmp(argv[0], "principal")) {
252 0 : result = cli_credentials_set_principal(
253 : samba_cmdline_get_creds(),
254 0 : argv[1], CRED_SPECIFIED);
255 0 : } else if (!strcmp(argv[0], "domain")) {
256 0 : result = cli_credentials_set_domain(
257 : samba_cmdline_get_creds(),
258 0 : argv[1], CRED_SPECIFIED);
259 0 : } else if (!strcmp(argv[0], "realm")) {
260 0 : result = cli_credentials_set_realm(
261 : samba_cmdline_get_creds(),
262 0 : argv[1], CRED_SPECIFIED);
263 0 : } else if (!strcmp(argv[0], "password")) {
264 0 : result = cli_credentials_set_password(
265 : samba_cmdline_get_creds(),
266 0 : argv[1], CRED_SPECIFIED);
267 : } else {
268 0 : shell_usage(command);
269 0 : return;
270 : }
271 :
272 0 : if (!result) {
273 0 : printf("failed to set %s\n", argv[0]);
274 : }
275 : } else {
276 0 : shell_usage(command);
277 : }
278 :
279 : }
280 :
281 0 : static void shell_target(const struct shell_command *command,
282 : struct torture_context *tctx, int argc, const char **argv)
283 : {
284 0 : if (argc == 0) {
285 0 : const char * host;
286 0 : const char * share;
287 0 : const char * binding;
288 :
289 0 : host = torture_setting_string(tctx, "host", NULL);
290 0 : share = torture_setting_string(tctx, "share", NULL);
291 0 : binding = torture_setting_string(tctx, "binding", NULL);
292 :
293 0 : printf("Target host: %s\n", host ? host : "");
294 0 : printf("Target share: %s\n", share ? share : "");
295 0 : printf("Target binding: %s\n", binding ? binding : "");
296 0 : } else if (argc == 1) {
297 0 : torture_parse_target(tctx, tctx->lp_ctx, argv[0]);
298 : } else {
299 0 : shell_usage(command);
300 : }
301 0 : }
302 :
303 0 : static void shell_usage(const struct shell_command * command)
304 : {
305 0 : if (command->usage) {
306 0 : fprintf(stderr, "Usage: %s %s\n",
307 0 : command->name, command->usage);
308 : } else {
309 0 : fprintf(stderr, "Usage: %s\n",
310 0 : command->name);
311 : }
312 0 : }
313 :
314 0 : static bool match_command(const char * name,
315 : const struct shell_command * command)
316 : {
317 0 : if (!strcmp(name, command->name)) {
318 0 : return true;
319 : }
320 :
321 0 : if (name[0] == command->name[0] && name[1] == '\0') {
322 0 : return true;
323 : }
324 :
325 0 : return false;
326 : }
|