2 * Samba Unix/Linux SMB client library
3 * Distributed SMB/CIFS Server Management Utility
4 * Local registry interface
6 * Copyright (C) Michael Adam 2008
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 3 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "registry/reg_util_token.h"
25 #include "utils/net.h"
26 #include "utils/net_registry_util.h"
27 #include "include/g_lock.h"
36 * split given path into hive and remaining path and open the hive key
38 static WERROR
open_hive(TALLOC_CTX
*ctx
, const char *path
,
39 uint32 desired_access
,
40 struct registry_key
**hive
,
44 NT_USER_TOKEN
*token
= NULL
;
45 char *hivename
= NULL
;
46 char *tmp_subkeyname
= NULL
;
47 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
49 if ((hive
== NULL
) || (subkeyname
== NULL
)) {
50 werr
= WERR_INVALID_PARAM
;
54 werr
= split_hive_key(tmp_ctx
, path
, &hivename
, &tmp_subkeyname
);
55 if (!W_ERROR_IS_OK(werr
)) {
58 *subkeyname
= talloc_strdup(ctx
, tmp_subkeyname
);
59 if (*subkeyname
== NULL
) {
64 werr
= ntstatus_to_werror(registry_create_admin_token(tmp_ctx
, &token
));
65 if (!W_ERROR_IS_OK(werr
)) {
69 werr
= reg_openhive(ctx
, hivename
, desired_access
, token
, hive
);
70 if (!W_ERROR_IS_OK(werr
)) {
81 static WERROR
open_key(TALLOC_CTX
*ctx
, const char *path
,
82 uint32 desired_access
,
83 struct registry_key
**key
)
86 char *subkey_name
= NULL
;
87 struct registry_key
*hive
= NULL
;
88 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
90 if ((path
== NULL
) || (key
== NULL
)) {
91 return WERR_INVALID_PARAM
;
94 werr
= open_hive(tmp_ctx
, path
, desired_access
, &hive
, &subkey_name
);
95 if (!W_ERROR_IS_OK(werr
)) {
96 d_fprintf(stderr
, _("open_hive failed: %s\n"),
101 werr
= reg_openkey(ctx
, hive
, subkey_name
, desired_access
, key
);
102 if (!W_ERROR_IS_OK(werr
)) {
103 d_fprintf(stderr
, _("reg_openkey failed: %s\n"),
111 TALLOC_FREE(tmp_ctx
);
117 * the main "net registry" function implementations
121 static int net_registry_enumerate(struct net_context
*c
, int argc
,
125 struct registry_key
*key
= NULL
;
126 TALLOC_CTX
*ctx
= talloc_stackframe();
130 char *valname
= NULL
;
131 struct registry_value
*valvalue
= NULL
;
134 if (argc
!= 1 || c
->display_usage
) {
137 _("net registry enumerate <path>\n"));
140 _("net registry enumerate 'HKLM\\Software\\Samba'\n"));
144 werr
= open_key(ctx
, argv
[0], REG_KEY_READ
, &key
);
145 if (!W_ERROR_IS_OK(werr
)) {
146 d_fprintf(stderr
, _("open_key failed: %s\n"), win_errstr(werr
));
151 werr
= reg_enumkey(ctx
, key
, count
, &subkey_name
, &modtime
),
155 print_registry_key(subkey_name
, &modtime
);
157 if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS
, werr
)) {
162 werr
= reg_enumvalue(ctx
, key
, count
, &valname
, &valvalue
),
166 print_registry_value_with_name(valname
, valvalue
);
168 if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS
, werr
)) {
178 static int net_registry_createkey(struct net_context
*c
, int argc
,
182 enum winreg_CreateAction action
;
184 struct registry_key
*hivekey
= NULL
;
185 struct registry_key
*subkey
= NULL
;
186 TALLOC_CTX
*ctx
= talloc_stackframe();
189 if (argc
!= 1 || c
->display_usage
) {
192 _("net registry createkey <path>\n"));
195 _("net registry createkey "
196 "'HKLM\\Software\\Samba\\smbconf.127.0.0.1'\n"));
199 if (strlen(argv
[0]) == 0) {
200 d_fprintf(stderr
, _("error: zero length key name given\n"));
204 werr
= open_hive(ctx
, argv
[0], REG_KEY_WRITE
, &hivekey
, &subkeyname
);
205 if (!W_ERROR_IS_OK(werr
)) {
206 d_fprintf(stderr
, _("open_hive failed: %s\n"),
211 werr
= reg_createkey(ctx
, hivekey
, subkeyname
, REG_KEY_WRITE
,
213 if (!W_ERROR_IS_OK(werr
)) {
214 d_fprintf(stderr
, _("reg_createkey failed: %s\n"),
219 case REG_ACTION_NONE
:
220 d_printf(_("createkey did nothing -- huh?\n"));
222 case REG_CREATED_NEW_KEY
:
223 d_printf(_("createkey created %s\n"), argv
[0]);
225 case REG_OPENED_EXISTING_KEY
:
226 d_printf(_("createkey opened existing %s\n"), argv
[0]);
237 static int net_registry_deletekey(struct net_context
*c
, int argc
,
242 struct registry_key
*hivekey
= NULL
;
243 TALLOC_CTX
*ctx
= talloc_stackframe();
246 if (argc
!= 1 || c
->display_usage
) {
249 _("net registry deletekey <path>\n"));
252 _("net registry deletekey "
253 "'HKLM\\Software\\Samba\\smbconf.127.0.0.1'\n"));
256 if (strlen(argv
[0]) == 0) {
257 d_fprintf(stderr
, _("error: zero length key name given\n"));
261 werr
= open_hive(ctx
, argv
[0], REG_KEY_WRITE
, &hivekey
, &subkeyname
);
262 if (!W_ERROR_IS_OK(werr
)) {
263 d_fprintf(stderr
, "open_hive %s: %s\n", _("failed"),
268 werr
= reg_deletekey(hivekey
, subkeyname
);
269 if (!W_ERROR_IS_OK(werr
)) {
270 d_fprintf(stderr
, "reg_deletekey %s: %s\n", _("failed"),
282 static int net_registry_getvalue_internal(struct net_context
*c
, int argc
,
283 const char **argv
, bool raw
)
287 struct registry_key
*key
= NULL
;
288 struct registry_value
*value
= NULL
;
289 TALLOC_CTX
*ctx
= talloc_stackframe();
291 if (argc
!= 2 || c
->display_usage
) {
292 d_fprintf(stderr
, "%s\n%s",
294 _("net registry getvalue <key> <valuename>\n"));
298 werr
= open_key(ctx
, argv
[0], REG_KEY_READ
, &key
);
299 if (!W_ERROR_IS_OK(werr
)) {
300 d_fprintf(stderr
, _("open_key failed: %s\n"), win_errstr(werr
));
304 werr
= reg_queryvalue(ctx
, key
, argv
[1], &value
);
305 if (!W_ERROR_IS_OK(werr
)) {
306 d_fprintf(stderr
, _("reg_queryvalue failed: %s\n"),
311 print_registry_value(value
, raw
);
320 static int net_registry_getvalue(struct net_context
*c
, int argc
,
323 return net_registry_getvalue_internal(c
, argc
, argv
, false);
326 static int net_registry_getvalueraw(struct net_context
*c
, int argc
,
329 return net_registry_getvalue_internal(c
, argc
, argv
, true);
332 static int net_registry_setvalue(struct net_context
*c
, int argc
,
336 struct registry_value value
;
337 struct registry_key
*key
= NULL
;
339 TALLOC_CTX
*ctx
= talloc_stackframe();
341 if (argc
< 4 || c
->display_usage
) {
342 d_fprintf(stderr
, "%s\n%s",
344 _("net registry setvalue <key> <valuename> "
345 "<type> [<val>]+\n"));
349 if (!strequal(argv
[2], "multi_sz") && (argc
!= 4)) {
350 d_fprintf(stderr
, _("Too many args for type %s\n"), argv
[2]);
354 if (strequal(argv
[2], "dword")) {
355 value
.type
= REG_DWORD
;
356 value
.v
.dword
= strtoul(argv
[3], NULL
, 10);
357 } else if (strequal(argv
[2], "sz")) {
359 value
.v
.sz
.len
= strlen(argv
[3])+1;
360 value
.v
.sz
.str
= CONST_DISCARD(char *, argv
[3]);
361 } else if (strequal(argv
[2], "multi_sz")) {
362 value
.type
= REG_MULTI_SZ
;
363 value
.v
.multi_sz
.num_strings
= argc
- 3;
364 value
.v
.multi_sz
.strings
= (char **)(argv
+ 3);
366 d_fprintf(stderr
, _("type \"%s\" not implemented\n"), argv
[2]);
370 werr
= open_key(ctx
, argv
[0], REG_KEY_WRITE
, &key
);
371 if (!W_ERROR_IS_OK(werr
)) {
372 d_fprintf(stderr
, _("open_key failed: %s\n"), win_errstr(werr
));
376 werr
= reg_setvalue(key
, argv
[1], &value
);
377 if (!W_ERROR_IS_OK(werr
)) {
378 d_fprintf(stderr
, _("reg_setvalue failed: %s\n"),
390 struct net_registry_increment_state
{
392 const char *valuename
;
398 static void net_registry_increment_fn(void *private_data
)
400 struct net_registry_increment_state
*state
=
401 (struct net_registry_increment_state
*)private_data
;
402 struct registry_value
*value
;
403 struct registry_key
*key
= NULL
;
405 state
->werr
= open_key(talloc_tos(), state
->keyname
,
406 REG_KEY_READ
|REG_KEY_WRITE
, &key
);
407 if (!W_ERROR_IS_OK(state
->werr
)) {
408 d_fprintf(stderr
, _("open_key failed: %s\n"),
409 win_errstr(state
->werr
));
413 state
->werr
= reg_queryvalue(key
, key
, state
->valuename
, &value
);
414 if (!W_ERROR_IS_OK(state
->werr
)) {
415 d_fprintf(stderr
, _("reg_queryvalue failed: %s\n"),
416 win_errstr(state
->werr
));
420 if (value
->type
!= REG_DWORD
) {
421 d_fprintf(stderr
, _("value not a DWORD: %s\n"),
422 str_regtype(value
->type
));
426 value
->v
.dword
+= state
->increment
;
427 state
->newvalue
= value
->v
.dword
;
429 state
->werr
= reg_setvalue(key
, state
->valuename
, value
);
430 if (!W_ERROR_IS_OK(state
->werr
)) {
431 d_fprintf(stderr
, _("reg_setvalue failed: %s\n"),
432 win_errstr(state
->werr
));
441 static int net_registry_increment(struct net_context
*c
, int argc
,
444 struct net_registry_increment_state state
;
448 if (argc
< 2 || c
->display_usage
) {
449 d_fprintf(stderr
, "%s\n%s",
451 _("net registry increment <key> <valuename> "
456 state
.keyname
= argv
[0];
457 state
.valuename
= argv
[1];
461 state
.increment
= strtoul(argv
[2], NULL
, 10);
464 status
= g_lock_do("registry_increment_lock", G_LOCK_WRITE
,
466 net_registry_increment_fn
, &state
);
467 if (!NT_STATUS_IS_OK(status
)) {
468 d_fprintf(stderr
, _("g_lock_do failed: %s\n"),
472 if (!W_ERROR_IS_OK(state
.werr
)) {
473 d_fprintf(stderr
, _("increment failed: %s\n"),
474 win_errstr(state
.werr
));
478 d_printf(_("%u\n"), (unsigned)state
.newvalue
);
486 static int net_registry_deletevalue(struct net_context
*c
, int argc
,
490 struct registry_key
*key
= NULL
;
491 TALLOC_CTX
*ctx
= talloc_stackframe();
494 if (argc
!= 2 || c
->display_usage
) {
495 d_fprintf(stderr
, "%s\n%s",
497 _("net registry deletevalue <key> <valuename>\n"));
501 werr
= open_key(ctx
, argv
[0], REG_KEY_WRITE
, &key
);
502 if (!W_ERROR_IS_OK(werr
)) {
503 d_fprintf(stderr
, _("open_key failed: %s\n"), win_errstr(werr
));
507 werr
= reg_deletevalue(key
, argv
[1]);
508 if (!W_ERROR_IS_OK(werr
)) {
509 d_fprintf(stderr
, _("reg_deletekey failed: %s\n"),
521 static WERROR
net_registry_getsd_internal(struct net_context
*c
,
524 struct security_descriptor
**sd
)
527 struct registry_key
*key
= NULL
;
528 TALLOC_CTX
*ctx
= talloc_stackframe();
529 uint32_t access_mask
= REG_KEY_READ
|
530 SEC_FLAG_MAXIMUM_ALLOWED
|
531 SEC_FLAG_SYSTEM_SECURITY
;
534 * net_rpc_regsitry uses SEC_FLAG_SYSTEM_SECURITY, but access
535 * is denied with these perms right now...
537 access_mask
= REG_KEY_READ
;
540 d_fprintf(stderr
, _("internal error: invalid argument\n"));
541 werr
= WERR_INVALID_PARAM
;
545 if (strlen(keyname
) == 0) {
546 d_fprintf(stderr
, _("error: zero length key name given\n"));
547 werr
= WERR_INVALID_PARAM
;
551 werr
= open_key(ctx
, keyname
, access_mask
, &key
);
552 if (!W_ERROR_IS_OK(werr
)) {
553 d_fprintf(stderr
, "%s%s\n", _("open_key failed: "),
558 werr
= reg_getkeysecurity(mem_ctx
, key
, sd
);
559 if (!W_ERROR_IS_OK(werr
)) {
560 d_fprintf(stderr
, "%s%s\n", _("reg_getkeysecurity failed: "),
572 static int net_registry_getsd(struct net_context
*c
, int argc
,
577 struct security_descriptor
*secdesc
= NULL
;
578 TALLOC_CTX
*ctx
= talloc_stackframe();
580 if (argc
!= 1 || c
->display_usage
) {
583 _("net registry getsd <path>\n"));
586 _("net registry getsd 'HKLM\\Software\\Samba'\n"));
590 werr
= net_registry_getsd_internal(c
, ctx
, argv
[0], &secdesc
);
591 if (!W_ERROR_IS_OK(werr
)) {
595 display_sec_desc(secdesc
);
604 static int net_registry_getsd_sddl(struct net_context
*c
,
605 int argc
, const char **argv
)
609 struct security_descriptor
*secdesc
= NULL
;
610 TALLOC_CTX
*ctx
= talloc_stackframe();
612 if (argc
!= 1 || c
->display_usage
) {
615 _("net registry getsd_sddl <path>\n"));
618 _("net registry getsd_sddl 'HKLM\\Software\\Samba'\n"));
622 werr
= net_registry_getsd_internal(c
, ctx
, argv
[0], &secdesc
);
623 if (!W_ERROR_IS_OK(werr
)) {
627 d_printf("%s\n", sddl_encode(ctx
, secdesc
, get_global_sam_sid()));
636 static WERROR
net_registry_setsd_internal(struct net_context
*c
,
639 struct security_descriptor
*sd
)
642 struct registry_key
*key
= NULL
;
643 TALLOC_CTX
*ctx
= talloc_stackframe();
644 uint32_t access_mask
= REG_KEY_WRITE
|
645 SEC_FLAG_MAXIMUM_ALLOWED
|
646 SEC_FLAG_SYSTEM_SECURITY
;
649 * net_rpc_regsitry uses SEC_FLAG_SYSTEM_SECURITY, but access
650 * is denied with these perms right now...
652 access_mask
= REG_KEY_WRITE
;
654 if (strlen(keyname
) == 0) {
655 d_fprintf(stderr
, _("error: zero length key name given\n"));
656 werr
= WERR_INVALID_PARAM
;
660 werr
= open_key(ctx
, keyname
, access_mask
, &key
);
661 if (!W_ERROR_IS_OK(werr
)) {
662 d_fprintf(stderr
, "%s%s\n", _("open_key failed: "),
667 werr
= reg_setkeysecurity(key
, sd
);
668 if (!W_ERROR_IS_OK(werr
)) {
669 d_fprintf(stderr
, "%s%s\n", _("reg_setkeysecurity failed: "),
681 static int net_registry_setsd_sddl(struct net_context
*c
,
682 int argc
, const char **argv
)
686 struct security_descriptor
*secdesc
= NULL
;
687 TALLOC_CTX
*ctx
= talloc_stackframe();
689 if (argc
!= 2 || c
->display_usage
) {
692 _("net registry setsd_sddl <path> <security_descriptor>\n"));
695 _("net registry setsd_sddl 'HKLM\\Software\\Samba'\n"));
699 secdesc
= sddl_decode(ctx
, argv
[1], get_global_sam_sid());
700 if (secdesc
== NULL
) {
704 werr
= net_registry_setsd_internal(c
, ctx
, argv
[0], secdesc
);
705 if (!W_ERROR_IS_OK(werr
)) {
716 int net_registry(struct net_context
*c
, int argc
, const char **argv
)
720 struct functable func
[] = {
723 net_registry_enumerate
,
725 N_("Enumerate registry keys and values"),
726 N_("net registry enumerate\n"
727 " Enumerate registry keys and values")
731 net_registry_createkey
,
733 N_("Create a new registry key"),
734 N_("net registry createkey\n"
735 " Create a new registry key")
739 net_registry_deletekey
,
741 N_("Delete a registry key"),
742 N_("net registry deletekey\n"
743 " Delete a registry key")
747 net_registry_getvalue
,
749 N_("Print a registry value"),
750 N_("net registry getvalue\n"
751 " Print a registry value")
755 net_registry_getvalueraw
,
757 N_("Print a registry value (raw format)"),
758 N_("net registry getvalueraw\n"
759 " Print a registry value (raw format)")
763 net_registry_setvalue
,
765 N_("Set a new registry value"),
766 N_("net registry setvalue\n"
767 " Set a new registry value")
771 net_registry_increment
,
773 N_("Increment a DWORD registry value under a lock"),
774 N_("net registry increment\n"
775 " Increment a DWORD registry value under a lock")
779 net_registry_deletevalue
,
781 N_("Delete a registry value"),
782 N_("net registry deletevalue\n"
783 " Delete a registry value")
789 N_("Get security descriptor"),
790 N_("net registry getsd\n"
791 " Get security descriptor")
795 net_registry_getsd_sddl
,
797 N_("Get security descriptor in sddl format"),
798 N_("net registry getsd_sddl\n"
799 " Get security descriptor in sddl format")
803 net_registry_setsd_sddl
,
805 N_("Set security descriptor from sddl format string"),
806 N_("net registry setsd_sddl\n"
807 " Set security descriptor from sddl format string")
809 { NULL
, NULL
, 0, NULL
, NULL
}
812 if (!W_ERROR_IS_OK(registry_init_basic())) {
816 ret
= net_run_function(c
, argc
, argv
, "net registry", func
);