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