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