Removed 'extern int DEBUGLEVEL' as it is now in the smb.h header.
[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    Copyright (C) Simo Sorce 2001
8    
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 2 of the License, or
12    (at your option) any later version.
13    
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18    
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software
21    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24 #ifdef SYSLOG
25 #undef SYSLOG
26 #endif
27
28 #include "includes.h"
29
30 extern int smb_tidx;
31
32 extern FILE* out_hnd;
33
34 /*
35  * keys.  of the form:
36  * ----
37  *
38  * [HKLM]|[HKU]\[parent_keyname_components]\[subkey]|[value]
39  *
40  * reg_getsubkey() splits this down into:
41  * [HKLM]|[HKU]\[parent_keyname_components] and [subkey]|[value]
42  *
43  * do_reg_connect() splits the left side down further into:
44  * [HKLM]|[HKU] and [parent_keyname_components].
45  *
46  * HKLM is short for HKEY_LOCAL_MACHINE
47  * HKU  is short for HKEY_USERS
48  *
49  * oh, and HKEY stands for "Hive Key".
50  *
51  */
52
53 #if 0 /* Simo: reg functions need to be updated to the new cmd interface */
54
55 /****************************************************************************
56 nt registry enum
57 ****************************************************************************/
58 static void cmd_reg_enum(struct client_info *info)
59 {
60         BOOL res = True;
61         BOOL res1 = True;
62         BOOL res2 = True;
63         int i;
64
65         POLICY_HND key_pol;
66         fstring full_keyname;
67         fstring key_name;
68
69         /*
70          * query key info
71          */
72
73         fstring key_class;
74         uint32 max_class_len = 0;
75         uint32 num_subkeys;
76         uint32 max_subkeylen;
77         uint32 max_subkeysize; 
78         uint32 num_values;
79         uint32 max_valnamelen;
80         uint32 max_valbufsize;
81         uint32 sec_desc;
82         NTTIME mod_time;
83
84         /*
85          * unknown 0x1a request
86          */
87
88         uint32 unk_1a_response;
89
90         DEBUG(5, ("cmd_reg_enum: smb_cli->fd:%d\n", smb_cli->fd));
91
92         if (!next_token_nr(NULL, full_keyname, NULL, sizeof(full_keyname)))
93         {
94                 fprintf(out_hnd, "regenum <key_name>\n");
95                 return;
96         }
97
98         /* open WINREG session. */
99         res = res ? cli_nt_session_open(smb_cli, PIPE_WINREG) : False;
100
101         /* open registry receive a policy handle */
102         res = res ? do_reg_connect(smb_cli, full_keyname, key_name,
103                                 &info->dom.reg_pol_connect) : False;
104
105         if ((*key_name) != 0)
106         {
107                 /* open an entry */
108                 res1 = res  ? do_reg_open_entry(smb_cli, &info->dom.reg_pol_connect,
109                                          key_name, 0x02000000, &key_pol) : False;
110         }
111         else
112         {
113                 memcpy(&key_pol, &info->dom.reg_pol_connect, sizeof(key_pol));
114         }
115
116         res1 = res1 ? do_reg_query_key(smb_cli,
117                                 &key_pol,
118                                 key_class, &max_class_len,
119                                 &num_subkeys, &max_subkeylen, &max_subkeysize,
120                                 &num_values, &max_valnamelen, &max_valbufsize,
121                                 &sec_desc, &mod_time) : False;
122
123         if (res1 && num_subkeys > 0)
124         {
125                 fprintf(out_hnd,"Subkeys\n");
126                 fprintf(out_hnd,"-------\n");
127         }
128
129         for (i = 0; i < num_subkeys; i++)
130         {
131                 /*
132                  * enumerate key
133                  */
134
135                 fstring enum_name;
136                 uint32 enum_unk1;
137                 uint32 enum_unk2;
138                 time_t key_mod_time;
139
140                 /* unknown 1a it */
141                 res2 = res1 ? do_reg_unknown_1a(smb_cli, &key_pol,
142                                         &unk_1a_response) : False;
143
144                 if (res2 && unk_1a_response != 5)
145                 {
146                         fprintf(out_hnd,"Unknown 1a response: %x\n", unk_1a_response);
147                 }
148
149                 /* enum key */
150                 res2 = res2 ? do_reg_enum_key(smb_cli, &key_pol,
151                                         i, enum_name,
152                                         &enum_unk1, &enum_unk2,
153                                         &key_mod_time) : False;
154                 
155                 if (res2)
156                 {
157                         display_reg_key_info(out_hnd, ACTION_HEADER   , enum_name, key_mod_time);
158                         display_reg_key_info(out_hnd, ACTION_ENUMERATE, enum_name, key_mod_time);
159                         display_reg_key_info(out_hnd, ACTION_FOOTER   , enum_name, key_mod_time);
160                 }
161
162         }
163
164         if (num_values > 0)
165         {
166                 fprintf(out_hnd,"Key Values\n");
167                 fprintf(out_hnd,"----------\n");
168         }
169
170         for (i = 0; i < num_values; i++)
171         {
172                 /*
173                  * enumerate key
174                  */
175
176                 uint32 val_type;
177                 BUFFER2 value;
178                 fstring val_name;
179
180                 /* unknown 1a it */
181                 res2 = res1 ? do_reg_unknown_1a(smb_cli, &key_pol,
182                                         &unk_1a_response) : False;
183
184                 if (res2 && unk_1a_response != 5)
185                 {
186                         fprintf(out_hnd,"Unknown 1a response: %x\n", unk_1a_response);
187                 }
188
189                 /* enum key */
190                 res2 = res2 ? do_reg_enum_val(smb_cli, &key_pol,
191                                         i, max_valnamelen, max_valbufsize,
192                                         val_name, &val_type, &value) : False;
193                 
194                 if (res2)
195                 {
196                         display_reg_value_info(out_hnd, ACTION_HEADER   , val_name, val_type, &value);
197                         display_reg_value_info(out_hnd, ACTION_ENUMERATE, val_name, val_type, &value);
198                         display_reg_value_info(out_hnd, ACTION_FOOTER   , val_name, val_type, &value);
199                 }
200         }
201
202         /* close the handles */
203         if ((*key_name) != 0)
204         {
205                 res1 = res1 ? do_reg_close(smb_cli, &key_pol) : False;
206         }
207         res  = res  ? do_reg_close(smb_cli, &info->dom.reg_pol_connect) : False;
208
209         /* close the session */
210         cli_nt_session_close(smb_cli);
211
212         if (res && res1 && res2)
213         {
214                 DEBUG(5,("cmd_reg_enum: query succeeded\n"));
215         }
216         else
217         {
218                 DEBUG(5,("cmd_reg_enum: query failed\n"));
219         }
220 }
221
222 /****************************************************************************
223 nt registry query key
224 ****************************************************************************/
225 static void cmd_reg_query_key(struct client_info *info)
226 {
227         BOOL res = True;
228         BOOL res1 = True;
229
230         POLICY_HND key_pol;
231         fstring full_keyname;
232         fstring key_name;
233
234         /*
235          * query key info
236          */
237
238         fstring key_class;
239         uint32 key_class_len = 0;
240         uint32 num_subkeys;
241         uint32 max_subkeylen;
242         uint32 max_subkeysize; 
243         uint32 num_values;
244         uint32 max_valnamelen;
245         uint32 max_valbufsize;
246         uint32 sec_desc;
247         NTTIME mod_time;
248
249         DEBUG(5, ("cmd_reg_enum: smb_cli->fd:%d\n", smb_cli->fd));
250
251         if (!next_token_nr(NULL, full_keyname, NULL, sizeof(full_keyname)))
252         {
253                 fprintf(out_hnd, "regquery key_name\n");
254                 return;
255         }
256
257         /* open WINREG session. */
258         res = res ? cli_nt_session_open(smb_cli, PIPE_WINREG) : False;
259
260         /* open registry receive a policy handle */
261         res = res ? do_reg_connect(smb_cli, full_keyname, key_name,
262                                 &info->dom.reg_pol_connect) : False;
263
264         if ((*key_name) != 0)
265         {
266                 /* open an entry */
267                 res1 = res  ? do_reg_open_entry(smb_cli, &info->dom.reg_pol_connect,
268                                          key_name, 0x02000000, &key_pol) : False;
269         }
270         else
271         {
272                 memcpy(&key_pol, &info->dom.reg_pol_connect, sizeof(key_pol));
273         }
274
275         res1 = res1 ? do_reg_query_key(smb_cli,
276                                 &key_pol,
277                                 key_class, &key_class_len,
278                                 &num_subkeys, &max_subkeylen, &max_subkeysize,
279                                 &num_values, &max_valnamelen, &max_valbufsize,
280                                 &sec_desc, &mod_time) : False;
281
282         if (res1 && key_class_len != 0)
283         {
284                 res1 = res1 ? do_reg_query_key(smb_cli,
285                                 &key_pol,
286                                 key_class, &key_class_len,
287                                 &num_subkeys, &max_subkeylen, &max_subkeysize,
288                                 &num_values, &max_valnamelen, &max_valbufsize,
289                                 &sec_desc, &mod_time) : False;
290         }
291
292         if (res1)
293         {
294                 fprintf(out_hnd,"Registry Query Info Key\n");
295                 fprintf(out_hnd,"key class: %s\n", key_class);
296                 fprintf(out_hnd,"subkeys, max_len, max_size: %d %d %d\n", num_subkeys, max_subkeylen, max_subkeysize);
297                 fprintf(out_hnd,"vals, max_len, max_size: 0x%x 0x%x 0x%x\n", num_values, max_valnamelen, max_valbufsize);
298                 fprintf(out_hnd,"sec desc: 0x%x\n", sec_desc);
299                 fprintf(out_hnd,"mod time: %s\n", http_timestring(nt_time_to_unix(&mod_time)));
300         }
301
302         /* close the handles */
303         if ((*key_name) != 0)
304         {
305                 res1 = res1 ? do_reg_close(smb_cli, &key_pol) : False;
306         }
307         res  = res  ? do_reg_close(smb_cli, &info->dom.reg_pol_connect) : False;
308
309         /* close the session */
310         cli_nt_session_close(smb_cli);
311
312         if (res && res1)
313         {
314                 DEBUG(5,("cmd_reg_query: query succeeded\n"));
315         }
316         else
317         {
318                 DEBUG(5,("cmd_reg_query: query failed\n"));
319         }
320 }
321
322 /****************************************************************************
323 nt registry create value
324 ****************************************************************************/
325 static void cmd_reg_create_val(struct client_info *info)
326 {
327         BOOL res = True;
328         BOOL res3 = True;
329         BOOL res4 = True;
330
331         POLICY_HND parent_pol;
332         fstring full_keyname;
333         fstring keyname;
334         fstring parent_name;
335         fstring val_name;
336         fstring tmp;
337         uint32 val_type;
338         BUFFER3 value;
339
340 #if 0
341         uint32 unk_0;
342         uint32 unk_1;
343         /* query it */
344         res1 = res1 ? do_reg_query_info(smb_cli, &val_pol,
345                                 val_name, *val_type) : False;
346 #endif
347
348         DEBUG(5, ("cmd_reg_create_val: smb_cli->fd:%d\n", smb_cli->fd));
349
350         if (!next_token_nr(NULL, full_keyname, NULL, sizeof(full_keyname)))
351         {
352                 fprintf(out_hnd, "regcreate <val_name> <val_type> <val>\n");
353                 return;
354         }
355
356         reg_get_subkey(full_keyname, keyname, val_name);
357
358         if (keyname[0] == 0 || val_name[0] == 0)
359         {
360                 fprintf(out_hnd, "invalid key name\n");
361                 return;
362         }
363         
364         if (!next_token_nr(NULL, tmp, NULL, sizeof(tmp)))
365         {
366                 fprintf(out_hnd, "regcreate <val_name> <val_type (1|4)> <val>\n");
367                 return;
368         }
369
370         val_type = atoi(tmp);
371
372         if (val_type != 1 && val_type != 3 && val_type != 4)
373         {
374                 fprintf(out_hnd, "val_type 1=UNISTR, 3=BYTES, 4=DWORD supported\n");
375                 return;
376         }
377
378         if (!next_token_nr(NULL, tmp, NULL, sizeof(tmp)))
379         {
380                 fprintf(out_hnd, "regcreate <val_name> <val_type (1|4)> <val>\n");
381                 return;
382         }
383
384         switch (val_type)
385         {
386                 case 0x01: /* UNISTR */
387                 {
388                         init_buffer3_str(&value, tmp, strlen(tmp)+1);
389                         break;
390                 }
391                 case 0x03: /* BYTES */
392                 {
393                         init_buffer3_hex(&value, tmp);
394                         break;
395                 }
396                 case 0x04: /* DWORD */
397                 {
398                         uint32 tmp_val;
399                         if (strnequal(tmp, "0x", 2))
400                         {
401                                 tmp_val = strtol(tmp, (char**)NULL, 16);
402                         }
403                         else
404                         {
405                                 tmp_val = strtol(tmp, (char**)NULL, 10);
406                         }
407                         init_buffer3_uint32(&value, tmp_val);
408                         break;
409                 }
410                 default:
411                 {
412                         fprintf(out_hnd, "i told you i only deal with UNISTR, DWORD and BYTES!\n");
413                         return;
414                 }
415         }
416                 
417         DEBUG(10,("key data:\n"));
418         dump_data(10, (char *)value.buffer, value.buf_len);
419
420         /* open WINREG session. */
421         res = res ? cli_nt_session_open(smb_cli, PIPE_WINREG) : False;
422
423         /* open registry receive a policy handle */
424         res = res ? do_reg_connect(smb_cli, keyname, parent_name,
425                                 &info->dom.reg_pol_connect) : False;
426
427         if ((*val_name) != 0)
428         {
429                 /* open an entry */
430                 res3 = res  ? do_reg_open_entry(smb_cli, &info->dom.reg_pol_connect,
431                                          parent_name, 0x02000000, &parent_pol) : False;
432         }
433         else
434         {
435                 memcpy(&parent_pol, &info->dom.reg_pol_connect, sizeof(parent_pol));
436         }
437
438         /* create an entry */
439         res4 = res3 ? do_reg_create_val(smb_cli, &parent_pol,
440                                  val_name, val_type, &value) : False;
441
442         /* flush the modified key */
443         res4 = res4 ? do_reg_flush_key(smb_cli, &parent_pol) : False;
444
445         /* close the val handle */
446         if ((*val_name) != 0)
447         {
448                 res3 = res3 ? do_reg_close(smb_cli, &parent_pol) : False;
449         }
450
451         /* close the registry handles */
452         res  = res  ? do_reg_close(smb_cli, &info->dom.reg_pol_connect) : False;
453
454         /* close the session */
455         cli_nt_session_close(smb_cli);
456
457         if (res && res3 && res4)
458         {
459                 DEBUG(5,("cmd_reg_create_val: query succeeded\n"));
460                 fprintf(out_hnd,"OK\n");
461         }
462         else
463         {
464                 DEBUG(5,("cmd_reg_create_val: query failed\n"));
465         }
466 }
467
468 /****************************************************************************
469 nt registry delete value
470 ****************************************************************************/
471 static void cmd_reg_delete_val(struct client_info *info)
472 {
473         BOOL res = True;
474         BOOL res3 = True;
475         BOOL res4 = True;
476
477         POLICY_HND parent_pol;
478         fstring full_keyname;
479         fstring keyname;
480         fstring parent_name;
481         fstring val_name;
482
483         DEBUG(5, ("cmd_reg_delete_val: smb_cli->fd:%d\n", smb_cli->fd));
484
485         if (!next_token_nr(NULL, full_keyname, NULL, sizeof(full_keyname)))
486         {
487                 fprintf(out_hnd, "regdelete <val_name>\n");
488                 return;
489         }
490
491         reg_get_subkey(full_keyname, keyname, val_name);
492
493         if (keyname[0] == 0 || val_name[0] == 0)
494         {
495                 fprintf(out_hnd, "invalid key name\n");
496                 return;
497         }
498         
499         /* open WINREG session. */
500         res = res ? cli_nt_session_open(smb_cli, PIPE_WINREG) : False;
501
502         /* open registry receive a policy handle */
503         res = res ? do_reg_connect(smb_cli, keyname, parent_name,
504                                 &info->dom.reg_pol_connect) : False;
505
506         if ((*val_name) != 0)
507         {
508                 /* open an entry */
509                 res3 = res  ? do_reg_open_entry(smb_cli, &info->dom.reg_pol_connect,
510                                          parent_name, 0x02000000, &parent_pol) : False;
511         }
512         else
513         {
514                 memcpy(&parent_pol, &info->dom.reg_pol_connect, sizeof(parent_pol));
515         }
516
517         /* delete an entry */
518         res4 = res3 ? do_reg_delete_val(smb_cli, &parent_pol, val_name) : False;
519
520         /* flush the modified key */
521         res4 = res4 ? do_reg_flush_key(smb_cli, &parent_pol) : False;
522
523         /* close the key handle */
524         res3 = res3 ? do_reg_close(smb_cli, &parent_pol) : False;
525
526         /* close the registry handles */
527         res  = res  ? do_reg_close(smb_cli, &info->dom.reg_pol_connect) : False;
528
529         /* close the session */
530         cli_nt_session_close(smb_cli);
531
532         if (res && res3 && res4)
533         {
534                 DEBUG(5,("cmd_reg_delete_val: query succeeded\n"));
535                 fprintf(out_hnd,"OK\n");
536         }
537         else
538         {
539                 DEBUG(5,("cmd_reg_delete_val: query failed\n"));
540         }
541 }
542
543 /****************************************************************************
544 nt registry delete key
545 ****************************************************************************/
546 static void cmd_reg_delete_key(struct client_info *info)
547 {
548         BOOL res = True;
549         BOOL res3 = True;
550         BOOL res4 = True;
551
552         POLICY_HND parent_pol;
553         fstring full_keyname;
554         fstring parent_name;
555         fstring key_name;
556         fstring subkey_name;
557
558         DEBUG(5, ("cmd_reg_delete_key: smb_cli->fd:%d\n", smb_cli->fd));
559
560         if (!next_token_nr(NULL, full_keyname, NULL, sizeof(full_keyname)))
561         {
562                 fprintf(out_hnd, "regdeletekey <key_name>\n");
563                 return;
564         }
565
566         reg_get_subkey(full_keyname, parent_name, subkey_name);
567
568         if (parent_name[0] == 0 || subkey_name[0] == 0)
569         {
570                 fprintf(out_hnd, "invalid key name\n");
571                 return;
572         }
573         
574         /* open WINREG session. */
575         res = res ? cli_nt_session_open(smb_cli, PIPE_WINREG) : False;
576
577         /* open registry receive a policy handle */
578         res = res ? do_reg_connect(smb_cli, parent_name, key_name,
579                                 &info->dom.reg_pol_connect) : False;
580
581         if ((*key_name) != 0)
582         {
583                 /* open an entry */
584                 res3 = res  ? do_reg_open_entry(smb_cli, &info->dom.reg_pol_connect,
585                                          key_name, 0x02000000, &parent_pol) : False;
586         }
587         else
588         {
589                 memcpy(&parent_pol, &info->dom.reg_pol_connect, sizeof(parent_pol));
590         }
591
592         /* create an entry */
593         res4 = res3 ? do_reg_delete_key(smb_cli, &parent_pol, subkey_name) : False;
594
595         /* flush the modified key */
596         res4 = res4 ? do_reg_flush_key(smb_cli, &parent_pol) : False;
597
598         /* close the key handle */
599         if ((*key_name) != 0)
600         {
601                 res3 = res3 ? do_reg_close(smb_cli, &parent_pol) : False;
602         }
603
604         /* close the registry handles */
605         res  = res  ? do_reg_close(smb_cli, &info->dom.reg_pol_connect) : False;
606
607         /* close the session */
608         cli_nt_session_close(smb_cli);
609
610         if (res && res3 && res4)
611         {
612                 DEBUG(5,("cmd_reg_delete_key: query succeeded\n"));
613                 fprintf(out_hnd,"OK\n");
614         }
615         else
616         {
617                 DEBUG(5,("cmd_reg_delete_key: query failed\n"));
618         }
619 }
620
621 /****************************************************************************
622 nt registry create key
623 ****************************************************************************/
624 static void cmd_reg_create_key(struct client_info *info)
625 {
626         BOOL res = True;
627         BOOL res3 = True;
628         BOOL res4 = True;
629
630         POLICY_HND parent_pol;
631         POLICY_HND key_pol;
632         fstring full_keyname;
633         fstring parent_key;
634         fstring parent_name;
635         fstring key_name;
636         fstring key_class;
637         SEC_ACCESS sam_access;
638
639         DEBUG(5, ("cmd_reg_create_key: smb_cli->fd:%d\n", smb_cli->fd));
640
641         if (!next_token_nr(NULL, full_keyname, NULL, sizeof(full_keyname)))
642         {
643                 fprintf(out_hnd, "regcreate <key_name> [key_class]\n");
644                 return;
645         }
646
647         reg_get_subkey(full_keyname, parent_key, key_name);
648
649         if (parent_key[0] == 0 || key_name[0] == 0)
650         {
651                 fprintf(out_hnd, "invalid key name\n");
652                 return;
653         }
654         
655         if (!next_token_nr(NULL, key_class, NULL, sizeof(key_class)))
656         {
657                 memset(key_class, 0, sizeof(key_class));
658         }
659
660         /* set access permissions */
661         sam_access.mask = SEC_RIGHTS_READ;
662
663         /* open WINREG session. */
664         res = res ? cli_nt_session_open(smb_cli, PIPE_WINREG) : False;
665
666         /* open registry receive a policy handle */
667         res = res ? do_reg_connect(smb_cli, parent_key, parent_name,
668                                 &info->dom.reg_pol_connect) : False;
669
670         if ((*parent_name) != 0)
671         {
672                 /* open an entry */
673                 res3 = res  ? do_reg_open_entry(smb_cli, &info->dom.reg_pol_connect,
674                                          parent_name, 0x02000000, &parent_pol) : False;
675         }
676         else
677         {
678                 memcpy(&parent_pol, &info->dom.reg_pol_connect, sizeof(parent_pol));
679         }
680
681         /* create an entry */
682         res4 = res3 ? do_reg_create_key(smb_cli, &parent_pol,
683                                  key_name, key_class, &sam_access, &key_pol) : False;
684
685         /* flush the modified key */
686         res4 = res4 ? do_reg_flush_key(smb_cli, &parent_pol) : False;
687
688         /* close the key handle */
689         res4 = res4 ? do_reg_close(smb_cli, &key_pol) : False;
690
691         /* close the key handle */
692         if ((*parent_name) != 0)
693         {
694                 res3 = res3 ? do_reg_close(smb_cli, &parent_pol) : False;
695         }
696
697         /* close the registry handles */
698         res  = res  ? do_reg_close(smb_cli, &info->dom.reg_pol_connect) : False;
699
700         /* close the session */
701         cli_nt_session_close(smb_cli);
702
703         if (res && res3 && res4)
704         {
705                 DEBUG(5,("cmd_reg_create_key: query succeeded\n"));
706                 fprintf(out_hnd,"OK\n");
707         }
708         else
709         {
710                 DEBUG(5,("cmd_reg_create_key: query failed\n"));
711         }
712 }
713
714 /****************************************************************************
715 nt registry security info
716 ****************************************************************************/
717 static void cmd_reg_test_key_sec(struct client_info *info)
718 {
719         BOOL res = True;
720         BOOL res3 = True;
721         BOOL res4 = True;
722
723         POLICY_HND key_pol;
724         fstring full_keyname;
725         fstring key_name;
726
727         /*
728          * security info
729          */
730
731         uint32 sec_buf_size;
732         SEC_DESC_BUF *psdb;
733
734         DEBUG(5, ("cmd_reg_get_key_sec: smb_cli->fd:%d\n", smb_cli->fd));
735
736         if (!next_token_nr(NULL, full_keyname, NULL, sizeof(full_keyname)))
737         {
738                 fprintf(out_hnd, "reggetsec <key_name>\n");
739                 return;
740         }
741
742         /* open WINREG session. */
743         res = res ? cli_nt_session_open(smb_cli, PIPE_WINREG) : False;
744
745         /* open registry receive a policy handle */
746         res = res ? do_reg_connect(smb_cli, full_keyname, key_name,
747                                 &info->dom.reg_pol_connect) : False;
748
749         if ((*key_name) != 0)
750         {
751                 /* open an entry */
752                 res3 = res  ? do_reg_open_entry(smb_cli, &info->dom.reg_pol_connect,
753                                          key_name, 0x02000000, &key_pol) : False;
754         }
755         else
756         {
757                 memcpy(&key_pol, &info->dom.reg_pol_connect, sizeof(key_pol));
758         }
759
760         /* open an entry */
761         res3 = res ? do_reg_open_entry(smb_cli, &info->dom.reg_pol_connect,
762                                  key_name, 0x02000000, &key_pol) : False;
763
764         /* query key sec info.  first call sets sec_buf_size. */
765
766         sec_buf_size = 0;
767         res4 = res3 ? do_reg_get_key_sec(smb_cli, &key_pol,
768                                 &sec_buf_size, &psdb) : False;
769         
770         free_sec_desc_buf(&psdb);
771
772         res4 = res4 ? do_reg_get_key_sec(smb_cli, &key_pol,
773                                 &sec_buf_size, &psdb) : False;
774
775         if (res4 && psdb->len > 0 && psdb->sec != NULL)
776         {
777                 display_sec_desc(out_hnd, ACTION_HEADER   , psdb->sec);
778                 display_sec_desc(out_hnd, ACTION_ENUMERATE, psdb->sec);
779                 display_sec_desc(out_hnd, ACTION_FOOTER   , psdb->sec);
780
781                 res4 = res4 ? do_reg_set_key_sec(smb_cli, &key_pol, psdb) : False;
782         }
783
784         free_sec_desc_buf(&psdb);
785
786         /* close the key handle */
787         if ((*key_name) != 0)
788         {
789                 res3 = res3 ? do_reg_close(smb_cli, &key_pol) : False;
790         }
791
792         /* close the registry handles */
793         res  = res  ? do_reg_close(smb_cli, &info->dom.reg_pol_connect) : False;
794
795         /* close the session */
796         cli_nt_session_close(smb_cli);
797
798         if (res && res3 && res4)
799         {
800                 DEBUG(5,("cmd_reg_test2: query succeeded\n"));
801                 fprintf(out_hnd,"Registry Test2\n");
802         }
803         else
804         {
805                 DEBUG(5,("cmd_reg_test2: query failed\n"));
806         }
807 }
808
809 /****************************************************************************
810 nt registry security info
811 ****************************************************************************/
812 static void cmd_reg_get_key_sec(struct client_info *info)
813 {
814         BOOL res = True;
815         BOOL res3 = True;
816         BOOL res4 = True;
817
818         POLICY_HND key_pol;
819         fstring full_keyname;
820         fstring key_name;
821
822         /*
823          * security info
824          */
825
826         uint32 sec_buf_size;
827         SEC_DESC_BUF *psdb;
828
829         DEBUG(5, ("cmd_reg_get_key_sec: smb_cli->fd:%d\n", smb_cli->fd));
830
831         if (!next_token_nr(NULL, full_keyname, NULL, sizeof(full_keyname)))
832         {
833                 fprintf(out_hnd, "reggetsec <key_name>\n");
834                 return;
835         }
836
837         /* open WINREG session. */
838         res = res ? cli_nt_session_open(smb_cli, PIPE_WINREG) : False;
839
840         /* open registry receive a policy handle */
841         res = res ? do_reg_connect(smb_cli, full_keyname, key_name,
842                                 &info->dom.reg_pol_connect) : False;
843
844         if ((*key_name) != 0)
845         {
846                 /* open an entry */
847                 res3 = res  ? do_reg_open_entry(smb_cli, &info->dom.reg_pol_connect,
848                                          key_name, 0x02000000, &key_pol) : False;
849         }
850         else
851         {
852                 memcpy(&key_pol, &info->dom.reg_pol_connect, sizeof(key_pol));
853         }
854
855         /* open an entry */
856         res3 = res ? do_reg_open_entry(smb_cli, &info->dom.reg_pol_connect,
857                                  key_name, 0x02000000, &key_pol) : False;
858
859         /* Get the size. */
860         sec_buf_size = 0;
861         res4 = res3 ? do_reg_get_key_sec(smb_cli, &key_pol,
862                                 &sec_buf_size, &psdb) : False;
863         
864         free_sec_desc_buf(&psdb);
865
866         res4 = res4 ? do_reg_get_key_sec(smb_cli, &key_pol,
867                                 &sec_buf_size, &psdb) : False;
868
869         if (res4 && psdb->len > 0 && psdb->sec != NULL)
870         {
871                 display_sec_desc(out_hnd, ACTION_HEADER   , psdb->sec);
872                 display_sec_desc(out_hnd, ACTION_ENUMERATE, psdb->sec);
873                 display_sec_desc(out_hnd, ACTION_FOOTER   , psdb->sec);
874         }
875
876         free_sec_desc_buf(&psdb);
877
878         /* close the key handle */
879         if ((*key_name) != 0)
880         {
881                 res3 = res3 ? do_reg_close(smb_cli, &key_pol) : False;
882         }
883
884         /* close the registry handles */
885         res  = res  ? do_reg_close(smb_cli, &info->dom.reg_pol_connect) : False;
886
887         /* close the session */
888         cli_nt_session_close(smb_cli);
889
890         if (res && res3 && res4)
891         {
892                 DEBUG(5,("cmd_reg_get_key_sec: query succeeded\n"));
893         }
894         else
895         {
896                 DEBUG(5,("cmd_reg_get_key_sec: query failed\n"));
897         }
898 }
899
900 #endif /* 0 */
901
902 /****************************************************************************
903 nt registry shutdown
904 ****************************************************************************/
905 static NTSTATUS cmd_reg_shutdown(struct cli_state *cli, int argc, char **argv)
906 {
907         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
908         fstring msg;
909         uint32 timeout = 20;
910         uint16 flgs = 0;
911         int opt;
912         int ret;
913         char *srv_name;
914         TALLOC_CTX *mem_ctx;
915
916         ret = asprintf (&srv_name, "\\\\%s", cli->desthost);
917         if (ret < 0) {
918                 DEBUG(0,("cmd_reg_shutdown: Not enough memory!\n"));
919                 return NT_STATUS_UNSUCCESSFUL;
920         }
921         strupper(srv_name);
922
923         if (!(mem_ctx=talloc_init()))
924         {
925                 DEBUG(0,("cmd_spoolss_getprinter: talloc_init returned NULL!\n"));
926                 return NT_STATUS_UNSUCCESSFUL;
927         }
928         
929         /* Initialise RPC connection */
930         if (!cli_nt_session_open (cli, PIPE_WINREG)) {
931                 fprintf (stderr, "Could not initialize winreg pipe!\n");
932                 goto done;
933         }
934                         
935         *msg = 0;
936         optind = 0; /* TODO: test if this hack works on other systems too --simo */
937
938         while ((opt = getopt(argc, argv, "m:t:rf")) != EOF)
939         {
940                 fprintf (stderr, "[%s]\n", argv[argc-1]);
941         
942                 switch (opt)
943                 {
944                         case 'm':
945                         {
946                                 safe_strcpy(msg, optarg, sizeof(msg)-1);
947                                 fprintf (stderr, "[%s|%s]\n", optarg, msg);
948                                 break;
949                         }
950                         case 't':
951                         {
952                                 timeout = atoi(optarg);
953                                 fprintf (stderr, "[%s|%d]\n", optarg, timeout);
954                         break;
955                         }
956                         case 'r':
957                         {
958                                 flgs |= 0x100;
959                         break;
960                         }
961                         case 'f':
962                         {
963                                 flgs |= 0x001;
964                                 break;
965                         }
966                 }
967         }
968
969         /* create an entry */
970         result = cli_reg_shutdown(cli, mem_ctx, srv_name, msg, timeout, flgs);
971
972         if (NT_STATUS_IS_OK(result))
973                 DEBUG(5,("cmd_reg_shutdown: query succeeded\n"));
974         else
975                 DEBUG(5,("cmd_reg_shutdown: query failed\n"));
976
977         cli_nt_session_close(cli);
978
979 done:
980         talloc_destroy(mem_ctx);
981                         
982         return result;
983 }
984
985 /****************************************************************************
986 abort a shutdown
987 ****************************************************************************/
988 static NTSTATUS cmd_reg_abort_shutdown(struct cli_state *cli, int argc, char **argv)
989 {
990         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
991         int ret;
992         char *srv_name;
993         TALLOC_CTX *mem_ctx;
994
995         ret = asprintf(&srv_name, "\\\\%s", cli->desthost);
996         if (ret < 0) {
997                 DEBUG(0,("cmd_reg_shutdown: Not enough memory!\n"));
998                 return NT_STATUS_UNSUCCESSFUL;
999         }
1000         strupper(srv_name);
1001
1002         if (!(mem_ctx=talloc_init()))
1003         {
1004                 DEBUG(0,("cmd_spoolss_getprinter: talloc_init returned NULL!\n"));
1005                 return NT_STATUS_UNSUCCESSFUL;
1006         }
1007         
1008         /* Initialise RPC connection */
1009         if (!cli_nt_session_open (cli, PIPE_WINREG)) {
1010                 fprintf (stderr, "Could not initialize winreg pipe!\n");
1011                 goto done;
1012         }
1013
1014         result = cli_reg_abort_shutdown(cli, mem_ctx, srv_name);
1015
1016         if (NT_STATUS_IS_OK(result))
1017                 DEBUG(5,("cmd_reg_abort_shutdown: query succeeded\n"));
1018         else
1019                 DEBUG(5,("cmd_reg_abort_shutdown: query failed\n"));
1020
1021         cli_nt_session_close(cli);
1022
1023 done:
1024         talloc_destroy(mem_ctx);
1025
1026         return result;
1027 }
1028
1029
1030 /* List of commands exported by this module */
1031 struct cmd_set reg_commands[] = {
1032
1033         { "REG"  },
1034
1035         { "shutdown",           cmd_reg_shutdown,               "Remote Shutdown",
1036                                 "[-m message] [-t timeout] [-r] [-f] (-r == reboot, -f == force)" },
1037                                 
1038         { "abortshutdown",      cmd_reg_abort_shutdown,         "Abort Shutdown",
1039                                 "" },                           
1040 /*
1041         { "regenum",            cmd_reg_enum,                   "Registry Enumeration",
1042                                 "<keyname>" },
1043                                 
1044         { "regdeletekey",       cmd_reg_delete_key,             "Registry Key Delete",
1045                                 "<keyname>" },
1046                                 
1047         { "regcreatekey",       cmd_reg_create_key,             "Registry Key Create",
1048                                 "<keyname> [keyclass]" },
1049                                 
1050         { "regqueryval",        cmd_reg_query_info,             "Registry Value Query",
1051                                 "<valname>" },
1052                                 
1053         { "regquerykey",        cmd_reg_query_key,              "Registry Key Query",
1054                                 "<keyname>" },
1055                                 
1056         { "regdeleteval",       cmd_reg_delete_val,             "Registry Value Delete",
1057                                 "<valname>" },
1058         
1059         { "regcreateval",       cmd_reg_create_val,             "Registry Key Create",
1060                                 "<valname> <valtype> <value>" },
1061         
1062         { "reggetsec",          cmd_reg_get_key_sec,            "Registry Key Security",
1063                                 "<keyname>" },
1064         
1065         { "regtestsec",         cmd_reg_test_key_sec,           "Test Registry Key Security",
1066                                 "<keyname>" },
1067 */
1068         { NULL }
1069 };