s4/asn1: Added torture suite for ASN1
[Samba/ekacnet.git] / source3 / utils / net_rpc_registry.c
blob36e83a75af8e1bdf07f44d1caa1ca95208d1baa3
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"
26 /*******************************************************************
27 connect to a registry hive root (open a registry policy)
28 *******************************************************************/
30 static NTSTATUS rpccli_winreg_Connect(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
31 uint32_t reg_type, uint32_t access_mask,
32 struct policy_handle *reg_hnd)
34 ZERO_STRUCTP(reg_hnd);
36 switch (reg_type)
38 case HKEY_CLASSES_ROOT:
39 return rpccli_winreg_OpenHKCR( cli, mem_ctx, NULL,
40 access_mask, reg_hnd, NULL);
42 case HKEY_LOCAL_MACHINE:
43 return rpccli_winreg_OpenHKLM( cli, mem_ctx, NULL,
44 access_mask, reg_hnd, NULL);
46 case HKEY_USERS:
47 return rpccli_winreg_OpenHKU( cli, mem_ctx, NULL,
48 access_mask, reg_hnd, NULL);
50 case HKEY_CURRENT_USER:
51 return rpccli_winreg_OpenHKCU( cli, mem_ctx, NULL,
52 access_mask, reg_hnd, NULL);
54 case HKEY_PERFORMANCE_DATA:
55 return rpccli_winreg_OpenHKPD( cli, mem_ctx, NULL,
56 access_mask, reg_hnd, NULL);
58 default:
59 /* fall through to end of function */
60 break;
63 return NT_STATUS_INVALID_PARAMETER;
66 static bool reg_hive_key(TALLOC_CTX *ctx, const char *fullname,
67 uint32 *reg_type, const char **key_name)
69 WERROR werr;
70 char *hivename = NULL;
71 char *tmp_keyname = NULL;
72 bool ret = false;
73 TALLOC_CTX *tmp_ctx = talloc_stackframe();
75 werr = split_hive_key(tmp_ctx, fullname, &hivename, &tmp_keyname);
76 if (!W_ERROR_IS_OK(werr)) {
77 goto done;
80 *key_name = talloc_strdup(ctx, tmp_keyname);
81 if (*key_name == NULL) {
82 goto done;
85 if (strequal(hivename, "HKLM") ||
86 strequal(hivename, "HKEY_LOCAL_MACHINE"))
88 (*reg_type) = HKEY_LOCAL_MACHINE;
89 } else if (strequal(hivename, "HKCR") ||
90 strequal(hivename, "HKEY_CLASSES_ROOT"))
92 (*reg_type) = HKEY_CLASSES_ROOT;
93 } else if (strequal(hivename, "HKU") ||
94 strequal(hivename, "HKEY_USERS"))
96 (*reg_type) = HKEY_USERS;
97 } else if (strequal(hivename, "HKCU") ||
98 strequal(hivename, "HKEY_CURRENT_USER"))
100 (*reg_type) = HKEY_CURRENT_USER;
101 } else if (strequal(hivename, "HKPD") ||
102 strequal(hivename, "HKEY_PERFORMANCE_DATA"))
104 (*reg_type) = HKEY_PERFORMANCE_DATA;
105 } else {
106 DEBUG(10,("reg_hive_key: unrecognised hive key %s\n",
107 fullname));
108 goto done;
111 ret = true;
113 done:
114 TALLOC_FREE(tmp_ctx);
115 return ret;
118 static NTSTATUS registry_openkey(TALLOC_CTX *mem_ctx,
119 struct rpc_pipe_client *pipe_hnd,
120 const char *name, uint32 access_mask,
121 struct policy_handle *hive_hnd,
122 struct policy_handle *key_hnd)
124 uint32 hive;
125 NTSTATUS status;
126 struct winreg_String key;
128 ZERO_STRUCT(key);
130 if (!reg_hive_key(mem_ctx, name, &hive, &key.name)) {
131 return NT_STATUS_INVALID_PARAMETER;
134 status = rpccli_winreg_Connect(pipe_hnd, mem_ctx, hive, access_mask,
135 hive_hnd);
136 if (!(NT_STATUS_IS_OK(status))) {
137 return status;
140 status = rpccli_winreg_OpenKey(pipe_hnd, mem_ctx, hive_hnd, key, 0,
141 access_mask, key_hnd, NULL);
142 if (!(NT_STATUS_IS_OK(status))) {
143 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, hive_hnd, NULL);
144 return status;
147 return NT_STATUS_OK;
150 static NTSTATUS registry_enumkeys(TALLOC_CTX *ctx,
151 struct rpc_pipe_client *pipe_hnd,
152 struct policy_handle *key_hnd,
153 uint32 *pnum_keys, char ***pnames,
154 char ***pclasses, NTTIME ***pmodtimes)
156 TALLOC_CTX *mem_ctx;
157 NTSTATUS status;
158 uint32 num_subkeys, max_subkeylen, max_classlen;
159 uint32 num_values, max_valnamelen, max_valbufsize;
160 uint32 i;
161 NTTIME last_changed_time;
162 uint32 secdescsize;
163 struct winreg_String classname;
164 char **names, **classes;
165 NTTIME **modtimes;
167 if (!(mem_ctx = talloc_new(ctx))) {
168 return NT_STATUS_NO_MEMORY;
171 ZERO_STRUCT(classname);
172 status = rpccli_winreg_QueryInfoKey(
173 pipe_hnd, mem_ctx, key_hnd, &classname, &num_subkeys,
174 &max_subkeylen, &max_classlen, &num_values, &max_valnamelen,
175 &max_valbufsize, &secdescsize, &last_changed_time, NULL );
177 if (!NT_STATUS_IS_OK(status)) {
178 goto error;
181 if (num_subkeys == 0) {
182 *pnum_keys = 0;
183 TALLOC_FREE(mem_ctx);
184 return NT_STATUS_OK;
187 if ((!(names = TALLOC_ZERO_ARRAY(mem_ctx, char *, num_subkeys))) ||
188 (!(classes = TALLOC_ZERO_ARRAY(mem_ctx, char *, num_subkeys))) ||
189 (!(modtimes = TALLOC_ZERO_ARRAY(mem_ctx, NTTIME *,
190 num_subkeys)))) {
191 status = NT_STATUS_NO_MEMORY;
192 goto error;
195 for (i=0; i<num_subkeys; i++) {
196 char c, n;
197 struct winreg_StringBuf class_buf;
198 struct winreg_StringBuf name_buf;
199 NTTIME modtime;
200 WERROR werr;
202 c = '\0';
203 class_buf.name = &c;
204 class_buf.size = max_classlen+2;
206 n = '\0';
207 name_buf.name = &n;
208 name_buf.size = max_subkeylen+2;
210 ZERO_STRUCT(modtime);
212 status = rpccli_winreg_EnumKey(pipe_hnd, mem_ctx, key_hnd,
213 i, &name_buf, &class_buf,
214 &modtime, &werr);
216 if (W_ERROR_EQUAL(werr,
217 WERR_NO_MORE_ITEMS) ) {
218 status = NT_STATUS_OK;
219 break;
221 if (!NT_STATUS_IS_OK(status)) {
222 goto error;
225 classes[i] = NULL;
227 if (class_buf.name &&
228 (!(classes[i] = talloc_strdup(classes, class_buf.name)))) {
229 status = NT_STATUS_NO_MEMORY;
230 goto error;
233 if (!(names[i] = talloc_strdup(names, name_buf.name))) {
234 status = NT_STATUS_NO_MEMORY;
235 goto error;
238 if ((!(modtimes[i] = (NTTIME *)talloc_memdup(
239 modtimes, &modtime, sizeof(modtime))))) {
240 status = NT_STATUS_NO_MEMORY;
241 goto error;
245 *pnum_keys = num_subkeys;
247 if (pnames) {
248 *pnames = talloc_move(ctx, &names);
250 if (pclasses) {
251 *pclasses = talloc_move(ctx, &classes);
253 if (pmodtimes) {
254 *pmodtimes = talloc_move(ctx, &modtimes);
257 status = NT_STATUS_OK;
259 error:
260 TALLOC_FREE(mem_ctx);
261 return status;
264 static NTSTATUS registry_enumvalues(TALLOC_CTX *ctx,
265 struct rpc_pipe_client *pipe_hnd,
266 struct policy_handle *key_hnd,
267 uint32 *pnum_values, char ***pvalnames,
268 struct registry_value ***pvalues)
270 TALLOC_CTX *mem_ctx;
271 NTSTATUS status;
272 uint32 num_subkeys, max_subkeylen, max_classlen;
273 uint32 num_values, max_valnamelen, max_valbufsize;
274 uint32 i;
275 NTTIME last_changed_time;
276 uint32 secdescsize;
277 struct winreg_String classname;
278 struct registry_value **values;
279 char **names;
281 if (!(mem_ctx = talloc_new(ctx))) {
282 return NT_STATUS_NO_MEMORY;
285 ZERO_STRUCT(classname);
286 status = rpccli_winreg_QueryInfoKey(
287 pipe_hnd, mem_ctx, key_hnd, &classname, &num_subkeys,
288 &max_subkeylen, &max_classlen, &num_values, &max_valnamelen,
289 &max_valbufsize, &secdescsize, &last_changed_time, NULL );
291 if (!NT_STATUS_IS_OK(status)) {
292 goto error;
295 if (num_values == 0) {
296 *pnum_values = 0;
297 TALLOC_FREE(mem_ctx);
298 return NT_STATUS_OK;
301 if ((!(names = TALLOC_ARRAY(mem_ctx, char *, num_values))) ||
302 (!(values = TALLOC_ARRAY(mem_ctx, struct registry_value *,
303 num_values)))) {
304 status = NT_STATUS_NO_MEMORY;
305 goto error;
308 for (i=0; i<num_values; i++) {
309 enum winreg_Type type = REG_NONE;
310 uint8 *data = NULL;
311 uint32 data_size;
312 uint32 value_length;
314 char n;
315 struct winreg_ValNameBuf name_buf;
316 WERROR err;
318 n = '\0';
319 name_buf.name = &n;
320 name_buf.size = max_valnamelen + 2;
322 data_size = max_valbufsize;
323 data = (uint8 *)TALLOC(mem_ctx, data_size);
324 value_length = 0;
326 status = rpccli_winreg_EnumValue(pipe_hnd, mem_ctx, key_hnd,
327 i, &name_buf, &type,
328 data, &data_size,
329 &value_length, &err);
331 if ( W_ERROR_EQUAL(err,
332 WERR_NO_MORE_ITEMS) ) {
333 status = NT_STATUS_OK;
334 break;
337 if (!(NT_STATUS_IS_OK(status))) {
338 goto error;
341 if (name_buf.name == NULL) {
342 status = NT_STATUS_INVALID_PARAMETER;
343 goto error;
346 if (!(names[i] = talloc_strdup(names, name_buf.name))) {
347 status = NT_STATUS_NO_MEMORY;
348 goto error;
351 err = registry_pull_value(values, &values[i], type, data,
352 data_size, value_length);
353 if (!W_ERROR_IS_OK(err)) {
354 status = werror_to_ntstatus(err);
355 goto error;
359 *pnum_values = num_values;
361 if (pvalnames) {
362 *pvalnames = talloc_move(ctx, &names);
364 if (pvalues) {
365 *pvalues = talloc_move(ctx, &values);
368 status = NT_STATUS_OK;
370 error:
371 TALLOC_FREE(mem_ctx);
372 return status;
375 static NTSTATUS registry_getsd(TALLOC_CTX *mem_ctx,
376 struct rpc_pipe_client *pipe_hnd,
377 struct policy_handle *key_hnd,
378 uint32_t sec_info,
379 struct KeySecurityData *sd)
381 return rpccli_winreg_GetKeySecurity(pipe_hnd, mem_ctx, key_hnd,
382 sec_info, sd, NULL);
386 static NTSTATUS registry_setvalue(TALLOC_CTX *mem_ctx,
387 struct rpc_pipe_client *pipe_hnd,
388 struct policy_handle *key_hnd,
389 const char *name,
390 const struct registry_value *value)
392 struct winreg_String name_string;
393 DATA_BLOB blob;
394 NTSTATUS result;
395 WERROR err;
397 err = registry_push_value(mem_ctx, value, &blob);
398 if (!W_ERROR_IS_OK(err)) {
399 return werror_to_ntstatus(err);
402 ZERO_STRUCT(name_string);
404 name_string.name = name;
405 result = rpccli_winreg_SetValue(pipe_hnd, blob.data, key_hnd,
406 name_string, value->type,
407 blob.data, blob.length, NULL);
408 TALLOC_FREE(blob.data);
409 return result;
412 static NTSTATUS rpc_registry_setvalue_internal(struct net_context *c,
413 const DOM_SID *domain_sid,
414 const char *domain_name,
415 struct cli_state *cli,
416 struct rpc_pipe_client *pipe_hnd,
417 TALLOC_CTX *mem_ctx,
418 int argc,
419 const char **argv )
421 struct policy_handle hive_hnd, key_hnd;
422 NTSTATUS status;
423 struct registry_value value;
425 status = registry_openkey(mem_ctx, pipe_hnd, argv[0],
426 SEC_FLAG_MAXIMUM_ALLOWED,
427 &hive_hnd, &key_hnd);
428 if (!NT_STATUS_IS_OK(status)) {
429 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
430 nt_errstr(status));
431 return status;
434 if (!strequal(argv[2], "multi_sz") && (argc != 4)) {
435 d_fprintf(stderr, _("Too many args for type %s\n"), argv[2]);
436 return NT_STATUS_NOT_IMPLEMENTED;
439 if (strequal(argv[2], "dword")) {
440 value.type = REG_DWORD;
441 value.v.dword = strtoul(argv[3], NULL, 10);
443 else if (strequal(argv[2], "sz")) {
444 value.type = REG_SZ;
445 value.v.sz.len = strlen(argv[3])+1;
446 value.v.sz.str = CONST_DISCARD(char *, argv[3]);
448 else {
449 d_fprintf(stderr, _("type \"%s\" not implemented\n"), argv[2]);
450 status = NT_STATUS_NOT_IMPLEMENTED;
451 goto error;
454 status = registry_setvalue(mem_ctx, pipe_hnd, &key_hnd,
455 argv[1], &value);
457 if (!NT_STATUS_IS_OK(status)) {
458 d_fprintf(stderr, _("registry_setvalue failed: %s\n"),
459 nt_errstr(status));
462 error:
463 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &key_hnd, NULL);
464 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd, NULL);
466 return NT_STATUS_OK;
469 static int rpc_registry_setvalue(struct net_context *c, int argc,
470 const char **argv )
472 if (argc < 4 || c->display_usage) {
473 d_fprintf(stderr, _("usage: net rpc registry setvalue <key> "
474 "<valuename> <type> [<val>]+\n"));
475 return -1;
478 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
479 rpc_registry_setvalue_internal, argc, argv );
482 static NTSTATUS rpc_registry_deletevalue_internal(struct net_context *c,
483 const DOM_SID *domain_sid,
484 const char *domain_name,
485 struct cli_state *cli,
486 struct rpc_pipe_client *pipe_hnd,
487 TALLOC_CTX *mem_ctx,
488 int argc,
489 const char **argv )
491 struct policy_handle hive_hnd, key_hnd;
492 NTSTATUS status;
493 struct winreg_String valuename;
495 ZERO_STRUCT(valuename);
497 status = registry_openkey(mem_ctx, pipe_hnd, argv[0],
498 SEC_FLAG_MAXIMUM_ALLOWED,
499 &hive_hnd, &key_hnd);
500 if (!NT_STATUS_IS_OK(status)) {
501 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
502 nt_errstr(status));
503 return status;
506 valuename.name = argv[1];
508 status = rpccli_winreg_DeleteValue(pipe_hnd, mem_ctx, &key_hnd,
509 valuename, NULL);
511 if (!NT_STATUS_IS_OK(status)) {
512 d_fprintf(stderr, _("registry_deletevalue failed: %s\n"),
513 nt_errstr(status));
516 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &key_hnd, NULL);
517 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd, NULL);
519 return status;
522 static int rpc_registry_deletevalue(struct net_context *c, int argc,
523 const char **argv )
525 if (argc != 2 || c->display_usage) {
526 d_fprintf(stderr, _("usage: net rpc registry deletevalue <key> "
527 "<valuename>\n"));
528 return -1;
531 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
532 rpc_registry_deletevalue_internal, argc, argv );
535 static NTSTATUS rpc_registry_getvalue_internal(struct net_context *c,
536 const DOM_SID *domain_sid,
537 const char *domain_name,
538 struct cli_state *cli,
539 struct rpc_pipe_client *pipe_hnd,
540 TALLOC_CTX *mem_ctx,
541 bool raw,
542 int argc,
543 const char **argv)
545 struct policy_handle hive_hnd, key_hnd;
546 NTSTATUS status;
547 WERROR werr;
548 struct winreg_String valuename;
549 struct registry_value *value = NULL;
550 enum winreg_Type type = REG_NONE;
551 uint8_t *data = NULL;
552 uint32_t data_size = 0;
553 uint32_t value_length = 0;
554 TALLOC_CTX *tmp_ctx = talloc_stackframe();
556 ZERO_STRUCT(valuename);
558 status = registry_openkey(tmp_ctx, pipe_hnd, argv[0],
559 SEC_FLAG_MAXIMUM_ALLOWED,
560 &hive_hnd, &key_hnd);
561 if (!NT_STATUS_IS_OK(status)) {
562 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
563 nt_errstr(status));
564 return status;
567 valuename.name = argv[1];
570 * call QueryValue once with data == NULL to get the
571 * needed memory size to be allocated, then allocate
572 * data buffer and call again.
574 status = rpccli_winreg_QueryValue(pipe_hnd, tmp_ctx, &key_hnd,
575 &valuename,
576 &type,
577 data,
578 &data_size,
579 &value_length,
580 NULL);
582 if (!NT_STATUS_IS_OK(status)) {
583 d_fprintf(stderr, _("registry_queryvalue failed: %s\n"),
584 nt_errstr(status));
585 goto done;
588 data = (uint8 *)TALLOC(tmp_ctx, data_size);
589 value_length = 0;
591 status = rpccli_winreg_QueryValue(pipe_hnd, tmp_ctx, &key_hnd,
592 &valuename,
593 &type,
594 data,
595 &data_size,
596 &value_length,
597 NULL);
599 if (!NT_STATUS_IS_OK(status)) {
600 d_fprintf(stderr, _("registry_queryvalue failed: %s\n"),
601 nt_errstr(status));
602 goto done;
605 werr = registry_pull_value(tmp_ctx, &value, type, data,
606 data_size, value_length);
607 if (!W_ERROR_IS_OK(werr)) {
608 status = werror_to_ntstatus(werr);
609 goto done;
612 print_registry_value(value, raw);
614 done:
615 rpccli_winreg_CloseKey(pipe_hnd, tmp_ctx, &key_hnd, NULL);
616 rpccli_winreg_CloseKey(pipe_hnd, tmp_ctx, &hive_hnd, NULL);
618 TALLOC_FREE(tmp_ctx);
620 return status;
623 static NTSTATUS rpc_registry_getvalue_full(struct net_context *c,
624 const DOM_SID *domain_sid,
625 const char *domain_name,
626 struct cli_state *cli,
627 struct rpc_pipe_client *pipe_hnd,
628 TALLOC_CTX *mem_ctx,
629 int argc,
630 const char **argv)
632 return rpc_registry_getvalue_internal(c, domain_sid, domain_name,
633 cli, pipe_hnd, mem_ctx, false,
634 argc, argv);
637 static int rpc_registry_getvalue(struct net_context *c, int argc,
638 const char **argv)
640 if (argc != 2 || c->display_usage) {
641 d_fprintf(stderr, _("usage: net rpc registry getvalue <key> "
642 "<valuename>\n"));
643 return -1;
646 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
647 rpc_registry_getvalue_full, argc, argv);
650 static NTSTATUS rpc_registry_getvalue_raw(struct net_context *c,
651 const DOM_SID *domain_sid,
652 const char *domain_name,
653 struct cli_state *cli,
654 struct rpc_pipe_client *pipe_hnd,
655 TALLOC_CTX *mem_ctx,
656 int argc,
657 const char **argv)
659 return rpc_registry_getvalue_internal(c, domain_sid, domain_name,
660 cli, pipe_hnd, mem_ctx, true,
661 argc, argv);
664 static int rpc_registry_getvalueraw(struct net_context *c, int argc,
665 const char **argv)
667 if (argc != 2 || c->display_usage) {
668 d_fprintf(stderr, _("usage: net rpc registry getvalue <key> "
669 "<valuename>\n"));
670 return -1;
673 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
674 rpc_registry_getvalue_raw, argc, argv);
677 static NTSTATUS rpc_registry_createkey_internal(struct net_context *c,
678 const DOM_SID *domain_sid,
679 const char *domain_name,
680 struct cli_state *cli,
681 struct rpc_pipe_client *pipe_hnd,
682 TALLOC_CTX *mem_ctx,
683 int argc,
684 const char **argv )
686 uint32 hive;
687 struct policy_handle hive_hnd, key_hnd;
688 struct winreg_String key, keyclass;
689 enum winreg_CreateAction action;
690 NTSTATUS status;
692 ZERO_STRUCT(key);
693 ZERO_STRUCT(keyclass);
695 if (!reg_hive_key(mem_ctx, argv[0], &hive, &key.name)) {
696 return NT_STATUS_INVALID_PARAMETER;
699 status = rpccli_winreg_Connect(pipe_hnd, mem_ctx, hive,
700 SEC_FLAG_MAXIMUM_ALLOWED,
701 &hive_hnd);
702 if (!(NT_STATUS_IS_OK(status))) {
703 return status;
706 action = REG_ACTION_NONE;
707 keyclass.name = "";
709 status = rpccli_winreg_CreateKey(pipe_hnd, mem_ctx, &hive_hnd, key,
710 keyclass, 0, REG_KEY_READ, NULL,
711 &key_hnd, &action, NULL);
712 if (!NT_STATUS_IS_OK(status)) {
713 d_fprintf(stderr, _("createkey returned %s\n"),
714 nt_errstr(status));
715 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd, NULL);
716 return status;
719 switch (action) {
720 case REG_ACTION_NONE:
721 d_printf(_("createkey did nothing -- huh?\n"));
722 break;
723 case REG_CREATED_NEW_KEY:
724 d_printf(_("createkey created %s\n"), argv[0]);
725 break;
726 case REG_OPENED_EXISTING_KEY:
727 d_printf(_("createkey opened existing %s\n"), argv[0]);
728 break;
731 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &key_hnd, NULL);
732 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd, NULL);
734 return status;
737 static int rpc_registry_createkey(struct net_context *c, int argc,
738 const char **argv )
740 if (argc != 1 || c->display_usage) {
741 d_fprintf(stderr,
742 _("usage: net rpc registry createkey <key>\n"));
743 return -1;
746 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
747 rpc_registry_createkey_internal, argc, argv );
750 static NTSTATUS rpc_registry_deletekey_internal(struct net_context *c,
751 const DOM_SID *domain_sid,
752 const char *domain_name,
753 struct cli_state *cli,
754 struct rpc_pipe_client *pipe_hnd,
755 TALLOC_CTX *mem_ctx,
756 int argc,
757 const char **argv )
759 uint32 hive;
760 struct policy_handle hive_hnd;
761 struct winreg_String key;
762 NTSTATUS status;
764 ZERO_STRUCT(key);
766 if (!reg_hive_key(mem_ctx, argv[0], &hive, &key.name)) {
767 return NT_STATUS_INVALID_PARAMETER;
770 status = rpccli_winreg_Connect(pipe_hnd, mem_ctx, hive,
771 SEC_FLAG_MAXIMUM_ALLOWED,
772 &hive_hnd);
773 if (!(NT_STATUS_IS_OK(status))) {
774 return status;
777 status = rpccli_winreg_DeleteKey(pipe_hnd, mem_ctx, &hive_hnd, key, NULL);
778 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd, NULL);
780 if (!NT_STATUS_IS_OK(status)) {
781 d_fprintf(stderr, _("deletekey returned %s\n"),
782 nt_errstr(status));
785 return status;
788 static int rpc_registry_deletekey(struct net_context *c, int argc, const char **argv )
790 if (argc != 1 || c->display_usage) {
791 d_fprintf(stderr,
792 _("usage: net rpc registry deletekey <key>\n"));
793 return -1;
796 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
797 rpc_registry_deletekey_internal, argc, argv );
800 /********************************************************************
801 ********************************************************************/
803 static NTSTATUS rpc_registry_enumerate_internal(struct net_context *c,
804 const DOM_SID *domain_sid,
805 const char *domain_name,
806 struct cli_state *cli,
807 struct rpc_pipe_client *pipe_hnd,
808 TALLOC_CTX *mem_ctx,
809 int argc,
810 const char **argv )
812 struct policy_handle pol_hive, pol_key;
813 NTSTATUS status;
814 uint32 num_subkeys = 0;
815 uint32 num_values = 0;
816 char **names = NULL, **classes = NULL;
817 NTTIME **modtimes = NULL;
818 uint32 i;
819 struct registry_value **values = NULL;
821 if (argc != 1 || c->display_usage) {
822 d_printf(_("Usage: net rpc registry enumerate <path>\n"));
823 d_printf(_("Example: net rpc registry enumerate "
824 "'HKLM\\Software\\Samba'\n"));
825 return NT_STATUS_INVALID_PARAMETER;
828 status = registry_openkey(mem_ctx, pipe_hnd, argv[0], REG_KEY_READ,
829 &pol_hive, &pol_key);
830 if (!NT_STATUS_IS_OK(status)) {
831 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
832 nt_errstr(status));
833 return status;
836 status = registry_enumkeys(mem_ctx, pipe_hnd, &pol_key, &num_subkeys,
837 &names, &classes, &modtimes);
838 if (!NT_STATUS_IS_OK(status)) {
839 d_fprintf(stderr, _("enumerating keys failed: %s\n"),
840 nt_errstr(status));
841 return status;
844 for (i=0; i<num_subkeys; i++) {
845 print_registry_key(names[i], modtimes[i]);
848 status = registry_enumvalues(mem_ctx, pipe_hnd, &pol_key, &num_values,
849 &names, &values);
850 if (!NT_STATUS_IS_OK(status)) {
851 d_fprintf(stderr, _("enumerating values failed: %s\n"),
852 nt_errstr(status));
853 return status;
856 for (i=0; i<num_values; i++) {
857 print_registry_value_with_name(names[i], values[i]);
860 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_key, NULL);
861 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_hive, NULL);
863 return status;
866 /********************************************************************
867 ********************************************************************/
869 static int rpc_registry_enumerate(struct net_context *c, int argc,
870 const char **argv )
872 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
873 rpc_registry_enumerate_internal, argc, argv );
876 /********************************************************************
877 ********************************************************************/
879 static NTSTATUS rpc_registry_save_internal(struct net_context *c,
880 const DOM_SID *domain_sid,
881 const char *domain_name,
882 struct cli_state *cli,
883 struct rpc_pipe_client *pipe_hnd,
884 TALLOC_CTX *mem_ctx,
885 int argc,
886 const char **argv )
888 WERROR result = WERR_GENERAL_FAILURE;
889 struct policy_handle pol_hive, pol_key;
890 NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
891 struct winreg_String filename;
893 if (argc != 2 || c->display_usage) {
894 d_printf(_("Usage: net rpc registry backup <path> "
895 "<file> \n"));
896 return NT_STATUS_INVALID_PARAMETER;
899 status = registry_openkey(mem_ctx, pipe_hnd, argv[0], REG_KEY_ALL,
900 &pol_hive, &pol_key);
901 if (!NT_STATUS_IS_OK(status)) {
902 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
903 nt_errstr(status));
904 return status;
907 filename.name = argv[1];
908 status = rpccli_winreg_SaveKey( pipe_hnd, mem_ctx, &pol_key, &filename, NULL, NULL);
909 if ( !W_ERROR_IS_OK(result) ) {
910 d_fprintf(stderr, _("Unable to save [%s] to %s:%s\n"), argv[0],
911 cli->desthost, argv[1]);
914 /* cleanup */
916 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_key, NULL);
917 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_hive, NULL);
919 return status;
922 /********************************************************************
923 ********************************************************************/
925 static int rpc_registry_save(struct net_context *c, int argc, const char **argv )
927 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
928 rpc_registry_save_internal, argc, argv );
932 /********************************************************************
933 ********************************************************************/
935 static void dump_values( REGF_NK_REC *nk )
937 int i, j;
938 const char *data_str = NULL;
939 uint32 data_size, data;
940 DATA_BLOB blob;
942 if ( !nk->values )
943 return;
945 for ( i=0; i<nk->num_values; i++ ) {
946 d_printf( "\"%s\" = ", nk->values[i].valuename ? nk->values[i].valuename : "(default)" );
947 d_printf( "(%s) ", reg_type_lookup( nk->values[i].type ) );
949 data_size = nk->values[i].data_size & ~VK_DATA_IN_OFFSET;
950 switch ( nk->values[i].type ) {
951 case REG_SZ:
952 blob = data_blob_const(nk->values[i].data, data_size);
953 pull_reg_sz(talloc_tos(), &blob, &data_str);
954 if (!data_str) {
955 break;
957 d_printf( "%s", data_str );
958 break;
959 case REG_MULTI_SZ:
960 case REG_EXPAND_SZ:
961 for ( j=0; j<data_size; j++ ) {
962 d_printf( "%c", nk->values[i].data[j] );
964 break;
965 case REG_DWORD:
966 data = IVAL( nk->values[i].data, 0 );
967 d_printf("0x%x", data );
968 break;
969 case REG_BINARY:
970 for ( j=0; j<data_size; j++ ) {
971 d_printf( "%x", nk->values[i].data[j] );
973 break;
974 default:
975 d_printf(_("unknown"));
976 break;
979 d_printf( "\n" );
984 /********************************************************************
985 ********************************************************************/
987 static bool dump_registry_tree( REGF_FILE *file, REGF_NK_REC *nk, const char *parent )
989 REGF_NK_REC *key;
991 /* depth first dump of the registry tree */
993 while ( (key = regfio_fetch_subkey( file, nk )) ) {
994 char *regpath;
995 if (asprintf(&regpath, "%s\\%s", parent, key->keyname) < 0) {
996 break;
998 d_printf("[%s]\n", regpath );
999 dump_values( key );
1000 d_printf("\n");
1001 dump_registry_tree( file, key, regpath );
1002 SAFE_FREE(regpath);
1005 return true;
1008 /********************************************************************
1009 ********************************************************************/
1011 static bool write_registry_tree( REGF_FILE *infile, REGF_NK_REC *nk,
1012 REGF_NK_REC *parent, REGF_FILE *outfile,
1013 const char *parentpath )
1015 REGF_NK_REC *key, *subkey;
1016 struct regval_ctr *values = NULL;
1017 struct regsubkey_ctr *subkeys = NULL;
1018 int i;
1019 char *path = NULL;
1020 WERROR werr;
1022 werr = regsubkey_ctr_init(infile->mem_ctx, &subkeys);
1023 if (!W_ERROR_IS_OK(werr)) {
1024 DEBUG(0, ("write_registry_tree: regsubkey_ctr_init failed: "
1025 "%s\n", win_errstr(werr)));
1026 return false;
1029 if ( !(values = TALLOC_ZERO_P( subkeys, struct regval_ctr )) ) {
1030 DEBUG(0,("write_registry_tree: talloc() failed!\n"));
1031 TALLOC_FREE(subkeys);
1032 return false;
1035 /* copy values into the struct regval_ctr */
1037 for ( i=0; i<nk->num_values; i++ ) {
1038 regval_ctr_addvalue( values, nk->values[i].valuename, nk->values[i].type,
1039 (const char *)nk->values[i].data, (nk->values[i].data_size & ~VK_DATA_IN_OFFSET) );
1042 /* copy subkeys into the struct regsubkey_ctr */
1044 while ( (subkey = regfio_fetch_subkey( infile, nk )) ) {
1045 regsubkey_ctr_addkey( subkeys, subkey->keyname );
1048 key = regfio_write_key( outfile, nk->keyname, values, subkeys, nk->sec_desc->sec_desc, parent );
1050 /* write each one of the subkeys out */
1052 path = talloc_asprintf(subkeys,
1053 "%s%s%s",
1054 parentpath,
1055 parent ? "\\" : "",
1056 nk->keyname);
1057 if (!path) {
1058 TALLOC_FREE(subkeys);
1059 return false;
1062 nk->subkey_index = 0;
1063 while ( (subkey = regfio_fetch_subkey( infile, nk )) ) {
1064 write_registry_tree( infile, subkey, key, outfile, path );
1067 d_printf("[%s]\n", path );
1068 TALLOC_FREE(subkeys);
1070 return true;
1073 /********************************************************************
1074 ********************************************************************/
1076 static int rpc_registry_dump(struct net_context *c, int argc, const char **argv)
1078 REGF_FILE *registry;
1079 REGF_NK_REC *nk;
1081 if (argc != 1 || c->display_usage) {
1082 d_printf(_("Usage: net rpc registry dump <file> \n"));
1083 return -1;
1086 d_printf(_("Opening %s...."), argv[0]);
1087 if ( !(registry = regfio_open( argv[0], O_RDONLY, 0)) ) {
1088 d_fprintf(stderr, _("Failed to open %s for reading\n"),argv[0]);
1089 return 1;
1091 d_printf(_("ok\n"));
1093 /* get the root of the registry file */
1095 if ((nk = regfio_rootkey( registry )) == NULL) {
1096 d_fprintf(stderr, _("Could not get rootkey\n"));
1097 regfio_close( registry );
1098 return 1;
1100 d_printf("[%s]\n", nk->keyname);
1101 dump_values( nk );
1102 d_printf("\n");
1104 dump_registry_tree( registry, nk, nk->keyname );
1106 #if 0
1107 talloc_report_full( registry->mem_ctx, stderr );
1108 #endif
1109 d_printf(_("Closing registry..."));
1110 regfio_close( registry );
1111 d_printf(_("ok\n"));
1113 return 0;
1116 /********************************************************************
1117 ********************************************************************/
1119 static int rpc_registry_copy(struct net_context *c, int argc, const char **argv )
1121 REGF_FILE *infile = NULL, *outfile = NULL;
1122 REGF_NK_REC *nk;
1123 int result = 1;
1125 if (argc != 2 || c->display_usage) {
1126 d_printf(_("Usage: net rpc registry copy <srcfile> "
1127 "<newfile>\n"));
1128 return -1;
1131 d_printf(_("Opening %s...."), argv[0]);
1132 if ( !(infile = regfio_open( argv[0], O_RDONLY, 0 )) ) {
1133 d_fprintf(stderr, _("Failed to open %s for reading\n"),argv[0]);
1134 return 1;
1136 d_printf(_("ok\n"));
1138 d_printf(_("Opening %s...."), argv[1]);
1139 if ( !(outfile = regfio_open( argv[1], (O_RDWR|O_CREAT|O_TRUNC), (S_IREAD|S_IWRITE) )) ) {
1140 d_fprintf(stderr, _("Failed to open %s for writing\n"),argv[1]);
1141 goto out;
1143 d_printf(_("ok\n"));
1145 /* get the root of the registry file */
1147 if ((nk = regfio_rootkey( infile )) == NULL) {
1148 d_fprintf(stderr, _("Could not get rootkey\n"));
1149 goto out;
1151 d_printf(_("RootKey: [%s]\n"), nk->keyname);
1153 write_registry_tree( infile, nk, NULL, outfile, "" );
1155 result = 0;
1157 out:
1159 d_printf(_("Closing %s..."), argv[1]);
1160 if (outfile) {
1161 regfio_close( outfile );
1163 d_printf(_("ok\n"));
1165 d_printf(_("Closing %s..."), argv[0]);
1166 if (infile) {
1167 regfio_close( infile );
1169 d_printf(_("ok\n"));
1171 return( result);
1174 /********************************************************************
1175 ********************************************************************/
1177 static NTSTATUS rpc_registry_getsd_internal(struct net_context *c,
1178 const DOM_SID *domain_sid,
1179 const char *domain_name,
1180 struct cli_state *cli,
1181 struct rpc_pipe_client *pipe_hnd,
1182 TALLOC_CTX *mem_ctx,
1183 int argc,
1184 const char **argv)
1186 struct policy_handle pol_hive, pol_key;
1187 NTSTATUS status;
1188 enum ndr_err_code ndr_err;
1189 struct KeySecurityData *sd = NULL;
1190 uint32_t sec_info;
1191 DATA_BLOB blob;
1192 struct security_descriptor sec_desc;
1193 uint32_t access_mask = REG_KEY_READ |
1194 SEC_FLAG_MAXIMUM_ALLOWED |
1195 SEC_FLAG_SYSTEM_SECURITY;
1197 if (argc <1 || argc > 2 || c->display_usage) {
1198 d_printf(_("Usage: net rpc registry getsd <path> "
1199 "<secinfo>\n"));
1200 d_printf(_("Example: net rpc registry getsd "
1201 "'HKLM\\Software\\Samba'\n"));
1202 return NT_STATUS_INVALID_PARAMETER;
1205 status = registry_openkey(mem_ctx, pipe_hnd, argv[0],
1206 access_mask,
1207 &pol_hive, &pol_key);
1208 if (!NT_STATUS_IS_OK(status)) {
1209 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
1210 nt_errstr(status));
1211 return status;
1214 sd = TALLOC_ZERO_P(mem_ctx, struct KeySecurityData);
1215 if (!sd) {
1216 status = NT_STATUS_NO_MEMORY;
1217 goto out;
1220 sd->size = 0x1000;
1222 if (argc >= 2) {
1223 sscanf(argv[1], "%x", &sec_info);
1224 } else {
1225 sec_info = SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL;
1228 status = registry_getsd(mem_ctx, pipe_hnd, &pol_key, sec_info, sd);
1229 if (!NT_STATUS_IS_OK(status)) {
1230 d_fprintf(stderr, _("getting sd failed: %s\n"),
1231 nt_errstr(status));
1232 goto out;
1235 blob.data = sd->data;
1236 blob.length = sd->size;
1238 ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, NULL, &sec_desc,
1239 (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
1240 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1241 status = ndr_map_error2ntstatus(ndr_err);
1242 goto out;
1244 status = NT_STATUS_OK;
1246 display_sec_desc(&sec_desc);
1248 out:
1249 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_key, NULL);
1250 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_hive, NULL);
1252 return status;
1256 static int rpc_registry_getsd(struct net_context *c, int argc, const char **argv)
1258 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
1259 rpc_registry_getsd_internal, argc, argv);
1262 /********************************************************************
1263 ********************************************************************/
1265 int net_rpc_registry(struct net_context *c, int argc, const char **argv)
1267 struct functable func[] = {
1269 "enumerate",
1270 rpc_registry_enumerate,
1271 NET_TRANSPORT_RPC,
1272 N_("Enumerate registry keys and values"),
1273 N_("net rpc registry enumerate\n"
1274 " Enumerate registry keys and values")
1277 "createkey",
1278 rpc_registry_createkey,
1279 NET_TRANSPORT_RPC,
1280 N_("Create a new registry key"),
1281 N_("net rpc registry createkey\n"
1282 " Create a new registry key")
1285 "deletekey",
1286 rpc_registry_deletekey,
1287 NET_TRANSPORT_RPC,
1288 N_("Delete a registry key"),
1289 N_("net rpc registry deletekey\n"
1290 " Delete a registry key")
1293 "getvalue",
1294 rpc_registry_getvalue,
1295 NET_TRANSPORT_RPC,
1296 N_("Print a registry value"),
1297 N_("net rpc registry getvalue\n"
1298 " Print a registry value")
1301 "getvalueraw",
1302 rpc_registry_getvalueraw,
1303 NET_TRANSPORT_RPC,
1304 N_("Print a registry value"),
1305 N_("net rpc registry getvalueraw\n"
1306 " Print a registry value (raw version)")
1309 "setvalue",
1310 rpc_registry_setvalue,
1311 NET_TRANSPORT_RPC,
1312 N_("Set a new registry value"),
1313 N_("net rpc registry setvalue\n"
1314 " Set a new registry value")
1317 "deletevalue",
1318 rpc_registry_deletevalue,
1319 NET_TRANSPORT_RPC,
1320 N_("Delete a registry value"),
1321 N_("net rpc registry deletevalue\n"
1322 " Delete a registry value")
1325 "save",
1326 rpc_registry_save,
1327 NET_TRANSPORT_RPC,
1328 N_("Save a registry file"),
1329 N_("net rpc registry save\n"
1330 " Save a registry file")
1333 "dump",
1334 rpc_registry_dump,
1335 NET_TRANSPORT_RPC,
1336 N_("Dump a registry file"),
1337 N_("net rpc registry dump\n"
1338 " Dump a registry file")
1341 "copy",
1342 rpc_registry_copy,
1343 NET_TRANSPORT_RPC,
1344 N_("Copy a registry file"),
1345 N_("net rpc registry copy\n"
1346 " Copy a registry file")
1349 "getsd",
1350 rpc_registry_getsd,
1351 NET_TRANSPORT_RPC,
1352 N_("Get security descriptor"),
1353 N_("net rpc registry getsd\n"
1354 " Get security descriptior")
1356 {NULL, NULL, 0, NULL, NULL}
1359 return net_run_function(c, argc, argv, "net rpc registry", func);