smbd: avoid a panic in close_directory()
[samba4-gss.git] / source3 / utils / net_rpc_registry.c
blobcec545902c76ade881226bad317a89cb16a2b55b
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"
35 #include "lib/util/smb_strtox.h"
38 /*******************************************************************
39 connect to a registry hive root (open a registry policy)
40 *******************************************************************/
42 static NTSTATUS dcerpc_winreg_Connect(struct dcerpc_binding_handle *b, TALLOC_CTX *mem_ctx,
43 uint32_t reg_type, uint32_t access_mask,
44 struct policy_handle *reg_hnd, WERROR *werr)
46 ZERO_STRUCTP(reg_hnd);
48 switch (reg_type)
50 case HKEY_CLASSES_ROOT:
51 return dcerpc_winreg_OpenHKCR(b, mem_ctx, NULL,
52 access_mask, reg_hnd, werr);
54 case HKEY_LOCAL_MACHINE:
55 return dcerpc_winreg_OpenHKLM(b, mem_ctx, NULL,
56 access_mask, reg_hnd, werr);
58 case HKEY_USERS:
59 return dcerpc_winreg_OpenHKU(b, mem_ctx, NULL,
60 access_mask, reg_hnd, werr);
62 case HKEY_CURRENT_USER:
63 return dcerpc_winreg_OpenHKCU(b, mem_ctx, NULL,
64 access_mask, reg_hnd, werr);
66 case HKEY_PERFORMANCE_DATA:
67 return dcerpc_winreg_OpenHKPD(b, mem_ctx, NULL,
68 access_mask, reg_hnd, werr);
70 default:
71 /* fall through to end of function */
72 break;
75 return NT_STATUS_INVALID_PARAMETER;
78 static bool reg_hive_key(TALLOC_CTX *ctx, const char *fullname,
79 uint32_t *reg_type, const char **key_name)
81 WERROR werr;
82 char *hivename = NULL;
83 char *tmp_keyname = NULL;
84 bool ret = false;
85 TALLOC_CTX *tmp_ctx = talloc_stackframe();
87 werr = split_hive_key(tmp_ctx, fullname, &hivename, &tmp_keyname);
88 if (!W_ERROR_IS_OK(werr)) {
89 goto done;
92 *key_name = talloc_strdup(ctx, tmp_keyname);
93 if (*key_name == NULL) {
94 goto done;
97 if (strequal(hivename, "HKLM") ||
98 strequal(hivename, "HKEY_LOCAL_MACHINE"))
100 (*reg_type) = HKEY_LOCAL_MACHINE;
101 } else if (strequal(hivename, "HKCR") ||
102 strequal(hivename, "HKEY_CLASSES_ROOT"))
104 (*reg_type) = HKEY_CLASSES_ROOT;
105 } else if (strequal(hivename, "HKU") ||
106 strequal(hivename, "HKEY_USERS"))
108 (*reg_type) = HKEY_USERS;
109 } else if (strequal(hivename, "HKCU") ||
110 strequal(hivename, "HKEY_CURRENT_USER"))
112 (*reg_type) = HKEY_CURRENT_USER;
113 } else if (strequal(hivename, "HKPD") ||
114 strequal(hivename, "HKEY_PERFORMANCE_DATA"))
116 (*reg_type) = HKEY_PERFORMANCE_DATA;
117 } else {
118 DEBUG(10,("reg_hive_key: unrecognised hive key %s\n",
119 fullname));
120 goto done;
123 ret = true;
125 done:
126 TALLOC_FREE(tmp_ctx);
127 return ret;
130 static NTSTATUS registry_openkey(TALLOC_CTX *mem_ctx,
131 struct rpc_pipe_client *pipe_hnd,
132 const char *name, uint32_t access_mask,
133 struct policy_handle *hive_hnd,
134 struct policy_handle *key_hnd)
136 uint32_t hive;
137 NTSTATUS status;
138 WERROR werr;
139 struct winreg_String key;
140 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
142 ZERO_STRUCT(key);
144 if (!reg_hive_key(mem_ctx, name, &hive, &key.name)) {
145 return NT_STATUS_INVALID_PARAMETER;
148 status = dcerpc_winreg_Connect(b, mem_ctx, hive, access_mask,
149 hive_hnd, &werr);
150 if (!(NT_STATUS_IS_OK(status))) {
151 return status;
153 if (!W_ERROR_IS_OK(werr)) {
154 return werror_to_ntstatus(werr);
157 status = dcerpc_winreg_OpenKey(b, mem_ctx, hive_hnd, key, 0,
158 access_mask, key_hnd, &werr);
159 if (!(NT_STATUS_IS_OK(status))) {
160 dcerpc_winreg_CloseKey(b, mem_ctx, hive_hnd, &werr);
161 return status;
163 if (!(W_ERROR_IS_OK(werr))) {
164 WERROR _werr;
165 dcerpc_winreg_CloseKey(b, mem_ctx, hive_hnd, &_werr);
166 return werror_to_ntstatus(werr);
169 return NT_STATUS_OK;
172 static NTSTATUS registry_enumkeys(TALLOC_CTX *ctx,
173 struct rpc_pipe_client *pipe_hnd,
174 struct policy_handle *key_hnd,
175 uint32_t *pnum_keys, char ***pnames,
176 char ***pclasses, NTTIME ***pmodtimes)
178 TALLOC_CTX *mem_ctx;
179 NTSTATUS status;
180 WERROR werr;
181 uint32_t num_subkeys, max_subkeylen, max_classlen;
182 uint32_t num_values, max_valnamelen, max_valbufsize;
183 uint32_t i;
184 NTTIME last_changed_time;
185 uint32_t secdescsize;
186 struct winreg_String classname;
187 char **names, **classes;
188 NTTIME **modtimes;
189 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
191 if (!(mem_ctx = talloc_new(ctx))) {
192 return NT_STATUS_NO_MEMORY;
195 ZERO_STRUCT(classname);
196 status = dcerpc_winreg_QueryInfoKey(
197 b, mem_ctx, key_hnd, &classname, &num_subkeys,
198 &max_subkeylen, &max_classlen, &num_values, &max_valnamelen,
199 &max_valbufsize, &secdescsize, &last_changed_time, &werr);
201 if (!NT_STATUS_IS_OK(status)) {
202 goto error;
204 if (!W_ERROR_IS_OK(werr)) {
205 status = werror_to_ntstatus(werr);
206 goto error;
209 if (num_subkeys == 0) {
210 *pnum_keys = 0;
211 TALLOC_FREE(mem_ctx);
212 return NT_STATUS_OK;
215 if ((!(names = talloc_zero_array(mem_ctx, char *, num_subkeys))) ||
216 (!(classes = talloc_zero_array(mem_ctx, char *, num_subkeys))) ||
217 (!(modtimes = talloc_zero_array(mem_ctx, NTTIME *,
218 num_subkeys)))) {
219 status = NT_STATUS_NO_MEMORY;
220 goto error;
223 for (i=0; i<num_subkeys; i++) {
224 char c, n;
225 struct winreg_StringBuf class_buf;
226 struct winreg_StringBuf name_buf;
227 NTTIME modtime;
229 c = '\0';
230 class_buf.name = &c;
231 class_buf.size = max_classlen+2;
233 n = '\0';
234 name_buf.name = &n;
235 name_buf.size = max_subkeylen+2;
237 ZERO_STRUCT(modtime);
239 status = dcerpc_winreg_EnumKey(b, mem_ctx, key_hnd,
240 i, &name_buf, &class_buf,
241 &modtime, &werr);
242 if (!NT_STATUS_IS_OK(status)) {
243 goto error;
245 if (W_ERROR_EQUAL(werr,
246 WERR_NO_MORE_ITEMS) ) {
247 status = NT_STATUS_OK;
248 break;
250 if (!W_ERROR_IS_OK(werr)) {
251 status = werror_to_ntstatus(werr);
252 goto error;
255 classes[i] = NULL;
257 if (class_buf.name &&
258 (!(classes[i] = talloc_strdup(classes, class_buf.name)))) {
259 status = NT_STATUS_NO_MEMORY;
260 goto error;
263 if (!(names[i] = talloc_strdup(names, name_buf.name))) {
264 status = NT_STATUS_NO_MEMORY;
265 goto error;
268 if ((!(modtimes[i] = (NTTIME *)talloc_memdup(
269 modtimes, &modtime, sizeof(modtime))))) {
270 status = NT_STATUS_NO_MEMORY;
271 goto error;
275 *pnum_keys = num_subkeys;
277 if (pnames) {
278 *pnames = talloc_move(ctx, &names);
280 if (pclasses) {
281 *pclasses = talloc_move(ctx, &classes);
283 if (pmodtimes) {
284 *pmodtimes = talloc_move(ctx, &modtimes);
287 status = NT_STATUS_OK;
289 error:
290 TALLOC_FREE(mem_ctx);
291 return status;
294 static NTSTATUS registry_enumvalues(TALLOC_CTX *ctx,
295 struct rpc_pipe_client *pipe_hnd,
296 struct policy_handle *key_hnd,
297 uint32_t *pnum_values, char ***pvalnames,
298 struct registry_value ***pvalues)
300 TALLOC_CTX *mem_ctx;
301 NTSTATUS status;
302 WERROR werr;
303 uint32_t num_subkeys, max_subkeylen, max_classlen;
304 uint32_t num_values, max_valnamelen, max_valbufsize;
305 uint32_t i;
306 NTTIME last_changed_time;
307 uint32_t secdescsize;
308 struct winreg_String classname;
309 struct registry_value **values;
310 char **names;
311 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
313 if (!(mem_ctx = talloc_new(ctx))) {
314 return NT_STATUS_NO_MEMORY;
317 ZERO_STRUCT(classname);
318 status = dcerpc_winreg_QueryInfoKey(
319 b, mem_ctx, key_hnd, &classname, &num_subkeys,
320 &max_subkeylen, &max_classlen, &num_values, &max_valnamelen,
321 &max_valbufsize, &secdescsize, &last_changed_time, &werr);
323 if (!NT_STATUS_IS_OK(status)) {
324 goto error;
326 if (!W_ERROR_IS_OK(werr)) {
327 status = werror_to_ntstatus(werr);
328 goto error;
331 if (num_values == 0) {
332 *pnum_values = 0;
333 TALLOC_FREE(mem_ctx);
334 return NT_STATUS_OK;
337 if ((!(names = talloc_array(mem_ctx, char *, num_values))) ||
338 (!(values = talloc_array(mem_ctx, struct registry_value *,
339 num_values)))) {
340 status = NT_STATUS_NO_MEMORY;
341 goto error;
344 for (i=0; i<num_values; i++) {
345 enum winreg_Type type = REG_NONE;
346 uint8_t *data = NULL;
347 uint32_t data_size;
348 uint32_t value_length;
350 char n;
351 struct winreg_ValNameBuf name_buf;
352 WERROR err;
354 n = '\0';
355 name_buf.name = &n;
356 name_buf.size = max_valnamelen + 2;
358 data_size = max_valbufsize;
359 data = (uint8_t *)TALLOC(mem_ctx, data_size);
360 value_length = 0;
362 status = dcerpc_winreg_EnumValue(b, mem_ctx, key_hnd,
363 i, &name_buf, &type,
364 data, &data_size,
365 &value_length, &err);
366 if (!(NT_STATUS_IS_OK(status))) {
367 goto error;
370 if ( W_ERROR_EQUAL(err,
371 WERR_NO_MORE_ITEMS) ) {
372 status = NT_STATUS_OK;
373 break;
376 if (!W_ERROR_IS_OK(err)) {
377 status = werror_to_ntstatus(err);
378 goto error;
381 if (name_buf.name == NULL) {
382 status = NT_STATUS_INVALID_PARAMETER;
383 goto error;
386 if (!(names[i] = talloc_strdup(names, name_buf.name))) {
387 status = NT_STATUS_NO_MEMORY;
388 goto error;
391 values[i] = talloc_zero(values, struct registry_value);
392 if (values[i] == NULL) {
393 status = NT_STATUS_NO_MEMORY;
394 goto error;
397 values[i]->type = type;
398 values[i]->data = data_blob_talloc(values[i], data, data_size);
401 *pnum_values = num_values;
403 if (pvalnames) {
404 *pvalnames = talloc_move(ctx, &names);
406 if (pvalues) {
407 *pvalues = talloc_move(ctx, &values);
410 status = NT_STATUS_OK;
412 error:
413 TALLOC_FREE(mem_ctx);
414 return status;
417 static NTSTATUS registry_enumvalues2(TALLOC_CTX *ctx,
418 struct rpc_pipe_client *pipe_hnd,
419 struct policy_handle *key_hnd,
420 uint32_t *pnum_values, char ***pvalnames,
421 struct regval_blob ***pvalues)
423 TALLOC_CTX *mem_ctx;
424 NTSTATUS status;
425 WERROR werr;
426 uint32_t num_subkeys, max_subkeylen, max_classlen;
427 uint32_t num_values, max_valnamelen, max_valbufsize;
428 uint32_t i;
429 NTTIME last_changed_time;
430 uint32_t secdescsize;
431 struct winreg_String classname;
432 struct regval_blob **values;
433 char **names;
434 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
436 if (!(mem_ctx = talloc_new(ctx))) {
437 return NT_STATUS_NO_MEMORY;
440 ZERO_STRUCT(classname);
441 status = dcerpc_winreg_QueryInfoKey(
442 b, mem_ctx, key_hnd, &classname, &num_subkeys,
443 &max_subkeylen, &max_classlen, &num_values, &max_valnamelen,
444 &max_valbufsize, &secdescsize, &last_changed_time, &werr);
446 if (!NT_STATUS_IS_OK(status)) {
447 goto error;
449 if (!W_ERROR_IS_OK(werr)) {
450 status = werror_to_ntstatus(werr);
451 goto error;
454 if (num_values == 0) {
455 *pnum_values = 0;
456 TALLOC_FREE(mem_ctx);
457 return NT_STATUS_OK;
460 if ((!(names = talloc_array(mem_ctx, char *, num_values))) ||
461 (!(values = talloc_array(mem_ctx, struct regval_blob *,
462 num_values)))) {
463 status = NT_STATUS_NO_MEMORY;
464 goto error;
467 for (i=0; i<num_values; i++) {
468 enum winreg_Type type = REG_NONE;
469 uint8_t *data = NULL;
470 uint32_t data_size;
471 uint32_t value_length;
473 char n;
474 struct winreg_ValNameBuf name_buf;
475 WERROR err;
477 n = '\0';
478 name_buf.name = &n;
479 name_buf.size = max_valnamelen + 2;
481 data_size = max_valbufsize;
482 data = (uint8_t *)TALLOC(mem_ctx, data_size);
483 value_length = 0;
485 status = dcerpc_winreg_EnumValue(b, mem_ctx, key_hnd,
486 i, &name_buf, &type,
487 data, &data_size,
488 &value_length, &err);
489 if (!(NT_STATUS_IS_OK(status))) {
490 goto error;
493 if ( W_ERROR_EQUAL(err, WERR_NO_MORE_ITEMS) ) {
494 status = NT_STATUS_OK;
495 break;
498 if (!W_ERROR_IS_OK(err)) {
499 status = werror_to_ntstatus(err);
500 goto error;
503 if (name_buf.name == NULL) {
504 status = NT_STATUS_INVALID_PARAMETER;
505 goto error;
508 if (!(names[i] = talloc_strdup(names, name_buf.name))) {
509 status = NT_STATUS_NO_MEMORY;
510 goto error;
513 assert(value_length<=data_size); /*??? */
515 values[i] = regval_compose(values,
516 name_buf.name,
517 type,
518 data, value_length);
519 if (!values[i]) {
520 status = NT_STATUS_NO_MEMORY;
521 goto error;
525 *pnum_values = num_values;
527 if (pvalnames) {
528 *pvalnames = talloc_move(ctx, &names);
530 if (pvalues) {
531 *pvalues = talloc_move(ctx, &values);
534 status = NT_STATUS_OK;
536 error:
537 TALLOC_FREE(mem_ctx);
538 return status;
541 static NTSTATUS registry_getsd(TALLOC_CTX *mem_ctx,
542 struct dcerpc_binding_handle *b,
543 struct policy_handle *key_hnd,
544 uint32_t sec_info,
545 struct KeySecurityData *sd,
546 WERROR *werr)
548 return dcerpc_winreg_GetKeySecurity(b, mem_ctx, key_hnd,
549 sec_info, sd, werr);
553 static NTSTATUS registry_setvalue(TALLOC_CTX *mem_ctx,
554 struct rpc_pipe_client *pipe_hnd,
555 struct policy_handle *key_hnd,
556 const char *name,
557 const struct registry_value *value)
559 struct winreg_String name_string;
560 NTSTATUS result;
561 WERROR werr;
562 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
564 ZERO_STRUCT(name_string);
566 name_string.name = name;
567 result = dcerpc_winreg_SetValue(b, mem_ctx, key_hnd,
568 name_string, value->type,
569 value->data.data, value->data.length, &werr);
570 if (!NT_STATUS_IS_OK(result)) {
571 return result;
574 return werror_to_ntstatus(werr);
577 static NTSTATUS rpc_registry_setvalue_internal(struct net_context *c,
578 const struct dom_sid *domain_sid,
579 const char *domain_name,
580 struct cli_state *cli,
581 struct rpc_pipe_client *pipe_hnd,
582 TALLOC_CTX *mem_ctx,
583 int argc,
584 const char **argv )
586 struct policy_handle hive_hnd, key_hnd;
587 NTSTATUS status;
588 WERROR werr;
589 struct registry_value value;
590 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
592 status = registry_openkey(mem_ctx, pipe_hnd, argv[0],
593 SEC_FLAG_MAXIMUM_ALLOWED,
594 &hive_hnd, &key_hnd);
595 if (!NT_STATUS_IS_OK(status)) {
596 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
597 nt_errstr(status));
598 return status;
601 if (!strequal(argv[2], "multi_sz") && (argc != 4)) {
602 d_fprintf(stderr, _("Too many args for type %s\n"), argv[2]);
603 return NT_STATUS_NOT_IMPLEMENTED;
606 if (strequal(argv[2], "dword")) {
607 int error = 0;
608 uint32_t v;
610 v = smb_strtoul(argv[3], NULL, 10, &error, SMB_STR_STANDARD);
611 if (error != 0) {
612 goto error;
615 value.type = REG_DWORD;
616 value.data = data_blob_talloc(mem_ctx, NULL, 4);
617 SIVAL(value.data.data, 0, v);
619 else if (strequal(argv[2], "sz")) {
620 value.type = REG_SZ;
621 if (!push_reg_sz(mem_ctx, &value.data, argv[3])) {
622 status = NT_STATUS_NO_MEMORY;
623 goto error;
626 else {
627 d_fprintf(stderr, _("type \"%s\" not implemented\n"), argv[2]);
628 status = NT_STATUS_NOT_IMPLEMENTED;
629 goto error;
632 status = registry_setvalue(mem_ctx, pipe_hnd, &key_hnd,
633 argv[1], &value);
635 if (!NT_STATUS_IS_OK(status)) {
636 d_fprintf(stderr, _("registry_setvalue failed: %s\n"),
637 nt_errstr(status));
640 error:
641 dcerpc_winreg_CloseKey(b, mem_ctx, &key_hnd, &werr);
642 dcerpc_winreg_CloseKey(b, mem_ctx, &hive_hnd, &werr);
644 return NT_STATUS_OK;
647 static int rpc_registry_setvalue(struct net_context *c, int argc,
648 const char **argv )
650 if (argc < 4 || c->display_usage) {
651 d_fprintf(stderr, "%s\n%s",
652 _("Usage:"),
653 _("net rpc registry setvalue <key> <valuename> "
654 "<type> [<val>]+\n"));
655 return -1;
658 return run_rpc_command(c, NULL, &ndr_table_winreg, 0,
659 rpc_registry_setvalue_internal, argc, argv );
662 static NTSTATUS rpc_registry_deletevalue_internal(struct net_context *c,
663 const struct dom_sid *domain_sid,
664 const char *domain_name,
665 struct cli_state *cli,
666 struct rpc_pipe_client *pipe_hnd,
667 TALLOC_CTX *mem_ctx,
668 int argc,
669 const char **argv )
671 struct policy_handle hive_hnd, key_hnd;
672 NTSTATUS status;
673 WERROR werr;
674 struct winreg_String valuename;
675 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
677 ZERO_STRUCT(valuename);
679 status = registry_openkey(mem_ctx, pipe_hnd, argv[0],
680 SEC_FLAG_MAXIMUM_ALLOWED,
681 &hive_hnd, &key_hnd);
682 if (!NT_STATUS_IS_OK(status)) {
683 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
684 nt_errstr(status));
685 return status;
688 valuename.name = argv[1];
690 status = dcerpc_winreg_DeleteValue(b, mem_ctx, &key_hnd,
691 valuename, &werr);
692 if (!NT_STATUS_IS_OK(status)) {
693 d_fprintf(stderr, _("registry_deletevalue failed: %s\n"),
694 nt_errstr(status));
696 if (!W_ERROR_IS_OK(werr)) {
697 status = werror_to_ntstatus(werr);
698 d_fprintf(stderr, _("registry_deletevalue failed: %s\n"),
699 win_errstr(werr));
702 dcerpc_winreg_CloseKey(b, mem_ctx, &key_hnd, &werr);
703 dcerpc_winreg_CloseKey(b, mem_ctx, &hive_hnd, &werr);
705 return status;
708 static int rpc_registry_deletevalue(struct net_context *c, int argc,
709 const char **argv )
711 if (argc != 2 || c->display_usage) {
712 d_fprintf(stderr, "%s\n%s",
713 _("Usage:"),
714 _("net rpc registry deletevalue <key> <valuename>\n"));
715 return -1;
718 return run_rpc_command(c, NULL, &ndr_table_winreg, 0,
719 rpc_registry_deletevalue_internal, argc, argv );
722 static NTSTATUS rpc_registry_getvalue_internal(struct net_context *c,
723 const struct dom_sid *domain_sid,
724 const char *domain_name,
725 struct cli_state *cli,
726 struct rpc_pipe_client *pipe_hnd,
727 TALLOC_CTX *mem_ctx,
728 bool raw,
729 int argc,
730 const char **argv)
732 struct policy_handle hive_hnd, key_hnd;
733 NTSTATUS status;
734 WERROR werr;
735 struct winreg_String valuename;
736 struct registry_value *value = NULL;
737 enum winreg_Type type = REG_NONE;
738 uint32_t data_size = 0;
739 uint32_t value_length = 0;
740 TALLOC_CTX *tmp_ctx = talloc_stackframe();
741 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
743 ZERO_STRUCT(valuename);
745 status = registry_openkey(tmp_ctx, pipe_hnd, argv[0],
746 SEC_FLAG_MAXIMUM_ALLOWED,
747 &hive_hnd, &key_hnd);
748 if (!NT_STATUS_IS_OK(status)) {
749 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
750 nt_errstr(status));
751 return status;
754 valuename.name = argv[1];
756 value = talloc_zero(tmp_ctx, struct registry_value);
757 if (value == NULL) {
758 return NT_STATUS_NO_MEMORY;
762 * call QueryValue once with data == NULL to get the
763 * needed memory size to be allocated, then allocate
764 * data buffer and call again.
766 status = dcerpc_winreg_QueryValue(b, tmp_ctx, &key_hnd,
767 &valuename,
768 &type,
769 NULL,
770 &data_size,
771 &value_length,
772 &werr);
774 if (!NT_STATUS_IS_OK(status)) {
775 d_fprintf(stderr, _("registry_queryvalue failed: %s\n"),
776 nt_errstr(status));
777 goto done;
779 if (!W_ERROR_IS_OK(werr)) {
780 status = werror_to_ntstatus(werr);
781 d_fprintf(stderr, _("registry_queryvalue failed: %s\n"),
782 nt_errstr(status));
783 goto done;
786 value->data = data_blob_talloc(tmp_ctx, NULL, data_size);
788 status = dcerpc_winreg_QueryValue(b, tmp_ctx, &key_hnd,
789 &valuename,
790 &type,
791 value->data.data,
792 &data_size,
793 &value_length,
794 &werr);
796 if (!NT_STATUS_IS_OK(status)) {
797 d_fprintf(stderr, _("registry_queryvalue failed: %s\n"),
798 nt_errstr(status));
799 goto done;
801 if (!W_ERROR_IS_OK(werr)) {
802 status = werror_to_ntstatus(werr);
803 d_fprintf(stderr, _("registry_queryvalue failed: %s\n"),
804 win_errstr(werr));
805 goto done;
809 value->type = type;
811 print_registry_value(value, raw);
813 done:
814 dcerpc_winreg_CloseKey(b, tmp_ctx, &key_hnd, &werr);
815 dcerpc_winreg_CloseKey(b, tmp_ctx, &hive_hnd, &werr);
817 TALLOC_FREE(tmp_ctx);
819 return status;
822 static NTSTATUS rpc_registry_getvalue_full(struct net_context *c,
823 const struct dom_sid *domain_sid,
824 const char *domain_name,
825 struct cli_state *cli,
826 struct rpc_pipe_client *pipe_hnd,
827 TALLOC_CTX *mem_ctx,
828 int argc,
829 const char **argv)
831 return rpc_registry_getvalue_internal(c, domain_sid, domain_name,
832 cli, pipe_hnd, mem_ctx, false,
833 argc, argv);
836 static int rpc_registry_getvalue(struct net_context *c, int argc,
837 const char **argv)
839 if (argc != 2 || c->display_usage) {
840 d_fprintf(stderr, "%s\n%s",
841 _("Usage:"),
842 _("net rpc registry getvalue <key> <valuename>\n"));
843 return -1;
846 return run_rpc_command(c, NULL, &ndr_table_winreg, 0,
847 rpc_registry_getvalue_full, argc, argv);
850 static NTSTATUS rpc_registry_getvalue_raw(struct net_context *c,
851 const struct dom_sid *domain_sid,
852 const char *domain_name,
853 struct cli_state *cli,
854 struct rpc_pipe_client *pipe_hnd,
855 TALLOC_CTX *mem_ctx,
856 int argc,
857 const char **argv)
859 return rpc_registry_getvalue_internal(c, domain_sid, domain_name,
860 cli, pipe_hnd, mem_ctx, true,
861 argc, argv);
864 static int rpc_registry_getvalueraw(struct net_context *c, int argc,
865 const char **argv)
867 if (argc != 2 || c->display_usage) {
868 d_fprintf(stderr, "%s\n%s",
869 _("Usage:"),
870 _("net rpc registry getvalue <key> <valuename>\n"));
871 return -1;
874 return run_rpc_command(c, NULL, &ndr_table_winreg, 0,
875 rpc_registry_getvalue_raw, argc, argv);
878 static NTSTATUS rpc_registry_createkey_internal(struct net_context *c,
879 const struct dom_sid *domain_sid,
880 const char *domain_name,
881 struct cli_state *cli,
882 struct rpc_pipe_client *pipe_hnd,
883 TALLOC_CTX *mem_ctx,
884 int argc,
885 const char **argv )
887 uint32_t hive;
888 struct policy_handle hive_hnd, key_hnd;
889 struct winreg_String key, keyclass;
890 enum winreg_CreateAction action;
891 NTSTATUS status;
892 WERROR werr;
893 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
895 ZERO_STRUCT(key);
896 ZERO_STRUCT(keyclass);
898 if (!reg_hive_key(mem_ctx, argv[0], &hive, &key.name)) {
899 return NT_STATUS_INVALID_PARAMETER;
902 status = dcerpc_winreg_Connect(b, mem_ctx, hive,
903 SEC_FLAG_MAXIMUM_ALLOWED,
904 &hive_hnd, &werr);
905 if (!(NT_STATUS_IS_OK(status))) {
906 return status;
908 if (!W_ERROR_IS_OK(werr)) {
909 return werror_to_ntstatus(werr);
912 action = REG_ACTION_NONE;
913 keyclass.name = "";
915 status = dcerpc_winreg_CreateKey(b, mem_ctx, &hive_hnd, key,
916 keyclass, 0, REG_KEY_READ, NULL,
917 &key_hnd, &action, &werr);
918 if (!NT_STATUS_IS_OK(status)) {
919 d_fprintf(stderr, _("createkey returned %s\n"),
920 nt_errstr(status));
921 dcerpc_winreg_CloseKey(b, mem_ctx, &hive_hnd, &werr);
922 return status;
924 if (!W_ERROR_IS_OK(werr)) {
925 WERROR _werr;
926 d_fprintf(stderr, _("createkey returned %s\n"),
927 win_errstr(werr));
928 dcerpc_winreg_CloseKey(b, mem_ctx, &hive_hnd, &_werr);
929 return werror_to_ntstatus(werr);
932 switch (action) {
933 case REG_ACTION_NONE:
934 d_printf(_("createkey did nothing -- huh?\n"));
935 break;
936 case REG_CREATED_NEW_KEY:
937 d_printf(_("createkey created %s\n"), argv[0]);
938 break;
939 case REG_OPENED_EXISTING_KEY:
940 d_printf(_("createkey opened existing %s\n"), argv[0]);
941 break;
944 dcerpc_winreg_CloseKey(b, mem_ctx, &key_hnd, &werr);
945 dcerpc_winreg_CloseKey(b, mem_ctx, &hive_hnd, &werr);
947 return status;
950 static int rpc_registry_createkey(struct net_context *c, int argc,
951 const char **argv )
953 if (argc != 1 || c->display_usage) {
954 d_fprintf(stderr, "%s\n%s",
955 _("Usage:"),
956 _("net rpc registry createkey <key>\n"));
957 return -1;
960 return run_rpc_command(c, NULL, &ndr_table_winreg, 0,
961 rpc_registry_createkey_internal, argc, argv );
964 static NTSTATUS rpc_registry_deletekey_internal(struct net_context *c,
965 const struct dom_sid *domain_sid,
966 const char *domain_name,
967 struct cli_state *cli,
968 struct rpc_pipe_client *pipe_hnd,
969 TALLOC_CTX *mem_ctx,
970 int argc,
971 const char **argv )
973 uint32_t hive;
974 struct policy_handle hive_hnd;
975 struct winreg_String key;
976 NTSTATUS status;
977 WERROR werr;
978 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
980 ZERO_STRUCT(key);
982 if (!reg_hive_key(mem_ctx, argv[0], &hive, &key.name)) {
983 return NT_STATUS_INVALID_PARAMETER;
986 status = dcerpc_winreg_Connect(b, mem_ctx, hive,
987 SEC_FLAG_MAXIMUM_ALLOWED,
988 &hive_hnd, &werr);
989 if (!(NT_STATUS_IS_OK(status))) {
990 return status;
992 if (!W_ERROR_IS_OK(werr)) {
993 return werror_to_ntstatus(werr);
996 status = dcerpc_winreg_DeleteKey(b, mem_ctx, &hive_hnd, key, &werr);
997 if (is_valid_policy_hnd(&hive_hnd)) {
998 WERROR _werr;
999 dcerpc_winreg_CloseKey(b, mem_ctx, &hive_hnd, &_werr);
1002 if (!NT_STATUS_IS_OK(status)) {
1003 d_fprintf(stderr, _("deletekey returned %s\n"),
1004 nt_errstr(status));
1005 return status;
1008 if (!W_ERROR_IS_OK(werr)) {
1009 d_fprintf(stderr, _("deletekey returned %s\n"),
1010 win_errstr(werr));
1011 return werror_to_ntstatus(werr);
1014 return status;
1017 static int rpc_registry_deletekey(struct net_context *c, int argc, const char **argv )
1019 if (argc != 1 || c->display_usage) {
1020 d_fprintf(stderr, "%s\n%s",
1021 _("Usage:"),
1022 _("net rpc registry deletekey <key>\n"));
1023 return -1;
1026 return run_rpc_command(c, NULL, &ndr_table_winreg, 0,
1027 rpc_registry_deletekey_internal, argc, argv );
1030 /********************************************************************
1031 ********************************************************************/
1033 static NTSTATUS rpc_registry_enumerate_internal(struct net_context *c,
1034 const struct dom_sid *domain_sid,
1035 const char *domain_name,
1036 struct cli_state *cli,
1037 struct rpc_pipe_client *pipe_hnd,
1038 TALLOC_CTX *mem_ctx,
1039 int argc,
1040 const char **argv )
1042 struct policy_handle pol_hive, pol_key;
1043 NTSTATUS status;
1044 WERROR werr;
1045 uint32_t num_subkeys = 0;
1046 uint32_t num_values = 0;
1047 char **names = NULL, **classes = NULL;
1048 NTTIME **modtimes = NULL;
1049 uint32_t i;
1050 struct registry_value **values = NULL;
1051 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
1053 if (argc != 1 || c->display_usage) {
1054 d_printf("%s\n%s",
1055 _("Usage:"),
1056 _("net rpc registry enumerate <path>\n"));
1057 d_printf("%s net rpc registry enumerate "
1058 "'HKLM\\Software\\Samba'\n", _("Example:"));
1059 return NT_STATUS_INVALID_PARAMETER;
1062 status = registry_openkey(mem_ctx, pipe_hnd, argv[0], REG_KEY_READ,
1063 &pol_hive, &pol_key);
1064 if (!NT_STATUS_IS_OK(status)) {
1065 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
1066 nt_errstr(status));
1067 return status;
1070 status = registry_enumkeys(mem_ctx, pipe_hnd, &pol_key, &num_subkeys,
1071 &names, &classes, &modtimes);
1072 if (!NT_STATUS_IS_OK(status)) {
1073 d_fprintf(stderr, _("enumerating keys failed: %s\n"),
1074 nt_errstr(status));
1075 return status;
1078 for (i=0; i<num_subkeys; i++) {
1079 print_registry_key(names[i], modtimes[i]);
1082 status = registry_enumvalues(mem_ctx, pipe_hnd, &pol_key, &num_values,
1083 &names, &values);
1084 if (!NT_STATUS_IS_OK(status)) {
1085 d_fprintf(stderr, _("enumerating values failed: %s\n"),
1086 nt_errstr(status));
1087 return status;
1090 for (i=0; i<num_values; i++) {
1091 print_registry_value_with_name(names[i], values[i]);
1094 dcerpc_winreg_CloseKey(b, mem_ctx, &pol_key, &werr);
1095 dcerpc_winreg_CloseKey(b, mem_ctx, &pol_hive, &werr);
1097 return status;
1100 /********************************************************************
1101 ********************************************************************/
1103 static int rpc_registry_enumerate(struct net_context *c, int argc,
1104 const char **argv )
1106 return run_rpc_command(c, NULL, &ndr_table_winreg, 0,
1107 rpc_registry_enumerate_internal, argc, argv );
1110 /********************************************************************
1111 ********************************************************************/
1113 static NTSTATUS rpc_registry_save_internal(struct net_context *c,
1114 const struct dom_sid *domain_sid,
1115 const char *domain_name,
1116 struct cli_state *cli,
1117 struct rpc_pipe_client *pipe_hnd,
1118 TALLOC_CTX *mem_ctx,
1119 int argc,
1120 const char **argv )
1122 WERROR result = WERR_GEN_FAILURE;
1123 struct policy_handle pol_hive, pol_key;
1124 NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
1125 struct winreg_String filename;
1126 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
1128 if (argc != 2 || c->display_usage) {
1129 d_printf("%s\n%s",
1130 _("Usage:"),
1131 _("net rpc registry backup <path> <file> \n"));
1132 return NT_STATUS_INVALID_PARAMETER;
1135 status = registry_openkey(mem_ctx, pipe_hnd, argv[0], REG_KEY_ALL,
1136 &pol_hive, &pol_key);
1137 if (!NT_STATUS_IS_OK(status)) {
1138 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
1139 nt_errstr(status));
1140 return status;
1143 filename.name = argv[1];
1144 status = dcerpc_winreg_SaveKey(b, mem_ctx, &pol_key, &filename, NULL, &result);
1145 if (!NT_STATUS_IS_OK(status)) {
1146 d_fprintf(stderr, _("Unable to save [%s] to %s:%s\n"), argv[0],
1147 pipe_hnd->desthost, argv[1]);
1149 if (!W_ERROR_IS_OK(result)) {
1150 status = werror_to_ntstatus(result);
1151 d_fprintf(stderr, _("Unable to save [%s] to %s:%s\n"), argv[0],
1152 pipe_hnd->desthost, argv[1]);
1155 /* cleanup */
1157 dcerpc_winreg_CloseKey(b, mem_ctx, &pol_key, &result);
1158 dcerpc_winreg_CloseKey(b, mem_ctx, &pol_hive, &result);
1160 return status;
1163 /********************************************************************
1164 ********************************************************************/
1166 static int rpc_registry_save(struct net_context *c, int argc, const char **argv )
1168 return run_rpc_command(c, NULL, &ndr_table_winreg, 0,
1169 rpc_registry_save_internal, argc, argv );
1173 /********************************************************************
1174 ********************************************************************/
1176 static void dump_values( REGF_NK_REC *nk )
1178 int i, j;
1179 const char *data_str = NULL;
1180 uint32_t data_size, data;
1181 DATA_BLOB blob;
1183 if ( !nk->values )
1184 return;
1186 for ( i=0; i<nk->num_values; i++ ) {
1187 d_printf( "\"%s\" = ", nk->values[i].valuename ? nk->values[i].valuename : "(default)" );
1188 d_printf( "(%s) ", str_regtype( nk->values[i].type ) );
1190 data_size = nk->values[i].data_size & ~VK_DATA_IN_OFFSET;
1191 switch ( nk->values[i].type ) {
1192 case REG_SZ:
1193 blob = data_blob_const(nk->values[i].data, data_size);
1194 if (!pull_reg_sz(talloc_tos(), &blob,
1195 &data_str)) {
1196 data_str = NULL;
1198 if (!data_str) {
1199 break;
1201 d_printf( "%s", data_str );
1202 break;
1203 case REG_MULTI_SZ:
1204 case REG_EXPAND_SZ:
1205 for ( j=0; j<data_size; j++ ) {
1206 d_printf( "%c", nk->values[i].data[j] );
1208 break;
1209 case REG_DWORD:
1210 data = IVAL( nk->values[i].data, 0 );
1211 d_printf("0x%x", data );
1212 break;
1213 case REG_BINARY:
1214 for ( j=0; j<data_size; j++ ) {
1215 d_printf( "%x", nk->values[i].data[j] );
1217 break;
1218 default:
1219 d_printf(_("unknown"));
1220 break;
1223 d_printf( "\n" );
1228 /********************************************************************
1229 ********************************************************************/
1231 static bool dump_registry_tree( REGF_FILE *file, REGF_NK_REC *nk, const char *parent )
1233 REGF_NK_REC *key;
1235 /* depth first dump of the registry tree */
1237 while ( (key = regfio_fetch_subkey( file, nk )) ) {
1238 char *regpath;
1239 if (asprintf(&regpath, "%s\\%s", parent, key->keyname) < 0) {
1240 break;
1242 d_printf("[%s]\n", regpath );
1243 dump_values( key );
1244 d_printf("\n");
1245 dump_registry_tree( file, key, regpath );
1246 SAFE_FREE(regpath);
1249 return true;
1252 /********************************************************************
1253 ********************************************************************/
1255 static bool write_registry_tree( REGF_FILE *infile, REGF_NK_REC *nk,
1256 REGF_NK_REC *parent, REGF_FILE *outfile,
1257 const char *parentpath )
1259 REGF_NK_REC *key, *subkey;
1260 struct regval_ctr *values = NULL;
1261 struct regsubkey_ctr *subkeys = NULL;
1262 int i;
1263 char *path = NULL;
1264 WERROR werr;
1266 werr = regsubkey_ctr_init(infile->mem_ctx, &subkeys);
1267 if (!W_ERROR_IS_OK(werr)) {
1268 DEBUG(0, ("write_registry_tree: regsubkey_ctr_init failed: "
1269 "%s\n", win_errstr(werr)));
1270 return false;
1273 werr = regval_ctr_init(subkeys, &values);
1274 if (!W_ERROR_IS_OK(werr)) {
1275 DEBUG(0,("write_registry_tree: talloc() failed!\n"));
1276 TALLOC_FREE(subkeys);
1277 return false;
1280 /* copy values into the struct regval_ctr */
1282 for ( i=0; i<nk->num_values; i++ ) {
1283 regval_ctr_addvalue( values, nk->values[i].valuename, nk->values[i].type,
1284 nk->values[i].data, (nk->values[i].data_size & ~VK_DATA_IN_OFFSET) );
1287 /* copy subkeys into the struct regsubkey_ctr */
1289 while ( (subkey = regfio_fetch_subkey( infile, nk )) ) {
1290 regsubkey_ctr_addkey( subkeys, subkey->keyname );
1293 key = regfio_write_key( outfile, nk->keyname, values, subkeys, nk->sec_desc->sec_desc, parent );
1295 /* write each one of the subkeys out */
1297 path = talloc_asprintf(subkeys,
1298 "%s%s%s",
1299 parentpath,
1300 parent ? "\\" : "",
1301 nk->keyname);
1302 if (!path) {
1303 TALLOC_FREE(subkeys);
1304 return false;
1307 nk->subkey_index = 0;
1308 while ( (subkey = regfio_fetch_subkey( infile, nk )) ) {
1309 write_registry_tree( infile, subkey, key, outfile, path );
1312 d_printf("[%s]\n", path );
1313 TALLOC_FREE(subkeys);
1315 return true;
1318 /********************************************************************
1319 ********************************************************************/
1321 static int rpc_registry_dump(struct net_context *c, int argc, const char **argv)
1323 REGF_FILE *registry;
1324 REGF_NK_REC *nk;
1326 if (argc != 1 || c->display_usage) {
1327 d_printf("%s\n%s",
1328 _("Usage:"),
1329 _("net rpc registry dump <file> \n"));
1330 return -1;
1333 d_printf(_("Opening %s...."), argv[0]);
1334 if ( !(registry = regfio_open( argv[0], O_RDONLY, 0)) ) {
1335 d_fprintf(stderr, _("Failed to open %s for reading\n"),argv[0]);
1336 return 1;
1338 d_printf(_("ok\n"));
1340 /* get the root of the registry file */
1342 if ((nk = regfio_rootkey( registry )) == NULL) {
1343 d_fprintf(stderr, _("Could not get rootkey\n"));
1344 regfio_close( registry );
1345 return 1;
1347 d_printf("[%s]\n", nk->keyname);
1348 dump_values( nk );
1349 d_printf("\n");
1351 dump_registry_tree( registry, nk, nk->keyname );
1353 #if 0
1354 talloc_report_full( registry->mem_ctx, stderr );
1355 #endif
1356 d_printf(_("Closing registry..."));
1357 regfio_close( registry );
1358 d_printf(_("ok\n"));
1360 return 0;
1363 /********************************************************************
1364 ********************************************************************/
1366 static int rpc_registry_copy(struct net_context *c, int argc, const char **argv )
1368 REGF_FILE *infile = NULL, *outfile = NULL;
1369 REGF_NK_REC *nk;
1370 int result = 1;
1372 if (argc != 2 || c->display_usage) {
1373 d_printf("%s\n%s",
1374 _("Usage:"),
1375 _("net rpc registry copy <srcfile> <newfile>\n"));
1376 return -1;
1379 d_printf(_("Opening %s...."), argv[0]);
1380 if ( !(infile = regfio_open( argv[0], O_RDONLY, 0 )) ) {
1381 d_fprintf(stderr, _("Failed to open %s for reading\n"),argv[0]);
1382 return 1;
1384 d_printf(_("ok\n"));
1386 d_printf(_("Opening %s...."), argv[1]);
1387 if ( !(outfile = regfio_open( argv[1], (O_RDWR|O_CREAT|O_TRUNC),
1388 (S_IRUSR|S_IWUSR) )) ) {
1389 d_fprintf(stderr, _("Failed to open %s for writing\n"),argv[1]);
1390 goto out;
1392 d_printf(_("ok\n"));
1394 /* get the root of the registry file */
1396 if ((nk = regfio_rootkey( infile )) == NULL) {
1397 d_fprintf(stderr, _("Could not get rootkey\n"));
1398 goto out;
1400 d_printf(_("RootKey: [%s]\n"), nk->keyname);
1402 write_registry_tree( infile, nk, NULL, outfile, "" );
1404 result = 0;
1406 out:
1408 d_printf(_("Closing %s..."), argv[1]);
1409 if (outfile) {
1410 regfio_close( outfile );
1412 d_printf(_("ok\n"));
1414 d_printf(_("Closing %s..."), argv[0]);
1415 if (infile) {
1416 regfio_close( infile );
1418 d_printf(_("ok\n"));
1420 return( result);
1423 /********************************************************************
1424 ********************************************************************/
1426 static NTSTATUS rpc_registry_getsd_internal(struct net_context *c,
1427 const struct dom_sid *domain_sid,
1428 const char *domain_name,
1429 struct cli_state *cli,
1430 struct rpc_pipe_client *pipe_hnd,
1431 TALLOC_CTX *mem_ctx,
1432 int argc,
1433 const char **argv)
1435 struct policy_handle pol_hive, pol_key;
1436 NTSTATUS status;
1437 WERROR werr;
1438 enum ndr_err_code ndr_err;
1439 struct KeySecurityData *sd = NULL;
1440 uint32_t sec_info;
1441 DATA_BLOB blob;
1442 struct security_descriptor sec_desc;
1443 uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED |
1444 SEC_FLAG_SYSTEM_SECURITY;
1445 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
1447 if (argc <1 || argc > 2 || c->display_usage) {
1448 d_printf("%s\n%s",
1449 _("Usage:"),
1450 _("net rpc registry getsd <path> <secinfo>\n"));
1451 d_printf("%s net rpc registry getsd "
1452 "'HKLM\\Software\\Samba'\n", _("Example:"));
1453 return NT_STATUS_INVALID_PARAMETER;
1456 status = registry_openkey(mem_ctx, pipe_hnd, argv[0],
1457 access_mask,
1458 &pol_hive, &pol_key);
1459 if (!NT_STATUS_IS_OK(status)) {
1460 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
1461 nt_errstr(status));
1462 return status;
1465 sd = talloc_zero(mem_ctx, struct KeySecurityData);
1466 if (!sd) {
1467 status = NT_STATUS_NO_MEMORY;
1468 goto out;
1471 sd->size = 0x1000;
1473 if (argc >= 2) {
1474 sscanf(argv[1], "%x", &sec_info);
1475 } else {
1476 sec_info = SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL;
1479 status = registry_getsd(mem_ctx, b, &pol_key, sec_info, sd, &werr);
1480 if (!NT_STATUS_IS_OK(status)) {
1481 d_fprintf(stderr, _("getting sd failed: %s\n"),
1482 nt_errstr(status));
1483 goto out;
1485 if (!W_ERROR_IS_OK(werr)) {
1486 status = werror_to_ntstatus(werr);
1487 d_fprintf(stderr, _("getting sd failed: %s\n"),
1488 win_errstr(werr));
1489 goto out;
1492 blob.data = sd->data;
1493 blob.length = sd->size;
1495 ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &sec_desc,
1496 (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
1497 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1498 status = ndr_map_error2ntstatus(ndr_err);
1499 goto out;
1501 status = NT_STATUS_OK;
1503 display_sec_desc(&sec_desc);
1505 out:
1506 dcerpc_winreg_CloseKey(b, mem_ctx, &pol_key, &werr);
1507 dcerpc_winreg_CloseKey(b, mem_ctx, &pol_hive, &werr);
1509 return status;
1513 static int rpc_registry_getsd(struct net_context *c, int argc, const char **argv)
1515 return run_rpc_command(c, NULL, &ndr_table_winreg, 0,
1516 rpc_registry_getsd_internal, argc, argv);
1519 /********************************************************************
1520 ********************************************************************/
1522 * @defgroup net_rpc_registry net rpc registry
1526 * @defgroup net_rpc_registry_export Export
1527 * @ingroup net_rpc_registry
1528 * @{
1531 static NTSTATUS registry_export(struct rpc_pipe_client* pipe_hnd,
1532 TALLOC_CTX* ctx,
1533 struct policy_handle* key_hnd,
1534 struct reg_format* f,
1535 const char* parentfullname,
1536 const char* name)
1538 NTSTATUS status;
1539 uint32_t num_subkeys = 0;
1540 uint32_t num_values = 0;
1541 char **names = NULL, **classes = NULL;
1542 NTTIME **modtimes = NULL;
1543 struct regval_blob **values = NULL;
1544 uint32_t i;
1545 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
1547 TALLOC_CTX* mem_ctx = talloc_new(ctx);
1550 const char* fullname = name
1551 ? talloc_asprintf(mem_ctx, "%s\\%s", parentfullname, name)
1552 : parentfullname;
1553 reg_format_key(f, &fullname, 1, false);
1555 status = registry_enumvalues2(mem_ctx, pipe_hnd, key_hnd, &num_values,
1556 &names, &values);
1557 if (!NT_STATUS_IS_OK(status)) {
1558 d_fprintf(stderr, _("enumerating values failed: %s\n"),
1559 nt_errstr(status));
1560 goto done;
1563 for (i=0; i<num_values; i++) {
1564 reg_format_regval_blob(f, names[i], values[i]);
1568 status = registry_enumkeys(mem_ctx, pipe_hnd, key_hnd, &num_subkeys,
1569 &names, &classes, &modtimes);
1570 if (!NT_STATUS_IS_OK(status)) {
1571 d_fprintf(stderr, _("enumerating keys failed: %s\n"),
1572 nt_errstr(status));
1573 goto done;
1576 for (i=0; i<num_subkeys; i++) {
1577 struct policy_handle subkey_hnd;
1578 struct winreg_String key;
1579 WERROR werr;
1580 ZERO_STRUCT(key);
1581 /* key.name = talloc_strdup(mem_ctx, names[i]); ??? */
1582 key.name = names[i];
1584 status = dcerpc_winreg_OpenKey(b, mem_ctx, key_hnd, key,
1585 0, REG_KEY_READ,
1586 &subkey_hnd, &werr);
1587 if (!NT_STATUS_IS_OK(status)) {
1588 d_fprintf(stderr,
1589 _("dcerpc_winreg_OpenKey failed: %s %s\n"),
1590 names[i], nt_errstr(status));
1591 continue;
1593 if (!W_ERROR_IS_OK(werr)) {
1594 status = werror_to_ntstatus(werr);
1595 d_fprintf(stderr,
1596 _("dcerpc_winreg_OpenKey failed: %s %s\n"),
1597 names[i], win_errstr(werr));
1598 continue;
1601 status = registry_export(pipe_hnd, mem_ctx, &subkey_hnd,
1602 f, fullname, names[i]);
1603 if (!(NT_STATUS_IS_OK(status))) {
1604 d_fprintf(stderr,
1605 _("export key failed: %s %s\n"),
1606 names[i], nt_errstr(status));
1608 dcerpc_winreg_CloseKey(b, mem_ctx,
1609 &subkey_hnd, &werr);
1611 done:
1612 talloc_free(mem_ctx);
1613 return status;
1616 static NTSTATUS rpc_registry_export_internal(struct net_context *c,
1617 const struct dom_sid *domain_sid,
1618 const char *domain_name,
1619 struct cli_state *cli,
1620 struct rpc_pipe_client *pipe_hnd,
1621 TALLOC_CTX *mem_ctx,
1622 int argc,
1623 const char **argv )
1625 struct policy_handle pol_hive, pol_key;
1626 NTSTATUS status;
1627 WERROR werr;
1628 struct reg_format* f;
1629 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
1631 if (argc < 2 || argc > 3 || c->display_usage) {
1632 d_printf("%s\n%s",
1633 _("Usage:"),
1634 _("net rpc registry export <path> <file> [opt]\n"));
1635 d_printf("%s net rpc registry export "
1636 "'HKLM\\Software\\Samba' samba.reg\n", _("Example:"));
1637 return NT_STATUS_INVALID_PARAMETER;
1640 status = registry_openkey(mem_ctx, pipe_hnd, argv[0], REG_KEY_READ,
1641 &pol_hive, &pol_key);
1642 if (!NT_STATUS_IS_OK(status)) {
1643 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
1644 nt_errstr(status));
1645 return status;
1648 f = reg_format_file(mem_ctx, argv[1], (argc > 2) ? argv[2] : NULL);
1649 if (f == NULL) {
1650 d_fprintf(stderr, _("open file failed: %s\n"), strerror(errno));
1651 return map_nt_error_from_unix(errno);
1654 status = registry_export(pipe_hnd, mem_ctx, &pol_key,
1655 f, argv[0], NULL );
1656 if (!NT_STATUS_IS_OK(status))
1657 return status;
1659 dcerpc_winreg_CloseKey(b, mem_ctx, &pol_key, &werr);
1660 dcerpc_winreg_CloseKey(b, mem_ctx, &pol_hive, &werr);
1662 return status;
1664 /********************************************************************
1665 ********************************************************************/
1667 static int rpc_registry_export(struct net_context *c, int argc,
1668 const char **argv )
1670 return run_rpc_command(c, NULL, &ndr_table_winreg, 0,
1671 rpc_registry_export_internal, argc, argv );
1674 /**@}*/
1676 /********************************************************************
1677 ********************************************************************/
1680 * @defgroup net_rpc_registry_import Import
1681 * @ingroup net_rpc_registry
1682 * @{
1685 struct import_ctx {
1686 struct rpc_pipe_client *pipe_hnd;
1687 TALLOC_CTX *mem_ctx;
1690 static WERROR import_create_key(struct import_ctx* ctx,
1691 struct policy_handle* parent, const char* name,
1692 void** pkey, bool* existing)
1694 WERROR werr;
1695 NTSTATUS status;
1696 void* mem_ctx = talloc_new(ctx->mem_ctx);
1698 struct policy_handle* key = NULL;
1699 struct policy_handle hive;
1700 struct winreg_String keyclass, keyname;
1701 enum winreg_CreateAction action = REG_ACTION_NONE;
1702 struct dcerpc_binding_handle *b = ctx->pipe_hnd->binding_handle;
1704 ZERO_STRUCT(keyname);
1705 keyname.name = name;
1707 if (parent == NULL) {
1708 uint32_t hive_idx = 0;
1709 if (!reg_hive_key(mem_ctx, name, &hive_idx, &keyname.name)) {
1710 werr = WERR_FOOBAR;
1711 goto done;
1714 status = dcerpc_winreg_Connect(b, mem_ctx,
1715 hive_idx, SEC_FLAG_MAXIMUM_ALLOWED,
1716 &hive, &werr);
1717 if (!NT_STATUS_IS_OK(status)) {
1718 werr = ntstatus_to_werror(status);
1719 d_fprintf(stderr, _("dcerpc_winreg_Connect returned %s\n"),
1720 nt_errstr(status));
1721 goto done;
1723 if (!W_ERROR_IS_OK(werr)) {
1724 d_fprintf(stderr, _("dcerpc_winreg_Connect returned %s\n"),
1725 win_errstr(werr));
1726 goto done;
1729 parent = &hive;
1732 key = talloc_zero(mem_ctx, struct policy_handle);
1733 if (key == NULL) {
1734 werr = WERR_NOT_ENOUGH_MEMORY;
1735 goto done;
1738 ZERO_STRUCT(keyclass);
1739 keyclass.name = "";
1741 status = dcerpc_winreg_CreateKey(b, mem_ctx,
1742 parent, keyname,
1743 keyclass, 0, REG_KEY_READ, NULL,
1744 key, &action, &werr);
1745 if (!NT_STATUS_IS_OK(status)) {
1746 werr = ntstatus_to_werror(status);
1747 d_fprintf(stderr, _("dcerpc_winreg_CreateKey returned %s\n"),
1748 nt_errstr(status));
1749 goto done;
1751 if (!W_ERROR_IS_OK(werr)) {
1752 d_fprintf(stderr, _("dcerpc_winreg_CreateKey returned %s\n"),
1753 win_errstr(werr));
1754 goto done;
1757 switch (action) {
1758 case REG_CREATED_NEW_KEY:
1759 d_printf(_("createkey created %s\n"), name);
1760 if (existing != NULL)
1761 *existing = false;
1762 break;
1764 case REG_OPENED_EXISTING_KEY:
1765 d_printf(_("createkey opened existing %s\n"), name);
1766 if (existing != NULL)
1767 *existing = true;
1768 break;
1770 case REG_ACTION_NONE:
1771 d_printf(_("createkey did nothing -- huh?\n"));
1772 werr = WERR_CREATE_FAILED;
1773 break;
1774 default:
1775 assert(false);
1778 done:
1779 if ( parent == &hive ) {
1780 WERROR _result;
1781 dcerpc_winreg_CloseKey(b, mem_ctx,
1782 parent, &_result);
1785 if (pkey!=NULL) {
1786 *pkey = talloc_steal(ctx->mem_ctx, key);
1789 talloc_free(mem_ctx);
1790 return werr;
1793 static WERROR import_delete_key(struct import_ctx* ctx,
1794 struct policy_handle* parent, const char* name)
1796 WERROR werr;
1797 NTSTATUS status;
1798 void* mem_ctx = talloc_new(ctx->mem_ctx);
1799 struct winreg_String keyname = { 0, };
1800 struct policy_handle hive;
1801 struct dcerpc_binding_handle *b = ctx->pipe_hnd->binding_handle;
1803 keyname.name = name;
1805 if (parent == NULL) {
1806 uint32_t hive_idx;
1807 if (!reg_hive_key(mem_ctx, name, &hive_idx, &keyname.name)) {
1808 werr = WERR_FOOBAR;
1809 goto done;
1812 status = dcerpc_winreg_Connect(b, mem_ctx, hive_idx,
1813 SEC_FLAG_MAXIMUM_ALLOWED, &hive,
1814 &werr);
1815 if (!NT_STATUS_IS_OK(status)) {
1816 werr = ntstatus_to_werror(status);
1817 d_fprintf(stderr, _("dcerpc_winreg_Connect returned %s\n"),
1818 nt_errstr(status));
1819 goto done;
1821 if (!W_ERROR_IS_OK(werr)) {
1822 d_fprintf(stderr, _("dcerpc_winreg_Connect returned %s\n"),
1823 win_errstr(werr));
1824 goto done;
1827 parent = &hive;
1830 status = dcerpc_winreg_DeleteKey(b, mem_ctx, parent,
1831 keyname, &werr);
1832 if (!NT_STATUS_IS_OK(status)) {
1833 werr = ntstatus_to_werror(status);
1834 d_fprintf(stderr, _("dcerpc_winreg_DeleteKey returned %s\n"),
1835 nt_errstr(status));
1836 goto done;
1838 if (!W_ERROR_IS_OK(werr)) {
1839 d_fprintf(stderr, _("dcerpc_winreg_DeleteKey returned %s\n"),
1840 win_errstr(werr));
1841 goto done;
1844 done:
1845 if ( parent == &hive ) {
1846 WERROR _result;
1847 dcerpc_winreg_CloseKey(b, mem_ctx, parent, &_result);
1850 talloc_free(mem_ctx);
1851 return werr;
1854 static WERROR import_close_key(struct import_ctx* ctx,
1855 struct policy_handle* key)
1857 WERROR werr;
1858 NTSTATUS status;
1859 void* mem_ctx = talloc_new(ctx->mem_ctx);
1860 struct dcerpc_binding_handle *b = ctx->pipe_hnd->binding_handle;
1862 status = dcerpc_winreg_CloseKey(b, mem_ctx, key, &werr);
1863 if (!NT_STATUS_IS_OK(status)) {
1864 werr = ntstatus_to_werror(status);
1865 d_fprintf(stderr, _("dcerpc_winreg_CloseKey returned %s\n"),
1866 nt_errstr(status));
1867 goto done;
1869 if (!W_ERROR_IS_OK(werr)) {
1870 d_fprintf(stderr, _("dcerpc_winreg_CloseKey returned %s\n"),
1871 win_errstr(werr));
1872 goto done;
1875 werr = (talloc_free(key) == 0) ? WERR_OK : WERR_GEN_FAILURE;
1876 done:
1877 talloc_free(mem_ctx);
1878 return werr;
1881 static WERROR import_create_val(struct import_ctx* ctx,
1882 struct policy_handle* parent, const char* name,
1883 uint32_t type, const uint8_t* val, uint32_t len)
1885 WERROR werr;
1886 NTSTATUS status;
1887 void* mem_ctx = talloc_new(ctx->mem_ctx);
1888 struct winreg_String valuename;
1889 struct dcerpc_binding_handle *b = ctx->pipe_hnd->binding_handle;
1891 if (parent == NULL) {
1892 return WERR_INVALID_PARAMETER;
1895 ZERO_STRUCT(valuename);
1896 valuename.name = name;
1898 status = dcerpc_winreg_SetValue(b, mem_ctx, parent,
1899 valuename, type,
1900 (uint8_t *)discard_const(val), len, &werr);
1901 if (!NT_STATUS_IS_OK(status)) {
1902 werr = ntstatus_to_werror(status);
1903 d_fprintf(stderr, _("registry_setvalue failed: %s\n"),
1904 nt_errstr(status));
1905 goto done;
1907 if (!W_ERROR_IS_OK(werr)) {
1908 d_fprintf(stderr, _("registry_setvalue failed: %s\n"),
1909 win_errstr(werr));
1910 goto done;
1913 done:
1914 talloc_free(mem_ctx);
1915 return werr;
1918 static WERROR import_delete_val(struct import_ctx* ctx,
1919 struct policy_handle* parent, const char* name)
1921 WERROR werr;
1922 NTSTATUS status;
1923 void* mem_ctx = talloc_new(ctx->mem_ctx);
1924 struct winreg_String valuename;
1925 struct dcerpc_binding_handle *b = ctx->pipe_hnd->binding_handle;
1927 if (parent == NULL) {
1928 return WERR_INVALID_PARAMETER;
1931 ZERO_STRUCT(valuename);
1932 valuename.name = name;
1934 status = dcerpc_winreg_DeleteValue(b, mem_ctx,
1935 parent, valuename, &werr);
1937 if (!NT_STATUS_IS_OK(status)) {
1938 werr = ntstatus_to_werror(status);
1939 d_fprintf(stderr, _("registry_deletevalue failed: %s\n"),
1940 nt_errstr(status));
1941 goto done;
1943 if (!NT_STATUS_IS_OK(status)) {
1944 d_fprintf(stderr, _("registry_deletevalue failed: %s\n"),
1945 win_errstr(werr));
1946 goto done;
1949 done:
1950 talloc_free(mem_ctx);
1951 return werr;
1956 static NTSTATUS rpc_registry_import_internal(struct net_context *c,
1957 const struct dom_sid *domain_sid,
1958 const char *domain_name,
1959 struct cli_state *cli,
1960 struct rpc_pipe_client *pipe_hnd,
1961 TALLOC_CTX *mem_ctx,
1962 int argc,
1963 const char **argv )
1965 struct import_ctx import_ctx;
1967 struct reg_import_callback import_callback = {
1968 .openkey = NULL,
1969 .closekey = (reg_import_callback_closekey_t)&import_close_key,
1970 .createkey = (reg_import_callback_createkey_t)&import_create_key,
1971 .deletekey = (reg_import_callback_deletekey_t)&import_delete_key,
1972 .deleteval = (reg_import_callback_deleteval_t)&import_delete_val,
1973 .setval = {
1974 .blob = (reg_import_callback_setval_blob_t)&import_create_val,
1976 .setval_type = BLOB,
1977 .data = &import_ctx
1980 int ret;
1981 if (argc < 1 || argc > 2 || c->display_usage) {
1982 d_printf("%s\n%s",
1983 _("Usage:"),
1984 _("net rpc registry import <file> [options]\n"));
1985 d_printf("%s net rpc registry export "
1986 "samba.reg enc=CP1252,flags=0\n", _("Example:"));
1987 return NT_STATUS_INVALID_PARAMETER;
1989 ZERO_STRUCT(import_ctx);
1990 import_ctx.pipe_hnd = pipe_hnd;
1991 import_ctx.mem_ctx = mem_ctx;
1992 ret = reg_parse_file(argv[0],
1993 reg_import_adapter(import_ctx.mem_ctx,
1994 import_callback
1996 (argc > 1) ? argv[1] : NULL
1999 return ret==0 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
2002 /********************************************************************
2003 ********************************************************************/
2005 static int rpc_registry_import(struct net_context *c, int argc,
2006 const char **argv )
2008 return run_rpc_command(c, NULL, &ndr_table_winreg, 0,
2009 rpc_registry_import_internal, argc, argv );
2012 /**@}*/
2013 /********************************************************************
2014 ********************************************************************/
2016 int net_rpc_registry(struct net_context *c, int argc, const char **argv)
2018 struct functable func[] = {
2020 "enumerate",
2021 rpc_registry_enumerate,
2022 NET_TRANSPORT_RPC,
2023 N_("Enumerate registry keys and values"),
2024 N_("net rpc registry enumerate\n"
2025 " Enumerate registry keys and values")
2028 "createkey",
2029 rpc_registry_createkey,
2030 NET_TRANSPORT_RPC,
2031 N_("Create a new registry key"),
2032 N_("net rpc registry createkey\n"
2033 " Create a new registry key")
2036 "deletekey",
2037 rpc_registry_deletekey,
2038 NET_TRANSPORT_RPC,
2039 N_("Delete a registry key"),
2040 N_("net rpc registry deletekey\n"
2041 " Delete a registry key")
2044 "getvalue",
2045 rpc_registry_getvalue,
2046 NET_TRANSPORT_RPC,
2047 N_("Print a registry value"),
2048 N_("net rpc registry getvalue\n"
2049 " Print a registry value")
2052 "getvalueraw",
2053 rpc_registry_getvalueraw,
2054 NET_TRANSPORT_RPC,
2055 N_("Print a registry value"),
2056 N_("net rpc registry getvalueraw\n"
2057 " Print a registry value (raw version)")
2060 "setvalue",
2061 rpc_registry_setvalue,
2062 NET_TRANSPORT_RPC,
2063 N_("Set a new registry value"),
2064 N_("net rpc registry setvalue\n"
2065 " Set a new registry value")
2068 "deletevalue",
2069 rpc_registry_deletevalue,
2070 NET_TRANSPORT_RPC,
2071 N_("Delete a registry value"),
2072 N_("net rpc registry deletevalue\n"
2073 " Delete a registry value")
2076 "save",
2077 rpc_registry_save,
2078 NET_TRANSPORT_RPC,
2079 N_("Save a registry file"),
2080 N_("net rpc registry save\n"
2081 " Save a registry file")
2084 "dump",
2085 rpc_registry_dump,
2086 NET_TRANSPORT_RPC,
2087 N_("Dump a registry file"),
2088 N_("net rpc registry dump\n"
2089 " Dump a registry file")
2092 "copy",
2093 rpc_registry_copy,
2094 NET_TRANSPORT_RPC,
2095 N_("Copy a registry file"),
2096 N_("net rpc registry copy\n"
2097 " Copy a registry file")
2100 "getsd",
2101 rpc_registry_getsd,
2102 NET_TRANSPORT_RPC,
2103 N_("Get security descriptor"),
2104 N_("net rpc registry getsd\n"
2105 " Get security descriptor")
2108 "import",
2109 rpc_registry_import,
2110 NET_TRANSPORT_RPC,
2111 N_("Import .reg file"),
2112 N_("net rpc registry import\n"
2113 " Import .reg file")
2116 "export",
2117 rpc_registry_export,
2118 NET_TRANSPORT_RPC,
2119 N_("Export .reg file"),
2120 N_("net rpc registry export\n"
2121 " Export .reg file")
2123 {NULL, NULL, 0, NULL, NULL}
2125 return net_run_function(c, argc, argv, "net rpc registry", func);