r23784: use the GPLv3 boilerplate as recommended by the FSF and the license text
[tprouty/samba.git] / source / torture / rpctorture.c
1 /* 
2    Unix SMB/CIFS implementation.
3    SMB client
4    Copyright (C) Andrew Tridgell 1994-1998
5    
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 3 of the License, or
9    (at your option) any later version.
10    
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15    
16    You should have received a copy of the GNU General Public License
17    along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "includes.h"
21
22 #ifndef REGISTER
23 #define REGISTER 0
24 #endif
25
26 extern pstring global_myname;
27
28 extern pstring user_socket_options;
29
30
31 extern file_info def_finfo;
32
33 #define CNV_LANG(s) dos2unix_format(s,False)
34 #define CNV_INPUT(s) unix2dos_format(s,True)
35
36 static struct cli_state smbcli;
37 struct cli_state *smb_cli = &smbcli;
38
39 FILE *out_hnd;
40
41 static pstring password; /* local copy only, if one is entered */
42
43 /****************************************************************************
44 initialise smb client structure
45 ****************************************************************************/
46 void rpcclient_init(void)
47 {
48         memset((char *)smb_cli, '\0', sizeof(smb_cli));
49         cli_initialise(smb_cli);
50         smb_cli->capabilities |= CAP_NT_SMBS;
51 }
52
53 /****************************************************************************
54 make smb client connection
55 ****************************************************************************/
56 static BOOL rpcclient_connect(struct client_info *info)
57 {
58         struct nmb_name calling;
59         struct nmb_name called;
60
61         make_nmb_name(&called , dns_to_netbios_name(info->dest_host ), info->name_type);
62         make_nmb_name(&calling, dns_to_netbios_name(info->myhostname), 0x0);
63
64         if (!cli_establish_connection(smb_cli, 
65                                   info->dest_host, &info->dest_ip, 
66                                   &calling, &called,
67                                   info->share, info->svc_type,
68                                   False, True))
69         {
70                 DEBUG(0,("rpcclient_connect: connection failed\n"));
71                 cli_shutdown(smb_cli);
72                 return False;
73         }
74
75         return True;
76 }
77
78 /****************************************************************************
79 stop the smb connection(s?)
80 ****************************************************************************/
81 static void rpcclient_stop(void)
82 {
83         cli_shutdown(smb_cli);
84 }
85
86 /****************************************************************************
87   log in as an nt user, log out again. 
88 ****************************************************************************/
89 void run_enums_test(int num_ops, struct client_info *cli_info, struct cli_state *cli)
90 {
91         pstring cmd;
92         int i;
93
94         /* establish connections.  nothing to stop these being re-established. */
95         rpcclient_connect(cli_info);
96
97         DEBUG(5,("rpcclient_connect: cli->fd:%d\n", cli->fd));
98         if (cli->fd <= 0)
99         {
100                 fprintf(out_hnd, "warning: connection could not be established to %s<%02x>\n",
101                                  cli_info->dest_host, cli_info->name_type);
102                 return;
103         }
104         
105         for (i = 0; i < num_ops; i++)
106         {
107                 set_first_token("");
108                 cmd_srv_enum_sess(cli_info);
109                 set_first_token("");
110                 cmd_srv_enum_shares(cli_info);
111                 set_first_token("");
112                 cmd_srv_enum_files(cli_info);
113
114                 if (password[0] != 0)
115                 {
116                         slprintf(cmd, sizeof(cmd)-1, "1");
117                         set_first_token(cmd);
118                 }
119                 else
120                 {
121                         set_first_token("");
122                 }
123                 cmd_srv_enum_conn(cli_info);
124         }
125
126         rpcclient_stop();
127
128 }
129
130 /****************************************************************************
131   log in as an nt user, log out again. 
132 ****************************************************************************/
133 void run_ntlogin_test(int num_ops, struct client_info *cli_info, struct cli_state *cli)
134 {
135         pstring cmd;
136         int i;
137
138         /* establish connections.  nothing to stop these being re-established. */
139         rpcclient_connect(cli_info);
140
141         DEBUG(5,("rpcclient_connect: cli->fd:%d\n", cli->fd));
142         if (cli->fd <= 0)
143         {
144                 fprintf(out_hnd, "warning: connection could not be established to %s<%02x>\n",
145                                  cli_info->dest_host, cli_info->name_type);
146                 return;
147         }
148         
149         for (i = 0; i < num_ops; i++)
150         {
151                 slprintf(cmd, sizeof(cmd)-1, "%s %s", cli->user_name, password);
152                 set_first_token(cmd);
153
154                 cmd_netlogon_login_test(cli_info);
155         }
156
157         rpcclient_stop();
158
159 }
160
161 /****************************************************************************
162   runs n simultaneous functions.
163 ****************************************************************************/
164 static void create_procs(int nprocs, int numops, 
165                 struct client_info *cli_info, struct cli_state *cli,
166                 void (*fn)(int, struct client_info *, struct cli_state *))
167 {
168         int i, status;
169
170         for (i=0;i<nprocs;i++)
171         {
172                 if (fork() == 0)
173                 {
174                         pid_t mypid = getpid();
175                         sys_srandom(mypid ^ time(NULL));
176                         fn(numops, cli_info, cli);
177                         fflush(out_hnd);
178                         _exit(0);
179                 }
180         }
181
182         for (i=0;i<nprocs;i++)
183         {
184                 waitpid(0, &status, 0);
185         }
186 }
187 /****************************************************************************
188 usage on the program - OUT OF DATE!
189 ****************************************************************************/
190 static void usage(char *pname)
191 {
192   fprintf(out_hnd, "Usage: %s service <password> [-d debuglevel] [-l log] ",
193            pname);
194
195   fprintf(out_hnd, "\nVersion %s\n",SAMBA_VERSION_STRING);
196   fprintf(out_hnd, "\t-d debuglevel         set the debuglevel\n");
197   fprintf(out_hnd, "\t-l log basename.      Basename for log/debug files\n");
198   fprintf(out_hnd, "\t-n netbios name.      Use this name as my netbios name\n");
199   fprintf(out_hnd, "\t-m max protocol       set the max protocol level\n");
200   fprintf(out_hnd, "\t-I dest IP            use this IP to connect to\n");
201   fprintf(out_hnd, "\t-E                    write messages to stderr instead of stdout\n");
202   fprintf(out_hnd, "\t-U username           set the network username\n");
203   fprintf(out_hnd, "\t-W workgroup          set the workgroup name\n");
204   fprintf(out_hnd, "\t-t terminal code      terminal i/o code {sjis|euc|jis7|jis8|junet|hex}\n");
205   fprintf(out_hnd, "\n");
206 }
207
208 enum client_action
209 {
210         CLIENT_NONE,
211         CLIENT_IPC,
212         CLIENT_SVC
213 };
214
215 /****************************************************************************
216   main program
217 ****************************************************************************/
218  int main(int argc,char *argv[])
219 {
220         char *pname = argv[0];
221         int opt;
222         extern char *optarg;
223         extern int optind;
224         pstring term_code;
225         BOOL got_pass = False;
226         char *cmd_str="";
227         enum client_action cli_action = CLIENT_NONE;
228         int nprocs = 1;
229         int numops = 100;
230         pstring logfile;
231
232         struct client_info cli_info;
233
234         out_hnd = stdout;
235
236         rpcclient_init();
237
238 #ifdef KANJI
239         pstrcpy(term_code, KANJI);
240 #else /* KANJI */
241         *term_code = 0;
242 #endif /* KANJI */
243
244         if (!lp_load(dyn_CONFIGFILE,True, False, False, True))
245         {
246                 fprintf(stderr, "Can't load %s - run testparm to debug it\n", dyn_CONFIGFILE);
247         }
248
249         DEBUGLEVEL = 0;
250
251         cli_info.put_total_size = 0;
252         cli_info.put_total_time_ms = 0;
253         cli_info.get_total_size = 0;
254         cli_info.get_total_time_ms = 0;
255
256         cli_info.dir_total = 0;
257         cli_info.newer_than = 0;
258         cli_info.archive_level = 0;
259         cli_info.print_mode = 1;
260
261         cli_info.translation = False;
262         cli_info.recurse_dir = False;
263         cli_info.lowercase = False;
264         cli_info.prompt = True;
265         cli_info.abort_mget = True;
266
267         cli_info.dest_ip.s_addr = 0;
268         cli_info.name_type = 0x20;
269
270         pstrcpy(cli_info.cur_dir , "\\");
271         pstrcpy(cli_info.file_sel, "");
272         pstrcpy(cli_info.base_dir, "");
273         pstrcpy(smb_cli->domain, "");
274         pstrcpy(smb_cli->user_name, "");
275         pstrcpy(cli_info.myhostname, "");
276         pstrcpy(cli_info.dest_host, "");
277
278         pstrcpy(cli_info.svc_type, "A:");
279         pstrcpy(cli_info.share, "");
280         pstrcpy(cli_info.service, "");
281
282         ZERO_STRUCT(cli_info.dom.level3_sid);
283         pstrcpy(cli_info.dom.level3_dom, "");
284         ZERO_STRUCT(cli_info.dom.level5_sid);
285         pstrcpy(cli_info.dom.level5_dom, "");
286
287         {
288                 int i;
289                 for (i=0; i<PI_MAX_PIPES; i++)
290                         smb_cli->pipes[i].fnum   = 0xffff;
291         }
292
293         setup_logging(pname, True);
294
295         if (!get_myname(global_myname))
296         {
297                 fprintf(stderr, "Failed to get my hostname.\n");
298         }
299
300         password[0] = 0;
301
302         if (argc < 2)
303         {
304                 usage(pname);
305                 exit(1);
306         }
307
308         if (*argv[1] != '-')
309         {
310                 pstrcpy(cli_info.service, argv[1]);  
311                 /* Convert any '/' characters in the service name to '\' characters */
312                 string_replace( cli_info.service, '/','\\');
313                 argc--;
314                 argv++;
315
316                 DEBUG(1,("service: %s\n", cli_info.service));
317
318                 if (count_chars(cli_info.service,'\\') < 3)
319                 {
320                         usage(pname);
321                         printf("\n%s: Not enough '\\' characters in service\n", cli_info.service);
322                         exit(1);
323                 }
324
325                 /*
326                 if (count_chars(cli_info.service,'\\') > 3)
327                 {
328                         usage(pname);
329                         printf("\n%s: Too many '\\' characters in service\n", cli_info.service);
330                         exit(1);
331                 }
332                 */
333
334                 if (argc > 1 && (*argv[1] != '-'))
335                 {
336                         got_pass = True;
337                         pstrcpy(password,argv[1]);  
338                         memset(argv[1],'X',strlen(argv[1]));
339                         argc--;
340                         argv++;
341                 }
342
343                 cli_action = CLIENT_SVC;
344         }
345
346         while ((opt = getopt(argc, argv,"s:O:M:S:i:N:o:n:d:l:hI:EB:U:L:t:m:W:T:D:c:")) != EOF)
347         {
348                 switch (opt)
349                 {
350                         case 'm':
351                         {
352                                 /* FIXME ... max_protocol seems to be funny here */
353
354                                 int max_protocol = 0;
355                                 max_protocol = interpret_protocol(optarg,max_protocol);
356                                 fprintf(stderr, "max protocol not currently supported\n");
357                                 break;
358                         }
359
360                         case 'O':
361                         {
362                                 pstrcpy(user_socket_options,optarg);
363                                 break;  
364                         }
365
366                         case 'S':
367                         {
368                                 pstrcpy(cli_info.dest_host,optarg);
369                                 strupper_m(cli_info.dest_host);
370                                 cli_action = CLIENT_IPC;
371                                 break;
372                         }
373
374                         case 'i':
375                         {
376                                 pstrcpy(scope, optarg);
377                                 break;
378                         }
379
380                         case 'U':
381                         {
382                                 char *lp;
383                                 pstrcpy(smb_cli->user_name,optarg);
384                                 if ((lp=strchr_m(smb_cli->user_name,'%')))
385                                 {
386                                         *lp = 0;
387                                         pstrcpy(password,lp+1);
388                                         got_pass = True;
389                                         memset(strchr_m(optarg,'%')+1,'X',strlen(password));
390                                 }
391                                 break;
392                         }
393
394                         case 'W':
395                         {
396                                 pstrcpy(smb_cli->domain,optarg);
397                                 break;
398                         }
399
400                         case 'E':
401                         {
402                                 dbf = x_stderr;
403                                 break;
404                         }
405
406                         case 'I':
407                         {
408                                 cli_info.dest_ip = *interpret_addr2(optarg);
409                                 if (is_zero_ip(cli_info.dest_ip))
410                                 {
411                                         exit(1);
412                                 }
413                                 break;
414                         }
415
416                         case 'N':
417                         {
418                                 nprocs = atoi(optarg);
419                                 break;
420                         }
421
422                         case 'o':
423                         {
424                                 numops = atoi(optarg);
425                                 break;
426                         }
427
428                         case 'n':
429                         {
430                                 fstrcpy(global_myname, optarg);
431                                 break;
432                         }
433
434                         case 'd':
435                         {
436                                 if (*optarg == 'A')
437                                         DEBUGLEVEL = 10000;
438                                 else
439                                         DEBUGLEVEL = atoi(optarg);
440                                 break;
441                         }
442
443                         case 'l':
444                         {
445                                 slprintf(logfile, sizeof(logfile)-1,
446                                          "%s.client",optarg);
447                                 lp_set_logfile(logfile);
448                                 break;
449                         }
450
451                         case 'c':
452                         {
453                                 cmd_str = optarg;
454                                 got_pass = True;
455                                 break;
456                         }
457
458                         case 'h':
459                         {
460                                 usage(pname);
461                                 exit(0);
462                                 break;
463                         }
464
465                         case 's':
466                         {
467                                 pstrcpy(dyn_CONFIGFILE, optarg);
468                                 break;
469                         }
470
471                         case 't':
472                         {
473                                 pstrcpy(term_code, optarg);
474                                 break;
475                         }
476
477                         default:
478                         {
479                                 usage(pname);
480                                 exit(1);
481                                 break;
482                         }
483                 }
484         }
485
486         if (cli_action == CLIENT_NONE)
487         {
488                 usage(pname);
489                 exit(1);
490         }
491
492         strupper_m(global_myname);
493         fstrcpy(cli_info.myhostname, global_myname);
494
495         DEBUG(3,("%s client started (version %s)\n",current_timestring(False),SAMBA_VERSION_STRING));
496
497         if (*smb_cli->domain == 0)
498         {
499                 pstrcpy(smb_cli->domain,lp_workgroup());
500         }
501         strupper_m(smb_cli->domain);
502
503         load_interfaces();
504
505         if (cli_action == CLIENT_IPC)
506         {
507                 pstrcpy(cli_info.share, "IPC$");
508                 pstrcpy(cli_info.svc_type, "IPC");
509         }
510
511         fstrcpy(cli_info.mach_acct, cli_info.myhostname);
512         strupper_m(cli_info.mach_acct);
513         fstrcat(cli_info.mach_acct, "$");
514
515         /* set the password cache info */
516         if (got_pass)
517         {
518                 if (password[0] == 0)
519                 {
520                         pwd_set_nullpwd(&(smb_cli->pwd));
521                 }
522                 else
523                 {
524                         pwd_make_lm_nt_16(&(smb_cli->pwd), password); /* generate 16 byte hashes */
525                 }
526         }
527         else 
528         {
529                 char *pwd = getpass("Enter Password:");
530                 safe_strcpy(password, pwd, sizeof(password));
531                 pwd_make_lm_nt_16(&(smb_cli->pwd), password); /* generate 16 byte hashes */
532         }
533
534         create_procs(nprocs, numops, &cli_info, smb_cli, run_enums_test);
535
536         if (password[0] != 0)
537         {
538                 create_procs(nprocs, numops, &cli_info, smb_cli, run_ntlogin_test);
539         }
540
541         fflush(out_hnd);
542
543         return(0);
544 }