s3-docs: mention -O, --stdout in smbget manpage.
[Samba/fernandojvsilva.git] / source3 / utils / net_rpc_registry.c
blobaa3a13208cb653b2eb92de97e8824aa4dfc9839f
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 "utils/net.h"
22 #include "utils/net_registry_util.h"
23 #include "regfio.h"
24 #include "reg_objects.h"
25 #include "../librpc/gen_ndr/cli_winreg.h"
27 /*******************************************************************
28 connect to a registry hive root (open a registry policy)
29 *******************************************************************/
31 static NTSTATUS rpccli_winreg_Connect(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
32 uint32_t reg_type, uint32_t access_mask,
33 struct policy_handle *reg_hnd)
35 ZERO_STRUCTP(reg_hnd);
37 switch (reg_type)
39 case HKEY_CLASSES_ROOT:
40 return rpccli_winreg_OpenHKCR( cli, mem_ctx, NULL,
41 access_mask, reg_hnd, NULL);
43 case HKEY_LOCAL_MACHINE:
44 return rpccli_winreg_OpenHKLM( cli, mem_ctx, NULL,
45 access_mask, reg_hnd, NULL);
47 case HKEY_USERS:
48 return rpccli_winreg_OpenHKU( cli, mem_ctx, NULL,
49 access_mask, reg_hnd, NULL);
51 case HKEY_CURRENT_USER:
52 return rpccli_winreg_OpenHKCU( cli, mem_ctx, NULL,
53 access_mask, reg_hnd, NULL);
55 case HKEY_PERFORMANCE_DATA:
56 return rpccli_winreg_OpenHKPD( cli, mem_ctx, NULL,
57 access_mask, reg_hnd, NULL);
59 default:
60 /* fall through to end of function */
61 break;
64 return NT_STATUS_INVALID_PARAMETER;
67 static bool reg_hive_key(TALLOC_CTX *ctx, const char *fullname,
68 uint32 *reg_type, const char **key_name)
70 WERROR werr;
71 char *hivename = NULL;
72 char *tmp_keyname = NULL;
73 bool ret = false;
74 TALLOC_CTX *tmp_ctx = talloc_stackframe();
76 werr = split_hive_key(tmp_ctx, fullname, &hivename, &tmp_keyname);
77 if (!W_ERROR_IS_OK(werr)) {
78 goto done;
81 *key_name = talloc_strdup(ctx, tmp_keyname);
82 if (*key_name == NULL) {
83 goto done;
86 if (strequal(hivename, "HKLM") ||
87 strequal(hivename, "HKEY_LOCAL_MACHINE"))
89 (*reg_type) = HKEY_LOCAL_MACHINE;
90 } else if (strequal(hivename, "HKCR") ||
91 strequal(hivename, "HKEY_CLASSES_ROOT"))
93 (*reg_type) = HKEY_CLASSES_ROOT;
94 } else if (strequal(hivename, "HKU") ||
95 strequal(hivename, "HKEY_USERS"))
97 (*reg_type) = HKEY_USERS;
98 } else if (strequal(hivename, "HKCU") ||
99 strequal(hivename, "HKEY_CURRENT_USER"))
101 (*reg_type) = HKEY_CURRENT_USER;
102 } else if (strequal(hivename, "HKPD") ||
103 strequal(hivename, "HKEY_PERFORMANCE_DATA"))
105 (*reg_type) = HKEY_PERFORMANCE_DATA;
106 } else {
107 DEBUG(10,("reg_hive_key: unrecognised hive key %s\n",
108 fullname));
109 goto done;
112 ret = true;
114 done:
115 TALLOC_FREE(tmp_ctx);
116 return ret;
119 static NTSTATUS registry_openkey(TALLOC_CTX *mem_ctx,
120 struct rpc_pipe_client *pipe_hnd,
121 const char *name, uint32 access_mask,
122 struct policy_handle *hive_hnd,
123 struct policy_handle *key_hnd)
125 uint32 hive;
126 NTSTATUS status;
127 struct winreg_String key;
129 ZERO_STRUCT(key);
131 if (!reg_hive_key(mem_ctx, name, &hive, &key.name)) {
132 return NT_STATUS_INVALID_PARAMETER;
135 status = rpccli_winreg_Connect(pipe_hnd, mem_ctx, hive, access_mask,
136 hive_hnd);
137 if (!(NT_STATUS_IS_OK(status))) {
138 return status;
141 status = rpccli_winreg_OpenKey(pipe_hnd, mem_ctx, hive_hnd, key, 0,
142 access_mask, key_hnd, NULL);
143 if (!(NT_STATUS_IS_OK(status))) {
144 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, hive_hnd, NULL);
145 return status;
148 return NT_STATUS_OK;
151 static NTSTATUS registry_enumkeys(TALLOC_CTX *ctx,
152 struct rpc_pipe_client *pipe_hnd,
153 struct policy_handle *key_hnd,
154 uint32 *pnum_keys, char ***pnames,
155 char ***pclasses, NTTIME ***pmodtimes)
157 TALLOC_CTX *mem_ctx;
158 NTSTATUS status;
159 uint32 num_subkeys, max_subkeylen, max_classlen;
160 uint32 num_values, max_valnamelen, max_valbufsize;
161 uint32 i;
162 NTTIME last_changed_time;
163 uint32 secdescsize;
164 struct winreg_String classname;
165 char **names, **classes;
166 NTTIME **modtimes;
168 if (!(mem_ctx = talloc_new(ctx))) {
169 return NT_STATUS_NO_MEMORY;
172 ZERO_STRUCT(classname);
173 status = rpccli_winreg_QueryInfoKey(
174 pipe_hnd, mem_ctx, key_hnd, &classname, &num_subkeys,
175 &max_subkeylen, &max_classlen, &num_values, &max_valnamelen,
176 &max_valbufsize, &secdescsize, &last_changed_time, NULL );
178 if (!NT_STATUS_IS_OK(status)) {
179 goto error;
182 if (num_subkeys == 0) {
183 *pnum_keys = 0;
184 TALLOC_FREE(mem_ctx);
185 return NT_STATUS_OK;
188 if ((!(names = TALLOC_ZERO_ARRAY(mem_ctx, char *, num_subkeys))) ||
189 (!(classes = TALLOC_ZERO_ARRAY(mem_ctx, char *, num_subkeys))) ||
190 (!(modtimes = TALLOC_ZERO_ARRAY(mem_ctx, NTTIME *,
191 num_subkeys)))) {
192 status = NT_STATUS_NO_MEMORY;
193 goto error;
196 for (i=0; i<num_subkeys; i++) {
197 char c, n;
198 struct winreg_StringBuf class_buf;
199 struct winreg_StringBuf name_buf;
200 NTTIME modtime;
201 WERROR werr;
203 c = '\0';
204 class_buf.name = &c;
205 class_buf.size = max_classlen+2;
207 n = '\0';
208 name_buf.name = &n;
209 name_buf.size = max_subkeylen+2;
211 ZERO_STRUCT(modtime);
213 status = rpccli_winreg_EnumKey(pipe_hnd, mem_ctx, key_hnd,
214 i, &name_buf, &class_buf,
215 &modtime, &werr);
217 if (W_ERROR_EQUAL(werr,
218 WERR_NO_MORE_ITEMS) ) {
219 status = NT_STATUS_OK;
220 break;
222 if (!NT_STATUS_IS_OK(status)) {
223 goto error;
226 classes[i] = NULL;
228 if (class_buf.name &&
229 (!(classes[i] = talloc_strdup(classes, class_buf.name)))) {
230 status = NT_STATUS_NO_MEMORY;
231 goto error;
234 if (!(names[i] = talloc_strdup(names, name_buf.name))) {
235 status = NT_STATUS_NO_MEMORY;
236 goto error;
239 if ((!(modtimes[i] = (NTTIME *)talloc_memdup(
240 modtimes, &modtime, sizeof(modtime))))) {
241 status = NT_STATUS_NO_MEMORY;
242 goto error;
246 *pnum_keys = num_subkeys;
248 if (pnames) {
249 *pnames = talloc_move(ctx, &names);
251 if (pclasses) {
252 *pclasses = talloc_move(ctx, &classes);
254 if (pmodtimes) {
255 *pmodtimes = talloc_move(ctx, &modtimes);
258 status = NT_STATUS_OK;
260 error:
261 TALLOC_FREE(mem_ctx);
262 return status;
265 static NTSTATUS registry_enumvalues(TALLOC_CTX *ctx,
266 struct rpc_pipe_client *pipe_hnd,
267 struct policy_handle *key_hnd,
268 uint32 *pnum_values, char ***pvalnames,
269 struct registry_value ***pvalues)
271 TALLOC_CTX *mem_ctx;
272 NTSTATUS status;
273 uint32 num_subkeys, max_subkeylen, max_classlen;
274 uint32 num_values, max_valnamelen, max_valbufsize;
275 uint32 i;
276 NTTIME last_changed_time;
277 uint32 secdescsize;
278 struct winreg_String classname;
279 struct registry_value **values;
280 char **names;
282 if (!(mem_ctx = talloc_new(ctx))) {
283 return NT_STATUS_NO_MEMORY;
286 ZERO_STRUCT(classname);
287 status = rpccli_winreg_QueryInfoKey(
288 pipe_hnd, mem_ctx, key_hnd, &classname, &num_subkeys,
289 &max_subkeylen, &max_classlen, &num_values, &max_valnamelen,
290 &max_valbufsize, &secdescsize, &last_changed_time, NULL );
292 if (!NT_STATUS_IS_OK(status)) {
293 goto error;
296 if (num_values == 0) {
297 *pnum_values = 0;
298 TALLOC_FREE(mem_ctx);
299 return NT_STATUS_OK;
302 if ((!(names = TALLOC_ARRAY(mem_ctx, char *, num_values))) ||
303 (!(values = TALLOC_ARRAY(mem_ctx, struct registry_value *,
304 num_values)))) {
305 status = NT_STATUS_NO_MEMORY;
306 goto error;
309 for (i=0; i<num_values; i++) {
310 enum winreg_Type type = REG_NONE;
311 uint8 *data = NULL;
312 uint32 data_size;
313 uint32 value_length;
315 char n;
316 struct winreg_ValNameBuf name_buf;
317 WERROR err;
319 n = '\0';
320 name_buf.name = &n;
321 name_buf.size = max_valnamelen + 2;
323 data_size = max_valbufsize;
324 data = (uint8 *)TALLOC(mem_ctx, data_size);
325 value_length = 0;
327 status = rpccli_winreg_EnumValue(pipe_hnd, mem_ctx, key_hnd,
328 i, &name_buf, &type,
329 data, &data_size,
330 &value_length, &err);
332 if ( W_ERROR_EQUAL(err,
333 WERR_NO_MORE_ITEMS) ) {
334 status = NT_STATUS_OK;
335 break;
338 if (!(NT_STATUS_IS_OK(status))) {
339 goto error;
342 if (name_buf.name == NULL) {
343 status = NT_STATUS_INVALID_PARAMETER;
344 goto error;
347 if (!(names[i] = talloc_strdup(names, name_buf.name))) {
348 status = NT_STATUS_NO_MEMORY;
349 goto error;
352 err = registry_pull_value(values, &values[i], type, data,
353 data_size, value_length);
354 if (!W_ERROR_IS_OK(err)) {
355 status = werror_to_ntstatus(err);
356 goto error;
360 *pnum_values = num_values;
362 if (pvalnames) {
363 *pvalnames = talloc_move(ctx, &names);
365 if (pvalues) {
366 *pvalues = talloc_move(ctx, &values);
369 status = NT_STATUS_OK;
371 error:
372 TALLOC_FREE(mem_ctx);
373 return status;
376 static NTSTATUS registry_getsd(TALLOC_CTX *mem_ctx,
377 struct rpc_pipe_client *pipe_hnd,
378 struct policy_handle *key_hnd,
379 uint32_t sec_info,
380 struct KeySecurityData *sd)
382 return rpccli_winreg_GetKeySecurity(pipe_hnd, mem_ctx, key_hnd,
383 sec_info, sd, NULL);
387 static NTSTATUS registry_setvalue(TALLOC_CTX *mem_ctx,
388 struct rpc_pipe_client *pipe_hnd,
389 struct policy_handle *key_hnd,
390 const char *name,
391 const struct registry_value *value)
393 struct winreg_String name_string;
394 DATA_BLOB blob;
395 NTSTATUS result;
396 WERROR err;
398 err = registry_push_value(mem_ctx, value, &blob);
399 if (!W_ERROR_IS_OK(err)) {
400 return werror_to_ntstatus(err);
403 ZERO_STRUCT(name_string);
405 name_string.name = name;
406 result = rpccli_winreg_SetValue(pipe_hnd, blob.data, key_hnd,
407 name_string, value->type,
408 blob.data, blob.length, NULL);
409 TALLOC_FREE(blob.data);
410 return result;
413 static NTSTATUS rpc_registry_setvalue_internal(struct net_context *c,
414 const DOM_SID *domain_sid,
415 const char *domain_name,
416 struct cli_state *cli,
417 struct rpc_pipe_client *pipe_hnd,
418 TALLOC_CTX *mem_ctx,
419 int argc,
420 const char **argv )
422 struct policy_handle hive_hnd, key_hnd;
423 NTSTATUS status;
424 struct registry_value value;
426 status = registry_openkey(mem_ctx, pipe_hnd, argv[0],
427 SEC_FLAG_MAXIMUM_ALLOWED,
428 &hive_hnd, &key_hnd);
429 if (!NT_STATUS_IS_OK(status)) {
430 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
431 nt_errstr(status));
432 return status;
435 if (!strequal(argv[2], "multi_sz") && (argc != 4)) {
436 d_fprintf(stderr, _("Too many args for type %s\n"), argv[2]);
437 return NT_STATUS_NOT_IMPLEMENTED;
440 if (strequal(argv[2], "dword")) {
441 value.type = REG_DWORD;
442 value.v.dword = strtoul(argv[3], NULL, 10);
444 else if (strequal(argv[2], "sz")) {
445 value.type = REG_SZ;
446 value.v.sz.len = strlen(argv[3])+1;
447 value.v.sz.str = CONST_DISCARD(char *, argv[3]);
449 else {
450 d_fprintf(stderr, _("type \"%s\" not implemented\n"), argv[2]);
451 status = NT_STATUS_NOT_IMPLEMENTED;
452 goto error;
455 status = registry_setvalue(mem_ctx, pipe_hnd, &key_hnd,
456 argv[1], &value);
458 if (!NT_STATUS_IS_OK(status)) {
459 d_fprintf(stderr, _("registry_setvalue failed: %s\n"),
460 nt_errstr(status));
463 error:
464 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &key_hnd, NULL);
465 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd, NULL);
467 return NT_STATUS_OK;
470 static int rpc_registry_setvalue(struct net_context *c, int argc,
471 const char **argv )
473 if (argc < 4 || c->display_usage) {
474 d_fprintf(stderr, _("usage: net rpc registry setvalue <key> "
475 "<valuename> <type> [<val>]+\n"));
476 return -1;
479 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
480 rpc_registry_setvalue_internal, argc, argv );
483 static NTSTATUS rpc_registry_deletevalue_internal(struct net_context *c,
484 const DOM_SID *domain_sid,
485 const char *domain_name,
486 struct cli_state *cli,
487 struct rpc_pipe_client *pipe_hnd,
488 TALLOC_CTX *mem_ctx,
489 int argc,
490 const char **argv )
492 struct policy_handle hive_hnd, key_hnd;
493 NTSTATUS status;
494 struct winreg_String valuename;
496 ZERO_STRUCT(valuename);
498 status = registry_openkey(mem_ctx, pipe_hnd, argv[0],
499 SEC_FLAG_MAXIMUM_ALLOWED,
500 &hive_hnd, &key_hnd);
501 if (!NT_STATUS_IS_OK(status)) {
502 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
503 nt_errstr(status));
504 return status;
507 valuename.name = argv[1];
509 status = rpccli_winreg_DeleteValue(pipe_hnd, mem_ctx, &key_hnd,
510 valuename, NULL);
512 if (!NT_STATUS_IS_OK(status)) {
513 d_fprintf(stderr, _("registry_deletevalue failed: %s\n"),
514 nt_errstr(status));
517 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &key_hnd, NULL);
518 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd, NULL);
520 return status;
523 static int rpc_registry_deletevalue(struct net_context *c, int argc,
524 const char **argv )
526 if (argc != 2 || c->display_usage) {
527 d_fprintf(stderr, _("usage: net rpc registry deletevalue <key> "
528 "<valuename>\n"));
529 return -1;
532 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
533 rpc_registry_deletevalue_internal, argc, argv );
536 static NTSTATUS rpc_registry_getvalue_internal(struct net_context *c,
537 const DOM_SID *domain_sid,
538 const char *domain_name,
539 struct cli_state *cli,
540 struct rpc_pipe_client *pipe_hnd,
541 TALLOC_CTX *mem_ctx,
542 bool raw,
543 int argc,
544 const char **argv)
546 struct policy_handle hive_hnd, key_hnd;
547 NTSTATUS status;
548 WERROR werr;
549 struct winreg_String valuename;
550 struct registry_value *value = NULL;
551 enum winreg_Type type = REG_NONE;
552 uint8_t *data = NULL;
553 uint32_t data_size = 0;
554 uint32_t value_length = 0;
555 TALLOC_CTX *tmp_ctx = talloc_stackframe();
557 ZERO_STRUCT(valuename);
559 status = registry_openkey(tmp_ctx, pipe_hnd, argv[0],
560 SEC_FLAG_MAXIMUM_ALLOWED,
561 &hive_hnd, &key_hnd);
562 if (!NT_STATUS_IS_OK(status)) {
563 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
564 nt_errstr(status));
565 return status;
568 valuename.name = argv[1];
571 * call QueryValue once with data == NULL to get the
572 * needed memory size to be allocated, then allocate
573 * data buffer and call again.
575 status = rpccli_winreg_QueryValue(pipe_hnd, tmp_ctx, &key_hnd,
576 &valuename,
577 &type,
578 data,
579 &data_size,
580 &value_length,
581 NULL);
583 if (!NT_STATUS_IS_OK(status)) {
584 d_fprintf(stderr, _("registry_queryvalue failed: %s\n"),
585 nt_errstr(status));
586 goto done;
589 data = (uint8 *)TALLOC(tmp_ctx, data_size);
590 value_length = 0;
592 status = rpccli_winreg_QueryValue(pipe_hnd, tmp_ctx, &key_hnd,
593 &valuename,
594 &type,
595 data,
596 &data_size,
597 &value_length,
598 NULL);
600 if (!NT_STATUS_IS_OK(status)) {
601 d_fprintf(stderr, _("registry_queryvalue failed: %s\n"),
602 nt_errstr(status));
603 goto done;
606 werr = registry_pull_value(tmp_ctx, &value, type, data,
607 data_size, value_length);
608 if (!W_ERROR_IS_OK(werr)) {
609 status = werror_to_ntstatus(werr);
610 goto done;
613 print_registry_value(value, raw);
615 done:
616 rpccli_winreg_CloseKey(pipe_hnd, tmp_ctx, &key_hnd, NULL);
617 rpccli_winreg_CloseKey(pipe_hnd, tmp_ctx, &hive_hnd, NULL);
619 TALLOC_FREE(tmp_ctx);
621 return status;
624 static NTSTATUS rpc_registry_getvalue_full(struct net_context *c,
625 const DOM_SID *domain_sid,
626 const char *domain_name,
627 struct cli_state *cli,
628 struct rpc_pipe_client *pipe_hnd,
629 TALLOC_CTX *mem_ctx,
630 int argc,
631 const char **argv)
633 return rpc_registry_getvalue_internal(c, domain_sid, domain_name,
634 cli, pipe_hnd, mem_ctx, false,
635 argc, argv);
638 static int rpc_registry_getvalue(struct net_context *c, int argc,
639 const char **argv)
641 if (argc != 2 || c->display_usage) {
642 d_fprintf(stderr, _("usage: net rpc registry getvalue <key> "
643 "<valuename>\n"));
644 return -1;
647 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
648 rpc_registry_getvalue_full, argc, argv);
651 static NTSTATUS rpc_registry_getvalue_raw(struct net_context *c,
652 const DOM_SID *domain_sid,
653 const char *domain_name,
654 struct cli_state *cli,
655 struct rpc_pipe_client *pipe_hnd,
656 TALLOC_CTX *mem_ctx,
657 int argc,
658 const char **argv)
660 return rpc_registry_getvalue_internal(c, domain_sid, domain_name,
661 cli, pipe_hnd, mem_ctx, true,
662 argc, argv);
665 static int rpc_registry_getvalueraw(struct net_context *c, int argc,
666 const char **argv)
668 if (argc != 2 || c->display_usage) {
669 d_fprintf(stderr, _("usage: net rpc registry getvalue <key> "
670 "<valuename>\n"));
671 return -1;
674 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
675 rpc_registry_getvalue_raw, argc, argv);
678 static NTSTATUS rpc_registry_createkey_internal(struct net_context *c,
679 const DOM_SID *domain_sid,
680 const char *domain_name,
681 struct cli_state *cli,
682 struct rpc_pipe_client *pipe_hnd,
683 TALLOC_CTX *mem_ctx,
684 int argc,
685 const char **argv )
687 uint32 hive;
688 struct policy_handle hive_hnd, key_hnd;
689 struct winreg_String key, keyclass;
690 enum winreg_CreateAction action;
691 NTSTATUS status;
693 ZERO_STRUCT(key);
694 ZERO_STRUCT(keyclass);
696 if (!reg_hive_key(mem_ctx, argv[0], &hive, &key.name)) {
697 return NT_STATUS_INVALID_PARAMETER;
700 status = rpccli_winreg_Connect(pipe_hnd, mem_ctx, hive,
701 SEC_FLAG_MAXIMUM_ALLOWED,
702 &hive_hnd);
703 if (!(NT_STATUS_IS_OK(status))) {
704 return status;
707 action = REG_ACTION_NONE;
708 keyclass.name = "";
710 status = rpccli_winreg_CreateKey(pipe_hnd, mem_ctx, &hive_hnd, key,
711 keyclass, 0, REG_KEY_READ, NULL,
712 &key_hnd, &action, NULL);
713 if (!NT_STATUS_IS_OK(status)) {
714 d_fprintf(stderr, _("createkey returned %s\n"),
715 nt_errstr(status));
716 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd, NULL);
717 return status;
720 switch (action) {
721 case REG_ACTION_NONE:
722 d_printf(_("createkey did nothing -- huh?\n"));
723 break;
724 case REG_CREATED_NEW_KEY:
725 d_printf(_("createkey created %s\n"), argv[0]);
726 break;
727 case REG_OPENED_EXISTING_KEY:
728 d_printf(_("createkey opened existing %s\n"), argv[0]);
729 break;
732 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &key_hnd, NULL);
733 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd, NULL);
735 return status;
738 static int rpc_registry_createkey(struct net_context *c, int argc,
739 const char **argv )
741 if (argc != 1 || c->display_usage) {
742 d_fprintf(stderr,
743 _("usage: net rpc registry createkey <key>\n"));
744 return -1;
747 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
748 rpc_registry_createkey_internal, argc, argv );
751 static NTSTATUS rpc_registry_deletekey_internal(struct net_context *c,
752 const DOM_SID *domain_sid,
753 const char *domain_name,
754 struct cli_state *cli,
755 struct rpc_pipe_client *pipe_hnd,
756 TALLOC_CTX *mem_ctx,
757 int argc,
758 const char **argv )
760 uint32 hive;
761 struct policy_handle hive_hnd;
762 struct winreg_String key;
763 NTSTATUS status;
765 ZERO_STRUCT(key);
767 if (!reg_hive_key(mem_ctx, argv[0], &hive, &key.name)) {
768 return NT_STATUS_INVALID_PARAMETER;
771 status = rpccli_winreg_Connect(pipe_hnd, mem_ctx, hive,
772 SEC_FLAG_MAXIMUM_ALLOWED,
773 &hive_hnd);
774 if (!(NT_STATUS_IS_OK(status))) {
775 return status;
778 status = rpccli_winreg_DeleteKey(pipe_hnd, mem_ctx, &hive_hnd, key, NULL);
779 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd, NULL);
781 if (!NT_STATUS_IS_OK(status)) {
782 d_fprintf(stderr, _("deletekey returned %s\n"),
783 nt_errstr(status));
786 return status;
789 static int rpc_registry_deletekey(struct net_context *c, int argc, const char **argv )
791 if (argc != 1 || c->display_usage) {
792 d_fprintf(stderr,
793 _("usage: net rpc registry deletekey <key>\n"));
794 return -1;
797 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
798 rpc_registry_deletekey_internal, argc, argv );
801 /********************************************************************
802 ********************************************************************/
804 static NTSTATUS rpc_registry_enumerate_internal(struct net_context *c,
805 const DOM_SID *domain_sid,
806 const char *domain_name,
807 struct cli_state *cli,
808 struct rpc_pipe_client *pipe_hnd,
809 TALLOC_CTX *mem_ctx,
810 int argc,
811 const char **argv )
813 struct policy_handle pol_hive, pol_key;
814 NTSTATUS status;
815 uint32 num_subkeys = 0;
816 uint32 num_values = 0;
817 char **names = NULL, **classes = NULL;
818 NTTIME **modtimes = NULL;
819 uint32 i;
820 struct registry_value **values = NULL;
822 if (argc != 1 || c->display_usage) {
823 d_printf(_("Usage: net rpc registry enumerate <path>\n"));
824 d_printf(_("Example: net rpc registry enumerate "
825 "'HKLM\\Software\\Samba'\n"));
826 return NT_STATUS_INVALID_PARAMETER;
829 status = registry_openkey(mem_ctx, pipe_hnd, argv[0], REG_KEY_READ,
830 &pol_hive, &pol_key);
831 if (!NT_STATUS_IS_OK(status)) {
832 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
833 nt_errstr(status));
834 return status;
837 status = registry_enumkeys(mem_ctx, pipe_hnd, &pol_key, &num_subkeys,
838 &names, &classes, &modtimes);
839 if (!NT_STATUS_IS_OK(status)) {
840 d_fprintf(stderr, _("enumerating keys failed: %s\n"),
841 nt_errstr(status));
842 return status;
845 for (i=0; i<num_subkeys; i++) {
846 print_registry_key(names[i], modtimes[i]);
849 status = registry_enumvalues(mem_ctx, pipe_hnd, &pol_key, &num_values,
850 &names, &values);
851 if (!NT_STATUS_IS_OK(status)) {
852 d_fprintf(stderr, _("enumerating values failed: %s\n"),
853 nt_errstr(status));
854 return status;
857 for (i=0; i<num_values; i++) {
858 print_registry_value_with_name(names[i], values[i]);
861 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_key, NULL);
862 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_hive, NULL);
864 return status;
867 /********************************************************************
868 ********************************************************************/
870 static int rpc_registry_enumerate(struct net_context *c, int argc,
871 const char **argv )
873 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
874 rpc_registry_enumerate_internal, argc, argv );
877 /********************************************************************
878 ********************************************************************/
880 static NTSTATUS rpc_registry_save_internal(struct net_context *c,
881 const DOM_SID *domain_sid,
882 const char *domain_name,
883 struct cli_state *cli,
884 struct rpc_pipe_client *pipe_hnd,
885 TALLOC_CTX *mem_ctx,
886 int argc,
887 const char **argv )
889 WERROR result = WERR_GENERAL_FAILURE;
890 struct policy_handle pol_hive, pol_key;
891 NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
892 struct winreg_String filename;
894 if (argc != 2 || c->display_usage) {
895 d_printf(_("Usage: net rpc registry backup <path> "
896 "<file> \n"));
897 return NT_STATUS_INVALID_PARAMETER;
900 status = registry_openkey(mem_ctx, pipe_hnd, argv[0], REG_KEY_ALL,
901 &pol_hive, &pol_key);
902 if (!NT_STATUS_IS_OK(status)) {
903 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
904 nt_errstr(status));
905 return status;
908 filename.name = argv[1];
909 status = rpccli_winreg_SaveKey( pipe_hnd, mem_ctx, &pol_key, &filename, NULL, NULL);
910 if ( !W_ERROR_IS_OK(result) ) {
911 d_fprintf(stderr, _("Unable to save [%s] to %s:%s\n"), argv[0],
912 cli->desthost, argv[1]);
915 /* cleanup */
917 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_key, NULL);
918 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_hive, NULL);
920 return status;
923 /********************************************************************
924 ********************************************************************/
926 static int rpc_registry_save(struct net_context *c, int argc, const char **argv )
928 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
929 rpc_registry_save_internal, argc, argv );
933 /********************************************************************
934 ********************************************************************/
936 static void dump_values( REGF_NK_REC *nk )
938 int i, j;
939 const char *data_str = NULL;
940 uint32 data_size, data;
941 DATA_BLOB blob;
943 if ( !nk->values )
944 return;
946 for ( i=0; i<nk->num_values; i++ ) {
947 d_printf( "\"%s\" = ", nk->values[i].valuename ? nk->values[i].valuename : "(default)" );
948 d_printf( "(%s) ", reg_type_lookup( nk->values[i].type ) );
950 data_size = nk->values[i].data_size & ~VK_DATA_IN_OFFSET;
951 switch ( nk->values[i].type ) {
952 case REG_SZ:
953 blob = data_blob_const(nk->values[i].data, data_size);
954 pull_reg_sz(talloc_tos(), &blob, &data_str);
955 if (!data_str) {
956 break;
958 d_printf( "%s", data_str );
959 break;
960 case REG_MULTI_SZ:
961 case REG_EXPAND_SZ:
962 for ( j=0; j<data_size; j++ ) {
963 d_printf( "%c", nk->values[i].data[j] );
965 break;
966 case REG_DWORD:
967 data = IVAL( nk->values[i].data, 0 );
968 d_printf("0x%x", data );
969 break;
970 case REG_BINARY:
971 for ( j=0; j<data_size; j++ ) {
972 d_printf( "%x", nk->values[i].data[j] );
974 break;
975 default:
976 d_printf(_("unknown"));
977 break;
980 d_printf( "\n" );
985 /********************************************************************
986 ********************************************************************/
988 static bool dump_registry_tree( REGF_FILE *file, REGF_NK_REC *nk, const char *parent )
990 REGF_NK_REC *key;
992 /* depth first dump of the registry tree */
994 while ( (key = regfio_fetch_subkey( file, nk )) ) {
995 char *regpath;
996 if (asprintf(&regpath, "%s\\%s", parent, key->keyname) < 0) {
997 break;
999 d_printf("[%s]\n", regpath );
1000 dump_values( key );
1001 d_printf("\n");
1002 dump_registry_tree( file, key, regpath );
1003 SAFE_FREE(regpath);
1006 return true;
1009 /********************************************************************
1010 ********************************************************************/
1012 static bool write_registry_tree( REGF_FILE *infile, REGF_NK_REC *nk,
1013 REGF_NK_REC *parent, REGF_FILE *outfile,
1014 const char *parentpath )
1016 REGF_NK_REC *key, *subkey;
1017 struct regval_ctr *values = NULL;
1018 struct regsubkey_ctr *subkeys = NULL;
1019 int i;
1020 char *path = NULL;
1021 WERROR werr;
1023 werr = regsubkey_ctr_init(infile->mem_ctx, &subkeys);
1024 if (!W_ERROR_IS_OK(werr)) {
1025 DEBUG(0, ("write_registry_tree: regsubkey_ctr_init failed: "
1026 "%s\n", win_errstr(werr)));
1027 return false;
1030 if ( !(values = TALLOC_ZERO_P( subkeys, struct regval_ctr )) ) {
1031 DEBUG(0,("write_registry_tree: talloc() failed!\n"));
1032 TALLOC_FREE(subkeys);
1033 return false;
1036 /* copy values into the struct regval_ctr */
1038 for ( i=0; i<nk->num_values; i++ ) {
1039 regval_ctr_addvalue( values, nk->values[i].valuename, nk->values[i].type,
1040 (const char *)nk->values[i].data, (nk->values[i].data_size & ~VK_DATA_IN_OFFSET) );
1043 /* copy subkeys into the struct regsubkey_ctr */
1045 while ( (subkey = regfio_fetch_subkey( infile, nk )) ) {
1046 regsubkey_ctr_addkey( subkeys, subkey->keyname );
1049 key = regfio_write_key( outfile, nk->keyname, values, subkeys, nk->sec_desc->sec_desc, parent );
1051 /* write each one of the subkeys out */
1053 path = talloc_asprintf(subkeys,
1054 "%s%s%s",
1055 parentpath,
1056 parent ? "\\" : "",
1057 nk->keyname);
1058 if (!path) {
1059 TALLOC_FREE(subkeys);
1060 return false;
1063 nk->subkey_index = 0;
1064 while ( (subkey = regfio_fetch_subkey( infile, nk )) ) {
1065 write_registry_tree( infile, subkey, key, outfile, path );
1068 d_printf("[%s]\n", path );
1069 TALLOC_FREE(subkeys);
1071 return true;
1074 /********************************************************************
1075 ********************************************************************/
1077 static int rpc_registry_dump(struct net_context *c, int argc, const char **argv)
1079 REGF_FILE *registry;
1080 REGF_NK_REC *nk;
1082 if (argc != 1 || c->display_usage) {
1083 d_printf(_("Usage: net rpc registry dump <file> \n"));
1084 return -1;
1087 d_printf(_("Opening %s...."), argv[0]);
1088 if ( !(registry = regfio_open( argv[0], O_RDONLY, 0)) ) {
1089 d_fprintf(stderr, _("Failed to open %s for reading\n"),argv[0]);
1090 return 1;
1092 d_printf(_("ok\n"));
1094 /* get the root of the registry file */
1096 if ((nk = regfio_rootkey( registry )) == NULL) {
1097 d_fprintf(stderr, _("Could not get rootkey\n"));
1098 regfio_close( registry );
1099 return 1;
1101 d_printf("[%s]\n", nk->keyname);
1102 dump_values( nk );
1103 d_printf("\n");
1105 dump_registry_tree( registry, nk, nk->keyname );
1107 #if 0
1108 talloc_report_full( registry->mem_ctx, stderr );
1109 #endif
1110 d_printf(_("Closing registry..."));
1111 regfio_close( registry );
1112 d_printf(_("ok\n"));
1114 return 0;
1117 /********************************************************************
1118 ********************************************************************/
1120 static int rpc_registry_copy(struct net_context *c, int argc, const char **argv )
1122 REGF_FILE *infile = NULL, *outfile = NULL;
1123 REGF_NK_REC *nk;
1124 int result = 1;
1126 if (argc != 2 || c->display_usage) {
1127 d_printf(_("Usage: net rpc registry copy <srcfile> "
1128 "<newfile>\n"));
1129 return -1;
1132 d_printf(_("Opening %s...."), argv[0]);
1133 if ( !(infile = regfio_open( argv[0], O_RDONLY, 0 )) ) {
1134 d_fprintf(stderr, _("Failed to open %s for reading\n"),argv[0]);
1135 return 1;
1137 d_printf(_("ok\n"));
1139 d_printf(_("Opening %s...."), argv[1]);
1140 if ( !(outfile = regfio_open( argv[1], (O_RDWR|O_CREAT|O_TRUNC), (S_IREAD|S_IWRITE) )) ) {
1141 d_fprintf(stderr, _("Failed to open %s for writing\n"),argv[1]);
1142 goto out;
1144 d_printf(_("ok\n"));
1146 /* get the root of the registry file */
1148 if ((nk = regfio_rootkey( infile )) == NULL) {
1149 d_fprintf(stderr, _("Could not get rootkey\n"));
1150 goto out;
1152 d_printf(_("RootKey: [%s]\n"), nk->keyname);
1154 write_registry_tree( infile, nk, NULL, outfile, "" );
1156 result = 0;
1158 out:
1160 d_printf(_("Closing %s..."), argv[1]);
1161 if (outfile) {
1162 regfio_close( outfile );
1164 d_printf(_("ok\n"));
1166 d_printf(_("Closing %s..."), argv[0]);
1167 if (infile) {
1168 regfio_close( infile );
1170 d_printf(_("ok\n"));
1172 return( result);
1175 /********************************************************************
1176 ********************************************************************/
1178 static NTSTATUS rpc_registry_getsd_internal(struct net_context *c,
1179 const DOM_SID *domain_sid,
1180 const char *domain_name,
1181 struct cli_state *cli,
1182 struct rpc_pipe_client *pipe_hnd,
1183 TALLOC_CTX *mem_ctx,
1184 int argc,
1185 const char **argv)
1187 struct policy_handle pol_hive, pol_key;
1188 NTSTATUS status;
1189 enum ndr_err_code ndr_err;
1190 struct KeySecurityData *sd = NULL;
1191 uint32_t sec_info;
1192 DATA_BLOB blob;
1193 struct security_descriptor sec_desc;
1194 uint32_t access_mask = REG_KEY_READ |
1195 SEC_FLAG_MAXIMUM_ALLOWED |
1196 SEC_FLAG_SYSTEM_SECURITY;
1198 if (argc <1 || argc > 2 || c->display_usage) {
1199 d_printf(_("Usage: net rpc registry getsd <path> "
1200 "<secinfo>\n"));
1201 d_printf(_("Example: net rpc registry getsd "
1202 "'HKLM\\Software\\Samba'\n"));
1203 return NT_STATUS_INVALID_PARAMETER;
1206 status = registry_openkey(mem_ctx, pipe_hnd, argv[0],
1207 access_mask,
1208 &pol_hive, &pol_key);
1209 if (!NT_STATUS_IS_OK(status)) {
1210 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
1211 nt_errstr(status));
1212 return status;
1215 sd = TALLOC_ZERO_P(mem_ctx, struct KeySecurityData);
1216 if (!sd) {
1217 status = NT_STATUS_NO_MEMORY;
1218 goto out;
1221 sd->size = 0x1000;
1223 if (argc >= 2) {
1224 sscanf(argv[1], "%x", &sec_info);
1225 } else {
1226 sec_info = SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL;
1229 status = registry_getsd(mem_ctx, pipe_hnd, &pol_key, sec_info, sd);
1230 if (!NT_STATUS_IS_OK(status)) {
1231 d_fprintf(stderr, _("getting sd failed: %s\n"),
1232 nt_errstr(status));
1233 goto out;
1236 blob.data = sd->data;
1237 blob.length = sd->size;
1239 ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, NULL, &sec_desc,
1240 (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
1241 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1242 status = ndr_map_error2ntstatus(ndr_err);
1243 goto out;
1245 status = NT_STATUS_OK;
1247 display_sec_desc(&sec_desc);
1249 out:
1250 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_key, NULL);
1251 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_hive, NULL);
1253 return status;
1257 static int rpc_registry_getsd(struct net_context *c, int argc, const char **argv)
1259 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
1260 rpc_registry_getsd_internal, argc, argv);
1263 /********************************************************************
1264 ********************************************************************/
1266 int net_rpc_registry(struct net_context *c, int argc, const char **argv)
1268 struct functable func[] = {
1270 "enumerate",
1271 rpc_registry_enumerate,
1272 NET_TRANSPORT_RPC,
1273 N_("Enumerate registry keys and values"),
1274 N_("net rpc registry enumerate\n"
1275 " Enumerate registry keys and values")
1278 "createkey",
1279 rpc_registry_createkey,
1280 NET_TRANSPORT_RPC,
1281 N_("Create a new registry key"),
1282 N_("net rpc registry createkey\n"
1283 " Create a new registry key")
1286 "deletekey",
1287 rpc_registry_deletekey,
1288 NET_TRANSPORT_RPC,
1289 N_("Delete a registry key"),
1290 N_("net rpc registry deletekey\n"
1291 " Delete a registry key")
1294 "getvalue",
1295 rpc_registry_getvalue,
1296 NET_TRANSPORT_RPC,
1297 N_("Print a registry value"),
1298 N_("net rpc registry getvalue\n"
1299 " Print a registry value")
1302 "getvalueraw",
1303 rpc_registry_getvalueraw,
1304 NET_TRANSPORT_RPC,
1305 N_("Print a registry value"),
1306 N_("net rpc registry getvalueraw\n"
1307 " Print a registry value (raw version)")
1310 "setvalue",
1311 rpc_registry_setvalue,
1312 NET_TRANSPORT_RPC,
1313 N_("Set a new registry value"),
1314 N_("net rpc registry setvalue\n"
1315 " Set a new registry value")
1318 "deletevalue",
1319 rpc_registry_deletevalue,
1320 NET_TRANSPORT_RPC,
1321 N_("Delete a registry value"),
1322 N_("net rpc registry deletevalue\n"
1323 " Delete a registry value")
1326 "save",
1327 rpc_registry_save,
1328 NET_TRANSPORT_RPC,
1329 N_("Save a registry file"),
1330 N_("net rpc registry save\n"
1331 " Save a registry file")
1334 "dump",
1335 rpc_registry_dump,
1336 NET_TRANSPORT_RPC,
1337 N_("Dump a registry file"),
1338 N_("net rpc registry dump\n"
1339 " Dump a registry file")
1342 "copy",
1343 rpc_registry_copy,
1344 NET_TRANSPORT_RPC,
1345 N_("Copy a registry file"),
1346 N_("net rpc registry copy\n"
1347 " Copy a registry file")
1350 "getsd",
1351 rpc_registry_getsd,
1352 NET_TRANSPORT_RPC,
1353 N_("Get security descriptor"),
1354 N_("net rpc registry getsd\n"
1355 " Get security descriptior")
1357 {NULL, NULL, 0, NULL, NULL}
1360 return net_run_function(c, argc, argv, "net rpc registry", func);