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