Fix starvation of pending writes in CTDB queues
[Samba.git] / source3 / rpcclient / cmd_winreg.c
blob26fa146ceddc806c3a66cc569ce009e1a7618900
1 /*
2 Unix SMB/CIFS implementation.
3 RPC pipe client
5 Copyright (C) Guenther Deschner 2009
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.
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.
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/>.
21 #include "includes.h"
22 #include "rpcclient.h"
23 #include "../librpc/gen_ndr/ndr_winreg_c.h"
24 #include "../librpc/gen_ndr/ndr_misc.h"
26 static WERROR cmd_winreg_enumkeys(struct rpc_pipe_client *cli,
27 TALLOC_CTX *mem_ctx, int argc,
28 const char **argv)
30 NTSTATUS status;
31 WERROR werr;
32 struct policy_handle handle;
33 uint32_t enum_index = 0;
34 struct winreg_StringBuf name;
35 struct dcerpc_binding_handle *b = cli->binding_handle;
37 if (argc < 2) {
38 printf("usage: %s [name]\n", argv[0]);
39 return WERR_OK;
42 status = dcerpc_winreg_OpenHKLM(b, mem_ctx,
43 NULL,
44 SEC_FLAG_MAXIMUM_ALLOWED,
45 &handle,
46 &werr);
47 if (!NT_STATUS_IS_OK(status)) {
48 return ntstatus_to_werror(status);
50 if (!W_ERROR_IS_OK(werr)) {
51 return werr;
54 ZERO_STRUCT(name);
56 name.name = argv[1];
57 name.length = strlen_m_term_null(name.name)*2;
58 name.size = name.length;
60 status = dcerpc_winreg_EnumKey(b, mem_ctx,
61 &handle,
62 enum_index,
63 &name,
64 NULL,
65 NULL,
66 &werr);
67 if (!NT_STATUS_IS_OK(status)) {
68 return ntstatus_to_werror(status);
70 if (!W_ERROR_IS_OK(werr)) {
71 return werr;
74 return WERR_OK;
77 /****************************************************************************
78 ****************************************************************************/
80 static WERROR pull_winreg_Data(TALLOC_CTX *mem_ctx,
81 const DATA_BLOB *blob,
82 union winreg_Data *data,
83 enum winreg_Type type)
85 enum ndr_err_code ndr_err;
86 ndr_err = ndr_pull_union_blob(blob, mem_ctx, data, type,
87 (ndr_pull_flags_fn_t)ndr_pull_winreg_Data);
88 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
89 return WERR_GEN_FAILURE;
91 return WERR_OK;
94 /****************************************************************************
95 ****************************************************************************/
97 static void display_winreg_data(const char *v,
98 enum winreg_Type type,
99 uint8_t *data,
100 uint32_t length)
102 size_t i;
103 union winreg_Data r;
104 DATA_BLOB blob = data_blob_const(data, length);
105 WERROR result;
107 result = pull_winreg_Data(talloc_tos(), &blob, &r, type);
108 if (!W_ERROR_IS_OK(result)) {
109 return;
112 switch (type) {
113 case REG_DWORD:
114 printf("%-20s: REG_DWORD: 0x%08x\n", v, r.value);
115 break;
116 case REG_SZ:
117 printf("%-20s: REG_SZ: %s\n", v, r.string);
118 break;
119 case REG_BINARY: {
120 char *hex = hex_encode_talloc(NULL,
121 r.binary.data, r.binary.length);
122 size_t len;
123 printf("%-20s: REG_BINARY:", v);
124 len = strlen(hex);
125 for (i=0; i<len; i++) {
126 if (hex[i] == '\0') {
127 break;
129 if (i%40 == 0) {
130 putchar('\n');
132 putchar(hex[i]);
134 TALLOC_FREE(hex);
135 putchar('\n');
136 break;
138 case REG_MULTI_SZ:
139 printf("%-20s: REG_MULTI_SZ: ", v);
140 for (i=0; r.string_array[i] != NULL; i++) {
141 printf("%s ", r.string_array[i]);
143 printf("\n");
144 break;
145 default:
146 printf("%-20ss: unknown type 0x%02x:\n", v, type);
147 break;
152 static WERROR cmd_winreg_querymultiplevalues_ex(struct rpc_pipe_client *cli,
153 TALLOC_CTX *mem_ctx, int argc,
154 const char **argv, bool multiplevalues2)
156 NTSTATUS status;
157 WERROR werr;
158 struct policy_handle handle, key_handle;
159 struct winreg_String key_name = { 0, };
160 struct dcerpc_binding_handle *b = cli->binding_handle;
162 struct QueryMultipleValue *values_in, *values_out;
163 uint32_t num_values;
164 uint8_t *buffer = NULL;
165 uint32_t i;
168 if (argc < 2) {
169 printf("usage: %s [key] [value1] [value2] ...\n", argv[0]);
170 return WERR_OK;
173 status = dcerpc_winreg_OpenHKLM(b, mem_ctx,
174 NULL,
175 SEC_FLAG_MAXIMUM_ALLOWED,
176 &handle,
177 &werr);
178 if (!NT_STATUS_IS_OK(status)) {
179 return ntstatus_to_werror(status);
181 if (!W_ERROR_IS_OK(werr)) {
182 return werr;
185 key_name.name = argv[1];
187 status = dcerpc_winreg_OpenKey(b, mem_ctx,
188 &handle,
189 key_name,
190 0, /* options */
191 SEC_FLAG_MAXIMUM_ALLOWED,
192 &key_handle,
193 &werr);
194 if (!NT_STATUS_IS_OK(status)) {
195 return ntstatus_to_werror(status);
197 if (!W_ERROR_IS_OK(werr)) {
198 return werr;
201 num_values = argc-2;
203 values_in = talloc_zero_array(mem_ctx, struct QueryMultipleValue, num_values);
204 if (values_in == NULL) {
205 return WERR_NOT_ENOUGH_MEMORY;
208 values_out = talloc_zero_array(mem_ctx, struct QueryMultipleValue, num_values);
209 if (values_out == NULL) {
210 return WERR_NOT_ENOUGH_MEMORY;
213 for (i=0; i < num_values; i++) {
215 values_in[i].ve_valuename = talloc_zero(values_in, struct winreg_ValNameBuf);
216 if (values_in[i].ve_valuename == NULL) {
217 return WERR_NOT_ENOUGH_MEMORY;
220 values_in[i].ve_valuename->name = talloc_strdup(values_in[i].ve_valuename, argv[i+2]);
221 values_in[i].ve_valuename->length = strlen_m_term_null(values_in[i].ve_valuename->name)*2;
222 values_in[i].ve_valuename->size = values_in[i].ve_valuename->length;
225 if (multiplevalues2) {
227 uint32_t offered = 0, needed = 0;
229 status = dcerpc_winreg_QueryMultipleValues2(b, mem_ctx,
230 &key_handle,
231 values_in,
232 values_out,
233 num_values,
234 buffer,
235 &offered,
236 &needed,
237 &werr);
238 if (!NT_STATUS_IS_OK(status)) {
239 return ntstatus_to_werror(status);
241 if (W_ERROR_EQUAL(werr, WERR_MORE_DATA)) {
242 offered = needed;
244 buffer = talloc_zero_array(mem_ctx, uint8_t, needed);
245 if (buffer == NULL) {
246 return WERR_NOT_ENOUGH_MEMORY;
249 status = dcerpc_winreg_QueryMultipleValues2(b, mem_ctx,
250 &key_handle,
251 values_in,
252 values_out,
253 num_values,
254 buffer,
255 &offered,
256 &needed,
257 &werr);
258 if (!NT_STATUS_IS_OK(status)) {
259 return ntstatus_to_werror(status);
261 if (!W_ERROR_IS_OK(werr)) {
262 return werr;
266 } else {
268 uint32_t buffer_size = 0xff;
270 buffer = talloc_zero_array(mem_ctx, uint8_t, buffer_size);
271 if (buffer == NULL) {
272 return WERR_NOT_ENOUGH_MEMORY;
275 status = dcerpc_winreg_QueryMultipleValues(b, mem_ctx,
276 &key_handle,
277 values_in,
278 values_out,
279 num_values,
280 buffer,
281 &buffer_size,
282 &werr);
283 if (!NT_STATUS_IS_OK(status)) {
284 return ntstatus_to_werror(status);
286 if (!W_ERROR_IS_OK(werr)) {
287 return werr;
291 for (i=0; i < num_values; i++) {
292 if (buffer) {
293 display_winreg_data(values_in[i].ve_valuename->name,
294 values_out[i].ve_type,
295 buffer + values_out[i].ve_valueptr,
296 values_out[i].ve_valuelen);
300 return WERR_OK;
303 static WERROR cmd_winreg_querymultiplevalues(struct rpc_pipe_client *cli,
304 TALLOC_CTX *mem_ctx, int argc,
305 const char **argv)
307 return cmd_winreg_querymultiplevalues_ex(cli, mem_ctx, argc, argv, false);
310 static WERROR cmd_winreg_querymultiplevalues2(struct rpc_pipe_client *cli,
311 TALLOC_CTX *mem_ctx, int argc,
312 const char **argv)
314 return cmd_winreg_querymultiplevalues_ex(cli, mem_ctx, argc, argv, true);
317 static WERROR cmd_winreg_enumval(struct rpc_pipe_client *cli,
318 TALLOC_CTX *mem_ctx, int argc,
319 const char **argv)
321 NTSTATUS status;
322 WERROR werr, ignore;
323 struct dcerpc_binding_handle *b = cli->binding_handle;
324 struct policy_handle parent_handle, handle;
325 uint32_t enum_index = 0;
327 if (argc < 1 || argc > 3) {
328 printf("usage: %s [name]\n", argv[0]);
329 return WERR_OK;
332 status = dcerpc_winreg_OpenHKLM(b, mem_ctx,
333 NULL,
334 SEC_FLAG_MAXIMUM_ALLOWED,
335 &parent_handle,
336 &werr);
337 if (!NT_STATUS_IS_OK(status)) {
338 return ntstatus_to_werror(status);
340 if (!W_ERROR_IS_OK(werr)) {
341 return werr;
344 if (argc >= 2) {
346 struct winreg_String keyname;
348 ZERO_STRUCT(keyname);
350 keyname.name = argv[1];
352 status = dcerpc_winreg_OpenKey(b, mem_ctx,
353 &parent_handle,
354 keyname,
356 SEC_FLAG_MAXIMUM_ALLOWED,
357 &handle,
358 &werr);
359 if (!NT_STATUS_IS_OK(status)) {
360 return ntstatus_to_werror(status);
362 if (!W_ERROR_IS_OK(werr)) {
363 return werr;
365 } else {
366 handle = parent_handle;
369 do {
370 struct winreg_ValNameBuf name;
371 enum winreg_Type type = REG_NONE;
372 uint32_t size = 0, length = 0;
373 struct winreg_EnumValue r;
375 name.name = "";
376 name.size = 1024;
378 r.in.handle = &handle;
379 r.in.enum_index = enum_index;
380 r.in.name = &name;
381 r.in.type = &type;
382 r.in.size = &size;
383 r.in.length = &length;
384 r.in.value = talloc_array(mem_ctx, uint8_t, size);
385 if (r.in.value == NULL) {
386 werr = WERR_NOT_ENOUGH_MEMORY;
387 goto done;
389 r.out.name = &name;
390 r.out.type = &type;
391 r.out.size = &size;
392 r.out.length = &length;
393 r.out.value = r.in.value;
395 status = dcerpc_winreg_EnumValue_r(b, mem_ctx, &r);
396 if (!NT_STATUS_IS_OK(status)) {
397 werr = ntstatus_to_werror(status);
398 goto done;
401 werr = r.out.result;
403 if (W_ERROR_EQUAL(werr, WERR_MORE_DATA)) {
404 *r.in.size = *r.out.size;
405 r.in.value = talloc_zero_array(mem_ctx, uint8_t, *r.in.size);
406 if (r.in.value == NULL) {
407 werr = WERR_NOT_ENOUGH_MEMORY;
408 goto done;
411 status = dcerpc_winreg_EnumValue_r(b, mem_ctx, &r);
412 if (!NT_STATUS_IS_OK(status)) {
413 werr = ntstatus_to_werror(status);
414 goto done;
417 werr = r.out.result;
419 if (!W_ERROR_IS_OK(r.out.result)) {
420 goto done;
423 printf("%02d: ", enum_index++);
425 display_winreg_data(r.out.name->name,
426 *r.out.type,
427 r.out.value,
428 *r.out.size);
430 } while (W_ERROR_IS_OK(werr));
432 done:
433 if (argc >= 2) {
434 dcerpc_winreg_CloseKey(b, mem_ctx, &handle, &ignore);
436 dcerpc_winreg_CloseKey(b, mem_ctx, &parent_handle, &ignore);
438 return werr;
441 /* List of commands exported by this module */
443 struct cmd_set winreg_commands[] = {
446 .name = "WINREG",
449 .name = "winreg_enumkey",
450 .returntype = RPC_RTYPE_WERROR,
451 .ntfn = NULL,
452 .wfn = cmd_winreg_enumkeys,
453 .table = &ndr_table_winreg,
454 .rpc_pipe = NULL,
455 .description = "Enumerate Keys",
456 .usage = "",
459 .name = "querymultiplevalues",
460 .returntype = RPC_RTYPE_WERROR,
461 .ntfn = NULL,
462 .wfn = cmd_winreg_querymultiplevalues,
463 .table = &ndr_table_winreg,
464 .rpc_pipe = NULL,
465 .description = "Query multiple values",
466 .usage = "",
469 .name = "querymultiplevalues2",
470 .returntype = RPC_RTYPE_WERROR,
471 .ntfn = NULL,
472 .wfn = cmd_winreg_querymultiplevalues2,
473 .table = &ndr_table_winreg,
474 .rpc_pipe = NULL,
475 .description = "Query multiple values",
476 .usage = "",
479 .name = "winreg_enumval",
480 .returntype = RPC_RTYPE_WERROR,
481 .ntfn = NULL,
482 .wfn = cmd_winreg_enumval,
483 .table = &ndr_table_winreg,
484 .rpc_pipe = NULL,
485 .description = "Enumerate Values",
486 .usage = "",
489 .name = NULL,