s3: Fix bug #9085.
[Samba.git] / source3 / utils / net_rpc_registry.c
blob8f1a10de3ed6bdc292fac491167d19dbcb204432
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 "utils/net.h"
22 #include "utils/net_registry_util.h"
23 #include "regfio.h"
24 #include "reg_objects.h"
25 #include "../librpc/gen_ndr/cli_winreg.h"
27 /*******************************************************************
28 connect to a registry hive root (open a registry policy)
29 *******************************************************************/
31 static NTSTATUS rpccli_winreg_Connect(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
32 uint32_t reg_type, uint32_t access_mask,
33 struct policy_handle *reg_hnd)
35 ZERO_STRUCTP(reg_hnd);
37 switch (reg_type)
39 case HKEY_CLASSES_ROOT:
40 return rpccli_winreg_OpenHKCR( cli, mem_ctx, NULL,
41 access_mask, reg_hnd, NULL);
43 case HKEY_LOCAL_MACHINE:
44 return rpccli_winreg_OpenHKLM( cli, mem_ctx, NULL,
45 access_mask, reg_hnd, NULL);
47 case HKEY_USERS:
48 return rpccli_winreg_OpenHKU( cli, mem_ctx, NULL,
49 access_mask, reg_hnd, NULL);
51 case HKEY_CURRENT_USER:
52 return rpccli_winreg_OpenHKCU( cli, mem_ctx, NULL,
53 access_mask, reg_hnd, NULL);
55 case HKEY_PERFORMANCE_DATA:
56 return rpccli_winreg_OpenHKPD( cli, mem_ctx, NULL,
57 access_mask, reg_hnd, NULL);
59 default:
60 /* fall through to end of function */
61 break;
64 return NT_STATUS_INVALID_PARAMETER;
67 static bool reg_hive_key(TALLOC_CTX *ctx, const char *fullname,
68 uint32 *reg_type, const char **key_name)
70 WERROR werr;
71 char *hivename = NULL;
72 char *tmp_keyname = NULL;
73 bool ret = false;
74 TALLOC_CTX *tmp_ctx = talloc_stackframe();
76 werr = split_hive_key(tmp_ctx, fullname, &hivename, &tmp_keyname);
77 if (!W_ERROR_IS_OK(werr)) {
78 goto done;
81 *key_name = talloc_strdup(ctx, tmp_keyname);
82 if (*key_name == NULL) {
83 goto done;
86 if (strequal(hivename, "HKLM") ||
87 strequal(hivename, "HKEY_LOCAL_MACHINE"))
89 (*reg_type) = HKEY_LOCAL_MACHINE;
90 } else if (strequal(hivename, "HKCR") ||
91 strequal(hivename, "HKEY_CLASSES_ROOT"))
93 (*reg_type) = HKEY_CLASSES_ROOT;
94 } else if (strequal(hivename, "HKU") ||
95 strequal(hivename, "HKEY_USERS"))
97 (*reg_type) = HKEY_USERS;
98 } else if (strequal(hivename, "HKCU") ||
99 strequal(hivename, "HKEY_CURRENT_USER"))
101 (*reg_type) = HKEY_CURRENT_USER;
102 } else if (strequal(hivename, "HKPD") ||
103 strequal(hivename, "HKEY_PERFORMANCE_DATA"))
105 (*reg_type) = HKEY_PERFORMANCE_DATA;
106 } else {
107 DEBUG(10,("reg_hive_key: unrecognised hive key %s\n",
108 fullname));
109 goto done;
112 ret = true;
114 done:
115 TALLOC_FREE(tmp_ctx);
116 return ret;
119 static NTSTATUS registry_openkey(TALLOC_CTX *mem_ctx,
120 struct rpc_pipe_client *pipe_hnd,
121 const char *name, uint32 access_mask,
122 struct policy_handle *hive_hnd,
123 struct policy_handle *key_hnd)
125 uint32 hive;
126 NTSTATUS status;
127 struct winreg_String key;
129 ZERO_STRUCT(key);
131 if (!reg_hive_key(mem_ctx, name, &hive, &key.name)) {
132 return NT_STATUS_INVALID_PARAMETER;
135 status = rpccli_winreg_Connect(pipe_hnd, mem_ctx, hive, access_mask,
136 hive_hnd);
137 if (!(NT_STATUS_IS_OK(status))) {
138 return status;
141 status = rpccli_winreg_OpenKey(pipe_hnd, mem_ctx, hive_hnd, key, 0,
142 access_mask, key_hnd, NULL);
143 if (!(NT_STATUS_IS_OK(status))) {
144 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, hive_hnd, NULL);
145 return status;
148 return NT_STATUS_OK;
151 static NTSTATUS registry_enumkeys(TALLOC_CTX *ctx,
152 struct rpc_pipe_client *pipe_hnd,
153 struct policy_handle *key_hnd,
154 uint32 *pnum_keys, char ***pnames,
155 char ***pclasses, NTTIME ***pmodtimes)
157 TALLOC_CTX *mem_ctx;
158 NTSTATUS status;
159 uint32 num_subkeys, max_subkeylen, max_classlen;
160 uint32 num_values, max_valnamelen, max_valbufsize;
161 uint32 i;
162 NTTIME last_changed_time;
163 uint32 secdescsize;
164 struct winreg_String classname;
165 char **names, **classes;
166 NTTIME **modtimes;
168 if (!(mem_ctx = talloc_new(ctx))) {
169 return NT_STATUS_NO_MEMORY;
172 ZERO_STRUCT(classname);
173 status = rpccli_winreg_QueryInfoKey(
174 pipe_hnd, mem_ctx, key_hnd, &classname, &num_subkeys,
175 &max_subkeylen, &max_classlen, &num_values, &max_valnamelen,
176 &max_valbufsize, &secdescsize, &last_changed_time, NULL );
178 if (!NT_STATUS_IS_OK(status)) {
179 goto error;
182 if (num_subkeys == 0) {
183 *pnum_keys = 0;
184 TALLOC_FREE(mem_ctx);
185 return NT_STATUS_OK;
188 if ((!(names = TALLOC_ZERO_ARRAY(mem_ctx, char *, num_subkeys))) ||
189 (!(classes = TALLOC_ZERO_ARRAY(mem_ctx, char *, num_subkeys))) ||
190 (!(modtimes = TALLOC_ZERO_ARRAY(mem_ctx, NTTIME *,
191 num_subkeys)))) {
192 status = NT_STATUS_NO_MEMORY;
193 goto error;
196 for (i=0; i<num_subkeys; i++) {
197 char c, n;
198 struct winreg_StringBuf class_buf;
199 struct winreg_StringBuf name_buf;
200 NTTIME modtime;
201 WERROR werr;
203 c = '\0';
204 class_buf.name = &c;
205 class_buf.size = max_classlen+2;
207 n = '\0';
208 name_buf.name = &n;
209 name_buf.size = max_subkeylen+2;
211 ZERO_STRUCT(modtime);
213 status = rpccli_winreg_EnumKey(pipe_hnd, mem_ctx, key_hnd,
214 i, &name_buf, &class_buf,
215 &modtime, &werr);
217 if (W_ERROR_EQUAL(werr,
218 WERR_NO_MORE_ITEMS) ) {
219 status = NT_STATUS_OK;
220 break;
222 if (!NT_STATUS_IS_OK(status)) {
223 goto error;
226 classes[i] = NULL;
228 if (class_buf.name &&
229 (!(classes[i] = talloc_strdup(classes, class_buf.name)))) {
230 status = NT_STATUS_NO_MEMORY;
231 goto error;
234 if (!(names[i] = talloc_strdup(names, name_buf.name))) {
235 status = NT_STATUS_NO_MEMORY;
236 goto error;
239 if ((!(modtimes[i] = (NTTIME *)talloc_memdup(
240 modtimes, &modtime, sizeof(modtime))))) {
241 status = NT_STATUS_NO_MEMORY;
242 goto error;
246 *pnum_keys = num_subkeys;
248 if (pnames) {
249 *pnames = talloc_move(ctx, &names);
251 if (pclasses) {
252 *pclasses = talloc_move(ctx, &classes);
254 if (pmodtimes) {
255 *pmodtimes = talloc_move(ctx, &modtimes);
258 status = NT_STATUS_OK;
260 error:
261 TALLOC_FREE(mem_ctx);
262 return status;
265 static NTSTATUS registry_enumvalues(TALLOC_CTX *ctx,
266 struct rpc_pipe_client *pipe_hnd,
267 struct policy_handle *key_hnd,
268 uint32 *pnum_values, char ***pvalnames,
269 struct registry_value ***pvalues)
271 TALLOC_CTX *mem_ctx;
272 NTSTATUS status;
273 uint32 num_subkeys, max_subkeylen, max_classlen;
274 uint32 num_values, max_valnamelen, max_valbufsize;
275 uint32 i;
276 NTTIME last_changed_time;
277 uint32 secdescsize;
278 struct winreg_String classname;
279 struct registry_value **values;
280 char **names;
282 if (!(mem_ctx = talloc_new(ctx))) {
283 return NT_STATUS_NO_MEMORY;
286 ZERO_STRUCT(classname);
287 status = rpccli_winreg_QueryInfoKey(
288 pipe_hnd, mem_ctx, key_hnd, &classname, &num_subkeys,
289 &max_subkeylen, &max_classlen, &num_values, &max_valnamelen,
290 &max_valbufsize, &secdescsize, &last_changed_time, NULL );
292 if (!NT_STATUS_IS_OK(status)) {
293 goto error;
296 if (num_values == 0) {
297 *pnum_values = 0;
298 TALLOC_FREE(mem_ctx);
299 return NT_STATUS_OK;
302 if ((!(names = TALLOC_ARRAY(mem_ctx, char *, num_values))) ||
303 (!(values = TALLOC_ARRAY(mem_ctx, struct registry_value *,
304 num_values)))) {
305 status = NT_STATUS_NO_MEMORY;
306 goto error;
309 for (i=0; i<num_values; i++) {
310 enum winreg_Type type = REG_NONE;
311 uint8 *data = NULL;
312 uint32 data_size;
313 uint32 value_length;
315 char n;
316 struct winreg_ValNameBuf name_buf;
317 WERROR err;
319 n = '\0';
320 name_buf.name = &n;
321 name_buf.size = max_valnamelen + 2;
323 data_size = max_valbufsize;
324 data = (uint8 *)TALLOC(mem_ctx, data_size);
325 value_length = 0;
327 status = rpccli_winreg_EnumValue(pipe_hnd, mem_ctx, key_hnd,
328 i, &name_buf, &type,
329 data, &data_size,
330 &value_length, &err);
332 if ( W_ERROR_EQUAL(err,
333 WERR_NO_MORE_ITEMS) ) {
334 status = NT_STATUS_OK;
335 break;
338 if (!(NT_STATUS_IS_OK(status))) {
339 goto error;
342 if (name_buf.name == NULL) {
343 status = NT_STATUS_INVALID_PARAMETER;
344 goto error;
347 if (!(names[i] = talloc_strdup(names, name_buf.name))) {
348 status = NT_STATUS_NO_MEMORY;
349 goto error;
352 err = registry_pull_value(values, &values[i], type, data,
353 data_size, value_length);
354 if (!W_ERROR_IS_OK(err)) {
355 status = werror_to_ntstatus(err);
356 goto error;
360 *pnum_values = num_values;
362 if (pvalnames) {
363 *pvalnames = talloc_move(ctx, &names);
365 if (pvalues) {
366 *pvalues = talloc_move(ctx, &values);
369 status = NT_STATUS_OK;
371 error:
372 TALLOC_FREE(mem_ctx);
373 return status;
376 static NTSTATUS registry_getsd(TALLOC_CTX *mem_ctx,
377 struct rpc_pipe_client *pipe_hnd,
378 struct policy_handle *key_hnd,
379 uint32_t sec_info,
380 struct KeySecurityData *sd)
382 return rpccli_winreg_GetKeySecurity(pipe_hnd, mem_ctx, key_hnd,
383 sec_info, sd, NULL);
387 static NTSTATUS registry_setvalue(TALLOC_CTX *mem_ctx,
388 struct rpc_pipe_client *pipe_hnd,
389 struct policy_handle *key_hnd,
390 const char *name,
391 const struct registry_value *value)
393 struct winreg_String name_string;
394 DATA_BLOB blob;
395 NTSTATUS result;
396 WERROR err;
398 err = registry_push_value(mem_ctx, value, &blob);
399 if (!W_ERROR_IS_OK(err)) {
400 return werror_to_ntstatus(err);
403 ZERO_STRUCT(name_string);
405 name_string.name = name;
406 result = rpccli_winreg_SetValue(pipe_hnd, blob.data, key_hnd,
407 name_string, value->type,
408 blob.data, blob.length, NULL);
409 TALLOC_FREE(blob.data);
410 return result;
413 static NTSTATUS rpc_registry_setvalue_internal(struct net_context *c,
414 const DOM_SID *domain_sid,
415 const char *domain_name,
416 struct cli_state *cli,
417 struct rpc_pipe_client *pipe_hnd,
418 TALLOC_CTX *mem_ctx,
419 int argc,
420 const char **argv )
422 struct policy_handle hive_hnd, key_hnd;
423 NTSTATUS status;
424 struct registry_value value;
426 status = registry_openkey(mem_ctx, pipe_hnd, argv[0],
427 SEC_FLAG_MAXIMUM_ALLOWED,
428 &hive_hnd, &key_hnd);
429 if (!NT_STATUS_IS_OK(status)) {
430 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
431 nt_errstr(status));
432 return status;
435 if (!strequal(argv[2], "multi_sz") && (argc != 4)) {
436 d_fprintf(stderr, _("Too many args for type %s\n"), argv[2]);
437 return NT_STATUS_NOT_IMPLEMENTED;
440 if (strequal(argv[2], "dword")) {
441 value.type = REG_DWORD;
442 value.v.dword = strtoul(argv[3], NULL, 10);
444 else if (strequal(argv[2], "sz")) {
445 value.type = REG_SZ;
446 value.v.sz.len = strlen(argv[3])+1;
447 value.v.sz.str = CONST_DISCARD(char *, argv[3]);
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 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 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 WERROR werr;
552 struct winreg_String valuename;
553 struct registry_value *value = NULL;
554 enum winreg_Type type = REG_NONE;
555 uint8_t *data = NULL;
556 uint32_t data_size = 0;
557 uint32_t value_length = 0;
558 TALLOC_CTX *tmp_ctx = talloc_stackframe();
560 ZERO_STRUCT(valuename);
562 status = registry_openkey(tmp_ctx, pipe_hnd, argv[0],
563 SEC_FLAG_MAXIMUM_ALLOWED,
564 &hive_hnd, &key_hnd);
565 if (!NT_STATUS_IS_OK(status)) {
566 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
567 nt_errstr(status));
568 return status;
571 valuename.name = argv[1];
574 * call QueryValue once with data == NULL to get the
575 * needed memory size to be allocated, then allocate
576 * data buffer and call again.
578 status = rpccli_winreg_QueryValue(pipe_hnd, tmp_ctx, &key_hnd,
579 &valuename,
580 &type,
581 data,
582 &data_size,
583 &value_length,
584 NULL);
586 if (!NT_STATUS_IS_OK(status)) {
587 d_fprintf(stderr, _("registry_queryvalue failed: %s\n"),
588 nt_errstr(status));
589 goto done;
592 data = (uint8 *)TALLOC(tmp_ctx, data_size);
593 value_length = 0;
595 status = rpccli_winreg_QueryValue(pipe_hnd, tmp_ctx, &key_hnd,
596 &valuename,
597 &type,
598 data,
599 &data_size,
600 &value_length,
601 NULL);
603 if (!NT_STATUS_IS_OK(status)) {
604 d_fprintf(stderr, _("registry_queryvalue failed: %s\n"),
605 nt_errstr(status));
606 goto done;
609 werr = registry_pull_value(tmp_ctx, &value, type, data,
610 data_size, value_length);
611 if (!W_ERROR_IS_OK(werr)) {
612 status = werror_to_ntstatus(werr);
613 goto done;
616 print_registry_value(value, raw);
618 done:
619 rpccli_winreg_CloseKey(pipe_hnd, tmp_ctx, &key_hnd, NULL);
620 rpccli_winreg_CloseKey(pipe_hnd, tmp_ctx, &hive_hnd, NULL);
622 TALLOC_FREE(tmp_ctx);
624 return status;
627 static NTSTATUS rpc_registry_getvalue_full(struct net_context *c,
628 const DOM_SID *domain_sid,
629 const char *domain_name,
630 struct cli_state *cli,
631 struct rpc_pipe_client *pipe_hnd,
632 TALLOC_CTX *mem_ctx,
633 int argc,
634 const char **argv)
636 return rpc_registry_getvalue_internal(c, domain_sid, domain_name,
637 cli, pipe_hnd, mem_ctx, false,
638 argc, argv);
641 static int rpc_registry_getvalue(struct net_context *c, int argc,
642 const char **argv)
644 if (argc != 2 || c->display_usage) {
645 d_fprintf(stderr, "%s\n%s",
646 _("Usage:"),
647 _("net rpc registry getvalue <key> <valuename>\n"));
648 return -1;
651 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
652 rpc_registry_getvalue_full, argc, argv);
655 static NTSTATUS rpc_registry_getvalue_raw(struct net_context *c,
656 const DOM_SID *domain_sid,
657 const char *domain_name,
658 struct cli_state *cli,
659 struct rpc_pipe_client *pipe_hnd,
660 TALLOC_CTX *mem_ctx,
661 int argc,
662 const char **argv)
664 return rpc_registry_getvalue_internal(c, domain_sid, domain_name,
665 cli, pipe_hnd, mem_ctx, true,
666 argc, argv);
669 static int rpc_registry_getvalueraw(struct net_context *c, int argc,
670 const char **argv)
672 if (argc != 2 || c->display_usage) {
673 d_fprintf(stderr, "%s\n%s",
674 _("Usage:"),
675 _("net rpc registry getvalue <key> <valuename>\n"));
676 return -1;
679 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
680 rpc_registry_getvalue_raw, argc, argv);
683 static NTSTATUS rpc_registry_createkey_internal(struct net_context *c,
684 const DOM_SID *domain_sid,
685 const char *domain_name,
686 struct cli_state *cli,
687 struct rpc_pipe_client *pipe_hnd,
688 TALLOC_CTX *mem_ctx,
689 int argc,
690 const char **argv )
692 uint32 hive;
693 struct policy_handle hive_hnd, key_hnd;
694 struct winreg_String key, keyclass;
695 enum winreg_CreateAction action;
696 NTSTATUS status;
698 ZERO_STRUCT(key);
699 ZERO_STRUCT(keyclass);
701 if (!reg_hive_key(mem_ctx, argv[0], &hive, &key.name)) {
702 return NT_STATUS_INVALID_PARAMETER;
705 status = rpccli_winreg_Connect(pipe_hnd, mem_ctx, hive,
706 SEC_FLAG_MAXIMUM_ALLOWED,
707 &hive_hnd);
708 if (!(NT_STATUS_IS_OK(status))) {
709 return status;
712 action = REG_ACTION_NONE;
713 keyclass.name = "";
715 status = rpccli_winreg_CreateKey(pipe_hnd, mem_ctx, &hive_hnd, key,
716 keyclass, 0, REG_KEY_READ, NULL,
717 &key_hnd, &action, NULL);
718 if (!NT_STATUS_IS_OK(status)) {
719 d_fprintf(stderr, _("createkey returned %s\n"),
720 nt_errstr(status));
721 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd, NULL);
722 return status;
725 switch (action) {
726 case REG_ACTION_NONE:
727 d_printf(_("createkey did nothing -- huh?\n"));
728 break;
729 case REG_CREATED_NEW_KEY:
730 d_printf(_("createkey created %s\n"), argv[0]);
731 break;
732 case REG_OPENED_EXISTING_KEY:
733 d_printf(_("createkey opened existing %s\n"), argv[0]);
734 break;
737 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &key_hnd, NULL);
738 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd, NULL);
740 return status;
743 static int rpc_registry_createkey(struct net_context *c, int argc,
744 const char **argv )
746 if (argc != 1 || c->display_usage) {
747 d_fprintf(stderr, "%s\n%s",
748 _("Usage:"),
749 _("net rpc registry createkey <key>\n"));
750 return -1;
753 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
754 rpc_registry_createkey_internal, argc, argv );
757 static NTSTATUS rpc_registry_deletekey_internal(struct net_context *c,
758 const DOM_SID *domain_sid,
759 const char *domain_name,
760 struct cli_state *cli,
761 struct rpc_pipe_client *pipe_hnd,
762 TALLOC_CTX *mem_ctx,
763 int argc,
764 const char **argv )
766 uint32 hive;
767 struct policy_handle hive_hnd;
768 struct winreg_String key;
769 NTSTATUS status;
771 ZERO_STRUCT(key);
773 if (!reg_hive_key(mem_ctx, argv[0], &hive, &key.name)) {
774 return NT_STATUS_INVALID_PARAMETER;
777 status = rpccli_winreg_Connect(pipe_hnd, mem_ctx, hive,
778 SEC_FLAG_MAXIMUM_ALLOWED,
779 &hive_hnd);
780 if (!(NT_STATUS_IS_OK(status))) {
781 return status;
784 status = rpccli_winreg_DeleteKey(pipe_hnd, mem_ctx, &hive_hnd, key, NULL);
785 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd, NULL);
787 if (!NT_STATUS_IS_OK(status)) {
788 d_fprintf(stderr, _("deletekey returned %s\n"),
789 nt_errstr(status));
792 return status;
795 static int rpc_registry_deletekey(struct net_context *c, int argc, const char **argv )
797 if (argc != 1 || c->display_usage) {
798 d_fprintf(stderr, "%s\n%s",
799 _("Usage:"),
800 _("net rpc registry deletekey <key>\n"));
801 return -1;
804 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
805 rpc_registry_deletekey_internal, argc, argv );
808 /********************************************************************
809 ********************************************************************/
811 static NTSTATUS rpc_registry_enumerate_internal(struct net_context *c,
812 const DOM_SID *domain_sid,
813 const char *domain_name,
814 struct cli_state *cli,
815 struct rpc_pipe_client *pipe_hnd,
816 TALLOC_CTX *mem_ctx,
817 int argc,
818 const char **argv )
820 struct policy_handle pol_hive, pol_key;
821 NTSTATUS status;
822 uint32 num_subkeys = 0;
823 uint32 num_values = 0;
824 char **names = NULL, **classes = NULL;
825 NTTIME **modtimes = NULL;
826 uint32 i;
827 struct registry_value **values = NULL;
829 if (argc != 1 || c->display_usage) {
830 d_printf("%s\n%s",
831 _("Usage:"),
832 _("net rpc registry enumerate <path>\n"));
833 d_printf("%s net rpc registry enumerate "
834 "'HKLM\\Software\\Samba'\n", _("Example:"));
835 return NT_STATUS_INVALID_PARAMETER;
838 status = registry_openkey(mem_ctx, pipe_hnd, argv[0], REG_KEY_READ,
839 &pol_hive, &pol_key);
840 if (!NT_STATUS_IS_OK(status)) {
841 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
842 nt_errstr(status));
843 return status;
846 status = registry_enumkeys(mem_ctx, pipe_hnd, &pol_key, &num_subkeys,
847 &names, &classes, &modtimes);
848 if (!NT_STATUS_IS_OK(status)) {
849 d_fprintf(stderr, _("enumerating keys failed: %s\n"),
850 nt_errstr(status));
851 return status;
854 for (i=0; i<num_subkeys; i++) {
855 print_registry_key(names[i], modtimes[i]);
858 status = registry_enumvalues(mem_ctx, pipe_hnd, &pol_key, &num_values,
859 &names, &values);
860 if (!NT_STATUS_IS_OK(status)) {
861 d_fprintf(stderr, _("enumerating values failed: %s\n"),
862 nt_errstr(status));
863 return status;
866 for (i=0; i<num_values; i++) {
867 print_registry_value_with_name(names[i], values[i]);
870 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_key, NULL);
871 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_hive, NULL);
873 return status;
876 /********************************************************************
877 ********************************************************************/
879 static int rpc_registry_enumerate(struct net_context *c, int argc,
880 const char **argv )
882 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
883 rpc_registry_enumerate_internal, argc, argv );
886 /********************************************************************
887 ********************************************************************/
889 static NTSTATUS rpc_registry_save_internal(struct net_context *c,
890 const DOM_SID *domain_sid,
891 const char *domain_name,
892 struct cli_state *cli,
893 struct rpc_pipe_client *pipe_hnd,
894 TALLOC_CTX *mem_ctx,
895 int argc,
896 const char **argv )
898 WERROR result = WERR_GENERAL_FAILURE;
899 struct policy_handle pol_hive, pol_key;
900 NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
901 struct winreg_String filename;
903 if (argc != 2 || c->display_usage) {
904 d_printf("%s\n%s",
905 _("Usage:"),
906 _("net rpc registry backup <path> <file> \n"));
907 return NT_STATUS_INVALID_PARAMETER;
910 status = registry_openkey(mem_ctx, pipe_hnd, argv[0], REG_KEY_ALL,
911 &pol_hive, &pol_key);
912 if (!NT_STATUS_IS_OK(status)) {
913 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
914 nt_errstr(status));
915 return status;
918 filename.name = argv[1];
919 status = rpccli_winreg_SaveKey( pipe_hnd, mem_ctx, &pol_key, &filename, NULL, NULL);
920 if ( !W_ERROR_IS_OK(result) ) {
921 d_fprintf(stderr, _("Unable to save [%s] to %s:%s\n"), argv[0],
922 cli->desthost, argv[1]);
925 /* cleanup */
927 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_key, NULL);
928 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_hive, NULL);
930 return status;
933 /********************************************************************
934 ********************************************************************/
936 static int rpc_registry_save(struct net_context *c, int argc, const char **argv )
938 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
939 rpc_registry_save_internal, argc, argv );
943 /********************************************************************
944 ********************************************************************/
946 static void dump_values( REGF_NK_REC *nk )
948 int i, j;
949 const char *data_str = NULL;
950 uint32 data_size, data;
951 DATA_BLOB blob;
953 if ( !nk->values )
954 return;
956 for ( i=0; i<nk->num_values; i++ ) {
957 d_printf( "\"%s\" = ", nk->values[i].valuename ? nk->values[i].valuename : "(default)" );
958 d_printf( "(%s) ", reg_type_lookup( nk->values[i].type ) );
960 data_size = nk->values[i].data_size & ~VK_DATA_IN_OFFSET;
961 switch ( nk->values[i].type ) {
962 case REG_SZ:
963 blob = data_blob_const(nk->values[i].data, data_size);
964 pull_reg_sz(talloc_tos(), &blob, &data_str);
965 if (!data_str) {
966 break;
968 d_printf( "%s", data_str );
969 break;
970 case REG_MULTI_SZ:
971 case REG_EXPAND_SZ:
972 for ( j=0; j<data_size; j++ ) {
973 d_printf( "%c", nk->values[i].data[j] );
975 break;
976 case REG_DWORD:
977 data = IVAL( nk->values[i].data, 0 );
978 d_printf("0x%x", data );
979 break;
980 case REG_BINARY:
981 for ( j=0; j<data_size; j++ ) {
982 d_printf( "%x", nk->values[i].data[j] );
984 break;
985 default:
986 d_printf(_("unknown"));
987 break;
990 d_printf( "\n" );
995 /********************************************************************
996 ********************************************************************/
998 static bool dump_registry_tree( REGF_FILE *file, REGF_NK_REC *nk, const char *parent )
1000 REGF_NK_REC *key;
1002 /* depth first dump of the registry tree */
1004 while ( (key = regfio_fetch_subkey( file, nk )) ) {
1005 char *regpath;
1006 if (asprintf(&regpath, "%s\\%s", parent, key->keyname) < 0) {
1007 break;
1009 d_printf("[%s]\n", regpath );
1010 dump_values( key );
1011 d_printf("\n");
1012 dump_registry_tree( file, key, regpath );
1013 SAFE_FREE(regpath);
1016 return true;
1019 /********************************************************************
1020 ********************************************************************/
1022 static bool write_registry_tree( REGF_FILE *infile, REGF_NK_REC *nk,
1023 REGF_NK_REC *parent, REGF_FILE *outfile,
1024 const char *parentpath )
1026 REGF_NK_REC *key, *subkey;
1027 struct regval_ctr *values = NULL;
1028 struct regsubkey_ctr *subkeys = NULL;
1029 int i;
1030 char *path = NULL;
1031 WERROR werr;
1033 werr = regsubkey_ctr_init(infile->mem_ctx, &subkeys);
1034 if (!W_ERROR_IS_OK(werr)) {
1035 DEBUG(0, ("write_registry_tree: regsubkey_ctr_init failed: "
1036 "%s\n", win_errstr(werr)));
1037 return false;
1040 if ( !(values = TALLOC_ZERO_P( subkeys, struct regval_ctr )) ) {
1041 DEBUG(0,("write_registry_tree: talloc() failed!\n"));
1042 TALLOC_FREE(subkeys);
1043 return false;
1046 /* copy values into the struct regval_ctr */
1048 for ( i=0; i<nk->num_values; i++ ) {
1049 regval_ctr_addvalue( values, nk->values[i].valuename, nk->values[i].type,
1050 (const char *)nk->values[i].data, (nk->values[i].data_size & ~VK_DATA_IN_OFFSET) );
1053 /* copy subkeys into the struct regsubkey_ctr */
1055 while ( (subkey = regfio_fetch_subkey( infile, nk )) ) {
1056 regsubkey_ctr_addkey( subkeys, subkey->keyname );
1059 key = regfio_write_key( outfile, nk->keyname, values, subkeys, nk->sec_desc->sec_desc, parent );
1061 /* write each one of the subkeys out */
1063 path = talloc_asprintf(subkeys,
1064 "%s%s%s",
1065 parentpath,
1066 parent ? "\\" : "",
1067 nk->keyname);
1068 if (!path) {
1069 TALLOC_FREE(subkeys);
1070 return false;
1073 nk->subkey_index = 0;
1074 while ( (subkey = regfio_fetch_subkey( infile, nk )) ) {
1075 write_registry_tree( infile, subkey, key, outfile, path );
1078 d_printf("[%s]\n", path );
1079 TALLOC_FREE(subkeys);
1081 return true;
1084 /********************************************************************
1085 ********************************************************************/
1087 static int rpc_registry_dump(struct net_context *c, int argc, const char **argv)
1089 REGF_FILE *registry;
1090 REGF_NK_REC *nk;
1092 if (argc != 1 || c->display_usage) {
1093 d_printf("%s\n%s",
1094 _("Usage:"),
1095 _("net rpc registry dump <file> \n"));
1096 return -1;
1099 d_printf(_("Opening %s...."), argv[0]);
1100 if ( !(registry = regfio_open( argv[0], O_RDONLY, 0)) ) {
1101 d_fprintf(stderr, _("Failed to open %s for reading\n"),argv[0]);
1102 return 1;
1104 d_printf(_("ok\n"));
1106 /* get the root of the registry file */
1108 if ((nk = regfio_rootkey( registry )) == NULL) {
1109 d_fprintf(stderr, _("Could not get rootkey\n"));
1110 regfio_close( registry );
1111 return 1;
1113 d_printf("[%s]\n", nk->keyname);
1114 dump_values( nk );
1115 d_printf("\n");
1117 dump_registry_tree( registry, nk, nk->keyname );
1119 #if 0
1120 talloc_report_full( registry->mem_ctx, stderr );
1121 #endif
1122 d_printf(_("Closing registry..."));
1123 regfio_close( registry );
1124 d_printf(_("ok\n"));
1126 return 0;
1129 /********************************************************************
1130 ********************************************************************/
1132 static int rpc_registry_copy(struct net_context *c, int argc, const char **argv )
1134 REGF_FILE *infile = NULL, *outfile = NULL;
1135 REGF_NK_REC *nk;
1136 int result = 1;
1138 if (argc != 2 || c->display_usage) {
1139 d_printf("%s\n%s",
1140 _("Usage:"),
1141 _("net rpc registry copy <srcfile> <newfile>\n"));
1142 return -1;
1145 d_printf(_("Opening %s...."), argv[0]);
1146 if ( !(infile = regfio_open( argv[0], O_RDONLY, 0 )) ) {
1147 d_fprintf(stderr, _("Failed to open %s for reading\n"),argv[0]);
1148 return 1;
1150 d_printf(_("ok\n"));
1152 d_printf(_("Opening %s...."), argv[1]);
1153 if ( !(outfile = regfio_open( argv[1], (O_RDWR|O_CREAT|O_TRUNC),
1154 (S_IRUSR|S_IWUSR) )) ) {
1155 d_fprintf(stderr, _("Failed to open %s for writing\n"),argv[1]);
1156 goto out;
1158 d_printf(_("ok\n"));
1160 /* get the root of the registry file */
1162 if ((nk = regfio_rootkey( infile )) == NULL) {
1163 d_fprintf(stderr, _("Could not get rootkey\n"));
1164 goto out;
1166 d_printf(_("RootKey: [%s]\n"), nk->keyname);
1168 write_registry_tree( infile, nk, NULL, outfile, "" );
1170 result = 0;
1172 out:
1174 d_printf(_("Closing %s..."), argv[1]);
1175 if (outfile) {
1176 regfio_close( outfile );
1178 d_printf(_("ok\n"));
1180 d_printf(_("Closing %s..."), argv[0]);
1181 if (infile) {
1182 regfio_close( infile );
1184 d_printf(_("ok\n"));
1186 return( result);
1189 /********************************************************************
1190 ********************************************************************/
1192 static NTSTATUS rpc_registry_getsd_internal(struct net_context *c,
1193 const DOM_SID *domain_sid,
1194 const char *domain_name,
1195 struct cli_state *cli,
1196 struct rpc_pipe_client *pipe_hnd,
1197 TALLOC_CTX *mem_ctx,
1198 int argc,
1199 const char **argv)
1201 struct policy_handle pol_hive, pol_key;
1202 NTSTATUS status;
1203 enum ndr_err_code ndr_err;
1204 struct KeySecurityData *sd = NULL;
1205 uint32_t sec_info;
1206 DATA_BLOB blob;
1207 struct security_descriptor sec_desc;
1208 uint32_t access_mask = REG_KEY_READ |
1209 SEC_FLAG_MAXIMUM_ALLOWED |
1210 SEC_FLAG_SYSTEM_SECURITY;
1212 if (argc <1 || argc > 2 || c->display_usage) {
1213 d_printf("%s\n%s",
1214 _("Usage:"),
1215 _("net rpc registry getsd <path> <secinfo>\n"));
1216 d_printf("%s net rpc registry getsd "
1217 "'HKLM\\Software\\Samba'\n", _("Example:"));
1218 return NT_STATUS_INVALID_PARAMETER;
1221 status = registry_openkey(mem_ctx, pipe_hnd, argv[0],
1222 access_mask,
1223 &pol_hive, &pol_key);
1224 if (!NT_STATUS_IS_OK(status)) {
1225 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
1226 nt_errstr(status));
1227 return status;
1230 sd = TALLOC_ZERO_P(mem_ctx, struct KeySecurityData);
1231 if (!sd) {
1232 status = NT_STATUS_NO_MEMORY;
1233 goto out;
1236 sd->size = 0x1000;
1238 if (argc >= 2) {
1239 sscanf(argv[1], "%x", &sec_info);
1240 } else {
1241 sec_info = SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL;
1244 status = registry_getsd(mem_ctx, pipe_hnd, &pol_key, sec_info, sd);
1245 if (!NT_STATUS_IS_OK(status)) {
1246 d_fprintf(stderr, _("getting sd failed: %s\n"),
1247 nt_errstr(status));
1248 goto out;
1251 blob.data = sd->data;
1252 blob.length = sd->size;
1254 ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, NULL, &sec_desc,
1255 (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
1256 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1257 status = ndr_map_error2ntstatus(ndr_err);
1258 goto out;
1260 status = NT_STATUS_OK;
1262 display_sec_desc(&sec_desc);
1264 out:
1265 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_key, NULL);
1266 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_hive, NULL);
1268 return status;
1272 static int rpc_registry_getsd(struct net_context *c, int argc, const char **argv)
1274 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
1275 rpc_registry_getsd_internal, argc, argv);
1278 /********************************************************************
1279 ********************************************************************/
1281 int net_rpc_registry(struct net_context *c, int argc, const char **argv)
1283 struct functable func[] = {
1285 "enumerate",
1286 rpc_registry_enumerate,
1287 NET_TRANSPORT_RPC,
1288 N_("Enumerate registry keys and values"),
1289 N_("net rpc registry enumerate\n"
1290 " Enumerate registry keys and values")
1293 "createkey",
1294 rpc_registry_createkey,
1295 NET_TRANSPORT_RPC,
1296 N_("Create a new registry key"),
1297 N_("net rpc registry createkey\n"
1298 " Create a new registry key")
1301 "deletekey",
1302 rpc_registry_deletekey,
1303 NET_TRANSPORT_RPC,
1304 N_("Delete a registry key"),
1305 N_("net rpc registry deletekey\n"
1306 " Delete a registry key")
1309 "getvalue",
1310 rpc_registry_getvalue,
1311 NET_TRANSPORT_RPC,
1312 N_("Print a registry value"),
1313 N_("net rpc registry getvalue\n"
1314 " Print a registry value")
1317 "getvalueraw",
1318 rpc_registry_getvalueraw,
1319 NET_TRANSPORT_RPC,
1320 N_("Print a registry value"),
1321 N_("net rpc registry getvalueraw\n"
1322 " Print a registry value (raw version)")
1325 "setvalue",
1326 rpc_registry_setvalue,
1327 NET_TRANSPORT_RPC,
1328 N_("Set a new registry value"),
1329 N_("net rpc registry setvalue\n"
1330 " Set a new registry value")
1333 "deletevalue",
1334 rpc_registry_deletevalue,
1335 NET_TRANSPORT_RPC,
1336 N_("Delete a registry value"),
1337 N_("net rpc registry deletevalue\n"
1338 " Delete a registry value")
1341 "save",
1342 rpc_registry_save,
1343 NET_TRANSPORT_RPC,
1344 N_("Save a registry file"),
1345 N_("net rpc registry save\n"
1346 " Save a registry file")
1349 "dump",
1350 rpc_registry_dump,
1351 NET_TRANSPORT_RPC,
1352 N_("Dump a registry file"),
1353 N_("net rpc registry dump\n"
1354 " Dump a registry file")
1357 "copy",
1358 rpc_registry_copy,
1359 NET_TRANSPORT_RPC,
1360 N_("Copy a registry file"),
1361 N_("net rpc registry copy\n"
1362 " Copy a registry file")
1365 "getsd",
1366 rpc_registry_getsd,
1367 NET_TRANSPORT_RPC,
1368 N_("Get security descriptor"),
1369 N_("net rpc registry getsd\n"
1370 " Get security descriptior")
1372 {NULL, NULL, 0, NULL, NULL}
1375 return net_run_function(c, argc, argv, "net rpc registry", func);