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"
26 #include "registry/reg_import.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 /******************************************************************************/
730 * @defgroup net_registry net registry
734 * @defgroup net_registry_import Import
735 * @ingroup net_registry
744 static WERROR import_create_key(struct import_ctx* ctx,
745 struct registry_key* parent,
746 const char* name, void** pkey, bool* existing)
749 void* mem_ctx = talloc_new(ctx->mem_ctx);
751 struct registry_key* key = NULL;
752 enum winreg_CreateAction action;
754 if (parent == NULL) {
755 char* subkeyname = NULL;
756 werr = open_hive(mem_ctx, name, REG_KEY_WRITE,
757 &parent, &subkeyname);
758 if (!W_ERROR_IS_OK(werr)) {
759 d_fprintf(stderr, "open_hive failed: %s\n",
766 action = REG_ACTION_NONE;
767 werr = reg_createkey(mem_ctx, parent, name, REG_KEY_WRITE,
769 if (!W_ERROR_IS_OK(werr)) {
770 d_fprintf(stderr, "reg_createkey failed: %s\n",
775 if (action == REG_ACTION_NONE) {
776 d_fprintf(stderr, "createkey did nothing -- huh?\n");
781 if (existing != NULL) {
782 *existing = (action == REG_OPENED_EXISTING_KEY);
786 *pkey = talloc_steal(ctx->mem_ctx, key);
790 talloc_free(mem_ctx);
794 static WERROR import_close_key(struct import_ctx* ctx,
795 struct registry_key* key)
800 static WERROR import_delete_key(struct import_ctx* ctx,
801 struct registry_key* parent, const char* name)
804 void* mem_ctx = talloc_new(talloc_tos());
806 if (parent == NULL) {
807 char* subkeyname = NULL;
808 werr = open_hive(mem_ctx, name, REG_KEY_WRITE,
809 &parent, &subkeyname);
810 if (!W_ERROR_IS_OK(werr)) {
811 d_fprintf(stderr, "open_hive failed: %s\n",
818 werr = reg_deletekey_recursive(mem_ctx, parent, name);
819 if (!W_ERROR_IS_OK(werr)) {
820 d_fprintf(stderr, "reg_deletekey_recursive %s: %s\n", "failed",
826 talloc_free(mem_ctx);
830 static WERROR import_create_val (struct import_ctx* ctx,
831 struct registry_key* parent, const char* name,
832 const struct registry_value* value)
836 if (parent == NULL) {
837 return WERR_INVALID_PARAM;
840 werr = reg_setvalue(parent, name, value);
841 if (!W_ERROR_IS_OK(werr)) {
842 d_fprintf(stderr, "reg_setvalue failed: %s\n",
848 static WERROR import_delete_val (struct import_ctx* ctx, struct registry_key* parent, const char* name) {
851 if (parent == NULL) {
852 return WERR_INVALID_PARAM;
855 werr = reg_deletevalue(parent, name);
856 if (!W_ERROR_IS_OK(werr)) {
857 d_fprintf(stderr, "reg_deletekey failed: %s\n",
865 static int net_registry_import(struct net_context *c, int argc,
868 struct import_ctx import_ctx;
869 struct reg_import_callback import_callback = {
871 .closekey = (reg_import_callback_closekey_t)&import_close_key,
872 .createkey = (reg_import_callback_createkey_t)&import_create_key,
873 .deletekey = (reg_import_callback_deletekey_t)&import_delete_key,
874 .deleteval = (reg_import_callback_deleteval_t)&import_delete_val,
875 .setval.registry_value = (reg_import_callback_setval_registry_value_t)
877 .setval_type = REGISTRY_VALUE,
883 if (argc < 1 || argc > 2 || c->display_usage) {
886 "net registry import <reg> [options]\n");
889 "net registry import file.reg enc=CP1252\n");
893 ZERO_STRUCT(import_ctx);
894 import_ctx.mem_ctx = talloc_stackframe();
897 regdb_transaction_start();
899 ret = reg_parse_file(argv[0],
900 reg_import_adapter(import_ctx.mem_ctx,
902 (argc > 1) ? argv[1] : NULL
905 d_printf("reg_parse_file failed: transaction canceled\n");
906 regdb_transaction_cancel();
908 regdb_transaction_commit();
912 talloc_free(import_ctx.mem_ctx);
918 /******************************************************************************/
920 int net_registry(struct net_context *c, int argc, const char **argv)
924 struct functable func[] = {
927 net_registry_enumerate,
929 "Enumerate registry keys and values",
930 "net registry enumerate\n"
931 " Enumerate registry keys and values"
935 net_registry_createkey,
937 "Create a new registry key",
938 "net registry createkey\n"
939 " Create a new registry key"
943 net_registry_deletekey,
945 "Delete a registry key",
946 "net registry deletekey\n"
947 " Delete a registry key"
951 net_registry_getvalue,
953 "Print a registry value",
954 "net registry getvalue\n"
955 " Print a registry value"
959 net_registry_getvalueraw,
961 "Print a registry value (raw format)",
962 "net registry getvalueraw\n"
963 " Print a registry value (raw format)"
967 net_registry_getvaluesraw,
969 "Print all values of a key in raw format",
970 "net registry getvaluesraw <key>\n"
971 " Print a registry value (raw format)"
975 net_registry_setvalue,
977 "Set a new registry value",
978 "net registry setvalue\n"
979 " Set a new registry value"
983 net_registry_increment,
985 "Increment a DWORD registry value under a lock",
986 "net registry increment\n"
987 " Increment a DWORD registry value under a lock"
991 net_registry_deletevalue,
993 "Delete a registry value",
994 "net registry deletevalue\n"
995 " Delete a registry value"
1000 NET_TRANSPORT_LOCAL,
1001 "Get security descriptor",
1002 "net registry getsd\n"
1003 " Get security descriptor"
1007 net_registry_getsd_sddl,
1008 NET_TRANSPORT_LOCAL,
1009 "Get security descriptor in sddl format",
1010 "net registry getsd_sddl\n"
1011 " Get security descriptor in sddl format"
1015 net_registry_setsd_sddl,
1016 NET_TRANSPORT_LOCAL,
1017 "Set security descriptor from sddl format string",
1018 "net registry setsd_sddl\n"
1019 " Set security descriptor from sddl format string"
1023 net_registry_import,
1024 NET_TRANSPORT_LOCAL,
1026 "net registry import\n"
1029 { NULL, NULL, 0, NULL, NULL }
1032 if (!W_ERROR_IS_OK(registry_init_basic())) {
1036 ret = net_run_function(c, argc, argv, "net registry", func);