s3-printing: use winreg interface for migration, instead of spoolss.
[Samba.git] / source3 / utils / net_registry.c
blob0acd8c4c3089b9848024c6da14921af5dab45912
1 /*
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/>.
22 #include "includes.h"
23 #include "registry.h"
24 #include "registry/reg_api.h"
25 #include "registry/reg_util_token.h"
26 #include "registry/reg_init_basic.h"
27 #include "utils/net.h"
28 #include "utils/net_registry_util.h"
29 #include "include/g_lock.h"
30 #include "registry/reg_backend_db.h"
31 #include "registry/reg_import.h"
32 #include "registry/reg_format.h"
33 #include <assert.h>
34 #include "../libcli/security/display_sec.h"
35 #include "../libcli/security/sddl.h"
36 #include "../libcli/registry/util_reg.h"
37 #include "passdb/machine_sid.h"
41 * Helper functions
45 /**
46 * split given path into hive and remaining path and open the hive key
48 static WERROR open_hive(TALLOC_CTX *ctx, const char *path,
49 uint32 desired_access,
50 struct registry_key **hive,
51 char **subkeyname)
53 WERROR werr;
54 struct security_token *token = NULL;
55 char *hivename = NULL;
56 char *tmp_subkeyname = NULL;
57 TALLOC_CTX *tmp_ctx = talloc_stackframe();
59 if ((hive == NULL) || (subkeyname == NULL)) {
60 werr = WERR_INVALID_PARAM;
61 goto done;
64 werr = split_hive_key(tmp_ctx, path, &hivename, &tmp_subkeyname);
65 if (!W_ERROR_IS_OK(werr)) {
66 goto done;
68 *subkeyname = talloc_strdup(ctx, tmp_subkeyname);
69 if (*subkeyname == NULL) {
70 werr = WERR_NOMEM;
71 goto done;
74 werr = ntstatus_to_werror(registry_create_admin_token(tmp_ctx, &token));
75 if (!W_ERROR_IS_OK(werr)) {
76 goto done;
79 werr = reg_openhive(ctx, hivename, desired_access, token, hive);
80 if (!W_ERROR_IS_OK(werr)) {
81 goto done;
84 werr = WERR_OK;
86 done:
87 TALLOC_FREE(tmp_ctx);
88 return werr;
91 static WERROR open_key(TALLOC_CTX *ctx, const char *path,
92 uint32 desired_access,
93 struct registry_key **key)
95 WERROR werr;
96 char *subkey_name = NULL;
97 struct registry_key *hive = NULL;
98 TALLOC_CTX *tmp_ctx = talloc_stackframe();
100 if ((path == NULL) || (key == NULL)) {
101 return WERR_INVALID_PARAM;
104 werr = open_hive(tmp_ctx, path, desired_access, &hive, &subkey_name);
105 if (!W_ERROR_IS_OK(werr)) {
106 d_fprintf(stderr, _("open_hive failed: %s\n"),
107 win_errstr(werr));
108 goto done;
111 werr = reg_openkey(ctx, hive, subkey_name, desired_access, key);
112 if (!W_ERROR_IS_OK(werr)) {
113 d_fprintf(stderr, _("reg_openkey failed: %s\n"),
114 win_errstr(werr));
115 goto done;
118 werr = WERR_OK;
120 done:
121 TALLOC_FREE(tmp_ctx);
122 return werr;
125 static WERROR registry_enumkey(struct registry_key* parent, const char* keyname, bool recursive)
127 WERROR werr;
128 TALLOC_CTX *ctx = talloc_stackframe();
129 char* subkey_name;
130 NTTIME modtime;
131 uint32_t count;
132 char* valname = NULL;
133 struct registry_value *valvalue = NULL;
134 struct registry_key* key = NULL;
136 werr = reg_openkey(ctx, parent, keyname, REG_KEY_READ, &key);
137 if (!W_ERROR_IS_OK(werr)) {
138 goto done;
141 if (recursive) {
142 printf("[%s]\n\n", key->key->name);
143 } else {
144 for (count = 0;
145 werr = reg_enumkey(ctx, key, count, &subkey_name, &modtime),
146 W_ERROR_IS_OK(werr);
147 count++)
149 print_registry_key(subkey_name, &modtime);
151 if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) {
152 goto done;
156 for (count = 0;
157 werr = reg_enumvalue(ctx, key, count, &valname, &valvalue),
158 W_ERROR_IS_OK(werr);
159 count++)
161 print_registry_value_with_name(valname, valvalue);
163 if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) {
164 goto done;
167 if (!recursive) {
168 werr = WERR_OK;
169 goto done;
172 for (count = 0;
173 werr = reg_enumkey(ctx, key, count, &subkey_name, &modtime),
174 W_ERROR_IS_OK(werr);
175 count++)
177 werr = registry_enumkey(key, subkey_name, recursive);
178 if (!W_ERROR_IS_OK(werr)) {
179 goto done;
182 if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) {
183 goto done;
186 werr = WERR_OK;
188 done:
189 TALLOC_FREE(ctx);
190 return werr;
197 * the main "net registry" function implementations
200 static int net_registry_enumerate(struct net_context *c, int argc,
201 const char **argv)
203 WERROR werr;
204 struct registry_key *key = NULL;
205 char* name = NULL;
206 TALLOC_CTX *ctx = talloc_stackframe();
207 int ret = -1;
209 if (argc != 1 || c->display_usage) {
210 d_printf("%s\n%s",
211 _("Usage:"),
212 _("net registry enumerate <path>\n"));
213 d_printf("%s\n%s",
214 _("Example:"),
215 _("net registry enumerate 'HKLM\\Software\\Samba'\n"));
216 goto done;
219 werr = open_hive(ctx, argv[0], REG_KEY_READ, &key, &name);
220 if (!W_ERROR_IS_OK(werr)) {
221 d_fprintf(stderr, _("open_key failed: %s\n"), win_errstr(werr));
222 goto done;
225 werr = registry_enumkey(key, name, c->opt_reboot);
226 if (W_ERROR_IS_OK(werr)) {
227 ret = 0;
229 done:
230 TALLOC_FREE(ctx);
231 return ret;
234 static int net_registry_enumerate_recursive(struct net_context *c, int argc,
235 const char **argv)
237 WERROR werr;
238 struct registry_key *key = NULL;
239 char* name = NULL;
240 TALLOC_CTX *ctx = talloc_stackframe();
241 int ret = -1;
243 if (argc != 1 || c->display_usage) {
244 d_printf("%s\n%s",
245 _("Usage:"),
246 _("net registry enumerate <path>\n"));
247 d_printf("%s\n%s",
248 _("Example:"),
249 _("net registry enumerate 'HKLM\\Software\\Samba'\n"));
250 goto done;
253 werr = open_hive(ctx, argv[0], REG_KEY_READ, &key, &name);
254 if (!W_ERROR_IS_OK(werr)) {
255 d_fprintf(stderr, _("open_key failed: %s\n"), win_errstr(werr));
256 goto done;
259 werr = registry_enumkey(key, name, true);
260 if (W_ERROR_IS_OK(werr)) {
261 ret = 0;
263 done:
264 TALLOC_FREE(ctx);
265 return ret;
269 static int net_registry_createkey(struct net_context *c, int argc,
270 const char **argv)
272 WERROR werr;
273 enum winreg_CreateAction action;
274 char *subkeyname;
275 struct registry_key *hivekey = NULL;
276 struct registry_key *subkey = NULL;
277 TALLOC_CTX *ctx = talloc_stackframe();
278 int ret = -1;
280 if (argc != 1 || c->display_usage) {
281 d_printf("%s\n%s",
282 _("Usage:"),
283 _("net registry createkey <path>\n"));
284 d_printf("%s\n%s",
285 _("Example:"),
286 _("net registry createkey "
287 "'HKLM\\Software\\Samba\\smbconf.127.0.0.1'\n"));
288 goto done;
290 if (strlen(argv[0]) == 0) {
291 d_fprintf(stderr, _("error: zero length key name given\n"));
292 goto done;
295 werr = open_hive(ctx, argv[0], REG_KEY_WRITE, &hivekey, &subkeyname);
296 if (!W_ERROR_IS_OK(werr)) {
297 d_fprintf(stderr, _("open_hive failed: %s\n"),
298 win_errstr(werr));
299 goto done;
302 werr = reg_createkey(ctx, hivekey, subkeyname, REG_KEY_WRITE,
303 &subkey, &action);
304 if (!W_ERROR_IS_OK(werr)) {
305 d_fprintf(stderr, _("reg_createkey failed: %s\n"),
306 win_errstr(werr));
307 goto done;
309 switch (action) {
310 case REG_ACTION_NONE:
311 d_printf(_("createkey did nothing -- huh?\n"));
312 break;
313 case REG_CREATED_NEW_KEY:
314 d_printf(_("createkey created %s\n"), argv[0]);
315 break;
316 case REG_OPENED_EXISTING_KEY:
317 d_printf(_("createkey opened existing %s\n"), argv[0]);
318 break;
321 ret = 0;
323 done:
324 TALLOC_FREE(ctx);
325 return ret;
328 static int net_registry_deletekey_internal(struct net_context *c, int argc,
329 const char **argv,
330 bool recursive)
332 WERROR werr;
333 char *subkeyname;
334 struct registry_key *hivekey = NULL;
335 TALLOC_CTX *ctx = talloc_stackframe();
336 int ret = -1;
338 if (argc != 1 || c->display_usage) {
339 d_printf("%s\n%s",
340 _("Usage:"),
341 _("net registry deletekey <path>\n"));
342 d_printf("%s\n%s",
343 _("Example:"),
344 _("net registry deletekey "
345 "'HKLM\\Software\\Samba\\smbconf.127.0.0.1'\n"));
346 goto done;
348 if (strlen(argv[0]) == 0) {
349 d_fprintf(stderr, _("error: zero length key name given\n"));
350 goto done;
353 werr = open_hive(ctx, argv[0], REG_KEY_WRITE, &hivekey, &subkeyname);
354 if (!W_ERROR_IS_OK(werr)) {
355 d_fprintf(stderr, "open_hive %s: %s\n", _("failed"),
356 win_errstr(werr));
357 goto done;
360 if (recursive) {
361 werr = reg_deletekey_recursive(hivekey, subkeyname);
362 } else {
363 werr = reg_deletekey(hivekey, subkeyname);
365 if (!W_ERROR_IS_OK(werr) &&
366 !(c->opt_force && W_ERROR_EQUAL(werr, WERR_BADFILE)))
368 d_fprintf(stderr, "reg_deletekey %s: %s\n", _("failed"),
369 win_errstr(werr));
370 goto done;
373 ret = 0;
375 done:
376 TALLOC_FREE(ctx);
377 return ret;
380 static int net_registry_deletekey(struct net_context *c, int argc,
381 const char **argv)
383 return net_registry_deletekey_internal(c, argc, argv, false);
386 static int net_registry_deletekey_recursive(struct net_context *c, int argc,
387 const char **argv)
389 return net_registry_deletekey_internal(c, argc, argv, true);
392 static int net_registry_getvalue_internal(struct net_context *c, int argc,
393 const char **argv, bool raw)
395 WERROR werr;
396 int ret = -1;
397 struct registry_key *key = NULL;
398 struct registry_value *value = NULL;
399 TALLOC_CTX *ctx = talloc_stackframe();
401 if (argc != 2 || c->display_usage) {
402 d_fprintf(stderr, "%s\n%s",
403 _("Usage:"),
404 _("net registry getvalue <key> <valuename>\n"));
405 goto done;
408 werr = open_key(ctx, argv[0], REG_KEY_READ, &key);
409 if (!W_ERROR_IS_OK(werr)) {
410 d_fprintf(stderr, _("open_key failed: %s\n"), win_errstr(werr));
411 goto done;
414 werr = reg_queryvalue(ctx, key, argv[1], &value);
415 if (!W_ERROR_IS_OK(werr)) {
416 d_fprintf(stderr, _("reg_queryvalue failed: %s\n"),
417 win_errstr(werr));
418 goto done;
421 print_registry_value(value, raw);
423 ret = 0;
425 done:
426 TALLOC_FREE(ctx);
427 return ret;
430 static int net_registry_getvalue(struct net_context *c, int argc,
431 const char **argv)
433 return net_registry_getvalue_internal(c, argc, argv, false);
436 static int net_registry_getvalueraw(struct net_context *c, int argc,
437 const char **argv)
439 return net_registry_getvalue_internal(c, argc, argv, true);
442 static int net_registry_getvaluesraw(struct net_context *c, int argc,
443 const char **argv)
445 WERROR werr;
446 int ret = -1;
447 struct registry_key *key = NULL;
448 TALLOC_CTX *ctx = talloc_stackframe();
449 uint32_t idx;
451 if (argc != 1 || c->display_usage) {
452 d_fprintf(stderr, "usage: net rpc registry getvaluesraw "
453 "<key>\n");
454 goto done;
457 werr = open_key(ctx, argv[0], REG_KEY_READ, &key);
458 if (!W_ERROR_IS_OK(werr)) {
459 d_fprintf(stderr, "open_key failed: %s\n", win_errstr(werr));
460 goto done;
463 idx = 0;
464 while (true) {
465 struct registry_value *val;
467 werr = reg_enumvalue(talloc_tos(), key, idx, NULL, &val);
469 if (W_ERROR_EQUAL(werr, WERR_NO_MORE_ITEMS)) {
470 ret = 0;
471 break;
473 if (!W_ERROR_IS_OK(werr)) {
474 break;
476 print_registry_value(val, true);
477 TALLOC_FREE(val);
478 idx += 1;
480 done:
481 TALLOC_FREE(ctx);
482 return ret;
485 static int net_registry_setvalue(struct net_context *c, int argc,
486 const char **argv)
488 WERROR werr;
489 struct registry_value value;
490 struct registry_key *key = NULL;
491 int ret = -1;
492 TALLOC_CTX *ctx = talloc_stackframe();
494 if (argc < 4 || c->display_usage) {
495 d_fprintf(stderr, "%s\n%s",
496 _("Usage:"),
497 _("net registry setvalue <key> <valuename> "
498 "<type> [<val>]+\n"));
499 goto done;
502 if (!strequal(argv[2], "multi_sz") && (argc != 4)) {
503 d_fprintf(stderr, _("Too many args for type %s\n"), argv[2]);
504 goto done;
507 if (strequal(argv[2], "dword")) {
508 uint32_t v = strtoul(argv[3], NULL, 10);
509 value.type = REG_DWORD;
510 value.data = data_blob_talloc(ctx, NULL, 4);
511 SIVAL(value.data.data, 0, v);
512 } else if (strequal(argv[2], "sz")) {
513 value.type = REG_SZ;
514 if (!push_reg_sz(ctx, &value.data, argv[3])) {
515 goto done;
517 } else if (strequal(argv[2], "multi_sz")) {
518 const char **array;
519 int count = argc - 3;
520 int i;
521 value.type = REG_MULTI_SZ;
522 array = talloc_zero_array(ctx, const char *, count + 1);
523 if (array == NULL) {
524 goto done;
526 for (i=0; i < count; i++) {
527 array[i] = talloc_strdup(array, argv[count+i]);
528 if (array[i] == NULL) {
529 goto done;
532 if (!push_reg_multi_sz(ctx, &value.data, array)) {
533 goto done;
535 } else {
536 d_fprintf(stderr, _("type \"%s\" not implemented\n"), argv[2]);
537 goto done;
540 werr = open_key(ctx, argv[0], REG_KEY_WRITE, &key);
541 if (!W_ERROR_IS_OK(werr)) {
542 d_fprintf(stderr, _("open_key failed: %s\n"), win_errstr(werr));
543 goto done;
546 werr = reg_setvalue(key, argv[1], &value);
547 if (!W_ERROR_IS_OK(werr)) {
548 d_fprintf(stderr, _("reg_setvalue failed: %s\n"),
549 win_errstr(werr));
550 goto done;
553 ret = 0;
555 done:
556 TALLOC_FREE(ctx);
557 return ret;
560 struct net_registry_increment_state {
561 const char *keyname;
562 const char *valuename;
563 uint32_t increment;
564 uint32_t newvalue;
565 WERROR werr;
568 static void net_registry_increment_fn(void *private_data)
570 struct net_registry_increment_state *state =
571 (struct net_registry_increment_state *)private_data;
572 struct registry_value *value;
573 struct registry_key *key = NULL;
574 uint32_t v;
576 state->werr = open_key(talloc_tos(), state->keyname,
577 REG_KEY_READ|REG_KEY_WRITE, &key);
578 if (!W_ERROR_IS_OK(state->werr)) {
579 d_fprintf(stderr, _("open_key failed: %s\n"),
580 win_errstr(state->werr));
581 goto done;
584 state->werr = reg_queryvalue(key, key, state->valuename, &value);
585 if (!W_ERROR_IS_OK(state->werr)) {
586 d_fprintf(stderr, _("reg_queryvalue failed: %s\n"),
587 win_errstr(state->werr));
588 goto done;
591 if (value->type != REG_DWORD) {
592 d_fprintf(stderr, _("value not a DWORD: %s\n"),
593 str_regtype(value->type));
594 goto done;
597 if (value->data.length < 4) {
598 d_fprintf(stderr, _("value too short for regular DWORD\n"));
599 goto done;
602 v = IVAL(value->data.data, 0);
603 v += state->increment;
604 state->newvalue = v;
606 SIVAL(value->data.data, 0, v);
608 state->werr = reg_setvalue(key, state->valuename, value);
609 if (!W_ERROR_IS_OK(state->werr)) {
610 d_fprintf(stderr, _("reg_setvalue failed: %s\n"),
611 win_errstr(state->werr));
612 goto done;
615 done:
616 TALLOC_FREE(key);
617 return;
620 static int net_registry_increment(struct net_context *c, int argc,
621 const char **argv)
623 struct net_registry_increment_state state;
624 NTSTATUS status;
625 int ret = -1;
627 if (argc < 2 || c->display_usage) {
628 d_fprintf(stderr, "%s\n%s",
629 _("Usage:"),
630 _("net registry increment <key> <valuename> "
631 "[<increment>]\n"));
632 goto done;
635 state.keyname = argv[0];
636 state.valuename = argv[1];
638 state.increment = 1;
639 if (argc == 3) {
640 state.increment = strtoul(argv[2], NULL, 10);
643 status = g_lock_do("registry_increment_lock", G_LOCK_WRITE,
644 timeval_set(600, 0), procid_self(),
645 net_registry_increment_fn, &state);
646 if (!NT_STATUS_IS_OK(status)) {
647 d_fprintf(stderr, _("g_lock_do failed: %s\n"),
648 nt_errstr(status));
649 goto done;
651 if (!W_ERROR_IS_OK(state.werr)) {
652 d_fprintf(stderr, _("increment failed: %s\n"),
653 win_errstr(state.werr));
654 goto done;
657 d_printf(_("%u\n"), (unsigned)state.newvalue);
659 ret = 0;
661 done:
662 return ret;
665 static int net_registry_deletevalue(struct net_context *c, int argc,
666 const char **argv)
668 WERROR werr;
669 struct registry_key *key = NULL;
670 TALLOC_CTX *ctx = talloc_stackframe();
671 int ret = -1;
673 if (argc != 2 || c->display_usage) {
674 d_fprintf(stderr, "%s\n%s",
675 _("Usage:"),
676 _("net registry deletevalue <key> <valuename>\n"));
677 goto done;
680 werr = open_key(ctx, argv[0], REG_KEY_WRITE, &key);
681 if (!W_ERROR_IS_OK(werr)) {
682 d_fprintf(stderr, _("open_key failed: %s\n"), win_errstr(werr));
683 goto done;
686 werr = reg_deletevalue(key, argv[1]);
687 if (!W_ERROR_IS_OK(werr)) {
688 d_fprintf(stderr, _("reg_deletevalue failed: %s\n"),
689 win_errstr(werr));
690 goto done;
693 ret = 0;
695 done:
696 TALLOC_FREE(ctx);
697 return ret;
700 static WERROR net_registry_getsd_internal(struct net_context *c,
701 TALLOC_CTX *mem_ctx,
702 const char *keyname,
703 struct security_descriptor **sd)
705 WERROR werr;
706 struct registry_key *key = NULL;
707 TALLOC_CTX *ctx = talloc_stackframe();
708 uint32_t access_mask = REG_KEY_READ |
709 SEC_FLAG_MAXIMUM_ALLOWED |
710 SEC_FLAG_SYSTEM_SECURITY;
713 * net_rpc_regsitry uses SEC_FLAG_SYSTEM_SECURITY, but access
714 * is denied with these perms right now...
716 access_mask = REG_KEY_READ;
718 if (sd == NULL) {
719 d_fprintf(stderr, _("internal error: invalid argument\n"));
720 werr = WERR_INVALID_PARAM;
721 goto done;
724 if (strlen(keyname) == 0) {
725 d_fprintf(stderr, _("error: zero length key name given\n"));
726 werr = WERR_INVALID_PARAM;
727 goto done;
730 werr = open_key(ctx, keyname, access_mask, &key);
731 if (!W_ERROR_IS_OK(werr)) {
732 d_fprintf(stderr, "%s%s\n", _("open_key failed: "),
733 win_errstr(werr));
734 goto done;
737 werr = reg_getkeysecurity(mem_ctx, key, sd);
738 if (!W_ERROR_IS_OK(werr)) {
739 d_fprintf(stderr, "%s%s\n", _("reg_getkeysecurity failed: "),
740 win_errstr(werr));
741 goto done;
744 werr = WERR_OK;
746 done:
747 TALLOC_FREE(ctx);
748 return werr;
751 static int net_registry_getsd(struct net_context *c, int argc,
752 const char **argv)
754 WERROR werr;
755 int ret = -1;
756 struct security_descriptor *secdesc = NULL;
757 TALLOC_CTX *ctx = talloc_stackframe();
759 if (argc != 1 || c->display_usage) {
760 d_printf("%s\n%s",
761 _("Usage:"),
762 _("net registry getsd <path>\n"));
763 d_printf("%s\n%s",
764 _("Example:"),
765 _("net registry getsd 'HKLM\\Software\\Samba'\n"));
766 goto done;
769 werr = net_registry_getsd_internal(c, ctx, argv[0], &secdesc);
770 if (!W_ERROR_IS_OK(werr)) {
771 goto done;
774 display_sec_desc(secdesc);
776 ret = 0;
778 done:
779 TALLOC_FREE(ctx);
780 return ret;
783 static int net_registry_getsd_sddl(struct net_context *c,
784 int argc, const char **argv)
786 WERROR werr;
787 int ret = -1;
788 struct security_descriptor *secdesc = NULL;
789 TALLOC_CTX *ctx = talloc_stackframe();
791 if (argc != 1 || c->display_usage) {
792 d_printf("%s\n%s",
793 _("Usage:"),
794 _("net registry getsd_sddl <path>\n"));
795 d_printf("%s\n%s",
796 _("Example:"),
797 _("net registry getsd_sddl 'HKLM\\Software\\Samba'\n"));
798 goto done;
801 werr = net_registry_getsd_internal(c, ctx, argv[0], &secdesc);
802 if (!W_ERROR_IS_OK(werr)) {
803 goto done;
806 d_printf("%s\n", sddl_encode(ctx, secdesc, get_global_sam_sid()));
808 ret = 0;
810 done:
811 TALLOC_FREE(ctx);
812 return ret;
815 static WERROR net_registry_setsd_internal(struct net_context *c,
816 TALLOC_CTX *mem_ctx,
817 const char *keyname,
818 struct security_descriptor *sd)
820 WERROR werr;
821 struct registry_key *key = NULL;
822 TALLOC_CTX *ctx = talloc_stackframe();
823 uint32_t access_mask = REG_KEY_WRITE |
824 SEC_FLAG_MAXIMUM_ALLOWED |
825 SEC_FLAG_SYSTEM_SECURITY;
828 * net_rpc_regsitry uses SEC_FLAG_SYSTEM_SECURITY, but access
829 * is denied with these perms right now...
831 access_mask = REG_KEY_WRITE;
833 if (strlen(keyname) == 0) {
834 d_fprintf(stderr, _("error: zero length key name given\n"));
835 werr = WERR_INVALID_PARAM;
836 goto done;
839 werr = open_key(ctx, keyname, access_mask, &key);
840 if (!W_ERROR_IS_OK(werr)) {
841 d_fprintf(stderr, "%s%s\n", _("open_key failed: "),
842 win_errstr(werr));
843 goto done;
846 werr = reg_setkeysecurity(key, sd);
847 if (!W_ERROR_IS_OK(werr)) {
848 d_fprintf(stderr, "%s%s\n", _("reg_setkeysecurity failed: "),
849 win_errstr(werr));
850 goto done;
853 werr = WERR_OK;
855 done:
856 TALLOC_FREE(ctx);
857 return werr;
860 static int net_registry_setsd_sddl(struct net_context *c,
861 int argc, const char **argv)
863 WERROR werr;
864 int ret = -1;
865 struct security_descriptor *secdesc = NULL;
866 TALLOC_CTX *ctx = talloc_stackframe();
868 if (argc != 2 || c->display_usage) {
869 d_printf("%s\n%s",
870 _("Usage:"),
871 _("net registry setsd_sddl <path> <security_descriptor>\n"));
872 d_printf("%s\n%s",
873 _("Example:"),
874 _("net registry setsd_sddl 'HKLM\\Software\\Samba'\n"));
875 goto done;
878 secdesc = sddl_decode(ctx, argv[1], get_global_sam_sid());
879 if (secdesc == NULL) {
880 goto done;
883 werr = net_registry_setsd_internal(c, ctx, argv[0], secdesc);
884 if (!W_ERROR_IS_OK(werr)) {
885 goto done;
888 ret = 0;
890 done:
891 TALLOC_FREE(ctx);
892 return ret;
895 /******************************************************************************/
897 * @defgroup net_registry net registry
901 * @defgroup net_registry_import Import
902 * @ingroup net_registry
903 * @{
906 struct import_ctx {
907 TALLOC_CTX *mem_ctx;
911 static WERROR import_create_key(struct import_ctx* ctx,
912 struct registry_key* parent,
913 const char* name, void** pkey, bool* existing)
915 WERROR werr;
916 void* mem_ctx = talloc_new(ctx->mem_ctx);
918 struct registry_key* key = NULL;
919 enum winreg_CreateAction action;
921 if (parent == NULL) {
922 char* subkeyname = NULL;
923 werr = open_hive(mem_ctx, name, REG_KEY_WRITE,
924 &parent, &subkeyname);
925 if (!W_ERROR_IS_OK(werr)) {
926 d_fprintf(stderr, _("open_hive failed: %s\n"),
927 win_errstr(werr));
928 goto done;
930 name = subkeyname;
933 action = REG_ACTION_NONE;
934 werr = reg_createkey(mem_ctx, parent, name, REG_KEY_WRITE,
935 &key, &action);
936 if (!W_ERROR_IS_OK(werr)) {
937 d_fprintf(stderr, _("reg_createkey failed: %s\n"),
938 win_errstr(werr));
939 goto done;
942 if (action == REG_ACTION_NONE) {
943 d_fprintf(stderr, _("createkey did nothing -- huh?\n"));
944 werr = WERR_CREATE_FAILED;
945 goto done;
948 if (existing != NULL) {
949 *existing = (action == REG_OPENED_EXISTING_KEY);
952 if (pkey!=NULL) {
953 *pkey = talloc_steal(ctx->mem_ctx, key);
956 done:
957 talloc_free(mem_ctx);
958 return werr;
961 static WERROR import_close_key(struct import_ctx* ctx,
962 struct registry_key* key)
964 return WERR_OK;
967 static WERROR import_delete_key(struct import_ctx* ctx,
968 struct registry_key* parent, const char* name)
970 WERROR werr;
971 void* mem_ctx = talloc_new(talloc_tos());
973 if (parent == NULL) {
974 char* subkeyname = NULL;
975 werr = open_hive(mem_ctx, name, REG_KEY_WRITE,
976 &parent, &subkeyname);
977 if (!W_ERROR_IS_OK(werr)) {
978 d_fprintf(stderr, _("open_hive failed: %s\n"),
979 win_errstr(werr));
980 goto done;
982 name = subkeyname;
985 werr = reg_deletekey_recursive(parent, name);
986 if (!W_ERROR_IS_OK(werr)) {
987 d_fprintf(stderr, "reg_deletekey_recursive %s: %s\n", _("failed"),
988 win_errstr(werr));
989 goto done;
992 done:
993 talloc_free(mem_ctx);
994 return werr;
997 static WERROR import_create_val (struct import_ctx* ctx,
998 struct registry_key* parent, const char* name,
999 const struct registry_value* value)
1001 WERROR werr;
1003 if (parent == NULL) {
1004 return WERR_INVALID_PARAM;
1007 werr = reg_setvalue(parent, name, value);
1008 if (!W_ERROR_IS_OK(werr)) {
1009 d_fprintf(stderr, _("reg_setvalue failed: %s\n"),
1010 win_errstr(werr));
1012 return werr;
1015 static WERROR import_delete_val (struct import_ctx* ctx, struct registry_key* parent, const char* name) {
1016 WERROR werr;
1018 if (parent == NULL) {
1019 return WERR_INVALID_PARAM;
1022 werr = reg_deletevalue(parent, name);
1023 if (!W_ERROR_IS_OK(werr)) {
1024 d_fprintf(stderr, _("reg_deletevalue failed: %s\n"),
1025 win_errstr(werr));
1028 return werr;
1032 static int net_registry_import(struct net_context *c, int argc,
1033 const char **argv)
1035 struct import_ctx import_ctx;
1036 struct reg_import_callback import_callback = {
1037 .openkey = NULL,
1038 .closekey = (reg_import_callback_closekey_t)&import_close_key,
1039 .createkey = (reg_import_callback_createkey_t)&import_create_key,
1040 .deletekey = (reg_import_callback_deletekey_t)&import_delete_key,
1041 .deleteval = (reg_import_callback_deleteval_t)&import_delete_val,
1042 .setval = {
1043 .registry_value = (reg_import_callback_setval_registry_value_t)
1044 &import_create_val,
1046 .setval_type = REGISTRY_VALUE,
1047 .data = &import_ctx
1050 int ret;
1052 if (argc < 1 || argc > 2 || c->display_usage) {
1053 d_printf("%s\n%s",
1054 _("Usage:"),
1055 _("net registry import <reg> [options]\n"));
1056 d_printf("%s\n%s",
1057 _("Example:"),
1058 _("net registry import file.reg enc=CP1252\n"));
1059 return -1;
1062 ZERO_STRUCT(import_ctx);
1063 import_ctx.mem_ctx = talloc_stackframe();
1065 regdb_open();
1066 regdb_transaction_start();
1068 ret = reg_parse_file(argv[0],
1069 reg_import_adapter(import_ctx.mem_ctx,
1070 import_callback),
1071 (argc > 1) ? argv[1] : NULL
1073 if (ret < 0) {
1074 d_printf("reg_parse_file failed: transaction canceled\n");
1075 regdb_transaction_cancel();
1076 } else{
1077 regdb_transaction_commit();
1080 regdb_close();
1081 talloc_free(import_ctx.mem_ctx);
1083 return ret;
1085 /**@}*/
1087 /******************************************************************************/
1090 * @defgroup net_registry_export Export
1091 * @ingroup net_registry
1092 * @{
1095 static int registry_export(TALLOC_CTX *ctx, /*const*/ struct registry_key* key,
1096 struct reg_format* f)
1098 int ret=-1;
1099 WERROR werr;
1100 uint32_t count;
1102 struct registry_value *valvalue = NULL;
1103 char *valname = NULL;
1105 struct registry_key* subkey = NULL;
1106 char *subkey_name = NULL;
1107 NTTIME modtime = 0;
1109 reg_format_registry_key(f, key, false);
1111 /* print values */
1112 for (count = 0;
1113 werr = reg_enumvalue(ctx, key, count, &valname, &valvalue),
1114 W_ERROR_IS_OK(werr);
1115 count++)
1117 reg_format_registry_value(f, valname, valvalue);
1119 if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) {
1120 d_fprintf(stderr, _("reg_enumvalue failed: %s\n"),
1121 win_errstr(werr));
1122 goto done;
1125 /* recurse on subkeys */
1126 for (count = 0;
1127 werr = reg_enumkey(ctx, key, count, &subkey_name, &modtime),
1128 W_ERROR_IS_OK(werr);
1129 count++)
1131 werr = reg_openkey(ctx, key, subkey_name, REG_KEY_READ,
1132 &subkey);
1133 if (!W_ERROR_IS_OK(werr)) {
1134 d_fprintf(stderr, _("reg_openkey failed: %s\n"),
1135 win_errstr(werr));
1136 goto done;
1139 registry_export(ctx, subkey, f);
1141 if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) {
1142 d_fprintf(stderr, _("reg_enumkey failed: %s\n"),
1143 win_errstr(werr));
1144 goto done;
1146 ret = 0;
1147 done:
1148 return ret;
1151 static int net_registry_export(struct net_context *c, int argc,
1152 const char **argv)
1154 int ret=-1;
1155 WERROR werr;
1156 struct registry_key *key = NULL;
1157 TALLOC_CTX *ctx = talloc_stackframe();
1158 struct reg_format* f=NULL;
1160 if (argc < 2 || argc > 3 || c->display_usage) {
1161 d_printf("%s\n%s",
1162 _("Usage:"),
1163 _("net registry export <path> <file> [opt]\n"));
1164 d_printf("%s\n%s",
1165 _("Example:"),
1166 _("net registry export 'HKLM\\Software\\Samba' "
1167 "samba.reg regedit5\n"));
1168 goto done;
1171 werr = open_key(ctx, argv[0], REG_KEY_READ, &key);
1172 if (!W_ERROR_IS_OK(werr)) {
1173 d_fprintf(stderr, _("open_key failed: %s\n"), win_errstr(werr));
1174 goto done;
1177 f = reg_format_file(ctx, argv[1], (argc > 2) ? argv[2] : NULL);
1178 if (f == NULL) {
1179 d_fprintf(stderr, _("open file failed: %s\n"), strerror(errno));
1180 goto done;
1183 ret = registry_export(ctx, key, f);
1185 done:
1186 TALLOC_FREE(ctx);
1187 return ret;
1189 /**@}*/
1191 /******************************************************************************/
1193 * @defgroup net_registry_convert Convert
1194 * @ingroup net_registry
1195 * @{
1198 static int net_registry_convert(struct net_context *c, int argc,
1199 const char **argv)
1201 int ret;
1202 void* mem_ctx;
1203 const char* in_opt = NULL;
1204 const char* out_opt = NULL;
1206 if (argc < 2 || argc > 4|| c->display_usage) {
1207 d_printf("%s\n%s",
1208 _("Usage:"),
1209 _("net registry convert <in> <out> [in_opt] [out_opt]\n"
1210 "net registry convert <in> <out> [out_opt]\n"));
1211 d_printf("%s\n%s",
1212 _("Example:"),
1213 _("net registry convert in.reg out.reg regedit4,enc=CP1252\n"));
1214 return -1;
1217 mem_ctx = talloc_stackframe();
1219 switch (argc ) {
1220 case 2:
1221 break;
1222 case 3:
1223 out_opt = argv[2];
1224 break;
1225 case 4:
1226 out_opt = argv[3];
1227 in_opt = argv[2];
1228 break;
1229 default:
1230 assert(false);
1234 ret = reg_parse_file(argv[0], (struct reg_parse_callback*)
1235 reg_format_file(mem_ctx, argv[1], out_opt),
1236 in_opt);
1238 talloc_free(mem_ctx);
1240 return ret;
1242 /**@}*/
1244 /******************************************************************************/
1246 int net_registry(struct net_context *c, int argc, const char **argv)
1248 int ret = -1;
1250 struct functable func[] = {
1252 "enumerate",
1253 net_registry_enumerate,
1254 NET_TRANSPORT_LOCAL,
1255 N_("Enumerate registry keys and values"),
1256 N_("net registry enumerate\n"
1257 " Enumerate registry keys and values")
1260 "enumerate_recursive",
1261 net_registry_enumerate_recursive,
1262 NET_TRANSPORT_LOCAL,
1263 N_("Enumerate registry keys and values"),
1264 N_("net registry enumerate_recursive\n"
1265 " Enumerate registry keys and values")
1268 "createkey",
1269 net_registry_createkey,
1270 NET_TRANSPORT_LOCAL,
1271 N_("Create a new registry key"),
1272 N_("net registry createkey\n"
1273 " Create a new registry key")
1276 "deletekey",
1277 net_registry_deletekey,
1278 NET_TRANSPORT_LOCAL,
1279 N_("Delete a registry key"),
1280 N_("net registry deletekey\n"
1281 " Delete a registry key")
1284 "deletekey_recursive",
1285 net_registry_deletekey_recursive,
1286 NET_TRANSPORT_LOCAL,
1287 N_("Delete a registry key with subkeys"),
1288 N_("net registry deletekey_recursive\n"
1289 " Delete a registry key with subkeys")
1292 "getvalue",
1293 net_registry_getvalue,
1294 NET_TRANSPORT_LOCAL,
1295 N_("Print a registry value"),
1296 N_("net registry getvalue\n"
1297 " Print a registry value")
1300 "getvalueraw",
1301 net_registry_getvalueraw,
1302 NET_TRANSPORT_LOCAL,
1303 N_("Print a registry value (raw format)"),
1304 N_("net registry getvalueraw\n"
1305 " Print a registry value (raw format)")
1308 "getvaluesraw",
1309 net_registry_getvaluesraw,
1310 NET_TRANSPORT_LOCAL,
1311 "Print all values of a key in raw format",
1312 "net registry getvaluesraw <key>\n"
1313 " Print a registry value (raw format)"
1316 "setvalue",
1317 net_registry_setvalue,
1318 NET_TRANSPORT_LOCAL,
1319 N_("Set a new registry value"),
1320 N_("net registry setvalue\n"
1321 " Set a new registry value")
1324 "increment",
1325 net_registry_increment,
1326 NET_TRANSPORT_LOCAL,
1327 N_("Increment a DWORD registry value under a lock"),
1328 N_("net registry increment\n"
1329 " Increment a DWORD registry value under a lock")
1332 "deletevalue",
1333 net_registry_deletevalue,
1334 NET_TRANSPORT_LOCAL,
1335 N_("Delete a registry value"),
1336 N_("net registry deletevalue\n"
1337 " Delete a registry value")
1340 "getsd",
1341 net_registry_getsd,
1342 NET_TRANSPORT_LOCAL,
1343 N_("Get security descriptor"),
1344 N_("net registry getsd\n"
1345 " Get security descriptor")
1348 "getsd_sddl",
1349 net_registry_getsd_sddl,
1350 NET_TRANSPORT_LOCAL,
1351 N_("Get security descriptor in sddl format"),
1352 N_("net registry getsd_sddl\n"
1353 " Get security descriptor in sddl format")
1356 "setsd_sddl",
1357 net_registry_setsd_sddl,
1358 NET_TRANSPORT_LOCAL,
1359 N_("Set security descriptor from sddl format string"),
1360 N_("net registry setsd_sddl\n"
1361 " Set security descriptor from sddl format string")
1364 "import",
1365 net_registry_import,
1366 NET_TRANSPORT_LOCAL,
1367 N_("Import .reg file"),
1368 N_("net registry import\n"
1369 " Import .reg file")
1372 "export",
1373 net_registry_export,
1374 NET_TRANSPORT_LOCAL,
1375 N_("Export .reg file"),
1376 N_("net registry export\n"
1377 " Export .reg file")
1380 "convert",
1381 net_registry_convert,
1382 NET_TRANSPORT_LOCAL,
1383 N_("Convert .reg file"),
1384 N_("net registry convert\n"
1385 " Convert .reg file")
1387 { NULL, NULL, 0, NULL, NULL }
1390 if (!W_ERROR_IS_OK(registry_init_basic())) {
1391 return -1;
1394 ret = net_run_function(c, argc, argv, "net registry", func);
1396 return ret;