s3-net: let rpccli_winreg_Connect optionally return WERROR
[Samba.git] / source3 / utils / net_rpc_registry.c
blob8e9f27bd525fe52ce5116de1fe4d0ca5e7e38767
1 /*
2 Samba Unix/Linux SMB client library
3 Distributed SMB/CIFS Server Management Utility
5 Copyright (C) Gerald (Jerry) Carter 2005-2006
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
20 #include "includes.h"
21 #include "popt_common.h"
22 #include "registry.h"
23 #include "utils/net.h"
24 #include "utils/net_registry_util.h"
25 #include "registry/regfio.h"
26 #include "../librpc/gen_ndr/cli_winreg.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, WERROR *werr)
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, werr);
46 case HKEY_LOCAL_MACHINE:
47 return rpccli_winreg_OpenHKLM( cli, mem_ctx, NULL,
48 access_mask, reg_hnd, werr);
50 case HKEY_USERS:
51 return rpccli_winreg_OpenHKU( cli, mem_ctx, NULL,
52 access_mask, reg_hnd, werr);
54 case HKEY_CURRENT_USER:
55 return rpccli_winreg_OpenHKCU( cli, mem_ctx, NULL,
56 access_mask, reg_hnd, werr);
58 case HKEY_PERFORMANCE_DATA:
59 return rpccli_winreg_OpenHKPD( cli, mem_ctx, NULL,
60 access_mask, reg_hnd, werr);
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, NULL);
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 values[i] = talloc_zero(values, struct registry_value);
356 if (values[i] == NULL) {
357 status = NT_STATUS_NO_MEMORY;
358 goto error;
361 values[i]->type = type;
362 values[i]->data = data_blob_talloc(values[i], data, data_size);
365 *pnum_values = num_values;
367 if (pvalnames) {
368 *pvalnames = talloc_move(ctx, &names);
370 if (pvalues) {
371 *pvalues = talloc_move(ctx, &values);
374 status = NT_STATUS_OK;
376 error:
377 TALLOC_FREE(mem_ctx);
378 return status;
381 static NTSTATUS registry_getsd(TALLOC_CTX *mem_ctx,
382 struct rpc_pipe_client *pipe_hnd,
383 struct policy_handle *key_hnd,
384 uint32_t sec_info,
385 struct KeySecurityData *sd)
387 return rpccli_winreg_GetKeySecurity(pipe_hnd, mem_ctx, key_hnd,
388 sec_info, sd, NULL);
392 static NTSTATUS registry_setvalue(TALLOC_CTX *mem_ctx,
393 struct rpc_pipe_client *pipe_hnd,
394 struct policy_handle *key_hnd,
395 const char *name,
396 const struct registry_value *value)
398 struct winreg_String name_string;
399 NTSTATUS result;
401 ZERO_STRUCT(name_string);
403 name_string.name = name;
404 result = rpccli_winreg_SetValue(pipe_hnd, mem_ctx, key_hnd,
405 name_string, value->type,
406 value->data.data, value->data.length, NULL);
407 return result;
410 static NTSTATUS rpc_registry_setvalue_internal(struct net_context *c,
411 const struct dom_sid *domain_sid,
412 const char *domain_name,
413 struct cli_state *cli,
414 struct rpc_pipe_client *pipe_hnd,
415 TALLOC_CTX *mem_ctx,
416 int argc,
417 const char **argv )
419 struct policy_handle hive_hnd, key_hnd;
420 NTSTATUS status;
421 struct registry_value value;
423 status = registry_openkey(mem_ctx, pipe_hnd, argv[0],
424 SEC_FLAG_MAXIMUM_ALLOWED,
425 &hive_hnd, &key_hnd);
426 if (!NT_STATUS_IS_OK(status)) {
427 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
428 nt_errstr(status));
429 return status;
432 if (!strequal(argv[2], "multi_sz") && (argc != 4)) {
433 d_fprintf(stderr, _("Too many args for type %s\n"), argv[2]);
434 return NT_STATUS_NOT_IMPLEMENTED;
437 if (strequal(argv[2], "dword")) {
438 uint32_t v = strtoul(argv[3], NULL, 10);
439 value.type = REG_DWORD;
440 value.data = data_blob_talloc(mem_ctx, NULL, 4);
441 SIVAL(value.data.data, 0, v);
443 else if (strequal(argv[2], "sz")) {
444 value.type = REG_SZ;
445 if (!push_reg_sz(mem_ctx, &value.data, argv[3])) {
446 status = NT_STATUS_NO_MEMORY;
447 goto error;
450 else {
451 d_fprintf(stderr, _("type \"%s\" not implemented\n"), argv[2]);
452 status = NT_STATUS_NOT_IMPLEMENTED;
453 goto error;
456 status = registry_setvalue(mem_ctx, pipe_hnd, &key_hnd,
457 argv[1], &value);
459 if (!NT_STATUS_IS_OK(status)) {
460 d_fprintf(stderr, _("registry_setvalue failed: %s\n"),
461 nt_errstr(status));
464 error:
465 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &key_hnd, NULL);
466 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd, NULL);
468 return NT_STATUS_OK;
471 static int rpc_registry_setvalue(struct net_context *c, int argc,
472 const char **argv )
474 if (argc < 4 || c->display_usage) {
475 d_fprintf(stderr, "%s\n%s",
476 _("Usage:"),
477 _("net rpc registry setvalue <key> <valuename> "
478 "<type> [<val>]+\n"));
479 return -1;
482 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
483 rpc_registry_setvalue_internal, argc, argv );
486 static NTSTATUS rpc_registry_deletevalue_internal(struct net_context *c,
487 const struct dom_sid *domain_sid,
488 const char *domain_name,
489 struct cli_state *cli,
490 struct rpc_pipe_client *pipe_hnd,
491 TALLOC_CTX *mem_ctx,
492 int argc,
493 const char **argv )
495 struct policy_handle hive_hnd, key_hnd;
496 NTSTATUS status;
497 struct winreg_String valuename;
499 ZERO_STRUCT(valuename);
501 status = registry_openkey(mem_ctx, pipe_hnd, argv[0],
502 SEC_FLAG_MAXIMUM_ALLOWED,
503 &hive_hnd, &key_hnd);
504 if (!NT_STATUS_IS_OK(status)) {
505 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
506 nt_errstr(status));
507 return status;
510 valuename.name = argv[1];
512 status = rpccli_winreg_DeleteValue(pipe_hnd, mem_ctx, &key_hnd,
513 valuename, NULL);
515 if (!NT_STATUS_IS_OK(status)) {
516 d_fprintf(stderr, _("registry_deletevalue failed: %s\n"),
517 nt_errstr(status));
520 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &key_hnd, NULL);
521 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd, NULL);
523 return status;
526 static int rpc_registry_deletevalue(struct net_context *c, int argc,
527 const char **argv )
529 if (argc != 2 || c->display_usage) {
530 d_fprintf(stderr, "%s\n%s",
531 _("Usage:"),
532 _("net rpc registry deletevalue <key> <valuename>\n"));
533 return -1;
536 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
537 rpc_registry_deletevalue_internal, argc, argv );
540 static NTSTATUS rpc_registry_getvalue_internal(struct net_context *c,
541 const struct dom_sid *domain_sid,
542 const char *domain_name,
543 struct cli_state *cli,
544 struct rpc_pipe_client *pipe_hnd,
545 TALLOC_CTX *mem_ctx,
546 bool raw,
547 int argc,
548 const char **argv)
550 struct policy_handle hive_hnd, key_hnd;
551 NTSTATUS status;
552 struct winreg_String valuename;
553 struct registry_value *value = NULL;
554 enum winreg_Type type = REG_NONE;
555 uint32_t data_size = 0;
556 uint32_t value_length = 0;
557 TALLOC_CTX *tmp_ctx = talloc_stackframe();
559 ZERO_STRUCT(valuename);
561 status = registry_openkey(tmp_ctx, pipe_hnd, argv[0],
562 SEC_FLAG_MAXIMUM_ALLOWED,
563 &hive_hnd, &key_hnd);
564 if (!NT_STATUS_IS_OK(status)) {
565 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
566 nt_errstr(status));
567 return status;
570 valuename.name = argv[1];
572 value = talloc_zero(tmp_ctx, struct registry_value);
573 if (value == NULL) {
574 return NT_STATUS_NO_MEMORY;
578 * call QueryValue once with data == NULL to get the
579 * needed memory size to be allocated, then allocate
580 * data buffer and call again.
582 status = rpccli_winreg_QueryValue(pipe_hnd, tmp_ctx, &key_hnd,
583 &valuename,
584 &type,
585 NULL,
586 &data_size,
587 &value_length,
588 NULL);
590 if (!NT_STATUS_IS_OK(status)) {
591 d_fprintf(stderr, _("registry_queryvalue failed: %s\n"),
592 nt_errstr(status));
593 goto done;
596 value->data = data_blob_talloc(tmp_ctx, NULL, data_size);
598 status = rpccli_winreg_QueryValue(pipe_hnd, tmp_ctx, &key_hnd,
599 &valuename,
600 &type,
601 value->data.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 value->type = type;
614 print_registry_value(value, raw);
616 done:
617 rpccli_winreg_CloseKey(pipe_hnd, tmp_ctx, &key_hnd, NULL);
618 rpccli_winreg_CloseKey(pipe_hnd, tmp_ctx, &hive_hnd, NULL);
620 TALLOC_FREE(tmp_ctx);
622 return status;
625 static NTSTATUS rpc_registry_getvalue_full(struct net_context *c,
626 const struct dom_sid *domain_sid,
627 const char *domain_name,
628 struct cli_state *cli,
629 struct rpc_pipe_client *pipe_hnd,
630 TALLOC_CTX *mem_ctx,
631 int argc,
632 const char **argv)
634 return rpc_registry_getvalue_internal(c, domain_sid, domain_name,
635 cli, pipe_hnd, mem_ctx, false,
636 argc, argv);
639 static int rpc_registry_getvalue(struct net_context *c, int argc,
640 const char **argv)
642 if (argc != 2 || c->display_usage) {
643 d_fprintf(stderr, "%s\n%s",
644 _("Usage:"),
645 _("net rpc registry getvalue <key> <valuename>\n"));
646 return -1;
649 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
650 rpc_registry_getvalue_full, argc, argv);
653 static NTSTATUS rpc_registry_getvalue_raw(struct net_context *c,
654 const struct dom_sid *domain_sid,
655 const char *domain_name,
656 struct cli_state *cli,
657 struct rpc_pipe_client *pipe_hnd,
658 TALLOC_CTX *mem_ctx,
659 int argc,
660 const char **argv)
662 return rpc_registry_getvalue_internal(c, domain_sid, domain_name,
663 cli, pipe_hnd, mem_ctx, true,
664 argc, argv);
667 static int rpc_registry_getvalueraw(struct net_context *c, int argc,
668 const char **argv)
670 if (argc != 2 || c->display_usage) {
671 d_fprintf(stderr, "%s\n%s",
672 _("Usage:"),
673 _("net rpc registry getvalue <key> <valuename>\n"));
674 return -1;
677 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
678 rpc_registry_getvalue_raw, argc, argv);
681 static NTSTATUS rpc_registry_createkey_internal(struct net_context *c,
682 const struct dom_sid *domain_sid,
683 const char *domain_name,
684 struct cli_state *cli,
685 struct rpc_pipe_client *pipe_hnd,
686 TALLOC_CTX *mem_ctx,
687 int argc,
688 const char **argv )
690 uint32 hive;
691 struct policy_handle hive_hnd, key_hnd;
692 struct winreg_String key, keyclass;
693 enum winreg_CreateAction action;
694 NTSTATUS status;
696 ZERO_STRUCT(key);
697 ZERO_STRUCT(keyclass);
699 if (!reg_hive_key(mem_ctx, argv[0], &hive, &key.name)) {
700 return NT_STATUS_INVALID_PARAMETER;
703 status = rpccli_winreg_Connect(pipe_hnd, mem_ctx, hive,
704 SEC_FLAG_MAXIMUM_ALLOWED,
705 &hive_hnd, NULL);
706 if (!(NT_STATUS_IS_OK(status))) {
707 return status;
710 action = REG_ACTION_NONE;
711 keyclass.name = "";
713 status = rpccli_winreg_CreateKey(pipe_hnd, mem_ctx, &hive_hnd, key,
714 keyclass, 0, REG_KEY_READ, NULL,
715 &key_hnd, &action, NULL);
716 if (!NT_STATUS_IS_OK(status)) {
717 d_fprintf(stderr, _("createkey returned %s\n"),
718 nt_errstr(status));
719 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd, NULL);
720 return status;
723 switch (action) {
724 case REG_ACTION_NONE:
725 d_printf(_("createkey did nothing -- huh?\n"));
726 break;
727 case REG_CREATED_NEW_KEY:
728 d_printf(_("createkey created %s\n"), argv[0]);
729 break;
730 case REG_OPENED_EXISTING_KEY:
731 d_printf(_("createkey opened existing %s\n"), argv[0]);
732 break;
735 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &key_hnd, NULL);
736 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd, NULL);
738 return status;
741 static int rpc_registry_createkey(struct net_context *c, int argc,
742 const char **argv )
744 if (argc != 1 || c->display_usage) {
745 d_fprintf(stderr, "%s\n%s",
746 _("Usage:"),
747 _("net rpc registry createkey <key>\n"));
748 return -1;
751 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
752 rpc_registry_createkey_internal, argc, argv );
755 static NTSTATUS rpc_registry_deletekey_internal(struct net_context *c,
756 const struct dom_sid *domain_sid,
757 const char *domain_name,
758 struct cli_state *cli,
759 struct rpc_pipe_client *pipe_hnd,
760 TALLOC_CTX *mem_ctx,
761 int argc,
762 const char **argv )
764 uint32 hive;
765 struct policy_handle hive_hnd;
766 struct winreg_String key;
767 NTSTATUS status;
769 ZERO_STRUCT(key);
771 if (!reg_hive_key(mem_ctx, argv[0], &hive, &key.name)) {
772 return NT_STATUS_INVALID_PARAMETER;
775 status = rpccli_winreg_Connect(pipe_hnd, mem_ctx, hive,
776 SEC_FLAG_MAXIMUM_ALLOWED,
777 &hive_hnd, NULL);
778 if (!(NT_STATUS_IS_OK(status))) {
779 return status;
782 status = rpccli_winreg_DeleteKey(pipe_hnd, mem_ctx, &hive_hnd, key, NULL);
783 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd, NULL);
785 if (!NT_STATUS_IS_OK(status)) {
786 d_fprintf(stderr, _("deletekey returned %s\n"),
787 nt_errstr(status));
790 return status;
793 static int rpc_registry_deletekey(struct net_context *c, int argc, const char **argv )
795 if (argc != 1 || c->display_usage) {
796 d_fprintf(stderr, "%s\n%s",
797 _("Usage:"),
798 _("net rpc registry deletekey <key>\n"));
799 return -1;
802 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
803 rpc_registry_deletekey_internal, argc, argv );
806 /********************************************************************
807 ********************************************************************/
809 static NTSTATUS rpc_registry_enumerate_internal(struct net_context *c,
810 const struct dom_sid *domain_sid,
811 const char *domain_name,
812 struct cli_state *cli,
813 struct rpc_pipe_client *pipe_hnd,
814 TALLOC_CTX *mem_ctx,
815 int argc,
816 const char **argv )
818 struct policy_handle pol_hive, pol_key;
819 NTSTATUS status;
820 uint32 num_subkeys = 0;
821 uint32 num_values = 0;
822 char **names = NULL, **classes = NULL;
823 NTTIME **modtimes = NULL;
824 uint32 i;
825 struct registry_value **values = NULL;
827 if (argc != 1 || c->display_usage) {
828 d_printf("%s\n%s",
829 _("Usage:"),
830 _("net rpc registry enumerate <path>\n"));
831 d_printf("%s net rpc registry enumerate "
832 "'HKLM\\Software\\Samba'\n", _("Example:"));
833 return NT_STATUS_INVALID_PARAMETER;
836 status = registry_openkey(mem_ctx, pipe_hnd, argv[0], REG_KEY_READ,
837 &pol_hive, &pol_key);
838 if (!NT_STATUS_IS_OK(status)) {
839 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
840 nt_errstr(status));
841 return status;
844 status = registry_enumkeys(mem_ctx, pipe_hnd, &pol_key, &num_subkeys,
845 &names, &classes, &modtimes);
846 if (!NT_STATUS_IS_OK(status)) {
847 d_fprintf(stderr, _("enumerating keys failed: %s\n"),
848 nt_errstr(status));
849 return status;
852 for (i=0; i<num_subkeys; i++) {
853 print_registry_key(names[i], modtimes[i]);
856 status = registry_enumvalues(mem_ctx, pipe_hnd, &pol_key, &num_values,
857 &names, &values);
858 if (!NT_STATUS_IS_OK(status)) {
859 d_fprintf(stderr, _("enumerating values failed: %s\n"),
860 nt_errstr(status));
861 return status;
864 for (i=0; i<num_values; i++) {
865 print_registry_value_with_name(names[i], values[i]);
868 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_key, NULL);
869 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_hive, NULL);
871 return status;
874 /********************************************************************
875 ********************************************************************/
877 static int rpc_registry_enumerate(struct net_context *c, int argc,
878 const char **argv )
880 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
881 rpc_registry_enumerate_internal, argc, argv );
884 /********************************************************************
885 ********************************************************************/
887 static NTSTATUS rpc_registry_save_internal(struct net_context *c,
888 const struct dom_sid *domain_sid,
889 const char *domain_name,
890 struct cli_state *cli,
891 struct rpc_pipe_client *pipe_hnd,
892 TALLOC_CTX *mem_ctx,
893 int argc,
894 const char **argv )
896 WERROR result = WERR_GENERAL_FAILURE;
897 struct policy_handle pol_hive, pol_key;
898 NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
899 struct winreg_String filename;
901 if (argc != 2 || c->display_usage) {
902 d_printf("%s\n%s",
903 _("Usage:"),
904 _("net rpc registry backup <path> <file> \n"));
905 return NT_STATUS_INVALID_PARAMETER;
908 status = registry_openkey(mem_ctx, pipe_hnd, argv[0], REG_KEY_ALL,
909 &pol_hive, &pol_key);
910 if (!NT_STATUS_IS_OK(status)) {
911 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
912 nt_errstr(status));
913 return status;
916 filename.name = argv[1];
917 status = rpccli_winreg_SaveKey( pipe_hnd, mem_ctx, &pol_key, &filename, NULL, NULL);
918 if ( !W_ERROR_IS_OK(result) ) {
919 d_fprintf(stderr, _("Unable to save [%s] to %s:%s\n"), argv[0],
920 cli->desthost, argv[1]);
923 /* cleanup */
925 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_key, NULL);
926 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_hive, NULL);
928 return status;
931 /********************************************************************
932 ********************************************************************/
934 static int rpc_registry_save(struct net_context *c, int argc, const char **argv )
936 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
937 rpc_registry_save_internal, argc, argv );
941 /********************************************************************
942 ********************************************************************/
944 static void dump_values( REGF_NK_REC *nk )
946 int i, j;
947 const char *data_str = NULL;
948 uint32 data_size, data;
949 DATA_BLOB blob;
951 if ( !nk->values )
952 return;
954 for ( i=0; i<nk->num_values; i++ ) {
955 d_printf( "\"%s\" = ", nk->values[i].valuename ? nk->values[i].valuename : "(default)" );
956 d_printf( "(%s) ", str_regtype( nk->values[i].type ) );
958 data_size = nk->values[i].data_size & ~VK_DATA_IN_OFFSET;
959 switch ( nk->values[i].type ) {
960 case REG_SZ:
961 blob = data_blob_const(nk->values[i].data, data_size);
962 pull_reg_sz(talloc_tos(), &blob, &data_str);
963 if (!data_str) {
964 break;
966 d_printf( "%s", data_str );
967 break;
968 case REG_MULTI_SZ:
969 case REG_EXPAND_SZ:
970 for ( j=0; j<data_size; j++ ) {
971 d_printf( "%c", nk->values[i].data[j] );
973 break;
974 case REG_DWORD:
975 data = IVAL( nk->values[i].data, 0 );
976 d_printf("0x%x", data );
977 break;
978 case REG_BINARY:
979 for ( j=0; j<data_size; j++ ) {
980 d_printf( "%x", nk->values[i].data[j] );
982 break;
983 default:
984 d_printf(_("unknown"));
985 break;
988 d_printf( "\n" );
993 /********************************************************************
994 ********************************************************************/
996 static bool dump_registry_tree( REGF_FILE *file, REGF_NK_REC *nk, const char *parent )
998 REGF_NK_REC *key;
1000 /* depth first dump of the registry tree */
1002 while ( (key = regfio_fetch_subkey( file, nk )) ) {
1003 char *regpath;
1004 if (asprintf(&regpath, "%s\\%s", parent, key->keyname) < 0) {
1005 break;
1007 d_printf("[%s]\n", regpath );
1008 dump_values( key );
1009 d_printf("\n");
1010 dump_registry_tree( file, key, regpath );
1011 SAFE_FREE(regpath);
1014 return true;
1017 /********************************************************************
1018 ********************************************************************/
1020 static bool write_registry_tree( REGF_FILE *infile, REGF_NK_REC *nk,
1021 REGF_NK_REC *parent, REGF_FILE *outfile,
1022 const char *parentpath )
1024 REGF_NK_REC *key, *subkey;
1025 struct regval_ctr *values = NULL;
1026 struct regsubkey_ctr *subkeys = NULL;
1027 int i;
1028 char *path = NULL;
1029 WERROR werr;
1031 werr = regsubkey_ctr_init(infile->mem_ctx, &subkeys);
1032 if (!W_ERROR_IS_OK(werr)) {
1033 DEBUG(0, ("write_registry_tree: regsubkey_ctr_init failed: "
1034 "%s\n", win_errstr(werr)));
1035 return false;
1038 werr = regval_ctr_init(subkeys, &values);
1039 if (!W_ERROR_IS_OK(werr)) {
1040 DEBUG(0,("write_registry_tree: talloc() failed!\n"));
1041 TALLOC_FREE(subkeys);
1042 return false;
1045 /* copy values into the struct regval_ctr */
1047 for ( i=0; i<nk->num_values; i++ ) {
1048 regval_ctr_addvalue( values, nk->values[i].valuename, nk->values[i].type,
1049 nk->values[i].data, (nk->values[i].data_size & ~VK_DATA_IN_OFFSET) );
1052 /* copy subkeys into the struct regsubkey_ctr */
1054 while ( (subkey = regfio_fetch_subkey( infile, nk )) ) {
1055 regsubkey_ctr_addkey( subkeys, subkey->keyname );
1058 key = regfio_write_key( outfile, nk->keyname, values, subkeys, nk->sec_desc->sec_desc, parent );
1060 /* write each one of the subkeys out */
1062 path = talloc_asprintf(subkeys,
1063 "%s%s%s",
1064 parentpath,
1065 parent ? "\\" : "",
1066 nk->keyname);
1067 if (!path) {
1068 TALLOC_FREE(subkeys);
1069 return false;
1072 nk->subkey_index = 0;
1073 while ( (subkey = regfio_fetch_subkey( infile, nk )) ) {
1074 write_registry_tree( infile, subkey, key, outfile, path );
1077 d_printf("[%s]\n", path );
1078 TALLOC_FREE(subkeys);
1080 return true;
1083 /********************************************************************
1084 ********************************************************************/
1086 static int rpc_registry_dump(struct net_context *c, int argc, const char **argv)
1088 REGF_FILE *registry;
1089 REGF_NK_REC *nk;
1091 if (argc != 1 || c->display_usage) {
1092 d_printf("%s\n%s",
1093 _("Usage:"),
1094 _("net rpc registry dump <file> \n"));
1095 return -1;
1098 d_printf(_("Opening %s...."), argv[0]);
1099 if ( !(registry = regfio_open( argv[0], O_RDONLY, 0)) ) {
1100 d_fprintf(stderr, _("Failed to open %s for reading\n"),argv[0]);
1101 return 1;
1103 d_printf(_("ok\n"));
1105 /* get the root of the registry file */
1107 if ((nk = regfio_rootkey( registry )) == NULL) {
1108 d_fprintf(stderr, _("Could not get rootkey\n"));
1109 regfio_close( registry );
1110 return 1;
1112 d_printf("[%s]\n", nk->keyname);
1113 dump_values( nk );
1114 d_printf("\n");
1116 dump_registry_tree( registry, nk, nk->keyname );
1118 #if 0
1119 talloc_report_full( registry->mem_ctx, stderr );
1120 #endif
1121 d_printf(_("Closing registry..."));
1122 regfio_close( registry );
1123 d_printf(_("ok\n"));
1125 return 0;
1128 /********************************************************************
1129 ********************************************************************/
1131 static int rpc_registry_copy(struct net_context *c, int argc, const char **argv )
1133 REGF_FILE *infile = NULL, *outfile = NULL;
1134 REGF_NK_REC *nk;
1135 int result = 1;
1137 if (argc != 2 || c->display_usage) {
1138 d_printf("%s\n%s",
1139 _("Usage:"),
1140 _("net rpc registry copy <srcfile> <newfile>\n"));
1141 return -1;
1144 d_printf(_("Opening %s...."), argv[0]);
1145 if ( !(infile = regfio_open( argv[0], O_RDONLY, 0 )) ) {
1146 d_fprintf(stderr, _("Failed to open %s for reading\n"),argv[0]);
1147 return 1;
1149 d_printf(_("ok\n"));
1151 d_printf(_("Opening %s...."), argv[1]);
1152 if ( !(outfile = regfio_open( argv[1], (O_RDWR|O_CREAT|O_TRUNC),
1153 (S_IRUSR|S_IWUSR) )) ) {
1154 d_fprintf(stderr, _("Failed to open %s for writing\n"),argv[1]);
1155 goto out;
1157 d_printf(_("ok\n"));
1159 /* get the root of the registry file */
1161 if ((nk = regfio_rootkey( infile )) == NULL) {
1162 d_fprintf(stderr, _("Could not get rootkey\n"));
1163 goto out;
1165 d_printf(_("RootKey: [%s]\n"), nk->keyname);
1167 write_registry_tree( infile, nk, NULL, outfile, "" );
1169 result = 0;
1171 out:
1173 d_printf(_("Closing %s..."), argv[1]);
1174 if (outfile) {
1175 regfio_close( outfile );
1177 d_printf(_("ok\n"));
1179 d_printf(_("Closing %s..."), argv[0]);
1180 if (infile) {
1181 regfio_close( infile );
1183 d_printf(_("ok\n"));
1185 return( result);
1188 /********************************************************************
1189 ********************************************************************/
1191 static NTSTATUS rpc_registry_getsd_internal(struct net_context *c,
1192 const struct dom_sid *domain_sid,
1193 const char *domain_name,
1194 struct cli_state *cli,
1195 struct rpc_pipe_client *pipe_hnd,
1196 TALLOC_CTX *mem_ctx,
1197 int argc,
1198 const char **argv)
1200 struct policy_handle pol_hive, pol_key;
1201 NTSTATUS status;
1202 enum ndr_err_code ndr_err;
1203 struct KeySecurityData *sd = NULL;
1204 uint32_t sec_info;
1205 DATA_BLOB blob;
1206 struct security_descriptor sec_desc;
1207 uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED |
1208 SEC_FLAG_SYSTEM_SECURITY;
1210 if (argc <1 || argc > 2 || c->display_usage) {
1211 d_printf("%s\n%s",
1212 _("Usage:"),
1213 _("net rpc registry getsd <path> <secinfo>\n"));
1214 d_printf("%s net rpc registry getsd "
1215 "'HKLM\\Software\\Samba'\n", _("Example:"));
1216 return NT_STATUS_INVALID_PARAMETER;
1219 status = registry_openkey(mem_ctx, pipe_hnd, argv[0],
1220 access_mask,
1221 &pol_hive, &pol_key);
1222 if (!NT_STATUS_IS_OK(status)) {
1223 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
1224 nt_errstr(status));
1225 return status;
1228 sd = TALLOC_ZERO_P(mem_ctx, struct KeySecurityData);
1229 if (!sd) {
1230 status = NT_STATUS_NO_MEMORY;
1231 goto out;
1234 sd->size = 0x1000;
1236 if (argc >= 2) {
1237 sscanf(argv[1], "%x", &sec_info);
1238 } else {
1239 sec_info = SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL;
1242 status = registry_getsd(mem_ctx, pipe_hnd, &pol_key, sec_info, sd);
1243 if (!NT_STATUS_IS_OK(status)) {
1244 d_fprintf(stderr, _("getting sd failed: %s\n"),
1245 nt_errstr(status));
1246 goto out;
1249 blob.data = sd->data;
1250 blob.length = sd->size;
1252 ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &sec_desc,
1253 (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
1254 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1255 status = ndr_map_error2ntstatus(ndr_err);
1256 goto out;
1258 status = NT_STATUS_OK;
1260 display_sec_desc(&sec_desc);
1262 out:
1263 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_key, NULL);
1264 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_hive, NULL);
1266 return status;
1270 static int rpc_registry_getsd(struct net_context *c, int argc, const char **argv)
1272 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
1273 rpc_registry_getsd_internal, argc, argv);
1276 /********************************************************************
1277 ********************************************************************/
1279 int net_rpc_registry(struct net_context *c, int argc, const char **argv)
1281 struct functable func[] = {
1283 "enumerate",
1284 rpc_registry_enumerate,
1285 NET_TRANSPORT_RPC,
1286 N_("Enumerate registry keys and values"),
1287 N_("net rpc registry enumerate\n"
1288 " Enumerate registry keys and values")
1291 "createkey",
1292 rpc_registry_createkey,
1293 NET_TRANSPORT_RPC,
1294 N_("Create a new registry key"),
1295 N_("net rpc registry createkey\n"
1296 " Create a new registry key")
1299 "deletekey",
1300 rpc_registry_deletekey,
1301 NET_TRANSPORT_RPC,
1302 N_("Delete a registry key"),
1303 N_("net rpc registry deletekey\n"
1304 " Delete a registry key")
1307 "getvalue",
1308 rpc_registry_getvalue,
1309 NET_TRANSPORT_RPC,
1310 N_("Print a registry value"),
1311 N_("net rpc registry getvalue\n"
1312 " Print a registry value")
1315 "getvalueraw",
1316 rpc_registry_getvalueraw,
1317 NET_TRANSPORT_RPC,
1318 N_("Print a registry value"),
1319 N_("net rpc registry getvalueraw\n"
1320 " Print a registry value (raw version)")
1323 "setvalue",
1324 rpc_registry_setvalue,
1325 NET_TRANSPORT_RPC,
1326 N_("Set a new registry value"),
1327 N_("net rpc registry setvalue\n"
1328 " Set a new registry value")
1331 "deletevalue",
1332 rpc_registry_deletevalue,
1333 NET_TRANSPORT_RPC,
1334 N_("Delete a registry value"),
1335 N_("net rpc registry deletevalue\n"
1336 " Delete a registry value")
1339 "save",
1340 rpc_registry_save,
1341 NET_TRANSPORT_RPC,
1342 N_("Save a registry file"),
1343 N_("net rpc registry save\n"
1344 " Save a registry file")
1347 "dump",
1348 rpc_registry_dump,
1349 NET_TRANSPORT_RPC,
1350 N_("Dump a registry file"),
1351 N_("net rpc registry dump\n"
1352 " Dump a registry file")
1355 "copy",
1356 rpc_registry_copy,
1357 NET_TRANSPORT_RPC,
1358 N_("Copy a registry file"),
1359 N_("net rpc registry copy\n"
1360 " Copy a registry file")
1363 "getsd",
1364 rpc_registry_getsd,
1365 NET_TRANSPORT_RPC,
1366 N_("Get security descriptor"),
1367 N_("net rpc registry getsd\n"
1368 " Get security descriptior")
1370 {NULL, NULL, 0, NULL, NULL}
1373 return net_run_function(c, argc, argv, "net rpc registry", func);