s3-net: add command rpc registry export
[bbaumbach/samba-autobuild/.git] / source3 / utils / net_rpc_registry.c
1 /* 
2    Samba Unix/Linux SMB client library 
3    Distributed SMB/CIFS Server Management Utility 
4
5    Copyright (C) Gerald (Jerry) Carter          2005-2006
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 3 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, see <http://www.gnu.org/licenses/>.  */
19  
20 #include "includes.h"
21 #include "popt_common.h"
22 #include "registry.h"
23 #include "utils/net.h"
24 #include "utils/net_registry_util.h"
25 #include "registry/regfio.h"
26 #include "../librpc/gen_ndr/cli_winreg.h"
27 #include "registry/reg_objects.h"
28 #include "../librpc/gen_ndr/ndr_security.h"
29 #include "registry/reg_format.h"
30 #include <assert.h>
31
32
33 /*******************************************************************
34  connect to a registry hive root (open a registry policy)
35 *******************************************************************/
36
37 static NTSTATUS rpccli_winreg_Connect(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
38                                       uint32_t reg_type, uint32_t access_mask,
39                                       struct policy_handle *reg_hnd, WERROR *werr)
40 {
41         ZERO_STRUCTP(reg_hnd);
42
43         switch (reg_type)
44         {
45         case HKEY_CLASSES_ROOT:
46                 return rpccli_winreg_OpenHKCR( cli, mem_ctx, NULL,
47                         access_mask, reg_hnd, werr);
48
49         case HKEY_LOCAL_MACHINE:
50                 return rpccli_winreg_OpenHKLM( cli, mem_ctx, NULL,
51                         access_mask, reg_hnd, werr);
52
53         case HKEY_USERS:
54                 return rpccli_winreg_OpenHKU( cli, mem_ctx, NULL,
55                         access_mask, reg_hnd, werr);
56
57         case HKEY_CURRENT_USER:
58                 return rpccli_winreg_OpenHKCU( cli, mem_ctx, NULL,
59                         access_mask, reg_hnd, werr);
60
61         case HKEY_PERFORMANCE_DATA:
62                 return rpccli_winreg_OpenHKPD( cli, mem_ctx, NULL,
63                         access_mask, reg_hnd, werr);
64
65         default:
66                 /* fall through to end of function */
67                 break;
68         }
69
70         return NT_STATUS_INVALID_PARAMETER;
71 }
72
73 static bool reg_hive_key(TALLOC_CTX *ctx, const char *fullname,
74                          uint32 *reg_type, const char **key_name)
75 {
76         WERROR werr;
77         char *hivename = NULL;
78         char *tmp_keyname = NULL;
79         bool ret = false;
80         TALLOC_CTX *tmp_ctx = talloc_stackframe();
81
82         werr = split_hive_key(tmp_ctx, fullname, &hivename, &tmp_keyname);
83         if (!W_ERROR_IS_OK(werr)) {
84                 goto done;
85         }
86
87         *key_name = talloc_strdup(ctx, tmp_keyname);
88         if (*key_name == NULL) {
89                 goto done;
90         }
91
92         if (strequal(hivename, "HKLM") ||
93             strequal(hivename, "HKEY_LOCAL_MACHINE"))
94         {
95                 (*reg_type) = HKEY_LOCAL_MACHINE;
96         } else if (strequal(hivename, "HKCR") ||
97                    strequal(hivename, "HKEY_CLASSES_ROOT"))
98         {
99                 (*reg_type) = HKEY_CLASSES_ROOT;
100         } else if (strequal(hivename, "HKU") ||
101                    strequal(hivename, "HKEY_USERS"))
102         {
103                 (*reg_type) = HKEY_USERS;
104         } else if (strequal(hivename, "HKCU") ||
105                    strequal(hivename, "HKEY_CURRENT_USER"))
106         {
107                 (*reg_type) = HKEY_CURRENT_USER;
108         } else if (strequal(hivename, "HKPD") ||
109                    strequal(hivename, "HKEY_PERFORMANCE_DATA"))
110         {
111                 (*reg_type) = HKEY_PERFORMANCE_DATA;
112         } else {
113                 DEBUG(10,("reg_hive_key: unrecognised hive key %s\n",
114                           fullname));
115                 goto done;
116         }
117
118         ret = true;
119
120 done:
121         TALLOC_FREE(tmp_ctx);
122         return ret;
123 }
124
125 static NTSTATUS registry_openkey(TALLOC_CTX *mem_ctx,
126                                  struct rpc_pipe_client *pipe_hnd,
127                                  const char *name, uint32 access_mask,
128                                  struct policy_handle *hive_hnd,
129                                  struct policy_handle *key_hnd)
130 {
131         uint32 hive;
132         NTSTATUS status;
133         struct winreg_String key;
134
135         ZERO_STRUCT(key);
136
137         if (!reg_hive_key(mem_ctx, name, &hive, &key.name)) {
138                 return NT_STATUS_INVALID_PARAMETER;
139         }
140
141         status = rpccli_winreg_Connect(pipe_hnd, mem_ctx, hive, access_mask,
142                                        hive_hnd, NULL);
143         if (!(NT_STATUS_IS_OK(status))) {
144                 return status;
145         }
146
147         status = rpccli_winreg_OpenKey(pipe_hnd, mem_ctx, hive_hnd, key, 0,
148                                        access_mask, key_hnd, NULL);
149         if (!(NT_STATUS_IS_OK(status))) {
150                 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, hive_hnd, NULL);
151                 return status;
152         }
153
154         return NT_STATUS_OK;
155 }
156
157 static NTSTATUS registry_enumkeys(TALLOC_CTX *ctx,
158                                   struct rpc_pipe_client *pipe_hnd,
159                                   struct policy_handle *key_hnd,
160                                   uint32 *pnum_keys, char ***pnames,
161                                   char ***pclasses, NTTIME ***pmodtimes)
162 {
163         TALLOC_CTX *mem_ctx;
164         NTSTATUS status;
165         uint32 num_subkeys, max_subkeylen, max_classlen;
166         uint32 num_values, max_valnamelen, max_valbufsize;
167         uint32 i;
168         NTTIME last_changed_time;
169         uint32 secdescsize;
170         struct winreg_String classname;
171         char **names, **classes;
172         NTTIME **modtimes;
173
174         if (!(mem_ctx = talloc_new(ctx))) {
175                 return NT_STATUS_NO_MEMORY;
176         }
177
178         ZERO_STRUCT(classname);
179         status = rpccli_winreg_QueryInfoKey(
180                 pipe_hnd, mem_ctx, key_hnd, &classname, &num_subkeys,
181                 &max_subkeylen, &max_classlen, &num_values, &max_valnamelen,
182                 &max_valbufsize, &secdescsize, &last_changed_time, NULL );
183
184         if (!NT_STATUS_IS_OK(status)) {
185                 goto error;
186         }
187
188         if (num_subkeys == 0) {
189                 *pnum_keys = 0;
190                 TALLOC_FREE(mem_ctx);
191                 return NT_STATUS_OK;
192         }
193
194         if ((!(names = TALLOC_ZERO_ARRAY(mem_ctx, char *, num_subkeys))) ||
195             (!(classes = TALLOC_ZERO_ARRAY(mem_ctx, char *, num_subkeys))) ||
196             (!(modtimes = TALLOC_ZERO_ARRAY(mem_ctx, NTTIME *,
197                                             num_subkeys)))) {
198                 status = NT_STATUS_NO_MEMORY;
199                 goto error;
200         }
201
202         for (i=0; i<num_subkeys; i++) {
203                 char c, n;
204                 struct winreg_StringBuf class_buf;
205                 struct winreg_StringBuf name_buf;
206                 NTTIME modtime;
207                 WERROR werr;
208
209                 c = '\0';
210                 class_buf.name = &c;
211                 class_buf.size = max_classlen+2;
212
213                 n = '\0';
214                 name_buf.name = &n;
215                 name_buf.size = max_subkeylen+2;
216
217                 ZERO_STRUCT(modtime);
218
219                 status = rpccli_winreg_EnumKey(pipe_hnd, mem_ctx, key_hnd,
220                                                i, &name_buf, &class_buf,
221                                                &modtime, &werr);
222
223                 if (W_ERROR_EQUAL(werr,
224                                   WERR_NO_MORE_ITEMS) ) {
225                         status = NT_STATUS_OK;
226                         break;
227                 }
228                 if (!NT_STATUS_IS_OK(status)) {
229                         goto error;
230                 }
231
232                 classes[i] = NULL;
233
234                 if (class_buf.name &&
235                     (!(classes[i] = talloc_strdup(classes, class_buf.name)))) {
236                         status = NT_STATUS_NO_MEMORY;
237                         goto error;
238                 }
239
240                 if (!(names[i] = talloc_strdup(names, name_buf.name))) {
241                         status = NT_STATUS_NO_MEMORY;
242                         goto error;
243                 }
244
245                 if ((!(modtimes[i] = (NTTIME *)talloc_memdup(
246                                modtimes, &modtime, sizeof(modtime))))) {
247                         status = NT_STATUS_NO_MEMORY;
248                         goto error;
249                 }
250         }
251
252         *pnum_keys = num_subkeys;
253
254         if (pnames) {
255                 *pnames = talloc_move(ctx, &names);
256         }
257         if (pclasses) {
258                 *pclasses = talloc_move(ctx, &classes);
259         }
260         if (pmodtimes) {
261                 *pmodtimes = talloc_move(ctx, &modtimes);
262         }
263
264         status = NT_STATUS_OK;
265
266  error:
267         TALLOC_FREE(mem_ctx);
268         return status;
269 }
270
271 static NTSTATUS registry_enumvalues(TALLOC_CTX *ctx,
272                                     struct rpc_pipe_client *pipe_hnd,
273                                     struct policy_handle *key_hnd,
274                                     uint32 *pnum_values, char ***pvalnames,
275                                     struct registry_value ***pvalues)
276 {
277         TALLOC_CTX *mem_ctx;
278         NTSTATUS status;
279         uint32 num_subkeys, max_subkeylen, max_classlen;
280         uint32 num_values, max_valnamelen, max_valbufsize;
281         uint32 i;
282         NTTIME last_changed_time;
283         uint32 secdescsize;
284         struct winreg_String classname;
285         struct registry_value **values;
286         char **names;
287
288         if (!(mem_ctx = talloc_new(ctx))) {
289                 return NT_STATUS_NO_MEMORY;
290         }
291
292         ZERO_STRUCT(classname);
293         status = rpccli_winreg_QueryInfoKey(
294                 pipe_hnd, mem_ctx, key_hnd, &classname, &num_subkeys,
295                 &max_subkeylen, &max_classlen, &num_values, &max_valnamelen,
296                 &max_valbufsize, &secdescsize, &last_changed_time, NULL );
297
298         if (!NT_STATUS_IS_OK(status)) {
299                 goto error;
300         }
301
302         if (num_values == 0) {
303                 *pnum_values = 0;
304                 TALLOC_FREE(mem_ctx);
305                 return NT_STATUS_OK;
306         }
307
308         if ((!(names = TALLOC_ARRAY(mem_ctx, char *, num_values))) ||
309             (!(values = TALLOC_ARRAY(mem_ctx, struct registry_value *,
310                                      num_values)))) {
311                 status = NT_STATUS_NO_MEMORY;
312                 goto error;
313         }
314
315         for (i=0; i<num_values; i++) {
316                 enum winreg_Type type = REG_NONE;
317                 uint8 *data = NULL;
318                 uint32 data_size;
319                 uint32 value_length;
320
321                 char n;
322                 struct winreg_ValNameBuf name_buf;
323                 WERROR err;
324
325                 n = '\0';
326                 name_buf.name = &n;
327                 name_buf.size = max_valnamelen + 2;
328
329                 data_size = max_valbufsize;
330                 data = (uint8 *)TALLOC(mem_ctx, data_size);
331                 value_length = 0;
332
333                 status = rpccli_winreg_EnumValue(pipe_hnd, mem_ctx, key_hnd,
334                                                  i, &name_buf, &type,
335                                                  data, &data_size,
336                                                  &value_length, &err);
337
338                 if ( W_ERROR_EQUAL(err,
339                                    WERR_NO_MORE_ITEMS) ) {
340                         status = NT_STATUS_OK;
341                         break;
342                 }
343
344                 if (!(NT_STATUS_IS_OK(status))) {
345                         goto error;
346                 }
347
348                 if (name_buf.name == NULL) {
349                         status = NT_STATUS_INVALID_PARAMETER;
350                         goto error;
351                 }
352
353                 if (!(names[i] = talloc_strdup(names, name_buf.name))) {
354                         status = NT_STATUS_NO_MEMORY;
355                         goto error;
356                 }
357
358                 values[i] = talloc_zero(values, struct registry_value);
359                 if (values[i] == NULL) {
360                         status = NT_STATUS_NO_MEMORY;
361                         goto error;
362                 }
363
364                 values[i]->type = type;
365                 values[i]->data = data_blob_talloc(values[i], data, data_size);
366         }
367
368         *pnum_values = num_values;
369
370         if (pvalnames) {
371                 *pvalnames = talloc_move(ctx, &names);
372         }
373         if (pvalues) {
374                 *pvalues = talloc_move(ctx, &values);
375         }
376
377         status = NT_STATUS_OK;
378
379  error:
380         TALLOC_FREE(mem_ctx);
381         return status;
382 }
383
384 static NTSTATUS registry_enumvalues2(TALLOC_CTX *ctx,
385                                      struct rpc_pipe_client *pipe_hnd,
386                                      struct policy_handle *key_hnd,
387                                      uint32 *pnum_values, char ***pvalnames,
388                                      struct regval_blob ***pvalues)
389 {
390         TALLOC_CTX *mem_ctx;
391         NTSTATUS status;
392         uint32 num_subkeys, max_subkeylen, max_classlen;
393         uint32 num_values, max_valnamelen, max_valbufsize;
394         uint32 i;
395         NTTIME last_changed_time;
396         uint32 secdescsize;
397         struct winreg_String classname;
398         struct regval_blob **values;
399         char **names;
400
401         if (!(mem_ctx = talloc_new(ctx))) {
402                 return NT_STATUS_NO_MEMORY;
403         }
404
405         ZERO_STRUCT(classname);
406         status = rpccli_winreg_QueryInfoKey(
407                 pipe_hnd, mem_ctx, key_hnd, &classname, &num_subkeys,
408                 &max_subkeylen, &max_classlen, &num_values, &max_valnamelen,
409                 &max_valbufsize, &secdescsize, &last_changed_time, NULL );
410
411         if (!NT_STATUS_IS_OK(status)) {
412                 goto error;
413         }
414
415         if (num_values == 0) {
416                 *pnum_values = 0;
417                 TALLOC_FREE(mem_ctx);
418                 return NT_STATUS_OK;
419         }
420
421         if ((!(names = TALLOC_ARRAY(mem_ctx, char *, num_values))) ||
422             (!(values = TALLOC_ARRAY(mem_ctx, struct regval_blob *,
423                                      num_values)))) {
424                 status = NT_STATUS_NO_MEMORY;
425                 goto error;
426         }
427
428         for (i=0; i<num_values; i++) {
429                 enum winreg_Type type = REG_NONE;
430                 uint8 *data = NULL;
431                 uint32 data_size;
432                 uint32 value_length;
433
434                 char n;
435                 struct winreg_ValNameBuf name_buf;
436                 WERROR err;
437
438                 n = '\0';
439                 name_buf.name = &n;
440                 name_buf.size = max_valnamelen + 2;
441
442                 data_size = max_valbufsize;
443                 data = (uint8 *)TALLOC(mem_ctx, data_size);
444                 value_length = 0;
445
446                 status = rpccli_winreg_EnumValue(pipe_hnd, mem_ctx, key_hnd,
447                                                  i, &name_buf, &type,
448                                                  data, &data_size,
449                                                  &value_length, &err);
450
451                 if ( W_ERROR_EQUAL(err, WERR_NO_MORE_ITEMS) ) {
452                         status = NT_STATUS_OK;
453                         break;
454                 }
455
456                 if (!(NT_STATUS_IS_OK(status))) {
457                         goto error;
458                 }
459
460                 if (name_buf.name == NULL) {
461                         status = NT_STATUS_INVALID_PARAMETER;
462                         goto error;
463                 }
464
465                 if (!(names[i] = talloc_strdup(names, name_buf.name))) {
466                         status = NT_STATUS_NO_MEMORY;
467                         goto error;
468                 }
469
470                 assert(value_length<=data_size); //???
471
472                 values[i] = regval_compose(values,
473                                            name_buf.name,
474                                            type,
475                                            data, value_length);
476                 if (!values[i]) {
477                         status = NT_STATUS_NO_MEMORY;
478                         goto error;
479                 }
480         }
481
482         *pnum_values = num_values;
483
484         if (pvalnames) {
485                 *pvalnames = talloc_move(ctx, &names);
486         }
487         if (pvalues) {
488                 *pvalues = talloc_move(ctx, &values);
489         }
490
491         status = NT_STATUS_OK;
492
493  error:
494         TALLOC_FREE(mem_ctx);
495         return status;
496 }
497
498 static NTSTATUS registry_getsd(TALLOC_CTX *mem_ctx,
499                                struct rpc_pipe_client *pipe_hnd,
500                                struct policy_handle *key_hnd,
501                                uint32_t sec_info,
502                                struct KeySecurityData *sd)
503 {
504         return rpccli_winreg_GetKeySecurity(pipe_hnd, mem_ctx, key_hnd,
505                                             sec_info, sd, NULL);
506 }
507
508
509 static NTSTATUS registry_setvalue(TALLOC_CTX *mem_ctx,
510                                   struct rpc_pipe_client *pipe_hnd,
511                                   struct policy_handle *key_hnd,
512                                   const char *name,
513                                   const struct registry_value *value)
514 {
515         struct winreg_String name_string;
516         NTSTATUS result;
517
518         ZERO_STRUCT(name_string);
519
520         name_string.name = name;
521         result = rpccli_winreg_SetValue(pipe_hnd, mem_ctx, key_hnd,
522                                         name_string, value->type,
523                                         value->data.data, value->data.length, NULL);
524         return result;
525 }
526
527 static NTSTATUS rpc_registry_setvalue_internal(struct net_context *c,
528                                                const struct dom_sid *domain_sid,
529                                                const char *domain_name,
530                                                struct cli_state *cli,
531                                                struct rpc_pipe_client *pipe_hnd,
532                                                TALLOC_CTX *mem_ctx,
533                                                int argc,
534                                                const char **argv )
535 {
536         struct policy_handle hive_hnd, key_hnd;
537         NTSTATUS status;
538         struct registry_value value;
539
540         status = registry_openkey(mem_ctx, pipe_hnd, argv[0],
541                                   SEC_FLAG_MAXIMUM_ALLOWED,
542                                   &hive_hnd, &key_hnd);
543         if (!NT_STATUS_IS_OK(status)) {
544                 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
545                           nt_errstr(status));
546                 return status;
547         }
548
549         if (!strequal(argv[2], "multi_sz") && (argc != 4)) {
550                 d_fprintf(stderr, _("Too many args for type %s\n"), argv[2]);
551                 return NT_STATUS_NOT_IMPLEMENTED;
552         }
553
554         if (strequal(argv[2], "dword")) {
555                 uint32_t v = strtoul(argv[3], NULL, 10);
556                 value.type = REG_DWORD;
557                 value.data = data_blob_talloc(mem_ctx, NULL, 4);
558                 SIVAL(value.data.data, 0, v);
559         }
560         else if (strequal(argv[2], "sz")) {
561                 value.type = REG_SZ;
562                 if (!push_reg_sz(mem_ctx, &value.data, argv[3])) {
563                         status = NT_STATUS_NO_MEMORY;
564                         goto error;
565                 }
566         }
567         else {
568                 d_fprintf(stderr, _("type \"%s\" not implemented\n"), argv[2]);
569                 status = NT_STATUS_NOT_IMPLEMENTED;
570                 goto error;
571         }
572
573         status = registry_setvalue(mem_ctx, pipe_hnd, &key_hnd,
574                                    argv[1], &value);
575
576         if (!NT_STATUS_IS_OK(status)) {
577                 d_fprintf(stderr, _("registry_setvalue failed: %s\n"),
578                           nt_errstr(status));
579         }
580
581  error:
582         rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &key_hnd, NULL);
583         rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd, NULL);
584
585         return NT_STATUS_OK;
586 }
587
588 static int rpc_registry_setvalue(struct net_context *c, int argc,
589                                  const char **argv )
590 {
591         if (argc < 4 || c->display_usage) {
592                 d_fprintf(stderr, "%s\n%s",
593                           _("Usage:"),
594                           _("net rpc registry setvalue <key> <valuename> "
595                             "<type> [<val>]+\n"));
596                 return -1;
597         }
598
599         return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
600                 rpc_registry_setvalue_internal, argc, argv );
601 }
602
603 static NTSTATUS rpc_registry_deletevalue_internal(struct net_context *c,
604                                                   const struct dom_sid *domain_sid,
605                                                   const char *domain_name,
606                                                   struct cli_state *cli,
607                                                   struct rpc_pipe_client *pipe_hnd,
608                                                   TALLOC_CTX *mem_ctx,
609                                                   int argc,
610                                                   const char **argv )
611 {
612         struct policy_handle hive_hnd, key_hnd;
613         NTSTATUS status;
614         struct winreg_String valuename;
615
616         ZERO_STRUCT(valuename);
617
618         status = registry_openkey(mem_ctx, pipe_hnd, argv[0],
619                                   SEC_FLAG_MAXIMUM_ALLOWED,
620                                   &hive_hnd, &key_hnd);
621         if (!NT_STATUS_IS_OK(status)) {
622                 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
623                           nt_errstr(status));
624                 return status;
625         }
626
627         valuename.name = argv[1];
628
629         status = rpccli_winreg_DeleteValue(pipe_hnd, mem_ctx, &key_hnd,
630                                            valuename, NULL);
631
632         if (!NT_STATUS_IS_OK(status)) {
633                 d_fprintf(stderr, _("registry_deletevalue failed: %s\n"),
634                           nt_errstr(status));
635         }
636
637         rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &key_hnd, NULL);
638         rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd, NULL);
639
640         return status;
641 }
642
643 static int rpc_registry_deletevalue(struct net_context *c, int argc,
644                                     const char **argv )
645 {
646         if (argc != 2 || c->display_usage) {
647                 d_fprintf(stderr, "%s\n%s",
648                           _("Usage:"),
649                           _("net rpc registry deletevalue <key> <valuename>\n"));
650                 return -1;
651         }
652
653         return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
654                 rpc_registry_deletevalue_internal, argc, argv );
655 }
656
657 static NTSTATUS rpc_registry_getvalue_internal(struct net_context *c,
658                                                const struct dom_sid *domain_sid,
659                                                const char *domain_name,
660                                                struct cli_state *cli,
661                                                struct rpc_pipe_client *pipe_hnd,
662                                                TALLOC_CTX *mem_ctx,
663                                                bool raw,
664                                                int argc,
665                                                const char **argv)
666 {
667         struct policy_handle hive_hnd, key_hnd;
668         NTSTATUS status;
669         struct winreg_String valuename;
670         struct registry_value *value = NULL;
671         enum winreg_Type type = REG_NONE;
672         uint32_t data_size = 0;
673         uint32_t value_length = 0;
674         TALLOC_CTX *tmp_ctx = talloc_stackframe();
675
676         ZERO_STRUCT(valuename);
677
678         status = registry_openkey(tmp_ctx, pipe_hnd, argv[0],
679                                   SEC_FLAG_MAXIMUM_ALLOWED,
680                                   &hive_hnd, &key_hnd);
681         if (!NT_STATUS_IS_OK(status)) {
682                 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
683                           nt_errstr(status));
684                 return status;
685         }
686
687         valuename.name = argv[1];
688
689         value = talloc_zero(tmp_ctx, struct registry_value);
690         if (value == NULL) {
691                 return NT_STATUS_NO_MEMORY;
692         }
693
694         /*
695          * call QueryValue once with data == NULL to get the
696          * needed memory size to be allocated, then allocate
697          * data buffer and call again.
698          */
699         status = rpccli_winreg_QueryValue(pipe_hnd, tmp_ctx, &key_hnd,
700                                           &valuename,
701                                           &type,
702                                           NULL,
703                                           &data_size,
704                                           &value_length,
705                                           NULL);
706
707         if (!NT_STATUS_IS_OK(status)) {
708                 d_fprintf(stderr, _("registry_queryvalue failed: %s\n"),
709                           nt_errstr(status));
710                 goto done;
711         }
712
713         value->data = data_blob_talloc(tmp_ctx, NULL, data_size);
714
715         status = rpccli_winreg_QueryValue(pipe_hnd, tmp_ctx, &key_hnd,
716                                           &valuename,
717                                           &type,
718                                           value->data.data,
719                                           &data_size,
720                                           &value_length,
721                                           NULL);
722
723         if (!NT_STATUS_IS_OK(status)) {
724                 d_fprintf(stderr, _("registry_queryvalue failed: %s\n"),
725                           nt_errstr(status));
726                 goto done;
727         }
728
729         value->type = type;
730
731         print_registry_value(value, raw);
732
733 done:
734         rpccli_winreg_CloseKey(pipe_hnd, tmp_ctx, &key_hnd, NULL);
735         rpccli_winreg_CloseKey(pipe_hnd, tmp_ctx, &hive_hnd, NULL);
736
737         TALLOC_FREE(tmp_ctx);
738
739         return status;
740 }
741
742 static NTSTATUS rpc_registry_getvalue_full(struct net_context *c,
743                                            const struct dom_sid *domain_sid,
744                                            const char *domain_name,
745                                            struct cli_state *cli,
746                                            struct rpc_pipe_client *pipe_hnd,
747                                            TALLOC_CTX *mem_ctx,
748                                            int argc,
749                                            const char **argv)
750 {
751         return rpc_registry_getvalue_internal(c, domain_sid, domain_name,
752                                               cli, pipe_hnd, mem_ctx, false,
753                                               argc, argv);
754 }
755
756 static int rpc_registry_getvalue(struct net_context *c, int argc,
757                                  const char **argv)
758 {
759         if (argc != 2 || c->display_usage) {
760                 d_fprintf(stderr, "%s\n%s",
761                           _("Usage:"),
762                           _("net rpc registry getvalue <key> <valuename>\n"));
763                 return -1;
764         }
765
766         return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
767                 rpc_registry_getvalue_full, argc, argv);
768 }
769
770 static NTSTATUS rpc_registry_getvalue_raw(struct net_context *c,
771                                           const struct dom_sid *domain_sid,
772                                           const char *domain_name,
773                                           struct cli_state *cli,
774                                           struct rpc_pipe_client *pipe_hnd,
775                                           TALLOC_CTX *mem_ctx,
776                                           int argc,
777                                           const char **argv)
778 {
779         return rpc_registry_getvalue_internal(c, domain_sid, domain_name,
780                                               cli, pipe_hnd, mem_ctx, true,
781                                               argc, argv);
782 }
783
784 static int rpc_registry_getvalueraw(struct net_context *c, int argc,
785                                     const char **argv)
786 {
787         if (argc != 2 || c->display_usage) {
788                 d_fprintf(stderr, "%s\n%s",
789                           _("Usage:"),
790                           _("net rpc registry getvalue <key> <valuename>\n"));
791                 return -1;
792         }
793
794         return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
795                 rpc_registry_getvalue_raw, argc, argv);
796 }
797
798 static NTSTATUS rpc_registry_createkey_internal(struct net_context *c,
799                                                 const struct dom_sid *domain_sid,
800                                                 const char *domain_name,
801                                                 struct cli_state *cli,
802                                                 struct rpc_pipe_client *pipe_hnd,
803                                                 TALLOC_CTX *mem_ctx,
804                                                 int argc,
805                                                 const char **argv )
806 {
807         uint32 hive;
808         struct policy_handle hive_hnd, key_hnd;
809         struct winreg_String key, keyclass;
810         enum winreg_CreateAction action;
811         NTSTATUS status;
812
813         ZERO_STRUCT(key);
814         ZERO_STRUCT(keyclass);
815
816         if (!reg_hive_key(mem_ctx, argv[0], &hive, &key.name)) {
817                 return NT_STATUS_INVALID_PARAMETER;
818         }
819
820         status = rpccli_winreg_Connect(pipe_hnd, mem_ctx, hive,
821                                        SEC_FLAG_MAXIMUM_ALLOWED,
822                                        &hive_hnd, NULL);
823         if (!(NT_STATUS_IS_OK(status))) {
824                 return status;
825         }
826
827         action = REG_ACTION_NONE;
828         keyclass.name = "";
829
830         status = rpccli_winreg_CreateKey(pipe_hnd, mem_ctx, &hive_hnd, key,
831                                          keyclass, 0, REG_KEY_READ, NULL,
832                                          &key_hnd, &action, NULL);
833         if (!NT_STATUS_IS_OK(status)) {
834                 d_fprintf(stderr, _("createkey returned %s\n"),
835                           nt_errstr(status));
836                 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd, NULL);
837                 return status;
838         }
839
840         switch (action) {
841                 case REG_ACTION_NONE:
842                         d_printf(_("createkey did nothing -- huh?\n"));
843                         break;
844                 case REG_CREATED_NEW_KEY:
845                         d_printf(_("createkey created %s\n"), argv[0]);
846                         break;
847                 case REG_OPENED_EXISTING_KEY:
848                         d_printf(_("createkey opened existing %s\n"), argv[0]);
849                         break;
850         }
851
852         rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &key_hnd, NULL);
853         rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd, NULL);
854
855         return status;
856 }
857
858 static int rpc_registry_createkey(struct net_context *c, int argc,
859                                   const char **argv )
860 {
861         if (argc != 1 || c->display_usage) {
862                 d_fprintf(stderr, "%s\n%s",
863                           _("Usage:"),
864                           _("net rpc registry createkey <key>\n"));
865                 return -1;
866         }
867
868         return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
869                 rpc_registry_createkey_internal, argc, argv );
870 }
871
872 static NTSTATUS rpc_registry_deletekey_internal(struct net_context *c,
873                                                 const struct dom_sid *domain_sid,
874                                                 const char *domain_name,
875                                                 struct cli_state *cli,
876                                                 struct rpc_pipe_client *pipe_hnd,
877                                                 TALLOC_CTX *mem_ctx,
878                                                 int argc,
879                                                 const char **argv )
880 {
881         uint32 hive;
882         struct policy_handle hive_hnd;
883         struct winreg_String key;
884         NTSTATUS status;
885
886         ZERO_STRUCT(key);
887
888         if (!reg_hive_key(mem_ctx, argv[0], &hive, &key.name)) {
889                 return NT_STATUS_INVALID_PARAMETER;
890         }
891
892         status = rpccli_winreg_Connect(pipe_hnd, mem_ctx, hive,
893                                        SEC_FLAG_MAXIMUM_ALLOWED,
894                                        &hive_hnd, NULL);
895         if (!(NT_STATUS_IS_OK(status))) {
896                 return status;
897         }
898
899         status = rpccli_winreg_DeleteKey(pipe_hnd, mem_ctx, &hive_hnd, key, NULL);
900         rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd, NULL);
901
902         if (!NT_STATUS_IS_OK(status)) {
903                 d_fprintf(stderr, _("deletekey returned %s\n"),
904                           nt_errstr(status));
905         }
906
907         return status;
908 }
909
910 static int rpc_registry_deletekey(struct net_context *c, int argc, const char **argv )
911 {
912         if (argc != 1 || c->display_usage) {
913                 d_fprintf(stderr, "%s\n%s",
914                           _("Usage:"),
915                           _("net rpc registry deletekey <key>\n"));
916                 return -1;
917         }
918
919         return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
920                 rpc_registry_deletekey_internal, argc, argv );
921 }
922
923 /********************************************************************
924 ********************************************************************/
925
926 static NTSTATUS rpc_registry_enumerate_internal(struct net_context *c,
927                                                 const struct dom_sid *domain_sid,
928                                                 const char *domain_name,
929                                                 struct cli_state *cli,
930                                                 struct rpc_pipe_client *pipe_hnd,
931                                                 TALLOC_CTX *mem_ctx,
932                                                 int argc,
933                                                 const char **argv )
934 {
935         struct policy_handle pol_hive, pol_key;
936         NTSTATUS status;
937         uint32 num_subkeys = 0;
938         uint32 num_values = 0;
939         char **names = NULL, **classes = NULL;
940         NTTIME **modtimes = NULL;
941         uint32 i;
942         struct registry_value **values = NULL;
943
944         if (argc != 1 || c->display_usage) {
945                 d_printf("%s\n%s",
946                          _("Usage:"),
947                          _("net rpc registry enumerate <path>\n"));
948                 d_printf("%s  net rpc registry enumerate "
949                          "'HKLM\\Software\\Samba'\n", _("Example:"));
950                 return NT_STATUS_INVALID_PARAMETER;
951         }
952
953         status = registry_openkey(mem_ctx, pipe_hnd, argv[0], REG_KEY_READ,
954                                   &pol_hive, &pol_key);
955         if (!NT_STATUS_IS_OK(status)) {
956                 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
957                           nt_errstr(status));
958                 return status;
959         }
960
961         status = registry_enumkeys(mem_ctx, pipe_hnd, &pol_key, &num_subkeys,
962                                    &names, &classes, &modtimes);
963         if (!NT_STATUS_IS_OK(status)) {
964                 d_fprintf(stderr, _("enumerating keys failed: %s\n"),
965                           nt_errstr(status));
966                 return status;
967         }
968
969         for (i=0; i<num_subkeys; i++) {
970                 print_registry_key(names[i], modtimes[i]);
971         }
972
973         status = registry_enumvalues(mem_ctx, pipe_hnd, &pol_key, &num_values,
974                                      &names, &values);
975         if (!NT_STATUS_IS_OK(status)) {
976                 d_fprintf(stderr, _("enumerating values failed: %s\n"),
977                           nt_errstr(status));
978                 return status;
979         }
980
981         for (i=0; i<num_values; i++) {
982                 print_registry_value_with_name(names[i], values[i]);
983         }
984
985         rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_key, NULL);
986         rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_hive, NULL);
987
988         return status;
989 }
990
991 /********************************************************************
992 ********************************************************************/
993
994 static int rpc_registry_enumerate(struct net_context *c, int argc,
995                                   const char **argv )
996 {
997         return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
998                 rpc_registry_enumerate_internal, argc, argv );
999 }
1000
1001 /********************************************************************
1002 ********************************************************************/
1003
1004 static NTSTATUS rpc_registry_save_internal(struct net_context *c,
1005                                         const struct dom_sid *domain_sid,
1006                                         const char *domain_name,
1007                                         struct cli_state *cli,
1008                                         struct rpc_pipe_client *pipe_hnd,
1009                                         TALLOC_CTX *mem_ctx,
1010                                         int argc,
1011                                         const char **argv )
1012 {
1013         WERROR result = WERR_GENERAL_FAILURE;
1014         struct policy_handle pol_hive, pol_key;
1015         NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
1016         struct winreg_String filename;
1017
1018         if (argc != 2 || c->display_usage) {
1019                 d_printf("%s\n%s",
1020                          _("Usage:"),
1021                          _("net rpc registry backup <path> <file> \n"));
1022                 return NT_STATUS_INVALID_PARAMETER;
1023         }
1024
1025         status = registry_openkey(mem_ctx, pipe_hnd, argv[0], REG_KEY_ALL,
1026                                   &pol_hive, &pol_key);
1027         if (!NT_STATUS_IS_OK(status)) {
1028                 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
1029                           nt_errstr(status));
1030                 return status;
1031         }
1032
1033         filename.name = argv[1];
1034         status = rpccli_winreg_SaveKey( pipe_hnd, mem_ctx, &pol_key, &filename, NULL, NULL);
1035         if ( !W_ERROR_IS_OK(result) ) {
1036                 d_fprintf(stderr, _("Unable to save [%s] to %s:%s\n"), argv[0],
1037                           cli->desthost, argv[1]);
1038         }
1039
1040         /* cleanup */
1041
1042         rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_key, NULL);
1043         rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_hive, NULL);
1044
1045         return status;
1046 }
1047
1048 /********************************************************************
1049 ********************************************************************/
1050
1051 static int rpc_registry_save(struct net_context *c, int argc, const char **argv )
1052 {
1053         return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
1054                 rpc_registry_save_internal, argc, argv );
1055 }
1056
1057
1058 /********************************************************************
1059 ********************************************************************/
1060
1061 static void dump_values( REGF_NK_REC *nk )
1062 {
1063         int i, j;
1064         const char *data_str = NULL;
1065         uint32 data_size, data;
1066         DATA_BLOB blob;
1067
1068         if ( !nk->values )
1069                 return;
1070
1071         for ( i=0; i<nk->num_values; i++ ) {
1072                 d_printf( "\"%s\" = ", nk->values[i].valuename ? nk->values[i].valuename : "(default)" );
1073                 d_printf( "(%s) ", str_regtype( nk->values[i].type ) );
1074
1075                 data_size = nk->values[i].data_size & ~VK_DATA_IN_OFFSET;
1076                 switch ( nk->values[i].type ) {
1077                         case REG_SZ:
1078                                 blob = data_blob_const(nk->values[i].data, data_size);
1079                                 pull_reg_sz(talloc_tos(), &blob, &data_str);
1080                                 if (!data_str) {
1081                                         break;
1082                                 }
1083                                 d_printf( "%s", data_str );
1084                                 break;
1085                         case REG_MULTI_SZ:
1086                         case REG_EXPAND_SZ:
1087                                 for ( j=0; j<data_size; j++ ) {
1088                                         d_printf( "%c", nk->values[i].data[j] );
1089                                 }
1090                                 break;
1091                         case REG_DWORD:
1092                                 data = IVAL( nk->values[i].data, 0 );
1093                                 d_printf("0x%x", data );
1094                                 break;
1095                         case REG_BINARY:
1096                                 for ( j=0; j<data_size; j++ ) {
1097                                         d_printf( "%x", nk->values[i].data[j] );
1098                                 }
1099                                 break;
1100                         default:
1101                                 d_printf(_("unknown"));
1102                                 break;
1103                 }
1104
1105                 d_printf( "\n" );
1106         }
1107
1108 }
1109
1110 /********************************************************************
1111 ********************************************************************/
1112
1113 static bool dump_registry_tree( REGF_FILE *file, REGF_NK_REC *nk, const char *parent )
1114 {
1115         REGF_NK_REC *key;
1116
1117         /* depth first dump of the registry tree */
1118
1119         while ( (key = regfio_fetch_subkey( file, nk )) ) {
1120                 char *regpath;
1121                 if (asprintf(&regpath, "%s\\%s", parent, key->keyname) < 0) {
1122                         break;
1123                 }
1124                 d_printf("[%s]\n", regpath );
1125                 dump_values( key );
1126                 d_printf("\n");
1127                 dump_registry_tree( file, key, regpath );
1128                 SAFE_FREE(regpath);
1129         }
1130
1131         return true;
1132 }
1133
1134 /********************************************************************
1135 ********************************************************************/
1136
1137 static bool write_registry_tree( REGF_FILE *infile, REGF_NK_REC *nk,
1138                                  REGF_NK_REC *parent, REGF_FILE *outfile,
1139                                  const char *parentpath )
1140 {
1141         REGF_NK_REC *key, *subkey;
1142         struct regval_ctr *values = NULL;
1143         struct regsubkey_ctr *subkeys = NULL;
1144         int i;
1145         char *path = NULL;
1146         WERROR werr;
1147
1148         werr = regsubkey_ctr_init(infile->mem_ctx, &subkeys);
1149         if (!W_ERROR_IS_OK(werr)) {
1150                 DEBUG(0, ("write_registry_tree: regsubkey_ctr_init failed: "
1151                           "%s\n", win_errstr(werr)));
1152                 return false;
1153         }
1154
1155         werr = regval_ctr_init(subkeys, &values);
1156         if (!W_ERROR_IS_OK(werr)) {
1157                 DEBUG(0,("write_registry_tree: talloc() failed!\n"));
1158                 TALLOC_FREE(subkeys);
1159                 return false;
1160         }
1161
1162         /* copy values into the struct regval_ctr */
1163
1164         for ( i=0; i<nk->num_values; i++ ) {
1165                 regval_ctr_addvalue( values, nk->values[i].valuename, nk->values[i].type,
1166                         nk->values[i].data, (nk->values[i].data_size & ~VK_DATA_IN_OFFSET) );
1167         }
1168
1169         /* copy subkeys into the struct regsubkey_ctr */
1170
1171         while ( (subkey = regfio_fetch_subkey( infile, nk )) ) {
1172                 regsubkey_ctr_addkey( subkeys, subkey->keyname );
1173         }
1174
1175         key = regfio_write_key( outfile, nk->keyname, values, subkeys, nk->sec_desc->sec_desc, parent );
1176
1177         /* write each one of the subkeys out */
1178
1179         path = talloc_asprintf(subkeys,
1180                         "%s%s%s",
1181                         parentpath,
1182                         parent ? "\\" : "",
1183                         nk->keyname);
1184         if (!path) {
1185                 TALLOC_FREE(subkeys);
1186                 return false;
1187         }
1188
1189         nk->subkey_index = 0;
1190         while ( (subkey = regfio_fetch_subkey( infile, nk )) ) {
1191                 write_registry_tree( infile, subkey, key, outfile, path );
1192         }
1193
1194         d_printf("[%s]\n", path );
1195         TALLOC_FREE(subkeys);
1196
1197         return true;
1198 }
1199
1200 /********************************************************************
1201 ********************************************************************/
1202
1203 static int rpc_registry_dump(struct net_context *c, int argc, const char **argv)
1204 {
1205         REGF_FILE   *registry;
1206         REGF_NK_REC *nk;
1207
1208         if (argc != 1 || c->display_usage) {
1209                 d_printf("%s\n%s",
1210                          _("Usage:"),
1211                          _("net rpc registry dump <file> \n"));
1212                 return -1;
1213         }
1214
1215         d_printf(_("Opening %s...."), argv[0]);
1216         if ( !(registry = regfio_open( argv[0], O_RDONLY, 0)) ) {
1217                 d_fprintf(stderr, _("Failed to open %s for reading\n"),argv[0]);
1218                 return 1;
1219         }
1220         d_printf(_("ok\n"));
1221
1222         /* get the root of the registry file */
1223
1224         if ((nk = regfio_rootkey( registry )) == NULL) {
1225                 d_fprintf(stderr, _("Could not get rootkey\n"));
1226                 regfio_close( registry );
1227                 return 1;
1228         }
1229         d_printf("[%s]\n", nk->keyname);
1230         dump_values( nk );
1231         d_printf("\n");
1232
1233         dump_registry_tree( registry, nk, nk->keyname );
1234
1235 #if 0
1236         talloc_report_full( registry->mem_ctx, stderr );
1237 #endif
1238         d_printf(_("Closing registry..."));
1239         regfio_close( registry );
1240         d_printf(_("ok\n"));
1241
1242         return 0;
1243 }
1244
1245 /********************************************************************
1246 ********************************************************************/
1247
1248 static int rpc_registry_copy(struct net_context *c, int argc, const char **argv )
1249 {
1250         REGF_FILE   *infile = NULL, *outfile = NULL;
1251         REGF_NK_REC *nk;
1252         int result = 1;
1253
1254         if (argc != 2 || c->display_usage) {
1255                 d_printf("%s\n%s",
1256                          _("Usage:"),
1257                          _("net rpc registry copy <srcfile> <newfile>\n"));
1258                 return -1;
1259         }
1260
1261         d_printf(_("Opening %s...."), argv[0]);
1262         if ( !(infile = regfio_open( argv[0], O_RDONLY, 0 )) ) {
1263                 d_fprintf(stderr, _("Failed to open %s for reading\n"),argv[0]);
1264                 return 1;
1265         }
1266         d_printf(_("ok\n"));
1267
1268         d_printf(_("Opening %s...."), argv[1]);
1269         if ( !(outfile = regfio_open( argv[1], (O_RDWR|O_CREAT|O_TRUNC), (S_IREAD|S_IWRITE) )) ) {
1270                 d_fprintf(stderr, _("Failed to open %s for writing\n"),argv[1]);
1271                 goto out;
1272         }
1273         d_printf(_("ok\n"));
1274
1275         /* get the root of the registry file */
1276
1277         if ((nk = regfio_rootkey( infile )) == NULL) {
1278                 d_fprintf(stderr, _("Could not get rootkey\n"));
1279                 goto out;
1280         }
1281         d_printf(_("RootKey: [%s]\n"), nk->keyname);
1282
1283         write_registry_tree( infile, nk, NULL, outfile, "" );
1284
1285         result = 0;
1286
1287 out:
1288
1289         d_printf(_("Closing %s..."), argv[1]);
1290         if (outfile) {
1291                 regfio_close( outfile );
1292         }
1293         d_printf(_("ok\n"));
1294
1295         d_printf(_("Closing %s..."), argv[0]);
1296         if (infile) {
1297                 regfio_close( infile );
1298         }
1299         d_printf(_("ok\n"));
1300
1301         return( result);
1302 }
1303
1304 /********************************************************************
1305 ********************************************************************/
1306
1307 static NTSTATUS rpc_registry_getsd_internal(struct net_context *c,
1308                                             const struct dom_sid *domain_sid,
1309                                             const char *domain_name,
1310                                             struct cli_state *cli,
1311                                             struct rpc_pipe_client *pipe_hnd,
1312                                             TALLOC_CTX *mem_ctx,
1313                                             int argc,
1314                                             const char **argv)
1315 {
1316         struct policy_handle pol_hive, pol_key;
1317         NTSTATUS status;
1318         enum ndr_err_code ndr_err;
1319         struct KeySecurityData *sd = NULL;
1320         uint32_t sec_info;
1321         DATA_BLOB blob;
1322         struct security_descriptor sec_desc;
1323         uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED |
1324                                SEC_FLAG_SYSTEM_SECURITY;
1325
1326         if (argc <1 || argc > 2 || c->display_usage) {
1327                 d_printf("%s\n%s",
1328                          _("Usage:"),
1329                          _("net rpc registry getsd <path> <secinfo>\n"));
1330                 d_printf("%s  net rpc registry getsd "
1331                            "'HKLM\\Software\\Samba'\n", _("Example:"));
1332                 return NT_STATUS_INVALID_PARAMETER;
1333         }
1334
1335         status = registry_openkey(mem_ctx, pipe_hnd, argv[0],
1336                                   access_mask,
1337                                   &pol_hive, &pol_key);
1338         if (!NT_STATUS_IS_OK(status)) {
1339                 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
1340                           nt_errstr(status));
1341                 return status;
1342         }
1343
1344         sd = TALLOC_ZERO_P(mem_ctx, struct KeySecurityData);
1345         if (!sd) {
1346                 status = NT_STATUS_NO_MEMORY;
1347                 goto out;
1348         }
1349
1350         sd->size = 0x1000;
1351
1352         if (argc >= 2) {
1353                 sscanf(argv[1], "%x", &sec_info);
1354         } else {
1355                 sec_info = SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL;
1356         }
1357
1358         status = registry_getsd(mem_ctx, pipe_hnd, &pol_key, sec_info, sd);
1359         if (!NT_STATUS_IS_OK(status)) {
1360                 d_fprintf(stderr, _("getting sd failed: %s\n"),
1361                           nt_errstr(status));
1362                 goto out;
1363         }
1364
1365         blob.data = sd->data;
1366         blob.length = sd->size;
1367
1368         ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &sec_desc,
1369                                        (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
1370         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1371                 status = ndr_map_error2ntstatus(ndr_err);
1372                 goto out;
1373         }
1374         status = NT_STATUS_OK;
1375
1376         display_sec_desc(&sec_desc);
1377
1378  out:
1379         rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_key, NULL);
1380         rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_hive, NULL);
1381
1382         return status;
1383 }
1384
1385
1386 static int rpc_registry_getsd(struct net_context *c, int argc, const char **argv)
1387 {
1388         return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
1389                 rpc_registry_getsd_internal, argc, argv);
1390 }
1391
1392 /********************************************************************
1393  ********************************************************************/
1394 /**
1395  * @defgroup net_rpc_registry net rpc registry
1396  */
1397
1398 /**
1399  * @defgroup net_rpc_registry_export Export
1400  * @ingroup net_rpc_registry
1401  * @{
1402  */
1403
1404 static NTSTATUS registry_export(struct rpc_pipe_client* pipe_hnd,
1405                                 TALLOC_CTX* ctx,
1406                                 struct policy_handle* key_hnd,
1407                                 struct reg_format* f,
1408                                 const char* parentfullname,
1409                                 const char* name)
1410 {
1411         NTSTATUS status;
1412         uint32 num_subkeys = 0;
1413         uint32 num_values = 0;
1414         char **names = NULL, **classes = NULL;
1415         NTTIME **modtimes = NULL;
1416         struct regval_blob **values = NULL;
1417         uint32 i;
1418
1419         TALLOC_CTX* mem_ctx = talloc_new(ctx);
1420
1421
1422         const char* fullname = name
1423                 ? talloc_asprintf(mem_ctx, "%s\\%s", parentfullname, name)
1424                 : parentfullname;
1425         reg_format_key(f, &fullname, 1, false);
1426
1427         status = registry_enumvalues2(mem_ctx, pipe_hnd, key_hnd, &num_values,
1428                                       &names, &values);
1429         if (!NT_STATUS_IS_OK(status)) {
1430                 d_fprintf(stderr, _("enumerating values failed: %s\n"),
1431                           nt_errstr(status));
1432                 goto done;
1433         }
1434
1435         for (i=0; i<num_values; i++) {
1436                 reg_format_regval_blob(f, names[i], values[i]);
1437         }
1438
1439
1440         status = registry_enumkeys(mem_ctx, pipe_hnd, key_hnd, &num_subkeys,
1441                                    &names, &classes, &modtimes);
1442         if (!NT_STATUS_IS_OK(status)) {
1443                 d_fprintf(stderr, _("enumerating keys failed: %s\n"),
1444                           nt_errstr(status));
1445                 goto done;
1446         }
1447
1448         for (i=0; i<num_subkeys; i++) {
1449                 struct policy_handle subkey_hnd;
1450                 struct winreg_String key;
1451                 ZERO_STRUCT(key);
1452                 /* key.name = talloc_strdup(mem_ctx, names[i]); ??? */
1453                 key.name = names[i];
1454
1455                 status = rpccli_winreg_OpenKey(pipe_hnd, mem_ctx, key_hnd, key,
1456                                                0, REG_KEY_READ,
1457                                                &subkey_hnd, NULL);
1458                 if (NT_STATUS_IS_OK(status)) {
1459                         status = registry_export(pipe_hnd, mem_ctx, &subkey_hnd,
1460                                                  f, fullname, names[i]);
1461                         if (!(NT_STATUS_IS_OK(status)))
1462                                 d_fprintf(stderr,
1463                                           _("export key failed: %s %s\n"),
1464                                           names[i], nt_errstr(status));
1465
1466                         rpccli_winreg_CloseKey(pipe_hnd, mem_ctx,
1467                                                &subkey_hnd, NULL);
1468                 } else {
1469                         d_fprintf(stderr,
1470                                   _("rpccli_winreg_OpenKey failed: %s %s\n"),
1471                                   names[i], nt_errstr(status));
1472                 }
1473         }
1474 done:
1475         talloc_free(mem_ctx);
1476         return status;
1477 }
1478
1479 static NTSTATUS rpc_registry_export_internal(struct net_context *c,
1480                                              const struct dom_sid *domain_sid,
1481                                              const char *domain_name,
1482                                              struct cli_state *cli,
1483                                              struct rpc_pipe_client *pipe_hnd,
1484                                              TALLOC_CTX *mem_ctx,
1485                                              int argc,
1486                                              const char **argv )
1487 {
1488         struct policy_handle pol_hive, pol_key;
1489         NTSTATUS status;
1490         struct reg_format* f;
1491
1492         if (argc < 2 || argc > 3 || c->display_usage) {
1493                 d_printf("%s\n%s",
1494                          _("Usage:"),
1495                          _("net rpc registry export <path> <file> [opt]\n"));
1496                 d_printf("%s  net rpc registry export "
1497                          "'HKLM\\Software\\Samba' samba.reg\n", _("Example:"));
1498                 return NT_STATUS_INVALID_PARAMETER;
1499         }
1500
1501         status = registry_openkey(mem_ctx, pipe_hnd, argv[0], REG_KEY_READ,
1502                                   &pol_hive, &pol_key);
1503         if (!NT_STATUS_IS_OK(status)) {
1504                 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
1505                           nt_errstr(status));
1506                 return status;
1507         }
1508
1509         f = reg_format_file(mem_ctx, argv[1], (argc > 2) ? argv[2] : NULL);
1510         if (f == NULL) {
1511                 d_fprintf(stderr, _("open file failed: %s\n"), strerror(errno));
1512                 return map_nt_error_from_unix(errno);
1513         }
1514
1515         status = registry_export(pipe_hnd, mem_ctx, &pol_key,
1516                                  f, argv[0], NULL );
1517         if (!NT_STATUS_IS_OK(status))
1518                 return status;
1519
1520         rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_key, NULL);
1521         rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_hive, NULL);
1522
1523         return status;
1524 }
1525 /********************************************************************
1526  ********************************************************************/
1527
1528 static int rpc_registry_export(struct net_context *c, int argc,
1529                                const char **argv )
1530 {
1531         return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
1532                                rpc_registry_export_internal, argc, argv );
1533 }
1534
1535 /**@}*/
1536
1537
1538 int net_rpc_registry(struct net_context *c, int argc, const char **argv)
1539 {
1540         struct functable func[] = {
1541                 {
1542                         "enumerate",
1543                         rpc_registry_enumerate,
1544                         NET_TRANSPORT_RPC,
1545                         N_("Enumerate registry keys and values"),
1546                         N_("net rpc registry enumerate\n"
1547                            "    Enumerate registry keys and values")
1548                 },
1549                 {
1550                         "createkey",
1551                         rpc_registry_createkey,
1552                         NET_TRANSPORT_RPC,
1553                         N_("Create a new registry key"),
1554                         N_("net rpc registry createkey\n"
1555                            "    Create a new registry key")
1556                 },
1557                 {
1558                         "deletekey",
1559                         rpc_registry_deletekey,
1560                         NET_TRANSPORT_RPC,
1561                         N_("Delete a registry key"),
1562                         N_("net rpc registry deletekey\n"
1563                            "    Delete a registry key")
1564                 },
1565                 {
1566                         "getvalue",
1567                         rpc_registry_getvalue,
1568                         NET_TRANSPORT_RPC,
1569                         N_("Print a registry value"),
1570                         N_("net rpc registry getvalue\n"
1571                            "    Print a registry value")
1572                 },
1573                 {
1574                         "getvalueraw",
1575                         rpc_registry_getvalueraw,
1576                         NET_TRANSPORT_RPC,
1577                         N_("Print a registry value"),
1578                         N_("net rpc registry getvalueraw\n"
1579                            "    Print a registry value (raw version)")
1580                 },
1581                 {
1582                         "setvalue",
1583                         rpc_registry_setvalue,
1584                         NET_TRANSPORT_RPC,
1585                         N_("Set a new registry value"),
1586                         N_("net rpc registry setvalue\n"
1587                            "    Set a new registry value")
1588                 },
1589                 {
1590                         "deletevalue",
1591                         rpc_registry_deletevalue,
1592                         NET_TRANSPORT_RPC,
1593                         N_("Delete a registry value"),
1594                         N_("net rpc registry deletevalue\n"
1595                            "    Delete a registry value")
1596                 },
1597                 {
1598                         "save",
1599                         rpc_registry_save,
1600                         NET_TRANSPORT_RPC,
1601                         N_("Save a registry file"),
1602                         N_("net rpc registry save\n"
1603                            "    Save a registry file")
1604                 },
1605                 {
1606                         "dump",
1607                         rpc_registry_dump,
1608                         NET_TRANSPORT_RPC,
1609                         N_("Dump a registry file"),
1610                         N_("net rpc registry dump\n"
1611                            "    Dump a registry file")
1612                 },
1613                 {
1614                         "copy",
1615                         rpc_registry_copy,
1616                         NET_TRANSPORT_RPC,
1617                         N_("Copy a registry file"),
1618                         N_("net rpc registry copy\n"
1619                            "    Copy a registry file")
1620                 },
1621                 {
1622                         "getsd",
1623                         rpc_registry_getsd,
1624                         NET_TRANSPORT_RPC,
1625                         N_("Get security descriptor"),
1626                         N_("net rpc registry getsd\n"
1627                            "    Get security descriptior")
1628                 },
1629                 {
1630                         "export",
1631                         rpc_registry_export,
1632                         NET_TRANSPORT_RPC,
1633                         N_("net registry export\n"
1634                            "    Export .reg file")
1635                 },
1636                 {NULL, NULL, 0, NULL, NULL}
1637         };
1638         return net_run_function(c, argc, argv, "net rpc registry", func);
1639 }