s4-python: Add missing prototypes.
[Samba.git] / source3 / utils / net_rpc_registry.c
blob5b9f887b330115bf15034e89d1aad190bad7beae
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),
1271 (S_IRUSR|S_IWUSR) )) ) {
1272 d_fprintf(stderr, _("Failed to open %s for writing\n"),argv[1]);
1273 goto out;
1275 d_printf(_("ok\n"));
1277 /* get the root of the registry file */
1279 if ((nk = regfio_rootkey( infile )) == NULL) {
1280 d_fprintf(stderr, _("Could not get rootkey\n"));
1281 goto out;
1283 d_printf(_("RootKey: [%s]\n"), nk->keyname);
1285 write_registry_tree( infile, nk, NULL, outfile, "" );
1287 result = 0;
1289 out:
1291 d_printf(_("Closing %s..."), argv[1]);
1292 if (outfile) {
1293 regfio_close( outfile );
1295 d_printf(_("ok\n"));
1297 d_printf(_("Closing %s..."), argv[0]);
1298 if (infile) {
1299 regfio_close( infile );
1301 d_printf(_("ok\n"));
1303 return( result);
1306 /********************************************************************
1307 ********************************************************************/
1309 static NTSTATUS rpc_registry_getsd_internal(struct net_context *c,
1310 const struct dom_sid *domain_sid,
1311 const char *domain_name,
1312 struct cli_state *cli,
1313 struct rpc_pipe_client *pipe_hnd,
1314 TALLOC_CTX *mem_ctx,
1315 int argc,
1316 const char **argv)
1318 struct policy_handle pol_hive, pol_key;
1319 NTSTATUS status;
1320 enum ndr_err_code ndr_err;
1321 struct KeySecurityData *sd = NULL;
1322 uint32_t sec_info;
1323 DATA_BLOB blob;
1324 struct security_descriptor sec_desc;
1325 uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED |
1326 SEC_FLAG_SYSTEM_SECURITY;
1328 if (argc <1 || argc > 2 || c->display_usage) {
1329 d_printf("%s\n%s",
1330 _("Usage:"),
1331 _("net rpc registry getsd <path> <secinfo>\n"));
1332 d_printf("%s net rpc registry getsd "
1333 "'HKLM\\Software\\Samba'\n", _("Example:"));
1334 return NT_STATUS_INVALID_PARAMETER;
1337 status = registry_openkey(mem_ctx, pipe_hnd, argv[0],
1338 access_mask,
1339 &pol_hive, &pol_key);
1340 if (!NT_STATUS_IS_OK(status)) {
1341 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
1342 nt_errstr(status));
1343 return status;
1346 sd = TALLOC_ZERO_P(mem_ctx, struct KeySecurityData);
1347 if (!sd) {
1348 status = NT_STATUS_NO_MEMORY;
1349 goto out;
1352 sd->size = 0x1000;
1354 if (argc >= 2) {
1355 sscanf(argv[1], "%x", &sec_info);
1356 } else {
1357 sec_info = SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL;
1360 status = registry_getsd(mem_ctx, pipe_hnd, &pol_key, sec_info, sd);
1361 if (!NT_STATUS_IS_OK(status)) {
1362 d_fprintf(stderr, _("getting sd failed: %s\n"),
1363 nt_errstr(status));
1364 goto out;
1367 blob.data = sd->data;
1368 blob.length = sd->size;
1370 ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &sec_desc,
1371 (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
1372 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1373 status = ndr_map_error2ntstatus(ndr_err);
1374 goto out;
1376 status = NT_STATUS_OK;
1378 display_sec_desc(&sec_desc);
1380 out:
1381 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_key, NULL);
1382 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_hive, NULL);
1384 return status;
1388 static int rpc_registry_getsd(struct net_context *c, int argc, const char **argv)
1390 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
1391 rpc_registry_getsd_internal, argc, argv);
1394 /********************************************************************
1395 ********************************************************************/
1397 * @defgroup net_rpc_registry net rpc registry
1401 * @defgroup net_rpc_registry_export Export
1402 * @ingroup net_rpc_registry
1403 * @{
1406 static NTSTATUS registry_export(struct rpc_pipe_client* pipe_hnd,
1407 TALLOC_CTX* ctx,
1408 struct policy_handle* key_hnd,
1409 struct reg_format* f,
1410 const char* parentfullname,
1411 const char* name)
1413 NTSTATUS status;
1414 uint32 num_subkeys = 0;
1415 uint32 num_values = 0;
1416 char **names = NULL, **classes = NULL;
1417 NTTIME **modtimes = NULL;
1418 struct regval_blob **values = NULL;
1419 uint32 i;
1421 TALLOC_CTX* mem_ctx = talloc_new(ctx);
1424 const char* fullname = name
1425 ? talloc_asprintf(mem_ctx, "%s\\%s", parentfullname, name)
1426 : parentfullname;
1427 reg_format_key(f, &fullname, 1, false);
1429 status = registry_enumvalues2(mem_ctx, pipe_hnd, key_hnd, &num_values,
1430 &names, &values);
1431 if (!NT_STATUS_IS_OK(status)) {
1432 d_fprintf(stderr, _("enumerating values failed: %s\n"),
1433 nt_errstr(status));
1434 goto done;
1437 for (i=0; i<num_values; i++) {
1438 reg_format_regval_blob(f, names[i], values[i]);
1442 status = registry_enumkeys(mem_ctx, pipe_hnd, key_hnd, &num_subkeys,
1443 &names, &classes, &modtimes);
1444 if (!NT_STATUS_IS_OK(status)) {
1445 d_fprintf(stderr, _("enumerating keys failed: %s\n"),
1446 nt_errstr(status));
1447 goto done;
1450 for (i=0; i<num_subkeys; i++) {
1451 struct policy_handle subkey_hnd;
1452 struct winreg_String key;
1453 ZERO_STRUCT(key);
1454 /* key.name = talloc_strdup(mem_ctx, names[i]); ??? */
1455 key.name = names[i];
1457 status = rpccli_winreg_OpenKey(pipe_hnd, mem_ctx, key_hnd, key,
1458 0, REG_KEY_READ,
1459 &subkey_hnd, NULL);
1460 if (NT_STATUS_IS_OK(status)) {
1461 status = registry_export(pipe_hnd, mem_ctx, &subkey_hnd,
1462 f, fullname, names[i]);
1463 if (!(NT_STATUS_IS_OK(status)))
1464 d_fprintf(stderr,
1465 _("export key failed: %s %s\n"),
1466 names[i], nt_errstr(status));
1468 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx,
1469 &subkey_hnd, NULL);
1470 } else {
1471 d_fprintf(stderr,
1472 _("rpccli_winreg_OpenKey failed: %s %s\n"),
1473 names[i], nt_errstr(status));
1476 done:
1477 talloc_free(mem_ctx);
1478 return status;
1481 static NTSTATUS rpc_registry_export_internal(struct net_context *c,
1482 const struct dom_sid *domain_sid,
1483 const char *domain_name,
1484 struct cli_state *cli,
1485 struct rpc_pipe_client *pipe_hnd,
1486 TALLOC_CTX *mem_ctx,
1487 int argc,
1488 const char **argv )
1490 struct policy_handle pol_hive, pol_key;
1491 NTSTATUS status;
1492 struct reg_format* f;
1494 if (argc < 2 || argc > 3 || c->display_usage) {
1495 d_printf("%s\n%s",
1496 _("Usage:"),
1497 _("net rpc registry export <path> <file> [opt]\n"));
1498 d_printf("%s net rpc registry export "
1499 "'HKLM\\Software\\Samba' samba.reg\n", _("Example:"));
1500 return NT_STATUS_INVALID_PARAMETER;
1503 status = registry_openkey(mem_ctx, pipe_hnd, argv[0], REG_KEY_READ,
1504 &pol_hive, &pol_key);
1505 if (!NT_STATUS_IS_OK(status)) {
1506 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
1507 nt_errstr(status));
1508 return status;
1511 f = reg_format_file(mem_ctx, argv[1], (argc > 2) ? argv[2] : NULL);
1512 if (f == NULL) {
1513 d_fprintf(stderr, _("open file failed: %s\n"), strerror(errno));
1514 return map_nt_error_from_unix(errno);
1517 status = registry_export(pipe_hnd, mem_ctx, &pol_key,
1518 f, argv[0], NULL );
1519 if (!NT_STATUS_IS_OK(status))
1520 return status;
1522 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_key, NULL);
1523 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_hive, NULL);
1525 return status;
1527 /********************************************************************
1528 ********************************************************************/
1530 static int rpc_registry_export(struct net_context *c, int argc,
1531 const char **argv )
1533 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
1534 rpc_registry_export_internal, argc, argv );
1537 /**@}*/
1539 /********************************************************************
1540 ********************************************************************/
1543 * @defgroup net_rpc_registry_import Import
1544 * @ingroup net_rpc_registry
1545 * @{
1548 struct import_ctx {
1549 struct rpc_pipe_client *pipe_hnd;
1550 TALLOC_CTX *mem_ctx;
1553 static WERROR import_create_key(struct import_ctx* ctx,
1554 struct policy_handle* parent, const char* name,
1555 void** pkey, bool* existing)
1557 WERROR werr;
1558 NTSTATUS status;
1559 void* mem_ctx = talloc_new(ctx->mem_ctx);
1561 struct policy_handle* key = NULL;
1562 struct policy_handle hive;
1563 struct winreg_String keyclass, keyname;
1564 enum winreg_CreateAction action = REG_ACTION_NONE;
1566 ZERO_STRUCT(keyname);
1567 keyname.name = name;
1569 if (parent == NULL) {
1570 uint32 hive_idx = 0;
1571 if (!reg_hive_key(mem_ctx, name, &hive_idx, &keyname.name)) {
1572 werr = WERR_FOOBAR;
1573 goto done;
1576 status = rpccli_winreg_Connect(ctx->pipe_hnd, mem_ctx,
1577 hive_idx, SEC_FLAG_MAXIMUM_ALLOWED,
1578 &hive, &werr);
1579 if (!NT_STATUS_IS_OK(status)) {
1580 d_fprintf(stderr, _("rpccli_winreg_Connect returned %s\n"),
1581 nt_errstr(status));
1582 goto done;
1585 parent = &hive;
1588 key = talloc_zero(mem_ctx, struct policy_handle);
1589 if (key == NULL) {
1590 werr = WERR_NOMEM;
1591 goto done;
1594 ZERO_STRUCT(keyclass);
1595 keyclass.name = "";
1597 status = rpccli_winreg_CreateKey(ctx->pipe_hnd, mem_ctx,
1598 parent, keyname,
1599 keyclass, 0, REG_KEY_READ, NULL,
1600 key, &action, &werr);
1601 if (!NT_STATUS_IS_OK(status)) {
1602 d_fprintf(stderr, _("rpccli_winreg_CreateKey returned %s\n"),
1603 nt_errstr(status));
1604 goto done;
1607 switch (action) {
1608 case REG_CREATED_NEW_KEY:
1609 d_printf(_("createkey created %s\n"), name);
1610 if (existing != NULL)
1611 *existing = false;
1612 break;
1614 case REG_OPENED_EXISTING_KEY:
1615 d_printf(_("createkey opened existing %s\n"), name);
1616 if (existing != NULL)
1617 *existing = true;
1618 break;
1620 case REG_ACTION_NONE:
1621 d_printf(_("createkey did nothing -- huh?\n"));
1622 werr = WERR_CREATE_FAILED;
1623 break;
1624 default:
1625 assert(false);
1628 done:
1629 if ( parent == &hive ) {
1630 rpccli_winreg_CloseKey(ctx->pipe_hnd, mem_ctx,
1631 parent, NULL);
1634 if (pkey!=NULL) {
1635 *pkey = talloc_steal(ctx->mem_ctx, key);
1638 talloc_free(mem_ctx);
1639 return werr;
1642 static WERROR import_delete_key(struct import_ctx* ctx,
1643 struct policy_handle* parent, const char* name)
1645 WERROR werr;
1646 NTSTATUS status;
1647 void* mem_ctx = talloc_new(ctx->mem_ctx);
1648 struct winreg_String keyname;
1649 struct policy_handle hive;
1651 keyname.name = name;
1653 if (parent == NULL) {
1654 uint32 hive_idx;
1655 if (!reg_hive_key(mem_ctx, name, &hive_idx, &keyname.name)) {
1656 werr = WERR_FOOBAR;
1657 goto done;
1660 status = rpccli_winreg_Connect(ctx->pipe_hnd, mem_ctx, hive_idx,
1661 SEC_FLAG_MAXIMUM_ALLOWED, &hive,
1662 &werr);
1663 if (!NT_STATUS_IS_OK(status)) {
1664 d_fprintf(stderr, _("rpccli_winreg_Connect returned %s\n"),
1665 nt_errstr(status));
1666 goto done;
1669 parent = &hive;
1672 status = rpccli_winreg_DeleteKey(ctx->pipe_hnd, mem_ctx, parent,
1673 keyname, &werr);
1674 if (!NT_STATUS_IS_OK(status)) {
1675 d_fprintf(stderr, _("rpccli_winreg_DeleteKey returned %s\n"),
1676 nt_errstr(status));
1677 goto done;
1680 done:
1681 if ( parent == &hive ) {
1682 rpccli_winreg_CloseKey(ctx->pipe_hnd, mem_ctx, parent, NULL);
1685 talloc_free(mem_ctx);
1686 return werr;
1689 static WERROR import_close_key(struct import_ctx* ctx,
1690 struct policy_handle* key)
1692 WERROR werr;
1693 NTSTATUS status;
1694 void* mem_ctx = talloc_new(ctx->mem_ctx);
1696 status = rpccli_winreg_CloseKey(ctx->pipe_hnd, mem_ctx, key, &werr);
1697 if (!NT_STATUS_IS_OK(status)) {
1698 d_fprintf(stderr, _("rpccli_winreg_CloseKey returned %s\n"),
1699 nt_errstr(status));
1700 goto done;
1703 werr = (talloc_free(key) == 0) ? WERR_OK : WERR_GENERAL_FAILURE;
1704 done:
1705 talloc_free(mem_ctx);
1706 return werr;
1709 static WERROR import_create_val(struct import_ctx* ctx,
1710 struct policy_handle* parent, const char* name,
1711 uint32_t type, const uint8_t* val, uint32_t len)
1713 WERROR werr;
1714 NTSTATUS status;
1715 void* mem_ctx = talloc_new(ctx->mem_ctx);
1716 struct winreg_String valuename;
1718 if (parent == NULL) {
1719 return WERR_INVALID_PARAM;
1722 ZERO_STRUCT(valuename);
1723 valuename.name = name;
1725 status = rpccli_winreg_SetValue(ctx->pipe_hnd, mem_ctx, parent,
1726 valuename, type,
1727 (uint8_t *)discard_const(val), len, &werr);
1728 if (!NT_STATUS_IS_OK(status)) {
1729 d_fprintf(stderr, _("registry_setvalue failed: %s\n"),
1730 nt_errstr(status));
1731 goto done;
1734 done:
1735 talloc_free(mem_ctx);
1736 return werr;
1739 static WERROR import_delete_val(struct import_ctx* ctx,
1740 struct policy_handle* parent, const char* name)
1742 WERROR werr;
1743 NTSTATUS status;
1744 void* mem_ctx = talloc_new(ctx->mem_ctx);
1745 struct winreg_String valuename;
1747 if (parent == NULL) {
1748 return WERR_INVALID_PARAM;
1751 ZERO_STRUCT(valuename);
1752 valuename.name = name;
1754 status = rpccli_winreg_DeleteValue(ctx->pipe_hnd, mem_ctx,
1755 parent, valuename, &werr);
1757 if (!NT_STATUS_IS_OK(status)) {
1758 d_fprintf(stderr, _("registry_deletevalue failed: %s\n"),
1759 nt_errstr(status));
1760 goto done;
1762 done:
1763 talloc_free(mem_ctx);
1764 return werr;
1769 static NTSTATUS rpc_registry_import_internal(struct net_context *c,
1770 const struct dom_sid *domain_sid,
1771 const char *domain_name,
1772 struct cli_state *cli,
1773 struct rpc_pipe_client *pipe_hnd,
1774 TALLOC_CTX *mem_ctx,
1775 int argc,
1776 const char **argv )
1778 struct import_ctx import_ctx;
1780 struct reg_import_callback import_callback = {
1781 .openkey = NULL,
1782 .closekey = (reg_import_callback_closekey_t)&import_close_key,
1783 .createkey = (reg_import_callback_createkey_t)&import_create_key,
1784 .deletekey = (reg_import_callback_deletekey_t)&import_delete_key,
1785 .deleteval = (reg_import_callback_deleteval_t)&import_delete_val,
1786 .setval.blob = (reg_import_callback_setval_blob_t)&import_create_val,
1787 .setval_type = BLOB,
1788 .data = &import_ctx
1791 int ret;
1792 if (argc < 1 || argc > 2 || c->display_usage) {
1793 d_printf("%s\n%s",
1794 _("Usage:"),
1795 _("net rpc registry import <file> [options]\n"));
1796 d_printf("%s net rpc registry export "
1797 "samba.reg enc=CP1252,flags=0\n", _("Example:"));
1798 return NT_STATUS_INVALID_PARAMETER;
1800 ZERO_STRUCT(import_ctx);
1801 import_ctx.pipe_hnd = pipe_hnd;
1802 import_ctx.mem_ctx = mem_ctx;
1803 ret = reg_parse_file(argv[0],
1804 reg_import_adapter(import_ctx.mem_ctx,
1805 import_callback
1807 (argc > 1) ? argv[1] : NULL
1810 return ret==0 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1813 /********************************************************************
1814 ********************************************************************/
1816 static int rpc_registry_import(struct net_context *c, int argc,
1817 const char **argv )
1819 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
1820 rpc_registry_import_internal, argc, argv );
1823 /**@}*/
1824 /********************************************************************
1825 ********************************************************************/
1827 int net_rpc_registry(struct net_context *c, int argc, const char **argv)
1829 struct functable func[] = {
1831 "enumerate",
1832 rpc_registry_enumerate,
1833 NET_TRANSPORT_RPC,
1834 N_("Enumerate registry keys and values"),
1835 N_("net rpc registry enumerate\n"
1836 " Enumerate registry keys and values")
1839 "createkey",
1840 rpc_registry_createkey,
1841 NET_TRANSPORT_RPC,
1842 N_("Create a new registry key"),
1843 N_("net rpc registry createkey\n"
1844 " Create a new registry key")
1847 "deletekey",
1848 rpc_registry_deletekey,
1849 NET_TRANSPORT_RPC,
1850 N_("Delete a registry key"),
1851 N_("net rpc registry deletekey\n"
1852 " Delete a registry key")
1855 "getvalue",
1856 rpc_registry_getvalue,
1857 NET_TRANSPORT_RPC,
1858 N_("Print a registry value"),
1859 N_("net rpc registry getvalue\n"
1860 " Print a registry value")
1863 "getvalueraw",
1864 rpc_registry_getvalueraw,
1865 NET_TRANSPORT_RPC,
1866 N_("Print a registry value"),
1867 N_("net rpc registry getvalueraw\n"
1868 " Print a registry value (raw version)")
1871 "setvalue",
1872 rpc_registry_setvalue,
1873 NET_TRANSPORT_RPC,
1874 N_("Set a new registry value"),
1875 N_("net rpc registry setvalue\n"
1876 " Set a new registry value")
1879 "deletevalue",
1880 rpc_registry_deletevalue,
1881 NET_TRANSPORT_RPC,
1882 N_("Delete a registry value"),
1883 N_("net rpc registry deletevalue\n"
1884 " Delete a registry value")
1887 "save",
1888 rpc_registry_save,
1889 NET_TRANSPORT_RPC,
1890 N_("Save a registry file"),
1891 N_("net rpc registry save\n"
1892 " Save a registry file")
1895 "dump",
1896 rpc_registry_dump,
1897 NET_TRANSPORT_RPC,
1898 N_("Dump a registry file"),
1899 N_("net rpc registry dump\n"
1900 " Dump a registry file")
1903 "copy",
1904 rpc_registry_copy,
1905 NET_TRANSPORT_RPC,
1906 N_("Copy a registry file"),
1907 N_("net rpc registry copy\n"
1908 " Copy a registry file")
1911 "getsd",
1912 rpc_registry_getsd,
1913 NET_TRANSPORT_RPC,
1914 N_("Get security descriptor"),
1915 N_("net rpc registry getsd\n"
1916 " Get security descriptior")
1919 "import",
1920 rpc_registry_import,
1921 NET_TRANSPORT_RPC,
1922 N_("Import .reg file"),
1923 N_("net rpc registry import\n"
1924 " Import .reg file")
1927 "export",
1928 rpc_registry_export,
1929 NET_TRANSPORT_RPC,
1930 N_("net registry export\n"
1931 " Export .reg file")
1933 {NULL, NULL, 0, NULL, NULL}
1935 return net_run_function(c, argc, argv, "net rpc registry", func);