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