s3:net rpc registry: use regval_ctr_init() instead of direct allocation
[Samba/ekacnet.git] / source3 / utils / net_rpc_registry.c
blobdb2e8d62057d34c30ef0740885ef8dee74f78714
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_util_marshalling.h"
28 /*******************************************************************
29 connect to a registry hive root (open a registry policy)
30 *******************************************************************/
32 static NTSTATUS rpccli_winreg_Connect(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
33 uint32_t reg_type, uint32_t access_mask,
34 struct policy_handle *reg_hnd)
36 ZERO_STRUCTP(reg_hnd);
38 switch (reg_type)
40 case HKEY_CLASSES_ROOT:
41 return rpccli_winreg_OpenHKCR( cli, mem_ctx, NULL,
42 access_mask, reg_hnd, NULL);
44 case HKEY_LOCAL_MACHINE:
45 return rpccli_winreg_OpenHKLM( cli, mem_ctx, NULL,
46 access_mask, reg_hnd, NULL);
48 case HKEY_USERS:
49 return rpccli_winreg_OpenHKU( cli, mem_ctx, NULL,
50 access_mask, reg_hnd, NULL);
52 case HKEY_CURRENT_USER:
53 return rpccli_winreg_OpenHKCU( cli, mem_ctx, NULL,
54 access_mask, reg_hnd, NULL);
56 case HKEY_PERFORMANCE_DATA:
57 return rpccli_winreg_OpenHKPD( cli, mem_ctx, NULL,
58 access_mask, reg_hnd, NULL);
60 default:
61 /* fall through to end of function */
62 break;
65 return NT_STATUS_INVALID_PARAMETER;
68 static bool reg_hive_key(TALLOC_CTX *ctx, const char *fullname,
69 uint32 *reg_type, const char **key_name)
71 WERROR werr;
72 char *hivename = NULL;
73 char *tmp_keyname = NULL;
74 bool ret = false;
75 TALLOC_CTX *tmp_ctx = talloc_stackframe();
77 werr = split_hive_key(tmp_ctx, fullname, &hivename, &tmp_keyname);
78 if (!W_ERROR_IS_OK(werr)) {
79 goto done;
82 *key_name = talloc_strdup(ctx, tmp_keyname);
83 if (*key_name == NULL) {
84 goto done;
87 if (strequal(hivename, "HKLM") ||
88 strequal(hivename, "HKEY_LOCAL_MACHINE"))
90 (*reg_type) = HKEY_LOCAL_MACHINE;
91 } else if (strequal(hivename, "HKCR") ||
92 strequal(hivename, "HKEY_CLASSES_ROOT"))
94 (*reg_type) = HKEY_CLASSES_ROOT;
95 } else if (strequal(hivename, "HKU") ||
96 strequal(hivename, "HKEY_USERS"))
98 (*reg_type) = HKEY_USERS;
99 } else if (strequal(hivename, "HKCU") ||
100 strequal(hivename, "HKEY_CURRENT_USER"))
102 (*reg_type) = HKEY_CURRENT_USER;
103 } else if (strequal(hivename, "HKPD") ||
104 strequal(hivename, "HKEY_PERFORMANCE_DATA"))
106 (*reg_type) = HKEY_PERFORMANCE_DATA;
107 } else {
108 DEBUG(10,("reg_hive_key: unrecognised hive key %s\n",
109 fullname));
110 goto done;
113 ret = true;
115 done:
116 TALLOC_FREE(tmp_ctx);
117 return ret;
120 static NTSTATUS registry_openkey(TALLOC_CTX *mem_ctx,
121 struct rpc_pipe_client *pipe_hnd,
122 const char *name, uint32 access_mask,
123 struct policy_handle *hive_hnd,
124 struct policy_handle *key_hnd)
126 uint32 hive;
127 NTSTATUS status;
128 struct winreg_String key;
130 ZERO_STRUCT(key);
132 if (!reg_hive_key(mem_ctx, name, &hive, &key.name)) {
133 return NT_STATUS_INVALID_PARAMETER;
136 status = rpccli_winreg_Connect(pipe_hnd, mem_ctx, hive, access_mask,
137 hive_hnd);
138 if (!(NT_STATUS_IS_OK(status))) {
139 return status;
142 status = rpccli_winreg_OpenKey(pipe_hnd, mem_ctx, hive_hnd, key, 0,
143 access_mask, key_hnd, NULL);
144 if (!(NT_STATUS_IS_OK(status))) {
145 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, hive_hnd, NULL);
146 return status;
149 return NT_STATUS_OK;
152 static NTSTATUS registry_enumkeys(TALLOC_CTX *ctx,
153 struct rpc_pipe_client *pipe_hnd,
154 struct policy_handle *key_hnd,
155 uint32 *pnum_keys, char ***pnames,
156 char ***pclasses, NTTIME ***pmodtimes)
158 TALLOC_CTX *mem_ctx;
159 NTSTATUS status;
160 uint32 num_subkeys, max_subkeylen, max_classlen;
161 uint32 num_values, max_valnamelen, max_valbufsize;
162 uint32 i;
163 NTTIME last_changed_time;
164 uint32 secdescsize;
165 struct winreg_String classname;
166 char **names, **classes;
167 NTTIME **modtimes;
169 if (!(mem_ctx = talloc_new(ctx))) {
170 return NT_STATUS_NO_MEMORY;
173 ZERO_STRUCT(classname);
174 status = rpccli_winreg_QueryInfoKey(
175 pipe_hnd, mem_ctx, key_hnd, &classname, &num_subkeys,
176 &max_subkeylen, &max_classlen, &num_values, &max_valnamelen,
177 &max_valbufsize, &secdescsize, &last_changed_time, NULL );
179 if (!NT_STATUS_IS_OK(status)) {
180 goto error;
183 if (num_subkeys == 0) {
184 *pnum_keys = 0;
185 TALLOC_FREE(mem_ctx);
186 return NT_STATUS_OK;
189 if ((!(names = TALLOC_ZERO_ARRAY(mem_ctx, char *, num_subkeys))) ||
190 (!(classes = TALLOC_ZERO_ARRAY(mem_ctx, char *, num_subkeys))) ||
191 (!(modtimes = TALLOC_ZERO_ARRAY(mem_ctx, NTTIME *,
192 num_subkeys)))) {
193 status = NT_STATUS_NO_MEMORY;
194 goto error;
197 for (i=0; i<num_subkeys; i++) {
198 char c, n;
199 struct winreg_StringBuf class_buf;
200 struct winreg_StringBuf name_buf;
201 NTTIME modtime;
202 WERROR werr;
204 c = '\0';
205 class_buf.name = &c;
206 class_buf.size = max_classlen+2;
208 n = '\0';
209 name_buf.name = &n;
210 name_buf.size = max_subkeylen+2;
212 ZERO_STRUCT(modtime);
214 status = rpccli_winreg_EnumKey(pipe_hnd, mem_ctx, key_hnd,
215 i, &name_buf, &class_buf,
216 &modtime, &werr);
218 if (W_ERROR_EQUAL(werr,
219 WERR_NO_MORE_ITEMS) ) {
220 status = NT_STATUS_OK;
221 break;
223 if (!NT_STATUS_IS_OK(status)) {
224 goto error;
227 classes[i] = NULL;
229 if (class_buf.name &&
230 (!(classes[i] = talloc_strdup(classes, class_buf.name)))) {
231 status = NT_STATUS_NO_MEMORY;
232 goto error;
235 if (!(names[i] = talloc_strdup(names, name_buf.name))) {
236 status = NT_STATUS_NO_MEMORY;
237 goto error;
240 if ((!(modtimes[i] = (NTTIME *)talloc_memdup(
241 modtimes, &modtime, sizeof(modtime))))) {
242 status = NT_STATUS_NO_MEMORY;
243 goto error;
247 *pnum_keys = num_subkeys;
249 if (pnames) {
250 *pnames = talloc_move(ctx, &names);
252 if (pclasses) {
253 *pclasses = talloc_move(ctx, &classes);
255 if (pmodtimes) {
256 *pmodtimes = talloc_move(ctx, &modtimes);
259 status = NT_STATUS_OK;
261 error:
262 TALLOC_FREE(mem_ctx);
263 return status;
266 static NTSTATUS registry_enumvalues(TALLOC_CTX *ctx,
267 struct rpc_pipe_client *pipe_hnd,
268 struct policy_handle *key_hnd,
269 uint32 *pnum_values, char ***pvalnames,
270 struct registry_value ***pvalues)
272 TALLOC_CTX *mem_ctx;
273 NTSTATUS status;
274 uint32 num_subkeys, max_subkeylen, max_classlen;
275 uint32 num_values, max_valnamelen, max_valbufsize;
276 uint32 i;
277 NTTIME last_changed_time;
278 uint32 secdescsize;
279 struct winreg_String classname;
280 struct registry_value **values;
281 char **names;
283 if (!(mem_ctx = talloc_new(ctx))) {
284 return NT_STATUS_NO_MEMORY;
287 ZERO_STRUCT(classname);
288 status = rpccli_winreg_QueryInfoKey(
289 pipe_hnd, mem_ctx, key_hnd, &classname, &num_subkeys,
290 &max_subkeylen, &max_classlen, &num_values, &max_valnamelen,
291 &max_valbufsize, &secdescsize, &last_changed_time, NULL );
293 if (!NT_STATUS_IS_OK(status)) {
294 goto error;
297 if (num_values == 0) {
298 *pnum_values = 0;
299 TALLOC_FREE(mem_ctx);
300 return NT_STATUS_OK;
303 if ((!(names = TALLOC_ARRAY(mem_ctx, char *, num_values))) ||
304 (!(values = TALLOC_ARRAY(mem_ctx, struct registry_value *,
305 num_values)))) {
306 status = NT_STATUS_NO_MEMORY;
307 goto error;
310 for (i=0; i<num_values; i++) {
311 enum winreg_Type type = REG_NONE;
312 uint8 *data = NULL;
313 uint32 data_size;
314 uint32 value_length;
316 char n;
317 struct winreg_ValNameBuf name_buf;
318 WERROR err;
320 n = '\0';
321 name_buf.name = &n;
322 name_buf.size = max_valnamelen + 2;
324 data_size = max_valbufsize;
325 data = (uint8 *)TALLOC(mem_ctx, data_size);
326 value_length = 0;
328 status = rpccli_winreg_EnumValue(pipe_hnd, mem_ctx, key_hnd,
329 i, &name_buf, &type,
330 data, &data_size,
331 &value_length, &err);
333 if ( W_ERROR_EQUAL(err,
334 WERR_NO_MORE_ITEMS) ) {
335 status = NT_STATUS_OK;
336 break;
339 if (!(NT_STATUS_IS_OK(status))) {
340 goto error;
343 if (name_buf.name == NULL) {
344 status = NT_STATUS_INVALID_PARAMETER;
345 goto error;
348 if (!(names[i] = talloc_strdup(names, name_buf.name))) {
349 status = NT_STATUS_NO_MEMORY;
350 goto error;
353 err = registry_pull_value(values, &values[i], type, data,
354 data_size, value_length);
355 if (!W_ERROR_IS_OK(err)) {
356 status = werror_to_ntstatus(err);
357 goto error;
361 *pnum_values = num_values;
363 if (pvalnames) {
364 *pvalnames = talloc_move(ctx, &names);
366 if (pvalues) {
367 *pvalues = talloc_move(ctx, &values);
370 status = NT_STATUS_OK;
372 error:
373 TALLOC_FREE(mem_ctx);
374 return status;
377 static NTSTATUS registry_getsd(TALLOC_CTX *mem_ctx,
378 struct rpc_pipe_client *pipe_hnd,
379 struct policy_handle *key_hnd,
380 uint32_t sec_info,
381 struct KeySecurityData *sd)
383 return rpccli_winreg_GetKeySecurity(pipe_hnd, mem_ctx, key_hnd,
384 sec_info, sd, NULL);
388 static NTSTATUS registry_setvalue(TALLOC_CTX *mem_ctx,
389 struct rpc_pipe_client *pipe_hnd,
390 struct policy_handle *key_hnd,
391 const char *name,
392 const struct registry_value *value)
394 struct winreg_String name_string;
395 DATA_BLOB blob;
396 NTSTATUS result;
397 WERROR err;
399 err = registry_push_value(mem_ctx, value, &blob);
400 if (!W_ERROR_IS_OK(err)) {
401 return werror_to_ntstatus(err);
404 ZERO_STRUCT(name_string);
406 name_string.name = name;
407 result = rpccli_winreg_SetValue(pipe_hnd, blob.data, key_hnd,
408 name_string, value->type,
409 blob.data, blob.length, NULL);
410 TALLOC_FREE(blob.data);
411 return result;
414 static NTSTATUS rpc_registry_setvalue_internal(struct net_context *c,
415 const struct dom_sid *domain_sid,
416 const char *domain_name,
417 struct cli_state *cli,
418 struct rpc_pipe_client *pipe_hnd,
419 TALLOC_CTX *mem_ctx,
420 int argc,
421 const char **argv )
423 struct policy_handle hive_hnd, key_hnd;
424 NTSTATUS status;
425 struct registry_value value;
427 status = registry_openkey(mem_ctx, pipe_hnd, argv[0],
428 SEC_FLAG_MAXIMUM_ALLOWED,
429 &hive_hnd, &key_hnd);
430 if (!NT_STATUS_IS_OK(status)) {
431 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
432 nt_errstr(status));
433 return status;
436 if (!strequal(argv[2], "multi_sz") && (argc != 4)) {
437 d_fprintf(stderr, _("Too many args for type %s\n"), argv[2]);
438 return NT_STATUS_NOT_IMPLEMENTED;
441 if (strequal(argv[2], "dword")) {
442 value.type = REG_DWORD;
443 value.v.dword = strtoul(argv[3], NULL, 10);
445 else if (strequal(argv[2], "sz")) {
446 value.type = REG_SZ;
447 value.v.sz.len = strlen(argv[3])+1;
448 value.v.sz.str = CONST_DISCARD(char *, argv[3]);
450 else {
451 d_fprintf(stderr, _("type \"%s\" not implemented\n"), argv[2]);
452 status = NT_STATUS_NOT_IMPLEMENTED;
453 goto error;
456 status = registry_setvalue(mem_ctx, pipe_hnd, &key_hnd,
457 argv[1], &value);
459 if (!NT_STATUS_IS_OK(status)) {
460 d_fprintf(stderr, _("registry_setvalue failed: %s\n"),
461 nt_errstr(status));
464 error:
465 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &key_hnd, NULL);
466 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd, NULL);
468 return NT_STATUS_OK;
471 static int rpc_registry_setvalue(struct net_context *c, int argc,
472 const char **argv )
474 if (argc < 4 || c->display_usage) {
475 d_fprintf(stderr, "%s\n%s",
476 _("Usage:"),
477 _("net rpc registry setvalue <key> <valuename> "
478 "<type> [<val>]+\n"));
479 return -1;
482 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
483 rpc_registry_setvalue_internal, argc, argv );
486 static NTSTATUS rpc_registry_deletevalue_internal(struct net_context *c,
487 const struct dom_sid *domain_sid,
488 const char *domain_name,
489 struct cli_state *cli,
490 struct rpc_pipe_client *pipe_hnd,
491 TALLOC_CTX *mem_ctx,
492 int argc,
493 const char **argv )
495 struct policy_handle hive_hnd, key_hnd;
496 NTSTATUS status;
497 struct winreg_String valuename;
499 ZERO_STRUCT(valuename);
501 status = registry_openkey(mem_ctx, pipe_hnd, argv[0],
502 SEC_FLAG_MAXIMUM_ALLOWED,
503 &hive_hnd, &key_hnd);
504 if (!NT_STATUS_IS_OK(status)) {
505 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
506 nt_errstr(status));
507 return status;
510 valuename.name = argv[1];
512 status = rpccli_winreg_DeleteValue(pipe_hnd, mem_ctx, &key_hnd,
513 valuename, NULL);
515 if (!NT_STATUS_IS_OK(status)) {
516 d_fprintf(stderr, _("registry_deletevalue failed: %s\n"),
517 nt_errstr(status));
520 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &key_hnd, NULL);
521 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd, NULL);
523 return status;
526 static int rpc_registry_deletevalue(struct net_context *c, int argc,
527 const char **argv )
529 if (argc != 2 || c->display_usage) {
530 d_fprintf(stderr, "%s\n%s",
531 _("Usage:"),
532 _("net rpc registry deletevalue <key> <valuename>\n"));
533 return -1;
536 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
537 rpc_registry_deletevalue_internal, argc, argv );
540 static NTSTATUS rpc_registry_getvalue_internal(struct net_context *c,
541 const struct dom_sid *domain_sid,
542 const char *domain_name,
543 struct cli_state *cli,
544 struct rpc_pipe_client *pipe_hnd,
545 TALLOC_CTX *mem_ctx,
546 bool raw,
547 int argc,
548 const char **argv)
550 struct policy_handle hive_hnd, key_hnd;
551 NTSTATUS status;
552 WERROR werr;
553 struct winreg_String valuename;
554 struct registry_value *value = NULL;
555 enum winreg_Type type = REG_NONE;
556 uint8_t *data = NULL;
557 uint32_t data_size = 0;
558 uint32_t value_length = 0;
559 TALLOC_CTX *tmp_ctx = talloc_stackframe();
561 ZERO_STRUCT(valuename);
563 status = registry_openkey(tmp_ctx, pipe_hnd, argv[0],
564 SEC_FLAG_MAXIMUM_ALLOWED,
565 &hive_hnd, &key_hnd);
566 if (!NT_STATUS_IS_OK(status)) {
567 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
568 nt_errstr(status));
569 return status;
572 valuename.name = argv[1];
575 * call QueryValue once with data == NULL to get the
576 * needed memory size to be allocated, then allocate
577 * data buffer and call again.
579 status = rpccli_winreg_QueryValue(pipe_hnd, tmp_ctx, &key_hnd,
580 &valuename,
581 &type,
582 data,
583 &data_size,
584 &value_length,
585 NULL);
587 if (!NT_STATUS_IS_OK(status)) {
588 d_fprintf(stderr, _("registry_queryvalue failed: %s\n"),
589 nt_errstr(status));
590 goto done;
593 data = (uint8 *)TALLOC(tmp_ctx, data_size);
594 value_length = 0;
596 status = rpccli_winreg_QueryValue(pipe_hnd, tmp_ctx, &key_hnd,
597 &valuename,
598 &type,
599 data,
600 &data_size,
601 &value_length,
602 NULL);
604 if (!NT_STATUS_IS_OK(status)) {
605 d_fprintf(stderr, _("registry_queryvalue failed: %s\n"),
606 nt_errstr(status));
607 goto done;
610 werr = registry_pull_value(tmp_ctx, &value, type, data,
611 data_size, value_length);
612 if (!W_ERROR_IS_OK(werr)) {
613 status = werror_to_ntstatus(werr);
614 goto done;
617 print_registry_value(value, raw);
619 done:
620 rpccli_winreg_CloseKey(pipe_hnd, tmp_ctx, &key_hnd, NULL);
621 rpccli_winreg_CloseKey(pipe_hnd, tmp_ctx, &hive_hnd, NULL);
623 TALLOC_FREE(tmp_ctx);
625 return status;
628 static NTSTATUS rpc_registry_getvalue_full(struct net_context *c,
629 const struct dom_sid *domain_sid,
630 const char *domain_name,
631 struct cli_state *cli,
632 struct rpc_pipe_client *pipe_hnd,
633 TALLOC_CTX *mem_ctx,
634 int argc,
635 const char **argv)
637 return rpc_registry_getvalue_internal(c, domain_sid, domain_name,
638 cli, pipe_hnd, mem_ctx, false,
639 argc, argv);
642 static int rpc_registry_getvalue(struct net_context *c, int argc,
643 const char **argv)
645 if (argc != 2 || c->display_usage) {
646 d_fprintf(stderr, "%s\n%s",
647 _("Usage:"),
648 _("net rpc registry getvalue <key> <valuename>\n"));
649 return -1;
652 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
653 rpc_registry_getvalue_full, argc, argv);
656 static NTSTATUS rpc_registry_getvalue_raw(struct net_context *c,
657 const struct dom_sid *domain_sid,
658 const char *domain_name,
659 struct cli_state *cli,
660 struct rpc_pipe_client *pipe_hnd,
661 TALLOC_CTX *mem_ctx,
662 int argc,
663 const char **argv)
665 return rpc_registry_getvalue_internal(c, domain_sid, domain_name,
666 cli, pipe_hnd, mem_ctx, true,
667 argc, argv);
670 static int rpc_registry_getvalueraw(struct net_context *c, int argc,
671 const char **argv)
673 if (argc != 2 || c->display_usage) {
674 d_fprintf(stderr, "%s\n%s",
675 _("Usage:"),
676 _("net rpc registry getvalue <key> <valuename>\n"));
677 return -1;
680 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
681 rpc_registry_getvalue_raw, argc, argv);
684 static NTSTATUS rpc_registry_createkey_internal(struct net_context *c,
685 const struct dom_sid *domain_sid,
686 const char *domain_name,
687 struct cli_state *cli,
688 struct rpc_pipe_client *pipe_hnd,
689 TALLOC_CTX *mem_ctx,
690 int argc,
691 const char **argv )
693 uint32 hive;
694 struct policy_handle hive_hnd, key_hnd;
695 struct winreg_String key, keyclass;
696 enum winreg_CreateAction action;
697 NTSTATUS status;
699 ZERO_STRUCT(key);
700 ZERO_STRUCT(keyclass);
702 if (!reg_hive_key(mem_ctx, argv[0], &hive, &key.name)) {
703 return NT_STATUS_INVALID_PARAMETER;
706 status = rpccli_winreg_Connect(pipe_hnd, mem_ctx, hive,
707 SEC_FLAG_MAXIMUM_ALLOWED,
708 &hive_hnd);
709 if (!(NT_STATUS_IS_OK(status))) {
710 return status;
713 action = REG_ACTION_NONE;
714 keyclass.name = "";
716 status = rpccli_winreg_CreateKey(pipe_hnd, mem_ctx, &hive_hnd, key,
717 keyclass, 0, REG_KEY_READ, NULL,
718 &key_hnd, &action, NULL);
719 if (!NT_STATUS_IS_OK(status)) {
720 d_fprintf(stderr, _("createkey returned %s\n"),
721 nt_errstr(status));
722 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd, NULL);
723 return status;
726 switch (action) {
727 case REG_ACTION_NONE:
728 d_printf(_("createkey did nothing -- huh?\n"));
729 break;
730 case REG_CREATED_NEW_KEY:
731 d_printf(_("createkey created %s\n"), argv[0]);
732 break;
733 case REG_OPENED_EXISTING_KEY:
734 d_printf(_("createkey opened existing %s\n"), argv[0]);
735 break;
738 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &key_hnd, NULL);
739 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd, NULL);
741 return status;
744 static int rpc_registry_createkey(struct net_context *c, int argc,
745 const char **argv )
747 if (argc != 1 || c->display_usage) {
748 d_fprintf(stderr, "%s\n%s",
749 _("Usage:"),
750 _("net rpc registry createkey <key>\n"));
751 return -1;
754 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
755 rpc_registry_createkey_internal, argc, argv );
758 static NTSTATUS rpc_registry_deletekey_internal(struct net_context *c,
759 const struct dom_sid *domain_sid,
760 const char *domain_name,
761 struct cli_state *cli,
762 struct rpc_pipe_client *pipe_hnd,
763 TALLOC_CTX *mem_ctx,
764 int argc,
765 const char **argv )
767 uint32 hive;
768 struct policy_handle hive_hnd;
769 struct winreg_String key;
770 NTSTATUS status;
772 ZERO_STRUCT(key);
774 if (!reg_hive_key(mem_ctx, argv[0], &hive, &key.name)) {
775 return NT_STATUS_INVALID_PARAMETER;
778 status = rpccli_winreg_Connect(pipe_hnd, mem_ctx, hive,
779 SEC_FLAG_MAXIMUM_ALLOWED,
780 &hive_hnd);
781 if (!(NT_STATUS_IS_OK(status))) {
782 return status;
785 status = rpccli_winreg_DeleteKey(pipe_hnd, mem_ctx, &hive_hnd, key, NULL);
786 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd, NULL);
788 if (!NT_STATUS_IS_OK(status)) {
789 d_fprintf(stderr, _("deletekey returned %s\n"),
790 nt_errstr(status));
793 return status;
796 static int rpc_registry_deletekey(struct net_context *c, int argc, const char **argv )
798 if (argc != 1 || c->display_usage) {
799 d_fprintf(stderr, "%s\n%s",
800 _("Usage:"),
801 _("net rpc registry deletekey <key>\n"));
802 return -1;
805 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
806 rpc_registry_deletekey_internal, argc, argv );
809 /********************************************************************
810 ********************************************************************/
812 static NTSTATUS rpc_registry_enumerate_internal(struct net_context *c,
813 const struct dom_sid *domain_sid,
814 const char *domain_name,
815 struct cli_state *cli,
816 struct rpc_pipe_client *pipe_hnd,
817 TALLOC_CTX *mem_ctx,
818 int argc,
819 const char **argv )
821 struct policy_handle pol_hive, pol_key;
822 NTSTATUS status;
823 uint32 num_subkeys = 0;
824 uint32 num_values = 0;
825 char **names = NULL, **classes = NULL;
826 NTTIME **modtimes = NULL;
827 uint32 i;
828 struct registry_value **values = NULL;
830 if (argc != 1 || c->display_usage) {
831 d_printf("%s\n%s",
832 _("Usage:"),
833 _("net rpc registry enumerate <path>\n"));
834 d_printf("%s net rpc registry enumerate "
835 "'HKLM\\Software\\Samba'\n", _("Example:"));
836 return NT_STATUS_INVALID_PARAMETER;
839 status = registry_openkey(mem_ctx, pipe_hnd, argv[0], REG_KEY_READ,
840 &pol_hive, &pol_key);
841 if (!NT_STATUS_IS_OK(status)) {
842 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
843 nt_errstr(status));
844 return status;
847 status = registry_enumkeys(mem_ctx, pipe_hnd, &pol_key, &num_subkeys,
848 &names, &classes, &modtimes);
849 if (!NT_STATUS_IS_OK(status)) {
850 d_fprintf(stderr, _("enumerating keys failed: %s\n"),
851 nt_errstr(status));
852 return status;
855 for (i=0; i<num_subkeys; i++) {
856 print_registry_key(names[i], modtimes[i]);
859 status = registry_enumvalues(mem_ctx, pipe_hnd, &pol_key, &num_values,
860 &names, &values);
861 if (!NT_STATUS_IS_OK(status)) {
862 d_fprintf(stderr, _("enumerating values failed: %s\n"),
863 nt_errstr(status));
864 return status;
867 for (i=0; i<num_values; i++) {
868 print_registry_value_with_name(names[i], values[i]);
871 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_key, NULL);
872 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_hive, NULL);
874 return status;
877 /********************************************************************
878 ********************************************************************/
880 static int rpc_registry_enumerate(struct net_context *c, int argc,
881 const char **argv )
883 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
884 rpc_registry_enumerate_internal, argc, argv );
887 /********************************************************************
888 ********************************************************************/
890 static NTSTATUS rpc_registry_save_internal(struct net_context *c,
891 const struct dom_sid *domain_sid,
892 const char *domain_name,
893 struct cli_state *cli,
894 struct rpc_pipe_client *pipe_hnd,
895 TALLOC_CTX *mem_ctx,
896 int argc,
897 const char **argv )
899 WERROR result = WERR_GENERAL_FAILURE;
900 struct policy_handle pol_hive, pol_key;
901 NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
902 struct winreg_String filename;
904 if (argc != 2 || c->display_usage) {
905 d_printf("%s\n%s",
906 _("Usage:"),
907 _("net rpc registry backup <path> <file> \n"));
908 return NT_STATUS_INVALID_PARAMETER;
911 status = registry_openkey(mem_ctx, pipe_hnd, argv[0], REG_KEY_ALL,
912 &pol_hive, &pol_key);
913 if (!NT_STATUS_IS_OK(status)) {
914 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
915 nt_errstr(status));
916 return status;
919 filename.name = argv[1];
920 status = rpccli_winreg_SaveKey( pipe_hnd, mem_ctx, &pol_key, &filename, NULL, NULL);
921 if ( !W_ERROR_IS_OK(result) ) {
922 d_fprintf(stderr, _("Unable to save [%s] to %s:%s\n"), argv[0],
923 cli->desthost, argv[1]);
926 /* cleanup */
928 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_key, NULL);
929 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_hive, NULL);
931 return status;
934 /********************************************************************
935 ********************************************************************/
937 static int rpc_registry_save(struct net_context *c, int argc, const char **argv )
939 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
940 rpc_registry_save_internal, argc, argv );
944 /********************************************************************
945 ********************************************************************/
947 static void dump_values( REGF_NK_REC *nk )
949 int i, j;
950 const char *data_str = NULL;
951 uint32 data_size, data;
952 DATA_BLOB blob;
954 if ( !nk->values )
955 return;
957 for ( i=0; i<nk->num_values; i++ ) {
958 d_printf( "\"%s\" = ", nk->values[i].valuename ? nk->values[i].valuename : "(default)" );
959 d_printf( "(%s) ", str_regtype( nk->values[i].type ) );
961 data_size = nk->values[i].data_size & ~VK_DATA_IN_OFFSET;
962 switch ( nk->values[i].type ) {
963 case REG_SZ:
964 blob = data_blob_const(nk->values[i].data, data_size);
965 pull_reg_sz(talloc_tos(), &blob, &data_str);
966 if (!data_str) {
967 break;
969 d_printf( "%s", data_str );
970 break;
971 case REG_MULTI_SZ:
972 case REG_EXPAND_SZ:
973 for ( j=0; j<data_size; j++ ) {
974 d_printf( "%c", nk->values[i].data[j] );
976 break;
977 case REG_DWORD:
978 data = IVAL( nk->values[i].data, 0 );
979 d_printf("0x%x", data );
980 break;
981 case REG_BINARY:
982 for ( j=0; j<data_size; j++ ) {
983 d_printf( "%x", nk->values[i].data[j] );
985 break;
986 default:
987 d_printf(_("unknown"));
988 break;
991 d_printf( "\n" );
996 /********************************************************************
997 ********************************************************************/
999 static bool dump_registry_tree( REGF_FILE *file, REGF_NK_REC *nk, const char *parent )
1001 REGF_NK_REC *key;
1003 /* depth first dump of the registry tree */
1005 while ( (key = regfio_fetch_subkey( file, nk )) ) {
1006 char *regpath;
1007 if (asprintf(&regpath, "%s\\%s", parent, key->keyname) < 0) {
1008 break;
1010 d_printf("[%s]\n", regpath );
1011 dump_values( key );
1012 d_printf("\n");
1013 dump_registry_tree( file, key, regpath );
1014 SAFE_FREE(regpath);
1017 return true;
1020 /********************************************************************
1021 ********************************************************************/
1023 static bool write_registry_tree( REGF_FILE *infile, REGF_NK_REC *nk,
1024 REGF_NK_REC *parent, REGF_FILE *outfile,
1025 const char *parentpath )
1027 REGF_NK_REC *key, *subkey;
1028 struct regval_ctr *values = NULL;
1029 struct regsubkey_ctr *subkeys = NULL;
1030 int i;
1031 char *path = NULL;
1032 WERROR werr;
1034 werr = regsubkey_ctr_init(infile->mem_ctx, &subkeys);
1035 if (!W_ERROR_IS_OK(werr)) {
1036 DEBUG(0, ("write_registry_tree: regsubkey_ctr_init failed: "
1037 "%s\n", win_errstr(werr)));
1038 return false;
1041 werr = regval_ctr_init(subkeys, &values);
1042 if (!W_ERROR_IS_OK(werr)) {
1043 DEBUG(0,("write_registry_tree: talloc() failed!\n"));
1044 TALLOC_FREE(subkeys);
1045 return false;
1048 /* copy values into the struct regval_ctr */
1050 for ( i=0; i<nk->num_values; i++ ) {
1051 regval_ctr_addvalue( values, nk->values[i].valuename, nk->values[i].type,
1052 nk->values[i].data, (nk->values[i].data_size & ~VK_DATA_IN_OFFSET) );
1055 /* copy subkeys into the struct regsubkey_ctr */
1057 while ( (subkey = regfio_fetch_subkey( infile, nk )) ) {
1058 regsubkey_ctr_addkey( subkeys, subkey->keyname );
1061 key = regfio_write_key( outfile, nk->keyname, values, subkeys, nk->sec_desc->sec_desc, parent );
1063 /* write each one of the subkeys out */
1065 path = talloc_asprintf(subkeys,
1066 "%s%s%s",
1067 parentpath,
1068 parent ? "\\" : "",
1069 nk->keyname);
1070 if (!path) {
1071 TALLOC_FREE(subkeys);
1072 return false;
1075 nk->subkey_index = 0;
1076 while ( (subkey = regfio_fetch_subkey( infile, nk )) ) {
1077 write_registry_tree( infile, subkey, key, outfile, path );
1080 d_printf("[%s]\n", path );
1081 TALLOC_FREE(subkeys);
1083 return true;
1086 /********************************************************************
1087 ********************************************************************/
1089 static int rpc_registry_dump(struct net_context *c, int argc, const char **argv)
1091 REGF_FILE *registry;
1092 REGF_NK_REC *nk;
1094 if (argc != 1 || c->display_usage) {
1095 d_printf("%s\n%s",
1096 _("Usage:"),
1097 _("net rpc registry dump <file> \n"));
1098 return -1;
1101 d_printf(_("Opening %s...."), argv[0]);
1102 if ( !(registry = regfio_open( argv[0], O_RDONLY, 0)) ) {
1103 d_fprintf(stderr, _("Failed to open %s for reading\n"),argv[0]);
1104 return 1;
1106 d_printf(_("ok\n"));
1108 /* get the root of the registry file */
1110 if ((nk = regfio_rootkey( registry )) == NULL) {
1111 d_fprintf(stderr, _("Could not get rootkey\n"));
1112 regfio_close( registry );
1113 return 1;
1115 d_printf("[%s]\n", nk->keyname);
1116 dump_values( nk );
1117 d_printf("\n");
1119 dump_registry_tree( registry, nk, nk->keyname );
1121 #if 0
1122 talloc_report_full( registry->mem_ctx, stderr );
1123 #endif
1124 d_printf(_("Closing registry..."));
1125 regfio_close( registry );
1126 d_printf(_("ok\n"));
1128 return 0;
1131 /********************************************************************
1132 ********************************************************************/
1134 static int rpc_registry_copy(struct net_context *c, int argc, const char **argv )
1136 REGF_FILE *infile = NULL, *outfile = NULL;
1137 REGF_NK_REC *nk;
1138 int result = 1;
1140 if (argc != 2 || c->display_usage) {
1141 d_printf("%s\n%s",
1142 _("Usage:"),
1143 _("net rpc registry copy <srcfile> <newfile>\n"));
1144 return -1;
1147 d_printf(_("Opening %s...."), argv[0]);
1148 if ( !(infile = regfio_open( argv[0], O_RDONLY, 0 )) ) {
1149 d_fprintf(stderr, _("Failed to open %s for reading\n"),argv[0]);
1150 return 1;
1152 d_printf(_("ok\n"));
1154 d_printf(_("Opening %s...."), argv[1]);
1155 if ( !(outfile = regfio_open( argv[1], (O_RDWR|O_CREAT|O_TRUNC), (S_IREAD|S_IWRITE) )) ) {
1156 d_fprintf(stderr, _("Failed to open %s for writing\n"),argv[1]);
1157 goto out;
1159 d_printf(_("ok\n"));
1161 /* get the root of the registry file */
1163 if ((nk = regfio_rootkey( infile )) == NULL) {
1164 d_fprintf(stderr, _("Could not get rootkey\n"));
1165 goto out;
1167 d_printf(_("RootKey: [%s]\n"), nk->keyname);
1169 write_registry_tree( infile, nk, NULL, outfile, "" );
1171 result = 0;
1173 out:
1175 d_printf(_("Closing %s..."), argv[1]);
1176 if (outfile) {
1177 regfio_close( outfile );
1179 d_printf(_("ok\n"));
1181 d_printf(_("Closing %s..."), argv[0]);
1182 if (infile) {
1183 regfio_close( infile );
1185 d_printf(_("ok\n"));
1187 return( result);
1190 /********************************************************************
1191 ********************************************************************/
1193 static NTSTATUS rpc_registry_getsd_internal(struct net_context *c,
1194 const struct dom_sid *domain_sid,
1195 const char *domain_name,
1196 struct cli_state *cli,
1197 struct rpc_pipe_client *pipe_hnd,
1198 TALLOC_CTX *mem_ctx,
1199 int argc,
1200 const char **argv)
1202 struct policy_handle pol_hive, pol_key;
1203 NTSTATUS status;
1204 enum ndr_err_code ndr_err;
1205 struct KeySecurityData *sd = NULL;
1206 uint32_t sec_info;
1207 DATA_BLOB blob;
1208 struct security_descriptor sec_desc;
1209 uint32_t access_mask = REG_KEY_READ |
1210 SEC_FLAG_MAXIMUM_ALLOWED |
1211 SEC_FLAG_SYSTEM_SECURITY;
1213 if (argc <1 || argc > 2 || c->display_usage) {
1214 d_printf("%s\n%s",
1215 _("Usage:"),
1216 _("net rpc registry getsd <path> <secinfo>\n"));
1217 d_printf("%s net rpc registry getsd "
1218 "'HKLM\\Software\\Samba'\n", _("Example:"));
1219 return NT_STATUS_INVALID_PARAMETER;
1222 status = registry_openkey(mem_ctx, pipe_hnd, argv[0],
1223 access_mask,
1224 &pol_hive, &pol_key);
1225 if (!NT_STATUS_IS_OK(status)) {
1226 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
1227 nt_errstr(status));
1228 return status;
1231 sd = TALLOC_ZERO_P(mem_ctx, struct KeySecurityData);
1232 if (!sd) {
1233 status = NT_STATUS_NO_MEMORY;
1234 goto out;
1237 sd->size = 0x1000;
1239 if (argc >= 2) {
1240 sscanf(argv[1], "%x", &sec_info);
1241 } else {
1242 sec_info = SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL;
1245 status = registry_getsd(mem_ctx, pipe_hnd, &pol_key, sec_info, sd);
1246 if (!NT_STATUS_IS_OK(status)) {
1247 d_fprintf(stderr, _("getting sd failed: %s\n"),
1248 nt_errstr(status));
1249 goto out;
1252 blob.data = sd->data;
1253 blob.length = sd->size;
1255 ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &sec_desc,
1256 (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
1257 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1258 status = ndr_map_error2ntstatus(ndr_err);
1259 goto out;
1261 status = NT_STATUS_OK;
1263 display_sec_desc(&sec_desc);
1265 out:
1266 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_key, NULL);
1267 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_hive, NULL);
1269 return status;
1273 static int rpc_registry_getsd(struct net_context *c, int argc, const char **argv)
1275 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
1276 rpc_registry_getsd_internal, argc, argv);
1279 /********************************************************************
1280 ********************************************************************/
1282 int net_rpc_registry(struct net_context *c, int argc, const char **argv)
1284 struct functable func[] = {
1286 "enumerate",
1287 rpc_registry_enumerate,
1288 NET_TRANSPORT_RPC,
1289 N_("Enumerate registry keys and values"),
1290 N_("net rpc registry enumerate\n"
1291 " Enumerate registry keys and values")
1294 "createkey",
1295 rpc_registry_createkey,
1296 NET_TRANSPORT_RPC,
1297 N_("Create a new registry key"),
1298 N_("net rpc registry createkey\n"
1299 " Create a new registry key")
1302 "deletekey",
1303 rpc_registry_deletekey,
1304 NET_TRANSPORT_RPC,
1305 N_("Delete a registry key"),
1306 N_("net rpc registry deletekey\n"
1307 " Delete a registry key")
1310 "getvalue",
1311 rpc_registry_getvalue,
1312 NET_TRANSPORT_RPC,
1313 N_("Print a registry value"),
1314 N_("net rpc registry getvalue\n"
1315 " Print a registry value")
1318 "getvalueraw",
1319 rpc_registry_getvalueraw,
1320 NET_TRANSPORT_RPC,
1321 N_("Print a registry value"),
1322 N_("net rpc registry getvalueraw\n"
1323 " Print a registry value (raw version)")
1326 "setvalue",
1327 rpc_registry_setvalue,
1328 NET_TRANSPORT_RPC,
1329 N_("Set a new registry value"),
1330 N_("net rpc registry setvalue\n"
1331 " Set a new registry value")
1334 "deletevalue",
1335 rpc_registry_deletevalue,
1336 NET_TRANSPORT_RPC,
1337 N_("Delete a registry value"),
1338 N_("net rpc registry deletevalue\n"
1339 " Delete a registry value")
1342 "save",
1343 rpc_registry_save,
1344 NET_TRANSPORT_RPC,
1345 N_("Save a registry file"),
1346 N_("net rpc registry save\n"
1347 " Save a registry file")
1350 "dump",
1351 rpc_registry_dump,
1352 NET_TRANSPORT_RPC,
1353 N_("Dump a registry file"),
1354 N_("net rpc registry dump\n"
1355 " Dump a registry file")
1358 "copy",
1359 rpc_registry_copy,
1360 NET_TRANSPORT_RPC,
1361 N_("Copy a registry file"),
1362 N_("net rpc registry copy\n"
1363 " Copy a registry file")
1366 "getsd",
1367 rpc_registry_getsd,
1368 NET_TRANSPORT_RPC,
1369 N_("Get security descriptor"),
1370 N_("net rpc registry getsd\n"
1371 " Get security descriptior")
1373 {NULL, NULL, 0, NULL, NULL}
1376 return net_run_function(c, argc, argv, "net rpc registry", func);