rpcclient registry commands.
[samba.git] / source / rpcclient / cmd_reg.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 1.9.
4    NT Domain Authentication SMB / MSRPC client
5    Copyright (C) Andrew Tridgell 1994-1997
6    Copyright (C) Luke Kenneth Casson Leighton 1996-1997
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
24
25 #ifdef SYSLOG
26 #undef SYSLOG
27 #endif
28
29 #include "includes.h"
30 #include "nterr.h"
31
32 extern int DEBUGLEVEL;
33
34 extern struct cli_state *smb_cli;
35 extern int smb_tidx;
36
37 extern FILE* out_hnd;
38
39
40 /****************************************************************************
41 nt registry enum
42 ****************************************************************************/
43 void cmd_reg_enum(struct client_info *info)
44 {
45         BOOL res = True;
46         BOOL res1 = True;
47         BOOL res2 = True;
48         int i;
49
50         POLICY_HND key_pol;
51         fstring key_name;
52
53         /*
54          * query key info
55          */
56
57         fstring key_class;
58         uint32 max_class_len = 0;
59         uint32 num_subkeys;
60         uint32 max_subkeylen;
61         uint32 max_subkeysize; 
62         uint32 num_values;
63         uint32 max_valnamelen;
64         uint32 max_valbufsize;
65         uint32 sec_desc;
66         NTTIME mod_time;
67
68         /*
69          * unknown 0x1a request
70          */
71
72         uint32 unk_1a_response;
73
74         DEBUG(5, ("cmd_reg_enum: smb_cli->fd:%d\n", smb_cli->fd));
75
76         if (!next_token(NULL, key_name, NULL, sizeof(key_name)))
77         {
78                 fprintf(out_hnd, "regenum key_name\n");
79                 return;
80         }
81
82         /* open WINREG session. */
83         res = res ? cli_nt_session_open(smb_cli, PIPE_WINREG) : False;
84
85         /* open registry receive a policy handle */
86         res = res ? do_reg_open_policy(smb_cli,
87                                 0x84E0, 0x02000000,
88                                 &info->dom.reg_pol_connect) : False;
89
90         /* open an entry */
91         res1 = res  ? do_reg_open_entry(smb_cli, &info->dom.reg_pol_connect,
92                                  key_name, 0x02000000, &key_pol) : False;
93
94         res1 = res1 ? do_reg_query_key(smb_cli,
95                                 &key_pol,
96                                 key_class, &max_class_len,
97                                 &num_subkeys, &max_subkeylen, &max_subkeysize,
98                                 &num_values, &max_valnamelen, &max_valbufsize,
99                                 &sec_desc, &mod_time) : False;
100
101         for (i = 0; i < num_subkeys; i++)
102         {
103                 /*
104                  * enumerate key
105                  */
106
107                 fstring enum_name;
108                 uint32 enum_unk1;
109                 uint32 enum_unk2;
110                 time_t key_mod_time;
111
112                 /* unknown 1a it */
113                 res2 = res1 ? do_reg_unknown_1a(smb_cli, &key_pol,
114                                         &unk_1a_response) : False;
115
116                 if (res2 && unk_1a_response != 5)
117                 {
118                         fprintf(out_hnd,"Unknown 1a response: %x\n", unk_1a_response);
119                 }
120
121                 /* enum key */
122                 res2 = res2 ? do_reg_enum_key(smb_cli, &key_pol,
123                                         i, enum_name,
124                                         &enum_unk1, &enum_unk2,
125                                         &key_mod_time) : False;
126                 
127                 if (res2)
128                 {
129                         display_reg_key_info(out_hnd, ACTION_HEADER   , enum_name, key_mod_time);
130                         display_reg_key_info(out_hnd, ACTION_ENUMERATE, enum_name, key_mod_time);
131                         display_reg_key_info(out_hnd, ACTION_FOOTER   , enum_name, key_mod_time);
132                 }
133
134         }
135
136         for (i = 0; i < num_values; i++)
137         {
138                 /*
139                  * enumerate key
140                  */
141
142                 uint32 val_type;
143                 BUFFER2 value;
144                 fstring val_name;
145
146                 /* unknown 1a it */
147                 res2 = res1 ? do_reg_unknown_1a(smb_cli, &key_pol,
148                                         &unk_1a_response) : False;
149
150                 if (res2 && unk_1a_response != 5)
151                 {
152                         fprintf(out_hnd,"Unknown 1a response: %x\n", unk_1a_response);
153                 }
154
155                 /* enum key */
156                 res2 = res2 ? do_reg_enum_val(smb_cli, &key_pol,
157                                         i, max_valnamelen, max_valbufsize,
158                                         val_name, &val_type, &value) : False;
159                 
160                 if (res2)
161                 {
162                         display_reg_value_info(out_hnd, ACTION_HEADER   , val_name, val_type, &value);
163                         display_reg_value_info(out_hnd, ACTION_ENUMERATE, val_name, val_type, &value);
164                         display_reg_value_info(out_hnd, ACTION_FOOTER   , val_name, val_type, &value);
165                 }
166         }
167
168         /* close the handles */
169         res1 = res1 ? do_reg_close(smb_cli, &key_pol) : False;
170         res  = res  ? do_reg_close(smb_cli, &info->dom.reg_pol_connect) : False;
171
172         /* close the session */
173         cli_nt_session_close(smb_cli);
174
175         if (res && res1 && res2)
176         {
177                 DEBUG(5,("cmd_reg_enum: query succeeded\n"));
178         }
179         else
180         {
181                 DEBUG(5,("cmd_reg_enum: query failed\n"));
182         }
183 }
184
185 /****************************************************************************
186 nt registry query key
187 ****************************************************************************/
188 void cmd_reg_query_key(struct client_info *info)
189 {
190         BOOL res = True;
191         BOOL res1 = True;
192
193         POLICY_HND key_pol;
194         fstring key_name;
195
196         /*
197          * query key info
198          */
199
200         fstring key_class;
201         uint32 key_class_len = 0;
202         uint32 num_subkeys;
203         uint32 max_subkeylen;
204         uint32 max_subkeysize; 
205         uint32 num_values;
206         uint32 max_valnamelen;
207         uint32 max_valbufsize;
208         uint32 sec_desc;
209         NTTIME mod_time;
210
211         DEBUG(5, ("cmd_reg_enum: smb_cli->fd:%d\n", smb_cli->fd));
212
213         if (!next_token(NULL, key_name, NULL, sizeof(key_name)))
214         {
215                 fprintf(out_hnd, "regquery key_name\n");
216                 return;
217         }
218
219         /* open WINREG session. */
220         res = res ? cli_nt_session_open(smb_cli, PIPE_WINREG) : False;
221
222         /* open registry receive a policy handle */
223         res = res ? do_reg_open_policy(smb_cli,
224                                 0x84E0, 0x02000000,
225                                 &info->dom.reg_pol_connect) : False;
226
227         /* open an entry */
228         res1 = res  ? do_reg_open_entry(smb_cli, &info->dom.reg_pol_connect,
229                                  key_name, 0x02000000, &key_pol) : False;
230
231         res1 = res1 ? do_reg_query_key(smb_cli,
232                                 &key_pol,
233                                 key_class, &key_class_len,
234                                 &num_subkeys, &max_subkeylen, &max_subkeysize,
235                                 &num_values, &max_valnamelen, &max_valbufsize,
236                                 &sec_desc, &mod_time) : False;
237
238         if (res1 && key_class_len != 0)
239         {
240                 res1 = res1 ? do_reg_query_key(smb_cli,
241                                 &key_pol,
242                                 key_class, &key_class_len,
243                                 &num_subkeys, &max_subkeylen, &max_subkeysize,
244                                 &num_values, &max_valnamelen, &max_valbufsize,
245                                 &sec_desc, &mod_time) : False;
246         }
247
248         if (res1)
249         {
250                 fprintf(out_hnd,"Registry Query Info Key\n");
251                 fprintf(out_hnd,"key class: %s\n", key_class);
252                 fprintf(out_hnd,"subkeys, max_len, max_size: %d %d %d\n", num_subkeys, max_subkeylen, max_subkeysize);
253                 fprintf(out_hnd,"vals, max_len, max_size: 0x%x 0x%x 0x%x\n", num_values, max_valnamelen, max_valbufsize);
254                 fprintf(out_hnd,"sec desc: 0x%x\n", sec_desc);
255                 fprintf(out_hnd,"mod time: %s\n", http_timestring(nt_time_to_unix(&mod_time)));
256         }
257
258         /* close the handles */
259         res1 = res1 ? do_reg_close(smb_cli, &key_pol) : False;
260         res  = res  ? do_reg_close(smb_cli, &info->dom.reg_pol_connect) : False;
261
262         /* close the session */
263         cli_nt_session_close(smb_cli);
264
265         if (res && res1)
266         {
267                 DEBUG(5,("cmd_reg_query: query succeeded\n"));
268         }
269         else
270         {
271                 DEBUG(5,("cmd_reg_query: query failed\n"));
272         }
273 }
274
275 /****************************************************************************
276 nt registry test
277 ****************************************************************************/
278 void cmd_reg_test2(struct client_info *info)
279 {
280         BOOL res = True;
281         BOOL res1 = True;
282         BOOL res2 = True;
283         BOOL res3 = True;
284         int i;
285
286         /*
287          * query key info
288          */
289
290         POLICY_HND key_pol;
291         fstring key_class;
292         uint32 max_class_len;
293         uint32 num_subkeys;
294         uint32 max_subkeylen;
295         uint32 max_subkeysize; 
296         uint32 num_values;
297         uint32 max_valnamelen;
298         uint32 max_valbufsize;
299         uint32 sec_desc;
300         NTTIME mod_time;
301
302         /*
303          * unknown 0x1a request
304          */
305
306         uint32 unk_1a_response;
307
308         /*
309          * enumerate key
310          */
311
312         fstring enum_name;
313         uint32 enum_unk1;
314         uint32 enum_unk2;
315         time_t key_mod_time;
316
317         DEBUG(5, ("cmd_reg_test: smb_cli->fd:%d\n", smb_cli->fd));
318
319         /* open WINREG session. */
320         res = res ? cli_nt_session_open(smb_cli, PIPE_WINREG) : False;
321
322         /* open registry receive a policy handle */
323         res  = res ? do_reg_open_policy(smb_cli,
324                                 0x84E0, 0x02000000,
325                                 &info->dom.reg_pol_connect) : False;
326
327         res1 = res ? do_reg_open_unk_4(smb_cli,
328                                 0x84E0, 0x02000000,
329                                 &info->dom.reg_pol_unk_4  ) : False;
330
331         res2 = res1 ? do_reg_query_key(smb_cli,
332                                 &key_pol,
333                                 key_class, &max_class_len,
334                                 &num_subkeys, &max_subkeylen, &max_subkeysize,
335                                 &num_values, &max_valnamelen, &max_valbufsize,
336                                 &sec_desc, &mod_time) : False;
337
338         for (i = 0; i < num_subkeys; i++)
339         {
340                 /* unknown 1a it */
341                 res3 = res2 ? do_reg_unknown_1a(smb_cli, &info->dom.reg_pol_connect,
342                                         &unk_1a_response) : False;
343
344                 if (res3)
345                 {
346                         fprintf(out_hnd,"Unknown 1a response: %x\n", unk_1a_response);
347                 }
348
349                 /* enum key */
350                 res3 = res3 ? do_reg_enum_key(smb_cli, &info->dom.reg_pol_connect,
351                                         i, enum_name,
352                                         &enum_unk1, &enum_unk2,
353                                         &key_mod_time) : False;
354                 
355                 if (res3)
356                 {
357                         fprintf(out_hnd,"Enum Key: %s  ", enum_name);
358                         fprintf(out_hnd,"unk (%08x %08x)  ", enum_unk1, enum_unk2);
359                         fprintf(out_hnd,"mod time: %s\n", http_timestring(key_mod_time));
360                 }
361         }
362
363         /* close the handles */
364         res2 = res2 ? do_reg_close(smb_cli, &key_pol                  ) : False;
365         res1 = res1 ? do_reg_close(smb_cli, &info->dom.reg_pol_unk_4  ) : False;
366         res  = res  ? do_reg_close(smb_cli, &info->dom.reg_pol_connect) : False;
367
368         /* close the session */
369         cli_nt_session_close(smb_cli);
370
371         if (res && res1 && res2)
372         {
373                 DEBUG(5,("cmd_reg_test2: query succeeded\n"));
374                 fprintf(out_hnd,"Registry Test2\n");
375         }
376         else
377         {
378                 DEBUG(5,("cmd_reg_test2: query failed\n"));
379         }
380 }
381
382 /****************************************************************************
383 nt registry create value
384 ****************************************************************************/
385 void cmd_reg_create_val(struct client_info *info)
386 {
387         BOOL res = True;
388         BOOL res3 = True;
389         BOOL res4 = True;
390
391         POLICY_HND parent_pol;
392         fstring parent_name;
393         fstring val_name;
394         fstring tmp;
395         uint32 val_type;
396         BUFFER3 value;
397
398 #if 0
399         uint32 unk_0;
400         uint32 unk_1;
401         /* query it */
402         res1 = res1 ? do_reg_query_info(smb_cli, &val_pol,
403                                 type, &unk_0, &unk_1) : False;
404 #endif
405
406         DEBUG(5, ("cmd_reg_get_val_sec: smb_cli->fd:%d\n", smb_cli->fd));
407
408         if (!next_token(NULL, parent_name, NULL, sizeof(parent_name)))
409         {
410                 fprintf(out_hnd, "regcreate <parent val name> <val_name> <val_type> <val>\n");
411                 return;
412         }
413
414         if (!next_token(NULL, val_name   , NULL, sizeof(val_name   )))
415         {
416                 fprintf(out_hnd, "regcreate <parent val name> <val_name> <val_type> <val>\n");
417                 return;
418         }
419
420         if (!next_token(NULL, tmp, NULL, sizeof(tmp)))
421         {
422                 fprintf(out_hnd, "regcreate <parent val name> <val_name> <val_type (1|4)> <val>\n");
423                 return;
424         }
425
426         val_type = atoi(tmp);
427
428         if (val_type != 1 && val_type != 3 && val_type != 4)
429         {
430                 fprintf(out_hnd, "val_type 1=UNISTR, 3=BYTES, 4=DWORD supported\n");
431                 return;
432         }
433
434         if (!next_token(NULL, tmp, NULL, sizeof(tmp)))
435         {
436                 fprintf(out_hnd, "regcreate <parent val name> <val_name> <val_type (1|4)> <val>\n");
437                 return;
438         }
439
440         switch (val_type)
441         {
442                 case 0x01: /* UNISTR */
443                 {
444                         make_buffer3_str(&value, tmp, strlen(tmp)+1);
445                         break;
446                 }
447                 case 0x03: /* BYTES */
448                 {
449                         make_buffer3_hex(&value, tmp);
450                         break;
451                 }
452                 case 0x04: /* DWORD */
453                 {
454                         uint32 tmp_val;
455                         if (strnequal(tmp, "0x", 2))
456                         {
457                                 tmp_val = strtol(tmp, (char**)NULL, 16);
458                         }
459                         else
460                         {
461                                 tmp_val = strtol(tmp, (char**)NULL, 10);
462                         }
463                         make_buffer3_uint32(&value, tmp_val);
464                         break;
465                 }
466                 default:
467                 {
468                         fprintf(out_hnd, "i told you i only deal with UNISTR, DWORD and BYTES!\n");
469                         return;
470                 }
471         }
472                 
473         DEBUG(10,("key data:\n"));
474         dump_data(10, value.buffer, value.buf_len);
475
476         /* open WINREG session. */
477         res = res ? cli_nt_session_open(smb_cli, PIPE_WINREG) : False;
478
479         /* open registry receive a policy handle */
480         res  = res ? do_reg_open_policy(smb_cli,
481                                 0x84E0, 0x02000000,
482                                 &info->dom.reg_pol_connect) : False;
483
484         /* open an entry */
485         res3 = res ? do_reg_open_entry(smb_cli, &info->dom.reg_pol_connect,
486                                  parent_name, 0x02000000, &parent_pol) : False;
487
488         /* create an entry */
489         res4 = res3 ? do_reg_create_val(smb_cli, &parent_pol,
490                                  val_name, val_type, &value) : False;
491
492         /* close the val handle */
493         res3 = res3 ? do_reg_close(smb_cli, &parent_pol) : False;
494
495         /* close the registry handles */
496         res  = res  ? do_reg_close(smb_cli, &info->dom.reg_pol_connect) : False;
497
498         /* close the session */
499         cli_nt_session_close(smb_cli);
500
501         if (res && res3 && res4)
502         {
503                 DEBUG(5,("cmd_reg_create_val: query succeeded\n"));
504                 fprintf(out_hnd,"OK\n");
505         }
506         else
507         {
508                 DEBUG(5,("cmd_reg_create_val: query failed\n"));
509         }
510 }
511
512 /****************************************************************************
513 nt registry create key
514 ****************************************************************************/
515 void cmd_reg_create_key(struct client_info *info)
516 {
517         BOOL res = True;
518         BOOL res3 = True;
519         BOOL res4 = True;
520
521         POLICY_HND parent_pol;
522         POLICY_HND key_pol;
523         fstring parent_name;
524         fstring key_name;
525         fstring key_class;
526         SEC_INFO sam_access;
527
528 #if 0
529         uint32 unk_0;
530         uint32 unk_1;
531         /* query it */
532         res1 = res1 ? do_reg_query_info(smb_cli, &key_pol,
533                                 type, &unk_0, &unk_1) : False;
534 #endif
535
536         DEBUG(5, ("cmd_reg_create_key: smb_cli->fd:%d\n", smb_cli->fd));
537
538         if (!next_token(NULL, parent_name, NULL, sizeof(parent_name)))
539         {
540                 fprintf(out_hnd, "regcreate <parent key name> <key_name> [key_class]\n");
541                 return;
542         }
543
544         if (!next_token(NULL, key_name   , NULL, sizeof(key_name   )))
545         {
546                 fprintf(out_hnd, "regcreate <parent key name> <key_name> [key_class]\n");
547                 return;
548         }
549
550         if (!next_token(NULL, key_class, NULL, sizeof(key_class)))
551         {
552                 memset(key_class, 0, sizeof(key_class));
553         }
554
555         /* set access permissions */
556         sam_access.perms = SEC_RIGHTS_READ;
557
558         /* open WINREG session. */
559         res = res ? cli_nt_session_open(smb_cli, PIPE_WINREG) : False;
560
561         /* open registry receive a policy handle */
562         res  = res ? do_reg_open_policy(smb_cli,
563                                 0x84E0, 0x02000000,
564                                 &info->dom.reg_pol_connect) : False;
565
566         /* open an entry */
567         res3 = res ? do_reg_open_entry(smb_cli, &info->dom.reg_pol_connect,
568                                  parent_name, 0x02000000, &parent_pol) : False;
569
570         /* create an entry */
571         res4 = res3 ? do_reg_create_key(smb_cli, &parent_pol,
572                                  key_name, key_class, &sam_access, &key_pol) : False;
573
574         /* close the key handle */
575         res4 = res4 ? do_reg_close(smb_cli, &key_pol) : False;
576
577         /* close the key handle */
578         res3 = res3 ? do_reg_close(smb_cli, &parent_pol) : False;
579
580         /* close the registry handles */
581         res  = res  ? do_reg_close(smb_cli, &info->dom.reg_pol_connect) : False;
582
583         /* close the session */
584         cli_nt_session_close(smb_cli);
585
586         if (res && res3 && res4)
587         {
588                 DEBUG(5,("cmd_reg_create_key: query succeeded\n"));
589                 fprintf(out_hnd,"OK\n");
590         }
591         else
592         {
593                 DEBUG(5,("cmd_reg_create_key: query failed\n"));
594         }
595 }
596
597 /****************************************************************************
598 nt registry security info
599 ****************************************************************************/
600 void cmd_reg_get_key_sec(struct client_info *info)
601 {
602         BOOL res = True;
603         BOOL res3 = True;
604         BOOL res4 = True;
605
606         POLICY_HND key_pol;
607         fstring key_name;
608
609         /*
610          * security info
611          */
612
613         uint32 sec_buf_size;
614         SEC_DESC_BUF sec_buf;
615
616         DEBUG(5, ("cmd_reg_get_key_sec: smb_cli->fd:%d\n", smb_cli->fd));
617
618         if (!next_token(NULL, key_name, NULL, sizeof(key_name)))
619         {
620                 fprintf(out_hnd, "regtest key_name\n");
621                 return;
622         }
623
624         /* open WINREG session. */
625         res = res ? cli_nt_session_open(smb_cli, PIPE_WINREG) : False;
626
627         /* open registry receive a policy handle */
628         res  = res ? do_reg_open_policy(smb_cli,
629                                 0x84E0, 0x02000000,
630                                 &info->dom.reg_pol_connect) : False;
631
632         /* open an entry */
633         res3 = res ? do_reg_open_entry(smb_cli, &info->dom.reg_pol_connect,
634                                  key_name, 0x02000000, &key_pol) : False;
635
636         /* query key sec info.  first call sets sec_buf_size. */
637         sec_buf_size = 0;
638         res4 = res3 ? do_reg_get_key_sec(smb_cli, &key_pol,
639                                 &sec_buf_size, &sec_buf) : False;
640         
641         res4 = res4 ? do_reg_get_key_sec(smb_cli, &key_pol,
642                                 &sec_buf_size, &sec_buf) : False;
643
644         if (res4 && sec_buf.len > 0)
645         {
646                 fprintf(out_hnd, "Security Info for %s: (%d)\n",
647                                  key_name, sec_buf_size);
648                 display_sec_desc(out_hnd, ACTION_HEADER   , &sec_buf.sec);
649                 display_sec_desc(out_hnd, ACTION_ENUMERATE, &sec_buf.sec);
650                 display_sec_desc(out_hnd, ACTION_FOOTER   , &sec_buf.sec);
651         }
652
653         /* close the key handle */
654         res3 = res3 ? do_reg_close(smb_cli, &key_pol) : False;
655
656         /* close the registry handles */
657         res  = res  ? do_reg_close(smb_cli, &info->dom.reg_pol_connect) : False;
658
659         /* close the session */
660         cli_nt_session_close(smb_cli);
661
662         if (res && res3 && res4)
663         {
664                 DEBUG(5,("cmd_reg_test2: query succeeded\n"));
665                 fprintf(out_hnd,"Registry Test2\n");
666         }
667         else
668         {
669                 DEBUG(5,("cmd_reg_test2: query failed\n"));
670         }
671 }
672