33890749eaea8a2a0411732cc072813318927a85
[kai/samba.git] / source3 / rpcclient / rpcclient.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 debugf;
33 extern pstring scope;
34 extern pstring global_myname;
35
36 extern pstring user_socket_options;
37
38
39 extern int DEBUGLEVEL;
40
41
42 #define CNV_LANG(s) dos2unix_format(s,False)
43 #define CNV_INPUT(s) unix2dos_format(s,True)
44
45 static int process_tok(fstring tok);
46 static void cmd_help(struct client_info *info, int argc, char *argv[]);
47 static void cmd_quit(struct client_info *info, int argc, char *argv[]);
48
49 static struct cli_state smbcli;
50 struct cli_state *smb_cli = &smbcli;
51
52 static struct client_info cli_info;
53
54 static char  **cmd_argv = NULL;
55 static uint32 cmd_argc = 0;
56
57 FILE *out_hnd;
58
59 /****************************************************************************
60 initialise smb client structure
61 ****************************************************************************/
62 void rpcclient_init(void)
63 {
64         bzero(smb_cli, sizeof(smb_cli));
65         cli_initialise(smb_cli);
66         smb_cli->capabilities |= CAP_NT_SMBS | CAP_STATUS32;
67 }
68
69 /****************************************************************************
70 make smb client connection
71 ****************************************************************************/
72 static BOOL rpcclient_connect(struct client_info *info)
73 {
74         struct nmb_name calling;
75         struct nmb_name called;
76
77         make_nmb_name(&called , dns_to_netbios_name(info->dest_host ), info->name_type, scope);
78         make_nmb_name(&calling, dns_to_netbios_name(info->myhostname), 0x0            , scope);
79
80         smb_cli->use_ntlmv2 = lp_client_ntlmv2();
81
82         if (!cli_establish_connection(smb_cli, 
83                                   info->dest_host, &info->dest_ip, 
84                                   &calling, &called,
85                                   info->share, info->svc_type,
86                                   False, True))
87         {
88                 DEBUG(0,("rpcclient_connect: connection failed\n"));
89                 cli_shutdown(smb_cli);
90                 return False;
91         }
92
93         return True;
94 }
95
96 /****************************************************************************
97 stop the smb connection(s?)
98 ****************************************************************************/
99 static void rpcclient_stop(void)
100 {
101         cli_shutdown(smb_cli);
102 }
103
104 #define COMPL_NONE 0
105 #define COMPL_REGKEY 1
106 #define COMPL_SAMUSR 3
107 #define COMPL_SAMGRP 4
108 #define COMPL_SAMALS 5
109 #define COMPL_SVCLST 6
110 #define COMPL_PRTLST 7
111
112 /****************************************************************************
113  This defines the commands supported by this client
114  ****************************************************************************/
115 struct
116 {
117         char *name;
118         void (*fn)(struct client_info*, int, char*[]);
119         char *description;
120         char compl_args[2];
121 }
122 commands[] = 
123 {
124         /*
125          * eventlog
126          */
127
128         {
129                 "eventlog",
130                 cmd_eventlog,
131                 "list the events",
132                 {COMPL_NONE, COMPL_NONE}
133         },
134
135         /*
136          * service control
137          */
138
139         {
140                 "svcenum",
141                 cmd_svc_enum,
142                 "[-i] Lists Services Manager",
143                 {COMPL_NONE, COMPL_NONE}
144         },
145
146         {
147                 "svcinfo",
148                 cmd_svc_info,
149                 "<service> Service Information",
150                 {COMPL_SVCLST, COMPL_NONE}
151         },
152
153         {
154                 "svcstart",
155                 cmd_svc_start,
156                 "<service> [arg 0] [arg 1] ... Start Service",
157                 {COMPL_SVCLST, COMPL_NONE}
158         },
159
160         {
161                 "svcstop",
162                 cmd_svc_stop,
163                 "<service> Stop Service",
164                 {COMPL_SVCLST, COMPL_NONE}
165         },
166
167         /*
168          * scheduler
169          */
170
171         {
172                 "at",
173                 cmd_at,
174                 "Scheduler control (at /? for syntax)",
175                 {COMPL_NONE, COMPL_NONE}
176         },
177
178         /*
179          * registry
180          */
181
182         {
183                 "regenum",
184                 cmd_reg_enum,
185                 "<keyname> Registry Enumeration (keys, values)",
186                 {COMPL_REGKEY, COMPL_NONE}
187         },
188         {
189                 "regdeletekey",
190                 cmd_reg_delete_key,
191                 "<keyname> Registry Key Delete",
192                 {COMPL_REGKEY, COMPL_NONE}
193         },
194         {
195                 "regcreatekey",
196                 cmd_reg_create_key,
197                 "<keyname> [keyclass] Registry Key Create",
198                 {COMPL_REGKEY, COMPL_NONE}
199         },
200         {
201                 "shutdown",
202                 cmd_reg_shutdown,
203                 "[-m message] [-t timeout] [-r or --reboot] [-f or --force-close] Remote Shutdown",
204                 {COMPL_NONE, COMPL_NONE}
205         },
206         {
207                 "regqueryval",
208                 cmd_reg_query_info,
209                 "<valname> Registry Value Query",
210                 {COMPL_REGKEY, COMPL_NONE}
211         },
212         {
213                 "regquerykey",
214                 cmd_reg_query_key,
215                 "<keyname> Registry Key Query",
216                 {COMPL_REGKEY, COMPL_NONE}
217         },
218         {
219                 "regdeleteval",
220                 cmd_reg_delete_val,
221                 "<valname> Registry Value Delete",
222                 {COMPL_REGKEY, COMPL_REGKEY}
223         },
224         {
225                 "regcreateval",
226                 cmd_reg_create_val,
227                 "<valname> <valtype> <value> Registry Key Create",
228                 {COMPL_REGKEY, COMPL_NONE}
229         },
230         {
231                 "reggetsec",
232                 cmd_reg_get_key_sec,
233                 "<keyname> Registry Key Security",
234                 {COMPL_REGKEY, COMPL_NONE}
235         },
236         {
237                 "regtestsec",
238                 cmd_reg_test_key_sec,
239                 "<keyname> Test Registry Key Security",
240                 {COMPL_REGKEY, COMPL_NONE}
241         },
242
243         /*
244          * printer testing
245          */
246
247         {
248                 "spoolenum",
249                 cmd_spoolss_enum_printers,
250                 "Enumerate Printers",
251                 {COMPL_NONE, COMPL_NONE}
252         },
253         {
254                 "spooljobs",
255                 cmd_spoolss_enum_jobs,
256                 "<printer name> Enumerate Printer Jobs",
257                 {COMPL_PRTLST, COMPL_NONE}
258         },
259         {
260                 "spoolopen",
261                 cmd_spoolss_open_printer_ex,
262                 "<printer name> Spool Printer Open Test",
263                 {COMPL_PRTLST, COMPL_NONE}
264         },
265         /*
266          * server
267          */
268         {
269                 "time",
270                 cmd_time,
271                 "Display remote time",
272                 {COMPL_NONE, COMPL_NONE}
273         },
274         {
275                 "brsinfo",
276                 cmd_brs_query_info,
277                 "Browser Query Info",
278                 {COMPL_NONE, COMPL_NONE}
279         },
280         {
281                 "wksinfo",
282                 cmd_wks_query_info,
283                 "Workstation Query Info",
284                 {COMPL_NONE, COMPL_NONE}
285         },
286         {
287                 "srvinfo",
288                 cmd_srv_query_info,
289                 "Server Query Info",
290                 {COMPL_NONE, COMPL_NONE}
291         },
292         {
293                 "srvsessions",
294                 cmd_srv_enum_sess,
295                 "List sessions on a server",
296                 {COMPL_NONE, COMPL_NONE}
297         },
298         {
299                 "srvshares",
300                 cmd_srv_enum_shares,
301                 "List shares on a server",
302                 {COMPL_NONE, COMPL_NONE}
303         },
304         {
305                 "srvtransports",
306                 cmd_srv_enum_tprt,
307                 "List transports on a server",
308                 {COMPL_NONE, COMPL_NONE}
309         },
310         {
311                 "srvconnections",
312                 cmd_srv_enum_conn,
313                 "List connections on a server",
314                 {COMPL_NONE, COMPL_NONE}
315         },
316         {
317                 "srvfiles",
318                 cmd_srv_enum_files,
319                 "List files on a server",
320                 {COMPL_NONE, COMPL_NONE}
321         },
322
323         /*
324          * lsa
325          */
326
327         {
328                 "lsaquery",
329                 cmd_lsa_query_info,
330                 "Query Info Policy (domain member or server)",
331                 {COMPL_NONE, COMPL_NONE}
332         },
333         {
334                 "lsaenumdomains",
335                 cmd_lsa_enum_trust_dom,
336                 "Enumerate Trusted Domains",
337                 {COMPL_NONE, COMPL_NONE}
338         },
339         {
340                 "lookupsids",
341                 cmd_lsa_lookup_sids,
342                 "Resolve names from SIDs",
343                 {COMPL_NONE, COMPL_NONE}
344         },
345         {
346                 "lookupnames",
347                 cmd_lsa_lookup_names,
348                 "Resolve SIDs from names",
349                 {COMPL_NONE, COMPL_NONE}
350         },
351         {
352                 "querysecret",
353                 cmd_lsa_query_secret,
354                 "LSA Query Secret (developer use)",
355                 {COMPL_NONE, COMPL_NONE}
356         },
357
358         /*
359          * netlogon
360          */
361
362         {
363                 "ntlogin",
364                 cmd_netlogon_login_test,
365                 "[username] [password] NT Domain login test",
366                 {COMPL_NONE, COMPL_NONE}
367         },
368         {
369                 "domtrust",
370                 cmd_netlogon_domain_test,
371                 "<domain> NT Inter-Domain test",
372                 {COMPL_NONE, COMPL_NONE}
373         },
374
375         /*
376          * sam
377          */
378
379         {
380                 "lookupdomain",
381                 cmd_sam_lookup_domain,
382                 "Obtain SID for a local domain",
383                 {COMPL_NONE, COMPL_NONE}
384         },
385         {
386                 "enumusers",
387                 cmd_sam_enum_users,
388                 "SAM User Database Query (experimental!)",
389                 {COMPL_NONE, COMPL_NONE}
390         },
391         {
392                 "addgroupmem",
393                 cmd_sam_add_groupmem,
394                 "<group rid> [user] [user] ... SAM Add Domain Group Member",
395                 {COMPL_SAMGRP, COMPL_SAMUSR}
396         },
397
398         {
399                 "addaliasmem",
400                 cmd_sam_add_aliasmem,
401                 "<alias rid> [member sid1] [member sid2] ... SAM Add Domain Alias Member",
402                 {COMPL_SAMALS, COMPL_NONE}
403         },
404         {
405                 "delgroupmem",
406                 cmd_sam_del_groupmem,
407                 "<group rid> [user] [user] ... SAM Delete Domain Group Member",
408                 {COMPL_SAMGRP, COMPL_SAMUSR}
409         },
410         {
411                 "delaliasmem",
412                 cmd_sam_del_aliasmem,
413                 "<alias rid> [member sid1] [member sid2] ... SAM Delete Domain Alias Member",
414                 {COMPL_SAMALS, COMPL_NONE}
415         },
416         {
417                 "creategroup",
418                 cmd_sam_create_dom_group,
419                 "SAM Create Domain Group",
420                 {COMPL_NONE, COMPL_NONE}
421         },
422         {
423                 "createalias",
424                 cmd_sam_create_dom_alias,
425                 "SAM Create Domain Alias",
426                 {COMPL_NONE, COMPL_NONE}
427         },
428         {
429                 "createuser",
430                 cmd_sam_create_dom_user,
431                 "<username> SAM Create Domain User",
432                 {COMPL_NONE, COMPL_NONE}
433         },
434         {
435                 "delgroup",
436                 cmd_sam_delete_dom_group,
437                 "SAM Delete Domain Group",
438                 {COMPL_SAMGRP, COMPL_NONE}
439         },
440         {
441                 "delalias",
442                 cmd_sam_delete_dom_alias,
443                 "SAM Delete Domain Alias",
444                 {COMPL_SAMALS, COMPL_NONE}
445         },
446         {
447                 "ntpass",
448                 cmd_sam_ntchange_pwd,
449                 "NT SAM Password Change",
450                 {COMPL_NONE, COMPL_NONE}
451         },
452         {
453                 "samuserset2",
454                 cmd_sam_set_userinfo2,
455                 "<username> [-s acb_bits] SAM User Set Info 2 (experimental!)",
456                 {COMPL_SAMUSR, COMPL_NONE}
457         },
458         {
459                 "samuserset",
460                 cmd_sam_set_userinfo,
461                 "<username> [-p password] SAM User Set Info (experimental!)",
462                 {COMPL_SAMUSR, COMPL_NONE}
463         },
464         {
465                 "samuser",
466                 cmd_sam_query_user,
467                 "<username> SAM User Query (experimental!)",
468                 {COMPL_SAMUSR, COMPL_NONE}
469         },
470         {
471                 "samgroup",
472                 cmd_sam_query_group,
473                 "<groupname> SAM Group Query (experimental!)",
474                 {COMPL_SAMGRP, COMPL_NONE}
475         },
476         {
477                 "samalias",
478                 cmd_sam_query_alias,
479                 "<aliasname> SAM Alias Query",
480                 {COMPL_SAMALS, COMPL_NONE}
481         },
482         {
483                 "samaliasmem",
484                 cmd_sam_query_aliasmem,
485                 "<aliasname> SAM Alias Members",
486                 {COMPL_SAMALS, COMPL_NONE}
487         },
488         {
489                 "samgroupmem",
490                 cmd_sam_query_groupmem,
491                 "SAM Group Members",
492                 {COMPL_SAMGRP, COMPL_NONE}
493         },
494         {
495                 "samtest",
496                 cmd_sam_test      ,
497                 "SAM User Encrypted RPC test (experimental!)",
498                 {COMPL_NONE, COMPL_NONE}
499         },
500         {
501                 "enumaliases",
502                 cmd_sam_enum_aliases,
503                 "SAM Aliases Database Query (experimental!)",
504                 {COMPL_NONE, COMPL_NONE}
505         },
506         {
507                 "enumdomains",
508                 cmd_sam_enum_domains,
509                 "SAM Domains Database Query (experimental!)",
510                 {COMPL_NONE, COMPL_NONE}
511         },
512         {
513                 "enumgroups",
514                 cmd_sam_enum_groups,
515                 "SAM Group Database Query (experimental!)",
516                 {COMPL_NONE, COMPL_NONE}
517         },
518         {
519                 "dominfo",
520                 cmd_sam_query_dominfo,
521                 "SAM Query Domain Info",
522                 {COMPL_NONE, COMPL_NONE}
523         },
524         {
525                 "dispinfo",
526                 cmd_sam_query_dispinfo,
527                 "SAM Query Display Info",
528                 {COMPL_NONE, COMPL_NONE}
529         },
530         {
531                 "samsync",
532                 cmd_sam_sync,
533                 "SAM Synchronization Test (experimental)",
534                 {COMPL_NONE, COMPL_NONE}
535         },
536
537         /*
538          * bye bye
539          */
540
541         {
542                 "quit",
543                 cmd_quit,
544                 "logoff the server",
545                 {COMPL_NONE, COMPL_NONE}
546         },
547         {
548                 "q",
549                 cmd_quit,
550                 "logoff the server",
551                 {COMPL_NONE, COMPL_NONE}
552         },
553         {
554                 "exit",
555                 cmd_quit,
556                 "logoff the server",
557                 {COMPL_NONE, COMPL_NONE}
558         },
559         {
560                 "bye",
561                 cmd_quit,
562                 "logoff the server",
563                 {COMPL_NONE, COMPL_NONE}
564         },
565
566         /*
567          * eek!
568          */
569
570         {
571                 "help",
572                 cmd_help,
573                 "[command] give help on a command",
574                 {COMPL_NONE, COMPL_NONE}
575         },
576         {
577                 "?",
578                 cmd_help,
579                 "[command] give help on a command",
580                 {COMPL_NONE, COMPL_NONE}
581         },
582
583         /*
584          * shell
585          */
586
587         {
588                 "!",
589                 NULL,
590                 "run a shell command on the local system",
591                 {COMPL_NONE, COMPL_NONE}
592         },
593
594         /*
595          * oop!
596          */
597
598         {
599                 "",
600                 NULL,
601                 NULL,
602                 {COMPL_NONE, COMPL_NONE}
603         }
604 };
605
606
607 /****************************************************************************
608 do a (presumably graceful) quit...
609 ****************************************************************************/
610 static void cmd_quit(struct client_info *info, int argc, char *argv[])
611 {
612         rpcclient_stop();
613 #ifdef MEM_MAN
614         {
615                 extern FILE* dbf;
616                 smb_mem_write_status(dbf);
617                 smb_mem_write_errors(dbf);
618                 smb_mem_write_verbose(dbf);
619                 dbgflush();
620         }
621 #endif
622         exit(0);
623 }
624
625 /****************************************************************************
626 help
627 ****************************************************************************/
628 static void cmd_help(struct client_info *info, int argc, char *argv[])
629 {
630   int i=0,j;
631
632   if (argc > 1)
633     {
634       if ((i = process_tok(argv[1])) >= 0)
635         fprintf(out_hnd, "HELP %s:\n\t%s\n\n",commands[i].name,commands[i].description);                    
636     }
637   else
638     while (commands[i].description)
639       {
640         for (j=0; commands[i].description && (j<5); j++) {
641           fprintf(out_hnd, "%-15s",commands[i].name);
642           i++;
643         }
644         fprintf(out_hnd, "\n");
645       }
646 }
647
648 /*******************************************************************
649   lookup a command string in the list of commands, including 
650   abbreviations
651   ******************************************************************/
652 static int process_tok(char *tok)
653 {
654   int i = 0, matches = 0;
655   int cmd=0;
656   int tok_len = strlen(tok);
657   
658   while (commands[i].fn != NULL)
659     {
660       if (strequal(commands[i].name,tok))
661         {
662           matches = 1;
663           cmd = i;
664           break;
665         }
666       else if (strnequal(commands[i].name, tok, tok_len))
667         {
668           matches++;
669           cmd = i;
670         }
671       i++;
672     }
673   
674   if (matches == 0)
675     return(-1);
676   else if (matches == 1)
677     return(cmd);
678   else
679     return(-2);
680 }
681
682 /****************************************************************************
683   process commands from the client
684 ****************************************************************************/
685 static BOOL do_command(struct client_info *info, char *line)
686 {
687         int i;
688         char *ptr = line;
689         pstring tok;
690
691         /* get the first part of the command */
692         if (!next_token(&ptr,tok,NULL, sizeof(tok)))
693         {
694                 return False;
695         }
696
697         do
698         {
699                 add_chars_to_array(&cmd_argc, &cmd_argv, tok);
700
701         } while (next_token(NULL, tok, NULL, sizeof(tok)));
702
703         if (cmd_argc == 0)
704         {
705                 return False;
706         }
707
708         if ((i = process_tok(cmd_argv[0])) >= 0)
709         {
710                 optind = -1;
711                 commands[i].fn(info, (uint32)cmd_argc, cmd_argv);
712         }
713         else if (i == -2)
714         {
715                 fprintf(out_hnd, "%s: command abbreviation ambiguous\n", CNV_LANG(tok));
716         }
717         else
718         {
719                 fprintf(out_hnd, "%s: command not found\n", CNV_LANG(tok));
720         }
721
722         free_char_array(cmd_argc, cmd_argv);
723         cmd_argc = 0;
724         cmd_argv = NULL;
725
726         return True;
727 }
728
729 #ifndef HAVE_LIBREADLINE
730 /****************************************************************************
731 wait for keyboard activity, swallowing network packets
732 ****************************************************************************/
733 static void wait_keyboard(struct cli_state *cli)
734 {
735         fd_set fds;
736         struct timeval timeout;
737   
738         while (1) {
739                 FD_ZERO(&fds);
740                 FD_SET(cli->fd,&fds);
741                 FD_SET(fileno(stdin),&fds);
742
743                 timeout.tv_sec = 20;
744                 timeout.tv_usec = 0;
745                 sys_select(MAX(cli->fd,fileno(stdin))+1,&fds,&timeout);
746       
747                 if (FD_ISSET(fileno(stdin),&fds))
748                         return;
749
750                 /* We deliberately use receive_smb instead of
751                    client_receive_smb as we want to receive
752                    session keepalives and then drop them here.
753                 */
754                 if (FD_ISSET(cli->fd,&fds))
755                         receive_smb(cli->fd,cli->inbuf,0);
756         }  
757 }
758 #endif
759
760 /****************************************************************************
761   process commands from the client
762 ****************************************************************************/
763 static BOOL process( struct client_info *info, char *cmd_str)
764 {
765         pstring line;
766         char *cmd = cmd_str;
767
768         if (cmd[0] != '\0') while (cmd[0] != '\0')
769         {
770                 char *p;
771
772                 if ((p = strchr(cmd, ';')) == 0)
773                 {
774                         strncpy(line, cmd, 999);
775                         line[1000] = '\0';
776                         cmd += strlen(cmd);
777                 }
778                 else
779                 {
780                         if (p - cmd > 999) p = cmd + 999;
781                         strncpy(line, cmd, p - cmd);
782                         line[p - cmd] = '\0';
783                         cmd = p + 1;
784                 }
785
786                 /* input language code to internal one */
787                 CNV_INPUT (line);
788
789                 if (!do_command(info, line)) continue;
790         }
791         else while (!feof(stdin))
792         {
793 #ifdef HAVE_LIBREADLINE
794                 pstring promptline;
795 #endif
796
797 #ifndef HAVE_LIBREADLINE
798
799                 /* display a prompt */
800                 fprintf(out_hnd, "smb: %s> ", CNV_LANG(info->cur_dir));
801                 fflush(out_hnd);
802
803 #ifdef CLIX
804                 line[0] = wait_keyboard(smb_cli);
805                 /* this might not be such a good idea... */
806                 if ( line[0] == EOF)
807                 {
808                         break;
809                 }
810 #else
811                 wait_keyboard(smb_cli);
812 #endif
813
814                 /* and get a response */
815 #ifdef CLIX
816                 fgets( &line[1],999, stdin);
817 #else
818                 if (!fgets(line,1000,stdin))
819                 {
820                         break;
821                 }
822 #endif
823
824 #else /* HAVE_LIBREADLINE */
825
826                 slprintf(promptline, sizeof(promptline) - 1, "smb: %s> ",
827                          CNV_LANG(info->cur_dir));
828
829                 if (!readline(promptline))
830                     break;
831
832                 /* Copy read line to samba buffer */
833
834                 pstrcpy(line, rl_line_buffer);
835
836                 /* Add to history */
837
838                 if (strlen(line) > 0) 
839                     add_history(line);
840 #endif
841                 /* input language code to internal one */
842                 CNV_INPUT (line);
843
844                 /* special case - first char is ! */
845                 if (*line == '!')
846                 {
847                         system(line + 1);
848                         continue;
849                 }
850
851                 fprintf(out_hnd, "%s\n", line);
852
853                 if (!do_command(info, line)) continue;
854         }
855
856         return(True);
857 }
858
859 /****************************************************************************
860 usage on the program
861 ****************************************************************************/
862 static void usage(char *pname)
863 {
864   fprintf(out_hnd, "Usage: %s [service] [-S server] [-d debuglevel] [-l log] ",
865            pname);
866
867   fprintf(out_hnd, "\nVersion %s\n",VERSION);
868   fprintf(out_hnd, "\t-d debuglevel         set the debuglevel\n");
869   fprintf(out_hnd, "\tservice               connect to \\\\server\\share \n");
870   fprintf(out_hnd, "\t-S server             connect to \\\\server\\IPC$ \n");
871   fprintf(out_hnd, "\t-l log basename.      Basename for log/debug files\n");
872   fprintf(out_hnd, "\t-n netbios name.      Use this name as my netbios name\n");
873   fprintf(out_hnd, "\t-N                    don't ask for a password\n");
874   fprintf(out_hnd, "\t-m max protocol       set the max protocol level\n");
875   fprintf(out_hnd, "\t-I dest IP            use this IP to connect to\n");
876   fprintf(out_hnd, "\t-E                    write messages to stderr instead of stdout\n");
877   fprintf(out_hnd, "\t-U username           set the network username\n");
878   fprintf(out_hnd, "\t-W domain             set the domain name\n");
879   fprintf(out_hnd, "\t-c command string     execute semicolon separated commands\n");
880   fprintf(out_hnd, "\t-t terminal code      terminal i/o code {sjis|euc|jis7|jis8|junet|hex}\n");
881   fprintf(out_hnd, "\n");
882 }
883
884 enum client_action
885 {
886         CLIENT_NONE,
887         CLIENT_IPC,
888         CLIENT_SVC
889 };
890
891 #ifdef HAVE_LIBREADLINE
892
893 /****************************************************************************
894 GNU readline completion functions
895 ****************************************************************************/
896
897 /* Complete a remote registry enum */
898
899 static uint32 reg_list_len = 0;
900 static char **reg_name = NULL;
901
902 static void reg_init(int val, const char *full_keyname, int num)
903 {
904         switch (val)
905         {
906                 case 0:
907                 {
908                         free_char_array(reg_list_len, reg_name);
909                         reg_list_len = 0;
910                         reg_name = NULL;
911                         break;
912                 }
913                 default:
914                 {
915                         break;
916                 }
917         }
918 }
919
920 static void reg_key_list(const char *full_name,
921                                 const char *name, time_t key_mod_time)
922 {
923         fstring key_name;
924         slprintf(key_name, sizeof(key_name)-1, "%s\\", name);
925         add_chars_to_array(&reg_list_len, &reg_name, key_name);
926 }
927
928 static void reg_val_list(const char *full_name,
929                                 const char* name,
930                                 uint32 type,
931                                 const BUFFER2 *value)
932 {
933         add_chars_to_array(&reg_list_len, &reg_name, name);
934 }
935
936 static char *complete_regenum(char *text, int state)
937 {
938         pstring full_keyname;
939         static uint32 i = 0;
940     
941         if (state == 0)
942         {
943                 if (cmd_argc >= 2 && cmd_argv != NULL && cmd_argv[1] != NULL)
944                 {
945                         char *sep;
946                         pstrcpy(full_keyname, cmd_argv[1]);
947                         sep = strrchr(full_keyname, '\\');
948                         if (sep != NULL)
949                         {
950                                 *sep = 0;
951                         }
952                 }
953
954                 /* Iterate all keys / values */
955                 if (!msrpc_reg_enum_key(smb_cli, full_keyname,
956                                    reg_init, reg_key_list, reg_val_list))
957                 {
958                         return NULL;
959                 }
960
961                 i = 0;
962         }
963
964         for (; i < reg_list_len; i++)
965         {
966                 if (text == NULL || text[0] == 0 ||
967                     strnequal(text, reg_name[i], strlen(text)))
968                 {
969                         char *name = strdup(reg_name[i]);
970                         i++;
971                         return name;
972                 }
973         }
974         
975         return NULL;
976 }
977
978
979 static char *complete_samenum_usr(char *text, int state)
980 {
981         static uint32 i = 0;
982         static uint32 num_usrs = 0;
983         static struct acct_info *sam = NULL;
984     
985         if (state == 0)
986         {
987                 fstring srv_name;
988                 fstring domain;
989                 fstring sid;
990                 DOM_SID sid1;
991                 sid_copy(&sid1, &cli_info.dom.level5_sid);
992                 sid_to_string(sid, &sid1);
993                 fstrcpy(domain, cli_info.dom.level5_dom);
994
995                 if (sid1.num_auths == 0)
996                 {
997                         return NULL;
998                 }
999
1000                 fstrcpy(srv_name, "\\\\");
1001                 fstrcat(srv_name, cli_info.dest_host);
1002                 strupper(srv_name);
1003
1004                 free(sam);
1005                 sam = NULL;
1006                 num_usrs = 0;
1007
1008                 /* Iterate all users */
1009                 if (msrpc_sam_enum_users(smb_cli,
1010                                    domain, &sid1, srv_name,
1011                                    &sam, &num_usrs,
1012                                    NULL, NULL, NULL, NULL) == 0)
1013                 {
1014                         return NULL;
1015                 }
1016
1017                 i = 0;
1018         }
1019
1020         for (; i < num_usrs; i++)
1021         {
1022                 char *usr_name = sam[i].acct_name;
1023                 if (text == NULL || text[0] == 0 ||
1024                     strnequal(text, usr_name, strlen(text)))
1025                 {
1026                         char *name = strdup(usr_name);
1027                         i++;
1028                         return name;
1029                 }
1030         }
1031         
1032         return NULL;
1033 }
1034
1035 static char *complete_samenum_als(char *text, int state)
1036 {
1037         static uint32 i = 0;
1038         static uint32 num_als = 0;
1039         static struct acct_info *sam = NULL;
1040     
1041         if (state == 0)
1042         {
1043                 fstring srv_name;
1044                 fstring domain;
1045                 fstring sid;
1046                 DOM_SID sid1;
1047                 sid_copy(&sid1, &cli_info.dom.level5_sid);
1048                 sid_to_string(sid, &sid1);
1049                 fstrcpy(domain, cli_info.dom.level5_dom);
1050
1051                 if (sid1.num_auths == 0)
1052                 {
1053                         return NULL;
1054                 }
1055
1056                 fstrcpy(srv_name, "\\\\");
1057                 fstrcat(srv_name, cli_info.dest_host);
1058                 strupper(srv_name);
1059
1060                 free(sam);
1061                 sam = NULL;
1062                 num_als = 0;
1063
1064                 /* Iterate all aliases */
1065                 if (msrpc_sam_enum_aliases(smb_cli,
1066                                    domain, &sid1, srv_name,
1067                                    &sam, &num_als,
1068                                    NULL, NULL, NULL) == 0)
1069                 {
1070                         return NULL;
1071                 }
1072
1073                 i = 0;
1074         }
1075
1076         for (; i < num_als; i++)
1077         {
1078                 char *als_name = sam[i].acct_name;
1079                 if (text == NULL || text[0] == 0 ||
1080                     strnequal(text, als_name, strlen(text)))
1081                 {
1082                         char *name = strdup(als_name);
1083                         i++;
1084                         return name;
1085                 }
1086         }
1087         
1088         return NULL;
1089 }
1090
1091 static char *complete_samenum_grp(char *text, int state)
1092 {
1093         static uint32 i = 0;
1094         static uint32 num_grps = 0;
1095         static struct acct_info *sam = NULL;
1096     
1097         if (state == 0)
1098         {
1099                 fstring srv_name;
1100                 fstring domain;
1101                 fstring sid;
1102                 DOM_SID sid1;
1103                 sid_copy(&sid1, &cli_info.dom.level5_sid);
1104                 sid_to_string(sid, &sid1);
1105                 fstrcpy(domain, cli_info.dom.level5_dom);
1106
1107                 if (sid1.num_auths == 0)
1108                 {
1109                         return NULL;
1110                 }
1111
1112                 fstrcpy(srv_name, "\\\\");
1113                 fstrcat(srv_name, cli_info.dest_host);
1114                 strupper(srv_name);
1115
1116                 free(sam);
1117                 sam = NULL;
1118                 num_grps = 0;
1119
1120                 /* Iterate all groups */
1121                 if (msrpc_sam_enum_groups(smb_cli,
1122                                    domain, &sid1, srv_name,
1123                                    &sam, &num_grps,
1124                                    NULL, NULL, NULL) == 0)
1125                 {
1126                         return NULL;
1127                 }
1128
1129                 i = 0;
1130         }
1131
1132         for (; i < num_grps; i++)
1133         {
1134                 char *grp_name = sam[i].acct_name;
1135                 if (text == NULL || text[0] == 0 ||
1136                     strnequal(text, grp_name, strlen(text)))
1137                 {
1138                         char *name = strdup(grp_name);
1139                         i++;
1140                         return name;
1141                 }
1142         }
1143         
1144         return NULL;
1145 }
1146
1147 static char *complete_svcenum(char *text, int state)
1148 {
1149         static uint32 i = 0;
1150         static uint32 num_svcs = 0;
1151         static ENUM_SRVC_STATUS *svc = NULL;
1152     
1153         if (state == 0)
1154         {
1155                 free(svc);
1156                 svc = NULL;
1157                 num_svcs = 0;
1158
1159                 /* Iterate all users */
1160                 if (msrpc_svc_enum(&cli_info, &svc, &num_svcs,
1161                                    NULL, NULL) == 0)
1162                 {
1163                         return NULL;
1164                 }
1165
1166                 i = 0;
1167         }
1168
1169         for (; i < num_svcs; i++)
1170         {
1171                 fstring svc_name;
1172                 unistr_to_ascii(svc_name, svc[i].uni_srvc_name.buffer,
1173                         sizeof(svc_name)-1);
1174
1175                 if (text == NULL || text[0] == 0 ||
1176                     strnequal(text, svc_name, strlen(text)))
1177                 {
1178                         char *name = strdup(svc_name);
1179                         i++;
1180                         return name;
1181                 }
1182         }
1183         
1184         return NULL;
1185 }
1186
1187 static char *complete_printersenum(char *text, int state)
1188 {
1189         static uint32 i = 0;
1190         static uint32 num = 0;
1191         static PRINTER_INFO_1 **ctr = NULL;
1192     
1193         if (state == 0)
1194         {
1195                 fstring srv_name;
1196                 fstrcpy(srv_name, "\\\\");
1197                 fstrcat(srv_name, smb_cli->desthost);
1198                 strupper(srv_name);
1199
1200                 free_print1_array(num, ctr);
1201                 ctr = NULL;
1202                 num = 0;
1203
1204                 /* Iterate all users */
1205                 if (!msrpc_spoolss_enum_printers(smb_cli, srv_name,
1206                                    1, &num, (void***)&ctr,
1207                                    NULL))
1208                 {
1209                         return NULL;
1210                 }
1211
1212                 i = 0;
1213         }
1214
1215         for (; i < num; i++)
1216         {
1217                 fstring name;
1218                 unistr_to_ascii(name, ctr[i]->name.buffer,
1219                         sizeof(name)-1);
1220
1221                 if (text == NULL || text[0] == 0 ||
1222                     strnequal(text, name, strlen(text)))
1223                 {
1224                         char *copy = strdup(name);
1225                         i++;
1226                         return copy;
1227                 }
1228         }
1229         
1230         return NULL;
1231 }
1232
1233 /* Complete an rpcclient command */
1234
1235 static char *complete_cmd(char *text, int state)
1236 {
1237     static int cmd_index;
1238     char *name;
1239
1240     /* Initialise */
1241
1242     if (state == 0) {
1243         cmd_index = 0;
1244     }
1245
1246     /* Return the next name which partially matches the list of commands */
1247     
1248     while (strlen(name = commands[cmd_index++].name) > 0) {
1249         if (strncmp(name, text, strlen(text)) == 0) {
1250             return strdup(name);
1251         }
1252     }
1253     
1254     return NULL;
1255 }
1256
1257 /* Main completion function */
1258
1259 static char **completion_fn(char *text, int start, int end)
1260 {
1261         pstring cmd_partial;
1262         int cmd_index;
1263         int num_words;
1264
1265     int i;
1266     char lastch = ' ';
1267
1268         safe_strcpy(cmd_partial, rl_line_buffer,
1269                     MAX(sizeof(cmd_partial),end)-1);
1270
1271     /* Complete rpcclient command */
1272
1273     if (start == 0)
1274         {
1275         return completion_matches(text, complete_cmd);
1276     }
1277
1278     /* Count # of words in command */
1279     
1280     num_words = 0;
1281     for (i = 0; i <= end; i++) {
1282         if ((rl_line_buffer[i] != ' ') && (lastch == ' '))
1283         {
1284                 num_words++;
1285         }
1286         lastch = rl_line_buffer[i];
1287     }
1288     
1289     if (rl_line_buffer[end] == ' ')
1290         num_words++;
1291
1292     /* Work out which command we are completing for */
1293
1294     for (cmd_index = 0; strcmp(commands[cmd_index].name, "") != 0; 
1295          cmd_index++) {
1296         
1297         /* Check each command in array */
1298         
1299         if (strncmp(rl_line_buffer, commands[cmd_index].name,
1300                     strlen(commands[cmd_index].name)) == 0) {
1301             
1302             /* Call appropriate completion function */
1303
1304       if (num_words == 2 || num_words == 3)
1305       {
1306         switch (commands[cmd_index].compl_args[num_words - 2])
1307         {
1308
1309         case COMPL_SAMGRP:
1310           return completion_matches(text, complete_samenum_grp);
1311
1312         case COMPL_SAMALS:
1313           return completion_matches(text, complete_samenum_als);
1314
1315         case COMPL_SAMUSR:
1316           return completion_matches(text, complete_samenum_usr);
1317
1318         case COMPL_SVCLST:
1319           return completion_matches(text, complete_svcenum);
1320
1321         case COMPL_PRTLST:
1322           return completion_matches(text, complete_printersenum);
1323
1324         case COMPL_REGKEY:
1325           return completion_matches(text, complete_regenum);
1326
1327         default:
1328             /* An invalid completion type */
1329             break;
1330         }
1331       }
1332         }
1333     }
1334
1335     /* Eeek! */
1336
1337     return NULL;
1338 }
1339
1340 /* To avoid filename completion being activated when no valid
1341    completions are found, we assign this stub completion function
1342    to the rl_completion_entry_function variable. */
1343
1344 static char *complete_cmd_null(char *text, int state)
1345 {
1346         return NULL;
1347 }
1348
1349 #endif /* HAVE_LIBREADLINE */
1350
1351 /****************************************************************************
1352   main program
1353 ****************************************************************************/
1354  int main(int argc,char *argv[])
1355 {
1356         BOOL interactive = True;
1357
1358         int opt;
1359         extern FILE *dbf;
1360         extern char *optarg;
1361         extern int optind;
1362         static pstring servicesf = CONFIGFILE;
1363         pstring term_code;
1364         char *p;
1365         BOOL got_pass = False;
1366         char *cmd_str="";
1367         mode_t myumask = 0755;
1368         enum client_action cli_action = CLIENT_NONE;
1369
1370         pstring password; /* local copy only, if one is entered */
1371
1372         out_hnd = stdout;
1373         fstrcpy(debugf, argv[0]);
1374
1375         rpcclient_init();
1376
1377 #ifdef KANJI
1378         pstrcpy(term_code, KANJI);
1379 #else /* KANJI */
1380         *term_code = 0;
1381 #endif /* KANJI */
1382
1383         DEBUGLEVEL = 2;
1384
1385         cli_info.put_total_size = 0;
1386         cli_info.put_total_time_ms = 0;
1387         cli_info.get_total_size = 0;
1388         cli_info.get_total_time_ms = 0;
1389
1390         cli_info.dir_total = 0;
1391         cli_info.newer_than = 0;
1392         cli_info.archive_level = 0;
1393         cli_info.print_mode = 1;
1394
1395         cli_info.translation = False;
1396         cli_info.recurse_dir = False;
1397         cli_info.lowercase = False;
1398         cli_info.prompt = True;
1399         cli_info.abort_mget = True;
1400
1401         cli_info.dest_ip.s_addr = 0;
1402         cli_info.name_type = 0x20;
1403
1404         pstrcpy(cli_info.cur_dir , "\\");
1405         pstrcpy(cli_info.file_sel, "");
1406         pstrcpy(cli_info.base_dir, "");
1407         pstrcpy(smb_cli->domain, "");
1408         pstrcpy(smb_cli->user_name, "");
1409         pstrcpy(cli_info.myhostname, "");
1410         pstrcpy(cli_info.dest_host, "");
1411
1412         pstrcpy(cli_info.svc_type, "A:");
1413         pstrcpy(cli_info.share, "");
1414         pstrcpy(cli_info.service, "");
1415
1416         ZERO_STRUCT(cli_info.dom.level3_sid);
1417         ZERO_STRUCT(cli_info.dom.level5_sid);
1418         fstrcpy(cli_info.dom.level3_dom, "");
1419         fstrcpy(cli_info.dom.level5_dom, "");
1420
1421 #ifdef HAVE_LIBREADLINE
1422
1423         /* Initialise GNU Readline */
1424         
1425         rl_readline_name = "rpcclient";
1426         rl_attempted_completion_function = completion_fn;
1427         rl_completion_entry_function = (Function *)complete_cmd_null;
1428         
1429         /* Initialise history list */
1430         
1431         using_history();
1432
1433 #endif /* HAVE_LIBREADLINE */
1434
1435         TimeInit();
1436         charset_initialise();
1437
1438         myumask = umask(0);
1439         umask(myumask);
1440
1441         if (!get_myname(global_myname, NULL))
1442         {
1443                 fprintf(stderr, "Failed to get my hostname.\n");
1444         }
1445
1446         if (getenv("USER"))
1447         {
1448                 pstrcpy(smb_cli->user_name,getenv("USER"));
1449
1450                 /* modification to support userid%passwd syntax in the USER var
1451                 25.Aug.97, jdblair@uab.edu */
1452
1453                 if ((p=strchr(smb_cli->user_name,'%')))
1454                 {
1455                         *p = 0;
1456                         pstrcpy(password,p+1);
1457                         got_pass = True;
1458                         memset(strchr(getenv("USER"),'%')+1,'X',strlen(password));
1459                 }
1460                 strupper(smb_cli->user_name);
1461         }
1462
1463         password[0] = 0;
1464
1465         /* modification to support PASSWD environmental var
1466            25.Aug.97, jdblair@uab.edu */
1467         if (getenv("PASSWD"))
1468         {
1469                 pstrcpy(password,getenv("PASSWD"));
1470         }
1471
1472         if (*smb_cli->user_name == 0 && getenv("LOGNAME"))
1473         {
1474                 pstrcpy(smb_cli->user_name,getenv("LOGNAME"));
1475                 strupper(smb_cli->user_name);
1476         }
1477
1478         if (argc < 2)
1479         {
1480                 usage(argv[0]);
1481                 exit(1);
1482         }
1483
1484         if (*argv[1] != '-')
1485         {
1486
1487                 pstrcpy(cli_info.service, argv[1]);  
1488                 /* Convert any '/' characters in the service name to '\' characters */
1489                 string_replace( cli_info.service, '/','\\');
1490                 argc--;
1491                 argv++;
1492
1493                 fprintf(out_hnd, "service: %s\n", cli_info.service);
1494
1495                 if (count_chars(cli_info.service,'\\') < 3)
1496                 {
1497                         usage(argv[0]);
1498                         printf("\n%s: Not enough '\\' characters in service\n", cli_info.service);
1499                         exit(1);
1500                 }
1501
1502                 /*
1503                 if (count_chars(cli_info.service,'\\') > 3)
1504                 {
1505                         usage(pname);
1506                         printf("\n%s: Too many '\\' characters in service\n", cli_info.service);
1507                         exit(1);
1508                 }
1509                 */
1510
1511                 if (argc > 1 && (*argv[1] != '-'))
1512                 {
1513                         got_pass = True;
1514                         pstrcpy(password,argv[1]);  
1515                         memset(argv[1],'X',strlen(argv[1]));
1516                         argc--;
1517                         argv++;
1518                 }
1519
1520                 cli_action = CLIENT_SVC;
1521         }
1522
1523         while ((opt = getopt(argc, argv,"s:B:O:M:S:i:N:n:d:l:hI:EB:U:L:t:m:W:T:D:c:")) != EOF)
1524         {
1525                 switch (opt)
1526                 {
1527                         case 'm':
1528                         {
1529                                 /* FIXME ... max_protocol seems to be funny here */
1530
1531                                 int max_protocol = 0;
1532                                 max_protocol = interpret_protocol(optarg,max_protocol);
1533                                 fprintf(stderr, "max protocol not currently supported\n");
1534                                 break;
1535                         }
1536
1537                         case 'O':
1538                         {
1539                                 pstrcpy(user_socket_options,optarg);
1540                                 break;  
1541                         }
1542
1543                         case 'S':
1544                         {
1545                                 pstrcpy(cli_info.dest_host,optarg);
1546                                 strupper(cli_info.dest_host);
1547                                 cli_action = CLIENT_IPC;
1548                                 break;
1549                         }
1550
1551                         case 'B':
1552                         {
1553                                 iface_set_default(NULL,optarg,NULL);
1554                                 break;
1555                         }
1556
1557                         case 'i':
1558                         {
1559                                 pstrcpy(scope, optarg);
1560                                 break;
1561                         }
1562
1563                         case 'U':
1564                         {
1565                                 char *lp;
1566                                 pstrcpy(smb_cli->user_name,optarg);
1567                                 if ((lp=strchr(smb_cli->user_name,'%')))
1568                                 {
1569                                         *lp = 0;
1570                                         pstrcpy(password,lp+1);
1571                                         got_pass = True;
1572                                         memset(strchr(optarg,'%')+1,'X',strlen(password));
1573                                 }
1574                                 break;
1575                         }
1576
1577                         case 'W':
1578                         {
1579                                 pstrcpy(smb_cli->domain,optarg);
1580                                 break;
1581                         }
1582
1583                         case 'E':
1584                         {
1585                                 dbf = stderr;
1586                                 break;
1587                         }
1588
1589                         case 'I':
1590                         {
1591                                 cli_info.dest_ip = *interpret_addr2(optarg);
1592                                 if (zero_ip(cli_info.dest_ip))
1593                                 {
1594                                         exit(1);
1595                                 }
1596                                 break;
1597                         }
1598
1599                         case 'n':
1600                         {
1601                                 fstrcpy(global_myname, optarg);
1602                                 break;
1603                         }
1604
1605                         case 'N':
1606                         {
1607                                 got_pass = True;
1608                                 break;
1609                         }
1610
1611                         case 'd':
1612                         {
1613                                 if (*optarg == 'A')
1614                                         DEBUGLEVEL = 10000;
1615                                 else
1616                                         DEBUGLEVEL = atoi(optarg);
1617                                 break;
1618                         }
1619
1620                         case 'l':
1621                         {
1622                                 slprintf(debugf, sizeof(debugf)-1,
1623                                          "%s.client", optarg);
1624                                 interactive = False;
1625                                 break;
1626                         }
1627
1628                         case 'c':
1629                         {
1630                                 cmd_str = optarg;
1631                                 got_pass = True;
1632                                 break;
1633                         }
1634
1635                         case 'h':
1636                         {
1637                                 usage(argv[0]);
1638                                 exit(0);
1639                                 break;
1640                         }
1641
1642                         case 's':
1643                         {
1644                                 pstrcpy(servicesf, optarg);
1645                                 break;
1646                         }
1647
1648                         case 't':
1649                         {
1650                                 pstrcpy(term_code, optarg);
1651                                 break;
1652                         }
1653
1654                         default:
1655                         {
1656                                 usage(argv[0]);
1657                                 exit(1);
1658                                 break;
1659                         }
1660                 }
1661         }
1662
1663         setup_logging(debugf, interactive);
1664
1665         if (cli_action == CLIENT_NONE)
1666         {
1667                 usage(argv[0]);
1668                 exit(1);
1669         }
1670
1671         strupper(global_myname);
1672         fstrcpy(cli_info.myhostname, global_myname);
1673
1674         DEBUG(3,("%s client started (version %s)\n",timestring(),VERSION));
1675
1676         if (!lp_load(servicesf,True, False, False))
1677         {
1678                 fprintf(stderr, "Can't load %s - run testparm to debug it\n", servicesf);
1679         }
1680
1681         codepage_initialise(lp_client_code_page());
1682
1683         load_interfaces();
1684
1685         if (cli_action == CLIENT_IPC)
1686         {
1687                 pstrcpy(cli_info.share, "IPC$");
1688                 pstrcpy(cli_info.svc_type, "IPC");
1689         }
1690
1691         fstrcpy(cli_info.mach_acct, cli_info.myhostname);
1692         strupper(cli_info.mach_acct);
1693         fstrcat(cli_info.mach_acct, "$");
1694
1695         /* set the password cache info */
1696         if (got_pass)
1697         {
1698                 if (password[0] == 0)
1699                 {
1700                         pwd_set_nullpwd(&(smb_cli->pwd));
1701                 }
1702                 else
1703                 {
1704                         /* generate 16 byte hashes */
1705                         pwd_make_lm_nt_16(&(smb_cli->pwd), password);
1706                 }
1707         }
1708         else 
1709         {
1710                 pwd_read(&(smb_cli->pwd), "Enter Password:", True);
1711         }
1712
1713         mdfour(smb_cli->sess_key, smb_cli->pwd.smb_nt_pwd, 16);
1714
1715         /* paranoia: destroy the local copy of the password */
1716         bzero(password, sizeof(password)); 
1717
1718         /* establish connections.  nothing to stop these being re-established. */
1719         rpcclient_connect(&cli_info);
1720
1721         smb_cli->ntlmssp_cli_flgs = 0x0;
1722
1723         DEBUG(5,("rpcclient_connect: smb_cli->fd:%d\n", smb_cli->fd));
1724         if (smb_cli->fd <= 0)
1725         {
1726                 fprintf(stderr, "warning: connection could not be established to %s<%02x>\n",
1727                                  cli_info.dest_host, cli_info.name_type);
1728                 fprintf(stderr, "this version of smbclient may crash if you proceed\n");
1729                 exit(-1);
1730         }
1731
1732         switch (cli_action)
1733         {
1734                 case CLIENT_IPC:
1735                 {
1736                         process(&cli_info, cmd_str);
1737                         break;
1738                 }
1739
1740                 default:
1741                 {
1742                         fprintf(stderr, "unknown client action requested\n");
1743                         break;
1744                 }
1745         }
1746
1747         rpcclient_stop();
1748
1749         return(0);
1750 }