s4:samr: allow builtin groups for samr_OpenGroup.
[Samba.git] / source3 / utils / net_rpc_registry.c
blobcc4eaa7eaa5b142c2d645cfedbc3ca9e82240861
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 "system/filesys.h"
22 #include "rpc_client/rpc_client.h"
23 #include "registry.h"
24 #include "utils/net.h"
25 #include "utils/net_registry_util.h"
26 #include "registry/regfio.h"
27 #include "../librpc/gen_ndr/ndr_winreg_c.h"
28 #include "../librpc/gen_ndr/ndr_security.h"
29 #include "registry/reg_format.h"
30 #include "registry/reg_import.h"
31 #include <assert.h>
32 #include "../libcli/security/display_sec.h"
33 #include "../libcli/registry/util_reg.h"
34 #include "client.h"
37 /*******************************************************************
38 connect to a registry hive root (open a registry policy)
39 *******************************************************************/
41 static NTSTATUS dcerpc_winreg_Connect(struct dcerpc_binding_handle *b, TALLOC_CTX *mem_ctx,
42 uint32_t reg_type, uint32_t access_mask,
43 struct policy_handle *reg_hnd, WERROR *werr)
45 ZERO_STRUCTP(reg_hnd);
47 switch (reg_type)
49 case HKEY_CLASSES_ROOT:
50 return dcerpc_winreg_OpenHKCR(b, mem_ctx, NULL,
51 access_mask, reg_hnd, werr);
53 case HKEY_LOCAL_MACHINE:
54 return dcerpc_winreg_OpenHKLM(b, mem_ctx, NULL,
55 access_mask, reg_hnd, werr);
57 case HKEY_USERS:
58 return dcerpc_winreg_OpenHKU(b, mem_ctx, NULL,
59 access_mask, reg_hnd, werr);
61 case HKEY_CURRENT_USER:
62 return dcerpc_winreg_OpenHKCU(b, mem_ctx, NULL,
63 access_mask, reg_hnd, werr);
65 case HKEY_PERFORMANCE_DATA:
66 return dcerpc_winreg_OpenHKPD(b, mem_ctx, NULL,
67 access_mask, reg_hnd, werr);
69 default:
70 /* fall through to end of function */
71 break;
74 return NT_STATUS_INVALID_PARAMETER;
77 static bool reg_hive_key(TALLOC_CTX *ctx, const char *fullname,
78 uint32 *reg_type, const char **key_name)
80 WERROR werr;
81 char *hivename = NULL;
82 char *tmp_keyname = NULL;
83 bool ret = false;
84 TALLOC_CTX *tmp_ctx = talloc_stackframe();
86 werr = split_hive_key(tmp_ctx, fullname, &hivename, &tmp_keyname);
87 if (!W_ERROR_IS_OK(werr)) {
88 goto done;
91 *key_name = talloc_strdup(ctx, tmp_keyname);
92 if (*key_name == NULL) {
93 goto done;
96 if (strequal(hivename, "HKLM") ||
97 strequal(hivename, "HKEY_LOCAL_MACHINE"))
99 (*reg_type) = HKEY_LOCAL_MACHINE;
100 } else if (strequal(hivename, "HKCR") ||
101 strequal(hivename, "HKEY_CLASSES_ROOT"))
103 (*reg_type) = HKEY_CLASSES_ROOT;
104 } else if (strequal(hivename, "HKU") ||
105 strequal(hivename, "HKEY_USERS"))
107 (*reg_type) = HKEY_USERS;
108 } else if (strequal(hivename, "HKCU") ||
109 strequal(hivename, "HKEY_CURRENT_USER"))
111 (*reg_type) = HKEY_CURRENT_USER;
112 } else if (strequal(hivename, "HKPD") ||
113 strequal(hivename, "HKEY_PERFORMANCE_DATA"))
115 (*reg_type) = HKEY_PERFORMANCE_DATA;
116 } else {
117 DEBUG(10,("reg_hive_key: unrecognised hive key %s\n",
118 fullname));
119 goto done;
122 ret = true;
124 done:
125 TALLOC_FREE(tmp_ctx);
126 return ret;
129 static NTSTATUS registry_openkey(TALLOC_CTX *mem_ctx,
130 struct rpc_pipe_client *pipe_hnd,
131 const char *name, uint32 access_mask,
132 struct policy_handle *hive_hnd,
133 struct policy_handle *key_hnd)
135 uint32 hive;
136 NTSTATUS status;
137 WERROR werr;
138 struct winreg_String key;
139 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
141 ZERO_STRUCT(key);
143 if (!reg_hive_key(mem_ctx, name, &hive, &key.name)) {
144 return NT_STATUS_INVALID_PARAMETER;
147 status = dcerpc_winreg_Connect(b, mem_ctx, hive, access_mask,
148 hive_hnd, &werr);
149 if (!(NT_STATUS_IS_OK(status))) {
150 return status;
152 if (!W_ERROR_IS_OK(werr)) {
153 return werror_to_ntstatus(werr);
156 status = dcerpc_winreg_OpenKey(b, mem_ctx, hive_hnd, key, 0,
157 access_mask, key_hnd, &werr);
158 if (!(NT_STATUS_IS_OK(status))) {
159 dcerpc_winreg_CloseKey(b, mem_ctx, hive_hnd, &werr);
160 return status;
162 if (!(W_ERROR_IS_OK(werr))) {
163 WERROR _werr;
164 dcerpc_winreg_CloseKey(b, mem_ctx, hive_hnd, &_werr);
165 return werror_to_ntstatus(werr);
168 return NT_STATUS_OK;
171 static NTSTATUS registry_enumkeys(TALLOC_CTX *ctx,
172 struct rpc_pipe_client *pipe_hnd,
173 struct policy_handle *key_hnd,
174 uint32 *pnum_keys, char ***pnames,
175 char ***pclasses, NTTIME ***pmodtimes)
177 TALLOC_CTX *mem_ctx;
178 NTSTATUS status;
179 WERROR werr;
180 uint32 num_subkeys, max_subkeylen, max_classlen;
181 uint32 num_values, max_valnamelen, max_valbufsize;
182 uint32 i;
183 NTTIME last_changed_time;
184 uint32 secdescsize;
185 struct winreg_String classname;
186 char **names, **classes;
187 NTTIME **modtimes;
188 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
190 if (!(mem_ctx = talloc_new(ctx))) {
191 return NT_STATUS_NO_MEMORY;
194 ZERO_STRUCT(classname);
195 status = dcerpc_winreg_QueryInfoKey(
196 b, mem_ctx, key_hnd, &classname, &num_subkeys,
197 &max_subkeylen, &max_classlen, &num_values, &max_valnamelen,
198 &max_valbufsize, &secdescsize, &last_changed_time, &werr);
200 if (!NT_STATUS_IS_OK(status)) {
201 goto error;
203 if (!W_ERROR_IS_OK(werr)) {
204 status = werror_to_ntstatus(werr);
205 goto error;
208 if (num_subkeys == 0) {
209 *pnum_keys = 0;
210 TALLOC_FREE(mem_ctx);
211 return NT_STATUS_OK;
214 if ((!(names = talloc_zero_array(mem_ctx, char *, num_subkeys))) ||
215 (!(classes = talloc_zero_array(mem_ctx, char *, num_subkeys))) ||
216 (!(modtimes = talloc_zero_array(mem_ctx, NTTIME *,
217 num_subkeys)))) {
218 status = NT_STATUS_NO_MEMORY;
219 goto error;
222 for (i=0; i<num_subkeys; i++) {
223 char c, n;
224 struct winreg_StringBuf class_buf;
225 struct winreg_StringBuf name_buf;
226 NTTIME modtime;
228 c = '\0';
229 class_buf.name = &c;
230 class_buf.size = max_classlen+2;
232 n = '\0';
233 name_buf.name = &n;
234 name_buf.size = max_subkeylen+2;
236 ZERO_STRUCT(modtime);
238 status = dcerpc_winreg_EnumKey(b, mem_ctx, key_hnd,
239 i, &name_buf, &class_buf,
240 &modtime, &werr);
241 if (!NT_STATUS_IS_OK(status)) {
242 goto error;
244 if (W_ERROR_EQUAL(werr,
245 WERR_NO_MORE_ITEMS) ) {
246 status = NT_STATUS_OK;
247 break;
249 if (!W_ERROR_IS_OK(werr)) {
250 status = werror_to_ntstatus(werr);
251 goto error;
254 classes[i] = NULL;
256 if (class_buf.name &&
257 (!(classes[i] = talloc_strdup(classes, class_buf.name)))) {
258 status = NT_STATUS_NO_MEMORY;
259 goto error;
262 if (!(names[i] = talloc_strdup(names, name_buf.name))) {
263 status = NT_STATUS_NO_MEMORY;
264 goto error;
267 if ((!(modtimes[i] = (NTTIME *)talloc_memdup(
268 modtimes, &modtime, sizeof(modtime))))) {
269 status = NT_STATUS_NO_MEMORY;
270 goto error;
274 *pnum_keys = num_subkeys;
276 if (pnames) {
277 *pnames = talloc_move(ctx, &names);
279 if (pclasses) {
280 *pclasses = talloc_move(ctx, &classes);
282 if (pmodtimes) {
283 *pmodtimes = talloc_move(ctx, &modtimes);
286 status = NT_STATUS_OK;
288 error:
289 TALLOC_FREE(mem_ctx);
290 return status;
293 static NTSTATUS registry_enumvalues(TALLOC_CTX *ctx,
294 struct rpc_pipe_client *pipe_hnd,
295 struct policy_handle *key_hnd,
296 uint32 *pnum_values, char ***pvalnames,
297 struct registry_value ***pvalues)
299 TALLOC_CTX *mem_ctx;
300 NTSTATUS status;
301 WERROR werr;
302 uint32 num_subkeys, max_subkeylen, max_classlen;
303 uint32 num_values, max_valnamelen, max_valbufsize;
304 uint32 i;
305 NTTIME last_changed_time;
306 uint32 secdescsize;
307 struct winreg_String classname;
308 struct registry_value **values;
309 char **names;
310 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
312 if (!(mem_ctx = talloc_new(ctx))) {
313 return NT_STATUS_NO_MEMORY;
316 ZERO_STRUCT(classname);
317 status = dcerpc_winreg_QueryInfoKey(
318 b, mem_ctx, key_hnd, &classname, &num_subkeys,
319 &max_subkeylen, &max_classlen, &num_values, &max_valnamelen,
320 &max_valbufsize, &secdescsize, &last_changed_time, &werr);
322 if (!NT_STATUS_IS_OK(status)) {
323 goto error;
325 if (!W_ERROR_IS_OK(werr)) {
326 status = werror_to_ntstatus(werr);
327 goto error;
330 if (num_values == 0) {
331 *pnum_values = 0;
332 TALLOC_FREE(mem_ctx);
333 return NT_STATUS_OK;
336 if ((!(names = talloc_array(mem_ctx, char *, num_values))) ||
337 (!(values = talloc_array(mem_ctx, struct registry_value *,
338 num_values)))) {
339 status = NT_STATUS_NO_MEMORY;
340 goto error;
343 for (i=0; i<num_values; i++) {
344 enum winreg_Type type = REG_NONE;
345 uint8 *data = NULL;
346 uint32 data_size;
347 uint32 value_length;
349 char n;
350 struct winreg_ValNameBuf name_buf;
351 WERROR err;
353 n = '\0';
354 name_buf.name = &n;
355 name_buf.size = max_valnamelen + 2;
357 data_size = max_valbufsize;
358 data = (uint8 *)TALLOC(mem_ctx, data_size);
359 value_length = 0;
361 status = dcerpc_winreg_EnumValue(b, mem_ctx, key_hnd,
362 i, &name_buf, &type,
363 data, &data_size,
364 &value_length, &err);
365 if (!(NT_STATUS_IS_OK(status))) {
366 goto error;
369 if ( W_ERROR_EQUAL(err,
370 WERR_NO_MORE_ITEMS) ) {
371 status = NT_STATUS_OK;
372 break;
375 if (!W_ERROR_IS_OK(err)) {
376 status = werror_to_ntstatus(err);
377 goto error;
380 if (name_buf.name == NULL) {
381 status = NT_STATUS_INVALID_PARAMETER;
382 goto error;
385 if (!(names[i] = talloc_strdup(names, name_buf.name))) {
386 status = NT_STATUS_NO_MEMORY;
387 goto error;
390 values[i] = talloc_zero(values, struct registry_value);
391 if (values[i] == NULL) {
392 status = NT_STATUS_NO_MEMORY;
393 goto error;
396 values[i]->type = type;
397 values[i]->data = data_blob_talloc(values[i], data, data_size);
400 *pnum_values = num_values;
402 if (pvalnames) {
403 *pvalnames = talloc_move(ctx, &names);
405 if (pvalues) {
406 *pvalues = talloc_move(ctx, &values);
409 status = NT_STATUS_OK;
411 error:
412 TALLOC_FREE(mem_ctx);
413 return status;
416 static NTSTATUS registry_enumvalues2(TALLOC_CTX *ctx,
417 struct rpc_pipe_client *pipe_hnd,
418 struct policy_handle *key_hnd,
419 uint32 *pnum_values, char ***pvalnames,
420 struct regval_blob ***pvalues)
422 TALLOC_CTX *mem_ctx;
423 NTSTATUS status;
424 WERROR werr;
425 uint32 num_subkeys, max_subkeylen, max_classlen;
426 uint32 num_values, max_valnamelen, max_valbufsize;
427 uint32 i;
428 NTTIME last_changed_time;
429 uint32 secdescsize;
430 struct winreg_String classname;
431 struct regval_blob **values;
432 char **names;
433 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
435 if (!(mem_ctx = talloc_new(ctx))) {
436 return NT_STATUS_NO_MEMORY;
439 ZERO_STRUCT(classname);
440 status = dcerpc_winreg_QueryInfoKey(
441 b, mem_ctx, key_hnd, &classname, &num_subkeys,
442 &max_subkeylen, &max_classlen, &num_values, &max_valnamelen,
443 &max_valbufsize, &secdescsize, &last_changed_time, &werr);
445 if (!NT_STATUS_IS_OK(status)) {
446 goto error;
448 if (!W_ERROR_IS_OK(werr)) {
449 status = werror_to_ntstatus(werr);
450 goto error;
453 if (num_values == 0) {
454 *pnum_values = 0;
455 TALLOC_FREE(mem_ctx);
456 return NT_STATUS_OK;
459 if ((!(names = talloc_array(mem_ctx, char *, num_values))) ||
460 (!(values = talloc_array(mem_ctx, struct regval_blob *,
461 num_values)))) {
462 status = NT_STATUS_NO_MEMORY;
463 goto error;
466 for (i=0; i<num_values; i++) {
467 enum winreg_Type type = REG_NONE;
468 uint8 *data = NULL;
469 uint32 data_size;
470 uint32 value_length;
472 char n;
473 struct winreg_ValNameBuf name_buf;
474 WERROR err;
476 n = '\0';
477 name_buf.name = &n;
478 name_buf.size = max_valnamelen + 2;
480 data_size = max_valbufsize;
481 data = (uint8 *)TALLOC(mem_ctx, data_size);
482 value_length = 0;
484 status = dcerpc_winreg_EnumValue(b, mem_ctx, key_hnd,
485 i, &name_buf, &type,
486 data, &data_size,
487 &value_length, &err);
488 if (!(NT_STATUS_IS_OK(status))) {
489 goto error;
492 if ( W_ERROR_EQUAL(err, WERR_NO_MORE_ITEMS) ) {
493 status = NT_STATUS_OK;
494 break;
497 if (!W_ERROR_IS_OK(err)) {
498 status = werror_to_ntstatus(err);
499 goto error;
502 if (name_buf.name == NULL) {
503 status = NT_STATUS_INVALID_PARAMETER;
504 goto error;
507 if (!(names[i] = talloc_strdup(names, name_buf.name))) {
508 status = NT_STATUS_NO_MEMORY;
509 goto error;
512 assert(value_length<=data_size); /*??? */
514 values[i] = regval_compose(values,
515 name_buf.name,
516 type,
517 data, value_length);
518 if (!values[i]) {
519 status = NT_STATUS_NO_MEMORY;
520 goto error;
524 *pnum_values = num_values;
526 if (pvalnames) {
527 *pvalnames = talloc_move(ctx, &names);
529 if (pvalues) {
530 *pvalues = talloc_move(ctx, &values);
533 status = NT_STATUS_OK;
535 error:
536 TALLOC_FREE(mem_ctx);
537 return status;
540 static NTSTATUS registry_getsd(TALLOC_CTX *mem_ctx,
541 struct dcerpc_binding_handle *b,
542 struct policy_handle *key_hnd,
543 uint32_t sec_info,
544 struct KeySecurityData *sd,
545 WERROR *werr)
547 return dcerpc_winreg_GetKeySecurity(b, mem_ctx, key_hnd,
548 sec_info, sd, werr);
552 static NTSTATUS registry_setvalue(TALLOC_CTX *mem_ctx,
553 struct rpc_pipe_client *pipe_hnd,
554 struct policy_handle *key_hnd,
555 const char *name,
556 const struct registry_value *value)
558 struct winreg_String name_string;
559 NTSTATUS result;
560 WERROR werr;
561 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
563 ZERO_STRUCT(name_string);
565 name_string.name = name;
566 result = dcerpc_winreg_SetValue(b, mem_ctx, key_hnd,
567 name_string, value->type,
568 value->data.data, value->data.length, &werr);
569 if (!NT_STATUS_IS_OK(result)) {
570 return result;
573 return werror_to_ntstatus(werr);
576 static NTSTATUS rpc_registry_setvalue_internal(struct net_context *c,
577 const struct dom_sid *domain_sid,
578 const char *domain_name,
579 struct cli_state *cli,
580 struct rpc_pipe_client *pipe_hnd,
581 TALLOC_CTX *mem_ctx,
582 int argc,
583 const char **argv )
585 struct policy_handle hive_hnd, key_hnd;
586 NTSTATUS status;
587 WERROR werr;
588 struct registry_value value;
589 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
591 status = registry_openkey(mem_ctx, pipe_hnd, argv[0],
592 SEC_FLAG_MAXIMUM_ALLOWED,
593 &hive_hnd, &key_hnd);
594 if (!NT_STATUS_IS_OK(status)) {
595 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
596 nt_errstr(status));
597 return status;
600 if (!strequal(argv[2], "multi_sz") && (argc != 4)) {
601 d_fprintf(stderr, _("Too many args for type %s\n"), argv[2]);
602 return NT_STATUS_NOT_IMPLEMENTED;
605 if (strequal(argv[2], "dword")) {
606 uint32_t v = strtoul(argv[3], NULL, 10);
607 value.type = REG_DWORD;
608 value.data = data_blob_talloc(mem_ctx, NULL, 4);
609 SIVAL(value.data.data, 0, v);
611 else if (strequal(argv[2], "sz")) {
612 value.type = REG_SZ;
613 if (!push_reg_sz(mem_ctx, &value.data, argv[3])) {
614 status = NT_STATUS_NO_MEMORY;
615 goto error;
618 else {
619 d_fprintf(stderr, _("type \"%s\" not implemented\n"), argv[2]);
620 status = NT_STATUS_NOT_IMPLEMENTED;
621 goto error;
624 status = registry_setvalue(mem_ctx, pipe_hnd, &key_hnd,
625 argv[1], &value);
627 if (!NT_STATUS_IS_OK(status)) {
628 d_fprintf(stderr, _("registry_setvalue failed: %s\n"),
629 nt_errstr(status));
632 error:
633 dcerpc_winreg_CloseKey(b, mem_ctx, &key_hnd, &werr);
634 dcerpc_winreg_CloseKey(b, mem_ctx, &hive_hnd, &werr);
636 return NT_STATUS_OK;
639 static int rpc_registry_setvalue(struct net_context *c, int argc,
640 const char **argv )
642 if (argc < 4 || c->display_usage) {
643 d_fprintf(stderr, "%s\n%s",
644 _("Usage:"),
645 _("net rpc registry setvalue <key> <valuename> "
646 "<type> [<val>]+\n"));
647 return -1;
650 return run_rpc_command(c, NULL, &ndr_table_winreg, 0,
651 rpc_registry_setvalue_internal, argc, argv );
654 static NTSTATUS rpc_registry_deletevalue_internal(struct net_context *c,
655 const struct dom_sid *domain_sid,
656 const char *domain_name,
657 struct cli_state *cli,
658 struct rpc_pipe_client *pipe_hnd,
659 TALLOC_CTX *mem_ctx,
660 int argc,
661 const char **argv )
663 struct policy_handle hive_hnd, key_hnd;
664 NTSTATUS status;
665 WERROR werr;
666 struct winreg_String valuename;
667 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
669 ZERO_STRUCT(valuename);
671 status = registry_openkey(mem_ctx, pipe_hnd, argv[0],
672 SEC_FLAG_MAXIMUM_ALLOWED,
673 &hive_hnd, &key_hnd);
674 if (!NT_STATUS_IS_OK(status)) {
675 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
676 nt_errstr(status));
677 return status;
680 valuename.name = argv[1];
682 status = dcerpc_winreg_DeleteValue(b, mem_ctx, &key_hnd,
683 valuename, &werr);
684 if (!NT_STATUS_IS_OK(status)) {
685 d_fprintf(stderr, _("registry_deletevalue failed: %s\n"),
686 nt_errstr(status));
688 if (!W_ERROR_IS_OK(werr)) {
689 status = werror_to_ntstatus(werr);
690 d_fprintf(stderr, _("registry_deletevalue failed: %s\n"),
691 win_errstr(werr));
694 dcerpc_winreg_CloseKey(b, mem_ctx, &key_hnd, &werr);
695 dcerpc_winreg_CloseKey(b, mem_ctx, &hive_hnd, &werr);
697 return status;
700 static int rpc_registry_deletevalue(struct net_context *c, int argc,
701 const char **argv )
703 if (argc != 2 || c->display_usage) {
704 d_fprintf(stderr, "%s\n%s",
705 _("Usage:"),
706 _("net rpc registry deletevalue <key> <valuename>\n"));
707 return -1;
710 return run_rpc_command(c, NULL, &ndr_table_winreg, 0,
711 rpc_registry_deletevalue_internal, argc, argv );
714 static NTSTATUS rpc_registry_getvalue_internal(struct net_context *c,
715 const struct dom_sid *domain_sid,
716 const char *domain_name,
717 struct cli_state *cli,
718 struct rpc_pipe_client *pipe_hnd,
719 TALLOC_CTX *mem_ctx,
720 bool raw,
721 int argc,
722 const char **argv)
724 struct policy_handle hive_hnd, key_hnd;
725 NTSTATUS status;
726 WERROR werr;
727 struct winreg_String valuename;
728 struct registry_value *value = NULL;
729 enum winreg_Type type = REG_NONE;
730 uint32_t data_size = 0;
731 uint32_t value_length = 0;
732 TALLOC_CTX *tmp_ctx = talloc_stackframe();
733 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
735 ZERO_STRUCT(valuename);
737 status = registry_openkey(tmp_ctx, pipe_hnd, argv[0],
738 SEC_FLAG_MAXIMUM_ALLOWED,
739 &hive_hnd, &key_hnd);
740 if (!NT_STATUS_IS_OK(status)) {
741 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
742 nt_errstr(status));
743 return status;
746 valuename.name = argv[1];
748 value = talloc_zero(tmp_ctx, struct registry_value);
749 if (value == NULL) {
750 return NT_STATUS_NO_MEMORY;
754 * call QueryValue once with data == NULL to get the
755 * needed memory size to be allocated, then allocate
756 * data buffer and call again.
758 status = dcerpc_winreg_QueryValue(b, tmp_ctx, &key_hnd,
759 &valuename,
760 &type,
761 NULL,
762 &data_size,
763 &value_length,
764 &werr);
766 if (!NT_STATUS_IS_OK(status)) {
767 d_fprintf(stderr, _("registry_queryvalue failed: %s\n"),
768 nt_errstr(status));
769 goto done;
771 if (!W_ERROR_IS_OK(werr)) {
772 status = werror_to_ntstatus(werr);
773 d_fprintf(stderr, _("registry_queryvalue failed: %s\n"),
774 nt_errstr(status));
775 goto done;
778 value->data = data_blob_talloc(tmp_ctx, NULL, data_size);
780 status = dcerpc_winreg_QueryValue(b, tmp_ctx, &key_hnd,
781 &valuename,
782 &type,
783 value->data.data,
784 &data_size,
785 &value_length,
786 &werr);
788 if (!NT_STATUS_IS_OK(status)) {
789 d_fprintf(stderr, _("registry_queryvalue failed: %s\n"),
790 nt_errstr(status));
791 goto done;
793 if (!W_ERROR_IS_OK(werr)) {
794 status = werror_to_ntstatus(werr);
795 d_fprintf(stderr, _("registry_queryvalue failed: %s\n"),
796 win_errstr(werr));
797 goto done;
801 value->type = type;
803 print_registry_value(value, raw);
805 done:
806 dcerpc_winreg_CloseKey(b, tmp_ctx, &key_hnd, &werr);
807 dcerpc_winreg_CloseKey(b, tmp_ctx, &hive_hnd, &werr);
809 TALLOC_FREE(tmp_ctx);
811 return status;
814 static NTSTATUS rpc_registry_getvalue_full(struct net_context *c,
815 const struct dom_sid *domain_sid,
816 const char *domain_name,
817 struct cli_state *cli,
818 struct rpc_pipe_client *pipe_hnd,
819 TALLOC_CTX *mem_ctx,
820 int argc,
821 const char **argv)
823 return rpc_registry_getvalue_internal(c, domain_sid, domain_name,
824 cli, pipe_hnd, mem_ctx, false,
825 argc, argv);
828 static int rpc_registry_getvalue(struct net_context *c, int argc,
829 const char **argv)
831 if (argc != 2 || c->display_usage) {
832 d_fprintf(stderr, "%s\n%s",
833 _("Usage:"),
834 _("net rpc registry getvalue <key> <valuename>\n"));
835 return -1;
838 return run_rpc_command(c, NULL, &ndr_table_winreg, 0,
839 rpc_registry_getvalue_full, argc, argv);
842 static NTSTATUS rpc_registry_getvalue_raw(struct net_context *c,
843 const struct dom_sid *domain_sid,
844 const char *domain_name,
845 struct cli_state *cli,
846 struct rpc_pipe_client *pipe_hnd,
847 TALLOC_CTX *mem_ctx,
848 int argc,
849 const char **argv)
851 return rpc_registry_getvalue_internal(c, domain_sid, domain_name,
852 cli, pipe_hnd, mem_ctx, true,
853 argc, argv);
856 static int rpc_registry_getvalueraw(struct net_context *c, int argc,
857 const char **argv)
859 if (argc != 2 || c->display_usage) {
860 d_fprintf(stderr, "%s\n%s",
861 _("Usage:"),
862 _("net rpc registry getvalue <key> <valuename>\n"));
863 return -1;
866 return run_rpc_command(c, NULL, &ndr_table_winreg, 0,
867 rpc_registry_getvalue_raw, argc, argv);
870 static NTSTATUS rpc_registry_createkey_internal(struct net_context *c,
871 const struct dom_sid *domain_sid,
872 const char *domain_name,
873 struct cli_state *cli,
874 struct rpc_pipe_client *pipe_hnd,
875 TALLOC_CTX *mem_ctx,
876 int argc,
877 const char **argv )
879 uint32 hive;
880 struct policy_handle hive_hnd, key_hnd;
881 struct winreg_String key, keyclass;
882 enum winreg_CreateAction action;
883 NTSTATUS status;
884 WERROR werr;
885 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
887 ZERO_STRUCT(key);
888 ZERO_STRUCT(keyclass);
890 if (!reg_hive_key(mem_ctx, argv[0], &hive, &key.name)) {
891 return NT_STATUS_INVALID_PARAMETER;
894 status = dcerpc_winreg_Connect(b, mem_ctx, hive,
895 SEC_FLAG_MAXIMUM_ALLOWED,
896 &hive_hnd, &werr);
897 if (!(NT_STATUS_IS_OK(status))) {
898 return status;
900 if (!W_ERROR_IS_OK(werr)) {
901 return werror_to_ntstatus(werr);
904 action = REG_ACTION_NONE;
905 keyclass.name = "";
907 status = dcerpc_winreg_CreateKey(b, mem_ctx, &hive_hnd, key,
908 keyclass, 0, REG_KEY_READ, NULL,
909 &key_hnd, &action, &werr);
910 if (!NT_STATUS_IS_OK(status)) {
911 d_fprintf(stderr, _("createkey returned %s\n"),
912 nt_errstr(status));
913 dcerpc_winreg_CloseKey(b, mem_ctx, &hive_hnd, &werr);
914 return status;
916 if (!W_ERROR_IS_OK(werr)) {
917 WERROR _werr;
918 d_fprintf(stderr, _("createkey returned %s\n"),
919 win_errstr(werr));
920 dcerpc_winreg_CloseKey(b, mem_ctx, &hive_hnd, &_werr);
921 return werror_to_ntstatus(werr);
924 switch (action) {
925 case REG_ACTION_NONE:
926 d_printf(_("createkey did nothing -- huh?\n"));
927 break;
928 case REG_CREATED_NEW_KEY:
929 d_printf(_("createkey created %s\n"), argv[0]);
930 break;
931 case REG_OPENED_EXISTING_KEY:
932 d_printf(_("createkey opened existing %s\n"), argv[0]);
933 break;
936 dcerpc_winreg_CloseKey(b, mem_ctx, &key_hnd, &werr);
937 dcerpc_winreg_CloseKey(b, mem_ctx, &hive_hnd, &werr);
939 return status;
942 static int rpc_registry_createkey(struct net_context *c, int argc,
943 const char **argv )
945 if (argc != 1 || c->display_usage) {
946 d_fprintf(stderr, "%s\n%s",
947 _("Usage:"),
948 _("net rpc registry createkey <key>\n"));
949 return -1;
952 return run_rpc_command(c, NULL, &ndr_table_winreg, 0,
953 rpc_registry_createkey_internal, argc, argv );
956 static NTSTATUS rpc_registry_deletekey_internal(struct net_context *c,
957 const struct dom_sid *domain_sid,
958 const char *domain_name,
959 struct cli_state *cli,
960 struct rpc_pipe_client *pipe_hnd,
961 TALLOC_CTX *mem_ctx,
962 int argc,
963 const char **argv )
965 uint32 hive;
966 struct policy_handle hive_hnd;
967 struct winreg_String key;
968 NTSTATUS status;
969 WERROR werr;
970 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
972 ZERO_STRUCT(key);
974 if (!reg_hive_key(mem_ctx, argv[0], &hive, &key.name)) {
975 return NT_STATUS_INVALID_PARAMETER;
978 status = dcerpc_winreg_Connect(b, mem_ctx, hive,
979 SEC_FLAG_MAXIMUM_ALLOWED,
980 &hive_hnd, &werr);
981 if (!(NT_STATUS_IS_OK(status))) {
982 return status;
984 if (!W_ERROR_IS_OK(werr)) {
985 return werror_to_ntstatus(werr);
988 status = dcerpc_winreg_DeleteKey(b, mem_ctx, &hive_hnd, key, &werr);
989 if (is_valid_policy_hnd(&hive_hnd)) {
990 WERROR _werr;
991 dcerpc_winreg_CloseKey(b, mem_ctx, &hive_hnd, &_werr);
994 if (!NT_STATUS_IS_OK(status)) {
995 d_fprintf(stderr, _("deletekey returned %s\n"),
996 nt_errstr(status));
997 return status;
1000 if (!W_ERROR_IS_OK(werr)) {
1001 d_fprintf(stderr, _("deletekey returned %s\n"),
1002 win_errstr(werr));
1003 return werror_to_ntstatus(werr);
1006 return status;
1009 static int rpc_registry_deletekey(struct net_context *c, int argc, const char **argv )
1011 if (argc != 1 || c->display_usage) {
1012 d_fprintf(stderr, "%s\n%s",
1013 _("Usage:"),
1014 _("net rpc registry deletekey <key>\n"));
1015 return -1;
1018 return run_rpc_command(c, NULL, &ndr_table_winreg, 0,
1019 rpc_registry_deletekey_internal, argc, argv );
1022 /********************************************************************
1023 ********************************************************************/
1025 static NTSTATUS rpc_registry_enumerate_internal(struct net_context *c,
1026 const struct dom_sid *domain_sid,
1027 const char *domain_name,
1028 struct cli_state *cli,
1029 struct rpc_pipe_client *pipe_hnd,
1030 TALLOC_CTX *mem_ctx,
1031 int argc,
1032 const char **argv )
1034 struct policy_handle pol_hive, pol_key;
1035 NTSTATUS status;
1036 WERROR werr;
1037 uint32 num_subkeys = 0;
1038 uint32 num_values = 0;
1039 char **names = NULL, **classes = NULL;
1040 NTTIME **modtimes = NULL;
1041 uint32 i;
1042 struct registry_value **values = NULL;
1043 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
1045 if (argc != 1 || c->display_usage) {
1046 d_printf("%s\n%s",
1047 _("Usage:"),
1048 _("net rpc registry enumerate <path>\n"));
1049 d_printf("%s net rpc registry enumerate "
1050 "'HKLM\\Software\\Samba'\n", _("Example:"));
1051 return NT_STATUS_INVALID_PARAMETER;
1054 status = registry_openkey(mem_ctx, pipe_hnd, argv[0], REG_KEY_READ,
1055 &pol_hive, &pol_key);
1056 if (!NT_STATUS_IS_OK(status)) {
1057 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
1058 nt_errstr(status));
1059 return status;
1062 status = registry_enumkeys(mem_ctx, pipe_hnd, &pol_key, &num_subkeys,
1063 &names, &classes, &modtimes);
1064 if (!NT_STATUS_IS_OK(status)) {
1065 d_fprintf(stderr, _("enumerating keys failed: %s\n"),
1066 nt_errstr(status));
1067 return status;
1070 for (i=0; i<num_subkeys; i++) {
1071 print_registry_key(names[i], modtimes[i]);
1074 status = registry_enumvalues(mem_ctx, pipe_hnd, &pol_key, &num_values,
1075 &names, &values);
1076 if (!NT_STATUS_IS_OK(status)) {
1077 d_fprintf(stderr, _("enumerating values failed: %s\n"),
1078 nt_errstr(status));
1079 return status;
1082 for (i=0; i<num_values; i++) {
1083 print_registry_value_with_name(names[i], values[i]);
1086 dcerpc_winreg_CloseKey(b, mem_ctx, &pol_key, &werr);
1087 dcerpc_winreg_CloseKey(b, mem_ctx, &pol_hive, &werr);
1089 return status;
1092 /********************************************************************
1093 ********************************************************************/
1095 static int rpc_registry_enumerate(struct net_context *c, int argc,
1096 const char **argv )
1098 return run_rpc_command(c, NULL, &ndr_table_winreg, 0,
1099 rpc_registry_enumerate_internal, argc, argv );
1102 /********************************************************************
1103 ********************************************************************/
1105 static NTSTATUS rpc_registry_save_internal(struct net_context *c,
1106 const struct dom_sid *domain_sid,
1107 const char *domain_name,
1108 struct cli_state *cli,
1109 struct rpc_pipe_client *pipe_hnd,
1110 TALLOC_CTX *mem_ctx,
1111 int argc,
1112 const char **argv )
1114 WERROR result = WERR_GENERAL_FAILURE;
1115 struct policy_handle pol_hive, pol_key;
1116 NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
1117 struct winreg_String filename;
1118 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
1120 if (argc != 2 || c->display_usage) {
1121 d_printf("%s\n%s",
1122 _("Usage:"),
1123 _("net rpc registry backup <path> <file> \n"));
1124 return NT_STATUS_INVALID_PARAMETER;
1127 status = registry_openkey(mem_ctx, pipe_hnd, argv[0], REG_KEY_ALL,
1128 &pol_hive, &pol_key);
1129 if (!NT_STATUS_IS_OK(status)) {
1130 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
1131 nt_errstr(status));
1132 return status;
1135 filename.name = argv[1];
1136 status = dcerpc_winreg_SaveKey(b, mem_ctx, &pol_key, &filename, NULL, &result);
1137 if (!NT_STATUS_IS_OK(status)) {
1138 d_fprintf(stderr, _("Unable to save [%s] to %s:%s\n"), argv[0],
1139 pipe_hnd->desthost, argv[1]);
1141 if (!W_ERROR_IS_OK(result)) {
1142 status = werror_to_ntstatus(result);
1143 d_fprintf(stderr, _("Unable to save [%s] to %s:%s\n"), argv[0],
1144 pipe_hnd->desthost, argv[1]);
1147 /* cleanup */
1149 dcerpc_winreg_CloseKey(b, mem_ctx, &pol_key, &result);
1150 dcerpc_winreg_CloseKey(b, mem_ctx, &pol_hive, &result);
1152 return status;
1155 /********************************************************************
1156 ********************************************************************/
1158 static int rpc_registry_save(struct net_context *c, int argc, const char **argv )
1160 return run_rpc_command(c, NULL, &ndr_table_winreg, 0,
1161 rpc_registry_save_internal, argc, argv );
1165 /********************************************************************
1166 ********************************************************************/
1168 static void dump_values( REGF_NK_REC *nk )
1170 int i, j;
1171 const char *data_str = NULL;
1172 uint32 data_size, data;
1173 DATA_BLOB blob;
1175 if ( !nk->values )
1176 return;
1178 for ( i=0; i<nk->num_values; i++ ) {
1179 d_printf( "\"%s\" = ", nk->values[i].valuename ? nk->values[i].valuename : "(default)" );
1180 d_printf( "(%s) ", str_regtype( nk->values[i].type ) );
1182 data_size = nk->values[i].data_size & ~VK_DATA_IN_OFFSET;
1183 switch ( nk->values[i].type ) {
1184 case REG_SZ:
1185 blob = data_blob_const(nk->values[i].data, data_size);
1186 if (!pull_reg_sz(talloc_tos(), &blob,
1187 &data_str)) {
1188 data_str = NULL;
1190 if (!data_str) {
1191 break;
1193 d_printf( "%s", data_str );
1194 break;
1195 case REG_MULTI_SZ:
1196 case REG_EXPAND_SZ:
1197 for ( j=0; j<data_size; j++ ) {
1198 d_printf( "%c", nk->values[i].data[j] );
1200 break;
1201 case REG_DWORD:
1202 data = IVAL( nk->values[i].data, 0 );
1203 d_printf("0x%x", data );
1204 break;
1205 case REG_BINARY:
1206 for ( j=0; j<data_size; j++ ) {
1207 d_printf( "%x", nk->values[i].data[j] );
1209 break;
1210 default:
1211 d_printf(_("unknown"));
1212 break;
1215 d_printf( "\n" );
1220 /********************************************************************
1221 ********************************************************************/
1223 static bool dump_registry_tree( REGF_FILE *file, REGF_NK_REC *nk, const char *parent )
1225 REGF_NK_REC *key;
1227 /* depth first dump of the registry tree */
1229 while ( (key = regfio_fetch_subkey( file, nk )) ) {
1230 char *regpath;
1231 if (asprintf(&regpath, "%s\\%s", parent, key->keyname) < 0) {
1232 break;
1234 d_printf("[%s]\n", regpath );
1235 dump_values( key );
1236 d_printf("\n");
1237 dump_registry_tree( file, key, regpath );
1238 SAFE_FREE(regpath);
1241 return true;
1244 /********************************************************************
1245 ********************************************************************/
1247 static bool write_registry_tree( REGF_FILE *infile, REGF_NK_REC *nk,
1248 REGF_NK_REC *parent, REGF_FILE *outfile,
1249 const char *parentpath )
1251 REGF_NK_REC *key, *subkey;
1252 struct regval_ctr *values = NULL;
1253 struct regsubkey_ctr *subkeys = NULL;
1254 int i;
1255 char *path = NULL;
1256 WERROR werr;
1258 werr = regsubkey_ctr_init(infile->mem_ctx, &subkeys);
1259 if (!W_ERROR_IS_OK(werr)) {
1260 DEBUG(0, ("write_registry_tree: regsubkey_ctr_init failed: "
1261 "%s\n", win_errstr(werr)));
1262 return false;
1265 werr = regval_ctr_init(subkeys, &values);
1266 if (!W_ERROR_IS_OK(werr)) {
1267 DEBUG(0,("write_registry_tree: talloc() failed!\n"));
1268 TALLOC_FREE(subkeys);
1269 return false;
1272 /* copy values into the struct regval_ctr */
1274 for ( i=0; i<nk->num_values; i++ ) {
1275 regval_ctr_addvalue( values, nk->values[i].valuename, nk->values[i].type,
1276 nk->values[i].data, (nk->values[i].data_size & ~VK_DATA_IN_OFFSET) );
1279 /* copy subkeys into the struct regsubkey_ctr */
1281 while ( (subkey = regfio_fetch_subkey( infile, nk )) ) {
1282 regsubkey_ctr_addkey( subkeys, subkey->keyname );
1285 key = regfio_write_key( outfile, nk->keyname, values, subkeys, nk->sec_desc->sec_desc, parent );
1287 /* write each one of the subkeys out */
1289 path = talloc_asprintf(subkeys,
1290 "%s%s%s",
1291 parentpath,
1292 parent ? "\\" : "",
1293 nk->keyname);
1294 if (!path) {
1295 TALLOC_FREE(subkeys);
1296 return false;
1299 nk->subkey_index = 0;
1300 while ( (subkey = regfio_fetch_subkey( infile, nk )) ) {
1301 write_registry_tree( infile, subkey, key, outfile, path );
1304 d_printf("[%s]\n", path );
1305 TALLOC_FREE(subkeys);
1307 return true;
1310 /********************************************************************
1311 ********************************************************************/
1313 static int rpc_registry_dump(struct net_context *c, int argc, const char **argv)
1315 REGF_FILE *registry;
1316 REGF_NK_REC *nk;
1318 if (argc != 1 || c->display_usage) {
1319 d_printf("%s\n%s",
1320 _("Usage:"),
1321 _("net rpc registry dump <file> \n"));
1322 return -1;
1325 d_printf(_("Opening %s...."), argv[0]);
1326 if ( !(registry = regfio_open( argv[0], O_RDONLY, 0)) ) {
1327 d_fprintf(stderr, _("Failed to open %s for reading\n"),argv[0]);
1328 return 1;
1330 d_printf(_("ok\n"));
1332 /* get the root of the registry file */
1334 if ((nk = regfio_rootkey( registry )) == NULL) {
1335 d_fprintf(stderr, _("Could not get rootkey\n"));
1336 regfio_close( registry );
1337 return 1;
1339 d_printf("[%s]\n", nk->keyname);
1340 dump_values( nk );
1341 d_printf("\n");
1343 dump_registry_tree( registry, nk, nk->keyname );
1345 #if 0
1346 talloc_report_full( registry->mem_ctx, stderr );
1347 #endif
1348 d_printf(_("Closing registry..."));
1349 regfio_close( registry );
1350 d_printf(_("ok\n"));
1352 return 0;
1355 /********************************************************************
1356 ********************************************************************/
1358 static int rpc_registry_copy(struct net_context *c, int argc, const char **argv )
1360 REGF_FILE *infile = NULL, *outfile = NULL;
1361 REGF_NK_REC *nk;
1362 int result = 1;
1364 if (argc != 2 || c->display_usage) {
1365 d_printf("%s\n%s",
1366 _("Usage:"),
1367 _("net rpc registry copy <srcfile> <newfile>\n"));
1368 return -1;
1371 d_printf(_("Opening %s...."), argv[0]);
1372 if ( !(infile = regfio_open( argv[0], O_RDONLY, 0 )) ) {
1373 d_fprintf(stderr, _("Failed to open %s for reading\n"),argv[0]);
1374 return 1;
1376 d_printf(_("ok\n"));
1378 d_printf(_("Opening %s...."), argv[1]);
1379 if ( !(outfile = regfio_open( argv[1], (O_RDWR|O_CREAT|O_TRUNC),
1380 (S_IRUSR|S_IWUSR) )) ) {
1381 d_fprintf(stderr, _("Failed to open %s for writing\n"),argv[1]);
1382 goto out;
1384 d_printf(_("ok\n"));
1386 /* get the root of the registry file */
1388 if ((nk = regfio_rootkey( infile )) == NULL) {
1389 d_fprintf(stderr, _("Could not get rootkey\n"));
1390 goto out;
1392 d_printf(_("RootKey: [%s]\n"), nk->keyname);
1394 write_registry_tree( infile, nk, NULL, outfile, "" );
1396 result = 0;
1398 out:
1400 d_printf(_("Closing %s..."), argv[1]);
1401 if (outfile) {
1402 regfio_close( outfile );
1404 d_printf(_("ok\n"));
1406 d_printf(_("Closing %s..."), argv[0]);
1407 if (infile) {
1408 regfio_close( infile );
1410 d_printf(_("ok\n"));
1412 return( result);
1415 /********************************************************************
1416 ********************************************************************/
1418 static NTSTATUS rpc_registry_getsd_internal(struct net_context *c,
1419 const struct dom_sid *domain_sid,
1420 const char *domain_name,
1421 struct cli_state *cli,
1422 struct rpc_pipe_client *pipe_hnd,
1423 TALLOC_CTX *mem_ctx,
1424 int argc,
1425 const char **argv)
1427 struct policy_handle pol_hive, pol_key;
1428 NTSTATUS status;
1429 WERROR werr;
1430 enum ndr_err_code ndr_err;
1431 struct KeySecurityData *sd = NULL;
1432 uint32_t sec_info;
1433 DATA_BLOB blob;
1434 struct security_descriptor sec_desc;
1435 uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED |
1436 SEC_FLAG_SYSTEM_SECURITY;
1437 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
1439 if (argc <1 || argc > 2 || c->display_usage) {
1440 d_printf("%s\n%s",
1441 _("Usage:"),
1442 _("net rpc registry getsd <path> <secinfo>\n"));
1443 d_printf("%s net rpc registry getsd "
1444 "'HKLM\\Software\\Samba'\n", _("Example:"));
1445 return NT_STATUS_INVALID_PARAMETER;
1448 status = registry_openkey(mem_ctx, pipe_hnd, argv[0],
1449 access_mask,
1450 &pol_hive, &pol_key);
1451 if (!NT_STATUS_IS_OK(status)) {
1452 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
1453 nt_errstr(status));
1454 return status;
1457 sd = talloc_zero(mem_ctx, struct KeySecurityData);
1458 if (!sd) {
1459 status = NT_STATUS_NO_MEMORY;
1460 goto out;
1463 sd->size = 0x1000;
1465 if (argc >= 2) {
1466 sscanf(argv[1], "%x", &sec_info);
1467 } else {
1468 sec_info = SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL;
1471 status = registry_getsd(mem_ctx, b, &pol_key, sec_info, sd, &werr);
1472 if (!NT_STATUS_IS_OK(status)) {
1473 d_fprintf(stderr, _("getting sd failed: %s\n"),
1474 nt_errstr(status));
1475 goto out;
1477 if (!W_ERROR_IS_OK(werr)) {
1478 status = werror_to_ntstatus(werr);
1479 d_fprintf(stderr, _("getting sd failed: %s\n"),
1480 win_errstr(werr));
1481 goto out;
1484 blob.data = sd->data;
1485 blob.length = sd->size;
1487 ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &sec_desc,
1488 (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
1489 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1490 status = ndr_map_error2ntstatus(ndr_err);
1491 goto out;
1493 status = NT_STATUS_OK;
1495 display_sec_desc(&sec_desc);
1497 out:
1498 dcerpc_winreg_CloseKey(b, mem_ctx, &pol_key, &werr);
1499 dcerpc_winreg_CloseKey(b, mem_ctx, &pol_hive, &werr);
1501 return status;
1505 static int rpc_registry_getsd(struct net_context *c, int argc, const char **argv)
1507 return run_rpc_command(c, NULL, &ndr_table_winreg, 0,
1508 rpc_registry_getsd_internal, argc, argv);
1511 /********************************************************************
1512 ********************************************************************/
1514 * @defgroup net_rpc_registry net rpc registry
1518 * @defgroup net_rpc_registry_export Export
1519 * @ingroup net_rpc_registry
1520 * @{
1523 static NTSTATUS registry_export(struct rpc_pipe_client* pipe_hnd,
1524 TALLOC_CTX* ctx,
1525 struct policy_handle* key_hnd,
1526 struct reg_format* f,
1527 const char* parentfullname,
1528 const char* name)
1530 NTSTATUS status;
1531 uint32 num_subkeys = 0;
1532 uint32 num_values = 0;
1533 char **names = NULL, **classes = NULL;
1534 NTTIME **modtimes = NULL;
1535 struct regval_blob **values = NULL;
1536 uint32 i;
1537 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
1539 TALLOC_CTX* mem_ctx = talloc_new(ctx);
1542 const char* fullname = name
1543 ? talloc_asprintf(mem_ctx, "%s\\%s", parentfullname, name)
1544 : parentfullname;
1545 reg_format_key(f, &fullname, 1, false);
1547 status = registry_enumvalues2(mem_ctx, pipe_hnd, key_hnd, &num_values,
1548 &names, &values);
1549 if (!NT_STATUS_IS_OK(status)) {
1550 d_fprintf(stderr, _("enumerating values failed: %s\n"),
1551 nt_errstr(status));
1552 goto done;
1555 for (i=0; i<num_values; i++) {
1556 reg_format_regval_blob(f, names[i], values[i]);
1560 status = registry_enumkeys(mem_ctx, pipe_hnd, key_hnd, &num_subkeys,
1561 &names, &classes, &modtimes);
1562 if (!NT_STATUS_IS_OK(status)) {
1563 d_fprintf(stderr, _("enumerating keys failed: %s\n"),
1564 nt_errstr(status));
1565 goto done;
1568 for (i=0; i<num_subkeys; i++) {
1569 struct policy_handle subkey_hnd;
1570 struct winreg_String key;
1571 WERROR werr;
1572 ZERO_STRUCT(key);
1573 /* key.name = talloc_strdup(mem_ctx, names[i]); ??? */
1574 key.name = names[i];
1576 status = dcerpc_winreg_OpenKey(b, mem_ctx, key_hnd, key,
1577 0, REG_KEY_READ,
1578 &subkey_hnd, &werr);
1579 if (!NT_STATUS_IS_OK(status)) {
1580 d_fprintf(stderr,
1581 _("dcerpc_winreg_OpenKey failed: %s %s\n"),
1582 names[i], nt_errstr(status));
1583 continue;
1585 if (!W_ERROR_IS_OK(werr)) {
1586 status = werror_to_ntstatus(werr);
1587 d_fprintf(stderr,
1588 _("dcerpc_winreg_OpenKey failed: %s %s\n"),
1589 names[i], win_errstr(werr));
1590 continue;
1593 status = registry_export(pipe_hnd, mem_ctx, &subkey_hnd,
1594 f, fullname, names[i]);
1595 if (!(NT_STATUS_IS_OK(status))) {
1596 d_fprintf(stderr,
1597 _("export key failed: %s %s\n"),
1598 names[i], nt_errstr(status));
1600 dcerpc_winreg_CloseKey(b, mem_ctx,
1601 &subkey_hnd, &werr);
1603 done:
1604 talloc_free(mem_ctx);
1605 return status;
1608 static NTSTATUS rpc_registry_export_internal(struct net_context *c,
1609 const struct dom_sid *domain_sid,
1610 const char *domain_name,
1611 struct cli_state *cli,
1612 struct rpc_pipe_client *pipe_hnd,
1613 TALLOC_CTX *mem_ctx,
1614 int argc,
1615 const char **argv )
1617 struct policy_handle pol_hive, pol_key;
1618 NTSTATUS status;
1619 WERROR werr;
1620 struct reg_format* f;
1621 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
1623 if (argc < 2 || argc > 3 || c->display_usage) {
1624 d_printf("%s\n%s",
1625 _("Usage:"),
1626 _("net rpc registry export <path> <file> [opt]\n"));
1627 d_printf("%s net rpc registry export "
1628 "'HKLM\\Software\\Samba' samba.reg\n", _("Example:"));
1629 return NT_STATUS_INVALID_PARAMETER;
1632 status = registry_openkey(mem_ctx, pipe_hnd, argv[0], REG_KEY_READ,
1633 &pol_hive, &pol_key);
1634 if (!NT_STATUS_IS_OK(status)) {
1635 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
1636 nt_errstr(status));
1637 return status;
1640 f = reg_format_file(mem_ctx, argv[1], (argc > 2) ? argv[2] : NULL);
1641 if (f == NULL) {
1642 d_fprintf(stderr, _("open file failed: %s\n"), strerror(errno));
1643 return map_nt_error_from_unix(errno);
1646 status = registry_export(pipe_hnd, mem_ctx, &pol_key,
1647 f, argv[0], NULL );
1648 if (!NT_STATUS_IS_OK(status))
1649 return status;
1651 dcerpc_winreg_CloseKey(b, mem_ctx, &pol_key, &werr);
1652 dcerpc_winreg_CloseKey(b, mem_ctx, &pol_hive, &werr);
1654 return status;
1656 /********************************************************************
1657 ********************************************************************/
1659 static int rpc_registry_export(struct net_context *c, int argc,
1660 const char **argv )
1662 return run_rpc_command(c, NULL, &ndr_table_winreg, 0,
1663 rpc_registry_export_internal, argc, argv );
1666 /**@}*/
1668 /********************************************************************
1669 ********************************************************************/
1672 * @defgroup net_rpc_registry_import Import
1673 * @ingroup net_rpc_registry
1674 * @{
1677 struct import_ctx {
1678 struct rpc_pipe_client *pipe_hnd;
1679 TALLOC_CTX *mem_ctx;
1682 static WERROR import_create_key(struct import_ctx* ctx,
1683 struct policy_handle* parent, const char* name,
1684 void** pkey, bool* existing)
1686 WERROR werr;
1687 NTSTATUS status;
1688 void* mem_ctx = talloc_new(ctx->mem_ctx);
1690 struct policy_handle* key = NULL;
1691 struct policy_handle hive;
1692 struct winreg_String keyclass, keyname;
1693 enum winreg_CreateAction action = REG_ACTION_NONE;
1694 struct dcerpc_binding_handle *b = ctx->pipe_hnd->binding_handle;
1696 ZERO_STRUCT(keyname);
1697 keyname.name = name;
1699 if (parent == NULL) {
1700 uint32 hive_idx = 0;
1701 if (!reg_hive_key(mem_ctx, name, &hive_idx, &keyname.name)) {
1702 werr = WERR_FOOBAR;
1703 goto done;
1706 status = dcerpc_winreg_Connect(b, mem_ctx,
1707 hive_idx, SEC_FLAG_MAXIMUM_ALLOWED,
1708 &hive, &werr);
1709 if (!NT_STATUS_IS_OK(status)) {
1710 werr = ntstatus_to_werror(status);
1711 d_fprintf(stderr, _("dcerpc_winreg_Connect returned %s\n"),
1712 nt_errstr(status));
1713 goto done;
1715 if (!W_ERROR_IS_OK(werr)) {
1716 d_fprintf(stderr, _("dcerpc_winreg_Connect returned %s\n"),
1717 win_errstr(werr));
1718 goto done;
1721 parent = &hive;
1724 key = talloc_zero(mem_ctx, struct policy_handle);
1725 if (key == NULL) {
1726 werr = WERR_NOMEM;
1727 goto done;
1730 ZERO_STRUCT(keyclass);
1731 keyclass.name = "";
1733 status = dcerpc_winreg_CreateKey(b, mem_ctx,
1734 parent, keyname,
1735 keyclass, 0, REG_KEY_READ, NULL,
1736 key, &action, &werr);
1737 if (!NT_STATUS_IS_OK(status)) {
1738 werr = ntstatus_to_werror(status);
1739 d_fprintf(stderr, _("dcerpc_winreg_CreateKey returned %s\n"),
1740 nt_errstr(status));
1741 goto done;
1743 if (!W_ERROR_IS_OK(werr)) {
1744 d_fprintf(stderr, _("dcerpc_winreg_CreateKey returned %s\n"),
1745 win_errstr(werr));
1746 goto done;
1749 switch (action) {
1750 case REG_CREATED_NEW_KEY:
1751 d_printf(_("createkey created %s\n"), name);
1752 if (existing != NULL)
1753 *existing = false;
1754 break;
1756 case REG_OPENED_EXISTING_KEY:
1757 d_printf(_("createkey opened existing %s\n"), name);
1758 if (existing != NULL)
1759 *existing = true;
1760 break;
1762 case REG_ACTION_NONE:
1763 d_printf(_("createkey did nothing -- huh?\n"));
1764 werr = WERR_CREATE_FAILED;
1765 break;
1766 default:
1767 assert(false);
1770 done:
1771 if ( parent == &hive ) {
1772 WERROR _result;
1773 dcerpc_winreg_CloseKey(b, mem_ctx,
1774 parent, &_result);
1777 if (pkey!=NULL) {
1778 *pkey = talloc_steal(ctx->mem_ctx, key);
1781 talloc_free(mem_ctx);
1782 return werr;
1785 static WERROR import_delete_key(struct import_ctx* ctx,
1786 struct policy_handle* parent, const char* name)
1788 WERROR werr;
1789 NTSTATUS status;
1790 void* mem_ctx = talloc_new(ctx->mem_ctx);
1791 struct winreg_String keyname = { 0, };
1792 struct policy_handle hive;
1793 struct dcerpc_binding_handle *b = ctx->pipe_hnd->binding_handle;
1795 keyname.name = name;
1797 if (parent == NULL) {
1798 uint32 hive_idx;
1799 if (!reg_hive_key(mem_ctx, name, &hive_idx, &keyname.name)) {
1800 werr = WERR_FOOBAR;
1801 goto done;
1804 status = dcerpc_winreg_Connect(b, mem_ctx, hive_idx,
1805 SEC_FLAG_MAXIMUM_ALLOWED, &hive,
1806 &werr);
1807 if (!NT_STATUS_IS_OK(status)) {
1808 werr = ntstatus_to_werror(status);
1809 d_fprintf(stderr, _("dcerpc_winreg_Connect returned %s\n"),
1810 nt_errstr(status));
1811 goto done;
1813 if (!W_ERROR_IS_OK(werr)) {
1814 d_fprintf(stderr, _("dcerpc_winreg_Connect returned %s\n"),
1815 win_errstr(werr));
1816 goto done;
1819 parent = &hive;
1822 status = dcerpc_winreg_DeleteKey(b, mem_ctx, parent,
1823 keyname, &werr);
1824 if (!NT_STATUS_IS_OK(status)) {
1825 werr = ntstatus_to_werror(status);
1826 d_fprintf(stderr, _("dcerpc_winreg_DeleteKey returned %s\n"),
1827 nt_errstr(status));
1828 goto done;
1830 if (!W_ERROR_IS_OK(werr)) {
1831 d_fprintf(stderr, _("dcerpc_winreg_DeleteKey returned %s\n"),
1832 win_errstr(werr));
1833 goto done;
1836 done:
1837 if ( parent == &hive ) {
1838 WERROR _result;
1839 dcerpc_winreg_CloseKey(b, mem_ctx, parent, &_result);
1842 talloc_free(mem_ctx);
1843 return werr;
1846 static WERROR import_close_key(struct import_ctx* ctx,
1847 struct policy_handle* key)
1849 WERROR werr;
1850 NTSTATUS status;
1851 void* mem_ctx = talloc_new(ctx->mem_ctx);
1852 struct dcerpc_binding_handle *b = ctx->pipe_hnd->binding_handle;
1854 status = dcerpc_winreg_CloseKey(b, mem_ctx, key, &werr);
1855 if (!NT_STATUS_IS_OK(status)) {
1856 werr = ntstatus_to_werror(status);
1857 d_fprintf(stderr, _("dcerpc_winreg_CloseKey returned %s\n"),
1858 nt_errstr(status));
1859 goto done;
1861 if (!W_ERROR_IS_OK(werr)) {
1862 d_fprintf(stderr, _("dcerpc_winreg_CloseKey returned %s\n"),
1863 win_errstr(werr));
1864 goto done;
1867 werr = (talloc_free(key) == 0) ? WERR_OK : WERR_GENERAL_FAILURE;
1868 done:
1869 talloc_free(mem_ctx);
1870 return werr;
1873 static WERROR import_create_val(struct import_ctx* ctx,
1874 struct policy_handle* parent, const char* name,
1875 uint32_t type, const uint8_t* val, uint32_t len)
1877 WERROR werr;
1878 NTSTATUS status;
1879 void* mem_ctx = talloc_new(ctx->mem_ctx);
1880 struct winreg_String valuename;
1881 struct dcerpc_binding_handle *b = ctx->pipe_hnd->binding_handle;
1883 if (parent == NULL) {
1884 return WERR_INVALID_PARAM;
1887 ZERO_STRUCT(valuename);
1888 valuename.name = name;
1890 status = dcerpc_winreg_SetValue(b, mem_ctx, parent,
1891 valuename, type,
1892 (uint8_t *)discard_const(val), len, &werr);
1893 if (!NT_STATUS_IS_OK(status)) {
1894 werr = ntstatus_to_werror(status);
1895 d_fprintf(stderr, _("registry_setvalue failed: %s\n"),
1896 nt_errstr(status));
1897 goto done;
1899 if (!W_ERROR_IS_OK(werr)) {
1900 d_fprintf(stderr, _("registry_setvalue failed: %s\n"),
1901 win_errstr(werr));
1902 goto done;
1905 done:
1906 talloc_free(mem_ctx);
1907 return werr;
1910 static WERROR import_delete_val(struct import_ctx* ctx,
1911 struct policy_handle* parent, const char* name)
1913 WERROR werr;
1914 NTSTATUS status;
1915 void* mem_ctx = talloc_new(ctx->mem_ctx);
1916 struct winreg_String valuename;
1917 struct dcerpc_binding_handle *b = ctx->pipe_hnd->binding_handle;
1919 if (parent == NULL) {
1920 return WERR_INVALID_PARAM;
1923 ZERO_STRUCT(valuename);
1924 valuename.name = name;
1926 status = dcerpc_winreg_DeleteValue(b, mem_ctx,
1927 parent, valuename, &werr);
1929 if (!NT_STATUS_IS_OK(status)) {
1930 werr = ntstatus_to_werror(status);
1931 d_fprintf(stderr, _("registry_deletevalue failed: %s\n"),
1932 nt_errstr(status));
1933 goto done;
1935 if (!NT_STATUS_IS_OK(status)) {
1936 d_fprintf(stderr, _("registry_deletevalue failed: %s\n"),
1937 win_errstr(werr));
1938 goto done;
1941 done:
1942 talloc_free(mem_ctx);
1943 return werr;
1948 static NTSTATUS rpc_registry_import_internal(struct net_context *c,
1949 const struct dom_sid *domain_sid,
1950 const char *domain_name,
1951 struct cli_state *cli,
1952 struct rpc_pipe_client *pipe_hnd,
1953 TALLOC_CTX *mem_ctx,
1954 int argc,
1955 const char **argv )
1957 struct import_ctx import_ctx;
1959 struct reg_import_callback import_callback = {
1960 .openkey = NULL,
1961 .closekey = (reg_import_callback_closekey_t)&import_close_key,
1962 .createkey = (reg_import_callback_createkey_t)&import_create_key,
1963 .deletekey = (reg_import_callback_deletekey_t)&import_delete_key,
1964 .deleteval = (reg_import_callback_deleteval_t)&import_delete_val,
1965 .setval = {
1966 .blob = (reg_import_callback_setval_blob_t)&import_create_val,
1968 .setval_type = BLOB,
1969 .data = &import_ctx
1972 int ret;
1973 if (argc < 1 || argc > 2 || c->display_usage) {
1974 d_printf("%s\n%s",
1975 _("Usage:"),
1976 _("net rpc registry import <file> [options]\n"));
1977 d_printf("%s net rpc registry export "
1978 "samba.reg enc=CP1252,flags=0\n", _("Example:"));
1979 return NT_STATUS_INVALID_PARAMETER;
1981 ZERO_STRUCT(import_ctx);
1982 import_ctx.pipe_hnd = pipe_hnd;
1983 import_ctx.mem_ctx = mem_ctx;
1984 ret = reg_parse_file(argv[0],
1985 reg_import_adapter(import_ctx.mem_ctx,
1986 import_callback
1988 (argc > 1) ? argv[1] : NULL
1991 return ret==0 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1994 /********************************************************************
1995 ********************************************************************/
1997 static int rpc_registry_import(struct net_context *c, int argc,
1998 const char **argv )
2000 return run_rpc_command(c, NULL, &ndr_table_winreg, 0,
2001 rpc_registry_import_internal, argc, argv );
2004 /**@}*/
2005 /********************************************************************
2006 ********************************************************************/
2008 int net_rpc_registry(struct net_context *c, int argc, const char **argv)
2010 struct functable func[] = {
2012 "enumerate",
2013 rpc_registry_enumerate,
2014 NET_TRANSPORT_RPC,
2015 N_("Enumerate registry keys and values"),
2016 N_("net rpc registry enumerate\n"
2017 " Enumerate registry keys and values")
2020 "createkey",
2021 rpc_registry_createkey,
2022 NET_TRANSPORT_RPC,
2023 N_("Create a new registry key"),
2024 N_("net rpc registry createkey\n"
2025 " Create a new registry key")
2028 "deletekey",
2029 rpc_registry_deletekey,
2030 NET_TRANSPORT_RPC,
2031 N_("Delete a registry key"),
2032 N_("net rpc registry deletekey\n"
2033 " Delete a registry key")
2036 "getvalue",
2037 rpc_registry_getvalue,
2038 NET_TRANSPORT_RPC,
2039 N_("Print a registry value"),
2040 N_("net rpc registry getvalue\n"
2041 " Print a registry value")
2044 "getvalueraw",
2045 rpc_registry_getvalueraw,
2046 NET_TRANSPORT_RPC,
2047 N_("Print a registry value"),
2048 N_("net rpc registry getvalueraw\n"
2049 " Print a registry value (raw version)")
2052 "setvalue",
2053 rpc_registry_setvalue,
2054 NET_TRANSPORT_RPC,
2055 N_("Set a new registry value"),
2056 N_("net rpc registry setvalue\n"
2057 " Set a new registry value")
2060 "deletevalue",
2061 rpc_registry_deletevalue,
2062 NET_TRANSPORT_RPC,
2063 N_("Delete a registry value"),
2064 N_("net rpc registry deletevalue\n"
2065 " Delete a registry value")
2068 "save",
2069 rpc_registry_save,
2070 NET_TRANSPORT_RPC,
2071 N_("Save a registry file"),
2072 N_("net rpc registry save\n"
2073 " Save a registry file")
2076 "dump",
2077 rpc_registry_dump,
2078 NET_TRANSPORT_RPC,
2079 N_("Dump a registry file"),
2080 N_("net rpc registry dump\n"
2081 " Dump a registry file")
2084 "copy",
2085 rpc_registry_copy,
2086 NET_TRANSPORT_RPC,
2087 N_("Copy a registry file"),
2088 N_("net rpc registry copy\n"
2089 " Copy a registry file")
2092 "getsd",
2093 rpc_registry_getsd,
2094 NET_TRANSPORT_RPC,
2095 N_("Get security descriptor"),
2096 N_("net rpc registry getsd\n"
2097 " Get security descriptior")
2100 "import",
2101 rpc_registry_import,
2102 NET_TRANSPORT_RPC,
2103 N_("Import .reg file"),
2104 N_("net rpc registry import\n"
2105 " Import .reg file")
2108 "export",
2109 rpc_registry_export,
2110 NET_TRANSPORT_RPC,
2111 N_("Export .reg file"),
2112 N_("net rpc registry export\n"
2113 " Export .reg file")
2115 {NULL, NULL, 0, NULL, NULL}
2117 return net_run_function(c, argc, argv, "net rpc registry", func);