Start of a rewrite of rpcclient based on the libsmb rpc client routines.
[sfrench/samba-autobuild/.git] / source3 / rpcclient / rpcclient.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 2.2
4    RPC pipe client
5
6    Copyright (C) Tim Potter 2000
7
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 2 of the License, or
11    (at your option) any later version.
12    
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17    
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23 #include "includes.h"
24
25 extern int DEBUGLEVEL;
26         
27 pstring password;
28 pstring username;
29 pstring workgroup;
30 pstring server;
31
32 /* Various pipe commands */
33
34 extern struct cmd_set lsarpc_commands[];
35 extern struct cmd_set samr_commands[];
36 extern struct cmd_set spoolss_commands[];
37
38 /* Initialise client credentials for authenticated pipe access */
39
40 void init_rpcclient_creds(struct ntuser_creds *creds)
41 {
42         ZERO_STRUCTP(creds);
43         
44         if (lp_encrypted_passwords()) {
45                 pwd_make_lm_nt_16(&creds->pwd, password);
46         } else {
47                 pwd_set_cleartext(&creds->pwd, password);
48         }
49
50         fstrcpy(creds->user_name, username);
51         fstrcpy(creds->domain, workgroup);
52 }
53
54 /* List to hold groups of commands */
55
56 static struct cmd_list {
57         struct cmd_list *prev, *next;
58         struct cmd_set *cmd_set;
59 } *cmd_list;
60
61 static uint32 cmd_help(int argc, char **argv)
62 {
63         struct cmd_list *temp_list;
64
65         for (temp_list = cmd_list; temp_list; temp_list = temp_list->next) {
66                 struct cmd_set *temp_set = temp_list->cmd_set;
67
68                 while(temp_set->name) {
69                         printf("%s\t%s\n", temp_set->name,
70                                temp_set->description);
71                         temp_set++;
72                 }
73         }
74
75         return 0;
76 }
77
78 static uint32 cmd_debuglevel(int argc, char **argv)
79 {
80         if (argc > 2) {
81                 printf("Usage: %s [debuglevel]\n", argv[0]);
82                 return NT_STATUS_NOPROBLEMO;
83         }
84
85         if (argc == 2) {
86                 DEBUGLEVEL = atoi(argv[1]);
87         }
88
89         printf("debuglevel is %d\n", DEBUGLEVEL);
90
91         return NT_STATUS_NOPROBLEMO;
92 }
93
94 /* Build in rpcclient commands */
95
96 static struct cmd_set rpcclient_commands[] = {
97         { "help", cmd_help, "Print list of commands" },
98         { "debuglevel", cmd_debuglevel, "Set debug level" },
99         { "?", cmd_help, "Print list of commands" },
100
101         { NULL, NULL, NULL }
102 };
103
104 void add_command_set(struct cmd_set *cmd_set)
105 {
106         struct cmd_list *entry;
107
108         if (!(entry = (struct cmd_list *)malloc(sizeof(struct cmd_list)))) {
109                 DEBUG(0, ("out of memory\n"));
110                 return;
111         }
112
113         ZERO_STRUCTP(entry);
114
115         entry->cmd_set = cmd_set;
116         DLIST_ADD(cmd_list, entry);
117 }
118
119 static uint32 do_cmd(struct cmd_set *cmd_entry, char *cmd)
120 {
121         char *p = cmd, **argv = NULL;
122         uint32 result;
123         pstring buf;
124         int argc = 0, i;
125
126         next_token(&p, buf, " ", sizeof(buf));
127
128         /* Count number of arguments first time through the loop then
129            allocate memory and strdup them. */
130
131  again:
132         while(next_token(NULL, buf, " ", sizeof(buf))) {
133                 if (argv) {
134                         argv[argc] = strdup(buf);
135                 }
136                 
137                 argc++;
138         }
139                                 
140         if (!argv) {
141
142                 /* Create argument list */
143
144                 argv = (char **)malloc(sizeof(char *) * argc);
145                 if (!argv) {
146                         fprintf(stderr, "out of memoryx\n");
147                         return 0;
148                 }
149                                         
150                 argc = 1;
151                 p = cmd;
152                 next_token(&p, buf, " ", sizeof(buf));
153                 argv[0] = strdup(buf);
154                                         
155                 goto again;
156         }
157
158         /* Call the function */
159
160         result = cmd_entry->fn(argc, argv);
161                                 
162         /* Cleanup */
163
164         for (i = 0; i < argc; i++) {
165                 free(argv[i]);
166         }
167         
168         free(argv);
169         
170         return result;
171 }
172
173 /* Process a command entered at the prompt or as part of -c */
174
175 static uint32 process_cmd(char *cmd)
176 {
177         struct cmd_list *temp_list;
178         BOOL found = False;
179         pstring buf;
180         char *p = cmd;
181         uint32 result;
182
183         if (!next_token(&p, buf, " ", sizeof(buf))) {
184                 return 0;
185         }
186
187         /* Search for matching commands */
188
189         for (temp_list = cmd_list; temp_list; temp_list = temp_list->next) {
190                 struct cmd_set *temp_set = temp_list->cmd_set;
191
192                 while(temp_set->name) {
193                         if (strequal(buf, temp_set->name)) {
194                                 found = True;
195                                 result = do_cmd(temp_set, cmd);
196                                 goto done;
197                         }
198                         temp_set++;
199                 }
200         }
201
202  done:
203         if (!found) {
204                 printf("command not found: %s\n", buf);
205                 return 0;
206         }
207
208         if (result != 0) {
209                 printf("result was %s\n", get_nt_error_msg(result));
210         }
211
212         return result;
213
214 }
215
216 /* Print usage information */
217
218 static void usage(char *pname)
219 {
220         printf("Usage: %s server [options]\n", pname);
221
222         printf("\t-N                    don't ask for a password\n");
223         printf("\t-d debuglevel         set the debuglevel\n");
224         printf("\t-h                    Print this help message.\n");
225         printf("\t-U username           set the network username\n");
226         printf("\t-W workgroup          set the workgroup name\n");
227         printf("\t-c command string     execute semicolon separated cmds\n");
228         printf("\n");
229 }
230
231 /* Main function */
232
233  int main(int argc, char *argv[])
234 {
235         extern char *optarg;
236         extern int optind;
237         struct in_addr dest_ip;
238         BOOL got_pass = False;
239         BOOL have_ip = False;
240         int opt;
241         pstring cmdstr, servicesf = CONFIGFILE;
242         extern FILE *dbf;
243
244         setlinebuf(stdout);
245         dbf = stderr;
246
247         setup_logging(argv[0], True);
248
249 #ifdef HAVE_LIBREADLINE
250         /* Allow conditional parsing of the ~/.inputrc file. */
251         rl_readline_name = "smbclient";
252 #endif    
253         
254         DEBUGLEVEL = 2;
255
256         TimeInit();
257         charset_initialise();
258
259         /* Parse options */
260
261         if (argc < 2) {
262                 usage(argv[0]);
263                 return 0;
264         }
265
266         pstrcpy(server, argv[1]);
267
268         argv++;
269         argc--;
270
271         while ((opt = getopt(argc, argv, "s:Nd:I:U:W:c:")) != EOF) {
272                 switch (opt) {
273                 case 's':
274                         pstrcpy(servicesf, optarg);
275                         break;
276                 case 'N':
277                         got_pass = True;
278                         break;
279                 case 'd':
280                         DEBUGLEVEL = atoi(optarg);
281                         break;
282                 case 'I':
283                         dest_ip = *interpret_addr2(optarg);
284                         have_ip = True;
285                         break;
286                 case 'U': {
287                         char *lp;
288                         pstrcpy(username,optarg);
289                         if ((lp=strchr(username,'%'))) {
290                                 *lp = 0;
291                                 pstrcpy(password,lp+1);
292                                 got_pass = True;
293                                 memset(strchr(optarg,'%')+1,'X',strlen(password));
294                         }
295                         break;
296                 }
297                 case 'W':
298                         pstrcpy(workgroup, optarg);
299                         break;
300                 case 'c':
301                         pstrcpy(cmdstr, optarg);
302                         got_pass = True;
303                         break;
304                 case 'h':
305                 default:
306                         usage(argv[0]);
307                         exit(1);
308                 }
309         }
310
311         /* Load smb.conf file */
312
313         if (!lp_load(servicesf,True,False,False)) {
314                 fprintf(stderr, "Can't load %s\n", servicesf);
315         }
316
317         codepage_initialise(lp_client_code_page());
318         load_interfaces();
319
320         /* Load command lists */
321
322         add_command_set(rpcclient_commands);
323         add_command_set(lsarpc_commands);
324         add_command_set(samr_commands);
325         add_command_set(spoolss_commands);
326
327         /* Do anything specified with -c */
328
329         if (cmdstr[0]) {
330                 pstring cmd;
331                 char *p = cmdstr;
332                 uint32 result;
333
334                 while(next_token(&p, cmd, ";", sizeof(pstring))) {
335                         result = process_cmd(cmd);
336                 }
337
338                 return 0;
339         }
340
341         /* Loop around accepting commands */
342
343         while(1) {
344                 pstring prompt, cmd;
345                 uint32 result;
346                 
347                 slprintf(prompt, sizeof(prompt) - 1, "rpcclient> ");
348
349 #if HAVE_READLINE
350                 cmd = readline(prompt);
351 #else
352                 printf("%s", prompt);
353
354                 if (!fgets(cmd, sizeof(cmd) - 1, stdin)) {
355                         break;
356                 }
357
358                 cmd[strlen(cmd) - 1] = '\0';
359 #endif
360                 result = process_cmd(cmd);
361         }
362
363         return 0;
364 }