Merge branch 'v3-2-test' of ssh://git.samba.org/data/git/samba into v3-2-test
[Samba/bb.git] / source / utils / net_rpc_registry.c
blob2d335942a23a8213979cc784265ddcf8c538f635
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 "regfio.h"
23 #include "reg_objects.h"
25 static bool reg_hive_key(const char *fullname, uint32 *reg_type,
26 const char **key_name)
28 const char *sep;
29 ptrdiff_t len;
31 sep = strchr_m(fullname, '\\');
33 if (sep != NULL) {
34 len = sep - fullname;
35 *key_name = sep+1;
37 else {
38 len = strlen(fullname);
39 *key_name = "";
42 if (strnequal(fullname, "HKLM", len) ||
43 strnequal(fullname, "HKEY_LOCAL_MACHINE", len))
44 (*reg_type) = HKEY_LOCAL_MACHINE;
45 else if (strnequal(fullname, "HKCR", len) ||
46 strnequal(fullname, "HKEY_CLASSES_ROOT", len))
47 (*reg_type) = HKEY_CLASSES_ROOT;
48 else if (strnequal(fullname, "HKU", len) ||
49 strnequal(fullname, "HKEY_USERS", len))
50 (*reg_type) = HKEY_USERS;
51 else if (strnequal(fullname, "HKCU", len) ||
52 strnequal(fullname, "HKEY_CURRENT_USER", len))
53 (*reg_type) = HKEY_CURRENT_USER;
54 else if (strnequal(fullname, "HKPD", len) ||
55 strnequal(fullname, "HKEY_PERFORMANCE_DATA", len))
56 (*reg_type) = HKEY_PERFORMANCE_DATA;
57 else {
58 DEBUG(10,("reg_hive_key: unrecognised hive key %s\n",
59 fullname));
60 return False;
63 return True;
66 static NTSTATUS registry_openkey(TALLOC_CTX *mem_ctx,
67 struct rpc_pipe_client *pipe_hnd,
68 const char *name, uint32 access_mask,
69 struct policy_handle *hive_hnd,
70 struct policy_handle *key_hnd)
72 uint32 hive;
73 NTSTATUS status;
74 struct winreg_String key;
76 ZERO_STRUCT(key);
78 if (!reg_hive_key(name, &hive, &key.name)) {
79 return NT_STATUS_INVALID_PARAMETER;
82 status = rpccli_winreg_Connect(pipe_hnd, mem_ctx, hive, access_mask,
83 hive_hnd);
84 if (!(NT_STATUS_IS_OK(status))) {
85 return status;
88 status = rpccli_winreg_OpenKey(pipe_hnd, mem_ctx, hive_hnd, key, 0,
89 access_mask, key_hnd, NULL);
90 if (!(NT_STATUS_IS_OK(status))) {
91 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, hive_hnd, NULL);
92 return status;
95 return NT_STATUS_OK;
98 static NTSTATUS registry_enumkeys(TALLOC_CTX *ctx,
99 struct rpc_pipe_client *pipe_hnd,
100 struct policy_handle *key_hnd,
101 uint32 *pnum_keys, char ***pnames,
102 char ***pclasses, NTTIME ***pmodtimes)
104 TALLOC_CTX *mem_ctx;
105 NTSTATUS status;
106 uint32 num_subkeys, max_subkeylen, max_classlen;
107 uint32 num_values, max_valnamelen, max_valbufsize;
108 uint32 i;
109 NTTIME last_changed_time;
110 uint32 secdescsize;
111 struct winreg_String classname;
112 char **names, **classes;
113 NTTIME **modtimes;
115 if (!(mem_ctx = talloc_new(ctx))) {
116 return NT_STATUS_NO_MEMORY;
119 ZERO_STRUCT(classname);
120 status = rpccli_winreg_QueryInfoKey(
121 pipe_hnd, mem_ctx, key_hnd, &classname, &num_subkeys,
122 &max_subkeylen, &max_classlen, &num_values, &max_valnamelen,
123 &max_valbufsize, &secdescsize, &last_changed_time, NULL );
125 if (!NT_STATUS_IS_OK(status)) {
126 goto error;
129 if (num_subkeys == 0) {
130 *pnum_keys = 0;
131 TALLOC_FREE(mem_ctx);
132 return NT_STATUS_OK;
135 if ((!(names = TALLOC_ZERO_ARRAY(mem_ctx, char *, num_subkeys))) ||
136 (!(classes = TALLOC_ZERO_ARRAY(mem_ctx, char *, num_subkeys))) ||
137 (!(modtimes = TALLOC_ZERO_ARRAY(mem_ctx, NTTIME *,
138 num_subkeys)))) {
139 status = NT_STATUS_NO_MEMORY;
140 goto error;
143 for (i=0; i<num_subkeys; i++) {
144 char c, n;
145 struct winreg_StringBuf class_buf;
146 struct winreg_StringBuf name_buf;
147 NTTIME modtime;
148 WERROR werr;
150 c = '\0';
151 class_buf.name = &c;
152 class_buf.size = max_classlen+2;
154 n = '\0';
155 name_buf.name = &n;
156 name_buf.size = max_subkeylen+2;
158 ZERO_STRUCT(modtime);
160 status = rpccli_winreg_EnumKey(pipe_hnd, mem_ctx, key_hnd,
161 i, &name_buf, &class_buf,
162 &modtime, &werr);
164 if (W_ERROR_EQUAL(werr,
165 WERR_NO_MORE_ITEMS) ) {
166 status = NT_STATUS_OK;
167 break;
169 if (!NT_STATUS_IS_OK(status)) {
170 goto error;
173 classes[i] = NULL;
175 if (class_buf.name &&
176 (!(classes[i] = talloc_strdup(classes, class_buf.name)))) {
177 status = NT_STATUS_NO_MEMORY;
178 goto error;
181 if (!(names[i] = talloc_strdup(names, name_buf.name))) {
182 status = NT_STATUS_NO_MEMORY;
183 goto error;
186 if ((!(modtimes[i] = (NTTIME *)talloc_memdup(
187 modtimes, &modtime, sizeof(modtime))))) {
188 status = NT_STATUS_NO_MEMORY;
189 goto error;
193 *pnum_keys = num_subkeys;
195 if (pnames) {
196 *pnames = talloc_move(ctx, &names);
198 if (pclasses) {
199 *pclasses = talloc_move(ctx, &classes);
201 if (pmodtimes) {
202 *pmodtimes = talloc_move(ctx, &modtimes);
205 status = NT_STATUS_OK;
207 error:
208 TALLOC_FREE(mem_ctx);
209 return status;
212 static NTSTATUS registry_enumvalues(TALLOC_CTX *ctx,
213 struct rpc_pipe_client *pipe_hnd,
214 struct policy_handle *key_hnd,
215 uint32 *pnum_values, char ***pvalnames,
216 struct registry_value ***pvalues)
218 TALLOC_CTX *mem_ctx;
219 NTSTATUS status;
220 uint32 num_subkeys, max_subkeylen, max_classlen;
221 uint32 num_values, max_valnamelen, max_valbufsize;
222 uint32 i;
223 NTTIME last_changed_time;
224 uint32 secdescsize;
225 struct winreg_String classname;
226 struct registry_value **values;
227 char **names;
229 if (!(mem_ctx = talloc_new(ctx))) {
230 return NT_STATUS_NO_MEMORY;
233 ZERO_STRUCT(classname);
234 status = rpccli_winreg_QueryInfoKey(
235 pipe_hnd, mem_ctx, key_hnd, &classname, &num_subkeys,
236 &max_subkeylen, &max_classlen, &num_values, &max_valnamelen,
237 &max_valbufsize, &secdescsize, &last_changed_time, NULL );
239 if (!NT_STATUS_IS_OK(status)) {
240 goto error;
243 if (num_values == 0) {
244 *pnum_values = 0;
245 TALLOC_FREE(mem_ctx);
246 return NT_STATUS_OK;
249 if ((!(names = TALLOC_ARRAY(mem_ctx, char *, num_values))) ||
250 (!(values = TALLOC_ARRAY(mem_ctx, struct registry_value *,
251 num_values)))) {
252 status = NT_STATUS_NO_MEMORY;
253 goto error;
256 for (i=0; i<num_values; i++) {
257 enum winreg_Type type = REG_NONE;
258 uint8 *data = NULL;
259 uint32 data_size;
260 uint32 value_length;
262 char n;
263 struct winreg_ValNameBuf name_buf;
264 WERROR err;
266 n = '\0';
267 name_buf.name = &n;
268 name_buf.size = max_valnamelen + 2;
270 data_size = max_valbufsize;
271 data = (uint8 *)TALLOC(mem_ctx, data_size);
272 value_length = 0;
274 status = rpccli_winreg_EnumValue(pipe_hnd, mem_ctx, key_hnd,
275 i, &name_buf, &type,
276 data, &data_size,
277 &value_length, &err);
279 if ( W_ERROR_EQUAL(err,
280 WERR_NO_MORE_ITEMS) ) {
281 status = NT_STATUS_OK;
282 break;
285 if (!(NT_STATUS_IS_OK(status))) {
286 goto error;
289 if (name_buf.name == NULL) {
290 status = NT_STATUS_INVALID_PARAMETER;
291 goto error;
294 if (!(names[i] = talloc_strdup(names, name_buf.name))) {
295 status = NT_STATUS_NO_MEMORY;
296 goto error;
299 err = registry_pull_value(values, &values[i], type, data,
300 data_size, value_length);
301 if (!W_ERROR_IS_OK(err)) {
302 status = werror_to_ntstatus(err);
303 goto error;
307 *pnum_values = num_values;
309 if (pvalnames) {
310 *pvalnames = talloc_move(ctx, &names);
312 if (pvalues) {
313 *pvalues = talloc_move(ctx, &values);
316 status = NT_STATUS_OK;
318 error:
319 TALLOC_FREE(mem_ctx);
320 return status;
323 static NTSTATUS registry_getsd(TALLOC_CTX *mem_ctx,
324 struct rpc_pipe_client *pipe_hnd,
325 struct policy_handle *key_hnd,
326 uint32_t sec_info,
327 struct KeySecurityData *sd)
329 return rpccli_winreg_GetKeySecurity(pipe_hnd, mem_ctx, key_hnd,
330 sec_info, sd, NULL);
334 static NTSTATUS registry_setvalue(TALLOC_CTX *mem_ctx,
335 struct rpc_pipe_client *pipe_hnd,
336 struct policy_handle *key_hnd,
337 const char *name,
338 const struct registry_value *value)
340 struct winreg_String name_string;
341 DATA_BLOB blob;
342 NTSTATUS result;
343 WERROR err;
345 err = registry_push_value(mem_ctx, value, &blob);
346 if (!W_ERROR_IS_OK(err)) {
347 return werror_to_ntstatus(err);
350 ZERO_STRUCT(name_string);
352 name_string.name = name;
353 result = rpccli_winreg_SetValue(pipe_hnd, blob.data, key_hnd,
354 name_string, value->type,
355 blob.data, blob.length, NULL);
356 TALLOC_FREE(blob.data);
357 return result;
360 static NTSTATUS rpc_registry_setvalue_internal(const DOM_SID *domain_sid,
361 const char *domain_name,
362 struct cli_state *cli,
363 struct rpc_pipe_client *pipe_hnd,
364 TALLOC_CTX *mem_ctx,
365 int argc,
366 const char **argv )
368 struct policy_handle hive_hnd, key_hnd;
369 NTSTATUS status;
370 struct registry_value value;
372 status = registry_openkey(mem_ctx, pipe_hnd, argv[0],
373 SEC_RIGHTS_MAXIMUM_ALLOWED,
374 &hive_hnd, &key_hnd);
375 if (!NT_STATUS_IS_OK(status)) {
376 d_fprintf(stderr, "registry_openkey failed: %s\n",
377 nt_errstr(status));
378 return status;
381 if (!strequal(argv[2], "multi_sz") && (argc != 4)) {
382 d_fprintf(stderr, "Too many args for type %s\n", argv[2]);
383 return NT_STATUS_NOT_IMPLEMENTED;
386 if (strequal(argv[2], "dword")) {
387 value.type = REG_DWORD;
388 value.v.dword = strtoul(argv[3], NULL, 10);
390 else if (strequal(argv[2], "sz")) {
391 value.type = REG_SZ;
392 value.v.sz.len = strlen(argv[3])+1;
393 value.v.sz.str = CONST_DISCARD(char *, argv[3]);
395 else {
396 d_fprintf(stderr, "type \"%s\" not implemented\n", argv[2]);
397 status = NT_STATUS_NOT_IMPLEMENTED;
398 goto error;
401 status = registry_setvalue(mem_ctx, pipe_hnd, &key_hnd,
402 argv[1], &value);
404 if (!NT_STATUS_IS_OK(status)) {
405 d_fprintf(stderr, "registry_setvalue failed: %s\n",
406 nt_errstr(status));
409 error:
410 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &key_hnd, NULL);
411 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd, NULL);
413 return NT_STATUS_OK;
416 static int rpc_registry_setvalue( int argc, const char **argv )
418 if (argc < 4) {
419 d_fprintf(stderr, "usage: net rpc registry setvalue <key> "
420 "<valuename> <type> [<val>]+\n");
421 return -1;
424 return run_rpc_command( NULL, PI_WINREG, 0,
425 rpc_registry_setvalue_internal, argc, argv );
428 static NTSTATUS rpc_registry_deletevalue_internal(const DOM_SID *domain_sid,
429 const char *domain_name,
430 struct cli_state *cli,
431 struct rpc_pipe_client *pipe_hnd,
432 TALLOC_CTX *mem_ctx,
433 int argc,
434 const char **argv )
436 struct policy_handle hive_hnd, key_hnd;
437 NTSTATUS status;
438 struct winreg_String valuename;
440 ZERO_STRUCT(valuename);
442 status = registry_openkey(mem_ctx, pipe_hnd, argv[0],
443 SEC_RIGHTS_MAXIMUM_ALLOWED,
444 &hive_hnd, &key_hnd);
445 if (!NT_STATUS_IS_OK(status)) {
446 d_fprintf(stderr, "registry_openkey failed: %s\n",
447 nt_errstr(status));
448 return status;
451 valuename.name = argv[1];
453 status = rpccli_winreg_DeleteValue(pipe_hnd, mem_ctx, &key_hnd,
454 valuename, NULL);
456 if (!NT_STATUS_IS_OK(status)) {
457 d_fprintf(stderr, "registry_deletevalue failed: %s\n",
458 nt_errstr(status));
461 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &key_hnd, NULL);
462 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd, NULL);
464 return NT_STATUS_OK;
467 static int rpc_registry_deletevalue( int argc, const char **argv )
469 if (argc != 2) {
470 d_fprintf(stderr, "usage: net rpc registry deletevalue <key> "
471 "<valuename>\n");
472 return -1;
475 return run_rpc_command( NULL, PI_WINREG, 0,
476 rpc_registry_deletevalue_internal, argc, argv );
479 static NTSTATUS rpc_registry_createkey_internal(const DOM_SID *domain_sid,
480 const char *domain_name,
481 struct cli_state *cli,
482 struct rpc_pipe_client *pipe_hnd,
483 TALLOC_CTX *mem_ctx,
484 int argc,
485 const char **argv )
487 uint32 hive;
488 struct policy_handle hive_hnd, key_hnd;
489 struct winreg_String key, keyclass;
490 enum winreg_CreateAction action;
491 NTSTATUS status;
493 ZERO_STRUCT(key);
494 ZERO_STRUCT(keyclass);
496 if (!reg_hive_key(argv[0], &hive, &key.name)) {
497 return NT_STATUS_INVALID_PARAMETER;
500 status = rpccli_winreg_Connect(pipe_hnd, mem_ctx, hive,
501 SEC_RIGHTS_MAXIMUM_ALLOWED,
502 &hive_hnd);
503 if (!(NT_STATUS_IS_OK(status))) {
504 return status;
507 action = REG_ACTION_NONE;
508 keyclass.name = "";
510 status = rpccli_winreg_CreateKey(pipe_hnd, mem_ctx, &hive_hnd, key,
511 keyclass, 0, REG_KEY_READ, NULL,
512 &key_hnd, &action, NULL);
513 if (!NT_STATUS_IS_OK(status)) {
514 d_fprintf(stderr, "createkey returned %s\n",
515 nt_errstr(status));
516 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd, NULL);
517 return status;
520 switch (action) {
521 case REG_ACTION_NONE:
522 d_printf("createkey did nothing -- huh?\n");
523 break;
524 case REG_CREATED_NEW_KEY:
525 d_printf("createkey created %s\n", argv[0]);
526 break;
527 case REG_OPENED_EXISTING_KEY:
528 d_printf("createkey opened existing %s\n", argv[0]);
529 break;
532 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &key_hnd, NULL);
533 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd, NULL);
535 return status;
538 static int rpc_registry_createkey( int argc, const char **argv )
540 if (argc != 1) {
541 d_fprintf(stderr, "usage: net rpc registry createkey <key>\n");
542 return -1;
545 return run_rpc_command( NULL, PI_WINREG, 0,
546 rpc_registry_createkey_internal, argc, argv );
549 static NTSTATUS rpc_registry_deletekey_internal(const DOM_SID *domain_sid,
550 const char *domain_name,
551 struct cli_state *cli,
552 struct rpc_pipe_client *pipe_hnd,
553 TALLOC_CTX *mem_ctx,
554 int argc,
555 const char **argv )
557 uint32 hive;
558 struct policy_handle hive_hnd;
559 struct winreg_String key;
560 NTSTATUS status;
562 ZERO_STRUCT(key);
564 if (!reg_hive_key(argv[0], &hive, &key.name)) {
565 return NT_STATUS_INVALID_PARAMETER;
568 status = rpccli_winreg_Connect(pipe_hnd, mem_ctx, hive,
569 SEC_RIGHTS_MAXIMUM_ALLOWED,
570 &hive_hnd);
571 if (!(NT_STATUS_IS_OK(status))) {
572 return status;
575 status = rpccli_winreg_DeleteKey(pipe_hnd, mem_ctx, &hive_hnd, key, NULL);
576 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd, NULL);
578 if (!NT_STATUS_IS_OK(status)) {
579 d_fprintf(stderr, "deletekey returned %s\n",
580 nt_errstr(status));
583 return status;
586 static int rpc_registry_deletekey( int argc, const char **argv )
588 if (argc != 1) {
589 d_fprintf(stderr, "usage: net rpc registry deletekey <key>\n");
590 return -1;
593 return run_rpc_command( NULL, PI_WINREG, 0,
594 rpc_registry_deletekey_internal, argc, argv );
597 /********************************************************************
598 ********************************************************************/
600 static NTSTATUS rpc_registry_enumerate_internal(const DOM_SID *domain_sid,
601 const char *domain_name,
602 struct cli_state *cli,
603 struct rpc_pipe_client *pipe_hnd,
604 TALLOC_CTX *mem_ctx,
605 int argc,
606 const char **argv )
608 POLICY_HND pol_hive, pol_key;
609 NTSTATUS status;
610 uint32 num_subkeys = 0;
611 uint32 num_values = 0;
612 char **names = NULL, **classes = NULL;
613 NTTIME **modtimes = NULL;
614 uint32 i;
615 struct registry_value **values = NULL;
617 if (argc != 1 ) {
618 d_printf("Usage: net rpc registry enumerate <path> [recurse]\n");
619 d_printf("Example: net rpc registry enumerate 'HKLM\\Software\\Samba'\n");
620 return NT_STATUS_OK;
623 status = registry_openkey(mem_ctx, pipe_hnd, argv[0], REG_KEY_READ,
624 &pol_hive, &pol_key);
625 if (!NT_STATUS_IS_OK(status)) {
626 d_fprintf(stderr, "registry_openkey failed: %s\n",
627 nt_errstr(status));
628 return status;
631 status = registry_enumkeys(mem_ctx, pipe_hnd, &pol_key, &num_subkeys,
632 &names, &classes, &modtimes);
633 if (!NT_STATUS_IS_OK(status)) {
634 d_fprintf(stderr, "enumerating keys failed: %s\n",
635 nt_errstr(status));
636 return status;
639 for (i=0; i<num_subkeys; i++) {
640 d_printf("Keyname = %s\n", names[i]);
641 d_printf("Modtime = %s\n", modtimes[i]
642 ? http_timestring(nt_time_to_unix(*modtimes[i]))
643 : "None");
644 d_printf("\n" );
647 status = registry_enumvalues(mem_ctx, pipe_hnd, &pol_key, &num_values,
648 &names, &values);
649 if (!NT_STATUS_IS_OK(status)) {
650 d_fprintf(stderr, "enumerating values failed: %s\n",
651 nt_errstr(status));
652 return status;
655 for (i=0; i<num_values; i++) {
656 struct registry_value *v = values[i];
657 d_printf("Valuename = %s\n", names[i]);
658 d_printf("Type = %s\n",
659 reg_type_lookup(v->type));
660 switch(v->type) {
661 case REG_DWORD:
662 d_printf("Value = %d\n", v->v.dword);
663 break;
664 case REG_SZ:
665 case REG_EXPAND_SZ:
666 d_printf("Value = \"%s\"\n", v->v.sz.str);
667 break;
668 case REG_MULTI_SZ: {
669 uint32 j;
670 for (j = 0; j < v->v.multi_sz.num_strings; j++) {
671 d_printf("Value[%3.3d] = \"%s\"\n", j,
672 v->v.multi_sz.strings[j]);
674 break;
676 case REG_BINARY:
677 d_printf("Value = %d bytes\n",
678 (int)v->v.binary.length);
679 break;
680 default:
681 d_printf("Value = <unprintable>\n");
682 break;
685 d_printf("\n");
688 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_key, NULL);
689 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_hive, NULL);
691 return status;
694 /********************************************************************
695 ********************************************************************/
697 static int rpc_registry_enumerate( int argc, const char **argv )
699 return run_rpc_command( NULL, PI_WINREG, 0,
700 rpc_registry_enumerate_internal, argc, argv );
703 /********************************************************************
704 ********************************************************************/
706 static NTSTATUS rpc_registry_save_internal(const DOM_SID *domain_sid,
707 const char *domain_name,
708 struct cli_state *cli,
709 struct rpc_pipe_client *pipe_hnd,
710 TALLOC_CTX *mem_ctx,
711 int argc,
712 const char **argv )
714 WERROR result = WERR_GENERAL_FAILURE;
715 POLICY_HND pol_hive, pol_key;
716 NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
717 struct winreg_String filename;
719 if (argc != 2 ) {
720 d_printf("Usage: net rpc registry backup <path> <file> \n");
721 return NT_STATUS_OK;
724 status = registry_openkey(mem_ctx, pipe_hnd, argv[0], REG_KEY_ALL,
725 &pol_hive, &pol_key);
726 if (!NT_STATUS_IS_OK(status)) {
727 d_fprintf(stderr, "registry_openkey failed: %s\n",
728 nt_errstr(status));
729 return status;
732 filename.name = argv[1];
733 status = rpccli_winreg_SaveKey( pipe_hnd, mem_ctx, &pol_key, &filename, NULL, NULL);
734 if ( !W_ERROR_IS_OK(result) ) {
735 d_fprintf(stderr, "Unable to save [%s] to %s:%s\n", argv[0], cli->desthost, argv[1]);
738 /* cleanup */
740 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_key, NULL);
741 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_hive, NULL);
743 return status;
746 /********************************************************************
747 ********************************************************************/
749 static int rpc_registry_save( int argc, const char **argv )
751 return run_rpc_command( NULL, PI_WINREG, 0,
752 rpc_registry_save_internal, argc, argv );
756 /********************************************************************
757 ********************************************************************/
759 static void dump_values( REGF_NK_REC *nk )
761 int i, j;
762 char *data_str = NULL;
763 uint32 data_size, data;
765 if ( !nk->values )
766 return;
768 for ( i=0; i<nk->num_values; i++ ) {
769 d_printf( "\"%s\" = ", nk->values[i].valuename ? nk->values[i].valuename : "(default)" );
770 d_printf( "(%s) ", reg_type_lookup( nk->values[i].type ) );
772 data_size = nk->values[i].data_size & ~VK_DATA_IN_OFFSET;
773 switch ( nk->values[i].type ) {
774 case REG_SZ:
775 rpcstr_pull_talloc(talloc_tos(),
776 &data_str,
777 nk->values[i].data,
779 STR_TERMINATE);
780 if (!data_str) {
781 break;
783 d_printf( "%s", data_str );
784 break;
785 case REG_MULTI_SZ:
786 case REG_EXPAND_SZ:
787 for ( j=0; j<data_size; j++ ) {
788 d_printf( "%c", nk->values[i].data[j] );
790 break;
791 case REG_DWORD:
792 data = IVAL( nk->values[i].data, 0 );
793 d_printf("0x%x", data );
794 break;
795 case REG_BINARY:
796 for ( j=0; j<data_size; j++ ) {
797 d_printf( "%x", nk->values[i].data[j] );
799 break;
800 default:
801 d_printf("unknown");
802 break;
805 d_printf( "\n" );
810 /********************************************************************
811 ********************************************************************/
813 static bool dump_registry_tree( REGF_FILE *file, REGF_NK_REC *nk, const char *parent )
815 REGF_NK_REC *key;
817 /* depth first dump of the registry tree */
819 while ( (key = regfio_fetch_subkey( file, nk )) ) {
820 char *regpath;
821 if (asprintf(&regpath, "%s\\%s", parent, key->keyname) < 0) {
822 break;
824 d_printf("[%s]\n", regpath );
825 dump_values( key );
826 d_printf("\n");
827 dump_registry_tree( file, key, regpath );
828 SAFE_FREE(regpath);
831 return True;
834 /********************************************************************
835 ********************************************************************/
837 static bool write_registry_tree( REGF_FILE *infile, REGF_NK_REC *nk,
838 REGF_NK_REC *parent, REGF_FILE *outfile,
839 const char *parentpath )
841 REGF_NK_REC *key, *subkey;
842 REGVAL_CTR *values = NULL;
843 REGSUBKEY_CTR *subkeys = NULL;
844 int i;
845 char *path = NULL;
847 if ( !( subkeys = TALLOC_ZERO_P( infile->mem_ctx, REGSUBKEY_CTR )) ) {
848 DEBUG(0,("write_registry_tree: talloc() failed!\n"));
849 return False;
852 if ( !(values = TALLOC_ZERO_P( subkeys, REGVAL_CTR )) ) {
853 DEBUG(0,("write_registry_tree: talloc() failed!\n"));
854 TALLOC_FREE(subkeys);
855 return False;
858 /* copy values into the REGVAL_CTR */
860 for ( i=0; i<nk->num_values; i++ ) {
861 regval_ctr_addvalue( values, nk->values[i].valuename, nk->values[i].type,
862 (const char *)nk->values[i].data, (nk->values[i].data_size & ~VK_DATA_IN_OFFSET) );
865 /* copy subkeys into the REGSUBKEY_CTR */
867 while ( (subkey = regfio_fetch_subkey( infile, nk )) ) {
868 regsubkey_ctr_addkey( subkeys, subkey->keyname );
871 key = regfio_write_key( outfile, nk->keyname, values, subkeys, nk->sec_desc->sec_desc, parent );
873 /* write each one of the subkeys out */
875 path = talloc_asprintf(subkeys,
876 "%s%s%s",
877 parentpath,
878 parent ? "\\" : "",
879 nk->keyname);
880 if (!path) {
881 TALLOC_FREE(subkeys);
882 return false;
885 nk->subkey_index = 0;
886 while ( (subkey = regfio_fetch_subkey( infile, nk )) ) {
887 write_registry_tree( infile, subkey, key, outfile, path );
890 d_printf("[%s]\n", path );
891 TALLOC_FREE(subkeys);
893 return True;
896 /********************************************************************
897 ********************************************************************/
899 static int rpc_registry_dump( int argc, const char **argv )
901 REGF_FILE *registry;
902 REGF_NK_REC *nk;
904 if (argc != 1 ) {
905 d_printf("Usage: net rpc registry dump <file> \n");
906 return 0;
909 d_printf("Opening %s....", argv[0]);
910 if ( !(registry = regfio_open( argv[0], O_RDONLY, 0)) ) {
911 d_fprintf(stderr, "Failed to open %s for reading\n", argv[0]);
912 return 1;
914 d_printf("ok\n");
916 /* get the root of the registry file */
918 if ((nk = regfio_rootkey( registry )) == NULL) {
919 d_fprintf(stderr, "Could not get rootkey\n");
920 regfio_close( registry );
921 return 1;
923 d_printf("[%s]\n", nk->keyname);
924 dump_values( nk );
925 d_printf("\n");
927 dump_registry_tree( registry, nk, nk->keyname );
929 #if 0
930 talloc_report_full( registry->mem_ctx, stderr );
931 #endif
932 d_printf("Closing registry...");
933 regfio_close( registry );
934 d_printf("ok\n");
936 return 0;
939 /********************************************************************
940 ********************************************************************/
942 static int rpc_registry_copy( int argc, const char **argv )
944 REGF_FILE *infile = NULL, *outfile = NULL;
945 REGF_NK_REC *nk;
946 int result = 1;
948 if (argc != 2 ) {
949 d_printf("Usage: net rpc registry copy <srcfile> <newfile>\n");
950 return 0;
953 d_printf("Opening %s....", argv[0]);
954 if ( !(infile = regfio_open( argv[0], O_RDONLY, 0 )) ) {
955 d_fprintf(stderr, "Failed to open %s for reading\n", argv[0]);
956 return 1;
958 d_printf("ok\n");
960 d_printf("Opening %s....", argv[1]);
961 if ( !(outfile = regfio_open( argv[1], (O_RDWR|O_CREAT|O_TRUNC), (S_IREAD|S_IWRITE) )) ) {
962 d_fprintf(stderr, "Failed to open %s for writing\n", argv[1]);
963 goto out;
965 d_printf("ok\n");
967 /* get the root of the registry file */
969 if ((nk = regfio_rootkey( infile )) == NULL) {
970 d_fprintf(stderr, "Could not get rootkey\n");
971 goto out;
973 d_printf("RootKey: [%s]\n", nk->keyname);
975 write_registry_tree( infile, nk, NULL, outfile, "" );
977 result = 0;
979 out:
981 d_printf("Closing %s...", argv[1]);
982 if (outfile) {
983 regfio_close( outfile );
985 d_printf("ok\n");
987 d_printf("Closing %s...", argv[0]);
988 if (infile) {
989 regfio_close( infile );
991 d_printf("ok\n");
993 return( result);
996 /********************************************************************
997 ********************************************************************/
999 static NTSTATUS rpc_registry_getsd_internal(const DOM_SID *domain_sid,
1000 const char *domain_name,
1001 struct cli_state *cli,
1002 struct rpc_pipe_client *pipe_hnd,
1003 TALLOC_CTX *mem_ctx,
1004 int argc,
1005 const char **argv)
1007 POLICY_HND pol_hive, pol_key;
1008 NTSTATUS status;
1009 enum ndr_err_code ndr_err;
1010 struct KeySecurityData *sd = NULL;
1011 uint32_t sec_info;
1012 DATA_BLOB blob;
1013 struct security_descriptor sec_desc;
1014 uint32_t access_mask = REG_KEY_READ |
1015 SEC_RIGHT_MAXIMUM_ALLOWED |
1016 SEC_RIGHT_SYSTEM_SECURITY;
1018 if (argc <1 || argc > 2) {
1019 d_printf("Usage: net rpc registry getsd <path> <secinfo>\n");
1020 d_printf("Example: net rpc registry getsd 'HKLM\\Software\\Samba'\n");
1021 return NT_STATUS_OK;
1024 status = registry_openkey(mem_ctx, pipe_hnd, argv[0],
1025 access_mask,
1026 &pol_hive, &pol_key);
1027 if (!NT_STATUS_IS_OK(status)) {
1028 d_fprintf(stderr, "registry_openkey failed: %s\n",
1029 nt_errstr(status));
1030 return status;
1033 sd = TALLOC_ZERO_P(mem_ctx, struct KeySecurityData);
1034 if (!sd) {
1035 status = NT_STATUS_NO_MEMORY;
1036 goto out;
1039 sd->size = 0x1000;
1041 if (argc >= 2) {
1042 sscanf(argv[1], "%x", &sec_info);
1043 } else {
1044 sec_info = SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL;
1047 status = registry_getsd(mem_ctx, pipe_hnd, &pol_key, sec_info, sd);
1048 if (!NT_STATUS_IS_OK(status)) {
1049 d_fprintf(stderr, "getting sd failed: %s\n",
1050 nt_errstr(status));
1051 goto out;
1054 blob.data = sd->data;
1055 blob.length = sd->size;
1057 ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &sec_desc,
1058 (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
1059 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1060 status = ndr_map_error2ntstatus(ndr_err);
1061 goto out;
1063 status = NT_STATUS_OK;
1065 display_sec_desc(&sec_desc);
1067 out:
1068 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_key, NULL);
1069 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_hive, NULL);
1071 return status;
1075 static int rpc_registry_getsd(int argc, const char **argv)
1077 return run_rpc_command(NULL, PI_WINREG, 0,
1078 rpc_registry_getsd_internal, argc, argv);
1081 /********************************************************************
1082 ********************************************************************/
1084 int net_rpc_registry(int argc, const char **argv)
1086 struct functable2 func[] = {
1087 { "enumerate", rpc_registry_enumerate,
1088 "Enumerate registry keys and values" },
1089 { "createkey", rpc_registry_createkey,
1090 "Create a new registry key" },
1091 { "deletekey", rpc_registry_deletekey,
1092 "Delete a registry key" },
1093 { "setvalue", rpc_registry_setvalue,
1094 "Set a new registry value" },
1095 { "deletevalue", rpc_registry_deletevalue,
1096 "Delete a registry value" },
1097 { "save", rpc_registry_save,
1098 "Save a registry file" },
1099 { "dump", rpc_registry_dump,
1100 "Dump a registry file" },
1101 { "copy", rpc_registry_copy,
1102 "Copy a registry file" },
1103 { "getsd", rpc_registry_getsd,
1104 "Get security descriptor" },
1105 {NULL, NULL, NULL}
1108 return net_run_function2(argc, argv, "net rpc registry", func);