s3-net: add command rpc registry import
[Samba.git] / source3 / utils / net_rpc_registry.c
blobdbc3d5dfa2e8cbab5be378a43249cade20c782ee
1 /*
2 Samba Unix/Linux SMB client library
3 Distributed SMB/CIFS Server Management Utility
5 Copyright (C) Gerald (Jerry) Carter 2005-2006
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.
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.
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/>. */
20 #include "includes.h"
21 #include "popt_common.h"
22 #include "registry.h"
23 #include "utils/net.h"
24 #include "utils/net_registry_util.h"
25 #include "registry/regfio.h"
26 #include "../librpc/gen_ndr/cli_winreg.h"
27 #include "registry/reg_objects.h"
28 #include "../librpc/gen_ndr/ndr_security.h"
29 #include "registry/reg_format.h"
30 #include "registry/reg_import.h"
31 #include <assert.h>
34 /*******************************************************************
35 connect to a registry hive root (open a registry policy)
36 *******************************************************************/
38 static NTSTATUS rpccli_winreg_Connect(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
39 uint32_t reg_type, uint32_t access_mask,
40 struct policy_handle *reg_hnd, WERROR *werr)
42 ZERO_STRUCTP(reg_hnd);
44 switch (reg_type)
46 case HKEY_CLASSES_ROOT:
47 return rpccli_winreg_OpenHKCR( cli, mem_ctx, NULL,
48 access_mask, reg_hnd, werr);
50 case HKEY_LOCAL_MACHINE:
51 return rpccli_winreg_OpenHKLM( cli, mem_ctx, NULL,
52 access_mask, reg_hnd, werr);
54 case HKEY_USERS:
55 return rpccli_winreg_OpenHKU( cli, mem_ctx, NULL,
56 access_mask, reg_hnd, werr);
58 case HKEY_CURRENT_USER:
59 return rpccli_winreg_OpenHKCU( cli, mem_ctx, NULL,
60 access_mask, reg_hnd, werr);
62 case HKEY_PERFORMANCE_DATA:
63 return rpccli_winreg_OpenHKPD( cli, mem_ctx, NULL,
64 access_mask, reg_hnd, werr);
66 default:
67 /* fall through to end of function */
68 break;
71 return NT_STATUS_INVALID_PARAMETER;
74 static bool reg_hive_key(TALLOC_CTX *ctx, const char *fullname,
75 uint32 *reg_type, const char **key_name)
77 WERROR werr;
78 char *hivename = NULL;
79 char *tmp_keyname = NULL;
80 bool ret = false;
81 TALLOC_CTX *tmp_ctx = talloc_stackframe();
83 werr = split_hive_key(tmp_ctx, fullname, &hivename, &tmp_keyname);
84 if (!W_ERROR_IS_OK(werr)) {
85 goto done;
88 *key_name = talloc_strdup(ctx, tmp_keyname);
89 if (*key_name == NULL) {
90 goto done;
93 if (strequal(hivename, "HKLM") ||
94 strequal(hivename, "HKEY_LOCAL_MACHINE"))
96 (*reg_type) = HKEY_LOCAL_MACHINE;
97 } else if (strequal(hivename, "HKCR") ||
98 strequal(hivename, "HKEY_CLASSES_ROOT"))
100 (*reg_type) = HKEY_CLASSES_ROOT;
101 } else if (strequal(hivename, "HKU") ||
102 strequal(hivename, "HKEY_USERS"))
104 (*reg_type) = HKEY_USERS;
105 } else if (strequal(hivename, "HKCU") ||
106 strequal(hivename, "HKEY_CURRENT_USER"))
108 (*reg_type) = HKEY_CURRENT_USER;
109 } else if (strequal(hivename, "HKPD") ||
110 strequal(hivename, "HKEY_PERFORMANCE_DATA"))
112 (*reg_type) = HKEY_PERFORMANCE_DATA;
113 } else {
114 DEBUG(10,("reg_hive_key: unrecognised hive key %s\n",
115 fullname));
116 goto done;
119 ret = true;
121 done:
122 TALLOC_FREE(tmp_ctx);
123 return ret;
126 static NTSTATUS registry_openkey(TALLOC_CTX *mem_ctx,
127 struct rpc_pipe_client *pipe_hnd,
128 const char *name, uint32 access_mask,
129 struct policy_handle *hive_hnd,
130 struct policy_handle *key_hnd)
132 uint32 hive;
133 NTSTATUS status;
134 struct winreg_String key;
136 ZERO_STRUCT(key);
138 if (!reg_hive_key(mem_ctx, name, &hive, &key.name)) {
139 return NT_STATUS_INVALID_PARAMETER;
142 status = rpccli_winreg_Connect(pipe_hnd, mem_ctx, hive, access_mask,
143 hive_hnd, NULL);
144 if (!(NT_STATUS_IS_OK(status))) {
145 return status;
148 status = rpccli_winreg_OpenKey(pipe_hnd, mem_ctx, hive_hnd, key, 0,
149 access_mask, key_hnd, NULL);
150 if (!(NT_STATUS_IS_OK(status))) {
151 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, hive_hnd, NULL);
152 return status;
155 return NT_STATUS_OK;
158 static NTSTATUS registry_enumkeys(TALLOC_CTX *ctx,
159 struct rpc_pipe_client *pipe_hnd,
160 struct policy_handle *key_hnd,
161 uint32 *pnum_keys, char ***pnames,
162 char ***pclasses, NTTIME ***pmodtimes)
164 TALLOC_CTX *mem_ctx;
165 NTSTATUS status;
166 uint32 num_subkeys, max_subkeylen, max_classlen;
167 uint32 num_values, max_valnamelen, max_valbufsize;
168 uint32 i;
169 NTTIME last_changed_time;
170 uint32 secdescsize;
171 struct winreg_String classname;
172 char **names, **classes;
173 NTTIME **modtimes;
175 if (!(mem_ctx = talloc_new(ctx))) {
176 return NT_STATUS_NO_MEMORY;
179 ZERO_STRUCT(classname);
180 status = rpccli_winreg_QueryInfoKey(
181 pipe_hnd, mem_ctx, key_hnd, &classname, &num_subkeys,
182 &max_subkeylen, &max_classlen, &num_values, &max_valnamelen,
183 &max_valbufsize, &secdescsize, &last_changed_time, NULL );
185 if (!NT_STATUS_IS_OK(status)) {
186 goto error;
189 if (num_subkeys == 0) {
190 *pnum_keys = 0;
191 TALLOC_FREE(mem_ctx);
192 return NT_STATUS_OK;
195 if ((!(names = TALLOC_ZERO_ARRAY(mem_ctx, char *, num_subkeys))) ||
196 (!(classes = TALLOC_ZERO_ARRAY(mem_ctx, char *, num_subkeys))) ||
197 (!(modtimes = TALLOC_ZERO_ARRAY(mem_ctx, NTTIME *,
198 num_subkeys)))) {
199 status = NT_STATUS_NO_MEMORY;
200 goto error;
203 for (i=0; i<num_subkeys; i++) {
204 char c, n;
205 struct winreg_StringBuf class_buf;
206 struct winreg_StringBuf name_buf;
207 NTTIME modtime;
208 WERROR werr;
210 c = '\0';
211 class_buf.name = &c;
212 class_buf.size = max_classlen+2;
214 n = '\0';
215 name_buf.name = &n;
216 name_buf.size = max_subkeylen+2;
218 ZERO_STRUCT(modtime);
220 status = rpccli_winreg_EnumKey(pipe_hnd, mem_ctx, key_hnd,
221 i, &name_buf, &class_buf,
222 &modtime, &werr);
224 if (W_ERROR_EQUAL(werr,
225 WERR_NO_MORE_ITEMS) ) {
226 status = NT_STATUS_OK;
227 break;
229 if (!NT_STATUS_IS_OK(status)) {
230 goto error;
233 classes[i] = NULL;
235 if (class_buf.name &&
236 (!(classes[i] = talloc_strdup(classes, class_buf.name)))) {
237 status = NT_STATUS_NO_MEMORY;
238 goto error;
241 if (!(names[i] = talloc_strdup(names, name_buf.name))) {
242 status = NT_STATUS_NO_MEMORY;
243 goto error;
246 if ((!(modtimes[i] = (NTTIME *)talloc_memdup(
247 modtimes, &modtime, sizeof(modtime))))) {
248 status = NT_STATUS_NO_MEMORY;
249 goto error;
253 *pnum_keys = num_subkeys;
255 if (pnames) {
256 *pnames = talloc_move(ctx, &names);
258 if (pclasses) {
259 *pclasses = talloc_move(ctx, &classes);
261 if (pmodtimes) {
262 *pmodtimes = talloc_move(ctx, &modtimes);
265 status = NT_STATUS_OK;
267 error:
268 TALLOC_FREE(mem_ctx);
269 return status;
272 static NTSTATUS registry_enumvalues(TALLOC_CTX *ctx,
273 struct rpc_pipe_client *pipe_hnd,
274 struct policy_handle *key_hnd,
275 uint32 *pnum_values, char ***pvalnames,
276 struct registry_value ***pvalues)
278 TALLOC_CTX *mem_ctx;
279 NTSTATUS status;
280 uint32 num_subkeys, max_subkeylen, max_classlen;
281 uint32 num_values, max_valnamelen, max_valbufsize;
282 uint32 i;
283 NTTIME last_changed_time;
284 uint32 secdescsize;
285 struct winreg_String classname;
286 struct registry_value **values;
287 char **names;
289 if (!(mem_ctx = talloc_new(ctx))) {
290 return NT_STATUS_NO_MEMORY;
293 ZERO_STRUCT(classname);
294 status = rpccli_winreg_QueryInfoKey(
295 pipe_hnd, mem_ctx, key_hnd, &classname, &num_subkeys,
296 &max_subkeylen, &max_classlen, &num_values, &max_valnamelen,
297 &max_valbufsize, &secdescsize, &last_changed_time, NULL );
299 if (!NT_STATUS_IS_OK(status)) {
300 goto error;
303 if (num_values == 0) {
304 *pnum_values = 0;
305 TALLOC_FREE(mem_ctx);
306 return NT_STATUS_OK;
309 if ((!(names = TALLOC_ARRAY(mem_ctx, char *, num_values))) ||
310 (!(values = TALLOC_ARRAY(mem_ctx, struct registry_value *,
311 num_values)))) {
312 status = NT_STATUS_NO_MEMORY;
313 goto error;
316 for (i=0; i<num_values; i++) {
317 enum winreg_Type type = REG_NONE;
318 uint8 *data = NULL;
319 uint32 data_size;
320 uint32 value_length;
322 char n;
323 struct winreg_ValNameBuf name_buf;
324 WERROR err;
326 n = '\0';
327 name_buf.name = &n;
328 name_buf.size = max_valnamelen + 2;
330 data_size = max_valbufsize;
331 data = (uint8 *)TALLOC(mem_ctx, data_size);
332 value_length = 0;
334 status = rpccli_winreg_EnumValue(pipe_hnd, mem_ctx, key_hnd,
335 i, &name_buf, &type,
336 data, &data_size,
337 &value_length, &err);
339 if ( W_ERROR_EQUAL(err,
340 WERR_NO_MORE_ITEMS) ) {
341 status = NT_STATUS_OK;
342 break;
345 if (!(NT_STATUS_IS_OK(status))) {
346 goto error;
349 if (name_buf.name == NULL) {
350 status = NT_STATUS_INVALID_PARAMETER;
351 goto error;
354 if (!(names[i] = talloc_strdup(names, name_buf.name))) {
355 status = NT_STATUS_NO_MEMORY;
356 goto error;
359 values[i] = talloc_zero(values, struct registry_value);
360 if (values[i] == NULL) {
361 status = NT_STATUS_NO_MEMORY;
362 goto error;
365 values[i]->type = type;
366 values[i]->data = data_blob_talloc(values[i], data, data_size);
369 *pnum_values = num_values;
371 if (pvalnames) {
372 *pvalnames = talloc_move(ctx, &names);
374 if (pvalues) {
375 *pvalues = talloc_move(ctx, &values);
378 status = NT_STATUS_OK;
380 error:
381 TALLOC_FREE(mem_ctx);
382 return status;
385 static NTSTATUS registry_enumvalues2(TALLOC_CTX *ctx,
386 struct rpc_pipe_client *pipe_hnd,
387 struct policy_handle *key_hnd,
388 uint32 *pnum_values, char ***pvalnames,
389 struct regval_blob ***pvalues)
391 TALLOC_CTX *mem_ctx;
392 NTSTATUS status;
393 uint32 num_subkeys, max_subkeylen, max_classlen;
394 uint32 num_values, max_valnamelen, max_valbufsize;
395 uint32 i;
396 NTTIME last_changed_time;
397 uint32 secdescsize;
398 struct winreg_String classname;
399 struct regval_blob **values;
400 char **names;
402 if (!(mem_ctx = talloc_new(ctx))) {
403 return NT_STATUS_NO_MEMORY;
406 ZERO_STRUCT(classname);
407 status = rpccli_winreg_QueryInfoKey(
408 pipe_hnd, mem_ctx, key_hnd, &classname, &num_subkeys,
409 &max_subkeylen, &max_classlen, &num_values, &max_valnamelen,
410 &max_valbufsize, &secdescsize, &last_changed_time, NULL );
412 if (!NT_STATUS_IS_OK(status)) {
413 goto error;
416 if (num_values == 0) {
417 *pnum_values = 0;
418 TALLOC_FREE(mem_ctx);
419 return NT_STATUS_OK;
422 if ((!(names = TALLOC_ARRAY(mem_ctx, char *, num_values))) ||
423 (!(values = TALLOC_ARRAY(mem_ctx, struct regval_blob *,
424 num_values)))) {
425 status = NT_STATUS_NO_MEMORY;
426 goto error;
429 for (i=0; i<num_values; i++) {
430 enum winreg_Type type = REG_NONE;
431 uint8 *data = NULL;
432 uint32 data_size;
433 uint32 value_length;
435 char n;
436 struct winreg_ValNameBuf name_buf;
437 WERROR err;
439 n = '\0';
440 name_buf.name = &n;
441 name_buf.size = max_valnamelen + 2;
443 data_size = max_valbufsize;
444 data = (uint8 *)TALLOC(mem_ctx, data_size);
445 value_length = 0;
447 status = rpccli_winreg_EnumValue(pipe_hnd, mem_ctx, key_hnd,
448 i, &name_buf, &type,
449 data, &data_size,
450 &value_length, &err);
452 if ( W_ERROR_EQUAL(err, WERR_NO_MORE_ITEMS) ) {
453 status = NT_STATUS_OK;
454 break;
457 if (!(NT_STATUS_IS_OK(status))) {
458 goto error;
461 if (name_buf.name == NULL) {
462 status = NT_STATUS_INVALID_PARAMETER;
463 goto error;
466 if (!(names[i] = talloc_strdup(names, name_buf.name))) {
467 status = NT_STATUS_NO_MEMORY;
468 goto error;
471 assert(value_length<=data_size); //???
473 values[i] = regval_compose(values,
474 name_buf.name,
475 type,
476 data, value_length);
477 if (!values[i]) {
478 status = NT_STATUS_NO_MEMORY;
479 goto error;
483 *pnum_values = num_values;
485 if (pvalnames) {
486 *pvalnames = talloc_move(ctx, &names);
488 if (pvalues) {
489 *pvalues = talloc_move(ctx, &values);
492 status = NT_STATUS_OK;
494 error:
495 TALLOC_FREE(mem_ctx);
496 return status;
499 static NTSTATUS registry_getsd(TALLOC_CTX *mem_ctx,
500 struct rpc_pipe_client *pipe_hnd,
501 struct policy_handle *key_hnd,
502 uint32_t sec_info,
503 struct KeySecurityData *sd)
505 return rpccli_winreg_GetKeySecurity(pipe_hnd, mem_ctx, key_hnd,
506 sec_info, sd, NULL);
510 static NTSTATUS registry_setvalue(TALLOC_CTX *mem_ctx,
511 struct rpc_pipe_client *pipe_hnd,
512 struct policy_handle *key_hnd,
513 const char *name,
514 const struct registry_value *value)
516 struct winreg_String name_string;
517 NTSTATUS result;
519 ZERO_STRUCT(name_string);
521 name_string.name = name;
522 result = rpccli_winreg_SetValue(pipe_hnd, mem_ctx, key_hnd,
523 name_string, value->type,
524 value->data.data, value->data.length, NULL);
525 return result;
528 static NTSTATUS rpc_registry_setvalue_internal(struct net_context *c,
529 const struct dom_sid *domain_sid,
530 const char *domain_name,
531 struct cli_state *cli,
532 struct rpc_pipe_client *pipe_hnd,
533 TALLOC_CTX *mem_ctx,
534 int argc,
535 const char **argv )
537 struct policy_handle hive_hnd, key_hnd;
538 NTSTATUS status;
539 struct registry_value value;
541 status = registry_openkey(mem_ctx, pipe_hnd, argv[0],
542 SEC_FLAG_MAXIMUM_ALLOWED,
543 &hive_hnd, &key_hnd);
544 if (!NT_STATUS_IS_OK(status)) {
545 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
546 nt_errstr(status));
547 return status;
550 if (!strequal(argv[2], "multi_sz") && (argc != 4)) {
551 d_fprintf(stderr, _("Too many args for type %s\n"), argv[2]);
552 return NT_STATUS_NOT_IMPLEMENTED;
555 if (strequal(argv[2], "dword")) {
556 uint32_t v = strtoul(argv[3], NULL, 10);
557 value.type = REG_DWORD;
558 value.data = data_blob_talloc(mem_ctx, NULL, 4);
559 SIVAL(value.data.data, 0, v);
561 else if (strequal(argv[2], "sz")) {
562 value.type = REG_SZ;
563 if (!push_reg_sz(mem_ctx, &value.data, argv[3])) {
564 status = NT_STATUS_NO_MEMORY;
565 goto error;
568 else {
569 d_fprintf(stderr, _("type \"%s\" not implemented\n"), argv[2]);
570 status = NT_STATUS_NOT_IMPLEMENTED;
571 goto error;
574 status = registry_setvalue(mem_ctx, pipe_hnd, &key_hnd,
575 argv[1], &value);
577 if (!NT_STATUS_IS_OK(status)) {
578 d_fprintf(stderr, _("registry_setvalue failed: %s\n"),
579 nt_errstr(status));
582 error:
583 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &key_hnd, NULL);
584 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd, NULL);
586 return NT_STATUS_OK;
589 static int rpc_registry_setvalue(struct net_context *c, int argc,
590 const char **argv )
592 if (argc < 4 || c->display_usage) {
593 d_fprintf(stderr, "%s\n%s",
594 _("Usage:"),
595 _("net rpc registry setvalue <key> <valuename> "
596 "<type> [<val>]+\n"));
597 return -1;
600 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
601 rpc_registry_setvalue_internal, argc, argv );
604 static NTSTATUS rpc_registry_deletevalue_internal(struct net_context *c,
605 const struct dom_sid *domain_sid,
606 const char *domain_name,
607 struct cli_state *cli,
608 struct rpc_pipe_client *pipe_hnd,
609 TALLOC_CTX *mem_ctx,
610 int argc,
611 const char **argv )
613 struct policy_handle hive_hnd, key_hnd;
614 NTSTATUS status;
615 struct winreg_String valuename;
617 ZERO_STRUCT(valuename);
619 status = registry_openkey(mem_ctx, pipe_hnd, argv[0],
620 SEC_FLAG_MAXIMUM_ALLOWED,
621 &hive_hnd, &key_hnd);
622 if (!NT_STATUS_IS_OK(status)) {
623 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
624 nt_errstr(status));
625 return status;
628 valuename.name = argv[1];
630 status = rpccli_winreg_DeleteValue(pipe_hnd, mem_ctx, &key_hnd,
631 valuename, NULL);
633 if (!NT_STATUS_IS_OK(status)) {
634 d_fprintf(stderr, _("registry_deletevalue failed: %s\n"),
635 nt_errstr(status));
638 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &key_hnd, NULL);
639 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd, NULL);
641 return status;
644 static int rpc_registry_deletevalue(struct net_context *c, int argc,
645 const char **argv )
647 if (argc != 2 || c->display_usage) {
648 d_fprintf(stderr, "%s\n%s",
649 _("Usage:"),
650 _("net rpc registry deletevalue <key> <valuename>\n"));
651 return -1;
654 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
655 rpc_registry_deletevalue_internal, argc, argv );
658 static NTSTATUS rpc_registry_getvalue_internal(struct net_context *c,
659 const struct dom_sid *domain_sid,
660 const char *domain_name,
661 struct cli_state *cli,
662 struct rpc_pipe_client *pipe_hnd,
663 TALLOC_CTX *mem_ctx,
664 bool raw,
665 int argc,
666 const char **argv)
668 struct policy_handle hive_hnd, key_hnd;
669 NTSTATUS status;
670 struct winreg_String valuename;
671 struct registry_value *value = NULL;
672 enum winreg_Type type = REG_NONE;
673 uint32_t data_size = 0;
674 uint32_t value_length = 0;
675 TALLOC_CTX *tmp_ctx = talloc_stackframe();
677 ZERO_STRUCT(valuename);
679 status = registry_openkey(tmp_ctx, pipe_hnd, argv[0],
680 SEC_FLAG_MAXIMUM_ALLOWED,
681 &hive_hnd, &key_hnd);
682 if (!NT_STATUS_IS_OK(status)) {
683 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
684 nt_errstr(status));
685 return status;
688 valuename.name = argv[1];
690 value = talloc_zero(tmp_ctx, struct registry_value);
691 if (value == NULL) {
692 return NT_STATUS_NO_MEMORY;
696 * call QueryValue once with data == NULL to get the
697 * needed memory size to be allocated, then allocate
698 * data buffer and call again.
700 status = rpccli_winreg_QueryValue(pipe_hnd, tmp_ctx, &key_hnd,
701 &valuename,
702 &type,
703 NULL,
704 &data_size,
705 &value_length,
706 NULL);
708 if (!NT_STATUS_IS_OK(status)) {
709 d_fprintf(stderr, _("registry_queryvalue failed: %s\n"),
710 nt_errstr(status));
711 goto done;
714 value->data = data_blob_talloc(tmp_ctx, NULL, data_size);
716 status = rpccli_winreg_QueryValue(pipe_hnd, tmp_ctx, &key_hnd,
717 &valuename,
718 &type,
719 value->data.data,
720 &data_size,
721 &value_length,
722 NULL);
724 if (!NT_STATUS_IS_OK(status)) {
725 d_fprintf(stderr, _("registry_queryvalue failed: %s\n"),
726 nt_errstr(status));
727 goto done;
730 value->type = type;
732 print_registry_value(value, raw);
734 done:
735 rpccli_winreg_CloseKey(pipe_hnd, tmp_ctx, &key_hnd, NULL);
736 rpccli_winreg_CloseKey(pipe_hnd, tmp_ctx, &hive_hnd, NULL);
738 TALLOC_FREE(tmp_ctx);
740 return status;
743 static NTSTATUS rpc_registry_getvalue_full(struct net_context *c,
744 const struct dom_sid *domain_sid,
745 const char *domain_name,
746 struct cli_state *cli,
747 struct rpc_pipe_client *pipe_hnd,
748 TALLOC_CTX *mem_ctx,
749 int argc,
750 const char **argv)
752 return rpc_registry_getvalue_internal(c, domain_sid, domain_name,
753 cli, pipe_hnd, mem_ctx, false,
754 argc, argv);
757 static int rpc_registry_getvalue(struct net_context *c, int argc,
758 const char **argv)
760 if (argc != 2 || c->display_usage) {
761 d_fprintf(stderr, "%s\n%s",
762 _("Usage:"),
763 _("net rpc registry getvalue <key> <valuename>\n"));
764 return -1;
767 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
768 rpc_registry_getvalue_full, argc, argv);
771 static NTSTATUS rpc_registry_getvalue_raw(struct net_context *c,
772 const struct dom_sid *domain_sid,
773 const char *domain_name,
774 struct cli_state *cli,
775 struct rpc_pipe_client *pipe_hnd,
776 TALLOC_CTX *mem_ctx,
777 int argc,
778 const char **argv)
780 return rpc_registry_getvalue_internal(c, domain_sid, domain_name,
781 cli, pipe_hnd, mem_ctx, true,
782 argc, argv);
785 static int rpc_registry_getvalueraw(struct net_context *c, int argc,
786 const char **argv)
788 if (argc != 2 || c->display_usage) {
789 d_fprintf(stderr, "%s\n%s",
790 _("Usage:"),
791 _("net rpc registry getvalue <key> <valuename>\n"));
792 return -1;
795 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
796 rpc_registry_getvalue_raw, argc, argv);
799 static NTSTATUS rpc_registry_createkey_internal(struct net_context *c,
800 const struct dom_sid *domain_sid,
801 const char *domain_name,
802 struct cli_state *cli,
803 struct rpc_pipe_client *pipe_hnd,
804 TALLOC_CTX *mem_ctx,
805 int argc,
806 const char **argv )
808 uint32 hive;
809 struct policy_handle hive_hnd, key_hnd;
810 struct winreg_String key, keyclass;
811 enum winreg_CreateAction action;
812 NTSTATUS status;
814 ZERO_STRUCT(key);
815 ZERO_STRUCT(keyclass);
817 if (!reg_hive_key(mem_ctx, argv[0], &hive, &key.name)) {
818 return NT_STATUS_INVALID_PARAMETER;
821 status = rpccli_winreg_Connect(pipe_hnd, mem_ctx, hive,
822 SEC_FLAG_MAXIMUM_ALLOWED,
823 &hive_hnd, NULL);
824 if (!(NT_STATUS_IS_OK(status))) {
825 return status;
828 action = REG_ACTION_NONE;
829 keyclass.name = "";
831 status = rpccli_winreg_CreateKey(pipe_hnd, mem_ctx, &hive_hnd, key,
832 keyclass, 0, REG_KEY_READ, NULL,
833 &key_hnd, &action, NULL);
834 if (!NT_STATUS_IS_OK(status)) {
835 d_fprintf(stderr, _("createkey returned %s\n"),
836 nt_errstr(status));
837 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd, NULL);
838 return status;
841 switch (action) {
842 case REG_ACTION_NONE:
843 d_printf(_("createkey did nothing -- huh?\n"));
844 break;
845 case REG_CREATED_NEW_KEY:
846 d_printf(_("createkey created %s\n"), argv[0]);
847 break;
848 case REG_OPENED_EXISTING_KEY:
849 d_printf(_("createkey opened existing %s\n"), argv[0]);
850 break;
853 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &key_hnd, NULL);
854 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd, NULL);
856 return status;
859 static int rpc_registry_createkey(struct net_context *c, int argc,
860 const char **argv )
862 if (argc != 1 || c->display_usage) {
863 d_fprintf(stderr, "%s\n%s",
864 _("Usage:"),
865 _("net rpc registry createkey <key>\n"));
866 return -1;
869 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
870 rpc_registry_createkey_internal, argc, argv );
873 static NTSTATUS rpc_registry_deletekey_internal(struct net_context *c,
874 const struct dom_sid *domain_sid,
875 const char *domain_name,
876 struct cli_state *cli,
877 struct rpc_pipe_client *pipe_hnd,
878 TALLOC_CTX *mem_ctx,
879 int argc,
880 const char **argv )
882 uint32 hive;
883 struct policy_handle hive_hnd;
884 struct winreg_String key;
885 NTSTATUS status;
887 ZERO_STRUCT(key);
889 if (!reg_hive_key(mem_ctx, argv[0], &hive, &key.name)) {
890 return NT_STATUS_INVALID_PARAMETER;
893 status = rpccli_winreg_Connect(pipe_hnd, mem_ctx, hive,
894 SEC_FLAG_MAXIMUM_ALLOWED,
895 &hive_hnd, NULL);
896 if (!(NT_STATUS_IS_OK(status))) {
897 return status;
900 status = rpccli_winreg_DeleteKey(pipe_hnd, mem_ctx, &hive_hnd, key, NULL);
901 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd, NULL);
903 if (!NT_STATUS_IS_OK(status)) {
904 d_fprintf(stderr, _("deletekey returned %s\n"),
905 nt_errstr(status));
908 return status;
911 static int rpc_registry_deletekey(struct net_context *c, int argc, const char **argv )
913 if (argc != 1 || c->display_usage) {
914 d_fprintf(stderr, "%s\n%s",
915 _("Usage:"),
916 _("net rpc registry deletekey <key>\n"));
917 return -1;
920 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
921 rpc_registry_deletekey_internal, argc, argv );
924 /********************************************************************
925 ********************************************************************/
927 static NTSTATUS rpc_registry_enumerate_internal(struct net_context *c,
928 const struct dom_sid *domain_sid,
929 const char *domain_name,
930 struct cli_state *cli,
931 struct rpc_pipe_client *pipe_hnd,
932 TALLOC_CTX *mem_ctx,
933 int argc,
934 const char **argv )
936 struct policy_handle pol_hive, pol_key;
937 NTSTATUS status;
938 uint32 num_subkeys = 0;
939 uint32 num_values = 0;
940 char **names = NULL, **classes = NULL;
941 NTTIME **modtimes = NULL;
942 uint32 i;
943 struct registry_value **values = NULL;
945 if (argc != 1 || c->display_usage) {
946 d_printf("%s\n%s",
947 _("Usage:"),
948 _("net rpc registry enumerate <path>\n"));
949 d_printf("%s net rpc registry enumerate "
950 "'HKLM\\Software\\Samba'\n", _("Example:"));
951 return NT_STATUS_INVALID_PARAMETER;
954 status = registry_openkey(mem_ctx, pipe_hnd, argv[0], REG_KEY_READ,
955 &pol_hive, &pol_key);
956 if (!NT_STATUS_IS_OK(status)) {
957 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
958 nt_errstr(status));
959 return status;
962 status = registry_enumkeys(mem_ctx, pipe_hnd, &pol_key, &num_subkeys,
963 &names, &classes, &modtimes);
964 if (!NT_STATUS_IS_OK(status)) {
965 d_fprintf(stderr, _("enumerating keys failed: %s\n"),
966 nt_errstr(status));
967 return status;
970 for (i=0; i<num_subkeys; i++) {
971 print_registry_key(names[i], modtimes[i]);
974 status = registry_enumvalues(mem_ctx, pipe_hnd, &pol_key, &num_values,
975 &names, &values);
976 if (!NT_STATUS_IS_OK(status)) {
977 d_fprintf(stderr, _("enumerating values failed: %s\n"),
978 nt_errstr(status));
979 return status;
982 for (i=0; i<num_values; i++) {
983 print_registry_value_with_name(names[i], values[i]);
986 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_key, NULL);
987 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_hive, NULL);
989 return status;
992 /********************************************************************
993 ********************************************************************/
995 static int rpc_registry_enumerate(struct net_context *c, int argc,
996 const char **argv )
998 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
999 rpc_registry_enumerate_internal, argc, argv );
1002 /********************************************************************
1003 ********************************************************************/
1005 static NTSTATUS rpc_registry_save_internal(struct net_context *c,
1006 const struct dom_sid *domain_sid,
1007 const char *domain_name,
1008 struct cli_state *cli,
1009 struct rpc_pipe_client *pipe_hnd,
1010 TALLOC_CTX *mem_ctx,
1011 int argc,
1012 const char **argv )
1014 WERROR result = WERR_GENERAL_FAILURE;
1015 struct policy_handle pol_hive, pol_key;
1016 NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
1017 struct winreg_String filename;
1019 if (argc != 2 || c->display_usage) {
1020 d_printf("%s\n%s",
1021 _("Usage:"),
1022 _("net rpc registry backup <path> <file> \n"));
1023 return NT_STATUS_INVALID_PARAMETER;
1026 status = registry_openkey(mem_ctx, pipe_hnd, argv[0], REG_KEY_ALL,
1027 &pol_hive, &pol_key);
1028 if (!NT_STATUS_IS_OK(status)) {
1029 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
1030 nt_errstr(status));
1031 return status;
1034 filename.name = argv[1];
1035 status = rpccli_winreg_SaveKey( pipe_hnd, mem_ctx, &pol_key, &filename, NULL, NULL);
1036 if ( !W_ERROR_IS_OK(result) ) {
1037 d_fprintf(stderr, _("Unable to save [%s] to %s:%s\n"), argv[0],
1038 cli->desthost, argv[1]);
1041 /* cleanup */
1043 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_key, NULL);
1044 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_hive, NULL);
1046 return status;
1049 /********************************************************************
1050 ********************************************************************/
1052 static int rpc_registry_save(struct net_context *c, int argc, const char **argv )
1054 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
1055 rpc_registry_save_internal, argc, argv );
1059 /********************************************************************
1060 ********************************************************************/
1062 static void dump_values( REGF_NK_REC *nk )
1064 int i, j;
1065 const char *data_str = NULL;
1066 uint32 data_size, data;
1067 DATA_BLOB blob;
1069 if ( !nk->values )
1070 return;
1072 for ( i=0; i<nk->num_values; i++ ) {
1073 d_printf( "\"%s\" = ", nk->values[i].valuename ? nk->values[i].valuename : "(default)" );
1074 d_printf( "(%s) ", str_regtype( nk->values[i].type ) );
1076 data_size = nk->values[i].data_size & ~VK_DATA_IN_OFFSET;
1077 switch ( nk->values[i].type ) {
1078 case REG_SZ:
1079 blob = data_blob_const(nk->values[i].data, data_size);
1080 pull_reg_sz(talloc_tos(), &blob, &data_str);
1081 if (!data_str) {
1082 break;
1084 d_printf( "%s", data_str );
1085 break;
1086 case REG_MULTI_SZ:
1087 case REG_EXPAND_SZ:
1088 for ( j=0; j<data_size; j++ ) {
1089 d_printf( "%c", nk->values[i].data[j] );
1091 break;
1092 case REG_DWORD:
1093 data = IVAL( nk->values[i].data, 0 );
1094 d_printf("0x%x", data );
1095 break;
1096 case REG_BINARY:
1097 for ( j=0; j<data_size; j++ ) {
1098 d_printf( "%x", nk->values[i].data[j] );
1100 break;
1101 default:
1102 d_printf(_("unknown"));
1103 break;
1106 d_printf( "\n" );
1111 /********************************************************************
1112 ********************************************************************/
1114 static bool dump_registry_tree( REGF_FILE *file, REGF_NK_REC *nk, const char *parent )
1116 REGF_NK_REC *key;
1118 /* depth first dump of the registry tree */
1120 while ( (key = regfio_fetch_subkey( file, nk )) ) {
1121 char *regpath;
1122 if (asprintf(&regpath, "%s\\%s", parent, key->keyname) < 0) {
1123 break;
1125 d_printf("[%s]\n", regpath );
1126 dump_values( key );
1127 d_printf("\n");
1128 dump_registry_tree( file, key, regpath );
1129 SAFE_FREE(regpath);
1132 return true;
1135 /********************************************************************
1136 ********************************************************************/
1138 static bool write_registry_tree( REGF_FILE *infile, REGF_NK_REC *nk,
1139 REGF_NK_REC *parent, REGF_FILE *outfile,
1140 const char *parentpath )
1142 REGF_NK_REC *key, *subkey;
1143 struct regval_ctr *values = NULL;
1144 struct regsubkey_ctr *subkeys = NULL;
1145 int i;
1146 char *path = NULL;
1147 WERROR werr;
1149 werr = regsubkey_ctr_init(infile->mem_ctx, &subkeys);
1150 if (!W_ERROR_IS_OK(werr)) {
1151 DEBUG(0, ("write_registry_tree: regsubkey_ctr_init failed: "
1152 "%s\n", win_errstr(werr)));
1153 return false;
1156 werr = regval_ctr_init(subkeys, &values);
1157 if (!W_ERROR_IS_OK(werr)) {
1158 DEBUG(0,("write_registry_tree: talloc() failed!\n"));
1159 TALLOC_FREE(subkeys);
1160 return false;
1163 /* copy values into the struct regval_ctr */
1165 for ( i=0; i<nk->num_values; i++ ) {
1166 regval_ctr_addvalue( values, nk->values[i].valuename, nk->values[i].type,
1167 nk->values[i].data, (nk->values[i].data_size & ~VK_DATA_IN_OFFSET) );
1170 /* copy subkeys into the struct regsubkey_ctr */
1172 while ( (subkey = regfio_fetch_subkey( infile, nk )) ) {
1173 regsubkey_ctr_addkey( subkeys, subkey->keyname );
1176 key = regfio_write_key( outfile, nk->keyname, values, subkeys, nk->sec_desc->sec_desc, parent );
1178 /* write each one of the subkeys out */
1180 path = talloc_asprintf(subkeys,
1181 "%s%s%s",
1182 parentpath,
1183 parent ? "\\" : "",
1184 nk->keyname);
1185 if (!path) {
1186 TALLOC_FREE(subkeys);
1187 return false;
1190 nk->subkey_index = 0;
1191 while ( (subkey = regfio_fetch_subkey( infile, nk )) ) {
1192 write_registry_tree( infile, subkey, key, outfile, path );
1195 d_printf("[%s]\n", path );
1196 TALLOC_FREE(subkeys);
1198 return true;
1201 /********************************************************************
1202 ********************************************************************/
1204 static int rpc_registry_dump(struct net_context *c, int argc, const char **argv)
1206 REGF_FILE *registry;
1207 REGF_NK_REC *nk;
1209 if (argc != 1 || c->display_usage) {
1210 d_printf("%s\n%s",
1211 _("Usage:"),
1212 _("net rpc registry dump <file> \n"));
1213 return -1;
1216 d_printf(_("Opening %s...."), argv[0]);
1217 if ( !(registry = regfio_open( argv[0], O_RDONLY, 0)) ) {
1218 d_fprintf(stderr, _("Failed to open %s for reading\n"),argv[0]);
1219 return 1;
1221 d_printf(_("ok\n"));
1223 /* get the root of the registry file */
1225 if ((nk = regfio_rootkey( registry )) == NULL) {
1226 d_fprintf(stderr, _("Could not get rootkey\n"));
1227 regfio_close( registry );
1228 return 1;
1230 d_printf("[%s]\n", nk->keyname);
1231 dump_values( nk );
1232 d_printf("\n");
1234 dump_registry_tree( registry, nk, nk->keyname );
1236 #if 0
1237 talloc_report_full( registry->mem_ctx, stderr );
1238 #endif
1239 d_printf(_("Closing registry..."));
1240 regfio_close( registry );
1241 d_printf(_("ok\n"));
1243 return 0;
1246 /********************************************************************
1247 ********************************************************************/
1249 static int rpc_registry_copy(struct net_context *c, int argc, const char **argv )
1251 REGF_FILE *infile = NULL, *outfile = NULL;
1252 REGF_NK_REC *nk;
1253 int result = 1;
1255 if (argc != 2 || c->display_usage) {
1256 d_printf("%s\n%s",
1257 _("Usage:"),
1258 _("net rpc registry copy <srcfile> <newfile>\n"));
1259 return -1;
1262 d_printf(_("Opening %s...."), argv[0]);
1263 if ( !(infile = regfio_open( argv[0], O_RDONLY, 0 )) ) {
1264 d_fprintf(stderr, _("Failed to open %s for reading\n"),argv[0]);
1265 return 1;
1267 d_printf(_("ok\n"));
1269 d_printf(_("Opening %s...."), argv[1]);
1270 if ( !(outfile = regfio_open( argv[1], (O_RDWR|O_CREAT|O_TRUNC), (S_IREAD|S_IWRITE) )) ) {
1271 d_fprintf(stderr, _("Failed to open %s for writing\n"),argv[1]);
1272 goto out;
1274 d_printf(_("ok\n"));
1276 /* get the root of the registry file */
1278 if ((nk = regfio_rootkey( infile )) == NULL) {
1279 d_fprintf(stderr, _("Could not get rootkey\n"));
1280 goto out;
1282 d_printf(_("RootKey: [%s]\n"), nk->keyname);
1284 write_registry_tree( infile, nk, NULL, outfile, "" );
1286 result = 0;
1288 out:
1290 d_printf(_("Closing %s..."), argv[1]);
1291 if (outfile) {
1292 regfio_close( outfile );
1294 d_printf(_("ok\n"));
1296 d_printf(_("Closing %s..."), argv[0]);
1297 if (infile) {
1298 regfio_close( infile );
1300 d_printf(_("ok\n"));
1302 return( result);
1305 /********************************************************************
1306 ********************************************************************/
1308 static NTSTATUS rpc_registry_getsd_internal(struct net_context *c,
1309 const struct dom_sid *domain_sid,
1310 const char *domain_name,
1311 struct cli_state *cli,
1312 struct rpc_pipe_client *pipe_hnd,
1313 TALLOC_CTX *mem_ctx,
1314 int argc,
1315 const char **argv)
1317 struct policy_handle pol_hive, pol_key;
1318 NTSTATUS status;
1319 enum ndr_err_code ndr_err;
1320 struct KeySecurityData *sd = NULL;
1321 uint32_t sec_info;
1322 DATA_BLOB blob;
1323 struct security_descriptor sec_desc;
1324 uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED |
1325 SEC_FLAG_SYSTEM_SECURITY;
1327 if (argc <1 || argc > 2 || c->display_usage) {
1328 d_printf("%s\n%s",
1329 _("Usage:"),
1330 _("net rpc registry getsd <path> <secinfo>\n"));
1331 d_printf("%s net rpc registry getsd "
1332 "'HKLM\\Software\\Samba'\n", _("Example:"));
1333 return NT_STATUS_INVALID_PARAMETER;
1336 status = registry_openkey(mem_ctx, pipe_hnd, argv[0],
1337 access_mask,
1338 &pol_hive, &pol_key);
1339 if (!NT_STATUS_IS_OK(status)) {
1340 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
1341 nt_errstr(status));
1342 return status;
1345 sd = TALLOC_ZERO_P(mem_ctx, struct KeySecurityData);
1346 if (!sd) {
1347 status = NT_STATUS_NO_MEMORY;
1348 goto out;
1351 sd->size = 0x1000;
1353 if (argc >= 2) {
1354 sscanf(argv[1], "%x", &sec_info);
1355 } else {
1356 sec_info = SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL;
1359 status = registry_getsd(mem_ctx, pipe_hnd, &pol_key, sec_info, sd);
1360 if (!NT_STATUS_IS_OK(status)) {
1361 d_fprintf(stderr, _("getting sd failed: %s\n"),
1362 nt_errstr(status));
1363 goto out;
1366 blob.data = sd->data;
1367 blob.length = sd->size;
1369 ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &sec_desc,
1370 (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
1371 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1372 status = ndr_map_error2ntstatus(ndr_err);
1373 goto out;
1375 status = NT_STATUS_OK;
1377 display_sec_desc(&sec_desc);
1379 out:
1380 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_key, NULL);
1381 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_hive, NULL);
1383 return status;
1387 static int rpc_registry_getsd(struct net_context *c, int argc, const char **argv)
1389 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
1390 rpc_registry_getsd_internal, argc, argv);
1393 /********************************************************************
1394 ********************************************************************/
1396 * @defgroup net_rpc_registry net rpc registry
1400 * @defgroup net_rpc_registry_export Export
1401 * @ingroup net_rpc_registry
1402 * @{
1405 static NTSTATUS registry_export(struct rpc_pipe_client* pipe_hnd,
1406 TALLOC_CTX* ctx,
1407 struct policy_handle* key_hnd,
1408 struct reg_format* f,
1409 const char* parentfullname,
1410 const char* name)
1412 NTSTATUS status;
1413 uint32 num_subkeys = 0;
1414 uint32 num_values = 0;
1415 char **names = NULL, **classes = NULL;
1416 NTTIME **modtimes = NULL;
1417 struct regval_blob **values = NULL;
1418 uint32 i;
1420 TALLOC_CTX* mem_ctx = talloc_new(ctx);
1423 const char* fullname = name
1424 ? talloc_asprintf(mem_ctx, "%s\\%s", parentfullname, name)
1425 : parentfullname;
1426 reg_format_key(f, &fullname, 1, false);
1428 status = registry_enumvalues2(mem_ctx, pipe_hnd, key_hnd, &num_values,
1429 &names, &values);
1430 if (!NT_STATUS_IS_OK(status)) {
1431 d_fprintf(stderr, _("enumerating values failed: %s\n"),
1432 nt_errstr(status));
1433 goto done;
1436 for (i=0; i<num_values; i++) {
1437 reg_format_regval_blob(f, names[i], values[i]);
1441 status = registry_enumkeys(mem_ctx, pipe_hnd, key_hnd, &num_subkeys,
1442 &names, &classes, &modtimes);
1443 if (!NT_STATUS_IS_OK(status)) {
1444 d_fprintf(stderr, _("enumerating keys failed: %s\n"),
1445 nt_errstr(status));
1446 goto done;
1449 for (i=0; i<num_subkeys; i++) {
1450 struct policy_handle subkey_hnd;
1451 struct winreg_String key;
1452 ZERO_STRUCT(key);
1453 /* key.name = talloc_strdup(mem_ctx, names[i]); ??? */
1454 key.name = names[i];
1456 status = rpccli_winreg_OpenKey(pipe_hnd, mem_ctx, key_hnd, key,
1457 0, REG_KEY_READ,
1458 &subkey_hnd, NULL);
1459 if (NT_STATUS_IS_OK(status)) {
1460 status = registry_export(pipe_hnd, mem_ctx, &subkey_hnd,
1461 f, fullname, names[i]);
1462 if (!(NT_STATUS_IS_OK(status)))
1463 d_fprintf(stderr,
1464 _("export key failed: %s %s\n"),
1465 names[i], nt_errstr(status));
1467 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx,
1468 &subkey_hnd, NULL);
1469 } else {
1470 d_fprintf(stderr,
1471 _("rpccli_winreg_OpenKey failed: %s %s\n"),
1472 names[i], nt_errstr(status));
1475 done:
1476 talloc_free(mem_ctx);
1477 return status;
1480 static NTSTATUS rpc_registry_export_internal(struct net_context *c,
1481 const struct dom_sid *domain_sid,
1482 const char *domain_name,
1483 struct cli_state *cli,
1484 struct rpc_pipe_client *pipe_hnd,
1485 TALLOC_CTX *mem_ctx,
1486 int argc,
1487 const char **argv )
1489 struct policy_handle pol_hive, pol_key;
1490 NTSTATUS status;
1491 struct reg_format* f;
1493 if (argc < 2 || argc > 3 || c->display_usage) {
1494 d_printf("%s\n%s",
1495 _("Usage:"),
1496 _("net rpc registry export <path> <file> [opt]\n"));
1497 d_printf("%s net rpc registry export "
1498 "'HKLM\\Software\\Samba' samba.reg\n", _("Example:"));
1499 return NT_STATUS_INVALID_PARAMETER;
1502 status = registry_openkey(mem_ctx, pipe_hnd, argv[0], REG_KEY_READ,
1503 &pol_hive, &pol_key);
1504 if (!NT_STATUS_IS_OK(status)) {
1505 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
1506 nt_errstr(status));
1507 return status;
1510 f = reg_format_file(mem_ctx, argv[1], (argc > 2) ? argv[2] : NULL);
1511 if (f == NULL) {
1512 d_fprintf(stderr, _("open file failed: %s\n"), strerror(errno));
1513 return map_nt_error_from_unix(errno);
1516 status = registry_export(pipe_hnd, mem_ctx, &pol_key,
1517 f, argv[0], NULL );
1518 if (!NT_STATUS_IS_OK(status))
1519 return status;
1521 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_key, NULL);
1522 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_hive, NULL);
1524 return status;
1526 /********************************************************************
1527 ********************************************************************/
1529 static int rpc_registry_export(struct net_context *c, int argc,
1530 const char **argv )
1532 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
1533 rpc_registry_export_internal, argc, argv );
1536 /**@}*/
1538 /********************************************************************
1539 ********************************************************************/
1542 * @defgroup net_rpc_registry_import Import
1543 * @ingroup net_rpc_registry
1544 * @{
1547 struct import_ctx {
1548 struct rpc_pipe_client *pipe_hnd;
1549 TALLOC_CTX *mem_ctx;
1552 static WERROR import_create_key(struct import_ctx* ctx,
1553 struct policy_handle* parent, const char* name,
1554 void** pkey, bool* existing)
1556 WERROR werr;
1557 NTSTATUS status;
1558 void* mem_ctx = talloc_new(ctx->mem_ctx);
1560 struct policy_handle* key = NULL;
1561 struct policy_handle hive;
1562 struct winreg_String keyclass, keyname;
1563 enum winreg_CreateAction action = REG_ACTION_NONE;
1565 ZERO_STRUCT(keyname);
1566 keyname.name = name;
1568 if (parent == NULL) {
1569 uint32 hive_idx = 0;
1570 if (!reg_hive_key(mem_ctx, name, &hive_idx, &keyname.name)) {
1571 werr = WERR_FOOBAR;
1572 goto done;
1575 status = rpccli_winreg_Connect(ctx->pipe_hnd, mem_ctx,
1576 hive_idx, SEC_FLAG_MAXIMUM_ALLOWED,
1577 &hive, &werr);
1578 if (!NT_STATUS_IS_OK(status)) {
1579 d_fprintf(stderr, _("rpccli_winreg_Connect returned %s\n"),
1580 nt_errstr(status));
1581 goto done;
1584 parent = &hive;
1587 key = talloc_zero(mem_ctx, struct policy_handle);
1588 if (key == NULL) {
1589 werr = WERR_NOMEM;
1590 goto done;
1593 ZERO_STRUCT(keyclass);
1594 keyclass.name = "";
1596 status = rpccli_winreg_CreateKey(ctx->pipe_hnd, mem_ctx,
1597 parent, keyname,
1598 keyclass, 0, REG_KEY_READ, NULL,
1599 key, &action, &werr);
1600 if (!NT_STATUS_IS_OK(status)) {
1601 d_fprintf(stderr, _("rpccli_winreg_CreateKey returned %s\n"),
1602 nt_errstr(status));
1603 goto done;
1606 switch (action) {
1607 case REG_CREATED_NEW_KEY:
1608 d_printf(_("createkey created %s\n"), name);
1609 if (existing != NULL)
1610 *existing = false;
1611 break;
1613 case REG_OPENED_EXISTING_KEY:
1614 d_printf(_("createkey opened existing %s\n"), name);
1615 if (existing != NULL)
1616 *existing = true;
1617 break;
1619 case REG_ACTION_NONE:
1620 d_printf(_("createkey did nothing -- huh?\n"));
1621 werr = WERR_CREATE_FAILED;
1622 break;
1623 default:
1624 assert(false);
1627 done:
1628 if ( parent == &hive ) {
1629 rpccli_winreg_CloseKey(ctx->pipe_hnd, mem_ctx,
1630 parent, NULL);
1633 if (pkey!=NULL) {
1634 *pkey = talloc_steal(ctx->mem_ctx, key);
1637 talloc_free(mem_ctx);
1638 return werr;
1641 static WERROR import_delete_key(struct import_ctx* ctx,
1642 struct policy_handle* parent, const char* name)
1644 WERROR werr;
1645 NTSTATUS status;
1646 void* mem_ctx = talloc_new(ctx->mem_ctx);
1647 struct winreg_String keyname;
1648 struct policy_handle hive;
1650 keyname.name = name;
1652 if (parent == NULL) {
1653 uint32 hive_idx;
1654 if (!reg_hive_key(mem_ctx, name, &hive_idx, &keyname.name)) {
1655 werr = WERR_FOOBAR;
1656 goto done;
1659 status = rpccli_winreg_Connect(ctx->pipe_hnd, mem_ctx, hive_idx,
1660 SEC_FLAG_MAXIMUM_ALLOWED, &hive,
1661 &werr);
1662 if (!NT_STATUS_IS_OK(status)) {
1663 d_fprintf(stderr, _("rpccli_winreg_Connect returned %s\n"),
1664 nt_errstr(status));
1665 goto done;
1668 parent = &hive;
1671 status = rpccli_winreg_DeleteKey(ctx->pipe_hnd, mem_ctx, parent,
1672 keyname, &werr);
1673 if (!NT_STATUS_IS_OK(status)) {
1674 d_fprintf(stderr, _("rpccli_winreg_DeleteKey returned %s\n"),
1675 nt_errstr(status));
1676 goto done;
1679 done:
1680 if ( parent == &hive ) {
1681 rpccli_winreg_CloseKey(ctx->pipe_hnd, mem_ctx, parent, NULL);
1684 talloc_free(mem_ctx);
1685 return werr;
1688 static WERROR import_close_key(struct import_ctx* ctx,
1689 struct policy_handle* key)
1691 WERROR werr;
1692 NTSTATUS status;
1693 void* mem_ctx = talloc_new(ctx->mem_ctx);
1695 status = rpccli_winreg_CloseKey(ctx->pipe_hnd, mem_ctx, key, &werr);
1696 if (!NT_STATUS_IS_OK(status)) {
1697 d_fprintf(stderr, _("rpccli_winreg_CloseKey returned %s\n"),
1698 nt_errstr(status));
1699 goto done;
1702 werr = (talloc_free(key) == 0) ? WERR_OK : WERR_GENERAL_FAILURE;
1703 done:
1704 talloc_free(mem_ctx);
1705 return werr;
1708 static WERROR import_create_val(struct import_ctx* ctx,
1709 struct policy_handle* parent, const char* name,
1710 uint32_t type, const uint8_t* val, uint32_t len)
1712 WERROR werr;
1713 NTSTATUS status;
1714 void* mem_ctx = talloc_new(ctx->mem_ctx);
1715 struct winreg_String valuename;
1717 if (parent == NULL) {
1718 return WERR_INVALID_PARAM;
1721 ZERO_STRUCT(valuename);
1722 valuename.name = name;
1724 status = rpccli_winreg_SetValue(ctx->pipe_hnd, mem_ctx, parent,
1725 valuename, type,
1726 discard_const(val), len, &werr);
1727 if (!NT_STATUS_IS_OK(status)) {
1728 d_fprintf(stderr, _("registry_setvalue failed: %s\n"),
1729 nt_errstr(status));
1730 goto done;
1733 done:
1734 talloc_free(mem_ctx);
1735 return werr;
1738 static WERROR import_delete_val(struct import_ctx* ctx,
1739 struct policy_handle* parent, const char* name)
1741 WERROR werr;
1742 NTSTATUS status;
1743 void* mem_ctx = talloc_new(ctx->mem_ctx);
1744 struct winreg_String valuename;
1746 if (parent == NULL) {
1747 return WERR_INVALID_PARAM;
1750 ZERO_STRUCT(valuename);
1751 valuename.name = name;
1753 status = rpccli_winreg_DeleteValue(ctx->pipe_hnd, mem_ctx,
1754 parent, valuename, &werr);
1756 if (!NT_STATUS_IS_OK(status)) {
1757 d_fprintf(stderr, _("registry_deletevalue failed: %s\n"),
1758 nt_errstr(status));
1759 goto done;
1761 done:
1762 talloc_free(mem_ctx);
1763 return werr;
1768 static NTSTATUS rpc_registry_import_internal(struct net_context *c,
1769 const struct dom_sid *domain_sid,
1770 const char *domain_name,
1771 struct cli_state *cli,
1772 struct rpc_pipe_client *pipe_hnd,
1773 TALLOC_CTX *mem_ctx,
1774 int argc,
1775 const char **argv )
1777 struct import_ctx import_ctx;
1779 struct reg_import_callback import_callback = {
1780 .openkey = NULL,
1781 .closekey = (reg_import_callback_closekey_t)&import_close_key,
1782 .createkey = (reg_import_callback_createkey_t)&import_create_key,
1783 .deletekey = (reg_import_callback_deletekey_t)&import_delete_key,
1784 .deleteval = (reg_import_callback_deleteval_t)&import_delete_val,
1785 .setval.blob = (reg_import_callback_setval_blob_t)&import_create_val,
1786 .setval_type = BLOB,
1787 .data = &import_ctx
1790 int ret;
1791 if (argc < 1 || argc > 2 || c->display_usage) {
1792 d_printf("%s\n%s",
1793 _("Usage:"),
1794 _("net rpc registry import <file> [options]\n"));
1795 d_printf("%s net rpc registry export "
1796 "samba.reg enc=CP1252,flags=0\n", _("Example:"));
1797 return NT_STATUS_INVALID_PARAMETER;
1799 ZERO_STRUCT(import_ctx);
1800 import_ctx.pipe_hnd = pipe_hnd;
1801 import_ctx.mem_ctx = mem_ctx;
1802 ret = reg_parse_file(argv[0],
1803 reg_import_adapter(import_ctx.mem_ctx,
1804 import_callback
1806 (argc > 1) ? argv[1] : NULL
1809 return ret==0 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1812 /********************************************************************
1813 ********************************************************************/
1815 static int rpc_registry_import(struct net_context *c, int argc,
1816 const char **argv )
1818 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
1819 rpc_registry_import_internal, argc, argv );
1822 /**@}*/
1823 /********************************************************************
1824 ********************************************************************/
1826 int net_rpc_registry(struct net_context *c, int argc, const char **argv)
1828 struct functable func[] = {
1830 "enumerate",
1831 rpc_registry_enumerate,
1832 NET_TRANSPORT_RPC,
1833 N_("Enumerate registry keys and values"),
1834 N_("net rpc registry enumerate\n"
1835 " Enumerate registry keys and values")
1838 "createkey",
1839 rpc_registry_createkey,
1840 NET_TRANSPORT_RPC,
1841 N_("Create a new registry key"),
1842 N_("net rpc registry createkey\n"
1843 " Create a new registry key")
1846 "deletekey",
1847 rpc_registry_deletekey,
1848 NET_TRANSPORT_RPC,
1849 N_("Delete a registry key"),
1850 N_("net rpc registry deletekey\n"
1851 " Delete a registry key")
1854 "getvalue",
1855 rpc_registry_getvalue,
1856 NET_TRANSPORT_RPC,
1857 N_("Print a registry value"),
1858 N_("net rpc registry getvalue\n"
1859 " Print a registry value")
1862 "getvalueraw",
1863 rpc_registry_getvalueraw,
1864 NET_TRANSPORT_RPC,
1865 N_("Print a registry value"),
1866 N_("net rpc registry getvalueraw\n"
1867 " Print a registry value (raw version)")
1870 "setvalue",
1871 rpc_registry_setvalue,
1872 NET_TRANSPORT_RPC,
1873 N_("Set a new registry value"),
1874 N_("net rpc registry setvalue\n"
1875 " Set a new registry value")
1878 "deletevalue",
1879 rpc_registry_deletevalue,
1880 NET_TRANSPORT_RPC,
1881 N_("Delete a registry value"),
1882 N_("net rpc registry deletevalue\n"
1883 " Delete a registry value")
1886 "save",
1887 rpc_registry_save,
1888 NET_TRANSPORT_RPC,
1889 N_("Save a registry file"),
1890 N_("net rpc registry save\n"
1891 " Save a registry file")
1894 "dump",
1895 rpc_registry_dump,
1896 NET_TRANSPORT_RPC,
1897 N_("Dump a registry file"),
1898 N_("net rpc registry dump\n"
1899 " Dump a registry file")
1902 "copy",
1903 rpc_registry_copy,
1904 NET_TRANSPORT_RPC,
1905 N_("Copy a registry file"),
1906 N_("net rpc registry copy\n"
1907 " Copy a registry file")
1910 "getsd",
1911 rpc_registry_getsd,
1912 NET_TRANSPORT_RPC,
1913 N_("Get security descriptor"),
1914 N_("net rpc registry getsd\n"
1915 " Get security descriptior")
1918 "import",
1919 rpc_registry_import,
1920 NET_TRANSPORT_RPC,
1921 N_("Import .reg file"),
1922 N_("net rpc registry import\n"
1923 " Import .reg file")
1926 "export",
1927 rpc_registry_export,
1928 NET_TRANSPORT_RPC,
1929 N_("net registry export\n"
1930 " Export .reg file")
1932 {NULL, NULL, 0, NULL, NULL}
1934 return net_run_function(c, argc, argv, "net rpc registry", func);