libcli/smbreadline/smbreadline.h: fix licence/copyright
[Samba.git] / source3 / rpc_client / cli_winreg.c
blob2517dbc50ab9c7d270810c7ee7bddd41a0702c71
1 /*
2 * Unix SMB/CIFS implementation.
4 * WINREG client routines
6 * Copyright (c) 2011 Andreas Schneider <asn@samba.org>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 3 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, see <http://www.gnu.org/licenses/>.
22 #include "includes.h"
23 #include "../librpc/gen_ndr/ndr_winreg_c.h"
24 #include "../librpc/gen_ndr/ndr_security.h"
25 #include "rpc_client/cli_winreg.h"
26 #include "../libcli/registry/util_reg.h"
28 NTSTATUS dcerpc_winreg_query_dword(TALLOC_CTX *mem_ctx,
29 struct dcerpc_binding_handle *h,
30 struct policy_handle *key_handle,
31 const char *value,
32 uint32_t *data,
33 WERROR *pwerr)
35 struct winreg_String wvalue;
36 enum winreg_Type type;
37 uint32_t value_len = 0;
38 uint32_t data_size = 0;
39 WERROR result = WERR_OK;
40 NTSTATUS status;
41 DATA_BLOB blob;
43 wvalue.name = value;
45 status = dcerpc_winreg_QueryValue(h,
46 mem_ctx,
47 key_handle,
48 &wvalue,
49 &type,
50 NULL,
51 &data_size,
52 &value_len,
53 &result);
54 if (!NT_STATUS_IS_OK(status)) {
55 return status;
57 if (!W_ERROR_IS_OK(result)) {
58 *pwerr = result;
59 return status;
62 if (type != REG_DWORD) {
63 *pwerr = WERR_INVALID_DATATYPE;
64 return status;
67 if (data_size != 4) {
68 *pwerr = WERR_INVALID_DATA;
69 return status;
72 blob = data_blob_talloc(mem_ctx, NULL, data_size);
73 if (blob.data == NULL) {
74 *pwerr = WERR_NOMEM;
75 return status;
77 value_len = 0;
79 status = dcerpc_winreg_QueryValue(h,
80 mem_ctx,
81 key_handle,
82 &wvalue,
83 &type,
84 blob.data,
85 &data_size,
86 &value_len,
87 &result);
88 if (!NT_STATUS_IS_OK(status)) {
89 return status;
91 if (!W_ERROR_IS_OK(result)) {
92 *pwerr = result;
93 return status;
96 if (data) {
97 *data = IVAL(blob.data, 0);
100 return status;
103 NTSTATUS dcerpc_winreg_query_binary(TALLOC_CTX *mem_ctx,
104 struct dcerpc_binding_handle *h,
105 struct policy_handle *key_handle,
106 const char *value,
107 DATA_BLOB *data,
108 WERROR *pwerr)
110 struct winreg_String wvalue;
111 enum winreg_Type type;
112 WERROR result = WERR_OK;
113 uint32_t value_len = 0;
114 uint32_t data_size = 0;
115 NTSTATUS status;
116 DATA_BLOB blob;
118 wvalue.name = value;
120 status = dcerpc_winreg_QueryValue(h,
121 mem_ctx,
122 key_handle,
123 &wvalue,
124 &type,
125 NULL,
126 &data_size,
127 &value_len,
128 &result);
129 if (!NT_STATUS_IS_OK(status)) {
130 return status;
132 if (!W_ERROR_IS_OK(result)) {
133 *pwerr = result;
134 return status;
137 if (type != REG_BINARY) {
138 *pwerr = WERR_INVALID_DATATYPE;
139 return status;
142 blob = data_blob_talloc(mem_ctx, NULL, data_size);
143 if (blob.data == NULL) {
144 *pwerr = WERR_NOMEM;
145 return status;
147 value_len = 0;
149 status = dcerpc_winreg_QueryValue(h,
150 mem_ctx,
151 key_handle,
152 &wvalue,
153 &type,
154 blob.data,
155 &data_size,
156 &value_len,
157 &result);
158 if (!NT_STATUS_IS_OK(status)) {
159 return status;
161 if (!W_ERROR_IS_OK(result)) {
162 *pwerr = result;
163 return status;
166 if (data) {
167 data->data = blob.data;
168 data->length = blob.length;
171 return status;
174 NTSTATUS dcerpc_winreg_query_multi_sz(TALLOC_CTX *mem_ctx,
175 struct dcerpc_binding_handle *h,
176 struct policy_handle *key_handle,
177 const char *value,
178 const char ***data,
179 WERROR *pwerr)
181 struct winreg_String wvalue;
182 enum winreg_Type type;
183 WERROR result = WERR_OK;
184 uint32_t value_len = 0;
185 uint32_t data_size = 0;
186 NTSTATUS status;
187 DATA_BLOB blob;
189 wvalue.name = value;
191 status = dcerpc_winreg_QueryValue(h,
192 mem_ctx,
193 key_handle,
194 &wvalue,
195 &type,
196 NULL,
197 &data_size,
198 &value_len,
199 &result);
200 if (!NT_STATUS_IS_OK(status)) {
201 return status;
203 if (!W_ERROR_IS_OK(result)) {
204 *pwerr = result;
205 return status;
208 if (type != REG_MULTI_SZ) {
209 *pwerr = WERR_INVALID_DATATYPE;
210 return status;
213 blob = data_blob_talloc(mem_ctx, NULL, data_size);
214 if (blob.data == NULL) {
215 *pwerr = WERR_NOMEM;
216 return status;
218 value_len = 0;
220 status = dcerpc_winreg_QueryValue(h,
221 mem_ctx,
222 key_handle,
223 &wvalue,
224 &type,
225 blob.data,
226 &data_size,
227 &value_len,
228 &result);
229 if (!NT_STATUS_IS_OK(status)) {
230 return status;
232 if (!W_ERROR_IS_OK(result)) {
233 *pwerr = result;
234 return status;
237 if (data) {
238 bool ok;
240 ok = pull_reg_multi_sz(mem_ctx, &blob, data);
241 if (!ok) {
242 *pwerr = WERR_NOMEM;
246 return status;
249 NTSTATUS dcerpc_winreg_query_sz(TALLOC_CTX *mem_ctx,
250 struct dcerpc_binding_handle *h,
251 struct policy_handle *key_handle,
252 const char *value,
253 const char **data,
254 WERROR *pwerr)
256 struct winreg_String wvalue;
257 enum winreg_Type type;
258 WERROR result = WERR_OK;
259 uint32_t value_len = 0;
260 uint32_t data_size = 0;
261 NTSTATUS status;
262 DATA_BLOB blob;
264 wvalue.name = value;
266 status = dcerpc_winreg_QueryValue(h,
267 mem_ctx,
268 key_handle,
269 &wvalue,
270 &type,
271 NULL,
272 &data_size,
273 &value_len,
274 &result);
275 if (!NT_STATUS_IS_OK(status)) {
276 return status;
278 if (!W_ERROR_IS_OK(result)) {
279 *pwerr = result;
280 return status;
283 if (type != REG_SZ) {
284 *pwerr = WERR_INVALID_DATATYPE;
285 return status;
288 blob = data_blob_talloc(mem_ctx, NULL, data_size);
289 if (blob.data == NULL) {
290 *pwerr = WERR_NOMEM;
291 return status;
293 value_len = 0;
295 status = dcerpc_winreg_QueryValue(h,
296 mem_ctx,
297 key_handle,
298 &wvalue,
299 &type,
300 blob.data,
301 &data_size,
302 &value_len,
303 &result);
304 if (!NT_STATUS_IS_OK(status)) {
305 return status;
307 if (!W_ERROR_IS_OK(result)) {
308 *pwerr = result;
309 return status;
312 if (data) {
313 bool ok;
315 ok = pull_reg_sz(mem_ctx, &blob, data);
316 if (!ok) {
317 *pwerr = WERR_NOMEM;
321 return status;
324 NTSTATUS dcerpc_winreg_query_sd(TALLOC_CTX *mem_ctx,
325 struct dcerpc_binding_handle *h,
326 struct policy_handle *key_handle,
327 const char *value,
328 struct security_descriptor **data,
329 WERROR *pwerr)
331 WERROR result = WERR_OK;
332 NTSTATUS status;
333 DATA_BLOB blob;
335 status = dcerpc_winreg_query_binary(mem_ctx,
337 key_handle,
338 value,
339 &blob,
340 &result);
341 if (!NT_STATUS_IS_OK(status)) {
342 return status;
344 if (!W_ERROR_IS_OK(result)) {
345 *pwerr = result;
346 return status;
349 if (data) {
350 struct security_descriptor *sd;
351 enum ndr_err_code ndr_err;
353 sd = talloc_zero(mem_ctx, struct security_descriptor);
354 if (sd == NULL) {
355 *pwerr = WERR_NOMEM;
356 return NT_STATUS_OK;
359 ndr_err = ndr_pull_struct_blob(&blob,
362 (ndr_pull_flags_fn_t) ndr_pull_security_descriptor);
363 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
364 DEBUG(2, ("dcerpc_winreg_query_sd: Failed to marshall "
365 "security descriptor\n"));
366 *pwerr = WERR_NOMEM;
367 return NT_STATUS_OK;
370 *data = sd;
373 return status;
376 NTSTATUS dcerpc_winreg_set_dword(TALLOC_CTX *mem_ctx,
377 struct dcerpc_binding_handle *h,
378 struct policy_handle *key_handle,
379 const char *value,
380 uint32_t data,
381 WERROR *pwerr)
383 struct winreg_String wvalue = { 0, };
384 DATA_BLOB blob;
385 WERROR result = WERR_OK;
386 NTSTATUS status;
388 wvalue.name = value;
389 blob = data_blob_talloc(mem_ctx, NULL, 4);
390 SIVAL(blob.data, 0, data);
392 status = dcerpc_winreg_SetValue(h,
393 mem_ctx,
394 key_handle,
395 wvalue,
396 REG_DWORD,
397 blob.data,
398 blob.length,
399 &result);
400 if (!NT_STATUS_IS_OK(status)) {
401 return status;
403 if (!W_ERROR_IS_OK(result)) {
404 *pwerr = result;
407 return status;
410 NTSTATUS dcerpc_winreg_set_sz(TALLOC_CTX *mem_ctx,
411 struct dcerpc_binding_handle *h,
412 struct policy_handle *key_handle,
413 const char *value,
414 const char *data,
415 WERROR *pwerr)
417 struct winreg_String wvalue = { 0, };
418 DATA_BLOB blob;
419 WERROR result = WERR_OK;
420 NTSTATUS status;
422 wvalue.name = value;
423 if (data == NULL) {
424 blob = data_blob_string_const("");
425 } else {
426 if (!push_reg_sz(mem_ctx, &blob, data)) {
427 DEBUG(2, ("dcerpc_winreg_set_sz: Could not marshall "
428 "string %s for %s\n",
429 data, wvalue.name));
430 *pwerr = WERR_NOMEM;
431 return NT_STATUS_OK;
435 status = dcerpc_winreg_SetValue(h,
436 mem_ctx,
437 key_handle,
438 wvalue,
439 REG_SZ,
440 blob.data,
441 blob.length,
442 &result);
443 if (!NT_STATUS_IS_OK(status)) {
444 return status;
446 if (!W_ERROR_IS_OK(result)) {
447 *pwerr = result;
450 return status;
453 NTSTATUS dcerpc_winreg_set_expand_sz(TALLOC_CTX *mem_ctx,
454 struct dcerpc_binding_handle *h,
455 struct policy_handle *key_handle,
456 const char *value,
457 const char *data,
458 WERROR *pwerr)
460 struct winreg_String wvalue = { 0, };
461 DATA_BLOB blob;
462 WERROR result = WERR_OK;
463 NTSTATUS status;
465 wvalue.name = value;
466 if (data == NULL) {
467 blob = data_blob_string_const("");
468 } else {
469 if (!push_reg_sz(mem_ctx, &blob, data)) {
470 DEBUG(2, ("dcerpc_winreg_set_expand_sz: Could not marshall "
471 "string %s for %s\n",
472 data, wvalue.name));
473 *pwerr = WERR_NOMEM;
474 return NT_STATUS_OK;
478 status = dcerpc_winreg_SetValue(h,
479 mem_ctx,
480 key_handle,
481 wvalue,
482 REG_EXPAND_SZ,
483 blob.data,
484 blob.length,
485 &result);
486 if (!NT_STATUS_IS_OK(status)) {
487 return status;
489 if (!W_ERROR_IS_OK(result)) {
490 *pwerr = result;
493 return status;
496 NTSTATUS dcerpc_winreg_set_multi_sz(TALLOC_CTX *mem_ctx,
497 struct dcerpc_binding_handle *h,
498 struct policy_handle *key_handle,
499 const char *value,
500 const char **data,
501 WERROR *pwerr)
503 struct winreg_String wvalue = { 0, };
504 DATA_BLOB blob;
505 WERROR result = WERR_OK;
506 NTSTATUS status;
508 wvalue.name = value;
509 if (!push_reg_multi_sz(mem_ctx, &blob, data)) {
510 DEBUG(2, ("dcerpc_winreg_set_multi_sz: Could not marshall "
511 "string multi sz for %s\n",
512 wvalue.name));
513 *pwerr = WERR_NOMEM;
514 return NT_STATUS_OK;
517 status = dcerpc_winreg_SetValue(h,
518 mem_ctx,
519 key_handle,
520 wvalue,
521 REG_MULTI_SZ,
522 blob.data,
523 blob.length,
524 &result);
525 if (!NT_STATUS_IS_OK(status)) {
526 return status;
528 if (!W_ERROR_IS_OK(result)) {
529 *pwerr = result;
532 return status;
535 NTSTATUS dcerpc_winreg_set_binary(TALLOC_CTX *mem_ctx,
536 struct dcerpc_binding_handle *h,
537 struct policy_handle *key_handle,
538 const char *value,
539 DATA_BLOB *data,
540 WERROR *pwerr)
542 struct winreg_String wvalue = { 0, };
543 WERROR result = WERR_OK;
544 NTSTATUS status;
546 wvalue.name = value;
548 status = dcerpc_winreg_SetValue(h,
549 mem_ctx,
550 key_handle,
551 wvalue,
552 REG_BINARY,
553 data->data,
554 data->length,
555 &result);
556 if (!NT_STATUS_IS_OK(status)) {
557 return status;
559 if (!W_ERROR_IS_OK(result)) {
560 *pwerr = result;
563 return status;
566 NTSTATUS dcerpc_winreg_set_sd(TALLOC_CTX *mem_ctx,
567 struct dcerpc_binding_handle *h,
568 struct policy_handle *key_handle,
569 const char *value,
570 const struct security_descriptor *data,
571 WERROR *pwerr)
573 enum ndr_err_code ndr_err;
574 DATA_BLOB blob;
576 ndr_err = ndr_push_struct_blob(&blob,
577 mem_ctx,
578 data,
579 (ndr_push_flags_fn_t) ndr_push_security_descriptor);
580 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
581 DEBUG(2, ("dcerpc_winreg_set_sd: Failed to marshall security "
582 "descriptor\n"));
583 *pwerr = WERR_NOMEM;
584 return NT_STATUS_OK;
587 return dcerpc_winreg_set_binary(mem_ctx,
589 key_handle,
590 value,
591 &blob,
592 pwerr);
595 NTSTATUS dcerpc_winreg_add_multi_sz(TALLOC_CTX *mem_ctx,
596 struct dcerpc_binding_handle *h,
597 struct policy_handle *key_handle,
598 const char *value,
599 const char *data,
600 WERROR *pwerr)
602 const char **a = NULL;
603 const char **p;
604 uint32_t i;
605 WERROR result = WERR_OK;
606 NTSTATUS status;
608 status = dcerpc_winreg_query_multi_sz(mem_ctx,
610 key_handle,
611 value,
613 &result);
615 /* count the elements */
616 for (p = a, i = 0; p && *p; p++, i++);
618 p = TALLOC_REALLOC_ARRAY(mem_ctx, a, const char *, i + 2);
619 if (p == NULL) {
620 *pwerr = WERR_NOMEM;
621 return NT_STATUS_OK;
624 p[i] = data;
625 p[i + 1] = NULL;
627 status = dcerpc_winreg_set_multi_sz(mem_ctx,
629 key_handle,
630 value,
632 pwerr);
634 return status;
637 NTSTATUS dcerpc_winreg_enum_keys(TALLOC_CTX *mem_ctx,
638 struct dcerpc_binding_handle *h,
639 struct policy_handle *key_hnd,
640 uint32_t *pnum_subkeys,
641 const char ***psubkeys,
642 WERROR *pwerr)
644 const char **subkeys;
645 uint32_t num_subkeys, max_subkeylen, max_classlen;
646 uint32_t num_values, max_valnamelen, max_valbufsize;
647 uint32_t i;
648 NTTIME last_changed_time;
649 uint32_t secdescsize;
650 struct winreg_String classname;
651 WERROR result = WERR_OK;
652 NTSTATUS status;
653 TALLOC_CTX *tmp_ctx;
655 tmp_ctx = talloc_stackframe();
656 if (tmp_ctx == NULL) {
657 return NT_STATUS_NO_MEMORY;
660 ZERO_STRUCT(classname);
662 status = dcerpc_winreg_QueryInfoKey(h,
663 tmp_ctx,
664 key_hnd,
665 &classname,
666 &num_subkeys,
667 &max_subkeylen,
668 &max_classlen,
669 &num_values,
670 &max_valnamelen,
671 &max_valbufsize,
672 &secdescsize,
673 &last_changed_time,
674 &result);
675 if (!NT_STATUS_IS_OK(status)) {
676 goto error;
678 if (!W_ERROR_IS_OK(result)) {
679 *pwerr = result;
680 goto error;
683 subkeys = talloc_zero_array(tmp_ctx, const char *, num_subkeys + 2);
684 if (subkeys == NULL) {
685 *pwerr = WERR_NOMEM;
686 goto error;
689 if (num_subkeys == 0) {
690 subkeys[0] = talloc_strdup(subkeys, "");
691 if (subkeys[0] == NULL) {
692 *pwerr = WERR_NOMEM;
693 goto error;
695 *pnum_subkeys = 0;
696 if (psubkeys) {
697 *psubkeys = talloc_move(mem_ctx, &subkeys);
700 TALLOC_FREE(tmp_ctx);
701 return NT_STATUS_OK;
704 for (i = 0; i < num_subkeys; i++) {
705 char c = '\0';
706 char n = '\0';
707 char *name = NULL;
708 struct winreg_StringBuf class_buf;
709 struct winreg_StringBuf name_buf;
710 NTTIME modtime;
712 class_buf.name = &c;
713 class_buf.size = max_classlen + 2;
714 class_buf.length = 0;
716 name_buf.name = &n;
717 name_buf.size = max_subkeylen + 2;
718 name_buf.length = 0;
720 ZERO_STRUCT(modtime);
722 status = dcerpc_winreg_EnumKey(h,
723 tmp_ctx,
724 key_hnd,
726 &name_buf,
727 &class_buf,
728 &modtime,
729 &result);
730 if (!NT_STATUS_IS_OK(status)) {
731 DEBUG(5, ("dcerpc_winreg_enum_keys: Could not enumerate keys: %s\n",
732 nt_errstr(status)));
733 goto error;
736 if (W_ERROR_EQUAL(result, WERR_NO_MORE_ITEMS) ) {
737 *pwerr = WERR_OK;
738 break;
740 if (!W_ERROR_IS_OK(result)) {
741 DEBUG(5, ("dcerpc_winreg_enum_keys: Could not enumerate keys: %s\n",
742 win_errstr(result)));
743 *pwerr = result;
744 goto error;
747 if (name_buf.name == NULL) {
748 *pwerr = WERR_INVALID_PARAMETER;
749 goto error;
752 name = talloc_strdup(subkeys, name_buf.name);
753 if (name == NULL) {
754 *pwerr = WERR_NOMEM;
755 goto error;
758 subkeys[i] = name;
761 *pnum_subkeys = num_subkeys;
762 if (psubkeys) {
763 *psubkeys = talloc_move(mem_ctx, &subkeys);
766 error:
767 TALLOC_FREE(tmp_ctx);
769 return status;
772 /* vim: set ts=8 sw=8 noet cindent syntax=c.doxygen: */