s4:WINREG RPC server - Cosmetic
[Samba/ekacnet.git] / source4 / rpc_server / winreg / rpc_winreg.c
blob86617a606a34d7984f2720a8551e2d7db15a30ec
1 /*
2 Unix SMB/CIFS implementation.
4 endpoint server for the winreg pipe
6 Copyright (C) 2004 Jelmer Vernooij, jelmer@samba.org
7 Copyright (C) 2008 Matthias Dieter Wallnöfer, mwallnoefer@yahoo.de
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.
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.
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/>.
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/security.h"
30 enum handle_types { HTYPE_REGVAL, HTYPE_REGKEY };
32 static NTSTATUS dcerpc_winreg_bind(struct dcesrv_call_state *dce_call,
33 const struct dcesrv_interface *iface)
35 struct registry_context *ctx;
36 WERROR err;
38 err = reg_open_samba(dce_call->context,
39 &ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx,
40 dce_call->conn->auth_state.session_info,
41 NULL);
43 if (!W_ERROR_IS_OK(err)) {
44 DEBUG(0, ("Error opening registry: %s\n", win_errstr(err)));
45 return NT_STATUS_UNSUCCESSFUL;
48 dce_call->context->private_data = ctx;
50 return NT_STATUS_OK;
53 #define DCESRV_INTERFACE_WINREG_BIND dcerpc_winreg_bind
55 static WERROR dcesrv_winreg_openhive(struct dcesrv_call_state *dce_call,
56 TALLOC_CTX *mem_ctx, uint32_t hkey,
57 struct policy_handle **outh)
59 struct registry_context *ctx = dce_call->context->private_data;
60 struct dcesrv_handle *h;
61 WERROR result;
63 h = dcesrv_handle_new(dce_call->context, HTYPE_REGKEY);
65 result = reg_get_predefined_key(ctx, hkey,
66 (struct registry_key **)&h->data);
67 if (!W_ERROR_IS_OK(result)) {
68 return result;
70 *outh = &h->wire_handle;
72 return result;
75 #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) \
76 { \
77 return dcesrv_winreg_openhive (dce_call, mem_ctx, n, &r->out.handle);\
80 func_winreg_OpenHive(HKCR,HKEY_CLASSES_ROOT)
81 func_winreg_OpenHive(HKCU,HKEY_CURRENT_USER)
82 func_winreg_OpenHive(HKLM,HKEY_LOCAL_MACHINE)
83 func_winreg_OpenHive(HKPD,HKEY_PERFORMANCE_DATA)
84 func_winreg_OpenHive(HKU,HKEY_USERS)
85 func_winreg_OpenHive(HKCC,HKEY_CURRENT_CONFIG)
86 func_winreg_OpenHive(HKDD,HKEY_DYN_DATA)
87 func_winreg_OpenHive(HKPT,HKEY_PERFORMANCE_TEXT)
88 func_winreg_OpenHive(HKPN,HKEY_PERFORMANCE_NLSTEXT)
91 winreg_CloseKey
93 static WERROR dcesrv_winreg_CloseKey(struct dcesrv_call_state *dce_call,
94 TALLOC_CTX *mem_ctx,
95 struct winreg_CloseKey *r)
97 struct dcesrv_handle *h;
99 DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY);
101 ZERO_STRUCTP(r->out.handle);
103 return WERR_OK;
107 winreg_CreateKey
109 static WERROR dcesrv_winreg_CreateKey(struct dcesrv_call_state *dce_call,
110 TALLOC_CTX *mem_ctx,
111 struct winreg_CreateKey *r)
113 struct dcesrv_handle *h, *newh;
114 struct security_descriptor sd;
115 struct registry_key *key;
116 WERROR result;
118 DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY);
119 key = h->data;
121 newh = dcesrv_handle_new(dce_call->context, HTYPE_REGKEY);
123 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
125 case SECURITY_SYSTEM:
126 case SECURITY_ADMINISTRATOR:
127 /* the security descriptor is optional */
128 if (r->in.secdesc != NULL) {
129 DATA_BLOB sdblob;
130 enum ndr_err_code ndr_err;
131 sdblob.data = r->in.secdesc->sd.data;
132 sdblob.length = r->in.secdesc->sd.len;
133 if (sdblob.data == NULL) {
134 return WERR_INVALID_PARAM;
136 ndr_err = ndr_pull_struct_blob_all(&sdblob, mem_ctx, NULL, &sd,
137 (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
138 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
139 return WERR_INVALID_PARAM;
143 result = reg_key_add_name(newh, key, r->in.name.name, NULL,
144 r->in.secdesc?&sd:NULL, (struct registry_key **)&newh->data);
145 if (W_ERROR_IS_OK(result)) {
146 r->out.new_handle = &newh->wire_handle;
147 } else {
148 talloc_free(newh);
151 return result;
152 default:
153 return WERR_ACCESS_DENIED;
159 winreg_DeleteKey
161 static WERROR dcesrv_winreg_DeleteKey(struct dcesrv_call_state *dce_call,
162 TALLOC_CTX *mem_ctx,
163 struct winreg_DeleteKey *r)
165 struct dcesrv_handle *h;
166 struct registry_key *key;
168 DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY);
169 key = h->data;
171 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
173 case SECURITY_SYSTEM:
174 case SECURITY_ADMINISTRATOR:
175 return reg_key_del(key, r->in.key.name);
176 default:
177 return WERR_ACCESS_DENIED;
183 winreg_DeleteValue
185 static WERROR dcesrv_winreg_DeleteValue(struct dcesrv_call_state *dce_call,
186 TALLOC_CTX *mem_ctx,
187 struct winreg_DeleteValue *r)
189 struct dcesrv_handle *h;
190 struct registry_key *key;
192 DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY);
193 key = h->data;
195 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
197 case SECURITY_SYSTEM:
198 case SECURITY_ADMINISTRATOR:
199 return reg_del_value(key, r->in.value.name);
200 default:
201 return WERR_ACCESS_DENIED;
207 winreg_EnumKey
209 static WERROR dcesrv_winreg_EnumKey(struct dcesrv_call_state *dce_call,
210 TALLOC_CTX *mem_ctx,
211 struct winreg_EnumKey *r)
213 struct dcesrv_handle *h;
214 struct registry_key *key;
215 const char *name, *classname;
216 NTTIME last_mod;
217 WERROR result;
219 DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY);
220 key = h->data;
222 result = reg_key_get_subkey_by_index(mem_ctx,
223 key, r->in.enum_index, &name, &classname, &last_mod);
225 if (2*strlen_m_term(name) > r->in.name->size) {
226 return WERR_MORE_DATA;
229 if (name != NULL) {
230 r->out.name->name = name;
231 r->out.name->length = 2*strlen_m_term(name);
232 } else {
233 r->out.name->name = r->in.name->name;
234 r->out.name->length = r->in.name->length;
236 r->out.name->size = r->in.name->size;
238 r->out.keyclass = r->in.keyclass;
239 if (classname != NULL) {
240 r->out.keyclass->name = classname;
241 r->out.keyclass->length = 2*strlen_m_term(classname);
242 } else {
243 r->out.keyclass->name = r->in.keyclass->name;
244 r->out.keyclass->length = r->in.keyclass->length;
246 r->out.keyclass->size = r->in.keyclass->size;
248 if (r->in.last_changed_time != NULL)
249 r->out.last_changed_time = &last_mod;
251 return result;
256 winreg_EnumValue
258 static WERROR dcesrv_winreg_EnumValue(struct dcesrv_call_state *dce_call,
259 TALLOC_CTX *mem_ctx,
260 struct winreg_EnumValue *r)
262 struct dcesrv_handle *h;
263 struct registry_key *key;
264 const char *data_name;
265 uint32_t data_type;
266 DATA_BLOB data;
267 WERROR result;
269 DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY);
270 key = h->data;
272 result = reg_key_get_value_by_index(mem_ctx, key,
273 r->in.enum_index, &data_name, &data_type, &data);
275 if (!W_ERROR_IS_OK(result)) {
276 /* if the lookup wasn't successful, send client query back */
277 data_name = r->in.name->name;
278 data_type = *r->in.type;
279 data.data = r->in.value;
280 data.length = *r->in.length;
283 /* check if there is enough room for the name */
284 if (r->in.name->size < 2*strlen_m_term(data_name)) {
285 return WERR_MORE_DATA;
288 /* "data_name" is NULL when we query the default attribute */
289 if (data_name != NULL) {
290 r->out.name->name = data_name;
291 r->out.name->length = 2*strlen_m_term(data_name);
292 } else {
293 r->out.name->name = r->in.name->name;
294 r->out.name->length = r->in.name->length;
296 r->out.name->size = r->in.name->size;
298 r->out.type = talloc(mem_ctx, uint32_t);
299 if (!r->out.type) {
300 return WERR_NOMEM;
302 *r->out.type = data_type;
304 /* check the client has enough room for the value */
305 if (r->in.value != NULL &&
306 r->in.size != NULL &&
307 data.length > *r->in.size) {
308 return WERR_MORE_DATA;
311 if (r->in.value != NULL) {
312 r->out.value = data.data;
315 if (r->in.size != NULL) {
316 r->out.size = talloc(mem_ctx, uint32_t);
317 *r->out.size = data.length;
318 r->out.length = r->out.size;
321 return result;
326 winreg_FlushKey
328 static WERROR dcesrv_winreg_FlushKey(struct dcesrv_call_state *dce_call,
329 TALLOC_CTX *mem_ctx,
330 struct winreg_FlushKey *r)
332 struct dcesrv_handle *h;
333 struct registry_key *key;
335 DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY);
336 key = h->data;
338 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
340 case SECURITY_SYSTEM:
341 case SECURITY_ADMINISTRATOR:
342 return reg_key_flush(key);
343 default:
344 return WERR_ACCESS_DENIED;
350 winreg_GetKeySecurity
352 static WERROR dcesrv_winreg_GetKeySecurity(struct dcesrv_call_state *dce_call,
353 TALLOC_CTX *mem_ctx,
354 struct winreg_GetKeySecurity *r)
356 struct dcesrv_handle *h;
358 DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY);
360 return WERR_NOT_SUPPORTED;
365 winreg_LoadKey
367 static WERROR dcesrv_winreg_LoadKey(struct dcesrv_call_state *dce_call,
368 TALLOC_CTX *mem_ctx,
369 struct winreg_LoadKey *r)
371 return WERR_NOT_SUPPORTED;
376 winreg_NotifyChangeKeyValue
378 static WERROR dcesrv_winreg_NotifyChangeKeyValue(struct dcesrv_call_state *dce_call,
379 TALLOC_CTX *mem_ctx,
380 struct winreg_NotifyChangeKeyValue *r)
382 return WERR_NOT_SUPPORTED;
387 winreg_OpenKey
389 static WERROR dcesrv_winreg_OpenKey(struct dcesrv_call_state *dce_call,
390 TALLOC_CTX *mem_ctx,
391 struct winreg_OpenKey *r)
393 struct dcesrv_handle *h, *newh;
394 struct registry_key *key;
395 WERROR result;
397 DCESRV_PULL_HANDLE_FAULT(h, r->in.parent_handle, HTYPE_REGKEY);
398 key = h->data;
400 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
402 case SECURITY_SYSTEM:
403 case SECURITY_ADMINISTRATOR:
404 case SECURITY_USER:
405 if (r->in.keyname.name && strcmp(r->in.keyname.name, "") == 0) {
406 newh = talloc_reference(dce_call->context, h);
407 result = WERR_OK;
408 } else {
409 newh = dcesrv_handle_new(dce_call->context, HTYPE_REGKEY);
410 result = reg_open_key(newh, key, r->in.keyname.name,
411 (struct registry_key **)&newh->data);
414 if (W_ERROR_IS_OK(result)) {
415 r->out.handle = &newh->wire_handle;
416 } else {
417 talloc_free(newh);
419 return result;
420 default:
421 return WERR_ACCESS_DENIED;
427 winreg_QueryInfoKey
429 static WERROR dcesrv_winreg_QueryInfoKey(struct dcesrv_call_state *dce_call,
430 TALLOC_CTX *mem_ctx,
431 struct winreg_QueryInfoKey *r)
433 struct dcesrv_handle *h;
434 struct registry_key *key;
435 const char *classname = NULL;
436 WERROR result;
438 DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY);
439 key = h->data;
441 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
443 case SECURITY_SYSTEM:
444 case SECURITY_ADMINISTRATOR:
445 case SECURITY_USER:
446 result = reg_key_get_info(mem_ctx, key, &classname,
447 r->out.num_subkeys, r->out.num_values,
448 r->out.last_changed_time, r->out.max_subkeylen,
449 r->out.max_valnamelen, r->out.max_valbufsize);
451 if (classname != NULL) {
452 r->out.classname->name = classname;
453 r->out.classname->name_len = 2*strlen_m_term(classname);
454 } else {
455 r->out.classname->name = r->in.classname->name;
456 r->out.classname->name_len = r->in.classname->name_len;
458 r->out.classname->name_size = r->in.classname->name_size;
460 return result;
461 default:
462 return WERR_ACCESS_DENIED;
468 winreg_QueryValue
470 static WERROR dcesrv_winreg_QueryValue(struct dcesrv_call_state *dce_call,
471 TALLOC_CTX *mem_ctx,
472 struct winreg_QueryValue *r)
474 struct dcesrv_handle *h;
475 struct registry_key *key;
476 uint32_t value_type;
477 DATA_BLOB value_data;
478 WERROR result;
480 DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY);
481 key = h->data;
483 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
485 case SECURITY_SYSTEM:
486 case SECURITY_ADMINISTRATOR:
487 case SECURITY_USER:
488 result = reg_key_get_value_by_name(mem_ctx, key,
489 r->in.value_name->name, &value_type, &value_data);
491 if (!W_ERROR_IS_OK(result)) {
492 /* if the lookup wasn't successful, send client query back */
493 value_type = *r->in.type;
494 value_data.data = r->in.data;
495 value_data.length = *r->in.data_length;
498 r->out.type = talloc(mem_ctx, uint32_t);
499 if (!r->out.type) {
500 return WERR_NOMEM;
502 *r->out.type = value_type;
503 r->out.data_length = talloc(mem_ctx, uint32_t);
504 if (!r->out.data_length) {
505 return WERR_NOMEM;
507 *r->out.data_length = value_data.length;
508 r->out.data_size = talloc(mem_ctx, uint32_t);
509 if (!r->out.data_size) {
510 return WERR_NOMEM;
512 *r->out.data_size = value_data.length;
513 r->out.data = value_data.data;
515 return result;
516 default:
517 return WERR_ACCESS_DENIED;
523 winreg_ReplaceKey
525 static WERROR dcesrv_winreg_ReplaceKey(struct dcesrv_call_state *dce_call,
526 TALLOC_CTX *mem_ctx,
527 struct winreg_ReplaceKey *r)
529 return WERR_NOT_SUPPORTED;
534 winreg_RestoreKey
536 static WERROR dcesrv_winreg_RestoreKey(struct dcesrv_call_state *dce_call,
537 TALLOC_CTX *mem_ctx,
538 struct winreg_RestoreKey *r)
540 return WERR_NOT_SUPPORTED;
545 winreg_SaveKey
547 static WERROR dcesrv_winreg_SaveKey(struct dcesrv_call_state *dce_call,
548 TALLOC_CTX *mem_ctx,
549 struct winreg_SaveKey *r)
551 return WERR_NOT_SUPPORTED;
556 winreg_SetKeySecurity
558 static WERROR dcesrv_winreg_SetKeySecurity(struct dcesrv_call_state *dce_call,
559 TALLOC_CTX *mem_ctx,
560 struct winreg_SetKeySecurity *r)
562 return WERR_NOT_SUPPORTED;
567 winreg_SetValue
569 static WERROR dcesrv_winreg_SetValue(struct dcesrv_call_state *dce_call,
570 TALLOC_CTX *mem_ctx,
571 struct winreg_SetValue *r)
573 struct dcesrv_handle *h;
574 struct registry_key *key;
575 DATA_BLOB data;
576 WERROR result;
578 DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY);
579 key = h->data;
581 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
583 case SECURITY_SYSTEM:
584 case SECURITY_ADMINISTRATOR:
585 data.data = r->in.data;
586 data.length = r->in.size;
587 result = reg_val_set(key, r->in.name.name, r->in.type, data);
588 return result;
589 default:
590 return WERR_ACCESS_DENIED;
596 winreg_UnLoadKey
598 static WERROR dcesrv_winreg_UnLoadKey(struct dcesrv_call_state *dce_call,
599 TALLOC_CTX *mem_ctx,
600 struct winreg_UnLoadKey *r)
602 return WERR_NOT_SUPPORTED;
607 winreg_InitiateSystemShutdown
609 static WERROR dcesrv_winreg_InitiateSystemShutdown(struct dcesrv_call_state *dce_call,
610 TALLOC_CTX *mem_ctx,
611 struct winreg_InitiateSystemShutdown *r)
613 return WERR_NOT_SUPPORTED;
618 winreg_AbortSystemShutdown
620 static WERROR dcesrv_winreg_AbortSystemShutdown(struct dcesrv_call_state *dce_call,
621 TALLOC_CTX *mem_ctx,
622 struct winreg_AbortSystemShutdown *r)
624 return WERR_NOT_SUPPORTED;
629 winreg_GetVersion
631 static WERROR dcesrv_winreg_GetVersion(struct dcesrv_call_state *dce_call,
632 TALLOC_CTX *mem_ctx,
633 struct winreg_GetVersion *r)
635 struct dcesrv_handle *h;
637 DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY);
639 r->out.version = talloc(mem_ctx, uint32_t);
640 W_ERROR_HAVE_NO_MEMORY(r->out.version);
642 *r->out.version = 5;
644 return WERR_OK;
649 winreg_QueryMultipleValues
651 static WERROR dcesrv_winreg_QueryMultipleValues(struct dcesrv_call_state *dce_call,
652 TALLOC_CTX *mem_ctx,
653 struct winreg_QueryMultipleValues *r)
655 return WERR_NOT_SUPPORTED;
660 winreg_InitiateSystemShutdownEx
662 static WERROR dcesrv_winreg_InitiateSystemShutdownEx(struct dcesrv_call_state *dce_call,
663 TALLOC_CTX *mem_ctx,
664 struct winreg_InitiateSystemShutdownEx *r)
666 return WERR_NOT_SUPPORTED;
671 winreg_SaveKeyEx
673 static WERROR dcesrv_winreg_SaveKeyEx(struct dcesrv_call_state *dce_call,
674 TALLOC_CTX *mem_ctx,
675 struct winreg_SaveKeyEx *r)
677 return WERR_NOT_SUPPORTED;
682 winreg_QueryMultipleValues2
684 static WERROR dcesrv_winreg_QueryMultipleValues2(struct dcesrv_call_state *dce_call,
685 TALLOC_CTX *mem_ctx,
686 struct winreg_QueryMultipleValues2 *r)
688 return WERR_NOT_SUPPORTED;
692 /* include the generated boilerplate */
693 #include "librpc/gen_ndr/ndr_winreg_s.c"