Remove smb_fname duplicates that just keep the same information as in fsp->fsp_name.
[Samba/gbeck.git] / source4 / rpc_server / winreg / rpc_winreg.c
blobc365d82875be7e520266e30e90654a51220648ca
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, dce_call->conn->auth_state.session_info,
40 NULL);
42 if (!W_ERROR_IS_OK(err)) {
43 DEBUG(0, ("Error opening registry: %s\n", win_errstr(err)));
44 return NT_STATUS_UNSUCCESSFUL;
47 dce_call->context->private_data = ctx;
49 return NT_STATUS_OK;
52 #define DCESRV_INTERFACE_WINREG_BIND dcerpc_winreg_bind
54 static WERROR dcesrv_winreg_openhive(struct dcesrv_call_state *dce_call,
55 TALLOC_CTX *mem_ctx, uint32_t hkey,
56 struct policy_handle **outh)
58 struct registry_context *ctx = dce_call->context->private_data;
59 struct dcesrv_handle *h;
60 WERROR result;
62 h = dcesrv_handle_new(dce_call->context, HTYPE_REGKEY);
64 result = reg_get_predefined_key(ctx, hkey,
65 (struct registry_key **)&h->data);
66 if (!W_ERROR_IS_OK(result)) {
67 return result;
69 *outh = &h->wire_handle;
71 return result;
74 #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) \
75 { \
76 return dcesrv_winreg_openhive (dce_call, mem_ctx, n, &r->out.handle);\
79 func_winreg_OpenHive(HKCR,HKEY_CLASSES_ROOT)
80 func_winreg_OpenHive(HKCU,HKEY_CURRENT_USER)
81 func_winreg_OpenHive(HKLM,HKEY_LOCAL_MACHINE)
82 func_winreg_OpenHive(HKPD,HKEY_PERFORMANCE_DATA)
83 func_winreg_OpenHive(HKU,HKEY_USERS)
84 func_winreg_OpenHive(HKCC,HKEY_CURRENT_CONFIG)
85 func_winreg_OpenHive(HKDD,HKEY_DYN_DATA)
86 func_winreg_OpenHive(HKPT,HKEY_PERFORMANCE_TEXT)
87 func_winreg_OpenHive(HKPN,HKEY_PERFORMANCE_NLSTEXT)
90 winreg_CloseKey
92 static WERROR dcesrv_winreg_CloseKey(struct dcesrv_call_state *dce_call,
93 TALLOC_CTX *mem_ctx,
94 struct winreg_CloseKey *r)
96 struct dcesrv_handle *h;
98 DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY);
100 talloc_free(h);
102 ZERO_STRUCTP(r->out.handle);
104 return WERR_OK;
108 winreg_CreateKey
110 static WERROR dcesrv_winreg_CreateKey(struct dcesrv_call_state *dce_call,
111 TALLOC_CTX *mem_ctx,
112 struct winreg_CreateKey *r)
114 struct dcesrv_handle *h, *newh;
115 struct security_descriptor sd;
116 struct registry_key *key;
117 WERROR result;
119 DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY);
120 key = h->data;
122 newh = dcesrv_handle_new(dce_call->context, HTYPE_REGKEY);
124 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
126 case SECURITY_SYSTEM:
127 case SECURITY_ADMINISTRATOR:
128 /* the security descriptor is optional */
129 if (r->in.secdesc != NULL) {
130 DATA_BLOB sdblob;
131 enum ndr_err_code ndr_err;
132 sdblob.data = r->in.secdesc->sd.data;
133 sdblob.length = r->in.secdesc->sd.len;
134 if (sdblob.data == NULL) {
135 return WERR_INVALID_PARAM;
137 ndr_err = ndr_pull_struct_blob_all(&sdblob, mem_ctx, NULL, &sd,
138 (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
139 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
140 return WERR_INVALID_PARAM;
144 result = reg_key_add_name(newh, key, r->in.name.name, NULL,
145 r->in.secdesc?&sd:NULL, (struct registry_key **)&newh->data);
146 if (W_ERROR_IS_OK(result)) {
147 r->out.new_handle = &newh->wire_handle;
148 } else {
149 talloc_free(newh);
152 return result;
153 default:
154 return WERR_ACCESS_DENIED;
160 winreg_DeleteKey
162 static WERROR dcesrv_winreg_DeleteKey(struct dcesrv_call_state *dce_call,
163 TALLOC_CTX *mem_ctx,
164 struct winreg_DeleteKey *r)
166 struct dcesrv_handle *h;
167 struct registry_key *key;
169 DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY);
170 key = h->data;
172 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
174 case SECURITY_SYSTEM:
175 case SECURITY_ADMINISTRATOR:
176 return reg_key_del(key, r->in.key.name);
177 default:
178 return WERR_ACCESS_DENIED;
184 winreg_DeleteValue
186 static WERROR dcesrv_winreg_DeleteValue(struct dcesrv_call_state *dce_call,
187 TALLOC_CTX *mem_ctx,
188 struct winreg_DeleteValue *r)
190 struct dcesrv_handle *h;
191 struct registry_key *key;
193 DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY);
194 key = h->data;
196 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
198 case SECURITY_SYSTEM:
199 case SECURITY_ADMINISTRATOR:
200 return reg_del_value(key, r->in.value.name);
201 default:
202 return WERR_ACCESS_DENIED;
208 winreg_EnumKey
210 static WERROR dcesrv_winreg_EnumKey(struct dcesrv_call_state *dce_call,
211 TALLOC_CTX *mem_ctx,
212 struct winreg_EnumKey *r)
214 struct dcesrv_handle *h;
215 struct registry_key *key;
216 const char *name, *classname;
217 NTTIME last_mod;
218 WERROR result;
220 DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY);
221 key = h->data;
223 result = reg_key_get_subkey_by_index(mem_ctx,
224 key, r->in.enum_index, &name, &classname, &last_mod);
226 if (2*strlen_m_term(name) > r->in.name->size) {
227 return WERR_MORE_DATA;
230 if (name != NULL) {
231 r->out.name->name = name;
232 r->out.name->length = 2*strlen_m_term(name);
233 } else {
234 r->out.name->name = r->in.name->name;
235 r->out.name->length = r->in.name->length;
237 r->out.name->size = r->in.name->size;
239 r->out.keyclass = r->in.keyclass;
240 if (classname != NULL) {
241 r->out.keyclass->name = classname;
242 r->out.keyclass->length = 2*strlen_m_term(classname);
243 } else {
244 r->out.keyclass->name = r->in.keyclass->name;
245 r->out.keyclass->length = r->in.keyclass->length;
247 r->out.keyclass->size = r->in.keyclass->size;
249 if (r->in.last_changed_time != NULL)
250 r->out.last_changed_time = &last_mod;
252 return result;
257 winreg_EnumValue
259 static WERROR dcesrv_winreg_EnumValue(struct dcesrv_call_state *dce_call,
260 TALLOC_CTX *mem_ctx,
261 struct winreg_EnumValue *r)
263 struct dcesrv_handle *h;
264 struct registry_key *key;
265 const char *data_name;
266 uint32_t data_type;
267 DATA_BLOB data;
268 WERROR result;
270 DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY);
271 key = h->data;
273 result = reg_key_get_value_by_index(mem_ctx, key,
274 r->in.enum_index, &data_name, &data_type, &data);
276 if (!W_ERROR_IS_OK(result)) {
277 /* if the lookup wasn't successful, send client query back */
278 data_name = r->in.name->name;
279 data_type = *r->in.type;
280 data.data = r->in.value;
281 data.length = *r->in.length;
284 /* check if there is enough room for the name */
285 if (r->in.name->size < 2*strlen_m_term(data_name)) {
286 return WERR_MORE_DATA;
289 /* "data_name" is NULL when we query the default attribute */
290 if (data_name != NULL) {
291 r->out.name->name = data_name;
292 r->out.name->length = 2*strlen_m_term(data_name);
293 } else {
294 r->out.name->name = r->in.name->name;
295 r->out.name->length = r->in.name->length;
297 r->out.name->size = r->in.name->size;
299 r->out.type = talloc(mem_ctx, uint32_t);
300 if (!r->out.type) {
301 return WERR_NOMEM;
303 *r->out.type = data_type;
305 /* check the client has enough room for the value */
306 if (r->in.value != NULL &&
307 r->in.size != NULL &&
308 data.length > *r->in.size) {
309 return WERR_MORE_DATA;
312 if (r->in.value != NULL) {
313 r->out.value = data.data;
316 if (r->in.size != NULL) {
317 r->out.size = talloc(mem_ctx, uint32_t);
318 *r->out.size = data.length;
319 r->out.length = r->out.size;
322 return result;
327 winreg_FlushKey
329 static WERROR dcesrv_winreg_FlushKey(struct dcesrv_call_state *dce_call,
330 TALLOC_CTX *mem_ctx,
331 struct winreg_FlushKey *r)
333 struct dcesrv_handle *h;
334 struct registry_key *key;
336 DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY);
337 key = h->data;
339 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
341 case SECURITY_SYSTEM:
342 case SECURITY_ADMINISTRATOR:
343 return reg_key_flush(key);
344 default:
345 return WERR_ACCESS_DENIED;
351 winreg_GetKeySecurity
353 static WERROR dcesrv_winreg_GetKeySecurity(struct dcesrv_call_state *dce_call,
354 TALLOC_CTX *mem_ctx,
355 struct winreg_GetKeySecurity *r)
357 struct dcesrv_handle *h;
359 DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY);
361 return WERR_NOT_SUPPORTED;
366 winreg_LoadKey
368 static WERROR dcesrv_winreg_LoadKey(struct dcesrv_call_state *dce_call,
369 TALLOC_CTX *mem_ctx,
370 struct winreg_LoadKey *r)
372 return WERR_NOT_SUPPORTED;
377 winreg_NotifyChangeKeyValue
379 static WERROR dcesrv_winreg_NotifyChangeKeyValue(struct dcesrv_call_state *dce_call,
380 TALLOC_CTX *mem_ctx,
381 struct winreg_NotifyChangeKeyValue *r)
383 return WERR_NOT_SUPPORTED;
388 winreg_OpenKey
390 static WERROR dcesrv_winreg_OpenKey(struct dcesrv_call_state *dce_call,
391 TALLOC_CTX *mem_ctx,
392 struct winreg_OpenKey *r)
394 struct dcesrv_handle *h, *newh;
395 struct registry_key *key;
396 WERROR result;
398 DCESRV_PULL_HANDLE_FAULT(h, r->in.parent_handle, HTYPE_REGKEY);
399 key = h->data;
401 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
403 case SECURITY_SYSTEM:
404 case SECURITY_ADMINISTRATOR:
405 case SECURITY_USER:
406 if (r->in.keyname.name && strcmp(r->in.keyname.name, "") == 0) {
407 newh = talloc_reference(dce_call->context, h);
408 result = WERR_OK;
409 } else {
410 newh = dcesrv_handle_new(dce_call->context, HTYPE_REGKEY);
411 result = reg_open_key(newh, key, r->in.keyname.name,
412 (struct registry_key **)&newh->data);
415 if (W_ERROR_IS_OK(result)) {
416 r->out.handle = &newh->wire_handle;
417 } else {
418 talloc_free(newh);
420 return result;
421 default:
422 return WERR_ACCESS_DENIED;
429 winreg_QueryInfoKey
431 static WERROR dcesrv_winreg_QueryInfoKey(struct dcesrv_call_state *dce_call,
432 TALLOC_CTX *mem_ctx,
433 struct winreg_QueryInfoKey *r)
435 struct dcesrv_handle *h;
436 struct registry_key *key;
437 const char *classname = NULL;
438 WERROR result;
440 DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY);
441 key = h->data;
443 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
445 case SECURITY_SYSTEM:
446 case SECURITY_ADMINISTRATOR:
447 case SECURITY_USER:
448 result = reg_key_get_info(mem_ctx, key, &classname,
449 r->out.num_subkeys, r->out.num_values,
450 r->out.last_changed_time, r->out.max_subkeylen,
451 r->out.max_valnamelen, r->out.max_valbufsize);
453 if (classname != NULL) {
454 r->out.classname->name = classname;
455 r->out.classname->name_len = 2*strlen_m_term(classname);
456 } else {
457 r->out.classname->name = r->in.classname->name;
458 r->out.classname->name_len = r->in.classname->name_len;
460 r->out.classname->name_size = r->in.classname->name_size;
462 return result;
463 default:
464 return WERR_ACCESS_DENIED;
470 winreg_QueryValue
472 static WERROR dcesrv_winreg_QueryValue(struct dcesrv_call_state *dce_call,
473 TALLOC_CTX *mem_ctx,
474 struct winreg_QueryValue *r)
476 struct dcesrv_handle *h;
477 struct registry_key *key;
478 uint32_t value_type;
479 DATA_BLOB value_data;
480 WERROR result;
482 DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY);
483 key = h->data;
485 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
487 case SECURITY_SYSTEM:
488 case SECURITY_ADMINISTRATOR:
489 case SECURITY_USER:
490 result = reg_key_get_value_by_name(mem_ctx, key,
491 r->in.value_name->name, &value_type, &value_data);
493 if (!W_ERROR_IS_OK(result)) {
494 /* if the lookup wasn't successful, send client query back */
495 value_type = *r->in.type;
496 value_data.data = r->in.data;
497 value_data.length = *r->in.data_length;
500 r->out.type = talloc(mem_ctx, uint32_t);
501 if (!r->out.type) {
502 return WERR_NOMEM;
504 *r->out.type = value_type;
505 r->out.data_length = talloc(mem_ctx, uint32_t);
506 if (!r->out.data_length) {
507 return WERR_NOMEM;
509 *r->out.data_length = value_data.length;
510 r->out.data_size = talloc(mem_ctx, uint32_t);
511 if (!r->out.data_size) {
512 return WERR_NOMEM;
514 *r->out.data_size = value_data.length;
515 r->out.data = value_data.data;
517 return result;
518 default:
519 return WERR_ACCESS_DENIED;
525 winreg_ReplaceKey
527 static WERROR dcesrv_winreg_ReplaceKey(struct dcesrv_call_state *dce_call,
528 TALLOC_CTX *mem_ctx,
529 struct winreg_ReplaceKey *r)
531 return WERR_NOT_SUPPORTED;
536 winreg_RestoreKey
538 static WERROR dcesrv_winreg_RestoreKey(struct dcesrv_call_state *dce_call,
539 TALLOC_CTX *mem_ctx,
540 struct winreg_RestoreKey *r)
542 return WERR_NOT_SUPPORTED;
547 winreg_SaveKey
549 static WERROR dcesrv_winreg_SaveKey(struct dcesrv_call_state *dce_call,
550 TALLOC_CTX *mem_ctx,
551 struct winreg_SaveKey *r)
553 return WERR_NOT_SUPPORTED;
558 winreg_SetKeySecurity
560 static WERROR dcesrv_winreg_SetKeySecurity(struct dcesrv_call_state *dce_call,
561 TALLOC_CTX *mem_ctx,
562 struct winreg_SetKeySecurity *r)
564 return WERR_NOT_SUPPORTED;
569 winreg_SetValue
571 static WERROR dcesrv_winreg_SetValue(struct dcesrv_call_state *dce_call,
572 TALLOC_CTX *mem_ctx,
573 struct winreg_SetValue *r)
575 struct dcesrv_handle *h;
576 struct registry_key *key;
577 DATA_BLOB data;
578 WERROR result;
580 DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY);
581 key = h->data;
583 switch (security_session_user_level(dce_call->conn->auth_state.session_info))
585 case SECURITY_SYSTEM:
586 case SECURITY_ADMINISTRATOR:
587 data.data = r->in.data;
588 data.length = r->in.size;
589 result = reg_val_set(key, r->in.name.name, r->in.type, data);
590 return result;
591 default:
592 return WERR_ACCESS_DENIED;
598 winreg_UnLoadKey
600 static WERROR dcesrv_winreg_UnLoadKey(struct dcesrv_call_state *dce_call,
601 TALLOC_CTX *mem_ctx,
602 struct winreg_UnLoadKey *r)
604 return WERR_NOT_SUPPORTED;
609 winreg_InitiateSystemShutdown
611 static WERROR dcesrv_winreg_InitiateSystemShutdown(struct dcesrv_call_state *dce_call,
612 TALLOC_CTX *mem_ctx,
613 struct winreg_InitiateSystemShutdown *r)
615 return WERR_NOT_SUPPORTED;
620 winreg_AbortSystemShutdown
622 static WERROR dcesrv_winreg_AbortSystemShutdown(struct dcesrv_call_state *dce_call,
623 TALLOC_CTX *mem_ctx,
624 struct winreg_AbortSystemShutdown *r)
626 return WERR_NOT_SUPPORTED;
631 winreg_GetVersion
633 static WERROR dcesrv_winreg_GetVersion(struct dcesrv_call_state *dce_call,
634 TALLOC_CTX *mem_ctx,
635 struct winreg_GetVersion *r)
637 struct dcesrv_handle *h;
639 DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY);
641 r->out.version = talloc(mem_ctx, uint32_t);
642 W_ERROR_HAVE_NO_MEMORY(r->out.version);
644 *r->out.version = 5;
646 return WERR_OK;
651 winreg_QueryMultipleValues
653 static WERROR dcesrv_winreg_QueryMultipleValues(struct dcesrv_call_state *dce_call,
654 TALLOC_CTX *mem_ctx,
655 struct winreg_QueryMultipleValues *r)
657 return WERR_NOT_SUPPORTED;
662 winreg_InitiateSystemShutdownEx
664 static WERROR dcesrv_winreg_InitiateSystemShutdownEx(struct dcesrv_call_state *dce_call,
665 TALLOC_CTX *mem_ctx,
666 struct winreg_InitiateSystemShutdownEx *r)
668 return WERR_NOT_SUPPORTED;
673 winreg_SaveKeyEx
675 static WERROR dcesrv_winreg_SaveKeyEx(struct dcesrv_call_state *dce_call,
676 TALLOC_CTX *mem_ctx,
677 struct winreg_SaveKeyEx *r)
679 return WERR_NOT_SUPPORTED;
684 winreg_QueryMultipleValues2
686 static WERROR dcesrv_winreg_QueryMultipleValues2(struct dcesrv_call_state *dce_call,
687 TALLOC_CTX *mem_ctx,
688 struct winreg_QueryMultipleValues2 *r)
690 return WERR_NOT_SUPPORTED;
694 /* include the generated boilerplate */
695 #include "librpc/gen_ndr/ndr_winreg_s.c"