Line data Source code
1 : /*
2 : Samba Unix/Linux SMB client library
3 : Distributed SMB/CIFS Server Management Utility
4 :
5 : Copyright (C) Gerald (Jerry) Carter 2005-2006
6 :
7 : This program is free software; you can redistribute it and/or modify
8 : it under the terms of the GNU General Public License as published by
9 : the Free Software Foundation; either version 3 of the License, or
10 : (at your option) any later version.
11 :
12 : This program is distributed in the hope that it will be useful,
13 : but WITHOUT ANY WARRANTY; without even the implied warranty of
14 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 : GNU General Public License for more details.
16 :
17 : You should have received a copy of the GNU General Public License
18 : along with this program. If not, see <http://www.gnu.org/licenses/>. */
19 :
20 : #include "includes.h"
21 : #include "system/filesys.h"
22 : #include "rpc_client/rpc_client.h"
23 : #include "registry.h"
24 : #include "utils/net.h"
25 : #include "utils/net_registry_util.h"
26 : #include "registry/regfio.h"
27 : #include "../librpc/gen_ndr/ndr_winreg_c.h"
28 : #include "../librpc/gen_ndr/ndr_security.h"
29 : #include "registry/reg_format.h"
30 : #include "registry/reg_import.h"
31 : #include <assert.h>
32 : #include "../libcli/security/display_sec.h"
33 : #include "../libcli/registry/util_reg.h"
34 : #include "client.h"
35 : #include "lib/util/smb_strtox.h"
36 :
37 :
38 : /*******************************************************************
39 : connect to a registry hive root (open a registry policy)
40 : *******************************************************************/
41 :
42 136 : static NTSTATUS dcerpc_winreg_Connect(struct dcerpc_binding_handle *b, TALLOC_CTX *mem_ctx,
43 : uint32_t reg_type, uint32_t access_mask,
44 : struct policy_handle *reg_hnd, WERROR *werr)
45 : {
46 136 : ZERO_STRUCTP(reg_hnd);
47 :
48 136 : switch (reg_type)
49 : {
50 0 : case HKEY_CLASSES_ROOT:
51 0 : return dcerpc_winreg_OpenHKCR(b, mem_ctx, NULL,
52 : access_mask, reg_hnd, werr);
53 :
54 136 : case HKEY_LOCAL_MACHINE:
55 136 : return dcerpc_winreg_OpenHKLM(b, mem_ctx, NULL,
56 : access_mask, reg_hnd, werr);
57 :
58 0 : case HKEY_USERS:
59 0 : return dcerpc_winreg_OpenHKU(b, mem_ctx, NULL,
60 : access_mask, reg_hnd, werr);
61 :
62 0 : case HKEY_CURRENT_USER:
63 0 : return dcerpc_winreg_OpenHKCU(b, mem_ctx, NULL,
64 : access_mask, reg_hnd, werr);
65 :
66 0 : case HKEY_PERFORMANCE_DATA:
67 0 : return dcerpc_winreg_OpenHKPD(b, mem_ctx, NULL,
68 : access_mask, reg_hnd, werr);
69 :
70 0 : default:
71 : /* fall through to end of function */
72 0 : break;
73 : }
74 :
75 0 : return NT_STATUS_INVALID_PARAMETER;
76 : }
77 :
78 138 : static bool reg_hive_key(TALLOC_CTX *ctx, const char *fullname,
79 : uint32_t *reg_type, const char **key_name)
80 : {
81 0 : WERROR werr;
82 138 : char *hivename = NULL;
83 138 : char *tmp_keyname = NULL;
84 138 : bool ret = false;
85 138 : TALLOC_CTX *tmp_ctx = talloc_stackframe();
86 :
87 138 : werr = split_hive_key(tmp_ctx, fullname, &hivename, &tmp_keyname);
88 138 : if (!W_ERROR_IS_OK(werr)) {
89 0 : goto done;
90 : }
91 :
92 138 : *key_name = talloc_strdup(ctx, tmp_keyname);
93 138 : if (*key_name == NULL) {
94 0 : goto done;
95 : }
96 :
97 158 : if (strequal(hivename, "HKLM") ||
98 20 : strequal(hivename, "HKEY_LOCAL_MACHINE"))
99 : {
100 136 : (*reg_type) = HKEY_LOCAL_MACHINE;
101 4 : } else if (strequal(hivename, "HKCR") ||
102 2 : strequal(hivename, "HKEY_CLASSES_ROOT"))
103 : {
104 0 : (*reg_type) = HKEY_CLASSES_ROOT;
105 4 : } else if (strequal(hivename, "HKU") ||
106 2 : strequal(hivename, "HKEY_USERS"))
107 : {
108 0 : (*reg_type) = HKEY_USERS;
109 4 : } else if (strequal(hivename, "HKCU") ||
110 2 : strequal(hivename, "HKEY_CURRENT_USER"))
111 : {
112 0 : (*reg_type) = HKEY_CURRENT_USER;
113 4 : } else if (strequal(hivename, "HKPD") ||
114 2 : strequal(hivename, "HKEY_PERFORMANCE_DATA"))
115 : {
116 0 : (*reg_type) = HKEY_PERFORMANCE_DATA;
117 : } else {
118 2 : DEBUG(10,("reg_hive_key: unrecognised hive key %s\n",
119 : fullname));
120 2 : goto done;
121 : }
122 :
123 136 : ret = true;
124 :
125 138 : done:
126 138 : TALLOC_FREE(tmp_ctx);
127 138 : return ret;
128 : }
129 :
130 74 : static NTSTATUS registry_openkey(TALLOC_CTX *mem_ctx,
131 : struct rpc_pipe_client *pipe_hnd,
132 : const char *name, uint32_t access_mask,
133 : struct policy_handle *hive_hnd,
134 : struct policy_handle *key_hnd)
135 : {
136 0 : uint32_t hive;
137 0 : NTSTATUS status;
138 0 : WERROR werr;
139 0 : struct winreg_String key;
140 74 : struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
141 :
142 74 : ZERO_STRUCT(key);
143 :
144 74 : if (!reg_hive_key(mem_ctx, name, &hive, &key.name)) {
145 2 : return NT_STATUS_INVALID_PARAMETER;
146 : }
147 :
148 72 : status = dcerpc_winreg_Connect(b, mem_ctx, hive, access_mask,
149 : hive_hnd, &werr);
150 72 : if (!(NT_STATUS_IS_OK(status))) {
151 0 : return status;
152 : }
153 72 : if (!W_ERROR_IS_OK(werr)) {
154 0 : return werror_to_ntstatus(werr);
155 : }
156 :
157 72 : status = dcerpc_winreg_OpenKey(b, mem_ctx, hive_hnd, key, 0,
158 : access_mask, key_hnd, &werr);
159 72 : if (!(NT_STATUS_IS_OK(status))) {
160 0 : dcerpc_winreg_CloseKey(b, mem_ctx, hive_hnd, &werr);
161 0 : return status;
162 : }
163 72 : if (!(W_ERROR_IS_OK(werr))) {
164 0 : WERROR _werr;
165 8 : dcerpc_winreg_CloseKey(b, mem_ctx, hive_hnd, &_werr);
166 8 : return werror_to_ntstatus(werr);
167 : }
168 :
169 64 : return NT_STATUS_OK;
170 : }
171 :
172 54 : static NTSTATUS registry_enumkeys(TALLOC_CTX *ctx,
173 : struct rpc_pipe_client *pipe_hnd,
174 : struct policy_handle *key_hnd,
175 : uint32_t *pnum_keys, char ***pnames,
176 : char ***pclasses, NTTIME ***pmodtimes)
177 : {
178 0 : TALLOC_CTX *mem_ctx;
179 0 : NTSTATUS status;
180 0 : WERROR werr;
181 0 : uint32_t num_subkeys, max_subkeylen, max_classlen;
182 0 : uint32_t num_values, max_valnamelen, max_valbufsize;
183 0 : uint32_t i;
184 0 : NTTIME last_changed_time;
185 0 : uint32_t secdescsize;
186 0 : struct winreg_String classname;
187 0 : char **names, **classes;
188 0 : NTTIME **modtimes;
189 54 : struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
190 :
191 54 : if (!(mem_ctx = talloc_new(ctx))) {
192 0 : return NT_STATUS_NO_MEMORY;
193 : }
194 :
195 54 : ZERO_STRUCT(classname);
196 54 : status = dcerpc_winreg_QueryInfoKey(
197 : b, mem_ctx, key_hnd, &classname, &num_subkeys,
198 : &max_subkeylen, &max_classlen, &num_values, &max_valnamelen,
199 : &max_valbufsize, &secdescsize, &last_changed_time, &werr);
200 :
201 54 : if (!NT_STATUS_IS_OK(status)) {
202 0 : goto error;
203 : }
204 54 : if (!W_ERROR_IS_OK(werr)) {
205 0 : status = werror_to_ntstatus(werr);
206 0 : goto error;
207 : }
208 :
209 54 : if (num_subkeys == 0) {
210 24 : *pnum_keys = 0;
211 24 : TALLOC_FREE(mem_ctx);
212 24 : return NT_STATUS_OK;
213 : }
214 :
215 30 : if ((!(names = talloc_zero_array(mem_ctx, char *, num_subkeys))) ||
216 30 : (!(classes = talloc_zero_array(mem_ctx, char *, num_subkeys))) ||
217 30 : (!(modtimes = talloc_zero_array(mem_ctx, NTTIME *,
218 : num_subkeys)))) {
219 0 : status = NT_STATUS_NO_MEMORY;
220 0 : goto error;
221 : }
222 :
223 100 : for (i=0; i<num_subkeys; i++) {
224 0 : char c, n;
225 0 : struct winreg_StringBuf class_buf;
226 0 : struct winreg_StringBuf name_buf;
227 0 : NTTIME modtime;
228 :
229 70 : c = '\0';
230 70 : class_buf.name = &c;
231 70 : class_buf.size = max_classlen+2;
232 :
233 70 : n = '\0';
234 70 : name_buf.name = &n;
235 70 : name_buf.size = max_subkeylen+2;
236 :
237 70 : ZERO_STRUCT(modtime);
238 :
239 70 : status = dcerpc_winreg_EnumKey(b, mem_ctx, key_hnd,
240 : i, &name_buf, &class_buf,
241 : &modtime, &werr);
242 70 : if (!NT_STATUS_IS_OK(status)) {
243 0 : goto error;
244 : }
245 70 : if (W_ERROR_EQUAL(werr,
246 : WERR_NO_MORE_ITEMS) ) {
247 0 : status = NT_STATUS_OK;
248 0 : break;
249 : }
250 70 : if (!W_ERROR_IS_OK(werr)) {
251 0 : status = werror_to_ntstatus(werr);
252 0 : goto error;
253 : }
254 :
255 70 : classes[i] = NULL;
256 :
257 70 : if (class_buf.name &&
258 70 : (!(classes[i] = talloc_strdup(classes, class_buf.name)))) {
259 0 : status = NT_STATUS_NO_MEMORY;
260 0 : goto error;
261 : }
262 :
263 70 : if (!(names[i] = talloc_strdup(names, name_buf.name))) {
264 0 : status = NT_STATUS_NO_MEMORY;
265 0 : goto error;
266 : }
267 :
268 70 : if ((!(modtimes[i] = (NTTIME *)talloc_memdup(
269 : modtimes, &modtime, sizeof(modtime))))) {
270 0 : status = NT_STATUS_NO_MEMORY;
271 0 : goto error;
272 : }
273 : }
274 :
275 30 : *pnum_keys = num_subkeys;
276 :
277 30 : if (pnames) {
278 30 : *pnames = talloc_move(ctx, &names);
279 : }
280 30 : if (pclasses) {
281 30 : *pclasses = talloc_move(ctx, &classes);
282 : }
283 30 : if (pmodtimes) {
284 30 : *pmodtimes = talloc_move(ctx, &modtimes);
285 : }
286 :
287 30 : status = NT_STATUS_OK;
288 :
289 30 : error:
290 30 : TALLOC_FREE(mem_ctx);
291 30 : return status;
292 : }
293 :
294 38 : static NTSTATUS registry_enumvalues(TALLOC_CTX *ctx,
295 : struct rpc_pipe_client *pipe_hnd,
296 : struct policy_handle *key_hnd,
297 : uint32_t *pnum_values, char ***pvalnames,
298 : struct registry_value ***pvalues)
299 : {
300 0 : TALLOC_CTX *mem_ctx;
301 0 : NTSTATUS status;
302 0 : WERROR werr;
303 0 : uint32_t num_subkeys, max_subkeylen, max_classlen;
304 0 : uint32_t num_values, max_valnamelen, max_valbufsize;
305 0 : uint32_t i;
306 0 : NTTIME last_changed_time;
307 0 : uint32_t secdescsize;
308 0 : struct winreg_String classname;
309 0 : struct registry_value **values;
310 0 : char **names;
311 38 : struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
312 :
313 38 : if (!(mem_ctx = talloc_new(ctx))) {
314 0 : return NT_STATUS_NO_MEMORY;
315 : }
316 :
317 38 : ZERO_STRUCT(classname);
318 38 : status = dcerpc_winreg_QueryInfoKey(
319 : b, mem_ctx, key_hnd, &classname, &num_subkeys,
320 : &max_subkeylen, &max_classlen, &num_values, &max_valnamelen,
321 : &max_valbufsize, &secdescsize, &last_changed_time, &werr);
322 :
323 38 : if (!NT_STATUS_IS_OK(status)) {
324 0 : goto error;
325 : }
326 38 : if (!W_ERROR_IS_OK(werr)) {
327 0 : status = werror_to_ntstatus(werr);
328 0 : goto error;
329 : }
330 :
331 38 : if (num_values == 0) {
332 34 : *pnum_values = 0;
333 34 : TALLOC_FREE(mem_ctx);
334 34 : return NT_STATUS_OK;
335 : }
336 :
337 4 : if ((!(names = talloc_array(mem_ctx, char *, num_values))) ||
338 4 : (!(values = talloc_array(mem_ctx, struct registry_value *,
339 : num_values)))) {
340 0 : status = NT_STATUS_NO_MEMORY;
341 0 : goto error;
342 : }
343 :
344 8 : for (i=0; i<num_values; i++) {
345 4 : enum winreg_Type type = REG_NONE;
346 4 : uint8_t *data = NULL;
347 0 : uint32_t data_size;
348 0 : uint32_t value_length;
349 :
350 0 : char n;
351 0 : struct winreg_ValNameBuf name_buf;
352 0 : WERROR err;
353 :
354 4 : n = '\0';
355 4 : name_buf.name = &n;
356 4 : name_buf.size = max_valnamelen + 2;
357 :
358 4 : data_size = max_valbufsize;
359 4 : data = (uint8_t *)TALLOC(mem_ctx, data_size);
360 4 : value_length = 0;
361 :
362 4 : status = dcerpc_winreg_EnumValue(b, mem_ctx, key_hnd,
363 : i, &name_buf, &type,
364 : data, &data_size,
365 : &value_length, &err);
366 4 : if (!(NT_STATUS_IS_OK(status))) {
367 0 : goto error;
368 : }
369 :
370 4 : if ( W_ERROR_EQUAL(err,
371 : WERR_NO_MORE_ITEMS) ) {
372 0 : status = NT_STATUS_OK;
373 0 : break;
374 : }
375 :
376 4 : if (!W_ERROR_IS_OK(err)) {
377 0 : status = werror_to_ntstatus(err);
378 0 : goto error;
379 : }
380 :
381 4 : if (name_buf.name == NULL) {
382 0 : status = NT_STATUS_INVALID_PARAMETER;
383 0 : goto error;
384 : }
385 :
386 4 : if (!(names[i] = talloc_strdup(names, name_buf.name))) {
387 0 : status = NT_STATUS_NO_MEMORY;
388 0 : goto error;
389 : }
390 :
391 4 : values[i] = talloc_zero(values, struct registry_value);
392 4 : if (values[i] == NULL) {
393 0 : status = NT_STATUS_NO_MEMORY;
394 0 : goto error;
395 : }
396 :
397 4 : values[i]->type = type;
398 4 : values[i]->data = data_blob_talloc(values[i], data, data_size);
399 : }
400 :
401 4 : *pnum_values = num_values;
402 :
403 4 : if (pvalnames) {
404 4 : *pvalnames = talloc_move(ctx, &names);
405 : }
406 4 : if (pvalues) {
407 4 : *pvalues = talloc_move(ctx, &values);
408 : }
409 :
410 4 : status = NT_STATUS_OK;
411 :
412 4 : error:
413 4 : TALLOC_FREE(mem_ctx);
414 4 : return status;
415 : }
416 :
417 16 : static NTSTATUS registry_enumvalues2(TALLOC_CTX *ctx,
418 : struct rpc_pipe_client *pipe_hnd,
419 : struct policy_handle *key_hnd,
420 : uint32_t *pnum_values, char ***pvalnames,
421 : struct regval_blob ***pvalues)
422 : {
423 0 : TALLOC_CTX *mem_ctx;
424 0 : NTSTATUS status;
425 0 : WERROR werr;
426 0 : uint32_t num_subkeys, max_subkeylen, max_classlen;
427 0 : uint32_t num_values, max_valnamelen, max_valbufsize;
428 0 : uint32_t i;
429 0 : NTTIME last_changed_time;
430 0 : uint32_t secdescsize;
431 0 : struct winreg_String classname;
432 0 : struct regval_blob **values;
433 0 : char **names;
434 16 : struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
435 :
436 16 : if (!(mem_ctx = talloc_new(ctx))) {
437 0 : return NT_STATUS_NO_MEMORY;
438 : }
439 :
440 16 : ZERO_STRUCT(classname);
441 16 : status = dcerpc_winreg_QueryInfoKey(
442 : b, mem_ctx, key_hnd, &classname, &num_subkeys,
443 : &max_subkeylen, &max_classlen, &num_values, &max_valnamelen,
444 : &max_valbufsize, &secdescsize, &last_changed_time, &werr);
445 :
446 16 : if (!NT_STATUS_IS_OK(status)) {
447 0 : goto error;
448 : }
449 16 : if (!W_ERROR_IS_OK(werr)) {
450 0 : status = werror_to_ntstatus(werr);
451 0 : goto error;
452 : }
453 :
454 16 : if (num_values == 0) {
455 12 : *pnum_values = 0;
456 12 : TALLOC_FREE(mem_ctx);
457 12 : return NT_STATUS_OK;
458 : }
459 :
460 4 : if ((!(names = talloc_array(mem_ctx, char *, num_values))) ||
461 4 : (!(values = talloc_array(mem_ctx, struct regval_blob *,
462 : num_values)))) {
463 0 : status = NT_STATUS_NO_MEMORY;
464 0 : goto error;
465 : }
466 :
467 96 : for (i=0; i<num_values; i++) {
468 92 : enum winreg_Type type = REG_NONE;
469 92 : uint8_t *data = NULL;
470 0 : uint32_t data_size;
471 0 : uint32_t value_length;
472 :
473 0 : char n;
474 0 : struct winreg_ValNameBuf name_buf;
475 0 : WERROR err;
476 :
477 92 : n = '\0';
478 92 : name_buf.name = &n;
479 92 : name_buf.size = max_valnamelen + 2;
480 :
481 92 : data_size = max_valbufsize;
482 92 : data = (uint8_t *)TALLOC(mem_ctx, data_size);
483 92 : value_length = 0;
484 :
485 92 : status = dcerpc_winreg_EnumValue(b, mem_ctx, key_hnd,
486 : i, &name_buf, &type,
487 : data, &data_size,
488 : &value_length, &err);
489 92 : if (!(NT_STATUS_IS_OK(status))) {
490 0 : goto error;
491 : }
492 :
493 92 : if ( W_ERROR_EQUAL(err, WERR_NO_MORE_ITEMS) ) {
494 0 : status = NT_STATUS_OK;
495 0 : break;
496 : }
497 :
498 92 : if (!W_ERROR_IS_OK(err)) {
499 0 : status = werror_to_ntstatus(err);
500 0 : goto error;
501 : }
502 :
503 92 : if (name_buf.name == NULL) {
504 0 : status = NT_STATUS_INVALID_PARAMETER;
505 0 : goto error;
506 : }
507 :
508 92 : if (!(names[i] = talloc_strdup(names, name_buf.name))) {
509 0 : status = NT_STATUS_NO_MEMORY;
510 0 : goto error;
511 : }
512 :
513 92 : assert(value_length<=data_size); /*??? */
514 :
515 92 : values[i] = regval_compose(values,
516 : name_buf.name,
517 : type,
518 : data, value_length);
519 92 : if (!values[i]) {
520 0 : status = NT_STATUS_NO_MEMORY;
521 0 : goto error;
522 : }
523 : }
524 :
525 4 : *pnum_values = num_values;
526 :
527 4 : if (pvalnames) {
528 4 : *pvalnames = talloc_move(ctx, &names);
529 : }
530 4 : if (pvalues) {
531 4 : *pvalues = talloc_move(ctx, &values);
532 : }
533 :
534 4 : status = NT_STATUS_OK;
535 :
536 4 : error:
537 4 : TALLOC_FREE(mem_ctx);
538 4 : return status;
539 : }
540 :
541 0 : static NTSTATUS registry_getsd(TALLOC_CTX *mem_ctx,
542 : struct dcerpc_binding_handle *b,
543 : struct policy_handle *key_hnd,
544 : uint32_t sec_info,
545 : struct KeySecurityData *sd,
546 : WERROR *werr)
547 : {
548 0 : return dcerpc_winreg_GetKeySecurity(b, mem_ctx, key_hnd,
549 : sec_info, sd, werr);
550 : }
551 :
552 :
553 8 : static NTSTATUS registry_setvalue(TALLOC_CTX *mem_ctx,
554 : struct rpc_pipe_client *pipe_hnd,
555 : struct policy_handle *key_hnd,
556 : const char *name,
557 : const struct registry_value *value)
558 : {
559 0 : struct winreg_String name_string;
560 0 : NTSTATUS result;
561 0 : WERROR werr;
562 8 : struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
563 :
564 8 : ZERO_STRUCT(name_string);
565 :
566 8 : name_string.name = name;
567 8 : result = dcerpc_winreg_SetValue(b, mem_ctx, key_hnd,
568 8 : name_string, value->type,
569 8 : value->data.data, value->data.length, &werr);
570 8 : if (!NT_STATUS_IS_OK(result)) {
571 0 : return result;
572 : }
573 :
574 8 : return werror_to_ntstatus(werr);
575 : }
576 :
577 8 : static NTSTATUS rpc_registry_setvalue_internal(struct net_context *c,
578 : const struct dom_sid *domain_sid,
579 : const char *domain_name,
580 : struct cli_state *cli,
581 : struct rpc_pipe_client *pipe_hnd,
582 : TALLOC_CTX *mem_ctx,
583 : int argc,
584 : const char **argv )
585 : {
586 0 : struct policy_handle hive_hnd, key_hnd;
587 0 : NTSTATUS status;
588 0 : WERROR werr;
589 0 : struct registry_value value;
590 8 : struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
591 :
592 8 : status = registry_openkey(mem_ctx, pipe_hnd, argv[0],
593 : SEC_FLAG_MAXIMUM_ALLOWED,
594 : &hive_hnd, &key_hnd);
595 8 : if (!NT_STATUS_IS_OK(status)) {
596 0 : d_fprintf(stderr, _("registry_openkey failed: %s\n"),
597 : nt_errstr(status));
598 0 : return status;
599 : }
600 :
601 8 : if (!strequal(argv[2], "multi_sz") && (argc != 4)) {
602 0 : d_fprintf(stderr, _("Too many args for type %s\n"), argv[2]);
603 0 : return NT_STATUS_NOT_IMPLEMENTED;
604 : }
605 :
606 8 : if (strequal(argv[2], "dword")) {
607 2 : int error = 0;
608 0 : uint32_t v;
609 :
610 2 : v = smb_strtoul(argv[3], NULL, 10, &error, SMB_STR_STANDARD);
611 2 : if (error != 0) {
612 0 : goto error;
613 : }
614 :
615 2 : value.type = REG_DWORD;
616 2 : value.data = data_blob_talloc(mem_ctx, NULL, 4);
617 2 : SIVAL(value.data.data, 0, v);
618 : }
619 6 : else if (strequal(argv[2], "sz")) {
620 6 : value.type = REG_SZ;
621 6 : if (!push_reg_sz(mem_ctx, &value.data, argv[3])) {
622 0 : status = NT_STATUS_NO_MEMORY;
623 0 : goto error;
624 : }
625 : }
626 : else {
627 0 : d_fprintf(stderr, _("type \"%s\" not implemented\n"), argv[2]);
628 0 : status = NT_STATUS_NOT_IMPLEMENTED;
629 0 : goto error;
630 : }
631 :
632 8 : status = registry_setvalue(mem_ctx, pipe_hnd, &key_hnd,
633 8 : argv[1], &value);
634 :
635 8 : if (!NT_STATUS_IS_OK(status)) {
636 0 : d_fprintf(stderr, _("registry_setvalue failed: %s\n"),
637 : nt_errstr(status));
638 : }
639 :
640 8 : error:
641 8 : dcerpc_winreg_CloseKey(b, mem_ctx, &key_hnd, &werr);
642 8 : dcerpc_winreg_CloseKey(b, mem_ctx, &hive_hnd, &werr);
643 :
644 8 : return NT_STATUS_OK;
645 : }
646 :
647 8 : static int rpc_registry_setvalue(struct net_context *c, int argc,
648 : const char **argv )
649 : {
650 8 : if (argc < 4 || c->display_usage) {
651 0 : d_fprintf(stderr, "%s\n%s",
652 : _("Usage:"),
653 : _("net rpc registry setvalue <key> <valuename> "
654 : "<type> [<val>]+\n"));
655 0 : return -1;
656 : }
657 :
658 8 : return run_rpc_command(c, NULL, &ndr_table_winreg, 0,
659 : rpc_registry_setvalue_internal, argc, argv );
660 : }
661 :
662 8 : static NTSTATUS rpc_registry_deletevalue_internal(struct net_context *c,
663 : const struct dom_sid *domain_sid,
664 : const char *domain_name,
665 : struct cli_state *cli,
666 : struct rpc_pipe_client *pipe_hnd,
667 : TALLOC_CTX *mem_ctx,
668 : int argc,
669 : const char **argv )
670 : {
671 0 : struct policy_handle hive_hnd, key_hnd;
672 0 : NTSTATUS status;
673 0 : WERROR werr;
674 0 : struct winreg_String valuename;
675 8 : struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
676 :
677 8 : ZERO_STRUCT(valuename);
678 :
679 8 : status = registry_openkey(mem_ctx, pipe_hnd, argv[0],
680 : SEC_FLAG_MAXIMUM_ALLOWED,
681 : &hive_hnd, &key_hnd);
682 8 : if (!NT_STATUS_IS_OK(status)) {
683 0 : d_fprintf(stderr, _("registry_openkey failed: %s\n"),
684 : nt_errstr(status));
685 0 : return status;
686 : }
687 :
688 8 : valuename.name = argv[1];
689 :
690 8 : status = dcerpc_winreg_DeleteValue(b, mem_ctx, &key_hnd,
691 : valuename, &werr);
692 8 : if (!NT_STATUS_IS_OK(status)) {
693 0 : d_fprintf(stderr, _("registry_deletevalue failed: %s\n"),
694 : nt_errstr(status));
695 : }
696 8 : if (!W_ERROR_IS_OK(werr)) {
697 4 : status = werror_to_ntstatus(werr);
698 4 : d_fprintf(stderr, _("registry_deletevalue failed: %s\n"),
699 : win_errstr(werr));
700 : }
701 :
702 8 : dcerpc_winreg_CloseKey(b, mem_ctx, &key_hnd, &werr);
703 8 : dcerpc_winreg_CloseKey(b, mem_ctx, &hive_hnd, &werr);
704 :
705 8 : return status;
706 : }
707 :
708 8 : static int rpc_registry_deletevalue(struct net_context *c, int argc,
709 : const char **argv )
710 : {
711 8 : if (argc != 2 || c->display_usage) {
712 0 : d_fprintf(stderr, "%s\n%s",
713 : _("Usage:"),
714 : _("net rpc registry deletevalue <key> <valuename>\n"));
715 0 : return -1;
716 : }
717 :
718 8 : return run_rpc_command(c, NULL, &ndr_table_winreg, 0,
719 : rpc_registry_deletevalue_internal, argc, argv );
720 : }
721 :
722 6 : static NTSTATUS rpc_registry_getvalue_internal(struct net_context *c,
723 : const struct dom_sid *domain_sid,
724 : const char *domain_name,
725 : struct cli_state *cli,
726 : struct rpc_pipe_client *pipe_hnd,
727 : TALLOC_CTX *mem_ctx,
728 : bool raw,
729 : int argc,
730 : const char **argv)
731 : {
732 0 : struct policy_handle hive_hnd, key_hnd;
733 0 : NTSTATUS status;
734 0 : WERROR werr;
735 0 : struct winreg_String valuename;
736 6 : struct registry_value *value = NULL;
737 6 : enum winreg_Type type = REG_NONE;
738 6 : uint32_t data_size = 0;
739 6 : uint32_t value_length = 0;
740 6 : TALLOC_CTX *tmp_ctx = talloc_stackframe();
741 6 : struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
742 :
743 6 : ZERO_STRUCT(valuename);
744 :
745 6 : status = registry_openkey(tmp_ctx, pipe_hnd, argv[0],
746 : SEC_FLAG_MAXIMUM_ALLOWED,
747 : &hive_hnd, &key_hnd);
748 6 : if (!NT_STATUS_IS_OK(status)) {
749 0 : d_fprintf(stderr, _("registry_openkey failed: %s\n"),
750 : nt_errstr(status));
751 0 : return status;
752 : }
753 :
754 6 : valuename.name = argv[1];
755 :
756 6 : value = talloc_zero(tmp_ctx, struct registry_value);
757 6 : if (value == NULL) {
758 0 : return NT_STATUS_NO_MEMORY;
759 : }
760 :
761 : /*
762 : * call QueryValue once with data == NULL to get the
763 : * needed memory size to be allocated, then allocate
764 : * data buffer and call again.
765 : */
766 6 : status = dcerpc_winreg_QueryValue(b, tmp_ctx, &key_hnd,
767 : &valuename,
768 : &type,
769 : NULL,
770 : &data_size,
771 : &value_length,
772 : &werr);
773 :
774 6 : if (!NT_STATUS_IS_OK(status)) {
775 0 : d_fprintf(stderr, _("registry_queryvalue failed: %s\n"),
776 : nt_errstr(status));
777 0 : goto done;
778 : }
779 6 : if (!W_ERROR_IS_OK(werr)) {
780 0 : status = werror_to_ntstatus(werr);
781 0 : d_fprintf(stderr, _("registry_queryvalue failed: %s\n"),
782 : nt_errstr(status));
783 0 : goto done;
784 : }
785 :
786 6 : value->data = data_blob_talloc(tmp_ctx, NULL, data_size);
787 :
788 6 : status = dcerpc_winreg_QueryValue(b, tmp_ctx, &key_hnd,
789 : &valuename,
790 : &type,
791 : value->data.data,
792 : &data_size,
793 : &value_length,
794 : &werr);
795 :
796 6 : if (!NT_STATUS_IS_OK(status)) {
797 0 : d_fprintf(stderr, _("registry_queryvalue failed: %s\n"),
798 : nt_errstr(status));
799 0 : goto done;
800 : }
801 6 : if (!W_ERROR_IS_OK(werr)) {
802 0 : status = werror_to_ntstatus(werr);
803 0 : d_fprintf(stderr, _("registry_queryvalue failed: %s\n"),
804 : win_errstr(werr));
805 0 : goto done;
806 : }
807 :
808 :
809 6 : value->type = type;
810 :
811 6 : print_registry_value(value, raw);
812 :
813 6 : done:
814 6 : dcerpc_winreg_CloseKey(b, tmp_ctx, &key_hnd, &werr);
815 6 : dcerpc_winreg_CloseKey(b, tmp_ctx, &hive_hnd, &werr);
816 :
817 6 : TALLOC_FREE(tmp_ctx);
818 :
819 6 : return status;
820 : }
821 :
822 0 : static NTSTATUS rpc_registry_getvalue_full(struct net_context *c,
823 : const struct dom_sid *domain_sid,
824 : const char *domain_name,
825 : struct cli_state *cli,
826 : struct rpc_pipe_client *pipe_hnd,
827 : TALLOC_CTX *mem_ctx,
828 : int argc,
829 : const char **argv)
830 : {
831 0 : return rpc_registry_getvalue_internal(c, domain_sid, domain_name,
832 : cli, pipe_hnd, mem_ctx, false,
833 : argc, argv);
834 : }
835 :
836 0 : static int rpc_registry_getvalue(struct net_context *c, int argc,
837 : const char **argv)
838 : {
839 0 : if (argc != 2 || c->display_usage) {
840 0 : d_fprintf(stderr, "%s\n%s",
841 : _("Usage:"),
842 : _("net rpc registry getvalue <key> <valuename>\n"));
843 0 : return -1;
844 : }
845 :
846 0 : return run_rpc_command(c, NULL, &ndr_table_winreg, 0,
847 : rpc_registry_getvalue_full, argc, argv);
848 : }
849 :
850 6 : static NTSTATUS rpc_registry_getvalue_raw(struct net_context *c,
851 : const struct dom_sid *domain_sid,
852 : const char *domain_name,
853 : struct cli_state *cli,
854 : struct rpc_pipe_client *pipe_hnd,
855 : TALLOC_CTX *mem_ctx,
856 : int argc,
857 : const char **argv)
858 : {
859 6 : return rpc_registry_getvalue_internal(c, domain_sid, domain_name,
860 : cli, pipe_hnd, mem_ctx, true,
861 : argc, argv);
862 : }
863 :
864 6 : static int rpc_registry_getvalueraw(struct net_context *c, int argc,
865 : const char **argv)
866 : {
867 6 : if (argc != 2 || c->display_usage) {
868 0 : d_fprintf(stderr, "%s\n%s",
869 : _("Usage:"),
870 : _("net rpc registry getvalue <key> <valuename>\n"));
871 0 : return -1;
872 : }
873 :
874 6 : return run_rpc_command(c, NULL, &ndr_table_winreg, 0,
875 : rpc_registry_getvalue_raw, argc, argv);
876 : }
877 :
878 20 : static NTSTATUS rpc_registry_createkey_internal(struct net_context *c,
879 : const struct dom_sid *domain_sid,
880 : const char *domain_name,
881 : struct cli_state *cli,
882 : struct rpc_pipe_client *pipe_hnd,
883 : TALLOC_CTX *mem_ctx,
884 : int argc,
885 : const char **argv )
886 : {
887 0 : uint32_t hive;
888 0 : struct policy_handle hive_hnd, key_hnd;
889 0 : struct winreg_String key, keyclass;
890 0 : enum winreg_CreateAction action;
891 0 : NTSTATUS status;
892 0 : WERROR werr;
893 20 : struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
894 :
895 20 : ZERO_STRUCT(key);
896 20 : ZERO_STRUCT(keyclass);
897 :
898 20 : if (!reg_hive_key(mem_ctx, argv[0], &hive, &key.name)) {
899 0 : return NT_STATUS_INVALID_PARAMETER;
900 : }
901 :
902 20 : status = dcerpc_winreg_Connect(b, mem_ctx, hive,
903 : SEC_FLAG_MAXIMUM_ALLOWED,
904 : &hive_hnd, &werr);
905 20 : if (!(NT_STATUS_IS_OK(status))) {
906 0 : return status;
907 : }
908 20 : if (!W_ERROR_IS_OK(werr)) {
909 0 : return werror_to_ntstatus(werr);
910 : }
911 :
912 20 : action = REG_ACTION_NONE;
913 20 : keyclass.name = "";
914 :
915 20 : status = dcerpc_winreg_CreateKey(b, mem_ctx, &hive_hnd, key,
916 : keyclass, 0, REG_KEY_READ, NULL,
917 : &key_hnd, &action, &werr);
918 20 : if (!NT_STATUS_IS_OK(status)) {
919 0 : d_fprintf(stderr, _("createkey returned %s\n"),
920 : nt_errstr(status));
921 0 : dcerpc_winreg_CloseKey(b, mem_ctx, &hive_hnd, &werr);
922 0 : return status;
923 : }
924 20 : if (!W_ERROR_IS_OK(werr)) {
925 0 : WERROR _werr;
926 0 : d_fprintf(stderr, _("createkey returned %s\n"),
927 : win_errstr(werr));
928 0 : dcerpc_winreg_CloseKey(b, mem_ctx, &hive_hnd, &_werr);
929 0 : return werror_to_ntstatus(werr);
930 : }
931 :
932 20 : switch (action) {
933 0 : case REG_ACTION_NONE:
934 0 : d_printf(_("createkey did nothing -- huh?\n"));
935 0 : break;
936 10 : case REG_CREATED_NEW_KEY:
937 10 : d_printf(_("createkey created %s\n"), argv[0]);
938 10 : break;
939 10 : case REG_OPENED_EXISTING_KEY:
940 10 : d_printf(_("createkey opened existing %s\n"), argv[0]);
941 10 : break;
942 : }
943 :
944 20 : dcerpc_winreg_CloseKey(b, mem_ctx, &key_hnd, &werr);
945 20 : dcerpc_winreg_CloseKey(b, mem_ctx, &hive_hnd, &werr);
946 :
947 20 : return status;
948 : }
949 :
950 20 : static int rpc_registry_createkey(struct net_context *c, int argc,
951 : const char **argv )
952 : {
953 20 : if (argc != 1 || c->display_usage) {
954 0 : d_fprintf(stderr, "%s\n%s",
955 : _("Usage:"),
956 : _("net rpc registry createkey <key>\n"));
957 0 : return -1;
958 : }
959 :
960 20 : return run_rpc_command(c, NULL, &ndr_table_winreg, 0,
961 : rpc_registry_createkey_internal, argc, argv );
962 : }
963 :
964 18 : static NTSTATUS rpc_registry_deletekey_internal(struct net_context *c,
965 : const struct dom_sid *domain_sid,
966 : const char *domain_name,
967 : struct cli_state *cli,
968 : struct rpc_pipe_client *pipe_hnd,
969 : TALLOC_CTX *mem_ctx,
970 : int argc,
971 : const char **argv )
972 : {
973 0 : uint32_t hive;
974 0 : struct policy_handle hive_hnd;
975 0 : struct winreg_String key;
976 0 : NTSTATUS status;
977 0 : WERROR werr;
978 18 : struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
979 :
980 18 : ZERO_STRUCT(key);
981 :
982 18 : if (!reg_hive_key(mem_ctx, argv[0], &hive, &key.name)) {
983 0 : return NT_STATUS_INVALID_PARAMETER;
984 : }
985 :
986 18 : status = dcerpc_winreg_Connect(b, mem_ctx, hive,
987 : SEC_FLAG_MAXIMUM_ALLOWED,
988 : &hive_hnd, &werr);
989 18 : if (!(NT_STATUS_IS_OK(status))) {
990 0 : return status;
991 : }
992 18 : if (!W_ERROR_IS_OK(werr)) {
993 0 : return werror_to_ntstatus(werr);
994 : }
995 :
996 18 : status = dcerpc_winreg_DeleteKey(b, mem_ctx, &hive_hnd, key, &werr);
997 18 : if (is_valid_policy_hnd(&hive_hnd)) {
998 0 : WERROR _werr;
999 18 : dcerpc_winreg_CloseKey(b, mem_ctx, &hive_hnd, &_werr);
1000 : }
1001 :
1002 18 : if (!NT_STATUS_IS_OK(status)) {
1003 0 : d_fprintf(stderr, _("deletekey returned %s\n"),
1004 : nt_errstr(status));
1005 0 : return status;
1006 : }
1007 :
1008 18 : if (!W_ERROR_IS_OK(werr)) {
1009 4 : d_fprintf(stderr, _("deletekey returned %s\n"),
1010 : win_errstr(werr));
1011 4 : return werror_to_ntstatus(werr);
1012 : }
1013 :
1014 14 : return status;
1015 : }
1016 :
1017 18 : static int rpc_registry_deletekey(struct net_context *c, int argc, const char **argv )
1018 : {
1019 18 : if (argc != 1 || c->display_usage) {
1020 0 : d_fprintf(stderr, "%s\n%s",
1021 : _("Usage:"),
1022 : _("net rpc registry deletekey <key>\n"));
1023 0 : return -1;
1024 : }
1025 :
1026 18 : return run_rpc_command(c, NULL, &ndr_table_winreg, 0,
1027 : rpc_registry_deletekey_internal, argc, argv );
1028 : }
1029 :
1030 : /********************************************************************
1031 : ********************************************************************/
1032 :
1033 50 : static NTSTATUS rpc_registry_enumerate_internal(struct net_context *c,
1034 : const struct dom_sid *domain_sid,
1035 : const char *domain_name,
1036 : struct cli_state *cli,
1037 : struct rpc_pipe_client *pipe_hnd,
1038 : TALLOC_CTX *mem_ctx,
1039 : int argc,
1040 : const char **argv )
1041 : {
1042 0 : struct policy_handle pol_hive, pol_key;
1043 0 : NTSTATUS status;
1044 0 : WERROR werr;
1045 50 : uint32_t num_subkeys = 0;
1046 50 : uint32_t num_values = 0;
1047 50 : char **names = NULL, **classes = NULL;
1048 50 : NTTIME **modtimes = NULL;
1049 0 : uint32_t i;
1050 50 : struct registry_value **values = NULL;
1051 50 : struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
1052 :
1053 50 : if (argc != 1 || c->display_usage) {
1054 2 : d_printf("%s\n%s",
1055 : _("Usage:"),
1056 : _("net rpc registry enumerate <path>\n"));
1057 2 : d_printf("%s net rpc registry enumerate "
1058 : "'HKLM\\Software\\Samba'\n", _("Example:"));
1059 2 : return NT_STATUS_INVALID_PARAMETER;
1060 : }
1061 :
1062 48 : status = registry_openkey(mem_ctx, pipe_hnd, argv[0], REG_KEY_READ,
1063 : &pol_hive, &pol_key);
1064 48 : if (!NT_STATUS_IS_OK(status)) {
1065 10 : d_fprintf(stderr, _("registry_openkey failed: %s\n"),
1066 : nt_errstr(status));
1067 10 : return status;
1068 : }
1069 :
1070 38 : status = registry_enumkeys(mem_ctx, pipe_hnd, &pol_key, &num_subkeys,
1071 : &names, &classes, &modtimes);
1072 38 : if (!NT_STATUS_IS_OK(status)) {
1073 0 : d_fprintf(stderr, _("enumerating keys failed: %s\n"),
1074 : nt_errstr(status));
1075 0 : return status;
1076 : }
1077 :
1078 96 : for (i=0; i<num_subkeys; i++) {
1079 58 : print_registry_key(names[i], modtimes[i]);
1080 : }
1081 :
1082 38 : status = registry_enumvalues(mem_ctx, pipe_hnd, &pol_key, &num_values,
1083 : &names, &values);
1084 38 : if (!NT_STATUS_IS_OK(status)) {
1085 0 : d_fprintf(stderr, _("enumerating values failed: %s\n"),
1086 : nt_errstr(status));
1087 0 : return status;
1088 : }
1089 :
1090 42 : for (i=0; i<num_values; i++) {
1091 4 : print_registry_value_with_name(names[i], values[i]);
1092 : }
1093 :
1094 38 : dcerpc_winreg_CloseKey(b, mem_ctx, &pol_key, &werr);
1095 38 : dcerpc_winreg_CloseKey(b, mem_ctx, &pol_hive, &werr);
1096 :
1097 38 : return status;
1098 : }
1099 :
1100 : /********************************************************************
1101 : ********************************************************************/
1102 :
1103 50 : static int rpc_registry_enumerate(struct net_context *c, int argc,
1104 : const char **argv )
1105 : {
1106 50 : return run_rpc_command(c, NULL, &ndr_table_winreg, 0,
1107 : rpc_registry_enumerate_internal, argc, argv );
1108 : }
1109 :
1110 : /********************************************************************
1111 : ********************************************************************/
1112 :
1113 0 : static NTSTATUS rpc_registry_save_internal(struct net_context *c,
1114 : const struct dom_sid *domain_sid,
1115 : const char *domain_name,
1116 : struct cli_state *cli,
1117 : struct rpc_pipe_client *pipe_hnd,
1118 : TALLOC_CTX *mem_ctx,
1119 : int argc,
1120 : const char **argv )
1121 : {
1122 0 : WERROR result = WERR_GEN_FAILURE;
1123 0 : struct policy_handle pol_hive, pol_key;
1124 0 : NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
1125 0 : struct winreg_String filename;
1126 0 : struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
1127 :
1128 0 : if (argc != 2 || c->display_usage) {
1129 0 : d_printf("%s\n%s",
1130 : _("Usage:"),
1131 : _("net rpc registry backup <path> <file> \n"));
1132 0 : return NT_STATUS_INVALID_PARAMETER;
1133 : }
1134 :
1135 0 : status = registry_openkey(mem_ctx, pipe_hnd, argv[0], REG_KEY_ALL,
1136 : &pol_hive, &pol_key);
1137 0 : if (!NT_STATUS_IS_OK(status)) {
1138 0 : d_fprintf(stderr, _("registry_openkey failed: %s\n"),
1139 : nt_errstr(status));
1140 0 : return status;
1141 : }
1142 :
1143 0 : filename.name = argv[1];
1144 0 : status = dcerpc_winreg_SaveKey(b, mem_ctx, &pol_key, &filename, NULL, &result);
1145 0 : if (!NT_STATUS_IS_OK(status)) {
1146 0 : d_fprintf(stderr, _("Unable to save [%s] to %s:%s\n"), argv[0],
1147 0 : pipe_hnd->desthost, argv[1]);
1148 : }
1149 0 : if (!W_ERROR_IS_OK(result)) {
1150 0 : status = werror_to_ntstatus(result);
1151 0 : d_fprintf(stderr, _("Unable to save [%s] to %s:%s\n"), argv[0],
1152 0 : pipe_hnd->desthost, argv[1]);
1153 : }
1154 :
1155 : /* cleanup */
1156 :
1157 0 : dcerpc_winreg_CloseKey(b, mem_ctx, &pol_key, &result);
1158 0 : dcerpc_winreg_CloseKey(b, mem_ctx, &pol_hive, &result);
1159 :
1160 0 : return status;
1161 : }
1162 :
1163 : /********************************************************************
1164 : ********************************************************************/
1165 :
1166 0 : static int rpc_registry_save(struct net_context *c, int argc, const char **argv )
1167 : {
1168 0 : return run_rpc_command(c, NULL, &ndr_table_winreg, 0,
1169 : rpc_registry_save_internal, argc, argv );
1170 : }
1171 :
1172 :
1173 : /********************************************************************
1174 : ********************************************************************/
1175 :
1176 0 : static void dump_values( REGF_NK_REC *nk )
1177 : {
1178 0 : int i, j;
1179 0 : const char *data_str = NULL;
1180 0 : uint32_t data_size, data;
1181 0 : DATA_BLOB blob;
1182 :
1183 0 : if ( !nk->values )
1184 0 : return;
1185 :
1186 0 : for ( i=0; i<nk->num_values; i++ ) {
1187 0 : d_printf( "\"%s\" = ", nk->values[i].valuename ? nk->values[i].valuename : "(default)" );
1188 0 : d_printf( "(%s) ", str_regtype( nk->values[i].type ) );
1189 :
1190 0 : data_size = nk->values[i].data_size & ~VK_DATA_IN_OFFSET;
1191 0 : switch ( nk->values[i].type ) {
1192 0 : case REG_SZ:
1193 0 : blob = data_blob_const(nk->values[i].data, data_size);
1194 0 : if (!pull_reg_sz(talloc_tos(), &blob,
1195 : &data_str)) {
1196 0 : data_str = NULL;
1197 : }
1198 0 : if (!data_str) {
1199 0 : break;
1200 : }
1201 0 : d_printf( "%s", data_str );
1202 0 : break;
1203 0 : case REG_MULTI_SZ:
1204 : case REG_EXPAND_SZ:
1205 0 : for ( j=0; j<data_size; j++ ) {
1206 0 : d_printf( "%c", nk->values[i].data[j] );
1207 : }
1208 0 : break;
1209 0 : case REG_DWORD:
1210 0 : data = IVAL( nk->values[i].data, 0 );
1211 0 : d_printf("0x%x", data );
1212 0 : break;
1213 0 : case REG_BINARY:
1214 0 : for ( j=0; j<data_size; j++ ) {
1215 0 : d_printf( "%x", nk->values[i].data[j] );
1216 : }
1217 0 : break;
1218 0 : default:
1219 0 : d_printf(_("unknown"));
1220 0 : break;
1221 : }
1222 :
1223 0 : d_printf( "\n" );
1224 : }
1225 :
1226 : }
1227 :
1228 : /********************************************************************
1229 : ********************************************************************/
1230 :
1231 0 : static bool dump_registry_tree( REGF_FILE *file, REGF_NK_REC *nk, const char *parent )
1232 : {
1233 0 : REGF_NK_REC *key;
1234 :
1235 : /* depth first dump of the registry tree */
1236 :
1237 0 : while ( (key = regfio_fetch_subkey( file, nk )) ) {
1238 0 : char *regpath;
1239 0 : if (asprintf(®path, "%s\\%s", parent, key->keyname) < 0) {
1240 0 : break;
1241 : }
1242 0 : d_printf("[%s]\n", regpath );
1243 0 : dump_values( key );
1244 0 : d_printf("\n");
1245 0 : dump_registry_tree( file, key, regpath );
1246 0 : SAFE_FREE(regpath);
1247 : }
1248 :
1249 0 : return true;
1250 : }
1251 :
1252 : /********************************************************************
1253 : ********************************************************************/
1254 :
1255 0 : static bool write_registry_tree( REGF_FILE *infile, REGF_NK_REC *nk,
1256 : REGF_NK_REC *parent, REGF_FILE *outfile,
1257 : const char *parentpath )
1258 : {
1259 0 : REGF_NK_REC *key, *subkey;
1260 0 : struct regval_ctr *values = NULL;
1261 0 : struct regsubkey_ctr *subkeys = NULL;
1262 0 : int i;
1263 0 : char *path = NULL;
1264 0 : WERROR werr;
1265 :
1266 0 : werr = regsubkey_ctr_init(infile->mem_ctx, &subkeys);
1267 0 : if (!W_ERROR_IS_OK(werr)) {
1268 0 : DEBUG(0, ("write_registry_tree: regsubkey_ctr_init failed: "
1269 : "%s\n", win_errstr(werr)));
1270 0 : return false;
1271 : }
1272 :
1273 0 : werr = regval_ctr_init(subkeys, &values);
1274 0 : if (!W_ERROR_IS_OK(werr)) {
1275 0 : DEBUG(0,("write_registry_tree: talloc() failed!\n"));
1276 0 : TALLOC_FREE(subkeys);
1277 0 : return false;
1278 : }
1279 :
1280 : /* copy values into the struct regval_ctr */
1281 :
1282 0 : for ( i=0; i<nk->num_values; i++ ) {
1283 0 : regval_ctr_addvalue( values, nk->values[i].valuename, nk->values[i].type,
1284 0 : nk->values[i].data, (nk->values[i].data_size & ~VK_DATA_IN_OFFSET) );
1285 : }
1286 :
1287 : /* copy subkeys into the struct regsubkey_ctr */
1288 :
1289 0 : while ( (subkey = regfio_fetch_subkey( infile, nk )) ) {
1290 0 : regsubkey_ctr_addkey( subkeys, subkey->keyname );
1291 : }
1292 :
1293 0 : key = regfio_write_key( outfile, nk->keyname, values, subkeys, nk->sec_desc->sec_desc, parent );
1294 :
1295 : /* write each one of the subkeys out */
1296 :
1297 0 : path = talloc_asprintf(subkeys,
1298 : "%s%s%s",
1299 : parentpath,
1300 : parent ? "\\" : "",
1301 : nk->keyname);
1302 0 : if (!path) {
1303 0 : TALLOC_FREE(subkeys);
1304 0 : return false;
1305 : }
1306 :
1307 0 : nk->subkey_index = 0;
1308 0 : while ( (subkey = regfio_fetch_subkey( infile, nk )) ) {
1309 0 : write_registry_tree( infile, subkey, key, outfile, path );
1310 : }
1311 :
1312 0 : d_printf("[%s]\n", path );
1313 0 : TALLOC_FREE(subkeys);
1314 :
1315 0 : return true;
1316 : }
1317 :
1318 : /********************************************************************
1319 : ********************************************************************/
1320 :
1321 0 : static int rpc_registry_dump(struct net_context *c, int argc, const char **argv)
1322 : {
1323 0 : REGF_FILE *registry;
1324 0 : REGF_NK_REC *nk;
1325 :
1326 0 : if (argc != 1 || c->display_usage) {
1327 0 : d_printf("%s\n%s",
1328 : _("Usage:"),
1329 : _("net rpc registry dump <file> \n"));
1330 0 : return -1;
1331 : }
1332 :
1333 0 : d_printf(_("Opening %s...."), argv[0]);
1334 0 : if ( !(registry = regfio_open( argv[0], O_RDONLY, 0)) ) {
1335 0 : d_fprintf(stderr, _("Failed to open %s for reading\n"),argv[0]);
1336 0 : return 1;
1337 : }
1338 0 : d_printf(_("ok\n"));
1339 :
1340 : /* get the root of the registry file */
1341 :
1342 0 : if ((nk = regfio_rootkey( registry )) == NULL) {
1343 0 : d_fprintf(stderr, _("Could not get rootkey\n"));
1344 0 : regfio_close( registry );
1345 0 : return 1;
1346 : }
1347 0 : d_printf("[%s]\n", nk->keyname);
1348 0 : dump_values( nk );
1349 0 : d_printf("\n");
1350 :
1351 0 : dump_registry_tree( registry, nk, nk->keyname );
1352 :
1353 : #if 0
1354 : talloc_report_full( registry->mem_ctx, stderr );
1355 : #endif
1356 0 : d_printf(_("Closing registry..."));
1357 0 : regfio_close( registry );
1358 0 : d_printf(_("ok\n"));
1359 :
1360 0 : return 0;
1361 : }
1362 :
1363 : /********************************************************************
1364 : ********************************************************************/
1365 :
1366 0 : static int rpc_registry_copy(struct net_context *c, int argc, const char **argv )
1367 : {
1368 0 : REGF_FILE *infile = NULL, *outfile = NULL;
1369 0 : REGF_NK_REC *nk;
1370 0 : int result = 1;
1371 :
1372 0 : if (argc != 2 || c->display_usage) {
1373 0 : d_printf("%s\n%s",
1374 : _("Usage:"),
1375 : _("net rpc registry copy <srcfile> <newfile>\n"));
1376 0 : return -1;
1377 : }
1378 :
1379 0 : d_printf(_("Opening %s...."), argv[0]);
1380 0 : if ( !(infile = regfio_open( argv[0], O_RDONLY, 0 )) ) {
1381 0 : d_fprintf(stderr, _("Failed to open %s for reading\n"),argv[0]);
1382 0 : return 1;
1383 : }
1384 0 : d_printf(_("ok\n"));
1385 :
1386 0 : d_printf(_("Opening %s...."), argv[1]);
1387 0 : if ( !(outfile = regfio_open( argv[1], (O_RDWR|O_CREAT|O_TRUNC),
1388 : (S_IRUSR|S_IWUSR) )) ) {
1389 0 : d_fprintf(stderr, _("Failed to open %s for writing\n"),argv[1]);
1390 0 : goto out;
1391 : }
1392 0 : d_printf(_("ok\n"));
1393 :
1394 : /* get the root of the registry file */
1395 :
1396 0 : if ((nk = regfio_rootkey( infile )) == NULL) {
1397 0 : d_fprintf(stderr, _("Could not get rootkey\n"));
1398 0 : goto out;
1399 : }
1400 0 : d_printf(_("RootKey: [%s]\n"), nk->keyname);
1401 :
1402 0 : write_registry_tree( infile, nk, NULL, outfile, "" );
1403 :
1404 0 : result = 0;
1405 :
1406 0 : out:
1407 :
1408 0 : d_printf(_("Closing %s..."), argv[1]);
1409 0 : if (outfile) {
1410 0 : regfio_close( outfile );
1411 : }
1412 0 : d_printf(_("ok\n"));
1413 :
1414 0 : d_printf(_("Closing %s..."), argv[0]);
1415 0 : if (infile) {
1416 0 : regfio_close( infile );
1417 : }
1418 0 : d_printf(_("ok\n"));
1419 :
1420 0 : return( result);
1421 : }
1422 :
1423 : /********************************************************************
1424 : ********************************************************************/
1425 :
1426 0 : static NTSTATUS rpc_registry_getsd_internal(struct net_context *c,
1427 : const struct dom_sid *domain_sid,
1428 : const char *domain_name,
1429 : struct cli_state *cli,
1430 : struct rpc_pipe_client *pipe_hnd,
1431 : TALLOC_CTX *mem_ctx,
1432 : int argc,
1433 : const char **argv)
1434 : {
1435 0 : struct policy_handle pol_hive, pol_key;
1436 0 : NTSTATUS status;
1437 0 : WERROR werr;
1438 0 : enum ndr_err_code ndr_err;
1439 0 : struct KeySecurityData *sd = NULL;
1440 0 : uint32_t sec_info;
1441 0 : DATA_BLOB blob;
1442 0 : struct security_descriptor sec_desc;
1443 0 : uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED |
1444 : SEC_FLAG_SYSTEM_SECURITY;
1445 0 : struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
1446 :
1447 0 : if (argc <1 || argc > 2 || c->display_usage) {
1448 0 : d_printf("%s\n%s",
1449 : _("Usage:"),
1450 : _("net rpc registry getsd <path> <secinfo>\n"));
1451 0 : d_printf("%s net rpc registry getsd "
1452 : "'HKLM\\Software\\Samba'\n", _("Example:"));
1453 0 : return NT_STATUS_INVALID_PARAMETER;
1454 : }
1455 :
1456 0 : status = registry_openkey(mem_ctx, pipe_hnd, argv[0],
1457 : access_mask,
1458 : &pol_hive, &pol_key);
1459 0 : if (!NT_STATUS_IS_OK(status)) {
1460 0 : d_fprintf(stderr, _("registry_openkey failed: %s\n"),
1461 : nt_errstr(status));
1462 0 : return status;
1463 : }
1464 :
1465 0 : sd = talloc_zero(mem_ctx, struct KeySecurityData);
1466 0 : if (!sd) {
1467 0 : status = NT_STATUS_NO_MEMORY;
1468 0 : goto out;
1469 : }
1470 :
1471 0 : sd->size = 0x1000;
1472 :
1473 0 : if (argc >= 2) {
1474 0 : sscanf(argv[1], "%x", &sec_info);
1475 : } else {
1476 0 : sec_info = SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL;
1477 : }
1478 :
1479 0 : status = registry_getsd(mem_ctx, b, &pol_key, sec_info, sd, &werr);
1480 0 : if (!NT_STATUS_IS_OK(status)) {
1481 0 : d_fprintf(stderr, _("getting sd failed: %s\n"),
1482 : nt_errstr(status));
1483 0 : goto out;
1484 : }
1485 0 : if (!W_ERROR_IS_OK(werr)) {
1486 0 : status = werror_to_ntstatus(werr);
1487 0 : d_fprintf(stderr, _("getting sd failed: %s\n"),
1488 : win_errstr(werr));
1489 0 : goto out;
1490 : }
1491 :
1492 0 : blob.data = sd->data;
1493 0 : blob.length = sd->size;
1494 :
1495 0 : ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &sec_desc,
1496 : (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
1497 0 : if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1498 0 : status = ndr_map_error2ntstatus(ndr_err);
1499 0 : goto out;
1500 : }
1501 0 : status = NT_STATUS_OK;
1502 :
1503 0 : display_sec_desc(&sec_desc);
1504 :
1505 0 : out:
1506 0 : dcerpc_winreg_CloseKey(b, mem_ctx, &pol_key, &werr);
1507 0 : dcerpc_winreg_CloseKey(b, mem_ctx, &pol_hive, &werr);
1508 :
1509 0 : return status;
1510 : }
1511 :
1512 :
1513 0 : static int rpc_registry_getsd(struct net_context *c, int argc, const char **argv)
1514 : {
1515 0 : return run_rpc_command(c, NULL, &ndr_table_winreg, 0,
1516 : rpc_registry_getsd_internal, argc, argv);
1517 : }
1518 :
1519 : /********************************************************************
1520 : ********************************************************************/
1521 : /**
1522 : * @defgroup net_rpc_registry net rpc registry
1523 : */
1524 :
1525 : /**
1526 : * @defgroup net_rpc_registry_export Export
1527 : * @ingroup net_rpc_registry
1528 : * @{
1529 : */
1530 :
1531 16 : static NTSTATUS registry_export(struct rpc_pipe_client* pipe_hnd,
1532 : TALLOC_CTX* ctx,
1533 : struct policy_handle* key_hnd,
1534 : struct reg_format* f,
1535 : const char* parentfullname,
1536 : const char* name)
1537 : {
1538 0 : NTSTATUS status;
1539 16 : uint32_t num_subkeys = 0;
1540 16 : uint32_t num_values = 0;
1541 16 : char **names = NULL, **classes = NULL;
1542 16 : NTTIME **modtimes = NULL;
1543 16 : struct regval_blob **values = NULL;
1544 0 : uint32_t i;
1545 16 : struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
1546 :
1547 16 : TALLOC_CTX* mem_ctx = talloc_new(ctx);
1548 :
1549 :
1550 16 : const char* fullname = name
1551 12 : ? talloc_asprintf(mem_ctx, "%s\\%s", parentfullname, name)
1552 16 : : parentfullname;
1553 16 : reg_format_key(f, &fullname, 1, false);
1554 :
1555 16 : status = registry_enumvalues2(mem_ctx, pipe_hnd, key_hnd, &num_values,
1556 : &names, &values);
1557 16 : if (!NT_STATUS_IS_OK(status)) {
1558 0 : d_fprintf(stderr, _("enumerating values failed: %s\n"),
1559 : nt_errstr(status));
1560 0 : goto done;
1561 : }
1562 :
1563 108 : for (i=0; i<num_values; i++) {
1564 92 : reg_format_regval_blob(f, names[i], values[i]);
1565 : }
1566 :
1567 :
1568 16 : status = registry_enumkeys(mem_ctx, pipe_hnd, key_hnd, &num_subkeys,
1569 : &names, &classes, &modtimes);
1570 16 : if (!NT_STATUS_IS_OK(status)) {
1571 0 : d_fprintf(stderr, _("enumerating keys failed: %s\n"),
1572 : nt_errstr(status));
1573 0 : goto done;
1574 : }
1575 :
1576 28 : for (i=0; i<num_subkeys; i++) {
1577 0 : struct policy_handle subkey_hnd;
1578 0 : struct winreg_String key;
1579 0 : WERROR werr;
1580 12 : ZERO_STRUCT(key);
1581 : /* key.name = talloc_strdup(mem_ctx, names[i]); ??? */
1582 12 : key.name = names[i];
1583 :
1584 12 : status = dcerpc_winreg_OpenKey(b, mem_ctx, key_hnd, key,
1585 : 0, REG_KEY_READ,
1586 : &subkey_hnd, &werr);
1587 12 : if (!NT_STATUS_IS_OK(status)) {
1588 0 : d_fprintf(stderr,
1589 0 : _("dcerpc_winreg_OpenKey failed: %s %s\n"),
1590 0 : names[i], nt_errstr(status));
1591 0 : continue;
1592 : }
1593 12 : if (!W_ERROR_IS_OK(werr)) {
1594 0 : status = werror_to_ntstatus(werr);
1595 0 : d_fprintf(stderr,
1596 0 : _("dcerpc_winreg_OpenKey failed: %s %s\n"),
1597 0 : names[i], win_errstr(werr));
1598 0 : continue;
1599 : }
1600 :
1601 12 : status = registry_export(pipe_hnd, mem_ctx, &subkey_hnd,
1602 12 : f, fullname, names[i]);
1603 12 : if (!(NT_STATUS_IS_OK(status))) {
1604 0 : d_fprintf(stderr,
1605 0 : _("export key failed: %s %s\n"),
1606 0 : names[i], nt_errstr(status));
1607 : }
1608 12 : dcerpc_winreg_CloseKey(b, mem_ctx,
1609 : &subkey_hnd, &werr);
1610 : }
1611 16 : done:
1612 16 : talloc_free(mem_ctx);
1613 16 : return status;
1614 : }
1615 :
1616 4 : static NTSTATUS rpc_registry_export_internal(struct net_context *c,
1617 : const struct dom_sid *domain_sid,
1618 : const char *domain_name,
1619 : struct cli_state *cli,
1620 : struct rpc_pipe_client *pipe_hnd,
1621 : TALLOC_CTX *mem_ctx,
1622 : int argc,
1623 : const char **argv )
1624 : {
1625 0 : struct policy_handle pol_hive, pol_key;
1626 0 : NTSTATUS status;
1627 0 : WERROR werr;
1628 0 : struct reg_format* f;
1629 4 : struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
1630 :
1631 4 : if (argc < 2 || argc > 3 || c->display_usage) {
1632 0 : d_printf("%s\n%s",
1633 : _("Usage:"),
1634 : _("net rpc registry export <path> <file> [opt]\n"));
1635 0 : d_printf("%s net rpc registry export "
1636 : "'HKLM\\Software\\Samba' samba.reg\n", _("Example:"));
1637 0 : return NT_STATUS_INVALID_PARAMETER;
1638 : }
1639 :
1640 4 : status = registry_openkey(mem_ctx, pipe_hnd, argv[0], REG_KEY_READ,
1641 : &pol_hive, &pol_key);
1642 4 : if (!NT_STATUS_IS_OK(status)) {
1643 0 : d_fprintf(stderr, _("registry_openkey failed: %s\n"),
1644 : nt_errstr(status));
1645 0 : return status;
1646 : }
1647 :
1648 4 : f = reg_format_file(mem_ctx, argv[1], (argc > 2) ? argv[2] : NULL);
1649 4 : if (f == NULL) {
1650 0 : d_fprintf(stderr, _("open file failed: %s\n"), strerror(errno));
1651 0 : return map_nt_error_from_unix(errno);
1652 : }
1653 :
1654 4 : status = registry_export(pipe_hnd, mem_ctx, &pol_key,
1655 : f, argv[0], NULL );
1656 4 : if (!NT_STATUS_IS_OK(status))
1657 0 : return status;
1658 :
1659 4 : dcerpc_winreg_CloseKey(b, mem_ctx, &pol_key, &werr);
1660 4 : dcerpc_winreg_CloseKey(b, mem_ctx, &pol_hive, &werr);
1661 :
1662 4 : return status;
1663 : }
1664 : /********************************************************************
1665 : ********************************************************************/
1666 :
1667 4 : static int rpc_registry_export(struct net_context *c, int argc,
1668 : const char **argv )
1669 : {
1670 4 : return run_rpc_command(c, NULL, &ndr_table_winreg, 0,
1671 : rpc_registry_export_internal, argc, argv );
1672 : }
1673 :
1674 : /**@}*/
1675 :
1676 : /********************************************************************
1677 : ********************************************************************/
1678 :
1679 : /**
1680 : * @defgroup net_rpc_registry_import Import
1681 : * @ingroup net_rpc_registry
1682 : * @{
1683 : */
1684 :
1685 : struct import_ctx {
1686 : struct rpc_pipe_client *pipe_hnd;
1687 : TALLOC_CTX *mem_ctx;
1688 : };
1689 :
1690 26 : static WERROR import_create_key(struct import_ctx* ctx,
1691 : struct policy_handle* parent, const char* name,
1692 : void** pkey, bool* existing)
1693 : {
1694 0 : WERROR werr;
1695 0 : NTSTATUS status;
1696 26 : void* mem_ctx = talloc_new(ctx->mem_ctx);
1697 :
1698 26 : struct policy_handle* key = NULL;
1699 0 : struct policy_handle hive;
1700 0 : struct winreg_String keyclass, keyname;
1701 26 : enum winreg_CreateAction action = REG_ACTION_NONE;
1702 26 : struct dcerpc_binding_handle *b = ctx->pipe_hnd->binding_handle;
1703 :
1704 26 : ZERO_STRUCT(keyname);
1705 26 : keyname.name = name;
1706 :
1707 26 : if (parent == NULL) {
1708 26 : uint32_t hive_idx = 0;
1709 26 : if (!reg_hive_key(mem_ctx, name, &hive_idx, &keyname.name)) {
1710 0 : werr = WERR_FOOBAR;
1711 0 : goto done;
1712 : }
1713 :
1714 26 : status = dcerpc_winreg_Connect(b, mem_ctx,
1715 : hive_idx, SEC_FLAG_MAXIMUM_ALLOWED,
1716 : &hive, &werr);
1717 26 : if (!NT_STATUS_IS_OK(status)) {
1718 0 : werr = ntstatus_to_werror(status);
1719 0 : d_fprintf(stderr, _("dcerpc_winreg_Connect returned %s\n"),
1720 : nt_errstr(status));
1721 0 : goto done;
1722 : }
1723 26 : if (!W_ERROR_IS_OK(werr)) {
1724 0 : d_fprintf(stderr, _("dcerpc_winreg_Connect returned %s\n"),
1725 : win_errstr(werr));
1726 0 : goto done;
1727 : }
1728 :
1729 26 : parent = &hive;
1730 : }
1731 :
1732 26 : key = talloc_zero(mem_ctx, struct policy_handle);
1733 26 : if (key == NULL) {
1734 0 : werr = WERR_NOT_ENOUGH_MEMORY;
1735 0 : goto done;
1736 : }
1737 :
1738 26 : ZERO_STRUCT(keyclass);
1739 26 : keyclass.name = "";
1740 :
1741 26 : status = dcerpc_winreg_CreateKey(b, mem_ctx,
1742 : parent, keyname,
1743 : keyclass, 0, REG_KEY_READ, NULL,
1744 : key, &action, &werr);
1745 26 : if (!NT_STATUS_IS_OK(status)) {
1746 0 : werr = ntstatus_to_werror(status);
1747 0 : d_fprintf(stderr, _("dcerpc_winreg_CreateKey returned %s\n"),
1748 : nt_errstr(status));
1749 0 : goto done;
1750 : }
1751 26 : if (!W_ERROR_IS_OK(werr)) {
1752 0 : d_fprintf(stderr, _("dcerpc_winreg_CreateKey returned %s\n"),
1753 : win_errstr(werr));
1754 0 : goto done;
1755 : }
1756 :
1757 26 : switch (action) {
1758 2 : case REG_CREATED_NEW_KEY:
1759 2 : d_printf(_("createkey created %s\n"), name);
1760 2 : if (existing != NULL)
1761 2 : *existing = false;
1762 26 : break;
1763 :
1764 24 : case REG_OPENED_EXISTING_KEY:
1765 24 : d_printf(_("createkey opened existing %s\n"), name);
1766 24 : if (existing != NULL)
1767 24 : *existing = true;
1768 24 : break;
1769 :
1770 0 : case REG_ACTION_NONE:
1771 0 : d_printf(_("createkey did nothing -- huh?\n"));
1772 0 : werr = WERR_CREATE_FAILED;
1773 0 : break;
1774 0 : default:
1775 0 : assert(false);
1776 : }
1777 :
1778 26 : done:
1779 26 : if ( parent == &hive ) {
1780 0 : WERROR _result;
1781 26 : dcerpc_winreg_CloseKey(b, mem_ctx,
1782 : parent, &_result);
1783 : }
1784 :
1785 26 : if (pkey!=NULL) {
1786 26 : *pkey = talloc_steal(ctx->mem_ctx, key);
1787 : }
1788 :
1789 26 : talloc_free(mem_ctx);
1790 26 : return werr;
1791 : }
1792 :
1793 0 : static WERROR import_delete_key(struct import_ctx* ctx,
1794 : struct policy_handle* parent, const char* name)
1795 : {
1796 0 : WERROR werr;
1797 0 : NTSTATUS status;
1798 0 : void* mem_ctx = talloc_new(ctx->mem_ctx);
1799 0 : struct winreg_String keyname = { 0, };
1800 0 : struct policy_handle hive;
1801 0 : struct dcerpc_binding_handle *b = ctx->pipe_hnd->binding_handle;
1802 :
1803 0 : keyname.name = name;
1804 :
1805 0 : if (parent == NULL) {
1806 0 : uint32_t hive_idx;
1807 0 : if (!reg_hive_key(mem_ctx, name, &hive_idx, &keyname.name)) {
1808 0 : werr = WERR_FOOBAR;
1809 0 : goto done;
1810 : }
1811 :
1812 0 : status = dcerpc_winreg_Connect(b, mem_ctx, hive_idx,
1813 : SEC_FLAG_MAXIMUM_ALLOWED, &hive,
1814 : &werr);
1815 0 : if (!NT_STATUS_IS_OK(status)) {
1816 0 : werr = ntstatus_to_werror(status);
1817 0 : d_fprintf(stderr, _("dcerpc_winreg_Connect returned %s\n"),
1818 : nt_errstr(status));
1819 0 : goto done;
1820 : }
1821 0 : if (!W_ERROR_IS_OK(werr)) {
1822 0 : d_fprintf(stderr, _("dcerpc_winreg_Connect returned %s\n"),
1823 : win_errstr(werr));
1824 0 : goto done;
1825 : }
1826 :
1827 0 : parent = &hive;
1828 : }
1829 :
1830 0 : status = dcerpc_winreg_DeleteKey(b, mem_ctx, parent,
1831 : keyname, &werr);
1832 0 : if (!NT_STATUS_IS_OK(status)) {
1833 0 : werr = ntstatus_to_werror(status);
1834 0 : d_fprintf(stderr, _("dcerpc_winreg_DeleteKey returned %s\n"),
1835 : nt_errstr(status));
1836 0 : goto done;
1837 : }
1838 0 : if (!W_ERROR_IS_OK(werr)) {
1839 0 : d_fprintf(stderr, _("dcerpc_winreg_DeleteKey returned %s\n"),
1840 : win_errstr(werr));
1841 0 : goto done;
1842 : }
1843 :
1844 0 : done:
1845 0 : if ( parent == &hive ) {
1846 0 : WERROR _result;
1847 0 : dcerpc_winreg_CloseKey(b, mem_ctx, parent, &_result);
1848 : }
1849 :
1850 0 : talloc_free(mem_ctx);
1851 0 : return werr;
1852 : }
1853 :
1854 22 : static WERROR import_close_key(struct import_ctx* ctx,
1855 : struct policy_handle* key)
1856 : {
1857 0 : WERROR werr;
1858 0 : NTSTATUS status;
1859 22 : void* mem_ctx = talloc_new(ctx->mem_ctx);
1860 22 : struct dcerpc_binding_handle *b = ctx->pipe_hnd->binding_handle;
1861 :
1862 22 : status = dcerpc_winreg_CloseKey(b, mem_ctx, key, &werr);
1863 22 : if (!NT_STATUS_IS_OK(status)) {
1864 0 : werr = ntstatus_to_werror(status);
1865 0 : d_fprintf(stderr, _("dcerpc_winreg_CloseKey returned %s\n"),
1866 : nt_errstr(status));
1867 0 : goto done;
1868 : }
1869 22 : if (!W_ERROR_IS_OK(werr)) {
1870 0 : d_fprintf(stderr, _("dcerpc_winreg_CloseKey returned %s\n"),
1871 : win_errstr(werr));
1872 0 : goto done;
1873 : }
1874 :
1875 22 : werr = (talloc_free(key) == 0) ? WERR_OK : WERR_GEN_FAILURE;
1876 22 : done:
1877 22 : talloc_free(mem_ctx);
1878 22 : return werr;
1879 : }
1880 :
1881 50 : static WERROR import_create_val(struct import_ctx* ctx,
1882 : struct policy_handle* parent, const char* name,
1883 : uint32_t type, const uint8_t* val, uint32_t len)
1884 : {
1885 0 : WERROR werr;
1886 0 : NTSTATUS status;
1887 50 : void* mem_ctx = talloc_new(ctx->mem_ctx);
1888 0 : struct winreg_String valuename;
1889 50 : struct dcerpc_binding_handle *b = ctx->pipe_hnd->binding_handle;
1890 :
1891 50 : if (parent == NULL) {
1892 0 : return WERR_INVALID_PARAMETER;
1893 : }
1894 :
1895 50 : ZERO_STRUCT(valuename);
1896 50 : valuename.name = name;
1897 :
1898 50 : status = dcerpc_winreg_SetValue(b, mem_ctx, parent,
1899 : valuename, type,
1900 : (uint8_t *)discard_const(val), len, &werr);
1901 50 : if (!NT_STATUS_IS_OK(status)) {
1902 0 : werr = ntstatus_to_werror(status);
1903 0 : d_fprintf(stderr, _("registry_setvalue failed: %s\n"),
1904 : nt_errstr(status));
1905 0 : goto done;
1906 : }
1907 50 : if (!W_ERROR_IS_OK(werr)) {
1908 2 : d_fprintf(stderr, _("registry_setvalue failed: %s\n"),
1909 : win_errstr(werr));
1910 2 : goto done;
1911 : }
1912 :
1913 48 : done:
1914 50 : talloc_free(mem_ctx);
1915 50 : return werr;
1916 : }
1917 :
1918 0 : static WERROR import_delete_val(struct import_ctx* ctx,
1919 : struct policy_handle* parent, const char* name)
1920 : {
1921 0 : WERROR werr;
1922 0 : NTSTATUS status;
1923 0 : void* mem_ctx = talloc_new(ctx->mem_ctx);
1924 0 : struct winreg_String valuename;
1925 0 : struct dcerpc_binding_handle *b = ctx->pipe_hnd->binding_handle;
1926 :
1927 0 : if (parent == NULL) {
1928 0 : return WERR_INVALID_PARAMETER;
1929 : }
1930 :
1931 0 : ZERO_STRUCT(valuename);
1932 0 : valuename.name = name;
1933 :
1934 0 : status = dcerpc_winreg_DeleteValue(b, mem_ctx,
1935 : parent, valuename, &werr);
1936 :
1937 0 : if (!NT_STATUS_IS_OK(status)) {
1938 0 : werr = ntstatus_to_werror(status);
1939 0 : d_fprintf(stderr, _("registry_deletevalue failed: %s\n"),
1940 : nt_errstr(status));
1941 0 : goto done;
1942 : }
1943 0 : if (!NT_STATUS_IS_OK(status)) {
1944 0 : d_fprintf(stderr, _("registry_deletevalue failed: %s\n"),
1945 : win_errstr(werr));
1946 0 : goto done;
1947 : }
1948 :
1949 0 : done:
1950 0 : talloc_free(mem_ctx);
1951 0 : return werr;
1952 : }
1953 :
1954 :
1955 :
1956 8 : static NTSTATUS rpc_registry_import_internal(struct net_context *c,
1957 : const struct dom_sid *domain_sid,
1958 : const char *domain_name,
1959 : struct cli_state *cli,
1960 : struct rpc_pipe_client *pipe_hnd,
1961 : TALLOC_CTX *mem_ctx,
1962 : int argc,
1963 : const char **argv )
1964 : {
1965 0 : struct import_ctx import_ctx;
1966 :
1967 8 : struct reg_import_callback import_callback = {
1968 : .openkey = NULL,
1969 : .closekey = (reg_import_callback_closekey_t)&import_close_key,
1970 : .createkey = (reg_import_callback_createkey_t)&import_create_key,
1971 : .deletekey = (reg_import_callback_deletekey_t)&import_delete_key,
1972 : .deleteval = (reg_import_callback_deleteval_t)&import_delete_val,
1973 : .setval = {
1974 : .blob = (reg_import_callback_setval_blob_t)&import_create_val,
1975 : },
1976 : .setval_type = BLOB,
1977 : .data = &import_ctx
1978 : };
1979 :
1980 0 : int ret;
1981 8 : if (argc < 1 || argc > 2 || c->display_usage) {
1982 0 : d_printf("%s\n%s",
1983 : _("Usage:"),
1984 : _("net rpc registry import <file> [options]\n"));
1985 0 : d_printf("%s net rpc registry export "
1986 : "samba.reg enc=CP1252,flags=0\n", _("Example:"));
1987 0 : return NT_STATUS_INVALID_PARAMETER;
1988 : }
1989 8 : ZERO_STRUCT(import_ctx);
1990 8 : import_ctx.pipe_hnd = pipe_hnd;
1991 8 : import_ctx.mem_ctx = mem_ctx;
1992 16 : ret = reg_parse_file(argv[0],
1993 8 : reg_import_adapter(import_ctx.mem_ctx,
1994 : import_callback
1995 : ),
1996 : (argc > 1) ? argv[1] : NULL
1997 : );
1998 :
1999 8 : return ret==0 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
2000 : }
2001 :
2002 : /********************************************************************
2003 : ********************************************************************/
2004 :
2005 8 : static int rpc_registry_import(struct net_context *c, int argc,
2006 : const char **argv )
2007 : {
2008 8 : return run_rpc_command(c, NULL, &ndr_table_winreg, 0,
2009 : rpc_registry_import_internal, argc, argv );
2010 : }
2011 :
2012 : /**@}*/
2013 : /********************************************************************
2014 : ********************************************************************/
2015 :
2016 122 : int net_rpc_registry(struct net_context *c, int argc, const char **argv)
2017 : {
2018 122 : struct functable func[] = {
2019 : {
2020 : "enumerate",
2021 : rpc_registry_enumerate,
2022 : NET_TRANSPORT_RPC,
2023 : N_("Enumerate registry keys and values"),
2024 : N_("net rpc registry enumerate\n"
2025 : " Enumerate registry keys and values")
2026 : },
2027 : {
2028 : "createkey",
2029 : rpc_registry_createkey,
2030 : NET_TRANSPORT_RPC,
2031 : N_("Create a new registry key"),
2032 : N_("net rpc registry createkey\n"
2033 : " Create a new registry key")
2034 : },
2035 : {
2036 : "deletekey",
2037 : rpc_registry_deletekey,
2038 : NET_TRANSPORT_RPC,
2039 : N_("Delete a registry key"),
2040 : N_("net rpc registry deletekey\n"
2041 : " Delete a registry key")
2042 : },
2043 : {
2044 : "getvalue",
2045 : rpc_registry_getvalue,
2046 : NET_TRANSPORT_RPC,
2047 : N_("Print a registry value"),
2048 : N_("net rpc registry getvalue\n"
2049 : " Print a registry value")
2050 : },
2051 : {
2052 : "getvalueraw",
2053 : rpc_registry_getvalueraw,
2054 : NET_TRANSPORT_RPC,
2055 : N_("Print a registry value"),
2056 : N_("net rpc registry getvalueraw\n"
2057 : " Print a registry value (raw version)")
2058 : },
2059 : {
2060 : "setvalue",
2061 : rpc_registry_setvalue,
2062 : NET_TRANSPORT_RPC,
2063 : N_("Set a new registry value"),
2064 : N_("net rpc registry setvalue\n"
2065 : " Set a new registry value")
2066 : },
2067 : {
2068 : "deletevalue",
2069 : rpc_registry_deletevalue,
2070 : NET_TRANSPORT_RPC,
2071 : N_("Delete a registry value"),
2072 : N_("net rpc registry deletevalue\n"
2073 : " Delete a registry value")
2074 : },
2075 : {
2076 : "save",
2077 : rpc_registry_save,
2078 : NET_TRANSPORT_RPC,
2079 : N_("Save a registry file"),
2080 : N_("net rpc registry save\n"
2081 : " Save a registry file")
2082 : },
2083 : {
2084 : "dump",
2085 : rpc_registry_dump,
2086 : NET_TRANSPORT_RPC,
2087 : N_("Dump a registry file"),
2088 : N_("net rpc registry dump\n"
2089 : " Dump a registry file")
2090 : },
2091 : {
2092 : "copy",
2093 : rpc_registry_copy,
2094 : NET_TRANSPORT_RPC,
2095 : N_("Copy a registry file"),
2096 : N_("net rpc registry copy\n"
2097 : " Copy a registry file")
2098 : },
2099 : {
2100 : "getsd",
2101 : rpc_registry_getsd,
2102 : NET_TRANSPORT_RPC,
2103 : N_("Get security descriptor"),
2104 : N_("net rpc registry getsd\n"
2105 : " Get security descriptor")
2106 : },
2107 : {
2108 : "import",
2109 : rpc_registry_import,
2110 : NET_TRANSPORT_RPC,
2111 : N_("Import .reg file"),
2112 : N_("net rpc registry import\n"
2113 : " Import .reg file")
2114 : },
2115 : {
2116 : "export",
2117 : rpc_registry_export,
2118 : NET_TRANSPORT_RPC,
2119 : N_("Export .reg file"),
2120 : N_("net rpc registry export\n"
2121 : " Export .reg file")
2122 : },
2123 : {NULL, NULL, 0, NULL, NULL}
2124 : };
2125 122 : return net_run_function(c, argc, argv, "net rpc registry", func);
2126 : }
|