Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 : RPC pipe client
4 :
5 : Copyright (C) Guenther Deschner 2009
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 :
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"
25 :
26 0 : static WERROR cmd_winreg_enumkeys(struct rpc_pipe_client *cli,
27 : TALLOC_CTX *mem_ctx, int argc,
28 : const char **argv)
29 : {
30 : NTSTATUS status;
31 : WERROR werr;
32 : struct policy_handle handle;
33 0 : uint32_t enum_index = 0;
34 : struct winreg_StringBuf name;
35 0 : struct dcerpc_binding_handle *b = cli->binding_handle;
36 :
37 0 : if (argc < 2) {
38 0 : printf("usage: %s [name]\n", argv[0]);
39 0 : return WERR_OK;
40 : }
41 :
42 0 : status = dcerpc_winreg_OpenHKLM(b, mem_ctx,
43 : NULL,
44 : SEC_FLAG_MAXIMUM_ALLOWED,
45 : &handle,
46 : &werr);
47 0 : if (!NT_STATUS_IS_OK(status)) {
48 0 : return ntstatus_to_werror(status);
49 : }
50 0 : if (!W_ERROR_IS_OK(werr)) {
51 0 : return werr;
52 : }
53 :
54 0 : ZERO_STRUCT(name);
55 :
56 0 : name.name = argv[1];
57 0 : name.length = strlen_m_term_null(name.name)*2;
58 0 : name.size = name.length;
59 :
60 0 : status = dcerpc_winreg_EnumKey(b, mem_ctx,
61 : &handle,
62 : enum_index,
63 : &name,
64 : NULL,
65 : NULL,
66 : &werr);
67 0 : if (!NT_STATUS_IS_OK(status)) {
68 0 : return ntstatus_to_werror(status);
69 : }
70 0 : if (!W_ERROR_IS_OK(werr)) {
71 0 : return werr;
72 : }
73 :
74 0 : return WERR_OK;
75 : }
76 :
77 : /****************************************************************************
78 : ****************************************************************************/
79 :
80 0 : static WERROR pull_winreg_Data(TALLOC_CTX *mem_ctx,
81 : const DATA_BLOB *blob,
82 : union winreg_Data *data,
83 : enum winreg_Type type)
84 : {
85 : enum ndr_err_code ndr_err;
86 0 : ndr_err = ndr_pull_union_blob(blob, mem_ctx, data, type,
87 : (ndr_pull_flags_fn_t)ndr_pull_winreg_Data);
88 0 : if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
89 0 : return WERR_GEN_FAILURE;
90 : }
91 0 : return WERR_OK;
92 : }
93 :
94 : /****************************************************************************
95 : ****************************************************************************/
96 :
97 0 : static void display_winreg_data(const char *v,
98 : enum winreg_Type type,
99 : uint8_t *data,
100 : uint32_t length)
101 : {
102 : size_t i;
103 : union winreg_Data r;
104 0 : DATA_BLOB blob = data_blob_const(data, length);
105 : WERROR result;
106 :
107 0 : result = pull_winreg_Data(talloc_tos(), &blob, &r, type);
108 0 : if (!W_ERROR_IS_OK(result)) {
109 0 : return;
110 : }
111 :
112 0 : switch (type) {
113 0 : case REG_DWORD:
114 0 : printf("%s: REG_DWORD: 0x%08x\n", v, r.value);
115 0 : break;
116 0 : case REG_SZ:
117 0 : printf("%s: REG_SZ: %s\n", v, r.string);
118 0 : break;
119 0 : case REG_BINARY: {
120 0 : char *hex = hex_encode_talloc(NULL,
121 0 : r.binary.data, r.binary.length);
122 : size_t len;
123 0 : printf("%s: REG_BINARY:", v);
124 0 : len = strlen(hex);
125 0 : for (i=0; i<len; i++) {
126 0 : if (hex[i] == '\0') {
127 0 : break;
128 : }
129 0 : if (i%40 == 0) {
130 0 : putchar('\n');
131 : }
132 0 : putchar(hex[i]);
133 : }
134 0 : TALLOC_FREE(hex);
135 0 : putchar('\n');
136 0 : break;
137 : }
138 0 : case REG_MULTI_SZ:
139 0 : printf("%s: REG_MULTI_SZ: ", v);
140 0 : for (i=0; r.string_array[i] != NULL; i++) {
141 0 : printf("%s ", r.string_array[i]);
142 : }
143 0 : printf("\n");
144 0 : break;
145 0 : default:
146 0 : printf("%s: unknown type 0x%02x:\n", v, type);
147 0 : break;
148 : }
149 : }
150 :
151 :
152 0 : static WERROR cmd_winreg_querymultiplevalues_ex(struct rpc_pipe_client *cli,
153 : TALLOC_CTX *mem_ctx, int argc,
154 : const char **argv, bool multiplevalues2)
155 : {
156 : NTSTATUS status;
157 : WERROR werr;
158 : struct policy_handle handle, key_handle;
159 0 : struct winreg_String key_name = { 0, };
160 0 : struct dcerpc_binding_handle *b = cli->binding_handle;
161 :
162 : struct QueryMultipleValue *values_in, *values_out;
163 : uint32_t num_values;
164 0 : uint8_t *buffer = NULL;
165 : uint32_t i;
166 :
167 :
168 0 : if (argc < 2) {
169 0 : printf("usage: %s [key] [value1] [value2] ...\n", argv[0]);
170 0 : return WERR_OK;
171 : }
172 :
173 0 : status = dcerpc_winreg_OpenHKLM(b, mem_ctx,
174 : NULL,
175 : SEC_FLAG_MAXIMUM_ALLOWED,
176 : &handle,
177 : &werr);
178 0 : if (!NT_STATUS_IS_OK(status)) {
179 0 : return ntstatus_to_werror(status);
180 : }
181 0 : if (!W_ERROR_IS_OK(werr)) {
182 0 : return werr;
183 : }
184 :
185 0 : key_name.name = argv[1];
186 :
187 0 : 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 0 : if (!NT_STATUS_IS_OK(status)) {
195 0 : return ntstatus_to_werror(status);
196 : }
197 0 : if (!W_ERROR_IS_OK(werr)) {
198 0 : return werr;
199 : }
200 :
201 0 : num_values = argc-2;
202 :
203 0 : values_in = talloc_zero_array(mem_ctx, struct QueryMultipleValue, num_values);
204 0 : if (values_in == NULL) {
205 0 : return WERR_NOT_ENOUGH_MEMORY;
206 : }
207 :
208 0 : values_out = talloc_zero_array(mem_ctx, struct QueryMultipleValue, num_values);
209 0 : if (values_out == NULL) {
210 0 : return WERR_NOT_ENOUGH_MEMORY;
211 : }
212 :
213 0 : for (i=0; i < num_values; i++) {
214 :
215 0 : values_in[i].ve_valuename = talloc_zero(values_in, struct winreg_ValNameBuf);
216 0 : if (values_in[i].ve_valuename == NULL) {
217 0 : return WERR_NOT_ENOUGH_MEMORY;
218 : }
219 :
220 0 : values_in[i].ve_valuename->name = talloc_strdup(values_in[i].ve_valuename, argv[i+2]);
221 0 : values_in[i].ve_valuename->length = strlen_m_term_null(values_in[i].ve_valuename->name)*2;
222 0 : values_in[i].ve_valuename->size = values_in[i].ve_valuename->length;
223 : }
224 :
225 0 : if (multiplevalues2) {
226 :
227 0 : uint32_t offered = 0, needed = 0;
228 :
229 0 : 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 0 : if (!NT_STATUS_IS_OK(status)) {
239 0 : return ntstatus_to_werror(status);
240 : }
241 0 : if (W_ERROR_EQUAL(werr, WERR_MORE_DATA)) {
242 0 : offered = needed;
243 :
244 0 : buffer = talloc_zero_array(mem_ctx, uint8_t, needed);
245 0 : if (buffer == NULL) {
246 0 : return WERR_NOT_ENOUGH_MEMORY;
247 : }
248 :
249 0 : 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 0 : if (!NT_STATUS_IS_OK(status)) {
259 0 : return ntstatus_to_werror(status);
260 : }
261 0 : if (!W_ERROR_IS_OK(werr)) {
262 0 : return werr;
263 : }
264 : }
265 :
266 : } else {
267 :
268 0 : uint32_t buffer_size = 0xff;
269 :
270 0 : buffer = talloc_zero_array(mem_ctx, uint8_t, buffer_size);
271 0 : if (buffer == NULL) {
272 0 : return WERR_NOT_ENOUGH_MEMORY;
273 : }
274 :
275 0 : 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 0 : if (!NT_STATUS_IS_OK(status)) {
284 0 : return ntstatus_to_werror(status);
285 : }
286 0 : if (!W_ERROR_IS_OK(werr)) {
287 0 : return werr;
288 : }
289 : }
290 :
291 0 : for (i=0; i < num_values; i++) {
292 0 : if (buffer) {
293 0 : display_winreg_data(values_in[i].ve_valuename->name,
294 0 : values_out[i].ve_type,
295 0 : buffer + values_out[i].ve_valueptr,
296 0 : values_out[i].ve_valuelen);
297 : }
298 : }
299 :
300 0 : return WERR_OK;
301 : }
302 :
303 0 : static WERROR cmd_winreg_querymultiplevalues(struct rpc_pipe_client *cli,
304 : TALLOC_CTX *mem_ctx, int argc,
305 : const char **argv)
306 : {
307 0 : return cmd_winreg_querymultiplevalues_ex(cli, mem_ctx, argc, argv, false);
308 : }
309 :
310 0 : static WERROR cmd_winreg_querymultiplevalues2(struct rpc_pipe_client *cli,
311 : TALLOC_CTX *mem_ctx, int argc,
312 : const char **argv)
313 : {
314 0 : return cmd_winreg_querymultiplevalues_ex(cli, mem_ctx, argc, argv, true);
315 : }
316 :
317 : /* List of commands exported by this module */
318 :
319 : struct cmd_set winreg_commands[] = {
320 :
321 : {
322 : .name = "WINREG",
323 : },
324 : {
325 : .name = "winreg_enumkey",
326 : .returntype = RPC_RTYPE_WERROR,
327 : .ntfn = NULL,
328 : .wfn = cmd_winreg_enumkeys,
329 : .table = &ndr_table_winreg,
330 : .rpc_pipe = NULL,
331 : .description = "Enumerate Keys",
332 : .usage = "",
333 : },
334 : {
335 : .name = "querymultiplevalues",
336 : .returntype = RPC_RTYPE_WERROR,
337 : .ntfn = NULL,
338 : .wfn = cmd_winreg_querymultiplevalues,
339 : .table = &ndr_table_winreg,
340 : .rpc_pipe = NULL,
341 : .description = "Query multiple values",
342 : .usage = "",
343 : },
344 : {
345 : .name = "querymultiplevalues2",
346 : .returntype = RPC_RTYPE_WERROR,
347 : .ntfn = NULL,
348 : .wfn = cmd_winreg_querymultiplevalues2,
349 : .table = &ndr_table_winreg,
350 : .rpc_pipe = NULL,
351 : .description = "Query multiple values",
352 : .usage = "",
353 : },
354 : {
355 : .name = NULL,
356 : },
357 : };
|