s3: smbcontrol to notify smbd about idmap changes
[Samba.git] / source3 / utils / net_rpc_registry.c
blobc98fc076553a286b0d0efd09fcf58ce174f2d8a6
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 "popt_common.h"
22 #include "registry.h"
23 #include "utils/net.h"
24 #include "utils/net_registry_util.h"
25 #include "registry/regfio.h"
26 #include "../librpc/gen_ndr/ndr_winreg_c.h"
27 #include "registry/reg_objects.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>
34 /*******************************************************************
35 connect to a registry hive root (open a registry policy)
36 *******************************************************************/
38 static NTSTATUS dcerpc_winreg_Connect(struct dcerpc_binding_handle *b, TALLOC_CTX *mem_ctx,
39 uint32_t reg_type, uint32_t access_mask,
40 struct policy_handle *reg_hnd, WERROR *werr)
42 ZERO_STRUCTP(reg_hnd);
44 switch (reg_type)
46 case HKEY_CLASSES_ROOT:
47 return dcerpc_winreg_OpenHKCR(b, mem_ctx, NULL,
48 access_mask, reg_hnd, werr);
50 case HKEY_LOCAL_MACHINE:
51 return dcerpc_winreg_OpenHKLM(b, mem_ctx, NULL,
52 access_mask, reg_hnd, werr);
54 case HKEY_USERS:
55 return dcerpc_winreg_OpenHKU(b, mem_ctx, NULL,
56 access_mask, reg_hnd, werr);
58 case HKEY_CURRENT_USER:
59 return dcerpc_winreg_OpenHKCU(b, mem_ctx, NULL,
60 access_mask, reg_hnd, werr);
62 case HKEY_PERFORMANCE_DATA:
63 return dcerpc_winreg_OpenHKPD(b, mem_ctx, NULL,
64 access_mask, reg_hnd, werr);
66 default:
67 /* fall through to end of function */
68 break;
71 return NT_STATUS_INVALID_PARAMETER;
74 static bool reg_hive_key(TALLOC_CTX *ctx, const char *fullname,
75 uint32 *reg_type, const char **key_name)
77 WERROR werr;
78 char *hivename = NULL;
79 char *tmp_keyname = NULL;
80 bool ret = false;
81 TALLOC_CTX *tmp_ctx = talloc_stackframe();
83 werr = split_hive_key(tmp_ctx, fullname, &hivename, &tmp_keyname);
84 if (!W_ERROR_IS_OK(werr)) {
85 goto done;
88 *key_name = talloc_strdup(ctx, tmp_keyname);
89 if (*key_name == NULL) {
90 goto done;
93 if (strequal(hivename, "HKLM") ||
94 strequal(hivename, "HKEY_LOCAL_MACHINE"))
96 (*reg_type) = HKEY_LOCAL_MACHINE;
97 } else if (strequal(hivename, "HKCR") ||
98 strequal(hivename, "HKEY_CLASSES_ROOT"))
100 (*reg_type) = HKEY_CLASSES_ROOT;
101 } else if (strequal(hivename, "HKU") ||
102 strequal(hivename, "HKEY_USERS"))
104 (*reg_type) = HKEY_USERS;
105 } else if (strequal(hivename, "HKCU") ||
106 strequal(hivename, "HKEY_CURRENT_USER"))
108 (*reg_type) = HKEY_CURRENT_USER;
109 } else if (strequal(hivename, "HKPD") ||
110 strequal(hivename, "HKEY_PERFORMANCE_DATA"))
112 (*reg_type) = HKEY_PERFORMANCE_DATA;
113 } else {
114 DEBUG(10,("reg_hive_key: unrecognised hive key %s\n",
115 fullname));
116 goto done;
119 ret = true;
121 done:
122 TALLOC_FREE(tmp_ctx);
123 return ret;
126 static NTSTATUS registry_openkey(TALLOC_CTX *mem_ctx,
127 struct rpc_pipe_client *pipe_hnd,
128 const char *name, uint32 access_mask,
129 struct policy_handle *hive_hnd,
130 struct policy_handle *key_hnd)
132 uint32 hive;
133 NTSTATUS status;
134 WERROR werr;
135 struct winreg_String key;
136 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
138 ZERO_STRUCT(key);
140 if (!reg_hive_key(mem_ctx, name, &hive, &key.name)) {
141 return NT_STATUS_INVALID_PARAMETER;
144 status = dcerpc_winreg_Connect(b, mem_ctx, hive, access_mask,
145 hive_hnd, &werr);
146 if (!(NT_STATUS_IS_OK(status))) {
147 return status;
149 if (!W_ERROR_IS_OK(werr)) {
150 return werror_to_ntstatus(werr);
153 status = dcerpc_winreg_OpenKey(b, mem_ctx, hive_hnd, key, 0,
154 access_mask, key_hnd, &werr);
155 if (!(NT_STATUS_IS_OK(status))) {
156 dcerpc_winreg_CloseKey(b, mem_ctx, hive_hnd, &werr);
157 return status;
159 if (!(W_ERROR_IS_OK(werr))) {
160 WERROR _werr;
161 dcerpc_winreg_CloseKey(b, mem_ctx, hive_hnd, &_werr);
162 return werror_to_ntstatus(werr);
165 return NT_STATUS_OK;
168 static NTSTATUS registry_enumkeys(TALLOC_CTX *ctx,
169 struct rpc_pipe_client *pipe_hnd,
170 struct policy_handle *key_hnd,
171 uint32 *pnum_keys, char ***pnames,
172 char ***pclasses, NTTIME ***pmodtimes)
174 TALLOC_CTX *mem_ctx;
175 NTSTATUS status;
176 WERROR werr;
177 uint32 num_subkeys, max_subkeylen, max_classlen;
178 uint32 num_values, max_valnamelen, max_valbufsize;
179 uint32 i;
180 NTTIME last_changed_time;
181 uint32 secdescsize;
182 struct winreg_String classname;
183 char **names, **classes;
184 NTTIME **modtimes;
185 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
187 if (!(mem_ctx = talloc_new(ctx))) {
188 return NT_STATUS_NO_MEMORY;
191 ZERO_STRUCT(classname);
192 status = dcerpc_winreg_QueryInfoKey(
193 b, mem_ctx, key_hnd, &classname, &num_subkeys,
194 &max_subkeylen, &max_classlen, &num_values, &max_valnamelen,
195 &max_valbufsize, &secdescsize, &last_changed_time, &werr);
197 if (!NT_STATUS_IS_OK(status)) {
198 goto error;
200 if (!W_ERROR_IS_OK(werr)) {
201 status = werror_to_ntstatus(werr);
202 goto error;
205 if (num_subkeys == 0) {
206 *pnum_keys = 0;
207 TALLOC_FREE(mem_ctx);
208 return NT_STATUS_OK;
211 if ((!(names = TALLOC_ZERO_ARRAY(mem_ctx, char *, num_subkeys))) ||
212 (!(classes = TALLOC_ZERO_ARRAY(mem_ctx, char *, num_subkeys))) ||
213 (!(modtimes = TALLOC_ZERO_ARRAY(mem_ctx, NTTIME *,
214 num_subkeys)))) {
215 status = NT_STATUS_NO_MEMORY;
216 goto error;
219 for (i=0; i<num_subkeys; i++) {
220 char c, n;
221 struct winreg_StringBuf class_buf;
222 struct winreg_StringBuf name_buf;
223 NTTIME modtime;
225 c = '\0';
226 class_buf.name = &c;
227 class_buf.size = max_classlen+2;
229 n = '\0';
230 name_buf.name = &n;
231 name_buf.size = max_subkeylen+2;
233 ZERO_STRUCT(modtime);
235 status = dcerpc_winreg_EnumKey(b, mem_ctx, key_hnd,
236 i, &name_buf, &class_buf,
237 &modtime, &werr);
238 if (!NT_STATUS_IS_OK(status)) {
239 goto error;
241 if (W_ERROR_EQUAL(werr,
242 WERR_NO_MORE_ITEMS) ) {
243 status = NT_STATUS_OK;
244 break;
246 if (!W_ERROR_IS_OK(werr)) {
247 status = werror_to_ntstatus(werr);
248 goto error;
251 classes[i] = NULL;
253 if (class_buf.name &&
254 (!(classes[i] = talloc_strdup(classes, class_buf.name)))) {
255 status = NT_STATUS_NO_MEMORY;
256 goto error;
259 if (!(names[i] = talloc_strdup(names, name_buf.name))) {
260 status = NT_STATUS_NO_MEMORY;
261 goto error;
264 if ((!(modtimes[i] = (NTTIME *)talloc_memdup(
265 modtimes, &modtime, sizeof(modtime))))) {
266 status = NT_STATUS_NO_MEMORY;
267 goto error;
271 *pnum_keys = num_subkeys;
273 if (pnames) {
274 *pnames = talloc_move(ctx, &names);
276 if (pclasses) {
277 *pclasses = talloc_move(ctx, &classes);
279 if (pmodtimes) {
280 *pmodtimes = talloc_move(ctx, &modtimes);
283 status = NT_STATUS_OK;
285 error:
286 TALLOC_FREE(mem_ctx);
287 return status;
290 static NTSTATUS registry_enumvalues(TALLOC_CTX *ctx,
291 struct rpc_pipe_client *pipe_hnd,
292 struct policy_handle *key_hnd,
293 uint32 *pnum_values, char ***pvalnames,
294 struct registry_value ***pvalues)
296 TALLOC_CTX *mem_ctx;
297 NTSTATUS status;
298 WERROR werr;
299 uint32 num_subkeys, max_subkeylen, max_classlen;
300 uint32 num_values, max_valnamelen, max_valbufsize;
301 uint32 i;
302 NTTIME last_changed_time;
303 uint32 secdescsize;
304 struct winreg_String classname;
305 struct registry_value **values;
306 char **names;
307 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
309 if (!(mem_ctx = talloc_new(ctx))) {
310 return NT_STATUS_NO_MEMORY;
313 ZERO_STRUCT(classname);
314 status = dcerpc_winreg_QueryInfoKey(
315 b, mem_ctx, key_hnd, &classname, &num_subkeys,
316 &max_subkeylen, &max_classlen, &num_values, &max_valnamelen,
317 &max_valbufsize, &secdescsize, &last_changed_time, &werr);
319 if (!NT_STATUS_IS_OK(status)) {
320 goto error;
322 if (!W_ERROR_IS_OK(werr)) {
323 status = werror_to_ntstatus(werr);
324 goto error;
327 if (num_values == 0) {
328 *pnum_values = 0;
329 TALLOC_FREE(mem_ctx);
330 return NT_STATUS_OK;
333 if ((!(names = TALLOC_ARRAY(mem_ctx, char *, num_values))) ||
334 (!(values = TALLOC_ARRAY(mem_ctx, struct registry_value *,
335 num_values)))) {
336 status = NT_STATUS_NO_MEMORY;
337 goto error;
340 for (i=0; i<num_values; i++) {
341 enum winreg_Type type = REG_NONE;
342 uint8 *data = NULL;
343 uint32 data_size;
344 uint32 value_length;
346 char n;
347 struct winreg_ValNameBuf name_buf;
348 WERROR err;
350 n = '\0';
351 name_buf.name = &n;
352 name_buf.size = max_valnamelen + 2;
354 data_size = max_valbufsize;
355 data = (uint8 *)TALLOC(mem_ctx, data_size);
356 value_length = 0;
358 status = dcerpc_winreg_EnumValue(b, mem_ctx, key_hnd,
359 i, &name_buf, &type,
360 data, &data_size,
361 &value_length, &err);
362 if (!(NT_STATUS_IS_OK(status))) {
363 goto error;
366 if ( W_ERROR_EQUAL(err,
367 WERR_NO_MORE_ITEMS) ) {
368 status = NT_STATUS_OK;
369 break;
372 if (!W_ERROR_IS_OK(err)) {
373 status = werror_to_ntstatus(err);
374 goto error;
377 if (name_buf.name == NULL) {
378 status = NT_STATUS_INVALID_PARAMETER;
379 goto error;
382 if (!(names[i] = talloc_strdup(names, name_buf.name))) {
383 status = NT_STATUS_NO_MEMORY;
384 goto error;
387 values[i] = talloc_zero(values, struct registry_value);
388 if (values[i] == NULL) {
389 status = NT_STATUS_NO_MEMORY;
390 goto error;
393 values[i]->type = type;
394 values[i]->data = data_blob_talloc(values[i], data, data_size);
397 *pnum_values = num_values;
399 if (pvalnames) {
400 *pvalnames = talloc_move(ctx, &names);
402 if (pvalues) {
403 *pvalues = talloc_move(ctx, &values);
406 status = NT_STATUS_OK;
408 error:
409 TALLOC_FREE(mem_ctx);
410 return status;
413 static NTSTATUS registry_enumvalues2(TALLOC_CTX *ctx,
414 struct rpc_pipe_client *pipe_hnd,
415 struct policy_handle *key_hnd,
416 uint32 *pnum_values, char ***pvalnames,
417 struct regval_blob ***pvalues)
419 TALLOC_CTX *mem_ctx;
420 NTSTATUS status;
421 WERROR werr;
422 uint32 num_subkeys, max_subkeylen, max_classlen;
423 uint32 num_values, max_valnamelen, max_valbufsize;
424 uint32 i;
425 NTTIME last_changed_time;
426 uint32 secdescsize;
427 struct winreg_String classname;
428 struct regval_blob **values;
429 char **names;
430 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
432 if (!(mem_ctx = talloc_new(ctx))) {
433 return NT_STATUS_NO_MEMORY;
436 ZERO_STRUCT(classname);
437 status = dcerpc_winreg_QueryInfoKey(
438 b, mem_ctx, key_hnd, &classname, &num_subkeys,
439 &max_subkeylen, &max_classlen, &num_values, &max_valnamelen,
440 &max_valbufsize, &secdescsize, &last_changed_time, &werr);
442 if (!NT_STATUS_IS_OK(status)) {
443 goto error;
445 if (!W_ERROR_IS_OK(werr)) {
446 status = werror_to_ntstatus(werr);
447 goto error;
450 if (num_values == 0) {
451 *pnum_values = 0;
452 TALLOC_FREE(mem_ctx);
453 return NT_STATUS_OK;
456 if ((!(names = TALLOC_ARRAY(mem_ctx, char *, num_values))) ||
457 (!(values = TALLOC_ARRAY(mem_ctx, struct regval_blob *,
458 num_values)))) {
459 status = NT_STATUS_NO_MEMORY;
460 goto error;
463 for (i=0; i<num_values; i++) {
464 enum winreg_Type type = REG_NONE;
465 uint8 *data = NULL;
466 uint32 data_size;
467 uint32 value_length;
469 char n;
470 struct winreg_ValNameBuf name_buf;
471 WERROR err;
473 n = '\0';
474 name_buf.name = &n;
475 name_buf.size = max_valnamelen + 2;
477 data_size = max_valbufsize;
478 data = (uint8 *)TALLOC(mem_ctx, data_size);
479 value_length = 0;
481 status = dcerpc_winreg_EnumValue(b, mem_ctx, key_hnd,
482 i, &name_buf, &type,
483 data, &data_size,
484 &value_length, &err);
485 if (!(NT_STATUS_IS_OK(status))) {
486 goto error;
489 if ( W_ERROR_EQUAL(err, WERR_NO_MORE_ITEMS) ) {
490 status = NT_STATUS_OK;
491 break;
494 if (!W_ERROR_IS_OK(err)) {
495 status = werror_to_ntstatus(err);
496 goto error;
499 if (name_buf.name == NULL) {
500 status = NT_STATUS_INVALID_PARAMETER;
501 goto error;
504 if (!(names[i] = talloc_strdup(names, name_buf.name))) {
505 status = NT_STATUS_NO_MEMORY;
506 goto error;
509 assert(value_length<=data_size); //???
511 values[i] = regval_compose(values,
512 name_buf.name,
513 type,
514 data, value_length);
515 if (!values[i]) {
516 status = NT_STATUS_NO_MEMORY;
517 goto error;
521 *pnum_values = num_values;
523 if (pvalnames) {
524 *pvalnames = talloc_move(ctx, &names);
526 if (pvalues) {
527 *pvalues = talloc_move(ctx, &values);
530 status = NT_STATUS_OK;
532 error:
533 TALLOC_FREE(mem_ctx);
534 return status;
537 static NTSTATUS registry_getsd(TALLOC_CTX *mem_ctx,
538 struct dcerpc_binding_handle *b,
539 struct policy_handle *key_hnd,
540 uint32_t sec_info,
541 struct KeySecurityData *sd,
542 WERROR *werr)
544 return dcerpc_winreg_GetKeySecurity(b, mem_ctx, key_hnd,
545 sec_info, sd, werr);
549 static NTSTATUS registry_setvalue(TALLOC_CTX *mem_ctx,
550 struct rpc_pipe_client *pipe_hnd,
551 struct policy_handle *key_hnd,
552 const char *name,
553 const struct registry_value *value)
555 struct winreg_String name_string;
556 NTSTATUS result;
557 WERROR werr;
558 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
560 ZERO_STRUCT(name_string);
562 name_string.name = name;
563 result = dcerpc_winreg_SetValue(b, mem_ctx, key_hnd,
564 name_string, value->type,
565 value->data.data, value->data.length, &werr);
566 if (!NT_STATUS_IS_OK(result)) {
567 return result;
570 return werror_to_ntstatus(werr);
573 static NTSTATUS rpc_registry_setvalue_internal(struct net_context *c,
574 const struct dom_sid *domain_sid,
575 const char *domain_name,
576 struct cli_state *cli,
577 struct rpc_pipe_client *pipe_hnd,
578 TALLOC_CTX *mem_ctx,
579 int argc,
580 const char **argv )
582 struct policy_handle hive_hnd, key_hnd;
583 NTSTATUS status;
584 WERROR werr;
585 struct registry_value value;
586 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
588 status = registry_openkey(mem_ctx, pipe_hnd, argv[0],
589 SEC_FLAG_MAXIMUM_ALLOWED,
590 &hive_hnd, &key_hnd);
591 if (!NT_STATUS_IS_OK(status)) {
592 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
593 nt_errstr(status));
594 return status;
597 if (!strequal(argv[2], "multi_sz") && (argc != 4)) {
598 d_fprintf(stderr, _("Too many args for type %s\n"), argv[2]);
599 return NT_STATUS_NOT_IMPLEMENTED;
602 if (strequal(argv[2], "dword")) {
603 uint32_t v = strtoul(argv[3], NULL, 10);
604 value.type = REG_DWORD;
605 value.data = data_blob_talloc(mem_ctx, NULL, 4);
606 SIVAL(value.data.data, 0, v);
608 else if (strequal(argv[2], "sz")) {
609 value.type = REG_SZ;
610 if (!push_reg_sz(mem_ctx, &value.data, argv[3])) {
611 status = NT_STATUS_NO_MEMORY;
612 goto error;
615 else {
616 d_fprintf(stderr, _("type \"%s\" not implemented\n"), argv[2]);
617 status = NT_STATUS_NOT_IMPLEMENTED;
618 goto error;
621 status = registry_setvalue(mem_ctx, pipe_hnd, &key_hnd,
622 argv[1], &value);
624 if (!NT_STATUS_IS_OK(status)) {
625 d_fprintf(stderr, _("registry_setvalue failed: %s\n"),
626 nt_errstr(status));
629 error:
630 dcerpc_winreg_CloseKey(b, mem_ctx, &key_hnd, &werr);
631 dcerpc_winreg_CloseKey(b, mem_ctx, &hive_hnd, &werr);
633 return NT_STATUS_OK;
636 static int rpc_registry_setvalue(struct net_context *c, int argc,
637 const char **argv )
639 if (argc < 4 || c->display_usage) {
640 d_fprintf(stderr, "%s\n%s",
641 _("Usage:"),
642 _("net rpc registry setvalue <key> <valuename> "
643 "<type> [<val>]+\n"));
644 return -1;
647 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
648 rpc_registry_setvalue_internal, argc, argv );
651 static NTSTATUS rpc_registry_deletevalue_internal(struct net_context *c,
652 const struct dom_sid *domain_sid,
653 const char *domain_name,
654 struct cli_state *cli,
655 struct rpc_pipe_client *pipe_hnd,
656 TALLOC_CTX *mem_ctx,
657 int argc,
658 const char **argv )
660 struct policy_handle hive_hnd, key_hnd;
661 NTSTATUS status;
662 WERROR werr;
663 struct winreg_String valuename;
664 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
666 ZERO_STRUCT(valuename);
668 status = registry_openkey(mem_ctx, pipe_hnd, argv[0],
669 SEC_FLAG_MAXIMUM_ALLOWED,
670 &hive_hnd, &key_hnd);
671 if (!NT_STATUS_IS_OK(status)) {
672 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
673 nt_errstr(status));
674 return status;
677 valuename.name = argv[1];
679 status = dcerpc_winreg_DeleteValue(b, mem_ctx, &key_hnd,
680 valuename, &werr);
681 if (!NT_STATUS_IS_OK(status)) {
682 d_fprintf(stderr, _("registry_deletevalue failed: %s\n"),
683 nt_errstr(status));
685 if (!W_ERROR_IS_OK(werr)) {
686 status = werror_to_ntstatus(werr);
687 d_fprintf(stderr, _("registry_deletevalue failed: %s\n"),
688 win_errstr(werr));
691 dcerpc_winreg_CloseKey(b, mem_ctx, &key_hnd, &werr);
692 dcerpc_winreg_CloseKey(b, mem_ctx, &hive_hnd, &werr);
694 return status;
697 static int rpc_registry_deletevalue(struct net_context *c, int argc,
698 const char **argv )
700 if (argc != 2 || c->display_usage) {
701 d_fprintf(stderr, "%s\n%s",
702 _("Usage:"),
703 _("net rpc registry deletevalue <key> <valuename>\n"));
704 return -1;
707 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
708 rpc_registry_deletevalue_internal, argc, argv );
711 static NTSTATUS rpc_registry_getvalue_internal(struct net_context *c,
712 const struct dom_sid *domain_sid,
713 const char *domain_name,
714 struct cli_state *cli,
715 struct rpc_pipe_client *pipe_hnd,
716 TALLOC_CTX *mem_ctx,
717 bool raw,
718 int argc,
719 const char **argv)
721 struct policy_handle hive_hnd, key_hnd;
722 NTSTATUS status;
723 WERROR werr;
724 struct winreg_String valuename;
725 struct registry_value *value = NULL;
726 enum winreg_Type type = REG_NONE;
727 uint32_t data_size = 0;
728 uint32_t value_length = 0;
729 TALLOC_CTX *tmp_ctx = talloc_stackframe();
730 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
732 ZERO_STRUCT(valuename);
734 status = registry_openkey(tmp_ctx, pipe_hnd, argv[0],
735 SEC_FLAG_MAXIMUM_ALLOWED,
736 &hive_hnd, &key_hnd);
737 if (!NT_STATUS_IS_OK(status)) {
738 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
739 nt_errstr(status));
740 return status;
743 valuename.name = argv[1];
745 value = talloc_zero(tmp_ctx, struct registry_value);
746 if (value == NULL) {
747 return NT_STATUS_NO_MEMORY;
751 * call QueryValue once with data == NULL to get the
752 * needed memory size to be allocated, then allocate
753 * data buffer and call again.
755 status = dcerpc_winreg_QueryValue(b, tmp_ctx, &key_hnd,
756 &valuename,
757 &type,
758 NULL,
759 &data_size,
760 &value_length,
761 &werr);
763 if (!NT_STATUS_IS_OK(status)) {
764 d_fprintf(stderr, _("registry_queryvalue failed: %s\n"),
765 nt_errstr(status));
766 goto done;
768 if (!W_ERROR_IS_OK(werr)) {
769 status = werror_to_ntstatus(werr);
770 d_fprintf(stderr, _("registry_queryvalue failed: %s\n"),
771 nt_errstr(status));
772 goto done;
775 value->data = data_blob_talloc(tmp_ctx, NULL, data_size);
777 status = dcerpc_winreg_QueryValue(b, tmp_ctx, &key_hnd,
778 &valuename,
779 &type,
780 value->data.data,
781 &data_size,
782 &value_length,
783 &werr);
785 if (!NT_STATUS_IS_OK(status)) {
786 d_fprintf(stderr, _("registry_queryvalue failed: %s\n"),
787 nt_errstr(status));
788 goto done;
790 if (!W_ERROR_IS_OK(werr)) {
791 status = werror_to_ntstatus(werr);
792 d_fprintf(stderr, _("registry_queryvalue failed: %s\n"),
793 win_errstr(werr));
794 goto done;
798 value->type = type;
800 print_registry_value(value, raw);
802 done:
803 dcerpc_winreg_CloseKey(b, tmp_ctx, &key_hnd, &werr);
804 dcerpc_winreg_CloseKey(b, tmp_ctx, &hive_hnd, &werr);
806 TALLOC_FREE(tmp_ctx);
808 return status;
811 static NTSTATUS rpc_registry_getvalue_full(struct net_context *c,
812 const struct dom_sid *domain_sid,
813 const char *domain_name,
814 struct cli_state *cli,
815 struct rpc_pipe_client *pipe_hnd,
816 TALLOC_CTX *mem_ctx,
817 int argc,
818 const char **argv)
820 return rpc_registry_getvalue_internal(c, domain_sid, domain_name,
821 cli, pipe_hnd, mem_ctx, false,
822 argc, argv);
825 static int rpc_registry_getvalue(struct net_context *c, int argc,
826 const char **argv)
828 if (argc != 2 || c->display_usage) {
829 d_fprintf(stderr, "%s\n%s",
830 _("Usage:"),
831 _("net rpc registry getvalue <key> <valuename>\n"));
832 return -1;
835 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
836 rpc_registry_getvalue_full, argc, argv);
839 static NTSTATUS rpc_registry_getvalue_raw(struct net_context *c,
840 const struct dom_sid *domain_sid,
841 const char *domain_name,
842 struct cli_state *cli,
843 struct rpc_pipe_client *pipe_hnd,
844 TALLOC_CTX *mem_ctx,
845 int argc,
846 const char **argv)
848 return rpc_registry_getvalue_internal(c, domain_sid, domain_name,
849 cli, pipe_hnd, mem_ctx, true,
850 argc, argv);
853 static int rpc_registry_getvalueraw(struct net_context *c, int argc,
854 const char **argv)
856 if (argc != 2 || c->display_usage) {
857 d_fprintf(stderr, "%s\n%s",
858 _("Usage:"),
859 _("net rpc registry getvalue <key> <valuename>\n"));
860 return -1;
863 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
864 rpc_registry_getvalue_raw, argc, argv);
867 static NTSTATUS rpc_registry_createkey_internal(struct net_context *c,
868 const struct dom_sid *domain_sid,
869 const char *domain_name,
870 struct cli_state *cli,
871 struct rpc_pipe_client *pipe_hnd,
872 TALLOC_CTX *mem_ctx,
873 int argc,
874 const char **argv )
876 uint32 hive;
877 struct policy_handle hive_hnd, key_hnd;
878 struct winreg_String key, keyclass;
879 enum winreg_CreateAction action;
880 NTSTATUS status;
881 WERROR werr;
882 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
884 ZERO_STRUCT(key);
885 ZERO_STRUCT(keyclass);
887 if (!reg_hive_key(mem_ctx, argv[0], &hive, &key.name)) {
888 return NT_STATUS_INVALID_PARAMETER;
891 status = dcerpc_winreg_Connect(b, mem_ctx, hive,
892 SEC_FLAG_MAXIMUM_ALLOWED,
893 &hive_hnd, &werr);
894 if (!(NT_STATUS_IS_OK(status))) {
895 return status;
897 if (!W_ERROR_IS_OK(werr)) {
898 return werror_to_ntstatus(werr);
901 action = REG_ACTION_NONE;
902 keyclass.name = "";
904 status = dcerpc_winreg_CreateKey(b, mem_ctx, &hive_hnd, key,
905 keyclass, 0, REG_KEY_READ, NULL,
906 &key_hnd, &action, &werr);
907 if (!NT_STATUS_IS_OK(status)) {
908 d_fprintf(stderr, _("createkey returned %s\n"),
909 nt_errstr(status));
910 dcerpc_winreg_CloseKey(b, mem_ctx, &hive_hnd, &werr);
911 return status;
913 if (!W_ERROR_IS_OK(werr)) {
914 WERROR _werr;
915 d_fprintf(stderr, _("createkey returned %s\n"),
916 win_errstr(werr));
917 dcerpc_winreg_CloseKey(b, mem_ctx, &hive_hnd, &_werr);
918 return werror_to_ntstatus(werr);
921 switch (action) {
922 case REG_ACTION_NONE:
923 d_printf(_("createkey did nothing -- huh?\n"));
924 break;
925 case REG_CREATED_NEW_KEY:
926 d_printf(_("createkey created %s\n"), argv[0]);
927 break;
928 case REG_OPENED_EXISTING_KEY:
929 d_printf(_("createkey opened existing %s\n"), argv[0]);
930 break;
933 dcerpc_winreg_CloseKey(b, mem_ctx, &key_hnd, &werr);
934 dcerpc_winreg_CloseKey(b, mem_ctx, &hive_hnd, &werr);
936 return status;
939 static int rpc_registry_createkey(struct net_context *c, int argc,
940 const char **argv )
942 if (argc != 1 || c->display_usage) {
943 d_fprintf(stderr, "%s\n%s",
944 _("Usage:"),
945 _("net rpc registry createkey <key>\n"));
946 return -1;
949 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
950 rpc_registry_createkey_internal, argc, argv );
953 static NTSTATUS rpc_registry_deletekey_internal(struct net_context *c,
954 const struct dom_sid *domain_sid,
955 const char *domain_name,
956 struct cli_state *cli,
957 struct rpc_pipe_client *pipe_hnd,
958 TALLOC_CTX *mem_ctx,
959 int argc,
960 const char **argv )
962 uint32 hive;
963 struct policy_handle hive_hnd;
964 struct winreg_String key;
965 NTSTATUS status;
966 WERROR werr;
967 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
969 ZERO_STRUCT(key);
971 if (!reg_hive_key(mem_ctx, argv[0], &hive, &key.name)) {
972 return NT_STATUS_INVALID_PARAMETER;
975 status = dcerpc_winreg_Connect(b, mem_ctx, hive,
976 SEC_FLAG_MAXIMUM_ALLOWED,
977 &hive_hnd, &werr);
978 if (!(NT_STATUS_IS_OK(status))) {
979 return status;
981 if (!W_ERROR_IS_OK(werr)) {
982 return werror_to_ntstatus(werr);
985 status = dcerpc_winreg_DeleteKey(b, mem_ctx, &hive_hnd, key, &werr);
986 if (is_valid_policy_hnd(&hive_hnd)) {
987 WERROR _werr;
988 dcerpc_winreg_CloseKey(b, mem_ctx, &hive_hnd, &_werr);
991 if (!NT_STATUS_IS_OK(status)) {
992 d_fprintf(stderr, _("deletekey returned %s\n"),
993 nt_errstr(status));
994 return status;
997 if (!W_ERROR_IS_OK(werr)) {
998 d_fprintf(stderr, _("deletekey returned %s\n"),
999 win_errstr(werr));
1000 return werror_to_ntstatus(werr);
1003 return status;
1006 static int rpc_registry_deletekey(struct net_context *c, int argc, const char **argv )
1008 if (argc != 1 || c->display_usage) {
1009 d_fprintf(stderr, "%s\n%s",
1010 _("Usage:"),
1011 _("net rpc registry deletekey <key>\n"));
1012 return -1;
1015 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
1016 rpc_registry_deletekey_internal, argc, argv );
1019 /********************************************************************
1020 ********************************************************************/
1022 static NTSTATUS rpc_registry_enumerate_internal(struct net_context *c,
1023 const struct dom_sid *domain_sid,
1024 const char *domain_name,
1025 struct cli_state *cli,
1026 struct rpc_pipe_client *pipe_hnd,
1027 TALLOC_CTX *mem_ctx,
1028 int argc,
1029 const char **argv )
1031 struct policy_handle pol_hive, pol_key;
1032 NTSTATUS status;
1033 WERROR werr;
1034 uint32 num_subkeys = 0;
1035 uint32 num_values = 0;
1036 char **names = NULL, **classes = NULL;
1037 NTTIME **modtimes = NULL;
1038 uint32 i;
1039 struct registry_value **values = NULL;
1040 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
1042 if (argc != 1 || c->display_usage) {
1043 d_printf("%s\n%s",
1044 _("Usage:"),
1045 _("net rpc registry enumerate <path>\n"));
1046 d_printf("%s net rpc registry enumerate "
1047 "'HKLM\\Software\\Samba'\n", _("Example:"));
1048 return NT_STATUS_INVALID_PARAMETER;
1051 status = registry_openkey(mem_ctx, pipe_hnd, argv[0], REG_KEY_READ,
1052 &pol_hive, &pol_key);
1053 if (!NT_STATUS_IS_OK(status)) {
1054 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
1055 nt_errstr(status));
1056 return status;
1059 status = registry_enumkeys(mem_ctx, pipe_hnd, &pol_key, &num_subkeys,
1060 &names, &classes, &modtimes);
1061 if (!NT_STATUS_IS_OK(status)) {
1062 d_fprintf(stderr, _("enumerating keys failed: %s\n"),
1063 nt_errstr(status));
1064 return status;
1067 for (i=0; i<num_subkeys; i++) {
1068 print_registry_key(names[i], modtimes[i]);
1071 status = registry_enumvalues(mem_ctx, pipe_hnd, &pol_key, &num_values,
1072 &names, &values);
1073 if (!NT_STATUS_IS_OK(status)) {
1074 d_fprintf(stderr, _("enumerating values failed: %s\n"),
1075 nt_errstr(status));
1076 return status;
1079 for (i=0; i<num_values; i++) {
1080 print_registry_value_with_name(names[i], values[i]);
1083 dcerpc_winreg_CloseKey(b, mem_ctx, &pol_key, &werr);
1084 dcerpc_winreg_CloseKey(b, mem_ctx, &pol_hive, &werr);
1086 return status;
1089 /********************************************************************
1090 ********************************************************************/
1092 static int rpc_registry_enumerate(struct net_context *c, int argc,
1093 const char **argv )
1095 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
1096 rpc_registry_enumerate_internal, argc, argv );
1099 /********************************************************************
1100 ********************************************************************/
1102 static NTSTATUS rpc_registry_save_internal(struct net_context *c,
1103 const struct dom_sid *domain_sid,
1104 const char *domain_name,
1105 struct cli_state *cli,
1106 struct rpc_pipe_client *pipe_hnd,
1107 TALLOC_CTX *mem_ctx,
1108 int argc,
1109 const char **argv )
1111 WERROR result = WERR_GENERAL_FAILURE;
1112 struct policy_handle pol_hive, pol_key;
1113 NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
1114 struct winreg_String filename;
1115 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
1117 if (argc != 2 || c->display_usage) {
1118 d_printf("%s\n%s",
1119 _("Usage:"),
1120 _("net rpc registry backup <path> <file> \n"));
1121 return NT_STATUS_INVALID_PARAMETER;
1124 status = registry_openkey(mem_ctx, pipe_hnd, argv[0], REG_KEY_ALL,
1125 &pol_hive, &pol_key);
1126 if (!NT_STATUS_IS_OK(status)) {
1127 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
1128 nt_errstr(status));
1129 return status;
1132 filename.name = argv[1];
1133 status = dcerpc_winreg_SaveKey(b, mem_ctx, &pol_key, &filename, NULL, &result);
1134 if (!NT_STATUS_IS_OK(status)) {
1135 d_fprintf(stderr, _("Unable to save [%s] to %s:%s\n"), argv[0],
1136 cli->desthost, argv[1]);
1138 if (!W_ERROR_IS_OK(result)) {
1139 status = werror_to_ntstatus(result);
1140 d_fprintf(stderr, _("Unable to save [%s] to %s:%s\n"), argv[0],
1141 cli->desthost, argv[1]);
1144 /* cleanup */
1146 dcerpc_winreg_CloseKey(b, mem_ctx, &pol_key, &result);
1147 dcerpc_winreg_CloseKey(b, mem_ctx, &pol_hive, &result);
1149 return status;
1152 /********************************************************************
1153 ********************************************************************/
1155 static int rpc_registry_save(struct net_context *c, int argc, const char **argv )
1157 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
1158 rpc_registry_save_internal, argc, argv );
1162 /********************************************************************
1163 ********************************************************************/
1165 static void dump_values( REGF_NK_REC *nk )
1167 int i, j;
1168 const char *data_str = NULL;
1169 uint32 data_size, data;
1170 DATA_BLOB blob;
1172 if ( !nk->values )
1173 return;
1175 for ( i=0; i<nk->num_values; i++ ) {
1176 d_printf( "\"%s\" = ", nk->values[i].valuename ? nk->values[i].valuename : "(default)" );
1177 d_printf( "(%s) ", str_regtype( nk->values[i].type ) );
1179 data_size = nk->values[i].data_size & ~VK_DATA_IN_OFFSET;
1180 switch ( nk->values[i].type ) {
1181 case REG_SZ:
1182 blob = data_blob_const(nk->values[i].data, data_size);
1183 pull_reg_sz(talloc_tos(), &blob, &data_str);
1184 if (!data_str) {
1185 break;
1187 d_printf( "%s", data_str );
1188 break;
1189 case REG_MULTI_SZ:
1190 case REG_EXPAND_SZ:
1191 for ( j=0; j<data_size; j++ ) {
1192 d_printf( "%c", nk->values[i].data[j] );
1194 break;
1195 case REG_DWORD:
1196 data = IVAL( nk->values[i].data, 0 );
1197 d_printf("0x%x", data );
1198 break;
1199 case REG_BINARY:
1200 for ( j=0; j<data_size; j++ ) {
1201 d_printf( "%x", nk->values[i].data[j] );
1203 break;
1204 default:
1205 d_printf(_("unknown"));
1206 break;
1209 d_printf( "\n" );
1214 /********************************************************************
1215 ********************************************************************/
1217 static bool dump_registry_tree( REGF_FILE *file, REGF_NK_REC *nk, const char *parent )
1219 REGF_NK_REC *key;
1221 /* depth first dump of the registry tree */
1223 while ( (key = regfio_fetch_subkey( file, nk )) ) {
1224 char *regpath;
1225 if (asprintf(&regpath, "%s\\%s", parent, key->keyname) < 0) {
1226 break;
1228 d_printf("[%s]\n", regpath );
1229 dump_values( key );
1230 d_printf("\n");
1231 dump_registry_tree( file, key, regpath );
1232 SAFE_FREE(regpath);
1235 return true;
1238 /********************************************************************
1239 ********************************************************************/
1241 static bool write_registry_tree( REGF_FILE *infile, REGF_NK_REC *nk,
1242 REGF_NK_REC *parent, REGF_FILE *outfile,
1243 const char *parentpath )
1245 REGF_NK_REC *key, *subkey;
1246 struct regval_ctr *values = NULL;
1247 struct regsubkey_ctr *subkeys = NULL;
1248 int i;
1249 char *path = NULL;
1250 WERROR werr;
1252 werr = regsubkey_ctr_init(infile->mem_ctx, &subkeys);
1253 if (!W_ERROR_IS_OK(werr)) {
1254 DEBUG(0, ("write_registry_tree: regsubkey_ctr_init failed: "
1255 "%s\n", win_errstr(werr)));
1256 return false;
1259 werr = regval_ctr_init(subkeys, &values);
1260 if (!W_ERROR_IS_OK(werr)) {
1261 DEBUG(0,("write_registry_tree: talloc() failed!\n"));
1262 TALLOC_FREE(subkeys);
1263 return false;
1266 /* copy values into the struct regval_ctr */
1268 for ( i=0; i<nk->num_values; i++ ) {
1269 regval_ctr_addvalue( values, nk->values[i].valuename, nk->values[i].type,
1270 nk->values[i].data, (nk->values[i].data_size & ~VK_DATA_IN_OFFSET) );
1273 /* copy subkeys into the struct regsubkey_ctr */
1275 while ( (subkey = regfio_fetch_subkey( infile, nk )) ) {
1276 regsubkey_ctr_addkey( subkeys, subkey->keyname );
1279 key = regfio_write_key( outfile, nk->keyname, values, subkeys, nk->sec_desc->sec_desc, parent );
1281 /* write each one of the subkeys out */
1283 path = talloc_asprintf(subkeys,
1284 "%s%s%s",
1285 parentpath,
1286 parent ? "\\" : "",
1287 nk->keyname);
1288 if (!path) {
1289 TALLOC_FREE(subkeys);
1290 return false;
1293 nk->subkey_index = 0;
1294 while ( (subkey = regfio_fetch_subkey( infile, nk )) ) {
1295 write_registry_tree( infile, subkey, key, outfile, path );
1298 d_printf("[%s]\n", path );
1299 TALLOC_FREE(subkeys);
1301 return true;
1304 /********************************************************************
1305 ********************************************************************/
1307 static int rpc_registry_dump(struct net_context *c, int argc, const char **argv)
1309 REGF_FILE *registry;
1310 REGF_NK_REC *nk;
1312 if (argc != 1 || c->display_usage) {
1313 d_printf("%s\n%s",
1314 _("Usage:"),
1315 _("net rpc registry dump <file> \n"));
1316 return -1;
1319 d_printf(_("Opening %s...."), argv[0]);
1320 if ( !(registry = regfio_open( argv[0], O_RDONLY, 0)) ) {
1321 d_fprintf(stderr, _("Failed to open %s for reading\n"),argv[0]);
1322 return 1;
1324 d_printf(_("ok\n"));
1326 /* get the root of the registry file */
1328 if ((nk = regfio_rootkey( registry )) == NULL) {
1329 d_fprintf(stderr, _("Could not get rootkey\n"));
1330 regfio_close( registry );
1331 return 1;
1333 d_printf("[%s]\n", nk->keyname);
1334 dump_values( nk );
1335 d_printf("\n");
1337 dump_registry_tree( registry, nk, nk->keyname );
1339 #if 0
1340 talloc_report_full( registry->mem_ctx, stderr );
1341 #endif
1342 d_printf(_("Closing registry..."));
1343 regfio_close( registry );
1344 d_printf(_("ok\n"));
1346 return 0;
1349 /********************************************************************
1350 ********************************************************************/
1352 static int rpc_registry_copy(struct net_context *c, int argc, const char **argv )
1354 REGF_FILE *infile = NULL, *outfile = NULL;
1355 REGF_NK_REC *nk;
1356 int result = 1;
1358 if (argc != 2 || c->display_usage) {
1359 d_printf("%s\n%s",
1360 _("Usage:"),
1361 _("net rpc registry copy <srcfile> <newfile>\n"));
1362 return -1;
1365 d_printf(_("Opening %s...."), argv[0]);
1366 if ( !(infile = regfio_open( argv[0], O_RDONLY, 0 )) ) {
1367 d_fprintf(stderr, _("Failed to open %s for reading\n"),argv[0]);
1368 return 1;
1370 d_printf(_("ok\n"));
1372 d_printf(_("Opening %s...."), argv[1]);
1373 if ( !(outfile = regfio_open( argv[1], (O_RDWR|O_CREAT|O_TRUNC),
1374 (S_IRUSR|S_IWUSR) )) ) {
1375 d_fprintf(stderr, _("Failed to open %s for writing\n"),argv[1]);
1376 goto out;
1378 d_printf(_("ok\n"));
1380 /* get the root of the registry file */
1382 if ((nk = regfio_rootkey( infile )) == NULL) {
1383 d_fprintf(stderr, _("Could not get rootkey\n"));
1384 goto out;
1386 d_printf(_("RootKey: [%s]\n"), nk->keyname);
1388 write_registry_tree( infile, nk, NULL, outfile, "" );
1390 result = 0;
1392 out:
1394 d_printf(_("Closing %s..."), argv[1]);
1395 if (outfile) {
1396 regfio_close( outfile );
1398 d_printf(_("ok\n"));
1400 d_printf(_("Closing %s..."), argv[0]);
1401 if (infile) {
1402 regfio_close( infile );
1404 d_printf(_("ok\n"));
1406 return( result);
1409 /********************************************************************
1410 ********************************************************************/
1412 static NTSTATUS rpc_registry_getsd_internal(struct net_context *c,
1413 const struct dom_sid *domain_sid,
1414 const char *domain_name,
1415 struct cli_state *cli,
1416 struct rpc_pipe_client *pipe_hnd,
1417 TALLOC_CTX *mem_ctx,
1418 int argc,
1419 const char **argv)
1421 struct policy_handle pol_hive, pol_key;
1422 NTSTATUS status;
1423 WERROR werr;
1424 enum ndr_err_code ndr_err;
1425 struct KeySecurityData *sd = NULL;
1426 uint32_t sec_info;
1427 DATA_BLOB blob;
1428 struct security_descriptor sec_desc;
1429 uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED |
1430 SEC_FLAG_SYSTEM_SECURITY;
1431 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
1433 if (argc <1 || argc > 2 || c->display_usage) {
1434 d_printf("%s\n%s",
1435 _("Usage:"),
1436 _("net rpc registry getsd <path> <secinfo>\n"));
1437 d_printf("%s net rpc registry getsd "
1438 "'HKLM\\Software\\Samba'\n", _("Example:"));
1439 return NT_STATUS_INVALID_PARAMETER;
1442 status = registry_openkey(mem_ctx, pipe_hnd, argv[0],
1443 access_mask,
1444 &pol_hive, &pol_key);
1445 if (!NT_STATUS_IS_OK(status)) {
1446 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
1447 nt_errstr(status));
1448 return status;
1451 sd = TALLOC_ZERO_P(mem_ctx, struct KeySecurityData);
1452 if (!sd) {
1453 status = NT_STATUS_NO_MEMORY;
1454 goto out;
1457 sd->size = 0x1000;
1459 if (argc >= 2) {
1460 sscanf(argv[1], "%x", &sec_info);
1461 } else {
1462 sec_info = SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL;
1465 status = registry_getsd(mem_ctx, b, &pol_key, sec_info, sd, &werr);
1466 if (!NT_STATUS_IS_OK(status)) {
1467 d_fprintf(stderr, _("getting sd failed: %s\n"),
1468 nt_errstr(status));
1469 goto out;
1471 if (!W_ERROR_IS_OK(werr)) {
1472 status = werror_to_ntstatus(werr);
1473 d_fprintf(stderr, _("getting sd failed: %s\n"),
1474 win_errstr(werr));
1475 goto out;
1478 blob.data = sd->data;
1479 blob.length = sd->size;
1481 ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &sec_desc,
1482 (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
1483 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1484 status = ndr_map_error2ntstatus(ndr_err);
1485 goto out;
1487 status = NT_STATUS_OK;
1489 display_sec_desc(&sec_desc);
1491 out:
1492 dcerpc_winreg_CloseKey(b, mem_ctx, &pol_key, &werr);
1493 dcerpc_winreg_CloseKey(b, mem_ctx, &pol_hive, &werr);
1495 return status;
1499 static int rpc_registry_getsd(struct net_context *c, int argc, const char **argv)
1501 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
1502 rpc_registry_getsd_internal, argc, argv);
1505 /********************************************************************
1506 ********************************************************************/
1508 * @defgroup net_rpc_registry net rpc registry
1512 * @defgroup net_rpc_registry_export Export
1513 * @ingroup net_rpc_registry
1514 * @{
1517 static NTSTATUS registry_export(struct rpc_pipe_client* pipe_hnd,
1518 TALLOC_CTX* ctx,
1519 struct policy_handle* key_hnd,
1520 struct reg_format* f,
1521 const char* parentfullname,
1522 const char* name)
1524 NTSTATUS status;
1525 uint32 num_subkeys = 0;
1526 uint32 num_values = 0;
1527 char **names = NULL, **classes = NULL;
1528 NTTIME **modtimes = NULL;
1529 struct regval_blob **values = NULL;
1530 uint32 i;
1531 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
1533 TALLOC_CTX* mem_ctx = talloc_new(ctx);
1536 const char* fullname = name
1537 ? talloc_asprintf(mem_ctx, "%s\\%s", parentfullname, name)
1538 : parentfullname;
1539 reg_format_key(f, &fullname, 1, false);
1541 status = registry_enumvalues2(mem_ctx, pipe_hnd, key_hnd, &num_values,
1542 &names, &values);
1543 if (!NT_STATUS_IS_OK(status)) {
1544 d_fprintf(stderr, _("enumerating values failed: %s\n"),
1545 nt_errstr(status));
1546 goto done;
1549 for (i=0; i<num_values; i++) {
1550 reg_format_regval_blob(f, names[i], values[i]);
1554 status = registry_enumkeys(mem_ctx, pipe_hnd, key_hnd, &num_subkeys,
1555 &names, &classes, &modtimes);
1556 if (!NT_STATUS_IS_OK(status)) {
1557 d_fprintf(stderr, _("enumerating keys failed: %s\n"),
1558 nt_errstr(status));
1559 goto done;
1562 for (i=0; i<num_subkeys; i++) {
1563 struct policy_handle subkey_hnd;
1564 struct winreg_String key;
1565 WERROR werr;
1566 ZERO_STRUCT(key);
1567 /* key.name = talloc_strdup(mem_ctx, names[i]); ??? */
1568 key.name = names[i];
1570 status = dcerpc_winreg_OpenKey(b, mem_ctx, key_hnd, key,
1571 0, REG_KEY_READ,
1572 &subkey_hnd, &werr);
1573 if (!NT_STATUS_IS_OK(status)) {
1574 d_fprintf(stderr,
1575 _("dcerpc_winreg_OpenKey failed: %s %s\n"),
1576 names[i], nt_errstr(status));
1577 continue;
1579 if (!W_ERROR_IS_OK(werr)) {
1580 status = werror_to_ntstatus(werr);
1581 d_fprintf(stderr,
1582 _("dcerpc_winreg_OpenKey failed: %s %s\n"),
1583 names[i], win_errstr(werr));
1584 continue;
1587 status = registry_export(pipe_hnd, mem_ctx, &subkey_hnd,
1588 f, fullname, names[i]);
1589 if (!(NT_STATUS_IS_OK(status))) {
1590 d_fprintf(stderr,
1591 _("export key failed: %s %s\n"),
1592 names[i], nt_errstr(status));
1594 dcerpc_winreg_CloseKey(b, mem_ctx,
1595 &subkey_hnd, &werr);
1597 done:
1598 talloc_free(mem_ctx);
1599 return status;
1602 static NTSTATUS rpc_registry_export_internal(struct net_context *c,
1603 const struct dom_sid *domain_sid,
1604 const char *domain_name,
1605 struct cli_state *cli,
1606 struct rpc_pipe_client *pipe_hnd,
1607 TALLOC_CTX *mem_ctx,
1608 int argc,
1609 const char **argv )
1611 struct policy_handle pol_hive, pol_key;
1612 NTSTATUS status;
1613 WERROR werr;
1614 struct reg_format* f;
1615 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
1617 if (argc < 2 || argc > 3 || c->display_usage) {
1618 d_printf("%s\n%s",
1619 _("Usage:"),
1620 _("net rpc registry export <path> <file> [opt]\n"));
1621 d_printf("%s net rpc registry export "
1622 "'HKLM\\Software\\Samba' samba.reg\n", _("Example:"));
1623 return NT_STATUS_INVALID_PARAMETER;
1626 status = registry_openkey(mem_ctx, pipe_hnd, argv[0], REG_KEY_READ,
1627 &pol_hive, &pol_key);
1628 if (!NT_STATUS_IS_OK(status)) {
1629 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
1630 nt_errstr(status));
1631 return status;
1634 f = reg_format_file(mem_ctx, argv[1], (argc > 2) ? argv[2] : NULL);
1635 if (f == NULL) {
1636 d_fprintf(stderr, _("open file failed: %s\n"), strerror(errno));
1637 return map_nt_error_from_unix(errno);
1640 status = registry_export(pipe_hnd, mem_ctx, &pol_key,
1641 f, argv[0], NULL );
1642 if (!NT_STATUS_IS_OK(status))
1643 return status;
1645 dcerpc_winreg_CloseKey(b, mem_ctx, &pol_key, &werr);
1646 dcerpc_winreg_CloseKey(b, mem_ctx, &pol_hive, &werr);
1648 return status;
1650 /********************************************************************
1651 ********************************************************************/
1653 static int rpc_registry_export(struct net_context *c, int argc,
1654 const char **argv )
1656 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
1657 rpc_registry_export_internal, argc, argv );
1660 /**@}*/
1662 /********************************************************************
1663 ********************************************************************/
1666 * @defgroup net_rpc_registry_import Import
1667 * @ingroup net_rpc_registry
1668 * @{
1671 struct import_ctx {
1672 struct rpc_pipe_client *pipe_hnd;
1673 TALLOC_CTX *mem_ctx;
1676 static WERROR import_create_key(struct import_ctx* ctx,
1677 struct policy_handle* parent, const char* name,
1678 void** pkey, bool* existing)
1680 WERROR werr;
1681 NTSTATUS status;
1682 void* mem_ctx = talloc_new(ctx->mem_ctx);
1684 struct policy_handle* key = NULL;
1685 struct policy_handle hive;
1686 struct winreg_String keyclass, keyname;
1687 enum winreg_CreateAction action = REG_ACTION_NONE;
1688 struct dcerpc_binding_handle *b = ctx->pipe_hnd->binding_handle;
1690 ZERO_STRUCT(keyname);
1691 keyname.name = name;
1693 if (parent == NULL) {
1694 uint32 hive_idx = 0;
1695 if (!reg_hive_key(mem_ctx, name, &hive_idx, &keyname.name)) {
1696 werr = WERR_FOOBAR;
1697 goto done;
1700 status = dcerpc_winreg_Connect(b, mem_ctx,
1701 hive_idx, SEC_FLAG_MAXIMUM_ALLOWED,
1702 &hive, &werr);
1703 if (!NT_STATUS_IS_OK(status)) {
1704 werr = ntstatus_to_werror(status);
1705 d_fprintf(stderr, _("dcerpc_winreg_Connect returned %s\n"),
1706 nt_errstr(status));
1707 goto done;
1709 if (!W_ERROR_IS_OK(werr)) {
1710 d_fprintf(stderr, _("dcerpc_winreg_Connect returned %s\n"),
1711 win_errstr(werr));
1712 goto done;
1715 parent = &hive;
1718 key = talloc_zero(mem_ctx, struct policy_handle);
1719 if (key == NULL) {
1720 werr = WERR_NOMEM;
1721 goto done;
1724 ZERO_STRUCT(keyclass);
1725 keyclass.name = "";
1727 status = dcerpc_winreg_CreateKey(b, mem_ctx,
1728 parent, keyname,
1729 keyclass, 0, REG_KEY_READ, NULL,
1730 key, &action, &werr);
1731 if (!NT_STATUS_IS_OK(status)) {
1732 werr = ntstatus_to_werror(status);
1733 d_fprintf(stderr, _("dcerpc_winreg_CreateKey returned %s\n"),
1734 nt_errstr(status));
1735 goto done;
1737 if (!W_ERROR_IS_OK(werr)) {
1738 d_fprintf(stderr, _("dcerpc_winreg_CreateKey returned %s\n"),
1739 win_errstr(werr));
1740 goto done;
1743 switch (action) {
1744 case REG_CREATED_NEW_KEY:
1745 d_printf(_("createkey created %s\n"), name);
1746 if (existing != NULL)
1747 *existing = false;
1748 break;
1750 case REG_OPENED_EXISTING_KEY:
1751 d_printf(_("createkey opened existing %s\n"), name);
1752 if (existing != NULL)
1753 *existing = true;
1754 break;
1756 case REG_ACTION_NONE:
1757 d_printf(_("createkey did nothing -- huh?\n"));
1758 werr = WERR_CREATE_FAILED;
1759 break;
1760 default:
1761 assert(false);
1764 done:
1765 if ( parent == &hive ) {
1766 WERROR _result;
1767 dcerpc_winreg_CloseKey(b, mem_ctx,
1768 parent, &_result);
1771 if (pkey!=NULL) {
1772 *pkey = talloc_steal(ctx->mem_ctx, key);
1775 talloc_free(mem_ctx);
1776 return werr;
1779 static WERROR import_delete_key(struct import_ctx* ctx,
1780 struct policy_handle* parent, const char* name)
1782 WERROR werr;
1783 NTSTATUS status;
1784 void* mem_ctx = talloc_new(ctx->mem_ctx);
1785 struct winreg_String keyname;
1786 struct policy_handle hive;
1787 struct dcerpc_binding_handle *b = ctx->pipe_hnd->binding_handle;
1789 keyname.name = name;
1791 if (parent == NULL) {
1792 uint32 hive_idx;
1793 if (!reg_hive_key(mem_ctx, name, &hive_idx, &keyname.name)) {
1794 werr = WERR_FOOBAR;
1795 goto done;
1798 status = dcerpc_winreg_Connect(b, mem_ctx, hive_idx,
1799 SEC_FLAG_MAXIMUM_ALLOWED, &hive,
1800 &werr);
1801 if (!NT_STATUS_IS_OK(status)) {
1802 werr = ntstatus_to_werror(status);
1803 d_fprintf(stderr, _("dcerpc_winreg_Connect returned %s\n"),
1804 nt_errstr(status));
1805 goto done;
1807 if (!W_ERROR_IS_OK(werr)) {
1808 d_fprintf(stderr, _("dcerpc_winreg_Connect returned %s\n"),
1809 win_errstr(werr));
1810 goto done;
1813 parent = &hive;
1816 status = dcerpc_winreg_DeleteKey(b, mem_ctx, parent,
1817 keyname, &werr);
1818 if (!NT_STATUS_IS_OK(status)) {
1819 werr = ntstatus_to_werror(status);
1820 d_fprintf(stderr, _("dcerpc_winreg_DeleteKey returned %s\n"),
1821 nt_errstr(status));
1822 goto done;
1824 if (!W_ERROR_IS_OK(werr)) {
1825 d_fprintf(stderr, _("dcerpc_winreg_DeleteKey returned %s\n"),
1826 win_errstr(werr));
1827 goto done;
1830 done:
1831 if ( parent == &hive ) {
1832 WERROR _result;
1833 dcerpc_winreg_CloseKey(b, mem_ctx, parent, &_result);
1836 talloc_free(mem_ctx);
1837 return werr;
1840 static WERROR import_close_key(struct import_ctx* ctx,
1841 struct policy_handle* key)
1843 WERROR werr;
1844 NTSTATUS status;
1845 void* mem_ctx = talloc_new(ctx->mem_ctx);
1846 struct dcerpc_binding_handle *b = ctx->pipe_hnd->binding_handle;
1848 status = dcerpc_winreg_CloseKey(b, mem_ctx, key, &werr);
1849 if (!NT_STATUS_IS_OK(status)) {
1850 werr = ntstatus_to_werror(status);
1851 d_fprintf(stderr, _("dcerpc_winreg_CloseKey returned %s\n"),
1852 nt_errstr(status));
1853 goto done;
1855 if (!W_ERROR_IS_OK(werr)) {
1856 d_fprintf(stderr, _("dcerpc_winreg_CloseKey returned %s\n"),
1857 win_errstr(werr));
1858 goto done;
1861 werr = (talloc_free(key) == 0) ? WERR_OK : WERR_GENERAL_FAILURE;
1862 done:
1863 talloc_free(mem_ctx);
1864 return werr;
1867 static WERROR import_create_val(struct import_ctx* ctx,
1868 struct policy_handle* parent, const char* name,
1869 uint32_t type, const uint8_t* val, uint32_t len)
1871 WERROR werr;
1872 NTSTATUS status;
1873 void* mem_ctx = talloc_new(ctx->mem_ctx);
1874 struct winreg_String valuename;
1875 struct dcerpc_binding_handle *b = ctx->pipe_hnd->binding_handle;
1877 if (parent == NULL) {
1878 return WERR_INVALID_PARAM;
1881 ZERO_STRUCT(valuename);
1882 valuename.name = name;
1884 status = dcerpc_winreg_SetValue(b, mem_ctx, parent,
1885 valuename, type,
1886 (uint8_t *)discard_const(val), len, &werr);
1887 if (!NT_STATUS_IS_OK(status)) {
1888 werr = ntstatus_to_werror(status);
1889 d_fprintf(stderr, _("registry_setvalue failed: %s\n"),
1890 nt_errstr(status));
1891 goto done;
1893 if (!W_ERROR_IS_OK(werr)) {
1894 d_fprintf(stderr, _("registry_setvalue failed: %s\n"),
1895 win_errstr(werr));
1896 goto done;
1899 done:
1900 talloc_free(mem_ctx);
1901 return werr;
1904 static WERROR import_delete_val(struct import_ctx* ctx,
1905 struct policy_handle* parent, const char* name)
1907 WERROR werr;
1908 NTSTATUS status;
1909 void* mem_ctx = talloc_new(ctx->mem_ctx);
1910 struct winreg_String valuename;
1911 struct dcerpc_binding_handle *b = ctx->pipe_hnd->binding_handle;
1913 if (parent == NULL) {
1914 return WERR_INVALID_PARAM;
1917 ZERO_STRUCT(valuename);
1918 valuename.name = name;
1920 status = dcerpc_winreg_DeleteValue(b, mem_ctx,
1921 parent, valuename, &werr);
1923 if (!NT_STATUS_IS_OK(status)) {
1924 werr = ntstatus_to_werror(status);
1925 d_fprintf(stderr, _("registry_deletevalue failed: %s\n"),
1926 nt_errstr(status));
1927 goto done;
1929 if (!NT_STATUS_IS_OK(status)) {
1930 d_fprintf(stderr, _("registry_deletevalue failed: %s\n"),
1931 win_errstr(werr));
1932 goto done;
1935 done:
1936 talloc_free(mem_ctx);
1937 return werr;
1942 static NTSTATUS rpc_registry_import_internal(struct net_context *c,
1943 const struct dom_sid *domain_sid,
1944 const char *domain_name,
1945 struct cli_state *cli,
1946 struct rpc_pipe_client *pipe_hnd,
1947 TALLOC_CTX *mem_ctx,
1948 int argc,
1949 const char **argv )
1951 struct import_ctx import_ctx;
1953 struct reg_import_callback import_callback = {
1954 .openkey = NULL,
1955 .closekey = (reg_import_callback_closekey_t)&import_close_key,
1956 .createkey = (reg_import_callback_createkey_t)&import_create_key,
1957 .deletekey = (reg_import_callback_deletekey_t)&import_delete_key,
1958 .deleteval = (reg_import_callback_deleteval_t)&import_delete_val,
1959 .setval.blob = (reg_import_callback_setval_blob_t)&import_create_val,
1960 .setval_type = BLOB,
1961 .data = &import_ctx
1964 int ret;
1965 if (argc < 1 || argc > 2 || c->display_usage) {
1966 d_printf("%s\n%s",
1967 _("Usage:"),
1968 _("net rpc registry import <file> [options]\n"));
1969 d_printf("%s net rpc registry export "
1970 "samba.reg enc=CP1252,flags=0\n", _("Example:"));
1971 return NT_STATUS_INVALID_PARAMETER;
1973 ZERO_STRUCT(import_ctx);
1974 import_ctx.pipe_hnd = pipe_hnd;
1975 import_ctx.mem_ctx = mem_ctx;
1976 ret = reg_parse_file(argv[0],
1977 reg_import_adapter(import_ctx.mem_ctx,
1978 import_callback
1980 (argc > 1) ? argv[1] : NULL
1983 return ret==0 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1986 /********************************************************************
1987 ********************************************************************/
1989 static int rpc_registry_import(struct net_context *c, int argc,
1990 const char **argv )
1992 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
1993 rpc_registry_import_internal, argc, argv );
1996 /**@}*/
1997 /********************************************************************
1998 ********************************************************************/
2000 int net_rpc_registry(struct net_context *c, int argc, const char **argv)
2002 struct functable func[] = {
2004 "enumerate",
2005 rpc_registry_enumerate,
2006 NET_TRANSPORT_RPC,
2007 N_("Enumerate registry keys and values"),
2008 N_("net rpc registry enumerate\n"
2009 " Enumerate registry keys and values")
2012 "createkey",
2013 rpc_registry_createkey,
2014 NET_TRANSPORT_RPC,
2015 N_("Create a new registry key"),
2016 N_("net rpc registry createkey\n"
2017 " Create a new registry key")
2020 "deletekey",
2021 rpc_registry_deletekey,
2022 NET_TRANSPORT_RPC,
2023 N_("Delete a registry key"),
2024 N_("net rpc registry deletekey\n"
2025 " Delete a registry key")
2028 "getvalue",
2029 rpc_registry_getvalue,
2030 NET_TRANSPORT_RPC,
2031 N_("Print a registry value"),
2032 N_("net rpc registry getvalue\n"
2033 " Print a registry value")
2036 "getvalueraw",
2037 rpc_registry_getvalueraw,
2038 NET_TRANSPORT_RPC,
2039 N_("Print a registry value"),
2040 N_("net rpc registry getvalueraw\n"
2041 " Print a registry value (raw version)")
2044 "setvalue",
2045 rpc_registry_setvalue,
2046 NET_TRANSPORT_RPC,
2047 N_("Set a new registry value"),
2048 N_("net rpc registry setvalue\n"
2049 " Set a new registry value")
2052 "deletevalue",
2053 rpc_registry_deletevalue,
2054 NET_TRANSPORT_RPC,
2055 N_("Delete a registry value"),
2056 N_("net rpc registry deletevalue\n"
2057 " Delete a registry value")
2060 "save",
2061 rpc_registry_save,
2062 NET_TRANSPORT_RPC,
2063 N_("Save a registry file"),
2064 N_("net rpc registry save\n"
2065 " Save a registry file")
2068 "dump",
2069 rpc_registry_dump,
2070 NET_TRANSPORT_RPC,
2071 N_("Dump a registry file"),
2072 N_("net rpc registry dump\n"
2073 " Dump a registry file")
2076 "copy",
2077 rpc_registry_copy,
2078 NET_TRANSPORT_RPC,
2079 N_("Copy a registry file"),
2080 N_("net rpc registry copy\n"
2081 " Copy a registry file")
2084 "getsd",
2085 rpc_registry_getsd,
2086 NET_TRANSPORT_RPC,
2087 N_("Get security descriptor"),
2088 N_("net rpc registry getsd\n"
2089 " Get security descriptior")
2092 "import",
2093 rpc_registry_import,
2094 NET_TRANSPORT_RPC,
2095 N_("Import .reg file"),
2096 N_("net rpc registry import\n"
2097 " Import .reg file")
2100 "export",
2101 rpc_registry_export,
2102 NET_TRANSPORT_RPC,
2103 N_("Export .reg file"),
2104 N_("net rpc registry export\n"
2105 " Export .reg file")
2107 {NULL, NULL, 0, NULL, NULL}
2109 return net_run_function(c, argc, argv, "net rpc registry", func);