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