printing: explicitly clear PUBLISHED attribute
[Samba.git] / source3 / utils / net_rpc_registry.c
blobdde129f8ac0bc5a42e59a0b111fe512f673c593f
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.syntax_id, 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.syntax_id, 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.syntax_id, 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.syntax_id, 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.syntax_id, 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.syntax_id, 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.syntax_id, 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 cli->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 cli->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.syntax_id, 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 pull_reg_sz(talloc_tos(), &blob, &data_str);
1187 if (!data_str) {
1188 break;
1190 d_printf( "%s", data_str );
1191 break;
1192 case REG_MULTI_SZ:
1193 case REG_EXPAND_SZ:
1194 for ( j=0; j<data_size; j++ ) {
1195 d_printf( "%c", nk->values[i].data[j] );
1197 break;
1198 case REG_DWORD:
1199 data = IVAL( nk->values[i].data, 0 );
1200 d_printf("0x%x", data );
1201 break;
1202 case REG_BINARY:
1203 for ( j=0; j<data_size; j++ ) {
1204 d_printf( "%x", nk->values[i].data[j] );
1206 break;
1207 default:
1208 d_printf(_("unknown"));
1209 break;
1212 d_printf( "\n" );
1217 /********************************************************************
1218 ********************************************************************/
1220 static bool dump_registry_tree( REGF_FILE *file, REGF_NK_REC *nk, const char *parent )
1222 REGF_NK_REC *key;
1224 /* depth first dump of the registry tree */
1226 while ( (key = regfio_fetch_subkey( file, nk )) ) {
1227 char *regpath;
1228 if (asprintf(&regpath, "%s\\%s", parent, key->keyname) < 0) {
1229 break;
1231 d_printf("[%s]\n", regpath );
1232 dump_values( key );
1233 d_printf("\n");
1234 dump_registry_tree( file, key, regpath );
1235 SAFE_FREE(regpath);
1238 return true;
1241 /********************************************************************
1242 ********************************************************************/
1244 static bool write_registry_tree( REGF_FILE *infile, REGF_NK_REC *nk,
1245 REGF_NK_REC *parent, REGF_FILE *outfile,
1246 const char *parentpath )
1248 REGF_NK_REC *key, *subkey;
1249 struct regval_ctr *values = NULL;
1250 struct regsubkey_ctr *subkeys = NULL;
1251 int i;
1252 char *path = NULL;
1253 WERROR werr;
1255 werr = regsubkey_ctr_init(infile->mem_ctx, &subkeys);
1256 if (!W_ERROR_IS_OK(werr)) {
1257 DEBUG(0, ("write_registry_tree: regsubkey_ctr_init failed: "
1258 "%s\n", win_errstr(werr)));
1259 return false;
1262 werr = regval_ctr_init(subkeys, &values);
1263 if (!W_ERROR_IS_OK(werr)) {
1264 DEBUG(0,("write_registry_tree: talloc() failed!\n"));
1265 TALLOC_FREE(subkeys);
1266 return false;
1269 /* copy values into the struct regval_ctr */
1271 for ( i=0; i<nk->num_values; i++ ) {
1272 regval_ctr_addvalue( values, nk->values[i].valuename, nk->values[i].type,
1273 nk->values[i].data, (nk->values[i].data_size & ~VK_DATA_IN_OFFSET) );
1276 /* copy subkeys into the struct regsubkey_ctr */
1278 while ( (subkey = regfio_fetch_subkey( infile, nk )) ) {
1279 regsubkey_ctr_addkey( subkeys, subkey->keyname );
1282 key = regfio_write_key( outfile, nk->keyname, values, subkeys, nk->sec_desc->sec_desc, parent );
1284 /* write each one of the subkeys out */
1286 path = talloc_asprintf(subkeys,
1287 "%s%s%s",
1288 parentpath,
1289 parent ? "\\" : "",
1290 nk->keyname);
1291 if (!path) {
1292 TALLOC_FREE(subkeys);
1293 return false;
1296 nk->subkey_index = 0;
1297 while ( (subkey = regfio_fetch_subkey( infile, nk )) ) {
1298 write_registry_tree( infile, subkey, key, outfile, path );
1301 d_printf("[%s]\n", path );
1302 TALLOC_FREE(subkeys);
1304 return true;
1307 /********************************************************************
1308 ********************************************************************/
1310 static int rpc_registry_dump(struct net_context *c, int argc, const char **argv)
1312 REGF_FILE *registry;
1313 REGF_NK_REC *nk;
1315 if (argc != 1 || c->display_usage) {
1316 d_printf("%s\n%s",
1317 _("Usage:"),
1318 _("net rpc registry dump <file> \n"));
1319 return -1;
1322 d_printf(_("Opening %s...."), argv[0]);
1323 if ( !(registry = regfio_open( argv[0], O_RDONLY, 0)) ) {
1324 d_fprintf(stderr, _("Failed to open %s for reading\n"),argv[0]);
1325 return 1;
1327 d_printf(_("ok\n"));
1329 /* get the root of the registry file */
1331 if ((nk = regfio_rootkey( registry )) == NULL) {
1332 d_fprintf(stderr, _("Could not get rootkey\n"));
1333 regfio_close( registry );
1334 return 1;
1336 d_printf("[%s]\n", nk->keyname);
1337 dump_values( nk );
1338 d_printf("\n");
1340 dump_registry_tree( registry, nk, nk->keyname );
1342 #if 0
1343 talloc_report_full( registry->mem_ctx, stderr );
1344 #endif
1345 d_printf(_("Closing registry..."));
1346 regfio_close( registry );
1347 d_printf(_("ok\n"));
1349 return 0;
1352 /********************************************************************
1353 ********************************************************************/
1355 static int rpc_registry_copy(struct net_context *c, int argc, const char **argv )
1357 REGF_FILE *infile = NULL, *outfile = NULL;
1358 REGF_NK_REC *nk;
1359 int result = 1;
1361 if (argc != 2 || c->display_usage) {
1362 d_printf("%s\n%s",
1363 _("Usage:"),
1364 _("net rpc registry copy <srcfile> <newfile>\n"));
1365 return -1;
1368 d_printf(_("Opening %s...."), argv[0]);
1369 if ( !(infile = regfio_open( argv[0], O_RDONLY, 0 )) ) {
1370 d_fprintf(stderr, _("Failed to open %s for reading\n"),argv[0]);
1371 return 1;
1373 d_printf(_("ok\n"));
1375 d_printf(_("Opening %s...."), argv[1]);
1376 if ( !(outfile = regfio_open( argv[1], (O_RDWR|O_CREAT|O_TRUNC),
1377 (S_IRUSR|S_IWUSR) )) ) {
1378 d_fprintf(stderr, _("Failed to open %s for writing\n"),argv[1]);
1379 goto out;
1381 d_printf(_("ok\n"));
1383 /* get the root of the registry file */
1385 if ((nk = regfio_rootkey( infile )) == NULL) {
1386 d_fprintf(stderr, _("Could not get rootkey\n"));
1387 goto out;
1389 d_printf(_("RootKey: [%s]\n"), nk->keyname);
1391 write_registry_tree( infile, nk, NULL, outfile, "" );
1393 result = 0;
1395 out:
1397 d_printf(_("Closing %s..."), argv[1]);
1398 if (outfile) {
1399 regfio_close( outfile );
1401 d_printf(_("ok\n"));
1403 d_printf(_("Closing %s..."), argv[0]);
1404 if (infile) {
1405 regfio_close( infile );
1407 d_printf(_("ok\n"));
1409 return( result);
1412 /********************************************************************
1413 ********************************************************************/
1415 static NTSTATUS rpc_registry_getsd_internal(struct net_context *c,
1416 const struct dom_sid *domain_sid,
1417 const char *domain_name,
1418 struct cli_state *cli,
1419 struct rpc_pipe_client *pipe_hnd,
1420 TALLOC_CTX *mem_ctx,
1421 int argc,
1422 const char **argv)
1424 struct policy_handle pol_hive, pol_key;
1425 NTSTATUS status;
1426 WERROR werr;
1427 enum ndr_err_code ndr_err;
1428 struct KeySecurityData *sd = NULL;
1429 uint32_t sec_info;
1430 DATA_BLOB blob;
1431 struct security_descriptor sec_desc;
1432 uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED |
1433 SEC_FLAG_SYSTEM_SECURITY;
1434 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
1436 if (argc <1 || argc > 2 || c->display_usage) {
1437 d_printf("%s\n%s",
1438 _("Usage:"),
1439 _("net rpc registry getsd <path> <secinfo>\n"));
1440 d_printf("%s net rpc registry getsd "
1441 "'HKLM\\Software\\Samba'\n", _("Example:"));
1442 return NT_STATUS_INVALID_PARAMETER;
1445 status = registry_openkey(mem_ctx, pipe_hnd, argv[0],
1446 access_mask,
1447 &pol_hive, &pol_key);
1448 if (!NT_STATUS_IS_OK(status)) {
1449 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
1450 nt_errstr(status));
1451 return status;
1454 sd = TALLOC_ZERO_P(mem_ctx, struct KeySecurityData);
1455 if (!sd) {
1456 status = NT_STATUS_NO_MEMORY;
1457 goto out;
1460 sd->size = 0x1000;
1462 if (argc >= 2) {
1463 sscanf(argv[1], "%x", &sec_info);
1464 } else {
1465 sec_info = SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL;
1468 status = registry_getsd(mem_ctx, b, &pol_key, sec_info, sd, &werr);
1469 if (!NT_STATUS_IS_OK(status)) {
1470 d_fprintf(stderr, _("getting sd failed: %s\n"),
1471 nt_errstr(status));
1472 goto out;
1474 if (!W_ERROR_IS_OK(werr)) {
1475 status = werror_to_ntstatus(werr);
1476 d_fprintf(stderr, _("getting sd failed: %s\n"),
1477 win_errstr(werr));
1478 goto out;
1481 blob.data = sd->data;
1482 blob.length = sd->size;
1484 ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &sec_desc,
1485 (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
1486 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1487 status = ndr_map_error2ntstatus(ndr_err);
1488 goto out;
1490 status = NT_STATUS_OK;
1492 display_sec_desc(&sec_desc);
1494 out:
1495 dcerpc_winreg_CloseKey(b, mem_ctx, &pol_key, &werr);
1496 dcerpc_winreg_CloseKey(b, mem_ctx, &pol_hive, &werr);
1498 return status;
1502 static int rpc_registry_getsd(struct net_context *c, int argc, const char **argv)
1504 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
1505 rpc_registry_getsd_internal, argc, argv);
1508 /********************************************************************
1509 ********************************************************************/
1511 * @defgroup net_rpc_registry net rpc registry
1515 * @defgroup net_rpc_registry_export Export
1516 * @ingroup net_rpc_registry
1517 * @{
1520 static NTSTATUS registry_export(struct rpc_pipe_client* pipe_hnd,
1521 TALLOC_CTX* ctx,
1522 struct policy_handle* key_hnd,
1523 struct reg_format* f,
1524 const char* parentfullname,
1525 const char* name)
1527 NTSTATUS status;
1528 uint32 num_subkeys = 0;
1529 uint32 num_values = 0;
1530 char **names = NULL, **classes = NULL;
1531 NTTIME **modtimes = NULL;
1532 struct regval_blob **values = NULL;
1533 uint32 i;
1534 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
1536 TALLOC_CTX* mem_ctx = talloc_new(ctx);
1539 const char* fullname = name
1540 ? talloc_asprintf(mem_ctx, "%s\\%s", parentfullname, name)
1541 : parentfullname;
1542 reg_format_key(f, &fullname, 1, false);
1544 status = registry_enumvalues2(mem_ctx, pipe_hnd, key_hnd, &num_values,
1545 &names, &values);
1546 if (!NT_STATUS_IS_OK(status)) {
1547 d_fprintf(stderr, _("enumerating values failed: %s\n"),
1548 nt_errstr(status));
1549 goto done;
1552 for (i=0; i<num_values; i++) {
1553 reg_format_regval_blob(f, names[i], values[i]);
1557 status = registry_enumkeys(mem_ctx, pipe_hnd, key_hnd, &num_subkeys,
1558 &names, &classes, &modtimes);
1559 if (!NT_STATUS_IS_OK(status)) {
1560 d_fprintf(stderr, _("enumerating keys failed: %s\n"),
1561 nt_errstr(status));
1562 goto done;
1565 for (i=0; i<num_subkeys; i++) {
1566 struct policy_handle subkey_hnd;
1567 struct winreg_String key;
1568 WERROR werr;
1569 ZERO_STRUCT(key);
1570 /* key.name = talloc_strdup(mem_ctx, names[i]); ??? */
1571 key.name = names[i];
1573 status = dcerpc_winreg_OpenKey(b, mem_ctx, key_hnd, key,
1574 0, REG_KEY_READ,
1575 &subkey_hnd, &werr);
1576 if (!NT_STATUS_IS_OK(status)) {
1577 d_fprintf(stderr,
1578 _("dcerpc_winreg_OpenKey failed: %s %s\n"),
1579 names[i], nt_errstr(status));
1580 continue;
1582 if (!W_ERROR_IS_OK(werr)) {
1583 status = werror_to_ntstatus(werr);
1584 d_fprintf(stderr,
1585 _("dcerpc_winreg_OpenKey failed: %s %s\n"),
1586 names[i], win_errstr(werr));
1587 continue;
1590 status = registry_export(pipe_hnd, mem_ctx, &subkey_hnd,
1591 f, fullname, names[i]);
1592 if (!(NT_STATUS_IS_OK(status))) {
1593 d_fprintf(stderr,
1594 _("export key failed: %s %s\n"),
1595 names[i], nt_errstr(status));
1597 dcerpc_winreg_CloseKey(b, mem_ctx,
1598 &subkey_hnd, &werr);
1600 done:
1601 talloc_free(mem_ctx);
1602 return status;
1605 static NTSTATUS rpc_registry_export_internal(struct net_context *c,
1606 const struct dom_sid *domain_sid,
1607 const char *domain_name,
1608 struct cli_state *cli,
1609 struct rpc_pipe_client *pipe_hnd,
1610 TALLOC_CTX *mem_ctx,
1611 int argc,
1612 const char **argv )
1614 struct policy_handle pol_hive, pol_key;
1615 NTSTATUS status;
1616 WERROR werr;
1617 struct reg_format* f;
1618 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
1620 if (argc < 2 || argc > 3 || c->display_usage) {
1621 d_printf("%s\n%s",
1622 _("Usage:"),
1623 _("net rpc registry export <path> <file> [opt]\n"));
1624 d_printf("%s net rpc registry export "
1625 "'HKLM\\Software\\Samba' samba.reg\n", _("Example:"));
1626 return NT_STATUS_INVALID_PARAMETER;
1629 status = registry_openkey(mem_ctx, pipe_hnd, argv[0], REG_KEY_READ,
1630 &pol_hive, &pol_key);
1631 if (!NT_STATUS_IS_OK(status)) {
1632 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
1633 nt_errstr(status));
1634 return status;
1637 f = reg_format_file(mem_ctx, argv[1], (argc > 2) ? argv[2] : NULL);
1638 if (f == NULL) {
1639 d_fprintf(stderr, _("open file failed: %s\n"), strerror(errno));
1640 return map_nt_error_from_unix(errno);
1643 status = registry_export(pipe_hnd, mem_ctx, &pol_key,
1644 f, argv[0], NULL );
1645 if (!NT_STATUS_IS_OK(status))
1646 return status;
1648 dcerpc_winreg_CloseKey(b, mem_ctx, &pol_key, &werr);
1649 dcerpc_winreg_CloseKey(b, mem_ctx, &pol_hive, &werr);
1651 return status;
1653 /********************************************************************
1654 ********************************************************************/
1656 static int rpc_registry_export(struct net_context *c, int argc,
1657 const char **argv )
1659 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
1660 rpc_registry_export_internal, argc, argv );
1663 /**@}*/
1665 /********************************************************************
1666 ********************************************************************/
1669 * @defgroup net_rpc_registry_import Import
1670 * @ingroup net_rpc_registry
1671 * @{
1674 struct import_ctx {
1675 struct rpc_pipe_client *pipe_hnd;
1676 TALLOC_CTX *mem_ctx;
1679 static WERROR import_create_key(struct import_ctx* ctx,
1680 struct policy_handle* parent, const char* name,
1681 void** pkey, bool* existing)
1683 WERROR werr;
1684 NTSTATUS status;
1685 void* mem_ctx = talloc_new(ctx->mem_ctx);
1687 struct policy_handle* key = NULL;
1688 struct policy_handle hive;
1689 struct winreg_String keyclass, keyname;
1690 enum winreg_CreateAction action = REG_ACTION_NONE;
1691 struct dcerpc_binding_handle *b = ctx->pipe_hnd->binding_handle;
1693 ZERO_STRUCT(keyname);
1694 keyname.name = name;
1696 if (parent == NULL) {
1697 uint32 hive_idx = 0;
1698 if (!reg_hive_key(mem_ctx, name, &hive_idx, &keyname.name)) {
1699 werr = WERR_FOOBAR;
1700 goto done;
1703 status = dcerpc_winreg_Connect(b, mem_ctx,
1704 hive_idx, SEC_FLAG_MAXIMUM_ALLOWED,
1705 &hive, &werr);
1706 if (!NT_STATUS_IS_OK(status)) {
1707 werr = ntstatus_to_werror(status);
1708 d_fprintf(stderr, _("dcerpc_winreg_Connect returned %s\n"),
1709 nt_errstr(status));
1710 goto done;
1712 if (!W_ERROR_IS_OK(werr)) {
1713 d_fprintf(stderr, _("dcerpc_winreg_Connect returned %s\n"),
1714 win_errstr(werr));
1715 goto done;
1718 parent = &hive;
1721 key = talloc_zero(mem_ctx, struct policy_handle);
1722 if (key == NULL) {
1723 werr = WERR_NOMEM;
1724 goto done;
1727 ZERO_STRUCT(keyclass);
1728 keyclass.name = "";
1730 status = dcerpc_winreg_CreateKey(b, mem_ctx,
1731 parent, keyname,
1732 keyclass, 0, REG_KEY_READ, NULL,
1733 key, &action, &werr);
1734 if (!NT_STATUS_IS_OK(status)) {
1735 werr = ntstatus_to_werror(status);
1736 d_fprintf(stderr, _("dcerpc_winreg_CreateKey returned %s\n"),
1737 nt_errstr(status));
1738 goto done;
1740 if (!W_ERROR_IS_OK(werr)) {
1741 d_fprintf(stderr, _("dcerpc_winreg_CreateKey returned %s\n"),
1742 win_errstr(werr));
1743 goto done;
1746 switch (action) {
1747 case REG_CREATED_NEW_KEY:
1748 d_printf(_("createkey created %s\n"), name);
1749 if (existing != NULL)
1750 *existing = false;
1751 break;
1753 case REG_OPENED_EXISTING_KEY:
1754 d_printf(_("createkey opened existing %s\n"), name);
1755 if (existing != NULL)
1756 *existing = true;
1757 break;
1759 case REG_ACTION_NONE:
1760 d_printf(_("createkey did nothing -- huh?\n"));
1761 werr = WERR_CREATE_FAILED;
1762 break;
1763 default:
1764 assert(false);
1767 done:
1768 if ( parent == &hive ) {
1769 WERROR _result;
1770 dcerpc_winreg_CloseKey(b, mem_ctx,
1771 parent, &_result);
1774 if (pkey!=NULL) {
1775 *pkey = talloc_steal(ctx->mem_ctx, key);
1778 talloc_free(mem_ctx);
1779 return werr;
1782 static WERROR import_delete_key(struct import_ctx* ctx,
1783 struct policy_handle* parent, const char* name)
1785 WERROR werr;
1786 NTSTATUS status;
1787 void* mem_ctx = talloc_new(ctx->mem_ctx);
1788 struct winreg_String keyname = { 0, };
1789 struct policy_handle hive;
1790 struct dcerpc_binding_handle *b = ctx->pipe_hnd->binding_handle;
1792 keyname.name = name;
1794 if (parent == NULL) {
1795 uint32 hive_idx;
1796 if (!reg_hive_key(mem_ctx, name, &hive_idx, &keyname.name)) {
1797 werr = WERR_FOOBAR;
1798 goto done;
1801 status = dcerpc_winreg_Connect(b, mem_ctx, hive_idx,
1802 SEC_FLAG_MAXIMUM_ALLOWED, &hive,
1803 &werr);
1804 if (!NT_STATUS_IS_OK(status)) {
1805 werr = ntstatus_to_werror(status);
1806 d_fprintf(stderr, _("dcerpc_winreg_Connect returned %s\n"),
1807 nt_errstr(status));
1808 goto done;
1810 if (!W_ERROR_IS_OK(werr)) {
1811 d_fprintf(stderr, _("dcerpc_winreg_Connect returned %s\n"),
1812 win_errstr(werr));
1813 goto done;
1816 parent = &hive;
1819 status = dcerpc_winreg_DeleteKey(b, mem_ctx, parent,
1820 keyname, &werr);
1821 if (!NT_STATUS_IS_OK(status)) {
1822 werr = ntstatus_to_werror(status);
1823 d_fprintf(stderr, _("dcerpc_winreg_DeleteKey returned %s\n"),
1824 nt_errstr(status));
1825 goto done;
1827 if (!W_ERROR_IS_OK(werr)) {
1828 d_fprintf(stderr, _("dcerpc_winreg_DeleteKey returned %s\n"),
1829 win_errstr(werr));
1830 goto done;
1833 done:
1834 if ( parent == &hive ) {
1835 WERROR _result;
1836 dcerpc_winreg_CloseKey(b, mem_ctx, parent, &_result);
1839 talloc_free(mem_ctx);
1840 return werr;
1843 static WERROR import_close_key(struct import_ctx* ctx,
1844 struct policy_handle* key)
1846 WERROR werr;
1847 NTSTATUS status;
1848 void* mem_ctx = talloc_new(ctx->mem_ctx);
1849 struct dcerpc_binding_handle *b = ctx->pipe_hnd->binding_handle;
1851 status = dcerpc_winreg_CloseKey(b, mem_ctx, key, &werr);
1852 if (!NT_STATUS_IS_OK(status)) {
1853 werr = ntstatus_to_werror(status);
1854 d_fprintf(stderr, _("dcerpc_winreg_CloseKey returned %s\n"),
1855 nt_errstr(status));
1856 goto done;
1858 if (!W_ERROR_IS_OK(werr)) {
1859 d_fprintf(stderr, _("dcerpc_winreg_CloseKey returned %s\n"),
1860 win_errstr(werr));
1861 goto done;
1864 werr = (talloc_free(key) == 0) ? WERR_OK : WERR_GENERAL_FAILURE;
1865 done:
1866 talloc_free(mem_ctx);
1867 return werr;
1870 static WERROR import_create_val(struct import_ctx* ctx,
1871 struct policy_handle* parent, const char* name,
1872 uint32_t type, const uint8_t* val, uint32_t len)
1874 WERROR werr;
1875 NTSTATUS status;
1876 void* mem_ctx = talloc_new(ctx->mem_ctx);
1877 struct winreg_String valuename;
1878 struct dcerpc_binding_handle *b = ctx->pipe_hnd->binding_handle;
1880 if (parent == NULL) {
1881 return WERR_INVALID_PARAM;
1884 ZERO_STRUCT(valuename);
1885 valuename.name = name;
1887 status = dcerpc_winreg_SetValue(b, mem_ctx, parent,
1888 valuename, type,
1889 (uint8_t *)discard_const(val), len, &werr);
1890 if (!NT_STATUS_IS_OK(status)) {
1891 werr = ntstatus_to_werror(status);
1892 d_fprintf(stderr, _("registry_setvalue failed: %s\n"),
1893 nt_errstr(status));
1894 goto done;
1896 if (!W_ERROR_IS_OK(werr)) {
1897 d_fprintf(stderr, _("registry_setvalue failed: %s\n"),
1898 win_errstr(werr));
1899 goto done;
1902 done:
1903 talloc_free(mem_ctx);
1904 return werr;
1907 static WERROR import_delete_val(struct import_ctx* ctx,
1908 struct policy_handle* parent, const char* name)
1910 WERROR werr;
1911 NTSTATUS status;
1912 void* mem_ctx = talloc_new(ctx->mem_ctx);
1913 struct winreg_String valuename;
1914 struct dcerpc_binding_handle *b = ctx->pipe_hnd->binding_handle;
1916 if (parent == NULL) {
1917 return WERR_INVALID_PARAM;
1920 ZERO_STRUCT(valuename);
1921 valuename.name = name;
1923 status = dcerpc_winreg_DeleteValue(b, mem_ctx,
1924 parent, valuename, &werr);
1926 if (!NT_STATUS_IS_OK(status)) {
1927 werr = ntstatus_to_werror(status);
1928 d_fprintf(stderr, _("registry_deletevalue failed: %s\n"),
1929 nt_errstr(status));
1930 goto done;
1932 if (!NT_STATUS_IS_OK(status)) {
1933 d_fprintf(stderr, _("registry_deletevalue failed: %s\n"),
1934 win_errstr(werr));
1935 goto done;
1938 done:
1939 talloc_free(mem_ctx);
1940 return werr;
1945 static NTSTATUS rpc_registry_import_internal(struct net_context *c,
1946 const struct dom_sid *domain_sid,
1947 const char *domain_name,
1948 struct cli_state *cli,
1949 struct rpc_pipe_client *pipe_hnd,
1950 TALLOC_CTX *mem_ctx,
1951 int argc,
1952 const char **argv )
1954 struct import_ctx import_ctx;
1956 struct reg_import_callback import_callback = {
1957 .openkey = NULL,
1958 .closekey = (reg_import_callback_closekey_t)&import_close_key,
1959 .createkey = (reg_import_callback_createkey_t)&import_create_key,
1960 .deletekey = (reg_import_callback_deletekey_t)&import_delete_key,
1961 .deleteval = (reg_import_callback_deleteval_t)&import_delete_val,
1962 .setval = {
1963 .blob = (reg_import_callback_setval_blob_t)&import_create_val,
1965 .setval_type = BLOB,
1966 .data = &import_ctx
1969 int ret;
1970 if (argc < 1 || argc > 2 || c->display_usage) {
1971 d_printf("%s\n%s",
1972 _("Usage:"),
1973 _("net rpc registry import <file> [options]\n"));
1974 d_printf("%s net rpc registry export "
1975 "samba.reg enc=CP1252,flags=0\n", _("Example:"));
1976 return NT_STATUS_INVALID_PARAMETER;
1978 ZERO_STRUCT(import_ctx);
1979 import_ctx.pipe_hnd = pipe_hnd;
1980 import_ctx.mem_ctx = mem_ctx;
1981 ret = reg_parse_file(argv[0],
1982 reg_import_adapter(import_ctx.mem_ctx,
1983 import_callback
1985 (argc > 1) ? argv[1] : NULL
1988 return ret==0 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1991 /********************************************************************
1992 ********************************************************************/
1994 static int rpc_registry_import(struct net_context *c, int argc,
1995 const char **argv )
1997 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
1998 rpc_registry_import_internal, argc, argv );
2001 /**@}*/
2002 /********************************************************************
2003 ********************************************************************/
2005 int net_rpc_registry(struct net_context *c, int argc, const char **argv)
2007 struct functable func[] = {
2009 "enumerate",
2010 rpc_registry_enumerate,
2011 NET_TRANSPORT_RPC,
2012 N_("Enumerate registry keys and values"),
2013 N_("net rpc registry enumerate\n"
2014 " Enumerate registry keys and values")
2017 "createkey",
2018 rpc_registry_createkey,
2019 NET_TRANSPORT_RPC,
2020 N_("Create a new registry key"),
2021 N_("net rpc registry createkey\n"
2022 " Create a new registry key")
2025 "deletekey",
2026 rpc_registry_deletekey,
2027 NET_TRANSPORT_RPC,
2028 N_("Delete a registry key"),
2029 N_("net rpc registry deletekey\n"
2030 " Delete a registry key")
2033 "getvalue",
2034 rpc_registry_getvalue,
2035 NET_TRANSPORT_RPC,
2036 N_("Print a registry value"),
2037 N_("net rpc registry getvalue\n"
2038 " Print a registry value")
2041 "getvalueraw",
2042 rpc_registry_getvalueraw,
2043 NET_TRANSPORT_RPC,
2044 N_("Print a registry value"),
2045 N_("net rpc registry getvalueraw\n"
2046 " Print a registry value (raw version)")
2049 "setvalue",
2050 rpc_registry_setvalue,
2051 NET_TRANSPORT_RPC,
2052 N_("Set a new registry value"),
2053 N_("net rpc registry setvalue\n"
2054 " Set a new registry value")
2057 "deletevalue",
2058 rpc_registry_deletevalue,
2059 NET_TRANSPORT_RPC,
2060 N_("Delete a registry value"),
2061 N_("net rpc registry deletevalue\n"
2062 " Delete a registry value")
2065 "save",
2066 rpc_registry_save,
2067 NET_TRANSPORT_RPC,
2068 N_("Save a registry file"),
2069 N_("net rpc registry save\n"
2070 " Save a registry file")
2073 "dump",
2074 rpc_registry_dump,
2075 NET_TRANSPORT_RPC,
2076 N_("Dump a registry file"),
2077 N_("net rpc registry dump\n"
2078 " Dump a registry file")
2081 "copy",
2082 rpc_registry_copy,
2083 NET_TRANSPORT_RPC,
2084 N_("Copy a registry file"),
2085 N_("net rpc registry copy\n"
2086 " Copy a registry file")
2089 "getsd",
2090 rpc_registry_getsd,
2091 NET_TRANSPORT_RPC,
2092 N_("Get security descriptor"),
2093 N_("net rpc registry getsd\n"
2094 " Get security descriptior")
2097 "import",
2098 rpc_registry_import,
2099 NET_TRANSPORT_RPC,
2100 N_("Import .reg file"),
2101 N_("net rpc registry import\n"
2102 " Import .reg file")
2105 "export",
2106 rpc_registry_export,
2107 NET_TRANSPORT_RPC,
2108 N_("Export .reg file"),
2109 N_("net rpc registry export\n"
2110 " Export .reg file")
2112 {NULL, NULL, 0, NULL, NULL}
2114 return net_run_function(c, argc, argv, "net rpc registry", func);