Update WHATSNEW entry for pre3
[Samba.git] / source / rpc_server / srv_winreg_nt.c
blob5aad23f8a83b6fb77cd713535116afafffa727e0
1 /*
2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 *
5 * Copyright (C) Gerald Carter 2002-2006.
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 /* Implementation of registry functions. */
23 #include "includes.h"
25 #undef DBGC_CLASS
26 #define DBGC_CLASS DBGC_RPC_SRV
28 /******************************************************************
29 free() function for struct registry_key
30 *****************************************************************/
32 static void free_regkey(void *ptr)
34 struct registry_key *key = (struct registry_key *)ptr;
35 TALLOC_FREE(key);
38 /******************************************************************
39 Find a registry key handle and return a struct registry_key *
40 *****************************************************************/
42 static struct registry_key *find_regkey_by_hnd(pipes_struct *p,
43 POLICY_HND *hnd)
45 struct registry_key *regkey = NULL;
47 if(!find_policy_by_hnd(p,hnd,(void **)(void *)&regkey)) {
48 DEBUG(2,("find_regkey_index_by_hnd: Registry Key not found: "));
49 return NULL;
52 return regkey;
55 /*******************************************************************
56 Function for open a new registry handle and creating a handle
57 Note that P should be valid & hnd should already have space
59 When we open a key, we store the full path to the key as
60 HK[LM|U]\<key>\<key>\...
61 *******************************************************************/
63 static WERROR open_registry_key( pipes_struct *p, POLICY_HND *hnd,
64 struct registry_key *parent,
65 const char *subkeyname,
66 uint32 access_desired )
68 WERROR result = WERR_OK;
69 struct registry_key *key;
71 if (parent == NULL) {
72 result = reg_openhive(NULL, subkeyname, access_desired,
73 p->pipe_user.nt_user_token, &key);
75 else {
76 result = reg_openkey(NULL, parent, subkeyname, access_desired,
77 &key);
80 if ( !W_ERROR_IS_OK(result) ) {
81 return result;
84 if ( !create_policy_hnd( p, hnd, free_regkey, key ) ) {
85 return WERR_BADFILE;
88 return WERR_OK;
91 /*******************************************************************
92 Function for open a new registry handle and creating a handle
93 Note that P should be valid & hnd should already have space
94 *******************************************************************/
96 static bool close_registry_key(pipes_struct *p, POLICY_HND *hnd)
98 struct registry_key *regkey = find_regkey_by_hnd(p, hnd);
100 if ( !regkey ) {
101 DEBUG(2,("close_registry_key: Invalid handle (%s:%u:%u)\n",
102 OUR_HANDLE(hnd)));
103 return False;
106 close_policy_hnd(p, hnd);
108 return True;
111 /********************************************************************
112 reg_close
113 ********************************************************************/
115 WERROR _winreg_CloseKey(pipes_struct *p, struct winreg_CloseKey *r)
117 /* close the policy handle */
119 if (!close_registry_key(p, r->in.handle))
120 return WERR_BADFID;
122 ZERO_STRUCTP(r->out.handle);
124 return WERR_OK;
127 /*******************************************************************
128 ********************************************************************/
130 WERROR _winreg_OpenHKLM(pipes_struct *p, struct winreg_OpenHKLM *r)
132 return open_registry_key(p, r->out.handle, NULL, KEY_HKLM, r->in.access_mask);
135 /*******************************************************************
136 ********************************************************************/
138 WERROR _winreg_OpenHKPD(pipes_struct *p, struct winreg_OpenHKPD *r)
140 return open_registry_key(p, r->out.handle, NULL, KEY_HKPD, r->in.access_mask);
143 /*******************************************************************
144 ********************************************************************/
146 WERROR _winreg_OpenHKPT(pipes_struct *p, struct winreg_OpenHKPT *r)
148 return open_registry_key(p, r->out.handle, NULL, KEY_HKPT, r->in.access_mask);
151 /*******************************************************************
152 ********************************************************************/
154 WERROR _winreg_OpenHKCR(pipes_struct *p, struct winreg_OpenHKCR *r)
156 return open_registry_key(p, r->out.handle, NULL, KEY_HKCR, r->in.access_mask);
159 /*******************************************************************
160 ********************************************************************/
162 WERROR _winreg_OpenHKU(pipes_struct *p, struct winreg_OpenHKU *r)
164 return open_registry_key(p, r->out.handle, NULL, KEY_HKU, r->in.access_mask);
167 /*******************************************************************
168 ********************************************************************/
170 WERROR _winreg_OpenHKCU(pipes_struct *p, struct winreg_OpenHKCU *r)
172 return open_registry_key(p, r->out.handle, NULL, KEY_HKCU, r->in.access_mask);
175 /*******************************************************************
176 ********************************************************************/
178 WERROR _winreg_OpenHKCC(pipes_struct *p, struct winreg_OpenHKCC *r)
180 return open_registry_key(p, r->out.handle, NULL, KEY_HKCC, r->in.access_mask);
183 /*******************************************************************
184 ********************************************************************/
186 WERROR _winreg_OpenHKDD(pipes_struct *p, struct winreg_OpenHKDD *r)
188 return open_registry_key(p, r->out.handle, NULL, KEY_HKDD, r->in.access_mask);
191 /*******************************************************************
192 ********************************************************************/
194 WERROR _winreg_OpenHKPN(pipes_struct *p, struct winreg_OpenHKPN *r)
196 return open_registry_key(p, r->out.handle, NULL, KEY_HKPN, r->in.access_mask);
199 /*******************************************************************
200 reg_reply_open_entry
201 ********************************************************************/
203 WERROR _winreg_OpenKey(pipes_struct *p, struct winreg_OpenKey *r)
205 struct registry_key *parent = find_regkey_by_hnd(p, r->in.parent_handle );
207 if ( !parent )
208 return WERR_BADFID;
210 return open_registry_key(p, r->out.handle, parent, r->in.keyname.name, r->in.access_mask);
213 /*******************************************************************
214 reg_reply_info
215 ********************************************************************/
217 WERROR _winreg_QueryValue(pipes_struct *p, struct winreg_QueryValue *r)
219 WERROR status = WERR_BADFILE;
220 struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
221 prs_struct prs_hkpd;
223 uint8_t *outbuf;
224 uint32_t outbuf_size;
226 DATA_BLOB val_blob;
227 bool free_buf = False;
228 bool free_prs = False;
230 if ( !regkey )
231 return WERR_BADFID;
233 *r->out.value_length = *r->out.type = REG_NONE;
235 DEBUG(7,("_reg_info: policy key name = [%s]\n", regkey->key->name));
236 DEBUG(7,("_reg_info: policy key type = [%08x]\n", regkey->key->type));
238 /* Handle QueryValue calls on HKEY_PERFORMANCE_DATA */
239 if(regkey->key->type == REG_KEY_HKPD)
241 if (strequal(r->in.value_name->name, "Global")) {
242 if (!prs_init(&prs_hkpd, *r->in.data_size, p->mem_ctx, MARSHALL))
243 return WERR_NOMEM;
244 status = reg_perfcount_get_hkpd(
245 &prs_hkpd, *r->in.data_size, &outbuf_size, NULL);
246 outbuf = (uint8_t *)prs_hkpd.data_p;
247 free_prs = True;
249 else if (strequal(r->in.value_name->name, "Counter 009")) {
250 outbuf_size = reg_perfcount_get_counter_names(
251 reg_perfcount_get_base_index(),
252 (char **)(void *)&outbuf);
253 free_buf = True;
255 else if (strequal(r->in.value_name->name, "Explain 009")) {
256 outbuf_size = reg_perfcount_get_counter_help(
257 reg_perfcount_get_base_index(),
258 (char **)(void *)&outbuf);
259 free_buf = True;
261 else if (isdigit(r->in.value_name->name[0])) {
262 /* we probably have a request for a specific object
263 * here */
264 if (!prs_init(&prs_hkpd, *r->in.data_size, p->mem_ctx, MARSHALL))
265 return WERR_NOMEM;
266 status = reg_perfcount_get_hkpd(
267 &prs_hkpd, *r->in.data_size, &outbuf_size,
268 r->in.value_name->name);
269 outbuf = (uint8_t *)prs_hkpd.data_p;
270 free_prs = True;
272 else {
273 DEBUG(3,("Unsupported key name [%s] for HKPD.\n",
274 r->in.value_name->name));
275 return WERR_BADFILE;
278 *r->out.type = REG_BINARY;
280 else {
281 struct registry_value *val;
283 status = reg_queryvalue(p->mem_ctx, regkey, r->in.value_name->name,
284 &val);
285 if (!W_ERROR_IS_OK(status)) {
286 if (r->out.data_size) {
287 *r->out.data_size = 0;
289 if (r->out.value_length) {
290 *r->out.value_length = 0;
292 return status;
295 status = registry_push_value(p->mem_ctx, val, &val_blob);
296 if (!W_ERROR_IS_OK(status)) {
297 return status;
300 outbuf = val_blob.data;
301 outbuf_size = val_blob.length;
302 *r->out.type = val->type;
305 *r->out.value_length = outbuf_size;
307 if ( *r->in.data_size == 0 || !r->out.data ) {
308 status = WERR_OK;
309 } else if ( *r->out.value_length > *r->in.data_size ) {
310 status = WERR_MORE_DATA;
311 } else {
312 memcpy( r->out.data, outbuf, *r->out.value_length );
313 status = WERR_OK;
316 *r->out.data_size = *r->out.value_length;
318 if (free_prs) prs_mem_free(&prs_hkpd);
319 if (free_buf) SAFE_FREE(outbuf);
321 return status;
324 /*****************************************************************************
325 Implementation of REG_QUERY_KEY
326 ****************************************************************************/
328 WERROR _winreg_QueryInfoKey(pipes_struct *p, struct winreg_QueryInfoKey *r)
330 WERROR status = WERR_OK;
331 struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
333 if ( !regkey )
334 return WERR_BADFID;
336 r->out.classname->name = NULL;
338 status = reg_queryinfokey(regkey, r->out.num_subkeys, r->out.max_subkeylen,
339 r->out.max_classlen, r->out.num_values, r->out.max_valnamelen,
340 r->out.max_valbufsize, r->out.secdescsize,
341 r->out.last_changed_time);
342 if (!W_ERROR_IS_OK(status)) {
343 return status;
347 * These calculations account for the registry buffers being
348 * UTF-16. They are inexact at best, but so far they worked.
351 *r->out.max_subkeylen *= 2;
353 *r->out.max_valnamelen += 1;
354 *r->out.max_valnamelen *= 2;
356 return WERR_OK;
360 /*****************************************************************************
361 Implementation of REG_GETVERSION
362 ****************************************************************************/
364 WERROR _winreg_GetVersion(pipes_struct *p, struct winreg_GetVersion *r)
366 struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
368 if ( !regkey )
369 return WERR_BADFID;
371 return reg_getversion(r->out.version);
375 /*****************************************************************************
376 Implementation of REG_ENUM_KEY
377 ****************************************************************************/
379 WERROR _winreg_EnumKey(pipes_struct *p, struct winreg_EnumKey *r)
381 WERROR err;
382 struct registry_key *key = find_regkey_by_hnd( p, r->in.handle );
384 if ( !key )
385 return WERR_BADFID;
387 if ( !r->in.name || !r->in.keyclass )
388 return WERR_INVALID_PARAM;
390 DEBUG(8,("_reg_enum_key: enumerating key [%s]\n", key->key->name));
392 err = reg_enumkey(p->mem_ctx, key, r->in.enum_index, (char **)&r->out.name->name,
393 r->out.last_changed_time);
394 if (!W_ERROR_IS_OK(err)) {
395 return err;
397 r->out.keyclass->name = "";
398 return WERR_OK;
401 /*****************************************************************************
402 Implementation of REG_ENUM_VALUE
403 ****************************************************************************/
405 WERROR _winreg_EnumValue(pipes_struct *p, struct winreg_EnumValue *r)
407 WERROR err;
408 struct registry_key *key = find_regkey_by_hnd( p, r->in.handle );
409 char *valname;
410 struct registry_value *val;
411 DATA_BLOB value_blob;
413 if ( !key )
414 return WERR_BADFID;
416 if ( !r->in.name )
417 return WERR_INVALID_PARAM;
419 DEBUG(8,("_winreg_EnumValue: enumerating values for key [%s]\n",
420 key->key->name));
422 err = reg_enumvalue(p->mem_ctx, key, r->in.enum_index, &valname, &val);
423 if (!W_ERROR_IS_OK(err)) {
424 return err;
427 err = registry_push_value(p->mem_ctx, val, &value_blob);
428 if (!W_ERROR_IS_OK(err)) {
429 return err;
432 if (r->out.name != NULL) {
433 r->out.name->name = valname;
436 if (r->out.type != NULL) {
437 *r->out.type = val->type;
440 if (r->out.value != NULL) {
441 if ((r->out.size == NULL) || (r->out.length == NULL)) {
442 return WERR_INVALID_PARAM;
445 if (value_blob.length > *r->out.size) {
446 return WERR_MORE_DATA;
449 memcpy( r->out.value, value_blob.data, value_blob.length );
452 if (r->out.length != NULL) {
453 *r->out.length = value_blob.length;
455 if (r->out.size != NULL) {
456 *r->out.size = value_blob.length;
459 return WERR_OK;
462 /*******************************************************************
463 reg_shutdwon
464 ********************************************************************/
466 WERROR _winreg_InitiateSystemShutdown(pipes_struct *p, struct winreg_InitiateSystemShutdown *r)
468 struct winreg_InitiateSystemShutdownEx s;
470 s.in.hostname = r->in.hostname;
471 s.in.message = r->in.message;
472 s.in.timeout = r->in.timeout;
473 s.in.force_apps = r->in.force_apps;
474 s.in.reboot = r->in.reboot;
475 s.in.reason = 0;
477 /* thunk down to _winreg_InitiateSystemShutdownEx()
478 (just returns a status) */
480 return _winreg_InitiateSystemShutdownEx( p, &s );
483 /*******************************************************************
484 reg_shutdown_ex
485 ********************************************************************/
487 #define SHUTDOWN_R_STRING "-r"
488 #define SHUTDOWN_F_STRING "-f"
491 WERROR _winreg_InitiateSystemShutdownEx(pipes_struct *p, struct winreg_InitiateSystemShutdownEx *r)
493 char *shutdown_script = NULL;
494 char *msg = NULL;
495 char *chkmsg = NULL;
496 fstring str_timeout;
497 fstring str_reason;
498 fstring reboot;
499 fstring f;
500 int ret;
501 bool can_shutdown;
503 shutdown_script = talloc_strdup(p->mem_ctx, lp_shutdown_script());
504 if (!shutdown_script) {
505 return WERR_NOMEM;
507 if (!*shutdown_script) {
508 return WERR_ACCESS_DENIED;
511 /* pull the message string and perform necessary sanity checks on it */
513 chkmsg[0] = '\0';
515 if ( r->in.message && r->in.message->name && r->in.message->name->name ) {
516 if ( (msg = talloc_strdup(p->mem_ctx, r->in.message->name->name )) == NULL ) {
517 return WERR_NOMEM;
519 chkmsg = TALLOC_ARRAY(p->mem_ctx, char, strlen(msg)+1);
520 if (!chkmsg) {
521 return WERR_NOMEM;
523 alpha_strcpy(chkmsg, msg, NULL, strlen(msg)+1);
526 fstr_sprintf(str_timeout, "%d", r->in.timeout);
527 fstr_sprintf(reboot, r->in.reboot ? SHUTDOWN_R_STRING : "");
528 fstr_sprintf(f, r->in.force_apps ? SHUTDOWN_F_STRING : "");
529 fstr_sprintf(str_reason, "%d", r->in.reason );
531 shutdown_script = talloc_all_string_sub(p->mem_ctx,
532 shutdown_script, "%z", chkmsg ? chkmsg : "");
533 if (!shutdown_script) {
534 return WERR_NOMEM;
536 shutdown_script = talloc_all_string_sub(p->mem_ctx,
537 shutdown_script, "%t", str_timeout);
538 if (!shutdown_script) {
539 return WERR_NOMEM;
541 shutdown_script = talloc_all_string_sub(p->mem_ctx,
542 shutdown_script, "%r", reboot);
543 if (!shutdown_script) {
544 return WERR_NOMEM;
546 shutdown_script = talloc_all_string_sub(p->mem_ctx,
547 shutdown_script, "%f", f);
548 if (!shutdown_script) {
549 return WERR_NOMEM;
551 shutdown_script = talloc_all_string_sub(p->mem_ctx,
552 shutdown_script, "%x", str_reason);
553 if (!shutdown_script) {
554 return WERR_NOMEM;
557 can_shutdown = user_has_privileges( p->pipe_user.nt_user_token, &se_remote_shutdown );
559 /* IF someone has privs, run the shutdown script as root. OTHERWISE run it as not root
560 Take the error return from the script and provide it as the Windows return code. */
562 /********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/
564 if ( can_shutdown )
565 become_root();
567 ret = smbrun( shutdown_script, NULL );
569 if ( can_shutdown )
570 unbecome_root();
572 /********** END SeRemoteShutdownPrivilege BLOCK **********/
574 DEBUG(3,("_reg_shutdown_ex: Running the command `%s' gave %d\n",
575 shutdown_script, ret));
577 return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED;
580 /*******************************************************************
581 reg_abort_shutdwon
582 ********************************************************************/
584 WERROR _winreg_AbortSystemShutdown(pipes_struct *p, struct winreg_AbortSystemShutdown *r)
586 const char *abort_shutdown_script;
587 int ret;
588 bool can_shutdown;
590 abort_shutdown_script = lp_abort_shutdown_script();
592 if (!*abort_shutdown_script)
593 return WERR_ACCESS_DENIED;
595 can_shutdown = user_has_privileges( p->pipe_user.nt_user_token, &se_remote_shutdown );
597 /********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/
599 if ( can_shutdown )
600 become_root();
602 ret = smbrun( abort_shutdown_script, NULL );
604 if ( can_shutdown )
605 unbecome_root();
607 /********** END SeRemoteShutdownPrivilege BLOCK **********/
609 DEBUG(3,("_reg_abort_shutdown: Running the command `%s' gave %d\n",
610 abort_shutdown_script, ret));
612 return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED;
615 /*******************************************************************
616 ********************************************************************/
618 static int validate_reg_filename(TALLOC_CTX *ctx, char **pp_fname )
620 char *p = NULL;
621 int num_services = lp_numservices();
622 int snum = -1;
623 const char *share_path;
624 char *fname = *pp_fname;
626 /* convert to a unix path, stripping the C:\ along the way */
628 if (!(p = valid_share_pathname(ctx, fname))) {
629 return -1;
632 /* has to exist within a valid file share */
634 for (snum=0; snum<num_services; snum++) {
635 if (!lp_snum_ok(snum) || lp_print_ok(snum)) {
636 continue;
639 share_path = lp_pathname(snum);
641 /* make sure we have a path (e.g. [homes] ) */
642 if (strlen(share_path) == 0) {
643 continue;
646 if (strncmp(share_path, p, strlen(share_path)) == 0) {
647 break;
651 *pp_fname = p;
652 return (snum < num_services) ? snum : -1;
655 /*******************************************************************
656 ********************************************************************/
658 WERROR _winreg_RestoreKey(pipes_struct *p, struct winreg_RestoreKey *r)
660 struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
661 char *fname = NULL;
662 int snum;
664 if ( !regkey )
665 return WERR_BADFID;
667 if ( !r->in.filename || !r->in.filename->name )
668 return WERR_INVALID_PARAM;
670 fname = talloc_strdup(p->mem_ctx, r->in.filename->name);
671 if (!fname) {
672 return WERR_NOMEM;
675 DEBUG(8,("_winreg_RestoreKey: verifying restore of key [%s] from "
676 "\"%s\"\n", regkey->key->name, fname));
678 if ((snum = validate_reg_filename(p->mem_ctx, &fname)) == -1)
679 return WERR_OBJECT_PATH_INVALID;
681 /* user must posses SeRestorePrivilege for this this proceed */
683 if ( !user_has_privileges( p->pipe_user.nt_user_token, &se_restore ) )
684 return WERR_ACCESS_DENIED;
686 DEBUG(2,("_winreg_RestoreKey: Restoring [%s] from %s in share %s\n",
687 regkey->key->name, fname, lp_servicename(snum) ));
689 return reg_restorekey(regkey, fname);
692 WERROR _winreg_SaveKey(pipes_struct *p, struct winreg_SaveKey *r)
694 struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
695 char *fname = NULL;
696 int snum = -1;
698 if ( !regkey )
699 return WERR_BADFID;
701 if ( !r->in.filename || !r->in.filename->name )
702 return WERR_INVALID_PARAM;
704 fname = talloc_strdup(p->mem_ctx, r->in.filename->name);
705 if (!fname) {
706 return WERR_NOMEM;
709 DEBUG(8,("_winreg_SaveKey: verifying backup of key [%s] to \"%s\"\n",
710 regkey->key->name, fname));
712 if ((snum = validate_reg_filename(p->mem_ctx, &fname)) == -1 )
713 return WERR_OBJECT_PATH_INVALID;
715 DEBUG(2,("_winreg_SaveKey: Saving [%s] to %s in share %s\n",
716 regkey->key->name, fname, lp_servicename(snum) ));
718 return reg_savekey(regkey, fname);
721 /*******************************************************************
722 ********************************************************************/
724 WERROR _winreg_SaveKeyEx(pipes_struct *p, struct winreg_SaveKeyEx *r)
726 /* fill in your code here if you think this call should
727 do anything */
729 p->rng_fault_state = True;
730 return WERR_NOT_SUPPORTED;
733 /*******************************************************************
734 ********************************************************************/
736 WERROR _winreg_CreateKey( pipes_struct *p, struct winreg_CreateKey *r)
738 struct registry_key *parent = find_regkey_by_hnd(p, r->in.handle);
739 struct registry_key *new_key;
740 WERROR result;
742 if ( !parent )
743 return WERR_BADFID;
745 result = reg_createkey(NULL, parent, r->in.name.name, r->in.access_mask,
746 &new_key, r->out.action_taken);
747 if (!W_ERROR_IS_OK(result)) {
748 return result;
751 if (!create_policy_hnd(p, r->out.new_handle, free_regkey, new_key)) {
752 TALLOC_FREE(new_key);
753 return WERR_BADFILE;
756 return WERR_OK;
759 /*******************************************************************
760 ********************************************************************/
762 WERROR _winreg_SetValue(pipes_struct *p, struct winreg_SetValue *r)
764 struct registry_key *key = find_regkey_by_hnd(p, r->in.handle);
765 struct registry_value *val;
766 WERROR status;
768 if ( !key )
769 return WERR_BADFID;
771 DEBUG(8,("_reg_set_value: Setting value for [%s:%s]\n",
772 key->key->name, r->in.name.name));
774 status = registry_pull_value(p->mem_ctx, &val, r->in.type, r->in.data,
775 r->in.size, r->in.size);
776 if (!W_ERROR_IS_OK(status)) {
777 return status;
780 return reg_setvalue(key, r->in.name.name, val);
783 /*******************************************************************
784 ********************************************************************/
786 WERROR _winreg_DeleteKey(pipes_struct *p, struct winreg_DeleteKey *r)
788 struct registry_key *parent = find_regkey_by_hnd(p, r->in.handle);
790 if ( !parent )
791 return WERR_BADFID;
793 return reg_deletekey(parent, r->in.key.name);
797 /*******************************************************************
798 ********************************************************************/
800 WERROR _winreg_DeleteValue(pipes_struct *p, struct winreg_DeleteValue *r)
802 struct registry_key *key = find_regkey_by_hnd(p, r->in.handle);
804 if ( !key )
805 return WERR_BADFID;
807 return reg_deletevalue(key, r->in.value.name);
810 /*******************************************************************
811 ********************************************************************/
813 WERROR _winreg_GetKeySecurity(pipes_struct *p, struct winreg_GetKeySecurity *r)
815 struct registry_key *key = find_regkey_by_hnd(p, r->in.handle);
816 WERROR err;
817 struct security_descriptor *secdesc;
818 uint8 *data;
819 size_t len;
821 if ( !key )
822 return WERR_BADFID;
824 /* access checks first */
826 if ( !(key->key->access_granted & STD_RIGHT_READ_CONTROL_ACCESS) )
827 return WERR_ACCESS_DENIED;
829 err = reg_getkeysecurity(p->mem_ctx, key, &secdesc);
830 if (!W_ERROR_IS_OK(err)) {
831 return err;
834 err = ntstatus_to_werror(marshall_sec_desc(p->mem_ctx, secdesc,
835 &data, &len));
836 if (!W_ERROR_IS_OK(err)) {
837 return err;
840 if (len > r->out.sd->size) {
841 r->out.sd->size = len;
842 return WERR_INSUFFICIENT_BUFFER;
845 r->out.sd->size = len;
846 r->out.sd->len = len;
847 r->out.sd->data = data;
849 return WERR_OK;
852 /*******************************************************************
853 ********************************************************************/
855 WERROR _winreg_SetKeySecurity(pipes_struct *p, struct winreg_SetKeySecurity *r)
857 struct registry_key *key = find_regkey_by_hnd(p, r->in.handle);
858 struct security_descriptor *secdesc;
859 WERROR err;
861 if ( !key )
862 return WERR_BADFID;
864 /* access checks first */
866 if ( !(key->key->access_granted & STD_RIGHT_WRITE_DAC_ACCESS) )
867 return WERR_ACCESS_DENIED;
869 err = ntstatus_to_werror(unmarshall_sec_desc(p->mem_ctx, r->in.sd->data,
870 r->in.sd->len, &secdesc));
871 if (!W_ERROR_IS_OK(err)) {
872 return err;
875 return reg_setkeysecurity(key, secdesc);
878 /*******************************************************************
879 ********************************************************************/
881 WERROR _winreg_FlushKey(pipes_struct *p, struct winreg_FlushKey *r)
883 /* I'm just replying OK because there's not a lot
884 here I see to do i --jerry */
886 return WERR_OK;
889 /*******************************************************************
890 ********************************************************************/
892 WERROR _winreg_UnLoadKey(pipes_struct *p, struct winreg_UnLoadKey *r)
894 /* fill in your code here if you think this call should
895 do anything */
897 p->rng_fault_state = True;
898 return WERR_NOT_SUPPORTED;
901 /*******************************************************************
902 ********************************************************************/
904 WERROR _winreg_ReplaceKey(pipes_struct *p, struct winreg_ReplaceKey *r)
906 /* fill in your code here if you think this call should
907 do anything */
909 p->rng_fault_state = True;
910 return WERR_NOT_SUPPORTED;
913 /*******************************************************************
914 ********************************************************************/
916 WERROR _winreg_LoadKey(pipes_struct *p, struct winreg_LoadKey *r)
918 /* fill in your code here if you think this call should
919 do anything */
921 p->rng_fault_state = True;
922 return WERR_NOT_SUPPORTED;
925 /*******************************************************************
926 ********************************************************************/
928 WERROR _winreg_NotifyChangeKeyValue(pipes_struct *p, struct winreg_NotifyChangeKeyValue *r)
930 /* fill in your code here if you think this call should
931 do anything */
933 p->rng_fault_state = True;
934 return WERR_NOT_SUPPORTED;
937 /*******************************************************************
938 ********************************************************************/
940 WERROR _winreg_QueryMultipleValues(pipes_struct *p, struct winreg_QueryMultipleValues *r)
942 /* fill in your code here if you think this call should
943 do anything */
945 p->rng_fault_state = True;
946 return WERR_NOT_SUPPORTED;
949 /*******************************************************************
950 ********************************************************************/
952 WERROR _winreg_QueryMultipleValues2(pipes_struct *p, struct winreg_QueryMultipleValues2 *r)
954 /* fill in your code here if you think this call should
955 do anything */
957 p->rng_fault_state = True;
958 return WERR_NOT_SUPPORTED;