Line data Source code
1 : /*
2 : * Samba Unix/Linux SMB client library
3 : * Distributed SMB/CIFS Server Management Utility
4 : * Local registry interface
5 : *
6 : * Copyright (C) Michael Adam 2008
7 : *
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.
12 : *
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.
17 : *
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/>.
20 : */
21 :
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 "registry/reg_api_util.h"
34 : #include <assert.h>
35 : #include "../libcli/security/display_sec.h"
36 : #include "../libcli/security/sddl.h"
37 : #include "../libcli/registry/util_reg.h"
38 : #include "passdb/machine_sid.h"
39 : #include "net_registry_check.h"
40 : #include "lib/util/util_tdb.h"
41 : #include "lib/util/smb_strtox.h"
42 :
43 : /*
44 : *
45 : * Helper functions
46 : *
47 : */
48 :
49 : /**
50 : * split given path into hive and remaining path and open the hive key
51 : */
52 350 : static WERROR open_hive(TALLOC_CTX *ctx, const char *path,
53 : uint32_t desired_access,
54 : struct registry_key **hive,
55 : char **subkeyname)
56 : {
57 0 : WERROR werr;
58 350 : struct security_token *token = NULL;
59 350 : char *hivename = NULL;
60 350 : char *tmp_subkeyname = NULL;
61 350 : TALLOC_CTX *tmp_ctx = talloc_stackframe();
62 :
63 350 : if ((hive == NULL) || (subkeyname == NULL)) {
64 0 : werr = WERR_INVALID_PARAMETER;
65 0 : goto done;
66 : }
67 :
68 350 : werr = split_hive_key(tmp_ctx, path, &hivename, &tmp_subkeyname);
69 350 : if (!W_ERROR_IS_OK(werr)) {
70 0 : goto done;
71 : }
72 350 : *subkeyname = talloc_strdup(ctx, tmp_subkeyname);
73 350 : if (*subkeyname == NULL) {
74 0 : werr = WERR_NOT_ENOUGH_MEMORY;
75 0 : goto done;
76 : }
77 :
78 350 : werr = ntstatus_to_werror(registry_create_admin_token(tmp_ctx, &token));
79 350 : if (!W_ERROR_IS_OK(werr)) {
80 0 : goto done;
81 : }
82 :
83 350 : werr = reg_openhive(ctx, hivename, desired_access, token, hive);
84 350 : if (!W_ERROR_IS_OK(werr)) {
85 2 : goto done;
86 : }
87 :
88 348 : werr = WERR_OK;
89 :
90 350 : done:
91 350 : TALLOC_FREE(tmp_ctx);
92 350 : return werr;
93 : }
94 :
95 34 : static WERROR open_key(TALLOC_CTX *ctx, const char *path,
96 : uint32_t desired_access,
97 : struct registry_key **key)
98 : {
99 0 : WERROR werr;
100 34 : char *subkey_name = NULL;
101 34 : struct registry_key *hive = NULL;
102 34 : TALLOC_CTX *tmp_ctx = talloc_stackframe();
103 :
104 34 : if ((path == NULL) || (key == NULL)) {
105 0 : return WERR_INVALID_PARAMETER;
106 : }
107 :
108 34 : werr = open_hive(tmp_ctx, path, desired_access, &hive, &subkey_name);
109 34 : if (!W_ERROR_IS_OK(werr)) {
110 0 : d_fprintf(stderr, _("open_hive failed: %s\n"),
111 : win_errstr(werr));
112 0 : goto done;
113 : }
114 :
115 34 : werr = reg_openkey(ctx, hive, subkey_name, desired_access, key);
116 34 : if (!W_ERROR_IS_OK(werr)) {
117 0 : d_fprintf(stderr, _("reg_openkey failed: %s\n"),
118 : win_errstr(werr));
119 0 : goto done;
120 : }
121 :
122 34 : werr = WERR_OK;
123 :
124 34 : done:
125 34 : TALLOC_FREE(tmp_ctx);
126 34 : return werr;
127 : }
128 :
129 52 : static WERROR registry_enumkey(struct registry_key *parent, const char *keyname,
130 : bool recursive)
131 : {
132 0 : WERROR werr;
133 52 : TALLOC_CTX *ctx = talloc_stackframe();
134 0 : char *subkey_name;
135 0 : NTTIME modtime;
136 0 : uint32_t count;
137 52 : char *valname = NULL;
138 52 : struct registry_value *valvalue = NULL;
139 52 : struct registry_key *key = NULL;
140 :
141 52 : werr = reg_openkey(ctx, parent, keyname, REG_KEY_READ, &key);
142 52 : if (!W_ERROR_IS_OK(werr)) {
143 8 : goto done;
144 : }
145 :
146 44 : if (recursive) {
147 0 : printf("[%s]\n\n", key->key->name);
148 : } else {
149 44 : for (count = 0;
150 114 : werr = reg_enumkey(ctx, key, count, &subkey_name, &modtime),
151 114 : W_ERROR_IS_OK(werr);
152 70 : count++)
153 : {
154 70 : print_registry_key(subkey_name, &modtime);
155 : }
156 44 : if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) {
157 0 : goto done;
158 : }
159 : }
160 :
161 44 : for (count = 0;
162 48 : werr = reg_enumvalue(ctx, key, count, &valname, &valvalue),
163 48 : W_ERROR_IS_OK(werr);
164 4 : count++)
165 : {
166 4 : print_registry_value_with_name(valname, valvalue);
167 : }
168 44 : if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) {
169 0 : goto done;
170 : }
171 :
172 44 : if (!recursive) {
173 44 : werr = WERR_OK;
174 44 : goto done;
175 : }
176 :
177 0 : for (count = 0;
178 0 : werr = reg_enumkey(ctx, key, count, &subkey_name, &modtime),
179 0 : W_ERROR_IS_OK(werr);
180 0 : count++)
181 : {
182 0 : werr = registry_enumkey(key, subkey_name, recursive);
183 0 : if (!W_ERROR_IS_OK(werr)) {
184 0 : goto done;
185 : }
186 : }
187 0 : if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) {
188 0 : goto done;
189 : }
190 :
191 0 : werr = WERR_OK;
192 :
193 52 : done:
194 52 : TALLOC_FREE(ctx);
195 52 : return werr;
196 : }
197 :
198 :
199 :
200 : /*
201 : *
202 : * the main "net registry" function implementations
203 : *
204 : */
205 56 : static int net_registry_enumerate(struct net_context *c, int argc,
206 : const char **argv)
207 : {
208 0 : WERROR werr;
209 56 : struct registry_key *key = NULL;
210 56 : char *name = NULL;
211 56 : TALLOC_CTX *ctx = talloc_stackframe();
212 56 : int ret = -1;
213 :
214 56 : if (argc != 1 || c->display_usage) {
215 2 : d_printf("%s\n%s",
216 : _("Usage:"),
217 : _("net registry enumerate <path>\n"));
218 2 : d_printf("%s\n%s",
219 : _("Example:"),
220 : _("net registry enumerate 'HKLM\\Software\\Samba'\n"));
221 2 : goto done;
222 : }
223 :
224 54 : werr = open_hive(ctx, argv[0], REG_KEY_READ, &key, &name);
225 54 : if (!W_ERROR_IS_OK(werr)) {
226 2 : d_fprintf(stderr, _("open_key failed: %s\n"), win_errstr(werr));
227 2 : goto done;
228 : }
229 :
230 52 : werr = registry_enumkey(key, name, c->opt_reboot);
231 52 : if (W_ERROR_IS_OK(werr)) {
232 44 : ret = 0;
233 : }
234 8 : done:
235 56 : TALLOC_FREE(ctx);
236 56 : return ret;
237 : }
238 :
239 0 : static int net_registry_enumerate_recursive(struct net_context *c, int argc,
240 : const char **argv)
241 : {
242 0 : WERROR werr;
243 0 : struct registry_key *key = NULL;
244 0 : char *name = NULL;
245 0 : TALLOC_CTX *ctx = talloc_stackframe();
246 0 : int ret = -1;
247 :
248 0 : if (argc != 1 || c->display_usage) {
249 0 : d_printf("%s\n%s",
250 : _("Usage:"),
251 : _("net registry enumerate <path>\n"));
252 0 : d_printf("%s\n%s",
253 : _("Example:"),
254 : _("net registry enumerate 'HKLM\\Software\\Samba'\n"));
255 0 : goto done;
256 : }
257 :
258 0 : werr = open_hive(ctx, argv[0], REG_KEY_READ, &key, &name);
259 0 : if (!W_ERROR_IS_OK(werr)) {
260 0 : d_fprintf(stderr, _("open_key failed: %s\n"), win_errstr(werr));
261 0 : goto done;
262 : }
263 :
264 0 : werr = registry_enumkey(key, name, true);
265 0 : if (W_ERROR_IS_OK(werr)) {
266 0 : ret = 0;
267 : }
268 0 : done:
269 0 : TALLOC_FREE(ctx);
270 0 : return ret;
271 : }
272 :
273 :
274 20 : static int net_registry_createkey(struct net_context *c, int argc,
275 : const char **argv)
276 : {
277 0 : WERROR werr;
278 0 : enum winreg_CreateAction action;
279 20 : char *subkeyname = NULL;
280 20 : struct registry_key *hivekey = NULL;
281 20 : struct registry_key *subkey = NULL;
282 20 : TALLOC_CTX *ctx = talloc_stackframe();
283 20 : int ret = -1;
284 :
285 20 : if (argc != 1 || c->display_usage) {
286 0 : d_printf("%s\n%s",
287 : _("Usage:"),
288 : _("net registry createkey <path>\n"));
289 0 : d_printf("%s\n%s",
290 : _("Example:"),
291 : _("net registry createkey "
292 : "'HKLM\\Software\\Samba\\smbconf.127.0.0.1'\n"));
293 0 : goto done;
294 : }
295 20 : if (strlen(argv[0]) == 0) {
296 0 : d_fprintf(stderr, _("error: zero length key name given\n"));
297 0 : goto done;
298 : }
299 :
300 20 : werr = open_hive(ctx, argv[0], REG_KEY_WRITE, &hivekey, &subkeyname);
301 20 : if (!W_ERROR_IS_OK(werr)) {
302 0 : d_fprintf(stderr, _("open_hive failed: %s\n"),
303 : win_errstr(werr));
304 0 : goto done;
305 : }
306 :
307 20 : werr = reg_createkey(ctx, hivekey, subkeyname, REG_KEY_WRITE,
308 : &subkey, &action);
309 20 : if (!W_ERROR_IS_OK(werr)) {
310 0 : d_fprintf(stderr, _("reg_createkey failed: %s\n"),
311 : win_errstr(werr));
312 0 : goto done;
313 : }
314 20 : switch (action) {
315 0 : case REG_ACTION_NONE:
316 0 : d_printf(_("createkey did nothing -- huh?\n"));
317 0 : break;
318 10 : case REG_CREATED_NEW_KEY:
319 10 : d_printf(_("createkey created %s\n"), argv[0]);
320 10 : break;
321 10 : case REG_OPENED_EXISTING_KEY:
322 10 : d_printf(_("createkey opened existing %s\n"), argv[0]);
323 10 : break;
324 : }
325 :
326 20 : ret = 0;
327 :
328 20 : done:
329 20 : TALLOC_FREE(ctx);
330 20 : return ret;
331 : }
332 :
333 18 : static int net_registry_deletekey_internal(struct net_context *c, int argc,
334 : const char **argv,
335 : bool recursive)
336 : {
337 0 : WERROR werr;
338 18 : char *subkeyname = NULL;
339 18 : struct registry_key *hivekey = NULL;
340 18 : TALLOC_CTX *ctx = talloc_stackframe();
341 18 : int ret = -1;
342 :
343 18 : if (argc != 1 || c->display_usage) {
344 0 : d_printf("%s\n%s",
345 : _("Usage:"),
346 : _("net registry deletekey <path>\n"));
347 0 : d_printf("%s\n%s",
348 : _("Example:"),
349 : _("net registry deletekey "
350 : "'HKLM\\Software\\Samba\\smbconf.127.0.0.1'\n"));
351 0 : goto done;
352 : }
353 18 : if (strlen(argv[0]) == 0) {
354 0 : d_fprintf(stderr, _("error: zero length key name given\n"));
355 0 : goto done;
356 : }
357 :
358 18 : werr = open_hive(ctx, argv[0], REG_KEY_WRITE, &hivekey, &subkeyname);
359 18 : if (!W_ERROR_IS_OK(werr)) {
360 0 : d_fprintf(stderr, "open_hive %s: %s\n", _("failed"),
361 : win_errstr(werr));
362 0 : goto done;
363 : }
364 :
365 18 : if (recursive) {
366 0 : werr = reg_deletekey_recursive(hivekey, subkeyname);
367 : } else {
368 18 : werr = reg_deletekey(hivekey, subkeyname);
369 : }
370 18 : if (!W_ERROR_IS_OK(werr) &&
371 4 : !(c->opt_force && W_ERROR_EQUAL(werr, WERR_FILE_NOT_FOUND)))
372 : {
373 4 : d_fprintf(stderr, "reg_deletekey %s: %s\n", _("failed"),
374 : win_errstr(werr));
375 4 : goto done;
376 : }
377 :
378 14 : ret = 0;
379 :
380 18 : done:
381 18 : TALLOC_FREE(ctx);
382 18 : return ret;
383 : }
384 :
385 18 : static int net_registry_deletekey(struct net_context *c, int argc,
386 : const char **argv)
387 : {
388 18 : return net_registry_deletekey_internal(c, argc, argv, false);
389 : }
390 :
391 0 : static int net_registry_deletekey_recursive(struct net_context *c, int argc,
392 : const char **argv)
393 : {
394 0 : return net_registry_deletekey_internal(c, argc, argv, true);
395 : }
396 :
397 6 : static int net_registry_getvalue_internal(struct net_context *c, int argc,
398 : const char **argv, bool raw)
399 : {
400 0 : WERROR werr;
401 6 : int ret = -1;
402 6 : struct registry_key *key = NULL;
403 6 : struct registry_value *value = NULL;
404 6 : TALLOC_CTX *ctx = talloc_stackframe();
405 :
406 6 : if (argc != 2 || c->display_usage) {
407 0 : d_fprintf(stderr, "%s\n%s",
408 : _("Usage:"),
409 : _("net registry getvalue <key> <valuename>\n"));
410 0 : goto done;
411 : }
412 :
413 6 : werr = open_key(ctx, argv[0], REG_KEY_READ, &key);
414 6 : if (!W_ERROR_IS_OK(werr)) {
415 0 : d_fprintf(stderr, _("open_key failed: %s\n"), win_errstr(werr));
416 0 : goto done;
417 : }
418 :
419 6 : werr = reg_queryvalue(ctx, key, argv[1], &value);
420 6 : if (!W_ERROR_IS_OK(werr)) {
421 0 : d_fprintf(stderr, _("reg_queryvalue failed: %s\n"),
422 : win_errstr(werr));
423 0 : goto done;
424 : }
425 :
426 6 : print_registry_value(value, raw);
427 :
428 6 : ret = 0;
429 :
430 6 : done:
431 6 : TALLOC_FREE(ctx);
432 6 : return ret;
433 : }
434 :
435 0 : static int net_registry_getvalue(struct net_context *c, int argc,
436 : const char **argv)
437 : {
438 0 : return net_registry_getvalue_internal(c, argc, argv, false);
439 : }
440 :
441 6 : static int net_registry_getvalueraw(struct net_context *c, int argc,
442 : const char **argv)
443 : {
444 6 : return net_registry_getvalue_internal(c, argc, argv, true);
445 : }
446 :
447 0 : static int net_registry_getvaluesraw(struct net_context *c, int argc,
448 : const char **argv)
449 : {
450 0 : WERROR werr;
451 0 : int ret = -1;
452 0 : struct registry_key *key = NULL;
453 0 : TALLOC_CTX *ctx = talloc_stackframe();
454 0 : uint32_t idx;
455 :
456 0 : if (argc != 1 || c->display_usage) {
457 0 : d_fprintf(stderr, "usage: net rpc registry getvaluesraw "
458 : "<key>\n");
459 0 : goto done;
460 : }
461 :
462 0 : werr = open_key(ctx, argv[0], REG_KEY_READ, &key);
463 0 : if (!W_ERROR_IS_OK(werr)) {
464 0 : d_fprintf(stderr, "open_key failed: %s\n", win_errstr(werr));
465 0 : goto done;
466 : }
467 :
468 0 : idx = 0;
469 0 : while (true) {
470 0 : struct registry_value *val;
471 :
472 0 : werr = reg_enumvalue(talloc_tos(), key, idx, NULL, &val);
473 :
474 0 : if (W_ERROR_EQUAL(werr, WERR_NO_MORE_ITEMS)) {
475 0 : ret = 0;
476 0 : break;
477 : }
478 0 : if (!W_ERROR_IS_OK(werr)) {
479 0 : break;
480 : }
481 0 : print_registry_value(val, true);
482 0 : TALLOC_FREE(val);
483 0 : idx += 1;
484 : }
485 0 : done:
486 0 : TALLOC_FREE(ctx);
487 0 : return ret;
488 : }
489 :
490 8 : static int net_registry_setvalue(struct net_context *c, int argc,
491 : const char **argv)
492 : {
493 0 : WERROR werr;
494 0 : struct registry_value value;
495 8 : struct registry_key *key = NULL;
496 8 : int ret = -1;
497 8 : TALLOC_CTX *ctx = talloc_stackframe();
498 :
499 8 : if (argc < 4 || c->display_usage) {
500 0 : d_fprintf(stderr, "%s\n%s",
501 : _("Usage:"),
502 : _("net registry setvalue <key> <valuename> "
503 : "<type> [<val>]+\n"));
504 0 : goto done;
505 : }
506 :
507 8 : if (!strequal(argv[2], "multi_sz") && (argc != 4)) {
508 0 : d_fprintf(stderr, _("Too many args for type %s\n"), argv[2]);
509 0 : goto done;
510 : }
511 :
512 8 : if (strequal(argv[2], "dword")) {
513 2 : int error = 0;
514 0 : uint32_t v;
515 :
516 2 : v = smb_strtoul(argv[3], NULL, 10, &error, SMB_STR_STANDARD);
517 2 : if (error != 0) {
518 0 : goto done;
519 : }
520 :
521 2 : value.type = REG_DWORD;
522 2 : value.data = data_blob_talloc(ctx, NULL, 4);
523 2 : SIVAL(value.data.data, 0, v);
524 6 : } else if (strequal(argv[2], "sz")) {
525 6 : value.type = REG_SZ;
526 6 : if (!push_reg_sz(ctx, &value.data, argv[3])) {
527 0 : goto done;
528 : }
529 0 : } else if (strequal(argv[2], "multi_sz")) {
530 0 : const char **array;
531 0 : int count = argc - 3;
532 0 : int i;
533 0 : value.type = REG_MULTI_SZ;
534 0 : array = talloc_zero_array(ctx, const char *, count + 1);
535 0 : if (array == NULL) {
536 0 : goto done;
537 : }
538 0 : for (i=0; i < count; i++) {
539 0 : array[i] = talloc_strdup(array, argv[count+i]);
540 0 : if (array[i] == NULL) {
541 0 : goto done;
542 : }
543 : }
544 0 : if (!push_reg_multi_sz(ctx, &value.data, array)) {
545 0 : goto done;
546 : }
547 : } else {
548 0 : d_fprintf(stderr, _("type \"%s\" not implemented\n"), argv[2]);
549 0 : goto done;
550 : }
551 :
552 8 : werr = open_key(ctx, argv[0], REG_KEY_WRITE, &key);
553 8 : if (!W_ERROR_IS_OK(werr)) {
554 0 : d_fprintf(stderr, _("open_key failed: %s\n"), win_errstr(werr));
555 0 : goto done;
556 : }
557 :
558 8 : werr = reg_setvalue(key, argv[1], &value);
559 8 : if (!W_ERROR_IS_OK(werr)) {
560 0 : d_fprintf(stderr, _("reg_setvalue failed: %s\n"),
561 : win_errstr(werr));
562 0 : goto done;
563 : }
564 :
565 8 : ret = 0;
566 :
567 8 : done:
568 8 : TALLOC_FREE(ctx);
569 8 : return ret;
570 : }
571 :
572 0 : static int net_registry_increment(struct net_context *c, int argc,
573 : const char **argv)
574 : {
575 0 : TDB_DATA lock_key = string_term_tdb_data("registry_increment_lock");
576 0 : struct g_lock_ctx *ctx = NULL;
577 0 : const char *keyname = NULL;
578 0 : struct registry_key *key = NULL;
579 0 : const char *valuename = NULL;
580 0 : struct registry_value *value = NULL;
581 0 : uint32_t v;
582 0 : uint32_t increment;
583 0 : uint32_t newvalue;
584 0 : NTSTATUS status;
585 0 : WERROR werr;
586 0 : int ret = -1;
587 :
588 0 : if (argc < 2 || c->display_usage) {
589 0 : d_fprintf(stderr, "%s\n%s",
590 : _("Usage:"),
591 : _("net registry increment <key> <valuename> "
592 : "[<increment>]\n"));
593 0 : goto done;
594 : }
595 :
596 0 : keyname = argv[0];
597 0 : valuename = argv[1];
598 :
599 0 : increment = 1;
600 0 : if (argc == 3) {
601 0 : int error = 0;
602 :
603 0 : increment = smb_strtoul(
604 0 : argv[2], NULL, 10, &error, SMB_STR_STANDARD);
605 0 : if (error != 0) {
606 0 : goto done;
607 : }
608 : }
609 :
610 0 : ctx = g_lock_ctx_init(c, c->msg_ctx);
611 0 : if (ctx == NULL) {
612 0 : d_fprintf(stderr, _("g_lock_ctx_init failed\n"));
613 0 : goto done;
614 : }
615 :
616 0 : status = g_lock_lock(ctx,
617 : lock_key,
618 : G_LOCK_WRITE,
619 : tevent_timeval_set(600, 0),
620 : NULL,
621 : NULL);
622 0 : if (!NT_STATUS_IS_OK(status)) {
623 0 : d_fprintf(stderr, _("g_lock_lock failed: %s\n"),
624 : nt_errstr(status));
625 0 : goto done;
626 : }
627 :
628 0 : werr = open_key(c, keyname, REG_KEY_READ|REG_KEY_WRITE, &key);
629 0 : if (!W_ERROR_IS_OK(werr)) {
630 0 : d_fprintf(stderr, _("open_key failed: %s\n"),
631 : win_errstr(werr));
632 0 : goto done;
633 : }
634 :
635 0 : werr = reg_queryvalue(key, key, valuename, &value);
636 0 : if (!W_ERROR_IS_OK(werr)) {
637 0 : d_fprintf(stderr, _("reg_queryvalue failed: %s\n"),
638 : win_errstr(werr));
639 0 : goto done;
640 : }
641 :
642 0 : if (value->type != REG_DWORD) {
643 0 : d_fprintf(stderr, _("value not a DWORD: %s\n"),
644 0 : str_regtype(value->type));
645 0 : goto done;
646 : }
647 :
648 0 : if (value->data.length < 4) {
649 0 : d_fprintf(stderr, _("value too short for regular DWORD\n"));
650 0 : goto done;
651 : }
652 :
653 0 : v = IVAL(value->data.data, 0);
654 0 : v += increment;
655 0 : newvalue = v;
656 :
657 0 : SIVAL(value->data.data, 0, v);
658 :
659 0 : werr = reg_setvalue(key, valuename, value);
660 0 : if (!W_ERROR_IS_OK(werr)) {
661 0 : d_fprintf(stderr, _("reg_setvalue failed: %s\n"),
662 : win_errstr(werr));
663 0 : goto done;
664 : }
665 :
666 0 : if (!W_ERROR_IS_OK(werr)) {
667 0 : d_fprintf(stderr, _("increment failed: %s\n"),
668 : win_errstr(werr));
669 0 : goto done;
670 : }
671 :
672 0 : g_lock_unlock(ctx, lock_key);
673 :
674 0 : d_printf(_("%"PRIu32"\n"), newvalue);
675 :
676 0 : ret = 0;
677 :
678 0 : done:
679 0 : TALLOC_FREE(value);
680 0 : TALLOC_FREE(key);
681 0 : TALLOC_FREE(ctx);
682 0 : return ret;
683 : }
684 :
685 8 : static int net_registry_deletevalue(struct net_context *c, int argc,
686 : const char **argv)
687 : {
688 0 : WERROR werr;
689 8 : struct registry_key *key = NULL;
690 8 : TALLOC_CTX *ctx = talloc_stackframe();
691 8 : int ret = -1;
692 :
693 8 : if (argc != 2 || c->display_usage) {
694 0 : d_fprintf(stderr, "%s\n%s",
695 : _("Usage:"),
696 : _("net registry deletevalue <key> <valuename>\n"));
697 0 : goto done;
698 : }
699 :
700 8 : werr = open_key(ctx, argv[0], REG_KEY_WRITE, &key);
701 8 : if (!W_ERROR_IS_OK(werr)) {
702 0 : d_fprintf(stderr, _("open_key failed: %s\n"), win_errstr(werr));
703 0 : goto done;
704 : }
705 :
706 8 : werr = reg_deletevalue(key, argv[1]);
707 8 : if (!W_ERROR_IS_OK(werr)) {
708 4 : d_fprintf(stderr, _("reg_deletevalue failed: %s\n"),
709 : win_errstr(werr));
710 4 : goto done;
711 : }
712 :
713 4 : ret = 0;
714 :
715 8 : done:
716 8 : TALLOC_FREE(ctx);
717 8 : return ret;
718 : }
719 :
720 2 : static WERROR net_registry_getsd_internal(struct net_context *c,
721 : TALLOC_CTX *mem_ctx,
722 : const char *keyname,
723 : struct security_descriptor **sd)
724 : {
725 0 : WERROR werr;
726 2 : struct registry_key *key = NULL;
727 2 : TALLOC_CTX *ctx = talloc_stackframe();
728 2 : uint32_t access_mask = REG_KEY_READ |
729 : SEC_FLAG_MAXIMUM_ALLOWED |
730 : SEC_FLAG_SYSTEM_SECURITY;
731 :
732 : /*
733 : * net_rpc_regsitry uses SEC_FLAG_SYSTEM_SECURITY, but access
734 : * is denied with these perms right now...
735 : */
736 2 : access_mask = REG_KEY_READ;
737 :
738 2 : if (sd == NULL) {
739 0 : d_fprintf(stderr, _("internal error: invalid argument\n"));
740 0 : werr = WERR_INVALID_PARAMETER;
741 0 : goto done;
742 : }
743 :
744 2 : if (strlen(keyname) == 0) {
745 0 : d_fprintf(stderr, _("error: zero length key name given\n"));
746 0 : werr = WERR_INVALID_PARAMETER;
747 0 : goto done;
748 : }
749 :
750 2 : werr = open_key(ctx, keyname, access_mask, &key);
751 2 : if (!W_ERROR_IS_OK(werr)) {
752 0 : d_fprintf(stderr, "%s%s\n", _("open_key failed: "),
753 : win_errstr(werr));
754 0 : goto done;
755 : }
756 :
757 2 : werr = reg_getkeysecurity(mem_ctx, key, sd);
758 2 : if (!W_ERROR_IS_OK(werr)) {
759 0 : d_fprintf(stderr, "%s%s\n", _("reg_getkeysecurity failed: "),
760 : win_errstr(werr));
761 0 : goto done;
762 : }
763 :
764 2 : werr = WERR_OK;
765 :
766 2 : done:
767 2 : TALLOC_FREE(ctx);
768 2 : return werr;
769 : }
770 :
771 2 : static int net_registry_getsd(struct net_context *c, int argc,
772 : const char **argv)
773 : {
774 0 : WERROR werr;
775 2 : int ret = -1;
776 2 : struct security_descriptor *secdesc = NULL;
777 2 : TALLOC_CTX *ctx = talloc_stackframe();
778 :
779 2 : if (argc != 1 || c->display_usage) {
780 0 : d_printf("%s\n%s",
781 : _("Usage:"),
782 : _("net registry getsd <path>\n"));
783 0 : d_printf("%s\n%s",
784 : _("Example:"),
785 : _("net registry getsd 'HKLM\\Software\\Samba'\n"));
786 0 : goto done;
787 : }
788 :
789 2 : werr = net_registry_getsd_internal(c, ctx, argv[0], &secdesc);
790 2 : if (!W_ERROR_IS_OK(werr)) {
791 0 : goto done;
792 : }
793 :
794 2 : display_sec_desc(secdesc);
795 :
796 2 : ret = 0;
797 :
798 2 : done:
799 2 : TALLOC_FREE(ctx);
800 2 : return ret;
801 : }
802 :
803 0 : static int net_registry_getsd_sddl(struct net_context *c,
804 : int argc, const char **argv)
805 : {
806 0 : WERROR werr;
807 0 : int ret = -1;
808 0 : struct security_descriptor *secdesc = NULL;
809 0 : TALLOC_CTX *ctx = talloc_stackframe();
810 :
811 0 : if (argc != 1 || c->display_usage) {
812 0 : d_printf("%s\n%s",
813 : _("Usage:"),
814 : _("net registry getsd_sddl <path>\n"));
815 0 : d_printf("%s\n%s",
816 : _("Example:"),
817 : _("net registry getsd_sddl 'HKLM\\Software\\Samba'\n"));
818 0 : goto done;
819 : }
820 :
821 0 : werr = net_registry_getsd_internal(c, ctx, argv[0], &secdesc);
822 0 : if (!W_ERROR_IS_OK(werr)) {
823 0 : goto done;
824 : }
825 :
826 0 : d_printf("%s\n", sddl_encode(ctx, secdesc, get_global_sam_sid()));
827 :
828 0 : ret = 0;
829 :
830 0 : done:
831 0 : TALLOC_FREE(ctx);
832 0 : return ret;
833 : }
834 :
835 0 : static WERROR net_registry_setsd_internal(struct net_context *c,
836 : TALLOC_CTX *mem_ctx,
837 : const char *keyname,
838 : struct security_descriptor *sd)
839 : {
840 0 : WERROR werr;
841 0 : struct registry_key *key = NULL;
842 0 : TALLOC_CTX *ctx = talloc_stackframe();
843 0 : uint32_t access_mask = REG_KEY_WRITE |
844 : SEC_FLAG_MAXIMUM_ALLOWED |
845 : SEC_FLAG_SYSTEM_SECURITY;
846 :
847 : /*
848 : * net_rpc_regsitry uses SEC_FLAG_SYSTEM_SECURITY, but access
849 : * is denied with these perms right now...
850 : */
851 0 : access_mask = REG_KEY_WRITE;
852 :
853 0 : if (strlen(keyname) == 0) {
854 0 : d_fprintf(stderr, _("error: zero length key name given\n"));
855 0 : werr = WERR_INVALID_PARAMETER;
856 0 : goto done;
857 : }
858 :
859 0 : werr = open_key(ctx, keyname, access_mask, &key);
860 0 : if (!W_ERROR_IS_OK(werr)) {
861 0 : d_fprintf(stderr, "%s%s\n", _("open_key failed: "),
862 : win_errstr(werr));
863 0 : goto done;
864 : }
865 :
866 0 : werr = reg_setkeysecurity(key, sd);
867 0 : if (!W_ERROR_IS_OK(werr)) {
868 0 : d_fprintf(stderr, "%s%s\n", _("reg_setkeysecurity failed: "),
869 : win_errstr(werr));
870 0 : goto done;
871 : }
872 :
873 0 : werr = WERR_OK;
874 :
875 0 : done:
876 0 : TALLOC_FREE(ctx);
877 0 : return werr;
878 : }
879 :
880 0 : static int net_registry_setsd_sddl(struct net_context *c,
881 : int argc, const char **argv)
882 : {
883 0 : WERROR werr;
884 0 : int ret = -1;
885 0 : struct security_descriptor *secdesc = NULL;
886 0 : TALLOC_CTX *ctx = talloc_stackframe();
887 :
888 0 : if (argc != 2 || c->display_usage) {
889 0 : d_printf("%s\n%s",
890 : _("Usage:"),
891 : _("net registry setsd_sddl <path> <security_descriptor>\n"));
892 0 : d_printf("%s\n%s",
893 : _("Example:"),
894 : _("net registry setsd_sddl 'HKLM\\Software\\Samba'\n"));
895 0 : goto done;
896 : }
897 :
898 0 : secdesc = sddl_decode(ctx, argv[1], get_global_sam_sid());
899 0 : if (secdesc == NULL) {
900 0 : goto done;
901 : }
902 :
903 0 : werr = net_registry_setsd_internal(c, ctx, argv[0], secdesc);
904 0 : if (!W_ERROR_IS_OK(werr)) {
905 0 : goto done;
906 : }
907 :
908 0 : ret = 0;
909 :
910 0 : done:
911 0 : TALLOC_FREE(ctx);
912 0 : return ret;
913 : }
914 :
915 : /******************************************************************************/
916 : /**
917 : * @defgroup net_registry net registry
918 : */
919 :
920 : /**
921 : * @defgroup net_registry_import Import
922 : * @ingroup net_registry
923 : * @{
924 : */
925 :
926 : struct import_ctx {
927 : TALLOC_CTX *mem_ctx;
928 : };
929 :
930 :
931 224 : static WERROR import_create_key(struct import_ctx *ctx,
932 : struct registry_key *parent,
933 : const char *name, void **pkey, bool *existing)
934 : {
935 0 : WERROR werr;
936 224 : TALLOC_CTX *mem_ctx = talloc_new(ctx->mem_ctx);
937 :
938 224 : struct registry_key *key = NULL;
939 0 : enum winreg_CreateAction action;
940 :
941 224 : if (parent == NULL) {
942 224 : char *subkeyname = NULL;
943 224 : werr = open_hive(mem_ctx, name, REG_KEY_WRITE,
944 : &parent, &subkeyname);
945 224 : if (!W_ERROR_IS_OK(werr)) {
946 0 : d_fprintf(stderr, _("open_hive failed: %s\n"),
947 : win_errstr(werr));
948 0 : goto done;
949 : }
950 224 : name = subkeyname;
951 : }
952 :
953 224 : action = REG_ACTION_NONE;
954 224 : werr = reg_createkey(mem_ctx, parent, name, REG_KEY_WRITE,
955 : &key, &action);
956 224 : if (!W_ERROR_IS_OK(werr)) {
957 0 : d_fprintf(stderr, _("reg_createkey failed: %s\n"),
958 : win_errstr(werr));
959 0 : goto done;
960 : }
961 :
962 224 : if (action == REG_ACTION_NONE) {
963 0 : d_fprintf(stderr, _("createkey did nothing -- huh?\n"));
964 0 : werr = WERR_CREATE_FAILED;
965 0 : goto done;
966 : }
967 :
968 224 : if (existing != NULL) {
969 224 : *existing = (action == REG_OPENED_EXISTING_KEY);
970 : }
971 :
972 224 : if (pkey!=NULL) {
973 224 : *pkey = talloc_steal(ctx->mem_ctx, key);
974 : }
975 :
976 0 : done:
977 224 : talloc_free(mem_ctx);
978 224 : return werr;
979 : }
980 :
981 222 : static WERROR import_close_key(struct import_ctx *ctx,
982 : struct registry_key *key)
983 : {
984 222 : return WERR_OK;
985 : }
986 :
987 0 : static WERROR import_delete_key(struct import_ctx *ctx,
988 : struct registry_key *parent, const char *name)
989 : {
990 0 : WERROR werr;
991 0 : TALLOC_CTX *mem_ctx = talloc_new(talloc_tos());
992 :
993 0 : if (parent == NULL) {
994 0 : char *subkeyname = NULL;
995 0 : werr = open_hive(mem_ctx, name, REG_KEY_WRITE,
996 : &parent, &subkeyname);
997 0 : if (!W_ERROR_IS_OK(werr)) {
998 0 : d_fprintf(stderr, _("open_hive failed: %s\n"),
999 : win_errstr(werr));
1000 0 : goto done;
1001 : }
1002 0 : name = subkeyname;
1003 : }
1004 :
1005 0 : werr = reg_deletekey_recursive(parent, name);
1006 0 : if (!W_ERROR_IS_OK(werr)) {
1007 0 : d_fprintf(stderr, "reg_deletekey_recursive %s: %s\n",
1008 : _("failed"), win_errstr(werr));
1009 0 : goto done;
1010 : }
1011 :
1012 0 : done:
1013 0 : talloc_free(mem_ctx);
1014 0 : return werr;
1015 : }
1016 :
1017 1086 : static WERROR import_create_val (struct import_ctx *ctx,
1018 : struct registry_key *parent, const char *name,
1019 : const struct registry_value *value)
1020 : {
1021 0 : WERROR werr;
1022 :
1023 1086 : if (parent == NULL) {
1024 0 : return WERR_INVALID_PARAMETER;
1025 : }
1026 :
1027 1086 : werr = reg_setvalue(parent, name, value);
1028 1086 : if (!W_ERROR_IS_OK(werr)) {
1029 0 : d_fprintf(stderr, _("reg_setvalue failed: %s\n"),
1030 : win_errstr(werr));
1031 : }
1032 1086 : return werr;
1033 : }
1034 :
1035 0 : static WERROR import_delete_val (struct import_ctx *ctx,
1036 : struct registry_key *parent, const char *name)
1037 : {
1038 0 : WERROR werr;
1039 :
1040 0 : if (parent == NULL) {
1041 0 : return WERR_INVALID_PARAMETER;
1042 : }
1043 :
1044 0 : werr = reg_deletevalue(parent, name);
1045 0 : if (!W_ERROR_IS_OK(werr)) {
1046 0 : d_fprintf(stderr, _("reg_deletevalue failed: %s\n"),
1047 : win_errstr(werr));
1048 : }
1049 :
1050 0 : return werr;
1051 : }
1052 :
1053 : struct precheck_ctx {
1054 : TALLOC_CTX *mem_ctx;
1055 : bool failed;
1056 : };
1057 :
1058 0 : static WERROR precheck_create_key(struct precheck_ctx *ctx,
1059 : struct registry_key *parent,
1060 : const char *name, void **pkey, bool *existing)
1061 : {
1062 0 : WERROR werr;
1063 0 : TALLOC_CTX *frame = talloc_stackframe();
1064 0 : struct registry_key *key = NULL;
1065 :
1066 0 : if (parent == NULL) {
1067 0 : char *subkeyname = NULL;
1068 0 : werr = open_hive(frame, name, REG_KEY_READ,
1069 : &parent, &subkeyname);
1070 0 : if (!W_ERROR_IS_OK(werr)) {
1071 0 : d_printf("Precheck: open_hive of [%s] failed: %s\n",
1072 : name, win_errstr(werr));
1073 0 : goto done;
1074 : }
1075 0 : name = subkeyname;
1076 : }
1077 :
1078 0 : werr = reg_openkey(frame, parent, name, 0, &key);
1079 0 : if (!W_ERROR_IS_OK(werr)) {
1080 0 : d_printf("Precheck: openkey [%s] failed: %s\n",
1081 : name, win_errstr(werr));
1082 0 : goto done;
1083 : }
1084 :
1085 0 : if (existing != NULL) {
1086 0 : *existing = true;
1087 : }
1088 :
1089 0 : if (pkey != NULL) {
1090 0 : *pkey = talloc_steal(ctx->mem_ctx, key);
1091 : }
1092 :
1093 0 : done:
1094 0 : talloc_free(frame);
1095 0 : ctx->failed = !W_ERROR_IS_OK(werr);
1096 0 : return werr;
1097 : }
1098 :
1099 0 : static WERROR precheck_close_key(struct precheck_ctx *ctx,
1100 : struct registry_key *key)
1101 : {
1102 0 : talloc_free(key);
1103 0 : return WERR_OK;
1104 : }
1105 :
1106 0 : static WERROR precheck_delete_key(struct precheck_ctx *ctx,
1107 : struct registry_key *parent, const char *name)
1108 : {
1109 0 : WERROR werr;
1110 0 : TALLOC_CTX *frame = talloc_stackframe();
1111 0 : struct registry_key *key;
1112 :
1113 0 : if (parent == NULL) {
1114 0 : char *subkeyname = NULL;
1115 0 : werr = open_hive(frame, name, REG_KEY_READ,
1116 : &parent, &subkeyname);
1117 0 : if (!W_ERROR_IS_OK(werr)) {
1118 0 : d_printf("Precheck: open_hive of [%s] failed: %s\n",
1119 : name, win_errstr(werr));
1120 0 : goto done;
1121 : }
1122 0 : name = subkeyname;
1123 : }
1124 :
1125 0 : werr = reg_openkey(ctx->mem_ctx, parent, name, 0, &key);
1126 0 : if (W_ERROR_IS_OK(werr)) {
1127 0 : d_printf("Precheck: key [%s\\%s] should not exist\n",
1128 0 : parent->key->name, name);
1129 0 : werr = WERR_FILE_EXISTS;
1130 0 : } else if (W_ERROR_EQUAL(werr, WERR_FILE_NOT_FOUND)) {
1131 0 : werr = WERR_OK;
1132 : } else {
1133 0 : d_printf("Precheck: openkey [%s\\%s] failed: %s\n",
1134 0 : parent->key->name, name, win_errstr(werr));
1135 : }
1136 :
1137 0 : done:
1138 0 : talloc_free(frame);
1139 0 : ctx->failed = !W_ERROR_IS_OK(werr);
1140 0 : return werr;
1141 : }
1142 :
1143 0 : static int registry_value_cmp(
1144 : const struct registry_value* v1, const struct registry_value* v2)
1145 : {
1146 0 : if (v1->type == v2->type) {
1147 0 : return data_blob_cmp(&v1->data, &v2->data);
1148 : }
1149 0 : return NUMERIC_CMP(v1->type, v2->type);
1150 : }
1151 :
1152 0 : static WERROR precheck_create_val(struct precheck_ctx *ctx,
1153 : struct registry_key *parent,
1154 : const char *name,
1155 : const struct registry_value *value)
1156 : {
1157 0 : TALLOC_CTX *frame = talloc_stackframe();
1158 0 : struct registry_value *old;
1159 0 : WERROR werr;
1160 :
1161 0 : SMB_ASSERT(parent);
1162 :
1163 0 : werr = reg_queryvalue(frame, parent, name, &old);
1164 0 : if (!W_ERROR_IS_OK(werr)) {
1165 0 : d_printf("Precheck: queryvalue \"%s\" of [%s] failed: %s\n",
1166 0 : name, parent->key->name, win_errstr(werr));
1167 0 : goto done;
1168 : }
1169 0 : if (registry_value_cmp(value, old) != 0) {
1170 0 : d_printf("Precheck: unexpected value \"%s\" of key [%s]\n",
1171 0 : name, parent->key->name);
1172 0 : ctx->failed = true;
1173 : }
1174 0 : done:
1175 0 : talloc_free(frame);
1176 0 : return werr;
1177 : }
1178 :
1179 0 : static WERROR precheck_delete_val(struct precheck_ctx *ctx,
1180 : struct registry_key *parent,
1181 : const char *name)
1182 : {
1183 0 : TALLOC_CTX *frame = talloc_stackframe();
1184 0 : struct registry_value *old;
1185 0 : WERROR werr;
1186 :
1187 0 : SMB_ASSERT(parent);
1188 :
1189 0 : werr = reg_queryvalue(frame, parent, name, &old);
1190 0 : if (W_ERROR_IS_OK(werr)) {
1191 0 : d_printf("Precheck: value \"%s\" of key [%s] should not exist\n",
1192 0 : name, parent->key->name);
1193 0 : werr = WERR_FILE_EXISTS;
1194 0 : } else if (W_ERROR_EQUAL(werr, WERR_FILE_NOT_FOUND)) {
1195 0 : werr = WERR_OK;
1196 : } else {
1197 0 : printf("Precheck: queryvalue \"%s\" of key [%s] failed: %s\n",
1198 0 : name, parent->key->name, win_errstr(werr));
1199 : }
1200 :
1201 0 : talloc_free(frame);
1202 0 : ctx->failed = !W_ERROR_IS_OK(werr);
1203 0 : return werr;
1204 : }
1205 :
1206 2 : static bool import_precheck(const char *fname, const char *parse_options)
1207 : {
1208 2 : TALLOC_CTX *mem_ctx = talloc_tos();
1209 2 : struct precheck_ctx precheck_ctx = {
1210 : .mem_ctx = mem_ctx,
1211 : .failed = false,
1212 : };
1213 2 : struct reg_import_callback precheck_callback = {
1214 : .openkey = NULL,
1215 : .closekey = (reg_import_callback_closekey_t)&precheck_close_key,
1216 : .createkey = (reg_import_callback_createkey_t)&precheck_create_key,
1217 : .deletekey = (reg_import_callback_deletekey_t)&precheck_delete_key,
1218 : .deleteval = (reg_import_callback_deleteval_t)&precheck_delete_val,
1219 : .setval = {
1220 : .registry_value = (reg_import_callback_setval_registry_value_t)
1221 : &precheck_create_val,
1222 : },
1223 : .setval_type = REGISTRY_VALUE,
1224 : .data = &precheck_ctx
1225 : };
1226 0 : struct reg_parse_callback *parse_callback;
1227 0 : int ret;
1228 :
1229 2 : if (!fname) {
1230 2 : return true;
1231 : }
1232 :
1233 0 : parse_callback = reg_import_adapter(mem_ctx, precheck_callback);
1234 0 : if (parse_callback == NULL) {
1235 0 : d_printf("talloc failed\n");
1236 0 : return false;
1237 : }
1238 :
1239 0 : ret = reg_parse_file(fname, parse_callback, parse_options);
1240 :
1241 0 : if (ret < 0 || precheck_ctx.failed) {
1242 0 : d_printf("Precheck failed\n");
1243 0 : return false;
1244 : }
1245 0 : return true;
1246 : }
1247 :
1248 2 : static int import_with_precheck_action(const char *import_fname,
1249 : const char *precheck_fname,
1250 : const char *parse_options)
1251 : {
1252 2 : TALLOC_CTX *frame = talloc_stackframe();
1253 2 : struct import_ctx import_ctx = {
1254 : .mem_ctx = frame,
1255 : };
1256 2 : struct reg_import_callback import_callback = {
1257 : .openkey = NULL,
1258 : .closekey = (reg_import_callback_closekey_t)&import_close_key,
1259 : .createkey = (reg_import_callback_createkey_t)&import_create_key,
1260 : .deletekey = (reg_import_callback_deletekey_t)&import_delete_key,
1261 : .deleteval = (reg_import_callback_deleteval_t)&import_delete_val,
1262 : .setval = {
1263 : .registry_value = (reg_import_callback_setval_registry_value_t)
1264 : &import_create_val,
1265 : },
1266 : .setval_type = REGISTRY_VALUE,
1267 : .data = &import_ctx
1268 : };
1269 0 : struct reg_parse_callback *parse_callback;
1270 2 : int ret = -1;
1271 0 : bool precheck_ok;
1272 :
1273 2 : precheck_ok = import_precheck(precheck_fname, parse_options);
1274 2 : if (!precheck_ok) {
1275 0 : goto done;
1276 : }
1277 :
1278 2 : parse_callback = reg_import_adapter(frame, import_callback);
1279 2 : if (parse_callback == NULL) {
1280 0 : d_printf("talloc failed\n");
1281 0 : goto done;
1282 : }
1283 :
1284 2 : ret = reg_parse_file(import_fname, parse_callback, parse_options);
1285 :
1286 2 : done:
1287 2 : talloc_free(frame);
1288 2 : return ret;
1289 : }
1290 :
1291 2 : static int net_registry_import(struct net_context *c, int argc,
1292 : const char **argv)
1293 : {
1294 2 : const char *parse_options = (argc > 1) ? argv[1] : NULL;
1295 2 : int ret = -1;
1296 0 : WERROR werr;
1297 :
1298 2 : if (argc < 1 || argc > 2 || c->display_usage) {
1299 0 : d_printf("%s\n%s",
1300 : _("Usage:"),
1301 : _("net registry import <reg> [options]\n"));
1302 0 : d_printf("%s\n%s",
1303 : _("Example:"),
1304 : _("net registry import file.reg enc=CP1252\n"));
1305 0 : return -1;
1306 : }
1307 :
1308 2 : werr = regdb_open();
1309 2 : if (!W_ERROR_IS_OK(werr)) {
1310 0 : d_printf("Failed to open regdb: %s\n", win_errstr(werr));
1311 0 : return -1;
1312 : }
1313 :
1314 2 : werr = regdb_transaction_start();
1315 2 : if (!W_ERROR_IS_OK(werr)) {
1316 0 : d_printf("Failed to start transaction on regdb: %s\n",
1317 : win_errstr(werr));
1318 0 : goto done;
1319 : }
1320 :
1321 2 : ret = import_with_precheck_action(argv[0], c->opt_precheck,
1322 : parse_options);
1323 :
1324 2 : if (ret < 0) {
1325 0 : d_printf("Transaction canceled!\n");
1326 0 : regdb_transaction_cancel();
1327 0 : goto done;
1328 : }
1329 :
1330 2 : SMB_ASSERT(ret == 0);
1331 :
1332 2 : if (c->opt_testmode) {
1333 0 : d_printf("Testmode: not committing changes.\n");
1334 0 : regdb_transaction_cancel();
1335 0 : goto done;
1336 : }
1337 :
1338 2 : werr = regdb_transaction_commit();
1339 2 : if (!W_ERROR_IS_OK(werr)) {
1340 0 : d_printf("Failed to commit transaction on regdb: %s\n",
1341 : win_errstr(werr));
1342 0 : ret = -1;
1343 : }
1344 :
1345 2 : done:
1346 2 : regdb_close();
1347 2 : return ret;
1348 : }
1349 : /**@}*/
1350 :
1351 : /******************************************************************************/
1352 :
1353 : /**
1354 : * @defgroup net_registry_export Export
1355 : * @ingroup net_registry
1356 : * @{
1357 : */
1358 :
1359 724 : static int registry_export(TALLOC_CTX *ctx, /*const*/ struct registry_key *key,
1360 : struct reg_format *f)
1361 : {
1362 724 : int ret=-1;
1363 0 : WERROR werr;
1364 0 : uint32_t count;
1365 :
1366 724 : struct registry_value *valvalue = NULL;
1367 724 : char *valname = NULL;
1368 :
1369 724 : char *subkey_name = NULL;
1370 724 : NTTIME modtime = 0;
1371 :
1372 724 : reg_format_registry_key(f, key, false);
1373 :
1374 : /* print values */
1375 724 : for (count = 0;
1376 2920 : werr = reg_enumvalue(ctx, key, count, &valname, &valvalue),
1377 2920 : W_ERROR_IS_OK(werr);
1378 2196 : count++)
1379 : {
1380 2196 : reg_format_registry_value(f, valname, valvalue);
1381 : }
1382 724 : if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) {
1383 0 : d_fprintf(stderr, _("reg_enumvalue failed: %s\n"),
1384 : win_errstr(werr));
1385 0 : goto done;
1386 : }
1387 :
1388 : /* recurse on subkeys */
1389 724 : for (count = 0;
1390 1438 : werr = reg_enumkey(ctx, key, count, &subkey_name, &modtime),
1391 1438 : W_ERROR_IS_OK(werr);
1392 714 : count++)
1393 : {
1394 714 : struct registry_key *subkey = NULL;
1395 :
1396 714 : werr = reg_openkey(ctx, key, subkey_name, REG_KEY_READ,
1397 : &subkey);
1398 714 : if (!W_ERROR_IS_OK(werr)) {
1399 0 : d_fprintf(stderr, _("reg_openkey failed: %s\n"),
1400 : win_errstr(werr));
1401 0 : goto done;
1402 : }
1403 :
1404 714 : registry_export(ctx, subkey, f);
1405 714 : TALLOC_FREE(subkey);
1406 : }
1407 724 : if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) {
1408 0 : d_fprintf(stderr, _("reg_enumkey failed: %s\n"),
1409 : win_errstr(werr));
1410 0 : goto done;
1411 : }
1412 724 : ret = 0;
1413 724 : done:
1414 724 : return ret;
1415 : }
1416 :
1417 10 : static int net_registry_export(struct net_context *c, int argc,
1418 : const char **argv)
1419 : {
1420 10 : int ret=-1;
1421 0 : WERROR werr;
1422 10 : struct registry_key *key = NULL;
1423 10 : TALLOC_CTX *ctx = talloc_stackframe();
1424 10 : struct reg_format *f=NULL;
1425 :
1426 10 : if (argc < 2 || argc > 3 || c->display_usage) {
1427 0 : d_printf("%s\n%s",
1428 : _("Usage:"),
1429 : _("net registry export <path> <file> [opt]\n"));
1430 0 : d_printf("%s\n%s",
1431 : _("Example:"),
1432 : _("net registry export 'HKLM\\Software\\Samba' "
1433 : "samba.reg regedit5\n"));
1434 0 : goto done;
1435 : }
1436 :
1437 10 : werr = open_key(ctx, argv[0], REG_KEY_READ, &key);
1438 10 : if (!W_ERROR_IS_OK(werr)) {
1439 0 : d_fprintf(stderr, _("open_key failed: %s\n"), win_errstr(werr));
1440 0 : goto done;
1441 : }
1442 :
1443 10 : f = reg_format_file(ctx, argv[1], (argc > 2) ? argv[2] : NULL);
1444 10 : if (f == NULL) {
1445 0 : d_fprintf(stderr, _("open file failed: %s\n"), strerror(errno));
1446 0 : goto done;
1447 : }
1448 :
1449 10 : ret = registry_export(ctx, key, f);
1450 :
1451 10 : done:
1452 10 : TALLOC_FREE(ctx);
1453 10 : return ret;
1454 : }
1455 : /**@}*/
1456 :
1457 : /******************************************************************************/
1458 : /**
1459 : * @defgroup net_registry_convert Convert
1460 : * @ingroup net_registry
1461 : * @{
1462 : */
1463 :
1464 0 : static int net_registry_convert(struct net_context *c, int argc,
1465 : const char **argv)
1466 : {
1467 0 : int ret;
1468 0 : TALLOC_CTX *mem_ctx;
1469 0 : const char *in_opt = NULL;
1470 0 : const char *out_opt = NULL;
1471 :
1472 0 : if (argc < 2 || argc > 4|| c->display_usage) {
1473 0 : d_printf("%s\n%s",
1474 : _("Usage:"),
1475 : _("net registry convert <in> <out> [in_opt] [out_opt]\n"
1476 : "net registry convert <in> <out> [out_opt]\n"));
1477 0 : d_printf("%s\n%s",
1478 : _("Example:"),
1479 : _("net registry convert in.reg out.reg regedit4,enc=CP1252\n"));
1480 0 : return -1;
1481 : }
1482 :
1483 0 : mem_ctx = talloc_stackframe();
1484 :
1485 0 : switch (argc ) {
1486 0 : case 2:
1487 0 : break;
1488 0 : case 3:
1489 0 : out_opt = argv[2];
1490 0 : break;
1491 0 : case 4:
1492 0 : out_opt = argv[3];
1493 0 : in_opt = argv[2];
1494 0 : break;
1495 0 : default:
1496 0 : assert(false);
1497 : }
1498 :
1499 :
1500 0 : ret = reg_parse_file(argv[0], (struct reg_parse_callback*)
1501 0 : reg_format_file(mem_ctx, argv[1], out_opt),
1502 : in_opt);
1503 :
1504 0 : talloc_free(mem_ctx);
1505 :
1506 0 : return ret;
1507 : }
1508 : /**@}*/
1509 :
1510 28 : static int net_registry_check(struct net_context *c, int argc,
1511 : const char **argv)
1512 : {
1513 0 : char *dbfile;
1514 0 : struct check_options opts;
1515 0 : int ret;
1516 :
1517 28 : if (argc > 1|| c->display_usage) {
1518 0 : d_printf("%s\n%s",
1519 : _("Usage:"),
1520 : _("net registry check [-vraTfl] [-o <ODB>] [--wipe] [<TDB>]\n"
1521 : " Check a registry database.\n"
1522 : " -v|--verbose\t be verbose\n"
1523 : " -r|--repair\t\t interactive repair mode\n"
1524 : " -a|--auto\t\t noninteractive repair mode\n"
1525 : " -T|--test\t\t dry run\n"
1526 : " -f|--force\t\t force\n"
1527 : " -l|--lock\t\t lock <TDB> while doing the check\n"
1528 : " -o|--output=<ODB>\t output database\n"
1529 : " --reg-version=n\t assume database format version {n|1,2,3}\n"
1530 : " --wipe\t\t create a new database from scratch\n"
1531 : " --db=<TDB>\t\t registry database to open\n"));
1532 0 : return c->display_usage ? 0 : -1;
1533 : }
1534 :
1535 28 : if (c->opt_db != NULL) {
1536 0 : dbfile = talloc_strdup(talloc_tos(), c->opt_db);
1537 28 : } else if (argc > 0) {
1538 20 : dbfile = talloc_strdup(talloc_tos(), argv[0]);
1539 : } else {
1540 8 : dbfile = state_path(talloc_tos(), "registry.tdb");
1541 : }
1542 28 : if (dbfile == NULL) {
1543 0 : return -1;
1544 : }
1545 :
1546 28 : opts = (struct check_options) {
1547 28 : .lock = c->opt_lock || c->opt_long_list_entries,
1548 28 : .test = c->opt_testmode,
1549 28 : .automatic = c->opt_auto,
1550 28 : .verbose = c->opt_verbose,
1551 28 : .force = c->opt_force,
1552 28 : .repair = c->opt_repair || c->opt_reboot,
1553 28 : .version = c->opt_reg_version,
1554 28 : .output = c->opt_output,
1555 28 : .wipe = c->opt_wipe,
1556 28 : .implicit_db = (c->opt_db == NULL) && (argc == 0),
1557 : };
1558 :
1559 28 : ret = net_registry_check_db(dbfile, &opts);
1560 28 : talloc_free(dbfile);
1561 28 : return ret;
1562 : }
1563 :
1564 :
1565 : /******************************************************************************/
1566 :
1567 158 : int net_registry(struct net_context *c, int argc, const char **argv)
1568 : {
1569 158 : int ret = -1;
1570 :
1571 158 : struct functable func[] = {
1572 : {
1573 : "enumerate",
1574 : net_registry_enumerate,
1575 : NET_TRANSPORT_LOCAL,
1576 : N_("Enumerate registry keys and values"),
1577 : N_("net registry enumerate\n"
1578 : " Enumerate registry keys and values")
1579 : },
1580 : {
1581 : "enumerate_recursive",
1582 : net_registry_enumerate_recursive,
1583 : NET_TRANSPORT_LOCAL,
1584 : N_("Enumerate registry keys and values"),
1585 : N_("net registry enumerate_recursive\n"
1586 : " Enumerate registry keys and values")
1587 : },
1588 : {
1589 : "createkey",
1590 : net_registry_createkey,
1591 : NET_TRANSPORT_LOCAL,
1592 : N_("Create a new registry key"),
1593 : N_("net registry createkey\n"
1594 : " Create a new registry key")
1595 : },
1596 : {
1597 : "deletekey",
1598 : net_registry_deletekey,
1599 : NET_TRANSPORT_LOCAL,
1600 : N_("Delete a registry key"),
1601 : N_("net registry deletekey\n"
1602 : " Delete a registry key")
1603 : },
1604 : {
1605 : "deletekey_recursive",
1606 : net_registry_deletekey_recursive,
1607 : NET_TRANSPORT_LOCAL,
1608 : N_("Delete a registry key with subkeys"),
1609 : N_("net registry deletekey_recursive\n"
1610 : " Delete a registry key with subkeys")
1611 : },
1612 : {
1613 : "getvalue",
1614 : net_registry_getvalue,
1615 : NET_TRANSPORT_LOCAL,
1616 : N_("Print a registry value"),
1617 : N_("net registry getvalue\n"
1618 : " Print a registry value")
1619 : },
1620 : {
1621 : "getvalueraw",
1622 : net_registry_getvalueraw,
1623 : NET_TRANSPORT_LOCAL,
1624 : N_("Print a registry value (raw format)"),
1625 : N_("net registry getvalueraw\n"
1626 : " Print a registry value (raw format)")
1627 : },
1628 : {
1629 : "getvaluesraw",
1630 : net_registry_getvaluesraw,
1631 : NET_TRANSPORT_LOCAL,
1632 : "Print all values of a key in raw format",
1633 : "net registry getvaluesraw <key>\n"
1634 : " Print a registry value (raw format)"
1635 : },
1636 : {
1637 : "setvalue",
1638 : net_registry_setvalue,
1639 : NET_TRANSPORT_LOCAL,
1640 : N_("Set a new registry value"),
1641 : N_("net registry setvalue\n"
1642 : " Set a new registry value")
1643 : },
1644 : {
1645 : "increment",
1646 : net_registry_increment,
1647 : NET_TRANSPORT_LOCAL,
1648 : N_("Increment a DWORD registry value under a lock"),
1649 : N_("net registry increment\n"
1650 : " Increment a DWORD registry value under a lock")
1651 : },
1652 : {
1653 : "deletevalue",
1654 : net_registry_deletevalue,
1655 : NET_TRANSPORT_LOCAL,
1656 : N_("Delete a registry value"),
1657 : N_("net registry deletevalue\n"
1658 : " Delete a registry value")
1659 : },
1660 : {
1661 : "getsd",
1662 : net_registry_getsd,
1663 : NET_TRANSPORT_LOCAL,
1664 : N_("Get security descriptor"),
1665 : N_("net registry getsd\n"
1666 : " Get security descriptor")
1667 : },
1668 : {
1669 : "getsd_sddl",
1670 : net_registry_getsd_sddl,
1671 : NET_TRANSPORT_LOCAL,
1672 : N_("Get security descriptor in sddl format"),
1673 : N_("net registry getsd_sddl\n"
1674 : " Get security descriptor in sddl format")
1675 : },
1676 : {
1677 : "setsd_sddl",
1678 : net_registry_setsd_sddl,
1679 : NET_TRANSPORT_LOCAL,
1680 : N_("Set security descriptor from sddl format string"),
1681 : N_("net registry setsd_sddl\n"
1682 : " Set security descriptor from sddl format string")
1683 : },
1684 : {
1685 : "import",
1686 : net_registry_import,
1687 : NET_TRANSPORT_LOCAL,
1688 : N_("Import .reg file"),
1689 : N_("net registry import\n"
1690 : " Import .reg file")
1691 : },
1692 : {
1693 : "export",
1694 : net_registry_export,
1695 : NET_TRANSPORT_LOCAL,
1696 : N_("Export .reg file"),
1697 : N_("net registry export\n"
1698 : " Export .reg file")
1699 : },
1700 : {
1701 : "convert",
1702 : net_registry_convert,
1703 : NET_TRANSPORT_LOCAL,
1704 : N_("Convert .reg file"),
1705 : N_("net registry convert\n"
1706 : " Convert .reg file")
1707 : },
1708 : {
1709 : "check",
1710 : net_registry_check,
1711 : NET_TRANSPORT_LOCAL,
1712 : N_("Check a registry database"),
1713 : N_("net registry check\n"
1714 : " Check a registry database")
1715 : },
1716 : { NULL, NULL, 0, NULL, NULL }
1717 : };
1718 :
1719 158 : if (!c->display_usage
1720 158 : && argc > 0
1721 158 : && (strcasecmp_m(argv[0], "convert") != 0)
1722 158 : && (strcasecmp_m(argv[0], "check") != 0))
1723 : {
1724 130 : if (!W_ERROR_IS_OK(registry_init_basic())) {
1725 0 : return -1;
1726 : }
1727 : }
1728 :
1729 158 : ret = net_run_function(c, argc, argv, "net registry", func);
1730 :
1731 158 : return ret;
1732 : }
|