s4:rootdse LDB module - remove unused variable
[Samba/gebeck_regimport.git] / source3 / rpcclient / cmd_winreg.c
blob6fcb5284671b05a6deaaf85093d37a3d66369129
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/cli_winreg.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;
36 if (argc < 2) {
37 printf("usage: %s [name]\n", argv[0]);
38 return WERR_OK;
41 status = rpccli_winreg_OpenHKLM(cli, mem_ctx,
42 NULL,
43 SEC_FLAG_MAXIMUM_ALLOWED,
44 &handle,
45 &werr);
46 if (!NT_STATUS_IS_OK(status)) {
47 return ntstatus_to_werror(status);
49 if (!W_ERROR_IS_OK(werr)) {
50 return werr;
53 ZERO_STRUCT(name);
55 name.name = argv[1];
56 name.length = strlen_m_term_null(name.name)*2;
57 name.size = name.length;
59 status = rpccli_winreg_EnumKey(cli, mem_ctx,
60 &handle,
61 enum_index,
62 &name,
63 NULL,
64 NULL,
65 &werr);
66 if (!NT_STATUS_IS_OK(status)) {
67 return ntstatus_to_werror(status);
69 if (!W_ERROR_IS_OK(werr)) {
70 return werr;
73 return WERR_OK;
76 /****************************************************************************
77 ****************************************************************************/
79 static WERROR pull_winreg_Data(TALLOC_CTX *mem_ctx,
80 const DATA_BLOB *blob,
81 union winreg_Data *data,
82 enum winreg_Type type)
84 enum ndr_err_code ndr_err;
85 ndr_err = ndr_pull_union_blob(blob, mem_ctx, data, type,
86 (ndr_pull_flags_fn_t)ndr_pull_winreg_Data);
87 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
88 return WERR_GENERAL_FAILURE;
90 return WERR_OK;
93 /****************************************************************************
94 ****************************************************************************/
96 static void display_winreg_data(const char *v,
97 enum winreg_Type type,
98 uint8_t *data,
99 uint32_t length)
101 int i;
102 union winreg_Data r;
103 DATA_BLOB blob = data_blob_const(data, length);
104 WERROR result;
106 result = pull_winreg_Data(talloc_tos(), &blob, &r, type);
107 if (!W_ERROR_IS_OK(result)) {
108 return;
111 switch (type) {
112 case REG_DWORD:
113 printf("%s: REG_DWORD: 0x%08x\n", v, r.value);
114 break;
115 case REG_SZ:
116 printf("%s: REG_SZ: %s\n", v, r.string);
117 break;
118 case REG_BINARY: {
119 char *hex = hex_encode_talloc(NULL,
120 r.binary.data, r.binary.length);
121 size_t len;
122 printf("%s: REG_BINARY:", v);
123 len = strlen(hex);
124 for (i=0; i<len; i++) {
125 if (hex[i] == '\0') {
126 break;
128 if (i%40 == 0) {
129 putchar('\n');
131 putchar(hex[i]);
133 TALLOC_FREE(hex);
134 putchar('\n');
135 break;
137 case REG_MULTI_SZ:
138 printf("%s: REG_MULTI_SZ: ", v);
139 for (i=0; r.string_array[i] != NULL; i++) {
140 printf("%s ", r.string_array[i]);
142 printf("\n");
143 break;
144 default:
145 printf("%s: unknown type 0x%02x:\n", v, type);
146 break;
151 static WERROR cmd_winreg_querymultiplevalues_ex(struct rpc_pipe_client *cli,
152 TALLOC_CTX *mem_ctx, int argc,
153 const char **argv, bool multiplevalues2)
155 NTSTATUS status;
156 WERROR werr;
157 struct policy_handle handle, key_handle;
158 struct winreg_String key_name;
160 struct QueryMultipleValue *values_in, *values_out;
161 uint32_t num_values;
162 uint8_t *buffer = NULL;
163 int i;
166 if (argc < 2) {
167 printf("usage: %s [key] [value1] [value2] ...\n", argv[0]);
168 return WERR_OK;
171 status = rpccli_winreg_OpenHKLM(cli, mem_ctx,
172 NULL,
173 SEC_FLAG_MAXIMUM_ALLOWED,
174 &handle,
175 &werr);
176 if (!NT_STATUS_IS_OK(status)) {
177 return ntstatus_to_werror(status);
179 if (!W_ERROR_IS_OK(werr)) {
180 return werr;
183 key_name.name = argv[1];
185 status = rpccli_winreg_OpenKey(cli, mem_ctx,
186 &handle,
187 key_name,
188 0, /* options */
189 SEC_FLAG_MAXIMUM_ALLOWED,
190 &key_handle,
191 &werr);
192 if (!NT_STATUS_IS_OK(status)) {
193 return ntstatus_to_werror(status);
195 if (!W_ERROR_IS_OK(werr)) {
196 return werr;
199 num_values = argc-2;
201 values_in = talloc_zero_array(mem_ctx, struct QueryMultipleValue, num_values);
202 if (values_in == NULL) {
203 return WERR_NOMEM;
206 values_out = talloc_zero_array(mem_ctx, struct QueryMultipleValue, num_values);
207 if (values_out == NULL) {
208 return WERR_NOMEM;
211 for (i=0; i < num_values; i++) {
213 values_in[i].ve_valuename = talloc_zero(values_in, struct winreg_ValNameBuf);
214 if (values_in[i].ve_valuename == NULL) {
215 return WERR_NOMEM;
218 values_in[i].ve_valuename->name = talloc_strdup(values_in[i].ve_valuename, argv[i+2]);
219 values_in[i].ve_valuename->length = strlen_m_term_null(values_in[i].ve_valuename->name)*2;
220 values_in[i].ve_valuename->size = values_in[i].ve_valuename->length;
223 if (multiplevalues2) {
225 uint32_t offered = 0, needed = 0;
227 status = rpccli_winreg_QueryMultipleValues2(cli, mem_ctx,
228 &key_handle,
229 values_in,
230 values_out,
231 num_values,
232 buffer,
233 &offered,
234 &needed,
235 &werr);
236 if (W_ERROR_EQUAL(werr, WERR_MORE_DATA)) {
237 offered = needed;
239 buffer = talloc_zero_array(mem_ctx, uint8_t, needed);
240 if (buffer == NULL) {
241 return WERR_NOMEM;
244 status = rpccli_winreg_QueryMultipleValues2(cli, mem_ctx,
245 &key_handle,
246 values_in,
247 values_out,
248 num_values,
249 buffer,
250 &offered,
251 &needed,
252 &werr);
253 if (!NT_STATUS_IS_OK(status)) {
254 return ntstatus_to_werror(status);
256 if (!W_ERROR_IS_OK(werr)) {
257 return werr;
261 } else {
263 uint32_t buffer_size = 0xff;
265 buffer = talloc_zero_array(mem_ctx, uint8_t, buffer_size);
266 if (buffer == NULL) {
267 return WERR_NOMEM;
270 status = rpccli_winreg_QueryMultipleValues(cli, mem_ctx,
271 &key_handle,
272 values_in,
273 values_out,
274 num_values,
275 buffer,
276 &buffer_size,
277 &werr);
278 if (!NT_STATUS_IS_OK(status)) {
279 return ntstatus_to_werror(status);
281 if (!W_ERROR_IS_OK(werr)) {
282 return werr;
286 for (i=0; i < num_values; i++) {
287 if (buffer) {
288 display_winreg_data(values_in[i].ve_valuename->name,
289 values_out[i].ve_type,
290 buffer + values_out[i].ve_valueptr,
291 values_out[i].ve_valuelen);
295 return WERR_OK;
298 static WERROR cmd_winreg_querymultiplevalues(struct rpc_pipe_client *cli,
299 TALLOC_CTX *mem_ctx, int argc,
300 const char **argv)
302 return cmd_winreg_querymultiplevalues_ex(cli, mem_ctx, argc, argv, false);
305 static WERROR cmd_winreg_querymultiplevalues2(struct rpc_pipe_client *cli,
306 TALLOC_CTX *mem_ctx, int argc,
307 const char **argv)
309 return cmd_winreg_querymultiplevalues_ex(cli, mem_ctx, argc, argv, true);
312 /* List of commands exported by this module */
314 struct cmd_set winreg_commands[] = {
316 { "WINREG" },
317 { "enumkey", RPC_RTYPE_WERROR, NULL, cmd_winreg_enumkeys, &ndr_table_winreg.syntax_id, NULL, "Enumerate Keys", "" },
318 { "querymultiplevalues", RPC_RTYPE_WERROR, NULL, cmd_winreg_querymultiplevalues, &ndr_table_winreg.syntax_id, NULL, "Query multiple values", "" },
319 { "querymultiplevalues2", RPC_RTYPE_WERROR, NULL, cmd_winreg_querymultiplevalues2, &ndr_table_winreg.syntax_id, NULL, "Query multiple values", "" },
320 { NULL }