s3: Fix Coverity ID 2195: NO_EFFECT
[Samba.git] / source3 / rpc_client / cli_winreg.c
blob67f85738642d77d41192ef8bbc63336c29933336
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"
27 NTSTATUS dcerpc_winreg_query_dword(TALLOC_CTX *mem_ctx,
28 struct dcerpc_binding_handle *h,
29 struct policy_handle *key_handle,
30 const char *value,
31 uint32_t *data,
32 WERROR *pwerr)
34 struct winreg_String wvalue;
35 enum winreg_Type type;
36 uint32_t value_len = 0;
37 uint32_t data_size = 0;
38 WERROR result = WERR_OK;
39 NTSTATUS status;
40 DATA_BLOB blob;
42 wvalue.name = value;
44 status = dcerpc_winreg_QueryValue(h,
45 mem_ctx,
46 key_handle,
47 &wvalue,
48 &type,
49 NULL,
50 &data_size,
51 &value_len,
52 &result);
53 if (!NT_STATUS_IS_OK(status)) {
54 return status;
56 if (!W_ERROR_IS_OK(result)) {
57 *pwerr = result;
58 return status;
61 if (type != REG_DWORD) {
62 *pwerr = WERR_INVALID_DATATYPE;
63 return status;
66 if (data_size != 4) {
67 *pwerr = WERR_INVALID_DATA;
68 return status;
71 blob = data_blob_talloc(mem_ctx, NULL, data_size);
72 if (blob.data == NULL) {
73 *pwerr = WERR_NOMEM;
74 return status;
76 value_len = 0;
78 status = dcerpc_winreg_QueryValue(h,
79 mem_ctx,
80 key_handle,
81 &wvalue,
82 &type,
83 blob.data,
84 &data_size,
85 &value_len,
86 &result);
87 if (!NT_STATUS_IS_OK(status)) {
88 return status;
90 if (!W_ERROR_IS_OK(result)) {
91 *pwerr = result;
92 return status;
95 if (data) {
96 *data = IVAL(blob.data, 0);
99 return status;
102 NTSTATUS dcerpc_winreg_query_binary(TALLOC_CTX *mem_ctx,
103 struct dcerpc_binding_handle *h,
104 struct policy_handle *key_handle,
105 const char *value,
106 DATA_BLOB *data,
107 WERROR *pwerr)
109 struct winreg_String wvalue;
110 enum winreg_Type type;
111 WERROR result = WERR_OK;
112 uint32_t value_len = 0;
113 uint32_t data_size = 0;
114 NTSTATUS status;
115 DATA_BLOB blob;
117 wvalue.name = value;
119 status = dcerpc_winreg_QueryValue(h,
120 mem_ctx,
121 key_handle,
122 &wvalue,
123 &type,
124 NULL,
125 &data_size,
126 &value_len,
127 &result);
128 if (!NT_STATUS_IS_OK(status)) {
129 return status;
131 if (!W_ERROR_IS_OK(result)) {
132 *pwerr = result;
133 return status;
136 if (type != REG_BINARY) {
137 *pwerr = WERR_INVALID_DATATYPE;
138 return status;
141 blob = data_blob_talloc(mem_ctx, NULL, data_size);
142 if (blob.data == NULL) {
143 *pwerr = WERR_NOMEM;
144 return status;
146 value_len = 0;
148 status = dcerpc_winreg_QueryValue(h,
149 mem_ctx,
150 key_handle,
151 &wvalue,
152 &type,
153 blob.data,
154 &data_size,
155 &value_len,
156 &result);
157 if (!NT_STATUS_IS_OK(status)) {
158 return status;
160 if (!W_ERROR_IS_OK(result)) {
161 *pwerr = result;
162 return status;
165 if (data) {
166 data->data = blob.data;
167 data->length = blob.length;
170 return status;
173 NTSTATUS dcerpc_winreg_query_multi_sz(TALLOC_CTX *mem_ctx,
174 struct dcerpc_binding_handle *h,
175 struct policy_handle *key_handle,
176 const char *value,
177 const char ***data,
178 WERROR *pwerr)
180 struct winreg_String wvalue;
181 enum winreg_Type type;
182 WERROR result = WERR_OK;
183 uint32_t value_len = 0;
184 uint32_t data_size = 0;
185 NTSTATUS status;
186 DATA_BLOB blob;
188 wvalue.name = value;
190 status = dcerpc_winreg_QueryValue(h,
191 mem_ctx,
192 key_handle,
193 &wvalue,
194 &type,
195 NULL,
196 &data_size,
197 &value_len,
198 &result);
199 if (!NT_STATUS_IS_OK(status)) {
200 return status;
202 if (!W_ERROR_IS_OK(result)) {
203 *pwerr = result;
204 return status;
207 if (type != REG_MULTI_SZ) {
208 *pwerr = WERR_INVALID_DATATYPE;
209 return status;
212 blob = data_blob_talloc(mem_ctx, NULL, data_size);
213 if (blob.data == NULL) {
214 *pwerr = WERR_NOMEM;
215 return status;
217 value_len = 0;
219 status = dcerpc_winreg_QueryValue(h,
220 mem_ctx,
221 key_handle,
222 &wvalue,
223 &type,
224 blob.data,
225 &data_size,
226 &value_len,
227 &result);
228 if (!NT_STATUS_IS_OK(status)) {
229 return status;
231 if (!W_ERROR_IS_OK(result)) {
232 *pwerr = result;
233 return status;
236 if (data) {
237 bool ok;
239 ok = pull_reg_multi_sz(mem_ctx, &blob, data);
240 if (!ok) {
241 *pwerr = WERR_NOMEM;
245 return status;
248 NTSTATUS dcerpc_winreg_query_sz(TALLOC_CTX *mem_ctx,
249 struct dcerpc_binding_handle *h,
250 struct policy_handle *key_handle,
251 const char *value,
252 const char **data,
253 WERROR *pwerr)
255 struct winreg_String wvalue;
256 enum winreg_Type type;
257 WERROR result = WERR_OK;
258 uint32_t value_len = 0;
259 uint32_t data_size = 0;
260 NTSTATUS status;
261 DATA_BLOB blob;
263 wvalue.name = value;
265 status = dcerpc_winreg_QueryValue(h,
266 mem_ctx,
267 key_handle,
268 &wvalue,
269 &type,
270 NULL,
271 &data_size,
272 &value_len,
273 &result);
274 if (!NT_STATUS_IS_OK(status)) {
275 return status;
277 if (!W_ERROR_IS_OK(result)) {
278 *pwerr = result;
279 return status;
282 if (type != REG_SZ) {
283 *pwerr = WERR_INVALID_DATATYPE;
284 return status;
287 blob = data_blob_talloc(mem_ctx, NULL, data_size);
288 if (blob.data == NULL) {
289 *pwerr = WERR_NOMEM;
290 return status;
292 value_len = 0;
294 status = dcerpc_winreg_QueryValue(h,
295 mem_ctx,
296 key_handle,
297 &wvalue,
298 &type,
299 blob.data,
300 &data_size,
301 &value_len,
302 &result);
303 if (!NT_STATUS_IS_OK(status)) {
304 return status;
306 if (!W_ERROR_IS_OK(result)) {
307 *pwerr = result;
308 return status;
311 if (data) {
312 bool ok;
314 ok = pull_reg_sz(mem_ctx, &blob, data);
315 if (!ok) {
316 *pwerr = WERR_NOMEM;
320 return status;
323 NTSTATUS dcerpc_winreg_query_sd(TALLOC_CTX *mem_ctx,
324 struct dcerpc_binding_handle *h,
325 struct policy_handle *key_handle,
326 const char *value,
327 struct security_descriptor **data,
328 WERROR *pwerr)
330 WERROR result = WERR_OK;
331 NTSTATUS status;
332 DATA_BLOB blob;
334 status = dcerpc_winreg_query_binary(mem_ctx,
336 key_handle,
337 value,
338 &blob,
339 &result);
340 if (!NT_STATUS_IS_OK(status)) {
341 return status;
343 if (!W_ERROR_IS_OK(result)) {
344 *pwerr = result;
345 return status;
348 if (data) {
349 struct security_descriptor *sd;
350 enum ndr_err_code ndr_err;
352 sd = talloc_zero(mem_ctx, struct security_descriptor);
353 if (sd == NULL) {
354 *pwerr = WERR_NOMEM;
355 return NT_STATUS_OK;
358 ndr_err = ndr_pull_struct_blob(&blob,
361 (ndr_pull_flags_fn_t) ndr_pull_security_descriptor);
362 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
363 DEBUG(2, ("dcerpc_winreg_query_sd: Failed to marshall "
364 "security descriptor\n"));
365 *pwerr = WERR_NOMEM;
366 return NT_STATUS_OK;
369 *data = sd;
372 return status;
375 NTSTATUS dcerpc_winreg_set_dword(TALLOC_CTX *mem_ctx,
376 struct dcerpc_binding_handle *h,
377 struct policy_handle *key_handle,
378 const char *value,
379 uint32_t data,
380 WERROR *pwerr)
382 struct winreg_String wvalue = { 0, };
383 DATA_BLOB blob;
384 WERROR result = WERR_OK;
385 NTSTATUS status;
387 wvalue.name = value;
388 blob = data_blob_talloc(mem_ctx, NULL, 4);
389 SIVAL(blob.data, 0, data);
391 status = dcerpc_winreg_SetValue(h,
392 mem_ctx,
393 key_handle,
394 wvalue,
395 REG_DWORD,
396 blob.data,
397 blob.length,
398 &result);
399 if (!NT_STATUS_IS_OK(status)) {
400 return status;
402 if (!W_ERROR_IS_OK(result)) {
403 *pwerr = result;
406 return status;
409 NTSTATUS dcerpc_winreg_set_sz(TALLOC_CTX *mem_ctx,
410 struct dcerpc_binding_handle *h,
411 struct policy_handle *key_handle,
412 const char *value,
413 const char *data,
414 WERROR *pwerr)
416 struct winreg_String wvalue = { 0, };
417 DATA_BLOB blob;
418 WERROR result = WERR_OK;
419 NTSTATUS status;
421 wvalue.name = value;
422 if (data == NULL) {
423 blob = data_blob_string_const("");
424 } else {
425 if (!push_reg_sz(mem_ctx, &blob, data)) {
426 DEBUG(2, ("dcerpc_winreg_set_sz: Could not marshall "
427 "string %s for %s\n",
428 data, wvalue.name));
429 *pwerr = WERR_NOMEM;
430 return NT_STATUS_OK;
434 status = dcerpc_winreg_SetValue(h,
435 mem_ctx,
436 key_handle,
437 wvalue,
438 REG_SZ,
439 blob.data,
440 blob.length,
441 &result);
442 if (!NT_STATUS_IS_OK(status)) {
443 return status;
445 if (!W_ERROR_IS_OK(result)) {
446 *pwerr = result;
449 return status;
452 NTSTATUS dcerpc_winreg_set_expand_sz(TALLOC_CTX *mem_ctx,
453 struct dcerpc_binding_handle *h,
454 struct policy_handle *key_handle,
455 const char *value,
456 const char *data,
457 WERROR *pwerr)
459 struct winreg_String wvalue = { 0, };
460 DATA_BLOB blob;
461 WERROR result = WERR_OK;
462 NTSTATUS status;
464 wvalue.name = value;
465 if (data == NULL) {
466 blob = data_blob_string_const("");
467 } else {
468 if (!push_reg_sz(mem_ctx, &blob, data)) {
469 DEBUG(2, ("dcerpc_winreg_set_expand_sz: Could not marshall "
470 "string %s for %s\n",
471 data, wvalue.name));
472 *pwerr = WERR_NOMEM;
473 return NT_STATUS_OK;
477 status = dcerpc_winreg_SetValue(h,
478 mem_ctx,
479 key_handle,
480 wvalue,
481 REG_EXPAND_SZ,
482 blob.data,
483 blob.length,
484 &result);
485 if (!NT_STATUS_IS_OK(status)) {
486 return status;
488 if (!W_ERROR_IS_OK(result)) {
489 *pwerr = result;
492 return status;
495 NTSTATUS dcerpc_winreg_set_multi_sz(TALLOC_CTX *mem_ctx,
496 struct dcerpc_binding_handle *h,
497 struct policy_handle *key_handle,
498 const char *value,
499 const char **data,
500 WERROR *pwerr)
502 struct winreg_String wvalue = { 0, };
503 DATA_BLOB blob;
504 WERROR result = WERR_OK;
505 NTSTATUS status;
507 wvalue.name = value;
508 if (!push_reg_multi_sz(mem_ctx, &blob, data)) {
509 DEBUG(2, ("dcerpc_winreg_set_multi_sz: Could not marshall "
510 "string multi sz for %s\n",
511 wvalue.name));
512 *pwerr = WERR_NOMEM;
513 return NT_STATUS_OK;
516 status = dcerpc_winreg_SetValue(h,
517 mem_ctx,
518 key_handle,
519 wvalue,
520 REG_MULTI_SZ,
521 blob.data,
522 blob.length,
523 &result);
524 if (!NT_STATUS_IS_OK(status)) {
525 return status;
527 if (!W_ERROR_IS_OK(result)) {
528 *pwerr = result;
531 return status;
534 NTSTATUS dcerpc_winreg_set_binary(TALLOC_CTX *mem_ctx,
535 struct dcerpc_binding_handle *h,
536 struct policy_handle *key_handle,
537 const char *value,
538 DATA_BLOB *data,
539 WERROR *pwerr)
541 struct winreg_String wvalue = { 0, };
542 WERROR result = WERR_OK;
543 NTSTATUS status;
545 wvalue.name = value;
547 status = dcerpc_winreg_SetValue(h,
548 mem_ctx,
549 key_handle,
550 wvalue,
551 REG_BINARY,
552 data->data,
553 data->length,
554 &result);
555 if (!NT_STATUS_IS_OK(status)) {
556 return status;
558 if (!W_ERROR_IS_OK(result)) {
559 *pwerr = result;
562 return status;
565 NTSTATUS dcerpc_winreg_set_sd(TALLOC_CTX *mem_ctx,
566 struct dcerpc_binding_handle *h,
567 struct policy_handle *key_handle,
568 const char *value,
569 const struct security_descriptor *data,
570 WERROR *pwerr)
572 enum ndr_err_code ndr_err;
573 DATA_BLOB blob;
575 ndr_err = ndr_push_struct_blob(&blob,
576 mem_ctx,
577 data,
578 (ndr_push_flags_fn_t) ndr_push_security_descriptor);
579 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
580 DEBUG(2, ("dcerpc_winreg_set_sd: Failed to marshall security "
581 "descriptor\n"));
582 *pwerr = WERR_NOMEM;
583 return NT_STATUS_OK;
586 return dcerpc_winreg_set_binary(mem_ctx,
588 key_handle,
589 value,
590 &blob,
591 pwerr);
594 NTSTATUS dcerpc_winreg_add_multi_sz(TALLOC_CTX *mem_ctx,
595 struct dcerpc_binding_handle *h,
596 struct policy_handle *key_handle,
597 const char *value,
598 const char *data,
599 WERROR *pwerr)
601 const char **a = NULL;
602 const char **p;
603 uint32_t i;
604 WERROR result = WERR_OK;
605 NTSTATUS status;
607 status = dcerpc_winreg_query_multi_sz(mem_ctx,
609 key_handle,
610 value,
612 &result);
614 /* count the elements */
615 for (p = a, i = 0; p && *p; p++, i++);
617 p = TALLOC_REALLOC_ARRAY(mem_ctx, a, const char *, i + 2);
618 if (p == NULL) {
619 *pwerr = WERR_NOMEM;
620 return NT_STATUS_OK;
623 p[i] = data;
624 p[i + 1] = NULL;
626 status = dcerpc_winreg_set_multi_sz(mem_ctx,
628 key_handle,
629 value,
631 pwerr);
633 return status;
636 NTSTATUS dcerpc_winreg_enum_keys(TALLOC_CTX *mem_ctx,
637 struct dcerpc_binding_handle *h,
638 struct policy_handle *key_hnd,
639 uint32_t *pnum_subkeys,
640 const char ***psubkeys,
641 WERROR *pwerr)
643 const char **subkeys;
644 uint32_t num_subkeys, max_subkeylen, max_classlen;
645 uint32_t num_values, max_valnamelen, max_valbufsize;
646 uint32_t i;
647 NTTIME last_changed_time;
648 uint32_t secdescsize;
649 struct winreg_String classname;
650 WERROR result = WERR_OK;
651 NTSTATUS status;
652 TALLOC_CTX *tmp_ctx;
654 tmp_ctx = talloc_stackframe();
655 if (tmp_ctx == NULL) {
656 return NT_STATUS_NO_MEMORY;
659 ZERO_STRUCT(classname);
661 status = dcerpc_winreg_QueryInfoKey(h,
662 tmp_ctx,
663 key_hnd,
664 &classname,
665 &num_subkeys,
666 &max_subkeylen,
667 &max_classlen,
668 &num_values,
669 &max_valnamelen,
670 &max_valbufsize,
671 &secdescsize,
672 &last_changed_time,
673 &result);
674 if (!NT_STATUS_IS_OK(status)) {
675 goto error;
677 if (!W_ERROR_IS_OK(result)) {
678 *pwerr = result;
679 goto error;
682 subkeys = talloc_zero_array(tmp_ctx, const char *, num_subkeys + 2);
683 if (subkeys == NULL) {
684 *pwerr = WERR_NOMEM;
685 goto error;
688 if (num_subkeys == 0) {
689 subkeys[0] = talloc_strdup(subkeys, "");
690 if (subkeys[0] == NULL) {
691 *pwerr = WERR_NOMEM;
692 goto error;
694 *pnum_subkeys = 0;
695 if (psubkeys) {
696 *psubkeys = talloc_move(mem_ctx, &subkeys);
699 TALLOC_FREE(tmp_ctx);
700 return NT_STATUS_OK;
703 for (i = 0; i < num_subkeys; i++) {
704 char c = '\0';
705 char n = '\0';
706 char *name = NULL;
707 struct winreg_StringBuf class_buf;
708 struct winreg_StringBuf name_buf;
709 NTTIME modtime;
711 class_buf.name = &c;
712 class_buf.size = max_classlen + 2;
713 class_buf.length = 0;
715 name_buf.name = &n;
716 name_buf.size = max_subkeylen + 2;
717 name_buf.length = 0;
719 ZERO_STRUCT(modtime);
721 status = dcerpc_winreg_EnumKey(h,
722 tmp_ctx,
723 key_hnd,
725 &name_buf,
726 &class_buf,
727 &modtime,
728 &result);
729 if (!NT_STATUS_IS_OK(status)) {
730 DEBUG(5, ("dcerpc_winreg_enum_keys: Could not enumerate keys: %s\n",
731 nt_errstr(status)));
732 goto error;
735 if (W_ERROR_EQUAL(result, WERR_NO_MORE_ITEMS) ) {
736 *pwerr = WERR_OK;
737 break;
739 if (!W_ERROR_IS_OK(result)) {
740 DEBUG(5, ("dcerpc_winreg_enum_keys: Could not enumerate keys: %s\n",
741 win_errstr(result)));
742 *pwerr = result;
743 goto error;
746 if (name_buf.name == NULL) {
747 *pwerr = WERR_INVALID_PARAMETER;
748 goto error;
751 name = talloc_strdup(subkeys, name_buf.name);
752 if (name == NULL) {
753 *pwerr = WERR_NOMEM;
754 goto error;
757 subkeys[i] = name;
760 *pnum_subkeys = num_subkeys;
761 if (psubkeys) {
762 *psubkeys = talloc_move(mem_ctx, &subkeys);
765 error:
766 TALLOC_FREE(tmp_ctx);
768 return status;
771 /* vim: set ts=8 sw=8 noet cindent syntax=c.doxygen: */