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/>.
23 #include "utils/net.h"
24 #include "utils/net_registry_util.h"
25 #include "include/g_lock.h"
35 * split given path into hive and remaining path and open the hive key
37 static WERROR open_hive(TALLOC_CTX *ctx, const char *path,
38 uint32 desired_access,
39 struct registry_key **hive,
43 NT_USER_TOKEN *token = NULL;
44 char *hivename = NULL;
45 char *tmp_subkeyname = NULL;
46 TALLOC_CTX *tmp_ctx = talloc_stackframe();
48 if ((hive == NULL) || (subkeyname == NULL)) {
49 werr = WERR_INVALID_PARAM;
53 werr = split_hive_key(tmp_ctx, path, &hivename, &tmp_subkeyname);
54 if (!W_ERROR_IS_OK(werr)) {
57 *subkeyname = talloc_strdup(ctx, tmp_subkeyname);
58 if (*subkeyname == NULL) {
63 werr = ntstatus_to_werror(registry_create_admin_token(tmp_ctx, &token));
64 if (!W_ERROR_IS_OK(werr)) {
68 werr = reg_openhive(ctx, hivename, desired_access, token, hive);
69 if (!W_ERROR_IS_OK(werr)) {
80 static WERROR open_key(TALLOC_CTX *ctx, const char *path,
81 uint32 desired_access,
82 struct registry_key **key)
85 char *subkey_name = NULL;
86 struct registry_key *hive = NULL;
87 TALLOC_CTX *tmp_ctx = talloc_stackframe();
89 if ((path == NULL) || (key == NULL)) {
90 return WERR_INVALID_PARAM;
93 werr = open_hive(tmp_ctx, path, desired_access, &hive, &subkey_name);
94 if (!W_ERROR_IS_OK(werr)) {
95 d_fprintf(stderr, "open_hive failed: %s\n", win_errstr(werr));
99 werr = reg_openkey(ctx, hive, subkey_name, desired_access, key);
100 if (!W_ERROR_IS_OK(werr)) {
101 d_fprintf(stderr, "reg_openkey failed: %s\n",
109 TALLOC_FREE(tmp_ctx);
115 * the main "net registry" function implementations
119 static int net_registry_enumerate(struct net_context *c, int argc,
123 struct registry_key *key = NULL;
124 TALLOC_CTX *ctx = talloc_stackframe();
128 char *valname = NULL;
129 struct registry_value *valvalue = NULL;
132 if (argc != 1 || c->display_usage) {
133 d_printf("Usage: net registry enumerate <path>\n");
134 d_printf("Example: net registry enumerate "
135 "'HKLM\\Software\\Samba'\n");
139 werr = open_key(ctx, argv[0], REG_KEY_READ, &key);
140 if (!W_ERROR_IS_OK(werr)) {
141 d_fprintf(stderr, "open_key failed: %s\n", win_errstr(werr));
146 werr = reg_enumkey(ctx, key, count, &subkey_name, &modtime),
150 print_registry_key(subkey_name, &modtime);
152 if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) {
157 werr = reg_enumvalue(ctx, key, count, &valname, &valvalue),
161 print_registry_value_with_name(valname, valvalue);
163 if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) {
173 static int net_registry_createkey(struct net_context *c, int argc,
177 enum winreg_CreateAction action;
179 struct registry_key *hivekey = NULL;
180 struct registry_key *subkey = NULL;
181 TALLOC_CTX *ctx = talloc_stackframe();
184 if (argc != 1 || c->display_usage) {
185 d_printf("Usage: net registry createkey <path>\n");
186 d_printf("Example: net registry createkey "
187 "'HKLM\\Software\\Samba\\smbconf.127.0.0.1'\n");
190 if (strlen(argv[0]) == 0) {
191 d_fprintf(stderr, "error: zero length key name given\n");
195 werr = open_hive(ctx, argv[0], REG_KEY_WRITE, &hivekey, &subkeyname);
196 if (!W_ERROR_IS_OK(werr)) {
197 d_fprintf(stderr, "open_hive failed: %s\n", win_errstr(werr));
201 werr = reg_createkey(ctx, hivekey, subkeyname, REG_KEY_WRITE,
203 if (!W_ERROR_IS_OK(werr)) {
204 d_fprintf(stderr, "reg_createkey failed: %s\n",
209 case REG_ACTION_NONE:
210 d_printf("createkey did nothing -- huh?\n");
212 case REG_CREATED_NEW_KEY:
213 d_printf("createkey created %s\n", argv[0]);
215 case REG_OPENED_EXISTING_KEY:
216 d_printf("createkey opened existing %s\n", argv[0]);
227 static int net_registry_deletekey(struct net_context *c, int argc,
232 struct registry_key *hivekey = NULL;
233 TALLOC_CTX *ctx = talloc_stackframe();
236 if (argc != 1 || c->display_usage) {
237 d_printf("Usage: net registry deletekey <path>\n");
238 d_printf("Example: net registry deletekey "
239 "'HKLM\\Software\\Samba\\smbconf.127.0.0.1'\n");
242 if (strlen(argv[0]) == 0) {
243 d_fprintf(stderr, "error: zero length key name given\n");
247 werr = open_hive(ctx, argv[0], REG_KEY_WRITE, &hivekey, &subkeyname);
248 if (!W_ERROR_IS_OK(werr)) {
249 d_fprintf(stderr, "open_hive failed: %s\n", win_errstr(werr));
253 werr = reg_deletekey(hivekey, subkeyname);
254 if (!W_ERROR_IS_OK(werr)) {
255 d_fprintf(stderr, "reg_deletekey failed: %s\n",
267 static int net_registry_getvalue_internal(struct net_context *c, int argc,
268 const char **argv, bool raw)
272 struct registry_key *key = NULL;
273 struct registry_value *value = NULL;
274 TALLOC_CTX *ctx = talloc_stackframe();
276 if (argc != 2 || c->display_usage) {
277 d_fprintf(stderr, "usage: net rpc registry getvalue <key> "
282 werr = open_key(ctx, argv[0], REG_KEY_READ, &key);
283 if (!W_ERROR_IS_OK(werr)) {
284 d_fprintf(stderr, "open_key failed: %s\n", win_errstr(werr));
288 werr = reg_queryvalue(ctx, key, argv[1], &value);
289 if (!W_ERROR_IS_OK(werr)) {
290 d_fprintf(stderr, "reg_queryvalue failed: %s\n",
295 print_registry_value(value, raw);
304 static int net_registry_getvalue(struct net_context *c, int argc,
307 return net_registry_getvalue_internal(c, argc, argv, false);
310 static int net_registry_getvalueraw(struct net_context *c, int argc,
313 return net_registry_getvalue_internal(c, argc, argv, true);
316 static int net_registry_getvaluesraw(struct net_context *c, int argc,
321 struct registry_key *key = NULL;
322 TALLOC_CTX *ctx = talloc_stackframe();
325 if (argc != 1 || c->display_usage) {
326 d_fprintf(stderr, "usage: net rpc registry getvaluesraw "
331 werr = open_key(ctx, argv[0], REG_KEY_READ, &key);
332 if (!W_ERROR_IS_OK(werr)) {
333 d_fprintf(stderr, "open_key failed: %s\n", win_errstr(werr));
339 struct registry_value *val;
341 werr = reg_enumvalue(talloc_tos(), key, idx, NULL, &val);
343 if (W_ERROR_EQUAL(werr, WERR_NO_MORE_ITEMS)) {
347 if (!W_ERROR_IS_OK(werr)) {
350 print_registry_value(val, true);
359 static int net_registry_setvalue(struct net_context *c, int argc,
363 struct registry_value value;
364 struct registry_key *key = NULL;
366 TALLOC_CTX *ctx = talloc_stackframe();
368 if (argc < 4 || c->display_usage) {
369 d_fprintf(stderr, "usage: net rpc registry setvalue <key> "
370 "<valuename> <type> [<val>]+\n");
374 if (!strequal(argv[2], "multi_sz") && (argc != 4)) {
375 d_fprintf(stderr, "Too many args for type %s\n", argv[2]);
379 if (strequal(argv[2], "dword")) {
380 value.type = REG_DWORD;
381 value.v.dword = strtoul(argv[3], NULL, 10);
382 } else if (strequal(argv[2], "sz")) {
384 value.v.sz.len = strlen(argv[3])+1;
385 value.v.sz.str = CONST_DISCARD(char *, argv[3]);
386 } else if (strequal(argv[2], "multi_sz")) {
387 value.type = REG_MULTI_SZ;
388 value.v.multi_sz.num_strings = argc - 3;
389 value.v.multi_sz.strings = (char **)(argv + 3);
391 d_fprintf(stderr, "type \"%s\" not implemented\n", argv[2]);
395 werr = open_key(ctx, argv[0], REG_KEY_WRITE, &key);
396 if (!W_ERROR_IS_OK(werr)) {
397 d_fprintf(stderr, "open_key failed: %s\n", win_errstr(werr));
401 werr = reg_setvalue(key, argv[1], &value);
402 if (!W_ERROR_IS_OK(werr)) {
403 d_fprintf(stderr, "reg_setvalue failed: %s\n",
415 struct net_registry_increment_state {
417 const char *valuename;
423 static void net_registry_increment_fn(void *private_data)
425 struct net_registry_increment_state *state =
426 (struct net_registry_increment_state *)private_data;
427 struct registry_value *value;
428 struct registry_key *key = NULL;
430 state->werr = open_key(talloc_tos(), state->keyname,
431 REG_KEY_READ|REG_KEY_WRITE, &key);
432 if (!W_ERROR_IS_OK(state->werr)) {
433 d_fprintf(stderr, "open_key failed: %s\n",
434 win_errstr(state->werr));
438 state->werr = reg_queryvalue(key, key, state->valuename, &value);
439 if (!W_ERROR_IS_OK(state->werr)) {
440 d_fprintf(stderr, "reg_queryvalue failed: %s\n",
441 win_errstr(state->werr));
445 if (value->type != REG_DWORD) {
446 d_fprintf(stderr, "value not a DWORD: %s\n",
447 reg_type_lookup(value->type));
451 value->v.dword += state->increment;
452 state->newvalue = value->v.dword;
454 state->werr = reg_setvalue(key, state->valuename, value);
455 if (!W_ERROR_IS_OK(state->werr)) {
456 d_fprintf(stderr, "reg_setvalue failed: %s\n",
457 win_errstr(state->werr));
466 static int net_registry_increment(struct net_context *c, int argc,
469 struct net_registry_increment_state state;
473 if (argc < 2 || c->display_usage) {
474 d_fprintf(stderr, "%s\n%s",
476 "net registry increment <key> <valuename> "
481 state.keyname = argv[0];
482 state.valuename = argv[1];
486 state.increment = strtoul(argv[2], NULL, 10);
489 status = g_lock_do("registry_increment_lock", G_LOCK_WRITE,
491 net_registry_increment_fn, &state);
492 if (!NT_STATUS_IS_OK(status)) {
493 d_fprintf(stderr, "g_lock_do failed: %s\n",
497 if (!W_ERROR_IS_OK(state.werr)) {
498 d_fprintf(stderr, "increment failed: %s\n",
499 win_errstr(state.werr));
503 d_printf("new value: %u\n", (unsigned)state.newvalue);
511 static int net_registry_deletevalue(struct net_context *c, int argc,
515 struct registry_key *key = NULL;
516 TALLOC_CTX *ctx = talloc_stackframe();
519 if (argc != 2 || c->display_usage) {
520 d_fprintf(stderr, "usage: net rpc registry deletevalue <key> "
525 werr = open_key(ctx, argv[0], REG_KEY_WRITE, &key);
526 if (!W_ERROR_IS_OK(werr)) {
527 d_fprintf(stderr, "open_key failed: %s\n", win_errstr(werr));
531 werr = reg_deletevalue(key, argv[1]);
532 if (!W_ERROR_IS_OK(werr)) {
533 d_fprintf(stderr, "reg_deletekey failed: %s\n",
545 static WERROR net_registry_getsd_internal(struct net_context *c,
548 struct security_descriptor **sd)
551 struct registry_key *key = NULL;
552 TALLOC_CTX *ctx = talloc_stackframe();
553 uint32_t access_mask = REG_KEY_READ |
554 SEC_FLAG_MAXIMUM_ALLOWED |
555 SEC_FLAG_SYSTEM_SECURITY;
558 * net_rpc_regsitry uses SEC_FLAG_SYSTEM_SECURITY, but access
559 * is denied with these perms right now...
561 access_mask = REG_KEY_READ;
564 d_fprintf(stderr, "internal error: invalid argument\n");
565 werr = WERR_INVALID_PARAM;
569 if (strlen(keyname) == 0) {
570 d_fprintf(stderr, "error: zero length key name given\n");
571 werr = WERR_INVALID_PARAM;
575 werr = open_key(ctx, keyname, access_mask, &key);
576 if (!W_ERROR_IS_OK(werr)) {
577 d_fprintf(stderr, "open_key failed: %s\n", win_errstr(werr));
581 werr = reg_getkeysecurity(mem_ctx, key, sd);
582 if (!W_ERROR_IS_OK(werr)) {
583 d_fprintf(stderr, "reg_getkeysecurity failed: %s\n",
595 static int net_registry_getsd(struct net_context *c, int argc,
600 struct security_descriptor *secdesc = NULL;
601 TALLOC_CTX *ctx = talloc_stackframe();
603 if (argc != 1 || c->display_usage) {
604 d_printf("Usage: net registry getsd <path>\n");
605 d_printf("Example: net registry getsd "
606 "'HKLM\\Software\\Samba'\n");
610 werr = net_registry_getsd_internal(c, ctx, argv[0], &secdesc);
611 if (!W_ERROR_IS_OK(werr)) {
615 display_sec_desc(secdesc);
624 static int net_registry_getsd_sddl(struct net_context *c,
625 int argc, const char **argv)
629 struct security_descriptor *secdesc = NULL;
630 TALLOC_CTX *ctx = talloc_stackframe();
632 if (argc != 1 || c->display_usage) {
633 d_printf("Usage: net registry getsd_sddl <path>\n");
634 d_printf("Example: net registry getsd_sddl 'HKLM\\Software\\Samba'\n");
638 werr = net_registry_getsd_internal(c, ctx, argv[0], &secdesc);
639 if (!W_ERROR_IS_OK(werr)) {
643 d_printf("%s\n", sddl_encode(ctx, secdesc, get_global_sam_sid()));
652 static WERROR net_registry_setsd_internal(struct net_context *c,
655 struct security_descriptor *sd)
658 struct registry_key *key = NULL;
659 TALLOC_CTX *ctx = talloc_stackframe();
660 uint32_t access_mask = REG_KEY_WRITE |
661 SEC_FLAG_MAXIMUM_ALLOWED |
662 SEC_FLAG_SYSTEM_SECURITY;
665 * net_rpc_regsitry uses SEC_FLAG_SYSTEM_SECURITY, but access
666 * is denied with these perms right now...
668 access_mask = REG_KEY_WRITE;
670 if (strlen(keyname) == 0) {
671 d_fprintf(stderr, "error: zero length key name given\n");
672 werr = WERR_INVALID_PARAM;
676 werr = open_key(ctx, keyname, access_mask, &key);
677 if (!W_ERROR_IS_OK(werr)) {
678 d_fprintf(stderr, "open_key failed: %s\n", win_errstr(werr));
682 werr = reg_setkeysecurity(key, sd);
683 if (!W_ERROR_IS_OK(werr)) {
684 d_fprintf(stderr, "reg_setkeysecurity failed: %s\n",
696 static int net_registry_setsd_sddl(struct net_context *c,
697 int argc, const char **argv)
701 struct security_descriptor *secdesc = NULL;
702 TALLOC_CTX *ctx = talloc_stackframe();
704 if (argc != 2 || c->display_usage) {
705 d_printf("Usage: net registry setsd_sddl <path> <security_descriptor>\n");
706 d_printf("Example:\n"
707 "net registry setsd_sddl 'HKLM\\Software\\Samba'\n");
711 secdesc = sddl_decode(ctx, argv[1], get_global_sam_sid());
712 if (secdesc == NULL) {
716 werr = net_registry_setsd_internal(c, ctx, argv[0], secdesc);
717 if (!W_ERROR_IS_OK(werr)) {
728 int net_registry(struct net_context *c, int argc, const char **argv)
732 struct functable func[] = {
735 net_registry_enumerate,
737 "Enumerate registry keys and values",
738 "net registry enumerate\n"
739 " Enumerate registry keys and values"
743 net_registry_createkey,
745 "Create a new registry key",
746 "net registry createkey\n"
747 " Create a new registry key"
751 net_registry_deletekey,
753 "Delete a registry key",
754 "net registry deletekey\n"
755 " Delete a registry key"
759 net_registry_getvalue,
761 "Print a registry value",
762 "net registry getvalue\n"
763 " Print a registry value"
767 net_registry_getvalueraw,
769 "Print a registry value (raw format)",
770 "net registry getvalueraw\n"
771 " Print a registry value (raw format)"
775 net_registry_getvaluesraw,
777 "Print all values of a key in raw format",
778 "net registry getvaluesraw <key>\n"
779 " Print a registry value (raw format)"
783 net_registry_setvalue,
785 "Set a new registry value",
786 "net registry setvalue\n"
787 " Set a new registry value"
791 net_registry_increment,
793 "Increment a DWORD registry value under a lock",
794 "net registry increment\n"
795 " Increment a DWORD registry value under a lock"
799 net_registry_deletevalue,
801 "Delete a registry value",
802 "net registry deletevalue\n"
803 " Delete a registry value"
809 "Get security descriptor",
810 "net registry getsd\n"
811 " Get security descriptor"
815 net_registry_getsd_sddl,
817 "Get security descriptor in sddl format",
818 "net registry getsd_sddl\n"
819 " Get security descriptor in sddl format"
823 net_registry_setsd_sddl,
825 "Set security descriptor from sddl format string",
826 "net registry setsd_sddl\n"
827 " Set security descriptor from sddl format string"
829 { NULL, NULL, 0, NULL, NULL }
832 if (!W_ERROR_IS_OK(registry_init_basic())) {
836 ret = net_run_function(c, argc, argv, "net registry", func);