s3: Fix an uninitialized variable
[Samba/gebeck_regimport.git] / source3 / utils / net_rpc_registry.c
blob08142357a9d4dac683f3648a1bd0bc19402bf92f
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 "registry.h"
22 #include "utils/net.h"
23 #include "utils/net_registry_util.h"
24 #include "regfio.h"
25 #include "../librpc/gen_ndr/cli_winreg.h"
26 #include "registry/reg_objects.h"
27 #include "../librpc/gen_ndr/ndr_security.h"
29 /*******************************************************************
30 connect to a registry hive root (open a registry policy)
31 *******************************************************************/
33 static NTSTATUS rpccli_winreg_Connect(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
34 uint32_t reg_type, uint32_t access_mask,
35 struct policy_handle *reg_hnd)
37 ZERO_STRUCTP(reg_hnd);
39 switch (reg_type)
41 case HKEY_CLASSES_ROOT:
42 return rpccli_winreg_OpenHKCR( cli, mem_ctx, NULL,
43 access_mask, reg_hnd, NULL);
45 case HKEY_LOCAL_MACHINE:
46 return rpccli_winreg_OpenHKLM( cli, mem_ctx, NULL,
47 access_mask, reg_hnd, NULL);
49 case HKEY_USERS:
50 return rpccli_winreg_OpenHKU( cli, mem_ctx, NULL,
51 access_mask, reg_hnd, NULL);
53 case HKEY_CURRENT_USER:
54 return rpccli_winreg_OpenHKCU( cli, mem_ctx, NULL,
55 access_mask, reg_hnd, NULL);
57 case HKEY_PERFORMANCE_DATA:
58 return rpccli_winreg_OpenHKPD( cli, mem_ctx, NULL,
59 access_mask, reg_hnd, NULL);
61 default:
62 /* fall through to end of function */
63 break;
66 return NT_STATUS_INVALID_PARAMETER;
69 static bool reg_hive_key(TALLOC_CTX *ctx, const char *fullname,
70 uint32 *reg_type, const char **key_name)
72 WERROR werr;
73 char *hivename = NULL;
74 char *tmp_keyname = NULL;
75 bool ret = false;
76 TALLOC_CTX *tmp_ctx = talloc_stackframe();
78 werr = split_hive_key(tmp_ctx, fullname, &hivename, &tmp_keyname);
79 if (!W_ERROR_IS_OK(werr)) {
80 goto done;
83 *key_name = talloc_strdup(ctx, tmp_keyname);
84 if (*key_name == NULL) {
85 goto done;
88 if (strequal(hivename, "HKLM") ||
89 strequal(hivename, "HKEY_LOCAL_MACHINE"))
91 (*reg_type) = HKEY_LOCAL_MACHINE;
92 } else if (strequal(hivename, "HKCR") ||
93 strequal(hivename, "HKEY_CLASSES_ROOT"))
95 (*reg_type) = HKEY_CLASSES_ROOT;
96 } else if (strequal(hivename, "HKU") ||
97 strequal(hivename, "HKEY_USERS"))
99 (*reg_type) = HKEY_USERS;
100 } else if (strequal(hivename, "HKCU") ||
101 strequal(hivename, "HKEY_CURRENT_USER"))
103 (*reg_type) = HKEY_CURRENT_USER;
104 } else if (strequal(hivename, "HKPD") ||
105 strequal(hivename, "HKEY_PERFORMANCE_DATA"))
107 (*reg_type) = HKEY_PERFORMANCE_DATA;
108 } else {
109 DEBUG(10,("reg_hive_key: unrecognised hive key %s\n",
110 fullname));
111 goto done;
114 ret = true;
116 done:
117 TALLOC_FREE(tmp_ctx);
118 return ret;
121 static NTSTATUS registry_openkey(TALLOC_CTX *mem_ctx,
122 struct rpc_pipe_client *pipe_hnd,
123 const char *name, uint32 access_mask,
124 struct policy_handle *hive_hnd,
125 struct policy_handle *key_hnd)
127 uint32 hive;
128 NTSTATUS status;
129 struct winreg_String key;
131 ZERO_STRUCT(key);
133 if (!reg_hive_key(mem_ctx, name, &hive, &key.name)) {
134 return NT_STATUS_INVALID_PARAMETER;
137 status = rpccli_winreg_Connect(pipe_hnd, mem_ctx, hive, access_mask,
138 hive_hnd);
139 if (!(NT_STATUS_IS_OK(status))) {
140 return status;
143 status = rpccli_winreg_OpenKey(pipe_hnd, mem_ctx, hive_hnd, key, 0,
144 access_mask, key_hnd, NULL);
145 if (!(NT_STATUS_IS_OK(status))) {
146 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, hive_hnd, NULL);
147 return status;
150 return NT_STATUS_OK;
153 static NTSTATUS registry_enumkeys(TALLOC_CTX *ctx,
154 struct rpc_pipe_client *pipe_hnd,
155 struct policy_handle *key_hnd,
156 uint32 *pnum_keys, char ***pnames,
157 char ***pclasses, NTTIME ***pmodtimes)
159 TALLOC_CTX *mem_ctx;
160 NTSTATUS status;
161 uint32 num_subkeys, max_subkeylen, max_classlen;
162 uint32 num_values, max_valnamelen, max_valbufsize;
163 uint32 i;
164 NTTIME last_changed_time;
165 uint32 secdescsize;
166 struct winreg_String classname;
167 char **names, **classes;
168 NTTIME **modtimes;
170 if (!(mem_ctx = talloc_new(ctx))) {
171 return NT_STATUS_NO_MEMORY;
174 ZERO_STRUCT(classname);
175 status = rpccli_winreg_QueryInfoKey(
176 pipe_hnd, mem_ctx, key_hnd, &classname, &num_subkeys,
177 &max_subkeylen, &max_classlen, &num_values, &max_valnamelen,
178 &max_valbufsize, &secdescsize, &last_changed_time, NULL );
180 if (!NT_STATUS_IS_OK(status)) {
181 goto error;
184 if (num_subkeys == 0) {
185 *pnum_keys = 0;
186 TALLOC_FREE(mem_ctx);
187 return NT_STATUS_OK;
190 if ((!(names = TALLOC_ZERO_ARRAY(mem_ctx, char *, num_subkeys))) ||
191 (!(classes = TALLOC_ZERO_ARRAY(mem_ctx, char *, num_subkeys))) ||
192 (!(modtimes = TALLOC_ZERO_ARRAY(mem_ctx, NTTIME *,
193 num_subkeys)))) {
194 status = NT_STATUS_NO_MEMORY;
195 goto error;
198 for (i=0; i<num_subkeys; i++) {
199 char c, n;
200 struct winreg_StringBuf class_buf;
201 struct winreg_StringBuf name_buf;
202 NTTIME modtime;
203 WERROR werr;
205 c = '\0';
206 class_buf.name = &c;
207 class_buf.size = max_classlen+2;
209 n = '\0';
210 name_buf.name = &n;
211 name_buf.size = max_subkeylen+2;
213 ZERO_STRUCT(modtime);
215 status = rpccli_winreg_EnumKey(pipe_hnd, mem_ctx, key_hnd,
216 i, &name_buf, &class_buf,
217 &modtime, &werr);
219 if (W_ERROR_EQUAL(werr,
220 WERR_NO_MORE_ITEMS) ) {
221 status = NT_STATUS_OK;
222 break;
224 if (!NT_STATUS_IS_OK(status)) {
225 goto error;
228 classes[i] = NULL;
230 if (class_buf.name &&
231 (!(classes[i] = talloc_strdup(classes, class_buf.name)))) {
232 status = NT_STATUS_NO_MEMORY;
233 goto error;
236 if (!(names[i] = talloc_strdup(names, name_buf.name))) {
237 status = NT_STATUS_NO_MEMORY;
238 goto error;
241 if ((!(modtimes[i] = (NTTIME *)talloc_memdup(
242 modtimes, &modtime, sizeof(modtime))))) {
243 status = NT_STATUS_NO_MEMORY;
244 goto error;
248 *pnum_keys = num_subkeys;
250 if (pnames) {
251 *pnames = talloc_move(ctx, &names);
253 if (pclasses) {
254 *pclasses = talloc_move(ctx, &classes);
256 if (pmodtimes) {
257 *pmodtimes = talloc_move(ctx, &modtimes);
260 status = NT_STATUS_OK;
262 error:
263 TALLOC_FREE(mem_ctx);
264 return status;
267 static NTSTATUS registry_enumvalues(TALLOC_CTX *ctx,
268 struct rpc_pipe_client *pipe_hnd,
269 struct policy_handle *key_hnd,
270 uint32 *pnum_values, char ***pvalnames,
271 struct registry_value ***pvalues)
273 TALLOC_CTX *mem_ctx;
274 NTSTATUS status;
275 uint32 num_subkeys, max_subkeylen, max_classlen;
276 uint32 num_values, max_valnamelen, max_valbufsize;
277 uint32 i;
278 NTTIME last_changed_time;
279 uint32 secdescsize;
280 struct winreg_String classname;
281 struct registry_value **values;
282 char **names;
284 if (!(mem_ctx = talloc_new(ctx))) {
285 return NT_STATUS_NO_MEMORY;
288 ZERO_STRUCT(classname);
289 status = rpccli_winreg_QueryInfoKey(
290 pipe_hnd, mem_ctx, key_hnd, &classname, &num_subkeys,
291 &max_subkeylen, &max_classlen, &num_values, &max_valnamelen,
292 &max_valbufsize, &secdescsize, &last_changed_time, NULL );
294 if (!NT_STATUS_IS_OK(status)) {
295 goto error;
298 if (num_values == 0) {
299 *pnum_values = 0;
300 TALLOC_FREE(mem_ctx);
301 return NT_STATUS_OK;
304 if ((!(names = TALLOC_ARRAY(mem_ctx, char *, num_values))) ||
305 (!(values = TALLOC_ARRAY(mem_ctx, struct registry_value *,
306 num_values)))) {
307 status = NT_STATUS_NO_MEMORY;
308 goto error;
311 for (i=0; i<num_values; i++) {
312 enum winreg_Type type = REG_NONE;
313 uint8 *data = NULL;
314 uint32 data_size;
315 uint32 value_length;
317 char n;
318 struct winreg_ValNameBuf name_buf;
319 WERROR err;
321 n = '\0';
322 name_buf.name = &n;
323 name_buf.size = max_valnamelen + 2;
325 data_size = max_valbufsize;
326 data = (uint8 *)TALLOC(mem_ctx, data_size);
327 value_length = 0;
329 status = rpccli_winreg_EnumValue(pipe_hnd, mem_ctx, key_hnd,
330 i, &name_buf, &type,
331 data, &data_size,
332 &value_length, &err);
334 if ( W_ERROR_EQUAL(err,
335 WERR_NO_MORE_ITEMS) ) {
336 status = NT_STATUS_OK;
337 break;
340 if (!(NT_STATUS_IS_OK(status))) {
341 goto error;
344 if (name_buf.name == NULL) {
345 status = NT_STATUS_INVALID_PARAMETER;
346 goto error;
349 if (!(names[i] = talloc_strdup(names, name_buf.name))) {
350 status = NT_STATUS_NO_MEMORY;
351 goto error;
354 values[i] = talloc_zero(values, struct registry_value);
355 if (values[i] == NULL) {
356 status = NT_STATUS_NO_MEMORY;
357 goto error;
360 values[i]->type = type;
361 values[i]->data = data_blob_talloc(values[i], data, data_size);
364 *pnum_values = num_values;
366 if (pvalnames) {
367 *pvalnames = talloc_move(ctx, &names);
369 if (pvalues) {
370 *pvalues = talloc_move(ctx, &values);
373 status = NT_STATUS_OK;
375 error:
376 TALLOC_FREE(mem_ctx);
377 return status;
380 static NTSTATUS registry_getsd(TALLOC_CTX *mem_ctx,
381 struct rpc_pipe_client *pipe_hnd,
382 struct policy_handle *key_hnd,
383 uint32_t sec_info,
384 struct KeySecurityData *sd)
386 return rpccli_winreg_GetKeySecurity(pipe_hnd, mem_ctx, key_hnd,
387 sec_info, sd, NULL);
391 static NTSTATUS registry_setvalue(TALLOC_CTX *mem_ctx,
392 struct rpc_pipe_client *pipe_hnd,
393 struct policy_handle *key_hnd,
394 const char *name,
395 const struct registry_value *value)
397 struct winreg_String name_string;
398 NTSTATUS result;
400 ZERO_STRUCT(name_string);
402 name_string.name = name;
403 result = rpccli_winreg_SetValue(pipe_hnd, mem_ctx, key_hnd,
404 name_string, value->type,
405 value->data.data, value->data.length, NULL);
406 return result;
409 static NTSTATUS rpc_registry_setvalue_internal(struct net_context *c,
410 const struct dom_sid *domain_sid,
411 const char *domain_name,
412 struct cli_state *cli,
413 struct rpc_pipe_client *pipe_hnd,
414 TALLOC_CTX *mem_ctx,
415 int argc,
416 const char **argv )
418 struct policy_handle hive_hnd, key_hnd;
419 NTSTATUS status;
420 struct registry_value value;
422 status = registry_openkey(mem_ctx, pipe_hnd, argv[0],
423 SEC_FLAG_MAXIMUM_ALLOWED,
424 &hive_hnd, &key_hnd);
425 if (!NT_STATUS_IS_OK(status)) {
426 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
427 nt_errstr(status));
428 return status;
431 if (!strequal(argv[2], "multi_sz") && (argc != 4)) {
432 d_fprintf(stderr, _("Too many args for type %s\n"), argv[2]);
433 return NT_STATUS_NOT_IMPLEMENTED;
436 if (strequal(argv[2], "dword")) {
437 uint32_t v = strtoul(argv[3], NULL, 10);
438 value.type = REG_DWORD;
439 value.data = data_blob_talloc(mem_ctx, NULL, 4);
440 SIVAL(value.data.data, 0, v);
442 else if (strequal(argv[2], "sz")) {
443 value.type = REG_SZ;
444 if (!push_reg_sz(mem_ctx, &value.data, argv[3])) {
445 status = NT_STATUS_NO_MEMORY;
446 goto error;
449 else {
450 d_fprintf(stderr, _("type \"%s\" not implemented\n"), argv[2]);
451 status = NT_STATUS_NOT_IMPLEMENTED;
452 goto error;
455 status = registry_setvalue(mem_ctx, pipe_hnd, &key_hnd,
456 argv[1], &value);
458 if (!NT_STATUS_IS_OK(status)) {
459 d_fprintf(stderr, _("registry_setvalue failed: %s\n"),
460 nt_errstr(status));
463 error:
464 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &key_hnd, NULL);
465 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd, NULL);
467 return NT_STATUS_OK;
470 static int rpc_registry_setvalue(struct net_context *c, int argc,
471 const char **argv )
473 if (argc < 4 || c->display_usage) {
474 d_fprintf(stderr, "%s\n%s",
475 _("Usage:"),
476 _("net rpc registry setvalue <key> <valuename> "
477 "<type> [<val>]+\n"));
478 return -1;
481 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
482 rpc_registry_setvalue_internal, argc, argv );
485 static NTSTATUS rpc_registry_deletevalue_internal(struct net_context *c,
486 const struct dom_sid *domain_sid,
487 const char *domain_name,
488 struct cli_state *cli,
489 struct rpc_pipe_client *pipe_hnd,
490 TALLOC_CTX *mem_ctx,
491 int argc,
492 const char **argv )
494 struct policy_handle hive_hnd, key_hnd;
495 NTSTATUS status;
496 struct winreg_String valuename;
498 ZERO_STRUCT(valuename);
500 status = registry_openkey(mem_ctx, pipe_hnd, argv[0],
501 SEC_FLAG_MAXIMUM_ALLOWED,
502 &hive_hnd, &key_hnd);
503 if (!NT_STATUS_IS_OK(status)) {
504 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
505 nt_errstr(status));
506 return status;
509 valuename.name = argv[1];
511 status = rpccli_winreg_DeleteValue(pipe_hnd, mem_ctx, &key_hnd,
512 valuename, NULL);
514 if (!NT_STATUS_IS_OK(status)) {
515 d_fprintf(stderr, _("registry_deletevalue failed: %s\n"),
516 nt_errstr(status));
519 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &key_hnd, NULL);
520 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd, NULL);
522 return status;
525 static int rpc_registry_deletevalue(struct net_context *c, int argc,
526 const char **argv )
528 if (argc != 2 || c->display_usage) {
529 d_fprintf(stderr, "%s\n%s",
530 _("Usage:"),
531 _("net rpc registry deletevalue <key> <valuename>\n"));
532 return -1;
535 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
536 rpc_registry_deletevalue_internal, argc, argv );
539 static NTSTATUS rpc_registry_getvalue_internal(struct net_context *c,
540 const struct dom_sid *domain_sid,
541 const char *domain_name,
542 struct cli_state *cli,
543 struct rpc_pipe_client *pipe_hnd,
544 TALLOC_CTX *mem_ctx,
545 bool raw,
546 int argc,
547 const char **argv)
549 struct policy_handle hive_hnd, key_hnd;
550 NTSTATUS status;
551 struct winreg_String valuename;
552 struct registry_value *value = NULL;
553 enum winreg_Type type = REG_NONE;
554 uint32_t data_size = 0;
555 uint32_t value_length = 0;
556 TALLOC_CTX *tmp_ctx = talloc_stackframe();
558 ZERO_STRUCT(valuename);
560 status = registry_openkey(tmp_ctx, pipe_hnd, argv[0],
561 SEC_FLAG_MAXIMUM_ALLOWED,
562 &hive_hnd, &key_hnd);
563 if (!NT_STATUS_IS_OK(status)) {
564 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
565 nt_errstr(status));
566 return status;
569 valuename.name = argv[1];
571 value = talloc_zero(tmp_ctx, struct registry_value);
572 if (value == NULL) {
573 return NT_STATUS_NO_MEMORY;
577 * call QueryValue once with data == NULL to get the
578 * needed memory size to be allocated, then allocate
579 * data buffer and call again.
581 status = rpccli_winreg_QueryValue(pipe_hnd, tmp_ctx, &key_hnd,
582 &valuename,
583 &type,
584 NULL,
585 &data_size,
586 &value_length,
587 NULL);
589 if (!NT_STATUS_IS_OK(status)) {
590 d_fprintf(stderr, _("registry_queryvalue failed: %s\n"),
591 nt_errstr(status));
592 goto done;
595 value->data = data_blob_talloc(tmp_ctx, NULL, data_size);
597 status = rpccli_winreg_QueryValue(pipe_hnd, tmp_ctx, &key_hnd,
598 &valuename,
599 &type,
600 value->data.data,
601 &data_size,
602 &value_length,
603 NULL);
605 if (!NT_STATUS_IS_OK(status)) {
606 d_fprintf(stderr, _("registry_queryvalue failed: %s\n"),
607 nt_errstr(status));
608 goto done;
611 value->type = type;
613 print_registry_value(value, raw);
615 done:
616 rpccli_winreg_CloseKey(pipe_hnd, tmp_ctx, &key_hnd, NULL);
617 rpccli_winreg_CloseKey(pipe_hnd, tmp_ctx, &hive_hnd, NULL);
619 TALLOC_FREE(tmp_ctx);
621 return status;
624 static NTSTATUS rpc_registry_getvalue_full(struct net_context *c,
625 const struct dom_sid *domain_sid,
626 const char *domain_name,
627 struct cli_state *cli,
628 struct rpc_pipe_client *pipe_hnd,
629 TALLOC_CTX *mem_ctx,
630 int argc,
631 const char **argv)
633 return rpc_registry_getvalue_internal(c, domain_sid, domain_name,
634 cli, pipe_hnd, mem_ctx, false,
635 argc, argv);
638 static int rpc_registry_getvalue(struct net_context *c, int argc,
639 const char **argv)
641 if (argc != 2 || c->display_usage) {
642 d_fprintf(stderr, "%s\n%s",
643 _("Usage:"),
644 _("net rpc registry getvalue <key> <valuename>\n"));
645 return -1;
648 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
649 rpc_registry_getvalue_full, argc, argv);
652 static NTSTATUS rpc_registry_getvalue_raw(struct net_context *c,
653 const struct dom_sid *domain_sid,
654 const char *domain_name,
655 struct cli_state *cli,
656 struct rpc_pipe_client *pipe_hnd,
657 TALLOC_CTX *mem_ctx,
658 int argc,
659 const char **argv)
661 return rpc_registry_getvalue_internal(c, domain_sid, domain_name,
662 cli, pipe_hnd, mem_ctx, true,
663 argc, argv);
666 static int rpc_registry_getvalueraw(struct net_context *c, int argc,
667 const char **argv)
669 if (argc != 2 || c->display_usage) {
670 d_fprintf(stderr, "%s\n%s",
671 _("Usage:"),
672 _("net rpc registry getvalue <key> <valuename>\n"));
673 return -1;
676 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
677 rpc_registry_getvalue_raw, argc, argv);
680 static NTSTATUS rpc_registry_createkey_internal(struct net_context *c,
681 const struct dom_sid *domain_sid,
682 const char *domain_name,
683 struct cli_state *cli,
684 struct rpc_pipe_client *pipe_hnd,
685 TALLOC_CTX *mem_ctx,
686 int argc,
687 const char **argv )
689 uint32 hive;
690 struct policy_handle hive_hnd, key_hnd;
691 struct winreg_String key, keyclass;
692 enum winreg_CreateAction action;
693 NTSTATUS status;
695 ZERO_STRUCT(key);
696 ZERO_STRUCT(keyclass);
698 if (!reg_hive_key(mem_ctx, argv[0], &hive, &key.name)) {
699 return NT_STATUS_INVALID_PARAMETER;
702 status = rpccli_winreg_Connect(pipe_hnd, mem_ctx, hive,
703 SEC_FLAG_MAXIMUM_ALLOWED,
704 &hive_hnd);
705 if (!(NT_STATUS_IS_OK(status))) {
706 return status;
709 action = REG_ACTION_NONE;
710 keyclass.name = "";
712 status = rpccli_winreg_CreateKey(pipe_hnd, mem_ctx, &hive_hnd, key,
713 keyclass, 0, REG_KEY_READ, NULL,
714 &key_hnd, &action, NULL);
715 if (!NT_STATUS_IS_OK(status)) {
716 d_fprintf(stderr, _("createkey returned %s\n"),
717 nt_errstr(status));
718 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd, NULL);
719 return status;
722 switch (action) {
723 case REG_ACTION_NONE:
724 d_printf(_("createkey did nothing -- huh?\n"));
725 break;
726 case REG_CREATED_NEW_KEY:
727 d_printf(_("createkey created %s\n"), argv[0]);
728 break;
729 case REG_OPENED_EXISTING_KEY:
730 d_printf(_("createkey opened existing %s\n"), argv[0]);
731 break;
734 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &key_hnd, NULL);
735 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd, NULL);
737 return status;
740 static int rpc_registry_createkey(struct net_context *c, int argc,
741 const char **argv )
743 if (argc != 1 || c->display_usage) {
744 d_fprintf(stderr, "%s\n%s",
745 _("Usage:"),
746 _("net rpc registry createkey <key>\n"));
747 return -1;
750 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
751 rpc_registry_createkey_internal, argc, argv );
754 static NTSTATUS rpc_registry_deletekey_internal(struct net_context *c,
755 const struct dom_sid *domain_sid,
756 const char *domain_name,
757 struct cli_state *cli,
758 struct rpc_pipe_client *pipe_hnd,
759 TALLOC_CTX *mem_ctx,
760 int argc,
761 const char **argv )
763 uint32 hive;
764 struct policy_handle hive_hnd;
765 struct winreg_String key;
766 NTSTATUS status;
768 ZERO_STRUCT(key);
770 if (!reg_hive_key(mem_ctx, argv[0], &hive, &key.name)) {
771 return NT_STATUS_INVALID_PARAMETER;
774 status = rpccli_winreg_Connect(pipe_hnd, mem_ctx, hive,
775 SEC_FLAG_MAXIMUM_ALLOWED,
776 &hive_hnd);
777 if (!(NT_STATUS_IS_OK(status))) {
778 return status;
781 status = rpccli_winreg_DeleteKey(pipe_hnd, mem_ctx, &hive_hnd, key, NULL);
782 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd, NULL);
784 if (!NT_STATUS_IS_OK(status)) {
785 d_fprintf(stderr, _("deletekey returned %s\n"),
786 nt_errstr(status));
789 return status;
792 static int rpc_registry_deletekey(struct net_context *c, int argc, const char **argv )
794 if (argc != 1 || c->display_usage) {
795 d_fprintf(stderr, "%s\n%s",
796 _("Usage:"),
797 _("net rpc registry deletekey <key>\n"));
798 return -1;
801 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
802 rpc_registry_deletekey_internal, argc, argv );
805 /********************************************************************
806 ********************************************************************/
808 static NTSTATUS rpc_registry_enumerate_internal(struct net_context *c,
809 const struct dom_sid *domain_sid,
810 const char *domain_name,
811 struct cli_state *cli,
812 struct rpc_pipe_client *pipe_hnd,
813 TALLOC_CTX *mem_ctx,
814 int argc,
815 const char **argv )
817 struct policy_handle pol_hive, pol_key;
818 NTSTATUS status;
819 uint32 num_subkeys = 0;
820 uint32 num_values = 0;
821 char **names = NULL, **classes = NULL;
822 NTTIME **modtimes = NULL;
823 uint32 i;
824 struct registry_value **values = NULL;
826 if (argc != 1 || c->display_usage) {
827 d_printf("%s\n%s",
828 _("Usage:"),
829 _("net rpc registry enumerate <path>\n"));
830 d_printf("%s net rpc registry enumerate "
831 "'HKLM\\Software\\Samba'\n", _("Example:"));
832 return NT_STATUS_INVALID_PARAMETER;
835 status = registry_openkey(mem_ctx, pipe_hnd, argv[0], REG_KEY_READ,
836 &pol_hive, &pol_key);
837 if (!NT_STATUS_IS_OK(status)) {
838 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
839 nt_errstr(status));
840 return status;
843 status = registry_enumkeys(mem_ctx, pipe_hnd, &pol_key, &num_subkeys,
844 &names, &classes, &modtimes);
845 if (!NT_STATUS_IS_OK(status)) {
846 d_fprintf(stderr, _("enumerating keys failed: %s\n"),
847 nt_errstr(status));
848 return status;
851 for (i=0; i<num_subkeys; i++) {
852 print_registry_key(names[i], modtimes[i]);
855 status = registry_enumvalues(mem_ctx, pipe_hnd, &pol_key, &num_values,
856 &names, &values);
857 if (!NT_STATUS_IS_OK(status)) {
858 d_fprintf(stderr, _("enumerating values failed: %s\n"),
859 nt_errstr(status));
860 return status;
863 for (i=0; i<num_values; i++) {
864 print_registry_value_with_name(names[i], values[i]);
867 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_key, NULL);
868 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_hive, NULL);
870 return status;
873 /********************************************************************
874 ********************************************************************/
876 static int rpc_registry_enumerate(struct net_context *c, int argc,
877 const char **argv )
879 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
880 rpc_registry_enumerate_internal, argc, argv );
883 /********************************************************************
884 ********************************************************************/
886 static NTSTATUS rpc_registry_save_internal(struct net_context *c,
887 const struct dom_sid *domain_sid,
888 const char *domain_name,
889 struct cli_state *cli,
890 struct rpc_pipe_client *pipe_hnd,
891 TALLOC_CTX *mem_ctx,
892 int argc,
893 const char **argv )
895 WERROR result = WERR_GENERAL_FAILURE;
896 struct policy_handle pol_hive, pol_key;
897 NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
898 struct winreg_String filename;
900 if (argc != 2 || c->display_usage) {
901 d_printf("%s\n%s",
902 _("Usage:"),
903 _("net rpc registry backup <path> <file> \n"));
904 return NT_STATUS_INVALID_PARAMETER;
907 status = registry_openkey(mem_ctx, pipe_hnd, argv[0], REG_KEY_ALL,
908 &pol_hive, &pol_key);
909 if (!NT_STATUS_IS_OK(status)) {
910 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
911 nt_errstr(status));
912 return status;
915 filename.name = argv[1];
916 status = rpccli_winreg_SaveKey( pipe_hnd, mem_ctx, &pol_key, &filename, NULL, NULL);
917 if ( !W_ERROR_IS_OK(result) ) {
918 d_fprintf(stderr, _("Unable to save [%s] to %s:%s\n"), argv[0],
919 cli->desthost, argv[1]);
922 /* cleanup */
924 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_key, NULL);
925 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_hive, NULL);
927 return status;
930 /********************************************************************
931 ********************************************************************/
933 static int rpc_registry_save(struct net_context *c, int argc, const char **argv )
935 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
936 rpc_registry_save_internal, argc, argv );
940 /********************************************************************
941 ********************************************************************/
943 static void dump_values( REGF_NK_REC *nk )
945 int i, j;
946 const char *data_str = NULL;
947 uint32 data_size, data;
948 DATA_BLOB blob;
950 if ( !nk->values )
951 return;
953 for ( i=0; i<nk->num_values; i++ ) {
954 d_printf( "\"%s\" = ", nk->values[i].valuename ? nk->values[i].valuename : "(default)" );
955 d_printf( "(%s) ", str_regtype( nk->values[i].type ) );
957 data_size = nk->values[i].data_size & ~VK_DATA_IN_OFFSET;
958 switch ( nk->values[i].type ) {
959 case REG_SZ:
960 blob = data_blob_const(nk->values[i].data, data_size);
961 pull_reg_sz(talloc_tos(), &blob, &data_str);
962 if (!data_str) {
963 break;
965 d_printf( "%s", data_str );
966 break;
967 case REG_MULTI_SZ:
968 case REG_EXPAND_SZ:
969 for ( j=0; j<data_size; j++ ) {
970 d_printf( "%c", nk->values[i].data[j] );
972 break;
973 case REG_DWORD:
974 data = IVAL( nk->values[i].data, 0 );
975 d_printf("0x%x", data );
976 break;
977 case REG_BINARY:
978 for ( j=0; j<data_size; j++ ) {
979 d_printf( "%x", nk->values[i].data[j] );
981 break;
982 default:
983 d_printf(_("unknown"));
984 break;
987 d_printf( "\n" );
992 /********************************************************************
993 ********************************************************************/
995 static bool dump_registry_tree( REGF_FILE *file, REGF_NK_REC *nk, const char *parent )
997 REGF_NK_REC *key;
999 /* depth first dump of the registry tree */
1001 while ( (key = regfio_fetch_subkey( file, nk )) ) {
1002 char *regpath;
1003 if (asprintf(&regpath, "%s\\%s", parent, key->keyname) < 0) {
1004 break;
1006 d_printf("[%s]\n", regpath );
1007 dump_values( key );
1008 d_printf("\n");
1009 dump_registry_tree( file, key, regpath );
1010 SAFE_FREE(regpath);
1013 return true;
1016 /********************************************************************
1017 ********************************************************************/
1019 static bool write_registry_tree( REGF_FILE *infile, REGF_NK_REC *nk,
1020 REGF_NK_REC *parent, REGF_FILE *outfile,
1021 const char *parentpath )
1023 REGF_NK_REC *key, *subkey;
1024 struct regval_ctr *values = NULL;
1025 struct regsubkey_ctr *subkeys = NULL;
1026 int i;
1027 char *path = NULL;
1028 WERROR werr;
1030 werr = regsubkey_ctr_init(infile->mem_ctx, &subkeys);
1031 if (!W_ERROR_IS_OK(werr)) {
1032 DEBUG(0, ("write_registry_tree: regsubkey_ctr_init failed: "
1033 "%s\n", win_errstr(werr)));
1034 return false;
1037 werr = regval_ctr_init(subkeys, &values);
1038 if (!W_ERROR_IS_OK(werr)) {
1039 DEBUG(0,("write_registry_tree: talloc() failed!\n"));
1040 TALLOC_FREE(subkeys);
1041 return false;
1044 /* copy values into the struct regval_ctr */
1046 for ( i=0; i<nk->num_values; i++ ) {
1047 regval_ctr_addvalue( values, nk->values[i].valuename, nk->values[i].type,
1048 nk->values[i].data, (nk->values[i].data_size & ~VK_DATA_IN_OFFSET) );
1051 /* copy subkeys into the struct regsubkey_ctr */
1053 while ( (subkey = regfio_fetch_subkey( infile, nk )) ) {
1054 regsubkey_ctr_addkey( subkeys, subkey->keyname );
1057 key = regfio_write_key( outfile, nk->keyname, values, subkeys, nk->sec_desc->sec_desc, parent );
1059 /* write each one of the subkeys out */
1061 path = talloc_asprintf(subkeys,
1062 "%s%s%s",
1063 parentpath,
1064 parent ? "\\" : "",
1065 nk->keyname);
1066 if (!path) {
1067 TALLOC_FREE(subkeys);
1068 return false;
1071 nk->subkey_index = 0;
1072 while ( (subkey = regfio_fetch_subkey( infile, nk )) ) {
1073 write_registry_tree( infile, subkey, key, outfile, path );
1076 d_printf("[%s]\n", path );
1077 TALLOC_FREE(subkeys);
1079 return true;
1082 /********************************************************************
1083 ********************************************************************/
1085 static int rpc_registry_dump(struct net_context *c, int argc, const char **argv)
1087 REGF_FILE *registry;
1088 REGF_NK_REC *nk;
1090 if (argc != 1 || c->display_usage) {
1091 d_printf("%s\n%s",
1092 _("Usage:"),
1093 _("net rpc registry dump <file> \n"));
1094 return -1;
1097 d_printf(_("Opening %s...."), argv[0]);
1098 if ( !(registry = regfio_open( argv[0], O_RDONLY, 0)) ) {
1099 d_fprintf(stderr, _("Failed to open %s for reading\n"),argv[0]);
1100 return 1;
1102 d_printf(_("ok\n"));
1104 /* get the root of the registry file */
1106 if ((nk = regfio_rootkey( registry )) == NULL) {
1107 d_fprintf(stderr, _("Could not get rootkey\n"));
1108 regfio_close( registry );
1109 return 1;
1111 d_printf("[%s]\n", nk->keyname);
1112 dump_values( nk );
1113 d_printf("\n");
1115 dump_registry_tree( registry, nk, nk->keyname );
1117 #if 0
1118 talloc_report_full( registry->mem_ctx, stderr );
1119 #endif
1120 d_printf(_("Closing registry..."));
1121 regfio_close( registry );
1122 d_printf(_("ok\n"));
1124 return 0;
1127 /********************************************************************
1128 ********************************************************************/
1130 static int rpc_registry_copy(struct net_context *c, int argc, const char **argv )
1132 REGF_FILE *infile = NULL, *outfile = NULL;
1133 REGF_NK_REC *nk;
1134 int result = 1;
1136 if (argc != 2 || c->display_usage) {
1137 d_printf("%s\n%s",
1138 _("Usage:"),
1139 _("net rpc registry copy <srcfile> <newfile>\n"));
1140 return -1;
1143 d_printf(_("Opening %s...."), argv[0]);
1144 if ( !(infile = regfio_open( argv[0], O_RDONLY, 0 )) ) {
1145 d_fprintf(stderr, _("Failed to open %s for reading\n"),argv[0]);
1146 return 1;
1148 d_printf(_("ok\n"));
1150 d_printf(_("Opening %s...."), argv[1]);
1151 if ( !(outfile = regfio_open( argv[1], (O_RDWR|O_CREAT|O_TRUNC), (S_IREAD|S_IWRITE) )) ) {
1152 d_fprintf(stderr, _("Failed to open %s for writing\n"),argv[1]);
1153 goto out;
1155 d_printf(_("ok\n"));
1157 /* get the root of the registry file */
1159 if ((nk = regfio_rootkey( infile )) == NULL) {
1160 d_fprintf(stderr, _("Could not get rootkey\n"));
1161 goto out;
1163 d_printf(_("RootKey: [%s]\n"), nk->keyname);
1165 write_registry_tree( infile, nk, NULL, outfile, "" );
1167 result = 0;
1169 out:
1171 d_printf(_("Closing %s..."), argv[1]);
1172 if (outfile) {
1173 regfio_close( outfile );
1175 d_printf(_("ok\n"));
1177 d_printf(_("Closing %s..."), argv[0]);
1178 if (infile) {
1179 regfio_close( infile );
1181 d_printf(_("ok\n"));
1183 return( result);
1186 /********************************************************************
1187 ********************************************************************/
1189 static NTSTATUS rpc_registry_getsd_internal(struct net_context *c,
1190 const struct dom_sid *domain_sid,
1191 const char *domain_name,
1192 struct cli_state *cli,
1193 struct rpc_pipe_client *pipe_hnd,
1194 TALLOC_CTX *mem_ctx,
1195 int argc,
1196 const char **argv)
1198 struct policy_handle pol_hive, pol_key;
1199 NTSTATUS status;
1200 enum ndr_err_code ndr_err;
1201 struct KeySecurityData *sd = NULL;
1202 uint32_t sec_info;
1203 DATA_BLOB blob;
1204 struct security_descriptor sec_desc;
1205 uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED |
1206 SEC_FLAG_SYSTEM_SECURITY;
1208 if (argc <1 || argc > 2 || c->display_usage) {
1209 d_printf("%s\n%s",
1210 _("Usage:"),
1211 _("net rpc registry getsd <path> <secinfo>\n"));
1212 d_printf("%s net rpc registry getsd "
1213 "'HKLM\\Software\\Samba'\n", _("Example:"));
1214 return NT_STATUS_INVALID_PARAMETER;
1217 status = registry_openkey(mem_ctx, pipe_hnd, argv[0],
1218 access_mask,
1219 &pol_hive, &pol_key);
1220 if (!NT_STATUS_IS_OK(status)) {
1221 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
1222 nt_errstr(status));
1223 return status;
1226 sd = TALLOC_ZERO_P(mem_ctx, struct KeySecurityData);
1227 if (!sd) {
1228 status = NT_STATUS_NO_MEMORY;
1229 goto out;
1232 sd->size = 0x1000;
1234 if (argc >= 2) {
1235 sscanf(argv[1], "%x", &sec_info);
1236 } else {
1237 sec_info = SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL;
1240 status = registry_getsd(mem_ctx, pipe_hnd, &pol_key, sec_info, sd);
1241 if (!NT_STATUS_IS_OK(status)) {
1242 d_fprintf(stderr, _("getting sd failed: %s\n"),
1243 nt_errstr(status));
1244 goto out;
1247 blob.data = sd->data;
1248 blob.length = sd->size;
1250 ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &sec_desc,
1251 (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
1252 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1253 status = ndr_map_error2ntstatus(ndr_err);
1254 goto out;
1256 status = NT_STATUS_OK;
1258 display_sec_desc(&sec_desc);
1260 out:
1261 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_key, NULL);
1262 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_hive, NULL);
1264 return status;
1268 static int rpc_registry_getsd(struct net_context *c, int argc, const char **argv)
1270 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
1271 rpc_registry_getsd_internal, argc, argv);
1274 /********************************************************************
1275 ********************************************************************/
1277 int net_rpc_registry(struct net_context *c, int argc, const char **argv)
1279 struct functable func[] = {
1281 "enumerate",
1282 rpc_registry_enumerate,
1283 NET_TRANSPORT_RPC,
1284 N_("Enumerate registry keys and values"),
1285 N_("net rpc registry enumerate\n"
1286 " Enumerate registry keys and values")
1289 "createkey",
1290 rpc_registry_createkey,
1291 NET_TRANSPORT_RPC,
1292 N_("Create a new registry key"),
1293 N_("net rpc registry createkey\n"
1294 " Create a new registry key")
1297 "deletekey",
1298 rpc_registry_deletekey,
1299 NET_TRANSPORT_RPC,
1300 N_("Delete a registry key"),
1301 N_("net rpc registry deletekey\n"
1302 " Delete a registry key")
1305 "getvalue",
1306 rpc_registry_getvalue,
1307 NET_TRANSPORT_RPC,
1308 N_("Print a registry value"),
1309 N_("net rpc registry getvalue\n"
1310 " Print a registry value")
1313 "getvalueraw",
1314 rpc_registry_getvalueraw,
1315 NET_TRANSPORT_RPC,
1316 N_("Print a registry value"),
1317 N_("net rpc registry getvalueraw\n"
1318 " Print a registry value (raw version)")
1321 "setvalue",
1322 rpc_registry_setvalue,
1323 NET_TRANSPORT_RPC,
1324 N_("Set a new registry value"),
1325 N_("net rpc registry setvalue\n"
1326 " Set a new registry value")
1329 "deletevalue",
1330 rpc_registry_deletevalue,
1331 NET_TRANSPORT_RPC,
1332 N_("Delete a registry value"),
1333 N_("net rpc registry deletevalue\n"
1334 " Delete a registry value")
1337 "save",
1338 rpc_registry_save,
1339 NET_TRANSPORT_RPC,
1340 N_("Save a registry file"),
1341 N_("net rpc registry save\n"
1342 " Save a registry file")
1345 "dump",
1346 rpc_registry_dump,
1347 NET_TRANSPORT_RPC,
1348 N_("Dump a registry file"),
1349 N_("net rpc registry dump\n"
1350 " Dump a registry file")
1353 "copy",
1354 rpc_registry_copy,
1355 NET_TRANSPORT_RPC,
1356 N_("Copy a registry file"),
1357 N_("net rpc registry copy\n"
1358 " Copy a registry file")
1361 "getsd",
1362 rpc_registry_getsd,
1363 NET_TRANSPORT_RPC,
1364 N_("Get security descriptor"),
1365 N_("net rpc registry getsd\n"
1366 " Get security descriptior")
1368 {NULL, NULL, 0, NULL, NULL}
1371 return net_run_function(c, argc, argv, "net rpc registry", func);