s3-security: remove some more shared secdesc defines.
[Samba/ekacnet.git] / source3 / utils / net_rpc_registry.c
blob59971af3a359983116b7a27ffd67a8b14f880dc7
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 "registry.h"
22 #include "utils/net.h"
23 #include "utils/net_registry_util.h"
24 #include "regfio.h"
25 #include "../librpc/gen_ndr/cli_winreg.h"
26 #include "registry/reg_util_marshalling.h"
27 #include "registry/reg_objects.h"
28 #include "../librpc/gen_ndr/ndr_security.h"
30 /*******************************************************************
31 connect to a registry hive root (open a registry policy)
32 *******************************************************************/
34 static NTSTATUS rpccli_winreg_Connect(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
35 uint32_t reg_type, uint32_t access_mask,
36 struct policy_handle *reg_hnd)
38 ZERO_STRUCTP(reg_hnd);
40 switch (reg_type)
42 case HKEY_CLASSES_ROOT:
43 return rpccli_winreg_OpenHKCR( cli, mem_ctx, NULL,
44 access_mask, reg_hnd, NULL);
46 case HKEY_LOCAL_MACHINE:
47 return rpccli_winreg_OpenHKLM( cli, mem_ctx, NULL,
48 access_mask, reg_hnd, NULL);
50 case HKEY_USERS:
51 return rpccli_winreg_OpenHKU( cli, mem_ctx, NULL,
52 access_mask, reg_hnd, NULL);
54 case HKEY_CURRENT_USER:
55 return rpccli_winreg_OpenHKCU( cli, mem_ctx, NULL,
56 access_mask, reg_hnd, NULL);
58 case HKEY_PERFORMANCE_DATA:
59 return rpccli_winreg_OpenHKPD( cli, mem_ctx, NULL,
60 access_mask, reg_hnd, NULL);
62 default:
63 /* fall through to end of function */
64 break;
67 return NT_STATUS_INVALID_PARAMETER;
70 static bool reg_hive_key(TALLOC_CTX *ctx, const char *fullname,
71 uint32 *reg_type, const char **key_name)
73 WERROR werr;
74 char *hivename = NULL;
75 char *tmp_keyname = NULL;
76 bool ret = false;
77 TALLOC_CTX *tmp_ctx = talloc_stackframe();
79 werr = split_hive_key(tmp_ctx, fullname, &hivename, &tmp_keyname);
80 if (!W_ERROR_IS_OK(werr)) {
81 goto done;
84 *key_name = talloc_strdup(ctx, tmp_keyname);
85 if (*key_name == NULL) {
86 goto done;
89 if (strequal(hivename, "HKLM") ||
90 strequal(hivename, "HKEY_LOCAL_MACHINE"))
92 (*reg_type) = HKEY_LOCAL_MACHINE;
93 } else if (strequal(hivename, "HKCR") ||
94 strequal(hivename, "HKEY_CLASSES_ROOT"))
96 (*reg_type) = HKEY_CLASSES_ROOT;
97 } else if (strequal(hivename, "HKU") ||
98 strequal(hivename, "HKEY_USERS"))
100 (*reg_type) = HKEY_USERS;
101 } else if (strequal(hivename, "HKCU") ||
102 strequal(hivename, "HKEY_CURRENT_USER"))
104 (*reg_type) = HKEY_CURRENT_USER;
105 } else if (strequal(hivename, "HKPD") ||
106 strequal(hivename, "HKEY_PERFORMANCE_DATA"))
108 (*reg_type) = HKEY_PERFORMANCE_DATA;
109 } else {
110 DEBUG(10,("reg_hive_key: unrecognised hive key %s\n",
111 fullname));
112 goto done;
115 ret = true;
117 done:
118 TALLOC_FREE(tmp_ctx);
119 return ret;
122 static NTSTATUS registry_openkey(TALLOC_CTX *mem_ctx,
123 struct rpc_pipe_client *pipe_hnd,
124 const char *name, uint32 access_mask,
125 struct policy_handle *hive_hnd,
126 struct policy_handle *key_hnd)
128 uint32 hive;
129 NTSTATUS status;
130 struct winreg_String key;
132 ZERO_STRUCT(key);
134 if (!reg_hive_key(mem_ctx, name, &hive, &key.name)) {
135 return NT_STATUS_INVALID_PARAMETER;
138 status = rpccli_winreg_Connect(pipe_hnd, mem_ctx, hive, access_mask,
139 hive_hnd);
140 if (!(NT_STATUS_IS_OK(status))) {
141 return status;
144 status = rpccli_winreg_OpenKey(pipe_hnd, mem_ctx, hive_hnd, key, 0,
145 access_mask, key_hnd, NULL);
146 if (!(NT_STATUS_IS_OK(status))) {
147 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, hive_hnd, NULL);
148 return status;
151 return NT_STATUS_OK;
154 static NTSTATUS registry_enumkeys(TALLOC_CTX *ctx,
155 struct rpc_pipe_client *pipe_hnd,
156 struct policy_handle *key_hnd,
157 uint32 *pnum_keys, char ***pnames,
158 char ***pclasses, NTTIME ***pmodtimes)
160 TALLOC_CTX *mem_ctx;
161 NTSTATUS status;
162 uint32 num_subkeys, max_subkeylen, max_classlen;
163 uint32 num_values, max_valnamelen, max_valbufsize;
164 uint32 i;
165 NTTIME last_changed_time;
166 uint32 secdescsize;
167 struct winreg_String classname;
168 char **names, **classes;
169 NTTIME **modtimes;
171 if (!(mem_ctx = talloc_new(ctx))) {
172 return NT_STATUS_NO_MEMORY;
175 ZERO_STRUCT(classname);
176 status = rpccli_winreg_QueryInfoKey(
177 pipe_hnd, mem_ctx, key_hnd, &classname, &num_subkeys,
178 &max_subkeylen, &max_classlen, &num_values, &max_valnamelen,
179 &max_valbufsize, &secdescsize, &last_changed_time, NULL );
181 if (!NT_STATUS_IS_OK(status)) {
182 goto error;
185 if (num_subkeys == 0) {
186 *pnum_keys = 0;
187 TALLOC_FREE(mem_ctx);
188 return NT_STATUS_OK;
191 if ((!(names = TALLOC_ZERO_ARRAY(mem_ctx, char *, num_subkeys))) ||
192 (!(classes = TALLOC_ZERO_ARRAY(mem_ctx, char *, num_subkeys))) ||
193 (!(modtimes = TALLOC_ZERO_ARRAY(mem_ctx, NTTIME *,
194 num_subkeys)))) {
195 status = NT_STATUS_NO_MEMORY;
196 goto error;
199 for (i=0; i<num_subkeys; i++) {
200 char c, n;
201 struct winreg_StringBuf class_buf;
202 struct winreg_StringBuf name_buf;
203 NTTIME modtime;
204 WERROR werr;
206 c = '\0';
207 class_buf.name = &c;
208 class_buf.size = max_classlen+2;
210 n = '\0';
211 name_buf.name = &n;
212 name_buf.size = max_subkeylen+2;
214 ZERO_STRUCT(modtime);
216 status = rpccli_winreg_EnumKey(pipe_hnd, mem_ctx, key_hnd,
217 i, &name_buf, &class_buf,
218 &modtime, &werr);
220 if (W_ERROR_EQUAL(werr,
221 WERR_NO_MORE_ITEMS) ) {
222 status = NT_STATUS_OK;
223 break;
225 if (!NT_STATUS_IS_OK(status)) {
226 goto error;
229 classes[i] = NULL;
231 if (class_buf.name &&
232 (!(classes[i] = talloc_strdup(classes, class_buf.name)))) {
233 status = NT_STATUS_NO_MEMORY;
234 goto error;
237 if (!(names[i] = talloc_strdup(names, name_buf.name))) {
238 status = NT_STATUS_NO_MEMORY;
239 goto error;
242 if ((!(modtimes[i] = (NTTIME *)talloc_memdup(
243 modtimes, &modtime, sizeof(modtime))))) {
244 status = NT_STATUS_NO_MEMORY;
245 goto error;
249 *pnum_keys = num_subkeys;
251 if (pnames) {
252 *pnames = talloc_move(ctx, &names);
254 if (pclasses) {
255 *pclasses = talloc_move(ctx, &classes);
257 if (pmodtimes) {
258 *pmodtimes = talloc_move(ctx, &modtimes);
261 status = NT_STATUS_OK;
263 error:
264 TALLOC_FREE(mem_ctx);
265 return status;
268 static NTSTATUS registry_enumvalues(TALLOC_CTX *ctx,
269 struct rpc_pipe_client *pipe_hnd,
270 struct policy_handle *key_hnd,
271 uint32 *pnum_values, char ***pvalnames,
272 struct registry_value ***pvalues)
274 TALLOC_CTX *mem_ctx;
275 NTSTATUS status;
276 uint32 num_subkeys, max_subkeylen, max_classlen;
277 uint32 num_values, max_valnamelen, max_valbufsize;
278 uint32 i;
279 NTTIME last_changed_time;
280 uint32 secdescsize;
281 struct winreg_String classname;
282 struct registry_value **values;
283 char **names;
285 if (!(mem_ctx = talloc_new(ctx))) {
286 return NT_STATUS_NO_MEMORY;
289 ZERO_STRUCT(classname);
290 status = rpccli_winreg_QueryInfoKey(
291 pipe_hnd, mem_ctx, key_hnd, &classname, &num_subkeys,
292 &max_subkeylen, &max_classlen, &num_values, &max_valnamelen,
293 &max_valbufsize, &secdescsize, &last_changed_time, NULL );
295 if (!NT_STATUS_IS_OK(status)) {
296 goto error;
299 if (num_values == 0) {
300 *pnum_values = 0;
301 TALLOC_FREE(mem_ctx);
302 return NT_STATUS_OK;
305 if ((!(names = TALLOC_ARRAY(mem_ctx, char *, num_values))) ||
306 (!(values = TALLOC_ARRAY(mem_ctx, struct registry_value *,
307 num_values)))) {
308 status = NT_STATUS_NO_MEMORY;
309 goto error;
312 for (i=0; i<num_values; i++) {
313 enum winreg_Type type = REG_NONE;
314 uint8 *data = NULL;
315 uint32 data_size;
316 uint32 value_length;
318 char n;
319 struct winreg_ValNameBuf name_buf;
320 WERROR err;
322 n = '\0';
323 name_buf.name = &n;
324 name_buf.size = max_valnamelen + 2;
326 data_size = max_valbufsize;
327 data = (uint8 *)TALLOC(mem_ctx, data_size);
328 value_length = 0;
330 status = rpccli_winreg_EnumValue(pipe_hnd, mem_ctx, key_hnd,
331 i, &name_buf, &type,
332 data, &data_size,
333 &value_length, &err);
335 if ( W_ERROR_EQUAL(err,
336 WERR_NO_MORE_ITEMS) ) {
337 status = NT_STATUS_OK;
338 break;
341 if (!(NT_STATUS_IS_OK(status))) {
342 goto error;
345 if (name_buf.name == NULL) {
346 status = NT_STATUS_INVALID_PARAMETER;
347 goto error;
350 if (!(names[i] = talloc_strdup(names, name_buf.name))) {
351 status = NT_STATUS_NO_MEMORY;
352 goto error;
355 err = registry_pull_value(values, &values[i], type, data,
356 data_size, value_length);
357 if (!W_ERROR_IS_OK(err)) {
358 status = werror_to_ntstatus(err);
359 goto error;
363 *pnum_values = num_values;
365 if (pvalnames) {
366 *pvalnames = talloc_move(ctx, &names);
368 if (pvalues) {
369 *pvalues = talloc_move(ctx, &values);
372 status = NT_STATUS_OK;
374 error:
375 TALLOC_FREE(mem_ctx);
376 return status;
379 static NTSTATUS registry_getsd(TALLOC_CTX *mem_ctx,
380 struct rpc_pipe_client *pipe_hnd,
381 struct policy_handle *key_hnd,
382 uint32_t sec_info,
383 struct KeySecurityData *sd)
385 return rpccli_winreg_GetKeySecurity(pipe_hnd, mem_ctx, key_hnd,
386 sec_info, sd, NULL);
390 static NTSTATUS registry_setvalue(TALLOC_CTX *mem_ctx,
391 struct rpc_pipe_client *pipe_hnd,
392 struct policy_handle *key_hnd,
393 const char *name,
394 const struct registry_value *value)
396 struct winreg_String name_string;
397 DATA_BLOB blob;
398 NTSTATUS result;
399 WERROR err;
401 err = registry_push_value(mem_ctx, value, &blob);
402 if (!W_ERROR_IS_OK(err)) {
403 return werror_to_ntstatus(err);
406 ZERO_STRUCT(name_string);
408 name_string.name = name;
409 result = rpccli_winreg_SetValue(pipe_hnd, blob.data, key_hnd,
410 name_string, value->type,
411 blob.data, blob.length, NULL);
412 TALLOC_FREE(blob.data);
413 return result;
416 static NTSTATUS rpc_registry_setvalue_internal(struct net_context *c,
417 const struct dom_sid *domain_sid,
418 const char *domain_name,
419 struct cli_state *cli,
420 struct rpc_pipe_client *pipe_hnd,
421 TALLOC_CTX *mem_ctx,
422 int argc,
423 const char **argv )
425 struct policy_handle hive_hnd, key_hnd;
426 NTSTATUS status;
427 struct registry_value value;
429 status = registry_openkey(mem_ctx, pipe_hnd, argv[0],
430 SEC_FLAG_MAXIMUM_ALLOWED,
431 &hive_hnd, &key_hnd);
432 if (!NT_STATUS_IS_OK(status)) {
433 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
434 nt_errstr(status));
435 return status;
438 if (!strequal(argv[2], "multi_sz") && (argc != 4)) {
439 d_fprintf(stderr, _("Too many args for type %s\n"), argv[2]);
440 return NT_STATUS_NOT_IMPLEMENTED;
443 if (strequal(argv[2], "dword")) {
444 value.type = REG_DWORD;
445 value.v.dword = strtoul(argv[3], NULL, 10);
447 else if (strequal(argv[2], "sz")) {
448 value.type = REG_SZ;
449 value.v.sz.len = strlen(argv[3])+1;
450 value.v.sz.str = CONST_DISCARD(char *, argv[3]);
452 else {
453 d_fprintf(stderr, _("type \"%s\" not implemented\n"), argv[2]);
454 status = NT_STATUS_NOT_IMPLEMENTED;
455 goto error;
458 status = registry_setvalue(mem_ctx, pipe_hnd, &key_hnd,
459 argv[1], &value);
461 if (!NT_STATUS_IS_OK(status)) {
462 d_fprintf(stderr, _("registry_setvalue failed: %s\n"),
463 nt_errstr(status));
466 error:
467 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &key_hnd, NULL);
468 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd, NULL);
470 return NT_STATUS_OK;
473 static int rpc_registry_setvalue(struct net_context *c, int argc,
474 const char **argv )
476 if (argc < 4 || c->display_usage) {
477 d_fprintf(stderr, "%s\n%s",
478 _("Usage:"),
479 _("net rpc registry setvalue <key> <valuename> "
480 "<type> [<val>]+\n"));
481 return -1;
484 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
485 rpc_registry_setvalue_internal, argc, argv );
488 static NTSTATUS rpc_registry_deletevalue_internal(struct net_context *c,
489 const struct dom_sid *domain_sid,
490 const char *domain_name,
491 struct cli_state *cli,
492 struct rpc_pipe_client *pipe_hnd,
493 TALLOC_CTX *mem_ctx,
494 int argc,
495 const char **argv )
497 struct policy_handle hive_hnd, key_hnd;
498 NTSTATUS status;
499 struct winreg_String valuename;
501 ZERO_STRUCT(valuename);
503 status = registry_openkey(mem_ctx, pipe_hnd, argv[0],
504 SEC_FLAG_MAXIMUM_ALLOWED,
505 &hive_hnd, &key_hnd);
506 if (!NT_STATUS_IS_OK(status)) {
507 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
508 nt_errstr(status));
509 return status;
512 valuename.name = argv[1];
514 status = rpccli_winreg_DeleteValue(pipe_hnd, mem_ctx, &key_hnd,
515 valuename, NULL);
517 if (!NT_STATUS_IS_OK(status)) {
518 d_fprintf(stderr, _("registry_deletevalue failed: %s\n"),
519 nt_errstr(status));
522 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &key_hnd, NULL);
523 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd, NULL);
525 return status;
528 static int rpc_registry_deletevalue(struct net_context *c, int argc,
529 const char **argv )
531 if (argc != 2 || c->display_usage) {
532 d_fprintf(stderr, "%s\n%s",
533 _("Usage:"),
534 _("net rpc registry deletevalue <key> <valuename>\n"));
535 return -1;
538 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
539 rpc_registry_deletevalue_internal, argc, argv );
542 static NTSTATUS rpc_registry_getvalue_internal(struct net_context *c,
543 const struct dom_sid *domain_sid,
544 const char *domain_name,
545 struct cli_state *cli,
546 struct rpc_pipe_client *pipe_hnd,
547 TALLOC_CTX *mem_ctx,
548 bool raw,
549 int argc,
550 const char **argv)
552 struct policy_handle hive_hnd, key_hnd;
553 NTSTATUS status;
554 WERROR werr;
555 struct winreg_String valuename;
556 struct registry_value *value = NULL;
557 enum winreg_Type type = REG_NONE;
558 uint8_t *data = NULL;
559 uint32_t data_size = 0;
560 uint32_t value_length = 0;
561 TALLOC_CTX *tmp_ctx = talloc_stackframe();
563 ZERO_STRUCT(valuename);
565 status = registry_openkey(tmp_ctx, pipe_hnd, argv[0],
566 SEC_FLAG_MAXIMUM_ALLOWED,
567 &hive_hnd, &key_hnd);
568 if (!NT_STATUS_IS_OK(status)) {
569 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
570 nt_errstr(status));
571 return status;
574 valuename.name = argv[1];
577 * call QueryValue once with data == NULL to get the
578 * needed memory size to be allocated, then allocate
579 * data buffer and call again.
581 status = rpccli_winreg_QueryValue(pipe_hnd, tmp_ctx, &key_hnd,
582 &valuename,
583 &type,
584 data,
585 &data_size,
586 &value_length,
587 NULL);
589 if (!NT_STATUS_IS_OK(status)) {
590 d_fprintf(stderr, _("registry_queryvalue failed: %s\n"),
591 nt_errstr(status));
592 goto done;
595 data = (uint8 *)TALLOC(tmp_ctx, data_size);
596 value_length = 0;
598 status = rpccli_winreg_QueryValue(pipe_hnd, tmp_ctx, &key_hnd,
599 &valuename,
600 &type,
601 data,
602 &data_size,
603 &value_length,
604 NULL);
606 if (!NT_STATUS_IS_OK(status)) {
607 d_fprintf(stderr, _("registry_queryvalue failed: %s\n"),
608 nt_errstr(status));
609 goto done;
612 werr = registry_pull_value(tmp_ctx, &value, type, data,
613 data_size, value_length);
614 if (!W_ERROR_IS_OK(werr)) {
615 status = werror_to_ntstatus(werr);
616 goto done;
619 print_registry_value(value, raw);
621 done:
622 rpccli_winreg_CloseKey(pipe_hnd, tmp_ctx, &key_hnd, NULL);
623 rpccli_winreg_CloseKey(pipe_hnd, tmp_ctx, &hive_hnd, NULL);
625 TALLOC_FREE(tmp_ctx);
627 return status;
630 static NTSTATUS rpc_registry_getvalue_full(struct net_context *c,
631 const struct dom_sid *domain_sid,
632 const char *domain_name,
633 struct cli_state *cli,
634 struct rpc_pipe_client *pipe_hnd,
635 TALLOC_CTX *mem_ctx,
636 int argc,
637 const char **argv)
639 return rpc_registry_getvalue_internal(c, domain_sid, domain_name,
640 cli, pipe_hnd, mem_ctx, false,
641 argc, argv);
644 static int rpc_registry_getvalue(struct net_context *c, int argc,
645 const char **argv)
647 if (argc != 2 || c->display_usage) {
648 d_fprintf(stderr, "%s\n%s",
649 _("Usage:"),
650 _("net rpc registry getvalue <key> <valuename>\n"));
651 return -1;
654 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
655 rpc_registry_getvalue_full, argc, argv);
658 static NTSTATUS rpc_registry_getvalue_raw(struct net_context *c,
659 const struct dom_sid *domain_sid,
660 const char *domain_name,
661 struct cli_state *cli,
662 struct rpc_pipe_client *pipe_hnd,
663 TALLOC_CTX *mem_ctx,
664 int argc,
665 const char **argv)
667 return rpc_registry_getvalue_internal(c, domain_sid, domain_name,
668 cli, pipe_hnd, mem_ctx, true,
669 argc, argv);
672 static int rpc_registry_getvalueraw(struct net_context *c, int argc,
673 const char **argv)
675 if (argc != 2 || c->display_usage) {
676 d_fprintf(stderr, "%s\n%s",
677 _("Usage:"),
678 _("net rpc registry getvalue <key> <valuename>\n"));
679 return -1;
682 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
683 rpc_registry_getvalue_raw, argc, argv);
686 static NTSTATUS rpc_registry_createkey_internal(struct net_context *c,
687 const struct dom_sid *domain_sid,
688 const char *domain_name,
689 struct cli_state *cli,
690 struct rpc_pipe_client *pipe_hnd,
691 TALLOC_CTX *mem_ctx,
692 int argc,
693 const char **argv )
695 uint32 hive;
696 struct policy_handle hive_hnd, key_hnd;
697 struct winreg_String key, keyclass;
698 enum winreg_CreateAction action;
699 NTSTATUS status;
701 ZERO_STRUCT(key);
702 ZERO_STRUCT(keyclass);
704 if (!reg_hive_key(mem_ctx, argv[0], &hive, &key.name)) {
705 return NT_STATUS_INVALID_PARAMETER;
708 status = rpccli_winreg_Connect(pipe_hnd, mem_ctx, hive,
709 SEC_FLAG_MAXIMUM_ALLOWED,
710 &hive_hnd);
711 if (!(NT_STATUS_IS_OK(status))) {
712 return status;
715 action = REG_ACTION_NONE;
716 keyclass.name = "";
718 status = rpccli_winreg_CreateKey(pipe_hnd, mem_ctx, &hive_hnd, key,
719 keyclass, 0, REG_KEY_READ, NULL,
720 &key_hnd, &action, NULL);
721 if (!NT_STATUS_IS_OK(status)) {
722 d_fprintf(stderr, _("createkey returned %s\n"),
723 nt_errstr(status));
724 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd, NULL);
725 return status;
728 switch (action) {
729 case REG_ACTION_NONE:
730 d_printf(_("createkey did nothing -- huh?\n"));
731 break;
732 case REG_CREATED_NEW_KEY:
733 d_printf(_("createkey created %s\n"), argv[0]);
734 break;
735 case REG_OPENED_EXISTING_KEY:
736 d_printf(_("createkey opened existing %s\n"), argv[0]);
737 break;
740 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &key_hnd, NULL);
741 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd, NULL);
743 return status;
746 static int rpc_registry_createkey(struct net_context *c, int argc,
747 const char **argv )
749 if (argc != 1 || c->display_usage) {
750 d_fprintf(stderr, "%s\n%s",
751 _("Usage:"),
752 _("net rpc registry createkey <key>\n"));
753 return -1;
756 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
757 rpc_registry_createkey_internal, argc, argv );
760 static NTSTATUS rpc_registry_deletekey_internal(struct net_context *c,
761 const struct dom_sid *domain_sid,
762 const char *domain_name,
763 struct cli_state *cli,
764 struct rpc_pipe_client *pipe_hnd,
765 TALLOC_CTX *mem_ctx,
766 int argc,
767 const char **argv )
769 uint32 hive;
770 struct policy_handle hive_hnd;
771 struct winreg_String key;
772 NTSTATUS status;
774 ZERO_STRUCT(key);
776 if (!reg_hive_key(mem_ctx, argv[0], &hive, &key.name)) {
777 return NT_STATUS_INVALID_PARAMETER;
780 status = rpccli_winreg_Connect(pipe_hnd, mem_ctx, hive,
781 SEC_FLAG_MAXIMUM_ALLOWED,
782 &hive_hnd);
783 if (!(NT_STATUS_IS_OK(status))) {
784 return status;
787 status = rpccli_winreg_DeleteKey(pipe_hnd, mem_ctx, &hive_hnd, key, NULL);
788 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd, NULL);
790 if (!NT_STATUS_IS_OK(status)) {
791 d_fprintf(stderr, _("deletekey returned %s\n"),
792 nt_errstr(status));
795 return status;
798 static int rpc_registry_deletekey(struct net_context *c, int argc, const char **argv )
800 if (argc != 1 || c->display_usage) {
801 d_fprintf(stderr, "%s\n%s",
802 _("Usage:"),
803 _("net rpc registry deletekey <key>\n"));
804 return -1;
807 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
808 rpc_registry_deletekey_internal, argc, argv );
811 /********************************************************************
812 ********************************************************************/
814 static NTSTATUS rpc_registry_enumerate_internal(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 struct policy_handle pol_hive, pol_key;
824 NTSTATUS status;
825 uint32 num_subkeys = 0;
826 uint32 num_values = 0;
827 char **names = NULL, **classes = NULL;
828 NTTIME **modtimes = NULL;
829 uint32 i;
830 struct registry_value **values = NULL;
832 if (argc != 1 || c->display_usage) {
833 d_printf("%s\n%s",
834 _("Usage:"),
835 _("net rpc registry enumerate <path>\n"));
836 d_printf("%s net rpc registry enumerate "
837 "'HKLM\\Software\\Samba'\n", _("Example:"));
838 return NT_STATUS_INVALID_PARAMETER;
841 status = registry_openkey(mem_ctx, pipe_hnd, argv[0], REG_KEY_READ,
842 &pol_hive, &pol_key);
843 if (!NT_STATUS_IS_OK(status)) {
844 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
845 nt_errstr(status));
846 return status;
849 status = registry_enumkeys(mem_ctx, pipe_hnd, &pol_key, &num_subkeys,
850 &names, &classes, &modtimes);
851 if (!NT_STATUS_IS_OK(status)) {
852 d_fprintf(stderr, _("enumerating keys failed: %s\n"),
853 nt_errstr(status));
854 return status;
857 for (i=0; i<num_subkeys; i++) {
858 print_registry_key(names[i], modtimes[i]);
861 status = registry_enumvalues(mem_ctx, pipe_hnd, &pol_key, &num_values,
862 &names, &values);
863 if (!NT_STATUS_IS_OK(status)) {
864 d_fprintf(stderr, _("enumerating values failed: %s\n"),
865 nt_errstr(status));
866 return status;
869 for (i=0; i<num_values; i++) {
870 print_registry_value_with_name(names[i], values[i]);
873 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_key, NULL);
874 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_hive, NULL);
876 return status;
879 /********************************************************************
880 ********************************************************************/
882 static int rpc_registry_enumerate(struct net_context *c, int argc,
883 const char **argv )
885 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
886 rpc_registry_enumerate_internal, argc, argv );
889 /********************************************************************
890 ********************************************************************/
892 static NTSTATUS rpc_registry_save_internal(struct net_context *c,
893 const struct dom_sid *domain_sid,
894 const char *domain_name,
895 struct cli_state *cli,
896 struct rpc_pipe_client *pipe_hnd,
897 TALLOC_CTX *mem_ctx,
898 int argc,
899 const char **argv )
901 WERROR result = WERR_GENERAL_FAILURE;
902 struct policy_handle pol_hive, pol_key;
903 NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
904 struct winreg_String filename;
906 if (argc != 2 || c->display_usage) {
907 d_printf("%s\n%s",
908 _("Usage:"),
909 _("net rpc registry backup <path> <file> \n"));
910 return NT_STATUS_INVALID_PARAMETER;
913 status = registry_openkey(mem_ctx, pipe_hnd, argv[0], REG_KEY_ALL,
914 &pol_hive, &pol_key);
915 if (!NT_STATUS_IS_OK(status)) {
916 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
917 nt_errstr(status));
918 return status;
921 filename.name = argv[1];
922 status = rpccli_winreg_SaveKey( pipe_hnd, mem_ctx, &pol_key, &filename, NULL, NULL);
923 if ( !W_ERROR_IS_OK(result) ) {
924 d_fprintf(stderr, _("Unable to save [%s] to %s:%s\n"), argv[0],
925 cli->desthost, argv[1]);
928 /* cleanup */
930 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_key, NULL);
931 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_hive, NULL);
933 return status;
936 /********************************************************************
937 ********************************************************************/
939 static int rpc_registry_save(struct net_context *c, int argc, const char **argv )
941 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
942 rpc_registry_save_internal, argc, argv );
946 /********************************************************************
947 ********************************************************************/
949 static void dump_values( REGF_NK_REC *nk )
951 int i, j;
952 const char *data_str = NULL;
953 uint32 data_size, data;
954 DATA_BLOB blob;
956 if ( !nk->values )
957 return;
959 for ( i=0; i<nk->num_values; i++ ) {
960 d_printf( "\"%s\" = ", nk->values[i].valuename ? nk->values[i].valuename : "(default)" );
961 d_printf( "(%s) ", str_regtype( nk->values[i].type ) );
963 data_size = nk->values[i].data_size & ~VK_DATA_IN_OFFSET;
964 switch ( nk->values[i].type ) {
965 case REG_SZ:
966 blob = data_blob_const(nk->values[i].data, data_size);
967 pull_reg_sz(talloc_tos(), &blob, &data_str);
968 if (!data_str) {
969 break;
971 d_printf( "%s", data_str );
972 break;
973 case REG_MULTI_SZ:
974 case REG_EXPAND_SZ:
975 for ( j=0; j<data_size; j++ ) {
976 d_printf( "%c", nk->values[i].data[j] );
978 break;
979 case REG_DWORD:
980 data = IVAL( nk->values[i].data, 0 );
981 d_printf("0x%x", data );
982 break;
983 case REG_BINARY:
984 for ( j=0; j<data_size; j++ ) {
985 d_printf( "%x", nk->values[i].data[j] );
987 break;
988 default:
989 d_printf(_("unknown"));
990 break;
993 d_printf( "\n" );
998 /********************************************************************
999 ********************************************************************/
1001 static bool dump_registry_tree( REGF_FILE *file, REGF_NK_REC *nk, const char *parent )
1003 REGF_NK_REC *key;
1005 /* depth first dump of the registry tree */
1007 while ( (key = regfio_fetch_subkey( file, nk )) ) {
1008 char *regpath;
1009 if (asprintf(&regpath, "%s\\%s", parent, key->keyname) < 0) {
1010 break;
1012 d_printf("[%s]\n", regpath );
1013 dump_values( key );
1014 d_printf("\n");
1015 dump_registry_tree( file, key, regpath );
1016 SAFE_FREE(regpath);
1019 return true;
1022 /********************************************************************
1023 ********************************************************************/
1025 static bool write_registry_tree( REGF_FILE *infile, REGF_NK_REC *nk,
1026 REGF_NK_REC *parent, REGF_FILE *outfile,
1027 const char *parentpath )
1029 REGF_NK_REC *key, *subkey;
1030 struct regval_ctr *values = NULL;
1031 struct regsubkey_ctr *subkeys = NULL;
1032 int i;
1033 char *path = NULL;
1034 WERROR werr;
1036 werr = regsubkey_ctr_init(infile->mem_ctx, &subkeys);
1037 if (!W_ERROR_IS_OK(werr)) {
1038 DEBUG(0, ("write_registry_tree: regsubkey_ctr_init failed: "
1039 "%s\n", win_errstr(werr)));
1040 return false;
1043 werr = regval_ctr_init(subkeys, &values);
1044 if (!W_ERROR_IS_OK(werr)) {
1045 DEBUG(0,("write_registry_tree: talloc() failed!\n"));
1046 TALLOC_FREE(subkeys);
1047 return false;
1050 /* copy values into the struct regval_ctr */
1052 for ( i=0; i<nk->num_values; i++ ) {
1053 regval_ctr_addvalue( values, nk->values[i].valuename, nk->values[i].type,
1054 nk->values[i].data, (nk->values[i].data_size & ~VK_DATA_IN_OFFSET) );
1057 /* copy subkeys into the struct regsubkey_ctr */
1059 while ( (subkey = regfio_fetch_subkey( infile, nk )) ) {
1060 regsubkey_ctr_addkey( subkeys, subkey->keyname );
1063 key = regfio_write_key( outfile, nk->keyname, values, subkeys, nk->sec_desc->sec_desc, parent );
1065 /* write each one of the subkeys out */
1067 path = talloc_asprintf(subkeys,
1068 "%s%s%s",
1069 parentpath,
1070 parent ? "\\" : "",
1071 nk->keyname);
1072 if (!path) {
1073 TALLOC_FREE(subkeys);
1074 return false;
1077 nk->subkey_index = 0;
1078 while ( (subkey = regfio_fetch_subkey( infile, nk )) ) {
1079 write_registry_tree( infile, subkey, key, outfile, path );
1082 d_printf("[%s]\n", path );
1083 TALLOC_FREE(subkeys);
1085 return true;
1088 /********************************************************************
1089 ********************************************************************/
1091 static int rpc_registry_dump(struct net_context *c, int argc, const char **argv)
1093 REGF_FILE *registry;
1094 REGF_NK_REC *nk;
1096 if (argc != 1 || c->display_usage) {
1097 d_printf("%s\n%s",
1098 _("Usage:"),
1099 _("net rpc registry dump <file> \n"));
1100 return -1;
1103 d_printf(_("Opening %s...."), argv[0]);
1104 if ( !(registry = regfio_open( argv[0], O_RDONLY, 0)) ) {
1105 d_fprintf(stderr, _("Failed to open %s for reading\n"),argv[0]);
1106 return 1;
1108 d_printf(_("ok\n"));
1110 /* get the root of the registry file */
1112 if ((nk = regfio_rootkey( registry )) == NULL) {
1113 d_fprintf(stderr, _("Could not get rootkey\n"));
1114 regfio_close( registry );
1115 return 1;
1117 d_printf("[%s]\n", nk->keyname);
1118 dump_values( nk );
1119 d_printf("\n");
1121 dump_registry_tree( registry, nk, nk->keyname );
1123 #if 0
1124 talloc_report_full( registry->mem_ctx, stderr );
1125 #endif
1126 d_printf(_("Closing registry..."));
1127 regfio_close( registry );
1128 d_printf(_("ok\n"));
1130 return 0;
1133 /********************************************************************
1134 ********************************************************************/
1136 static int rpc_registry_copy(struct net_context *c, int argc, const char **argv )
1138 REGF_FILE *infile = NULL, *outfile = NULL;
1139 REGF_NK_REC *nk;
1140 int result = 1;
1142 if (argc != 2 || c->display_usage) {
1143 d_printf("%s\n%s",
1144 _("Usage:"),
1145 _("net rpc registry copy <srcfile> <newfile>\n"));
1146 return -1;
1149 d_printf(_("Opening %s...."), argv[0]);
1150 if ( !(infile = regfio_open( argv[0], O_RDONLY, 0 )) ) {
1151 d_fprintf(stderr, _("Failed to open %s for reading\n"),argv[0]);
1152 return 1;
1154 d_printf(_("ok\n"));
1156 d_printf(_("Opening %s...."), argv[1]);
1157 if ( !(outfile = regfio_open( argv[1], (O_RDWR|O_CREAT|O_TRUNC), (S_IREAD|S_IWRITE) )) ) {
1158 d_fprintf(stderr, _("Failed to open %s for writing\n"),argv[1]);
1159 goto out;
1161 d_printf(_("ok\n"));
1163 /* get the root of the registry file */
1165 if ((nk = regfio_rootkey( infile )) == NULL) {
1166 d_fprintf(stderr, _("Could not get rootkey\n"));
1167 goto out;
1169 d_printf(_("RootKey: [%s]\n"), nk->keyname);
1171 write_registry_tree( infile, nk, NULL, outfile, "" );
1173 result = 0;
1175 out:
1177 d_printf(_("Closing %s..."), argv[1]);
1178 if (outfile) {
1179 regfio_close( outfile );
1181 d_printf(_("ok\n"));
1183 d_printf(_("Closing %s..."), argv[0]);
1184 if (infile) {
1185 regfio_close( infile );
1187 d_printf(_("ok\n"));
1189 return( result);
1192 /********************************************************************
1193 ********************************************************************/
1195 static NTSTATUS rpc_registry_getsd_internal(struct net_context *c,
1196 const struct dom_sid *domain_sid,
1197 const char *domain_name,
1198 struct cli_state *cli,
1199 struct rpc_pipe_client *pipe_hnd,
1200 TALLOC_CTX *mem_ctx,
1201 int argc,
1202 const char **argv)
1204 struct policy_handle pol_hive, pol_key;
1205 NTSTATUS status;
1206 enum ndr_err_code ndr_err;
1207 struct KeySecurityData *sd = NULL;
1208 uint32_t sec_info;
1209 DATA_BLOB blob;
1210 struct security_descriptor sec_desc;
1211 uint32_t access_mask = REG_KEY_READ |
1212 SEC_FLAG_MAXIMUM_ALLOWED |
1213 SEC_FLAG_SYSTEM_SECURITY;
1215 if (argc <1 || argc > 2 || c->display_usage) {
1216 d_printf("%s\n%s",
1217 _("Usage:"),
1218 _("net rpc registry getsd <path> <secinfo>\n"));
1219 d_printf("%s net rpc registry getsd "
1220 "'HKLM\\Software\\Samba'\n", _("Example:"));
1221 return NT_STATUS_INVALID_PARAMETER;
1224 status = registry_openkey(mem_ctx, pipe_hnd, argv[0],
1225 access_mask,
1226 &pol_hive, &pol_key);
1227 if (!NT_STATUS_IS_OK(status)) {
1228 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
1229 nt_errstr(status));
1230 return status;
1233 sd = TALLOC_ZERO_P(mem_ctx, struct KeySecurityData);
1234 if (!sd) {
1235 status = NT_STATUS_NO_MEMORY;
1236 goto out;
1239 sd->size = 0x1000;
1241 if (argc >= 2) {
1242 sscanf(argv[1], "%x", &sec_info);
1243 } else {
1244 sec_info = SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL;
1247 status = registry_getsd(mem_ctx, pipe_hnd, &pol_key, sec_info, sd);
1248 if (!NT_STATUS_IS_OK(status)) {
1249 d_fprintf(stderr, _("getting sd failed: %s\n"),
1250 nt_errstr(status));
1251 goto out;
1254 blob.data = sd->data;
1255 blob.length = sd->size;
1257 ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &sec_desc,
1258 (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
1259 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1260 status = ndr_map_error2ntstatus(ndr_err);
1261 goto out;
1263 status = NT_STATUS_OK;
1265 display_sec_desc(&sec_desc);
1267 out:
1268 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_key, NULL);
1269 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_hive, NULL);
1271 return status;
1275 static int rpc_registry_getsd(struct net_context *c, int argc, const char **argv)
1277 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
1278 rpc_registry_getsd_internal, argc, argv);
1281 /********************************************************************
1282 ********************************************************************/
1284 int net_rpc_registry(struct net_context *c, int argc, const char **argv)
1286 struct functable func[] = {
1288 "enumerate",
1289 rpc_registry_enumerate,
1290 NET_TRANSPORT_RPC,
1291 N_("Enumerate registry keys and values"),
1292 N_("net rpc registry enumerate\n"
1293 " Enumerate registry keys and values")
1296 "createkey",
1297 rpc_registry_createkey,
1298 NET_TRANSPORT_RPC,
1299 N_("Create a new registry key"),
1300 N_("net rpc registry createkey\n"
1301 " Create a new registry key")
1304 "deletekey",
1305 rpc_registry_deletekey,
1306 NET_TRANSPORT_RPC,
1307 N_("Delete a registry key"),
1308 N_("net rpc registry deletekey\n"
1309 " Delete a registry key")
1312 "getvalue",
1313 rpc_registry_getvalue,
1314 NET_TRANSPORT_RPC,
1315 N_("Print a registry value"),
1316 N_("net rpc registry getvalue\n"
1317 " Print a registry value")
1320 "getvalueraw",
1321 rpc_registry_getvalueraw,
1322 NET_TRANSPORT_RPC,
1323 N_("Print a registry value"),
1324 N_("net rpc registry getvalueraw\n"
1325 " Print a registry value (raw version)")
1328 "setvalue",
1329 rpc_registry_setvalue,
1330 NET_TRANSPORT_RPC,
1331 N_("Set a new registry value"),
1332 N_("net rpc registry setvalue\n"
1333 " Set a new registry value")
1336 "deletevalue",
1337 rpc_registry_deletevalue,
1338 NET_TRANSPORT_RPC,
1339 N_("Delete a registry value"),
1340 N_("net rpc registry deletevalue\n"
1341 " Delete a registry value")
1344 "save",
1345 rpc_registry_save,
1346 NET_TRANSPORT_RPC,
1347 N_("Save a registry file"),
1348 N_("net rpc registry save\n"
1349 " Save a registry file")
1352 "dump",
1353 rpc_registry_dump,
1354 NET_TRANSPORT_RPC,
1355 N_("Dump a registry file"),
1356 N_("net rpc registry dump\n"
1357 " Dump a registry file")
1360 "copy",
1361 rpc_registry_copy,
1362 NET_TRANSPORT_RPC,
1363 N_("Copy a registry file"),
1364 N_("net rpc registry copy\n"
1365 " Copy a registry file")
1368 "getsd",
1369 rpc_registry_getsd,
1370 NET_TRANSPORT_RPC,
1371 N_("Get security descriptor"),
1372 N_("net rpc registry getsd\n"
1373 " Get security descriptior")
1375 {NULL, NULL, 0, NULL, NULL}
1378 return net_run_function(c, argc, argv, "net rpc registry", func);