Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 :
4 : endpoint server for the winreg pipe
5 :
6 : Copyright (C) 2004 Jelmer Vernooij, jelmer@samba.org
7 : Copyright (C) 2008 Matthias Dieter Wallnöfer, mwallnoefer@yahoo.de
8 :
9 : This program is free software; you can redistribute it and/or modify
10 : it under the terms of the GNU General Public License as published by
11 : the Free Software Foundation; either version 3 of the License, or
12 : (at your option) any later version.
13 :
14 : This program is distributed in the hope that it will be useful,
15 : but WITHOUT ANY WARRANTY; without even the implied warranty of
16 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 : GNU General Public License for more details.
18 :
19 : You should have received a copy of the GNU General Public License
20 : along with this program. If not, see <http://www.gnu.org/licenses/>.
21 : */
22 :
23 : #include "includes.h"
24 : #include "rpc_server/dcerpc_server.h"
25 : #include "lib/registry/registry.h"
26 : #include "librpc/gen_ndr/ndr_winreg.h"
27 : #include "librpc/gen_ndr/ndr_security.h"
28 : #include "libcli/security/session.h"
29 :
30 : enum handle_types { HTYPE_REGVAL, HTYPE_REGKEY };
31 :
32 323 : static WERROR dcesrv_winreg_openhive(struct dcesrv_call_state *dce_call,
33 : TALLOC_CTX *mem_ctx, uint32_t hkey,
34 : struct policy_handle **outh)
35 : {
36 0 : struct auth_session_info *session_info =
37 323 : dcesrv_call_session_info(dce_call);
38 323 : struct registry_context *ctx = NULL;
39 0 : struct dcesrv_handle *h;
40 0 : WERROR result;
41 :
42 323 : h = dcesrv_handle_create(dce_call, HTYPE_REGKEY);
43 323 : W_ERROR_HAVE_NO_MEMORY(h);
44 :
45 323 : result = reg_open_samba(h, &ctx,
46 : dce_call->event_ctx,
47 323 : dce_call->conn->dce_ctx->lp_ctx,
48 : session_info,
49 : NULL);
50 323 : if (!W_ERROR_IS_OK(result)) {
51 0 : DEBUG(0, ("Error opening registry: %s\n", win_errstr(result)));
52 0 : return result;
53 : }
54 :
55 323 : result = reg_get_predefined_key(ctx, hkey,
56 323 : (struct registry_key **)&h->data);
57 323 : if (!W_ERROR_IS_OK(result)) {
58 0 : return result;
59 : }
60 323 : *outh = &h->wire_handle;
61 :
62 323 : return result;
63 : }
64 :
65 : #define func_winreg_OpenHive(k,n) static WERROR dcesrv_winreg_Open ## k (struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct winreg_Open ## k *r) \
66 : { \
67 : return dcesrv_winreg_openhive (dce_call, mem_ctx, n, &r->out.handle);\
68 : }
69 :
70 80 : func_winreg_OpenHive(HKCR,HKEY_CLASSES_ROOT)
71 80 : func_winreg_OpenHive(HKCU,HKEY_CURRENT_USER)
72 83 : func_winreg_OpenHive(HKLM,HKEY_LOCAL_MACHINE)
73 0 : func_winreg_OpenHive(HKPD,HKEY_PERFORMANCE_DATA)
74 80 : func_winreg_OpenHive(HKU,HKEY_USERS)
75 0 : func_winreg_OpenHive(HKCC,HKEY_CURRENT_CONFIG)
76 0 : func_winreg_OpenHive(HKDD,HKEY_DYN_DATA)
77 0 : func_winreg_OpenHive(HKPT,HKEY_PERFORMANCE_TEXT)
78 0 : func_winreg_OpenHive(HKPN,HKEY_PERFORMANCE_NLSTEXT)
79 :
80 : /*
81 : winreg_CloseKey
82 : */
83 643 : static WERROR dcesrv_winreg_CloseKey(struct dcesrv_call_state *dce_call,
84 : TALLOC_CTX *mem_ctx,
85 : struct winreg_CloseKey *r)
86 : {
87 0 : struct dcesrv_handle *h;
88 :
89 643 : DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY);
90 :
91 643 : talloc_unlink(dce_call->context, h);
92 :
93 643 : ZERO_STRUCTP(r->out.handle);
94 :
95 643 : return WERR_OK;
96 : }
97 :
98 : /*
99 : winreg_CreateKey
100 : */
101 1680 : static WERROR dcesrv_winreg_CreateKey(struct dcesrv_call_state *dce_call,
102 : TALLOC_CTX *mem_ctx,
103 : struct winreg_CreateKey *r)
104 : {
105 0 : struct auth_session_info *session_info =
106 1680 : dcesrv_call_session_info(dce_call);
107 0 : struct dcesrv_handle *h, *newh;
108 0 : struct security_descriptor sd;
109 0 : struct registry_key *key;
110 0 : WERROR result;
111 :
112 1680 : DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY);
113 1680 : key = h->data;
114 :
115 1680 : newh = dcesrv_handle_create(dce_call, HTYPE_REGKEY);
116 :
117 1680 : switch (security_session_user_level(session_info, NULL))
118 : {
119 1680 : case SECURITY_SYSTEM:
120 : case SECURITY_ADMINISTRATOR:
121 : /* we support only non volatile keys */
122 1680 : if (r->in.options != REG_OPTION_NON_VOLATILE) {
123 0 : return WERR_NOT_SUPPORTED;
124 : }
125 :
126 : /* the security descriptor is optional */
127 1680 : if (r->in.secdesc != NULL) {
128 0 : DATA_BLOB sdblob;
129 0 : enum ndr_err_code ndr_err;
130 0 : sdblob.data = r->in.secdesc->sd.data;
131 0 : sdblob.length = r->in.secdesc->sd.len;
132 0 : if (sdblob.data == NULL) {
133 0 : return WERR_INVALID_PARAMETER;
134 : }
135 0 : ndr_err = ndr_pull_struct_blob_all(&sdblob, mem_ctx, &sd,
136 : (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
137 0 : if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
138 0 : return WERR_INVALID_PARAMETER;
139 : }
140 : }
141 :
142 1680 : result = reg_key_add_name(newh, key, r->in.name.name, NULL,
143 1680 : r->in.secdesc?&sd:NULL, (struct registry_key **)&newh->data);
144 :
145 1680 : r->out.action_taken = talloc(mem_ctx, enum winreg_CreateAction);
146 1680 : if (r->out.action_taken == NULL) {
147 0 : talloc_free(newh);
148 0 : return WERR_NOT_ENOUGH_MEMORY;
149 : }
150 1680 : *r->out.action_taken = REG_ACTION_NONE;
151 :
152 1680 : if (W_ERROR_IS_OK(result)) {
153 1680 : r->out.new_handle = &newh->wire_handle;
154 1680 : *r->out.action_taken = REG_CREATED_NEW_KEY;
155 : } else {
156 0 : talloc_free(newh);
157 : }
158 :
159 1680 : return result;
160 0 : default:
161 0 : return WERR_ACCESS_DENIED;
162 : }
163 : }
164 :
165 :
166 : /*
167 : winreg_DeleteKey
168 : */
169 2560 : static WERROR dcesrv_winreg_DeleteKey(struct dcesrv_call_state *dce_call,
170 : TALLOC_CTX *mem_ctx,
171 : struct winreg_DeleteKey *r)
172 : {
173 0 : struct auth_session_info *session_info =
174 2560 : dcesrv_call_session_info(dce_call);
175 0 : struct dcesrv_handle *h;
176 0 : struct registry_key *key;
177 0 : WERROR result;
178 :
179 2560 : DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY);
180 2560 : key = h->data;
181 :
182 2560 : switch (security_session_user_level(session_info, NULL))
183 : {
184 2560 : case SECURITY_SYSTEM:
185 : case SECURITY_ADMINISTRATOR:
186 2560 : result = reg_key_del(mem_ctx, key, r->in.key.name);
187 2560 : talloc_unlink(dce_call->context, h);
188 :
189 2560 : return result;
190 0 : default:
191 0 : return WERR_ACCESS_DENIED;
192 : }
193 : }
194 :
195 :
196 : /*
197 : winreg_DeleteValue
198 : */
199 2400 : static WERROR dcesrv_winreg_DeleteValue(struct dcesrv_call_state *dce_call,
200 : TALLOC_CTX *mem_ctx,
201 : struct winreg_DeleteValue *r)
202 : {
203 0 : struct auth_session_info *session_info =
204 2400 : dcesrv_call_session_info(dce_call);
205 0 : struct dcesrv_handle *h;
206 0 : struct registry_key *key;
207 :
208 2400 : DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY);
209 2400 : key = h->data;
210 :
211 2400 : switch (security_session_user_level(session_info, NULL))
212 : {
213 2400 : case SECURITY_SYSTEM:
214 : case SECURITY_ADMINISTRATOR:
215 2400 : return reg_del_value(mem_ctx, key, r->in.value.name);
216 0 : default:
217 0 : return WERR_ACCESS_DENIED;
218 : }
219 : }
220 :
221 :
222 : /*
223 : winreg_EnumKey
224 : */
225 240 : static WERROR dcesrv_winreg_EnumKey(struct dcesrv_call_state *dce_call,
226 : TALLOC_CTX *mem_ctx,
227 : struct winreg_EnumKey *r)
228 : {
229 0 : struct dcesrv_handle *h;
230 0 : struct registry_key *key;
231 0 : const char *name, *classname;
232 0 : NTTIME last_mod;
233 0 : WERROR result;
234 :
235 240 : DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY);
236 240 : key = h->data;
237 :
238 240 : result = reg_key_get_subkey_by_index(mem_ctx,
239 : key, r->in.enum_index, &name, &classname, &last_mod);
240 :
241 240 : if (2*strlen_m_term(name) > r->in.name->size) {
242 0 : return WERR_MORE_DATA;
243 : }
244 :
245 240 : if (name != NULL) {
246 0 : r->out.name->name = name;
247 0 : r->out.name->length = 2*strlen_m_term(name);
248 : } else {
249 240 : r->out.name->name = r->in.name->name;
250 240 : r->out.name->length = r->in.name->length;
251 : }
252 240 : r->out.name->size = r->in.name->size;
253 :
254 240 : r->out.keyclass = r->in.keyclass;
255 240 : if (classname != NULL) {
256 0 : r->out.keyclass->name = classname;
257 0 : r->out.keyclass->length = 2*strlen_m_term(classname);
258 : } else {
259 240 : r->out.keyclass->name = r->in.keyclass->name;
260 240 : r->out.keyclass->length = r->in.keyclass->length;
261 : }
262 240 : r->out.keyclass->size = r->in.keyclass->size;
263 :
264 240 : if (r->in.last_changed_time != NULL)
265 240 : r->out.last_changed_time = &last_mod;
266 :
267 240 : return result;
268 : }
269 :
270 :
271 : /*
272 : winreg_EnumValue
273 : */
274 2880 : static WERROR dcesrv_winreg_EnumValue(struct dcesrv_call_state *dce_call,
275 : TALLOC_CTX *mem_ctx,
276 : struct winreg_EnumValue *r)
277 : {
278 0 : struct dcesrv_handle *h;
279 0 : struct registry_key *key;
280 0 : const char *data_name;
281 0 : uint32_t data_type;
282 0 : DATA_BLOB data;
283 0 : WERROR result;
284 :
285 2880 : DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY);
286 2880 : key = h->data;
287 :
288 2880 : result = reg_key_get_value_by_index(mem_ctx, key,
289 : r->in.enum_index, &data_name, &data_type, &data);
290 :
291 2880 : if (!W_ERROR_IS_OK(result)) {
292 : /* if the lookup wasn't successful, send client query back */
293 960 : data_name = r->in.name->name;
294 960 : data_type = *r->in.type;
295 960 : data.data = r->in.value;
296 960 : data.length = *r->in.length;
297 : }
298 :
299 : /* "data_name" is NULL when we query the default attribute */
300 2880 : if (data_name != NULL) {
301 2880 : r->out.name->name = data_name;
302 2880 : r->out.name->length = 2*strlen_m_term(data_name);
303 : } else {
304 0 : r->out.name->name = r->in.name->name;
305 0 : r->out.name->length = r->in.name->length;
306 : }
307 2880 : r->out.name->size = r->in.name->size;
308 :
309 2880 : r->out.type = talloc(mem_ctx, enum winreg_Type);
310 2880 : if (!r->out.type) {
311 0 : return WERR_NOT_ENOUGH_MEMORY;
312 : }
313 2880 : *r->out.type = (enum winreg_Type) data_type;
314 :
315 2880 : if (r->in.size != NULL) {
316 2880 : r->out.size = talloc(mem_ctx, uint32_t);
317 2880 : *r->out.size = data.length;
318 : }
319 : /* check the client has enough room for the value */
320 2880 : if (r->in.value != NULL &&
321 2640 : r->in.size != NULL &&
322 2640 : data.length > *r->in.size) {
323 960 : return WERR_MORE_DATA;
324 : }
325 :
326 1920 : if (r->in.value != NULL) {
327 1680 : r->out.value = data.data;
328 : }
329 :
330 1920 : if (r->in.length != NULL) {
331 1920 : r->out.length = r->out.size;
332 : }
333 :
334 1920 : return result;
335 : }
336 :
337 :
338 : /*
339 : winreg_FlushKey
340 : */
341 640 : static WERROR dcesrv_winreg_FlushKey(struct dcesrv_call_state *dce_call,
342 : TALLOC_CTX *mem_ctx,
343 : struct winreg_FlushKey *r)
344 : {
345 0 : struct auth_session_info *session_info =
346 640 : dcesrv_call_session_info(dce_call);
347 0 : struct dcesrv_handle *h;
348 0 : struct registry_key *key;
349 :
350 640 : DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY);
351 640 : key = h->data;
352 :
353 640 : switch (security_session_user_level(session_info, NULL))
354 : {
355 640 : case SECURITY_SYSTEM:
356 : case SECURITY_ADMINISTRATOR:
357 640 : return reg_key_flush(key);
358 0 : default:
359 0 : return WERR_ACCESS_DENIED;
360 : }
361 : }
362 :
363 :
364 : /*
365 : winreg_GetKeySecurity
366 : */
367 0 : static WERROR dcesrv_winreg_GetKeySecurity(struct dcesrv_call_state *dce_call,
368 : TALLOC_CTX *mem_ctx,
369 : struct winreg_GetKeySecurity *r)
370 : {
371 0 : struct dcesrv_handle *h;
372 :
373 0 : DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY);
374 :
375 0 : return WERR_NOT_SUPPORTED;
376 : }
377 :
378 :
379 : /*
380 : winreg_LoadKey
381 : */
382 0 : static WERROR dcesrv_winreg_LoadKey(struct dcesrv_call_state *dce_call,
383 : TALLOC_CTX *mem_ctx,
384 : struct winreg_LoadKey *r)
385 : {
386 0 : return WERR_NOT_SUPPORTED;
387 : }
388 :
389 :
390 : /*
391 : winreg_NotifyChangeKeyValue
392 : */
393 240 : static WERROR dcesrv_winreg_NotifyChangeKeyValue(struct dcesrv_call_state *dce_call,
394 : TALLOC_CTX *mem_ctx,
395 : struct winreg_NotifyChangeKeyValue *r)
396 : {
397 240 : return WERR_NOT_SUPPORTED;
398 : }
399 :
400 :
401 : /*
402 : winreg_OpenKey
403 : */
404 720 : static WERROR dcesrv_winreg_OpenKey(struct dcesrv_call_state *dce_call,
405 : TALLOC_CTX *mem_ctx,
406 : struct winreg_OpenKey *r)
407 : {
408 0 : struct auth_session_info *session_info =
409 720 : dcesrv_call_session_info(dce_call);
410 0 : struct dcesrv_handle *h, *newh;
411 0 : struct registry_key *key;
412 0 : WERROR result;
413 :
414 720 : DCESRV_PULL_HANDLE_FAULT(h, r->in.parent_handle, HTYPE_REGKEY);
415 720 : key = h->data;
416 :
417 720 : switch (security_session_user_level(session_info, NULL))
418 : {
419 720 : case SECURITY_SYSTEM:
420 : case SECURITY_ADMINISTRATOR:
421 : case SECURITY_USER:
422 720 : if (r->in.keyname.name && strcmp(r->in.keyname.name, "") == 0) {
423 0 : newh = talloc_reference(dce_call->context, h);
424 0 : result = WERR_OK;
425 : } else {
426 720 : newh = dcesrv_handle_create(dce_call, HTYPE_REGKEY);
427 720 : result = reg_open_key(newh, key, r->in.keyname.name,
428 720 : (struct registry_key **)&newh->data);
429 : }
430 :
431 720 : if (W_ERROR_IS_OK(result)) {
432 400 : r->out.handle = &newh->wire_handle;
433 : } else {
434 320 : talloc_free(newh);
435 : }
436 720 : return result;
437 0 : default:
438 0 : return WERR_ACCESS_DENIED;
439 : }
440 : }
441 :
442 :
443 : /*
444 : winreg_QueryInfoKey
445 : */
446 241 : static WERROR dcesrv_winreg_QueryInfoKey(struct dcesrv_call_state *dce_call,
447 : TALLOC_CTX *mem_ctx,
448 : struct winreg_QueryInfoKey *r)
449 : {
450 0 : struct auth_session_info *session_info =
451 241 : dcesrv_call_session_info(dce_call);
452 0 : struct dcesrv_handle *h;
453 0 : struct registry_key *key;
454 241 : const char *classname = NULL;
455 0 : WERROR result;
456 :
457 241 : DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY);
458 241 : key = h->data;
459 :
460 241 : switch (security_session_user_level(session_info, NULL))
461 : {
462 241 : case SECURITY_SYSTEM:
463 : case SECURITY_ADMINISTRATOR:
464 : case SECURITY_USER:
465 241 : result = reg_key_get_info(mem_ctx, key, &classname,
466 : r->out.num_subkeys, r->out.num_values,
467 : r->out.last_changed_time, r->out.max_subkeylen,
468 : r->out.max_valnamelen, r->out.max_valbufsize);
469 :
470 241 : if (r->out.max_subkeylen != NULL) {
471 : /* for UTF16 encoding */
472 241 : *r->out.max_subkeylen *= 2;
473 : }
474 241 : if (r->out.max_valnamelen != NULL) {
475 : /* for UTF16 encoding */
476 241 : *r->out.max_valnamelen *= 2;
477 : }
478 :
479 241 : if (classname != NULL) {
480 0 : r->out.classname->name = classname;
481 0 : r->out.classname->name_len = 2*strlen_m_term(classname);
482 : } else {
483 241 : r->out.classname->name = r->in.classname->name;
484 241 : r->out.classname->name_len = r->in.classname->name_len;
485 : }
486 241 : r->out.classname->name_size = r->in.classname->name_size;
487 :
488 241 : return result;
489 0 : default:
490 0 : return WERR_ACCESS_DENIED;
491 : }
492 : }
493 :
494 :
495 : /*
496 : winreg_QueryValue
497 : */
498 15200 : static WERROR dcesrv_winreg_QueryValue(struct dcesrv_call_state *dce_call,
499 : TALLOC_CTX *mem_ctx,
500 : struct winreg_QueryValue *r)
501 : {
502 0 : struct auth_session_info *session_info =
503 15200 : dcesrv_call_session_info(dce_call);
504 0 : struct dcesrv_handle *h;
505 0 : struct registry_key *key;
506 0 : uint32_t value_type;
507 0 : DATA_BLOB value_data;
508 0 : WERROR result;
509 :
510 15200 : DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY);
511 15200 : key = h->data;
512 :
513 15200 : switch (security_session_user_level(session_info, NULL))
514 : {
515 15200 : case SECURITY_SYSTEM:
516 : case SECURITY_ADMINISTRATOR:
517 : case SECURITY_USER:
518 15200 : if ((r->in.type == NULL) || (r->in.data_length == NULL) ||
519 9920 : (r->in.data_size == NULL)) {
520 7040 : return WERR_INVALID_PARAMETER;
521 : }
522 :
523 8160 : result = reg_key_get_value_by_name(mem_ctx, key,
524 8160 : r->in.value_name->name, &value_type, &value_data);
525 :
526 8160 : if (!W_ERROR_IS_OK(result)) {
527 : /* if the lookup wasn't successful, send client query back */
528 720 : value_type = *r->in.type;
529 720 : value_data.data = r->in.data;
530 720 : value_data.length = *r->in.data_length;
531 : } else {
532 7440 : if ((r->in.data != NULL)
533 5920 : && (*r->in.data_size < value_data.length)) {
534 2960 : result = WERR_MORE_DATA;
535 : }
536 : }
537 :
538 8160 : r->out.type = talloc(mem_ctx, enum winreg_Type);
539 8160 : if (!r->out.type) {
540 0 : return WERR_NOT_ENOUGH_MEMORY;
541 : }
542 8160 : *r->out.type = (enum winreg_Type) value_type;
543 8160 : r->out.data_length = talloc(mem_ctx, uint32_t);
544 8160 : if (!r->out.data_length) {
545 0 : return WERR_NOT_ENOUGH_MEMORY;
546 : }
547 8160 : *r->out.data_length = value_data.length;
548 8160 : r->out.data_size = talloc(mem_ctx, uint32_t);
549 8160 : if (!r->out.data_size) {
550 0 : return WERR_NOT_ENOUGH_MEMORY;
551 : }
552 8160 : *r->out.data_size = value_data.length;
553 8160 : r->out.data = value_data.data;
554 :
555 8160 : return result;
556 0 : default:
557 0 : return WERR_ACCESS_DENIED;
558 : }
559 : }
560 :
561 :
562 : /*
563 : winreg_ReplaceKey
564 : */
565 0 : static WERROR dcesrv_winreg_ReplaceKey(struct dcesrv_call_state *dce_call,
566 : TALLOC_CTX *mem_ctx,
567 : struct winreg_ReplaceKey *r)
568 : {
569 0 : return WERR_NOT_SUPPORTED;
570 : }
571 :
572 :
573 : /*
574 : winreg_RestoreKey
575 : */
576 0 : static WERROR dcesrv_winreg_RestoreKey(struct dcesrv_call_state *dce_call,
577 : TALLOC_CTX *mem_ctx,
578 : struct winreg_RestoreKey *r)
579 : {
580 0 : return WERR_NOT_SUPPORTED;
581 : }
582 :
583 :
584 : /*
585 : winreg_SaveKey
586 : */
587 0 : static WERROR dcesrv_winreg_SaveKey(struct dcesrv_call_state *dce_call,
588 : TALLOC_CTX *mem_ctx,
589 : struct winreg_SaveKey *r)
590 : {
591 0 : return WERR_NOT_SUPPORTED;
592 : }
593 :
594 :
595 : /*
596 : winreg_SetKeySecurity
597 : */
598 0 : static WERROR dcesrv_winreg_SetKeySecurity(struct dcesrv_call_state *dce_call,
599 : TALLOC_CTX *mem_ctx,
600 : struct winreg_SetKeySecurity *r)
601 : {
602 0 : return WERR_NOT_SUPPORTED;
603 : }
604 :
605 :
606 : /*
607 : winreg_SetValue
608 : */
609 2400 : static WERROR dcesrv_winreg_SetValue(struct dcesrv_call_state *dce_call,
610 : TALLOC_CTX *mem_ctx,
611 : struct winreg_SetValue *r)
612 : {
613 0 : struct auth_session_info *session_info =
614 2400 : dcesrv_call_session_info(dce_call);
615 0 : struct dcesrv_handle *h;
616 0 : struct registry_key *key;
617 0 : DATA_BLOB data;
618 0 : WERROR result;
619 :
620 2400 : DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY);
621 2400 : key = h->data;
622 :
623 2400 : switch (security_session_user_level(session_info, NULL))
624 : {
625 2400 : case SECURITY_SYSTEM:
626 : case SECURITY_ADMINISTRATOR:
627 2400 : data.data = r->in.data;
628 2400 : data.length = r->in.size;
629 2400 : result = reg_val_set(key, r->in.name.name, r->in.type, data);
630 2400 : return result;
631 0 : default:
632 0 : return WERR_ACCESS_DENIED;
633 : }
634 : }
635 :
636 :
637 : /*
638 : winreg_UnLoadKey
639 : */
640 0 : static WERROR dcesrv_winreg_UnLoadKey(struct dcesrv_call_state *dce_call,
641 : TALLOC_CTX *mem_ctx,
642 : struct winreg_UnLoadKey *r)
643 : {
644 0 : return WERR_NOT_SUPPORTED;
645 : }
646 :
647 :
648 : /*
649 : winreg_InitiateSystemShutdown
650 : */
651 0 : static WERROR dcesrv_winreg_InitiateSystemShutdown(struct dcesrv_call_state *dce_call,
652 : TALLOC_CTX *mem_ctx,
653 : struct winreg_InitiateSystemShutdown *r)
654 : {
655 0 : return WERR_NOT_SUPPORTED;
656 : }
657 :
658 :
659 : /*
660 : winreg_AbortSystemShutdown
661 : */
662 0 : static WERROR dcesrv_winreg_AbortSystemShutdown(struct dcesrv_call_state *dce_call,
663 : TALLOC_CTX *mem_ctx,
664 : struct winreg_AbortSystemShutdown *r)
665 : {
666 0 : return WERR_NOT_SUPPORTED;
667 : }
668 :
669 :
670 : /*
671 : winreg_GetVersion
672 : */
673 321 : static WERROR dcesrv_winreg_GetVersion(struct dcesrv_call_state *dce_call,
674 : TALLOC_CTX *mem_ctx,
675 : struct winreg_GetVersion *r)
676 : {
677 0 : struct dcesrv_handle *h;
678 :
679 321 : DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY);
680 :
681 321 : r->out.version = talloc(mem_ctx, uint32_t);
682 321 : W_ERROR_HAVE_NO_MEMORY(r->out.version);
683 :
684 321 : *r->out.version = 5;
685 :
686 321 : return WERR_OK;
687 : }
688 :
689 :
690 : /*
691 : winreg_QueryMultipleValues
692 : */
693 0 : static WERROR dcesrv_winreg_QueryMultipleValues(struct dcesrv_call_state *dce_call,
694 : TALLOC_CTX *mem_ctx,
695 : struct winreg_QueryMultipleValues *r)
696 : {
697 0 : return WERR_NOT_SUPPORTED;
698 : }
699 :
700 :
701 : /*
702 : winreg_InitiateSystemShutdownEx
703 : */
704 0 : static WERROR dcesrv_winreg_InitiateSystemShutdownEx(struct dcesrv_call_state *dce_call,
705 : TALLOC_CTX *mem_ctx,
706 : struct winreg_InitiateSystemShutdownEx *r)
707 : {
708 0 : return WERR_NOT_SUPPORTED;
709 : }
710 :
711 :
712 : /*
713 : winreg_SaveKeyEx
714 : */
715 0 : static WERROR dcesrv_winreg_SaveKeyEx(struct dcesrv_call_state *dce_call,
716 : TALLOC_CTX *mem_ctx,
717 : struct winreg_SaveKeyEx *r)
718 : {
719 0 : return WERR_NOT_SUPPORTED;
720 : }
721 :
722 :
723 : /*
724 : winreg_QueryMultipleValues2
725 : */
726 0 : static WERROR dcesrv_winreg_QueryMultipleValues2(struct dcesrv_call_state *dce_call,
727 : TALLOC_CTX *mem_ctx,
728 : struct winreg_QueryMultipleValues2 *r)
729 : {
730 0 : return WERR_NOT_SUPPORTED;
731 : }
732 :
733 : /*
734 : winreg_DeleteKeyEx
735 : */
736 0 : static WERROR dcesrv_winreg_DeleteKeyEx(struct dcesrv_call_state *dce_call,
737 : TALLOC_CTX *mem_ctx,
738 : struct winreg_DeleteKeyEx *r)
739 : {
740 0 : return WERR_NOT_SUPPORTED;
741 : }
742 :
743 : /* include the generated boilerplate */
744 : #include "librpc/gen_ndr/ndr_winreg_s.c"
|