Merge branch 'master' of /home/tridge/samba/git/combined
[Samba/aatanasov.git] / source3 / rpc_server / srv_winreg_nt.c
blob3de9f0e623ad0757fb9e8ed1f9f35ffbae069fae
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 Find a registry key handle and return a struct registry_key *
30 *****************************************************************/
32 static struct registry_key *find_regkey_by_hnd(pipes_struct *p,
33 struct policy_handle *hnd)
35 struct registry_key *regkey = NULL;
37 if(!find_policy_by_hnd(p,hnd,(void **)(void *)&regkey)) {
38 DEBUG(2,("find_regkey_index_by_hnd: Registry Key not found: "));
39 return NULL;
42 return regkey;
45 /*******************************************************************
46 Function for open a new registry handle and creating a handle
47 Note that P should be valid & hnd should already have space
49 When we open a key, we store the full path to the key as
50 HK[LM|U]\<key>\<key>\...
51 *******************************************************************/
53 static WERROR open_registry_key( pipes_struct *p, struct policy_handle *hnd,
54 struct registry_key *parent,
55 const char *subkeyname,
56 uint32 access_desired )
58 WERROR result = WERR_OK;
59 struct registry_key *key;
61 if (parent == NULL) {
62 result = reg_openhive(p->mem_ctx, subkeyname, access_desired,
63 p->server_info->ptok, &key);
65 else {
66 result = reg_openkey(p->mem_ctx, parent, subkeyname,
67 access_desired, &key);
70 if ( !W_ERROR_IS_OK(result) ) {
71 return result;
74 if ( !create_policy_hnd( p, hnd, key ) ) {
75 return WERR_BADFILE;
78 return WERR_OK;
81 /*******************************************************************
82 Function for open a new registry handle and creating a handle
83 Note that P should be valid & hnd should already have space
84 *******************************************************************/
86 static bool close_registry_key(pipes_struct *p, struct policy_handle *hnd)
88 struct registry_key *regkey = find_regkey_by_hnd(p, hnd);
90 if ( !regkey ) {
91 DEBUG(2,("close_registry_key: Invalid handle (%s:%u:%u)\n",
92 OUR_HANDLE(hnd)));
93 return False;
96 close_policy_hnd(p, hnd);
98 return True;
101 /********************************************************************
102 reg_close
103 ********************************************************************/
105 WERROR _winreg_CloseKey(pipes_struct *p, struct winreg_CloseKey *r)
107 /* close the policy handle */
109 if (!close_registry_key(p, r->in.handle))
110 return WERR_BADFID;
112 ZERO_STRUCTP(r->out.handle);
114 return WERR_OK;
117 /*******************************************************************
118 ********************************************************************/
120 WERROR _winreg_OpenHKLM(pipes_struct *p, struct winreg_OpenHKLM *r)
122 return open_registry_key(p, r->out.handle, NULL, KEY_HKLM, r->in.access_mask);
125 /*******************************************************************
126 ********************************************************************/
128 WERROR _winreg_OpenHKPD(pipes_struct *p, struct winreg_OpenHKPD *r)
130 return open_registry_key(p, r->out.handle, NULL, KEY_HKPD, r->in.access_mask);
133 /*******************************************************************
134 ********************************************************************/
136 WERROR _winreg_OpenHKPT(pipes_struct *p, struct winreg_OpenHKPT *r)
138 return open_registry_key(p, r->out.handle, NULL, KEY_HKPT, r->in.access_mask);
141 /*******************************************************************
142 ********************************************************************/
144 WERROR _winreg_OpenHKCR(pipes_struct *p, struct winreg_OpenHKCR *r)
146 return open_registry_key(p, r->out.handle, NULL, KEY_HKCR, r->in.access_mask);
149 /*******************************************************************
150 ********************************************************************/
152 WERROR _winreg_OpenHKU(pipes_struct *p, struct winreg_OpenHKU *r)
154 return open_registry_key(p, r->out.handle, NULL, KEY_HKU, r->in.access_mask);
157 /*******************************************************************
158 ********************************************************************/
160 WERROR _winreg_OpenHKCU(pipes_struct *p, struct winreg_OpenHKCU *r)
162 return open_registry_key(p, r->out.handle, NULL, KEY_HKCU, r->in.access_mask);
165 /*******************************************************************
166 ********************************************************************/
168 WERROR _winreg_OpenHKCC(pipes_struct *p, struct winreg_OpenHKCC *r)
170 return open_registry_key(p, r->out.handle, NULL, KEY_HKCC, r->in.access_mask);
173 /*******************************************************************
174 ********************************************************************/
176 WERROR _winreg_OpenHKDD(pipes_struct *p, struct winreg_OpenHKDD *r)
178 return open_registry_key(p, r->out.handle, NULL, KEY_HKDD, r->in.access_mask);
181 /*******************************************************************
182 ********************************************************************/
184 WERROR _winreg_OpenHKPN(pipes_struct *p, struct winreg_OpenHKPN *r)
186 return open_registry_key(p, r->out.handle, NULL, KEY_HKPN, r->in.access_mask);
189 /*******************************************************************
190 reg_reply_open_entry
191 ********************************************************************/
193 WERROR _winreg_OpenKey(pipes_struct *p, struct winreg_OpenKey *r)
195 struct registry_key *parent = find_regkey_by_hnd(p, r->in.parent_handle );
197 if ( !parent )
198 return WERR_BADFID;
200 return open_registry_key(p, r->out.handle, parent, r->in.keyname.name, r->in.access_mask);
203 /*******************************************************************
204 reg_reply_info
205 ********************************************************************/
207 WERROR _winreg_QueryValue(pipes_struct *p, struct winreg_QueryValue *r)
209 WERROR status = WERR_BADFILE;
210 struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
211 prs_struct prs_hkpd;
213 uint8_t *outbuf;
214 uint32_t outbuf_size;
216 DATA_BLOB val_blob;
217 bool free_buf = False;
218 bool free_prs = False;
220 if ( !regkey )
221 return WERR_BADFID;
223 if ((r->out.data_length == NULL) || (r->out.type == NULL)) {
224 return WERR_INVALID_PARAM;
227 *r->out.data_length = *r->out.type = REG_NONE;
229 DEBUG(7,("_reg_info: policy key name = [%s]\n", regkey->key->name));
230 DEBUG(7,("_reg_info: policy key type = [%08x]\n", regkey->key->type));
232 /* Handle QueryValue calls on HKEY_PERFORMANCE_DATA */
233 if(regkey->key->type == REG_KEY_HKPD)
235 if (strequal(r->in.value_name->name, "Global")) {
236 if (!prs_init(&prs_hkpd, *r->in.data_size, p->mem_ctx, MARSHALL))
237 return WERR_NOMEM;
238 status = reg_perfcount_get_hkpd(
239 &prs_hkpd, *r->in.data_size, &outbuf_size, NULL);
240 outbuf = (uint8_t *)prs_hkpd.data_p;
241 free_prs = True;
243 else if (strequal(r->in.value_name->name, "Counter 009")) {
244 outbuf_size = reg_perfcount_get_counter_names(
245 reg_perfcount_get_base_index(),
246 (char **)(void *)&outbuf);
247 free_buf = True;
249 else if (strequal(r->in.value_name->name, "Explain 009")) {
250 outbuf_size = reg_perfcount_get_counter_help(
251 reg_perfcount_get_base_index(),
252 (char **)(void *)&outbuf);
253 free_buf = True;
255 else if (isdigit(r->in.value_name->name[0])) {
256 /* we probably have a request for a specific object
257 * here */
258 if (!prs_init(&prs_hkpd, *r->in.data_size, p->mem_ctx, MARSHALL))
259 return WERR_NOMEM;
260 status = reg_perfcount_get_hkpd(
261 &prs_hkpd, *r->in.data_size, &outbuf_size,
262 r->in.value_name->name);
263 outbuf = (uint8_t *)prs_hkpd.data_p;
264 free_prs = True;
266 else {
267 DEBUG(3,("Unsupported key name [%s] for HKPD.\n",
268 r->in.value_name->name));
269 return WERR_BADFILE;
272 *r->out.type = REG_BINARY;
274 else {
275 struct registry_value *val;
277 status = reg_queryvalue(p->mem_ctx, regkey, r->in.value_name->name,
278 &val);
279 if (!W_ERROR_IS_OK(status)) {
280 if (r->out.data_size) {
281 *r->out.data_size = 0;
283 if (r->out.data_length) {
284 *r->out.data_length = 0;
286 return status;
289 status = registry_push_value(p->mem_ctx, val, &val_blob);
290 if (!W_ERROR_IS_OK(status)) {
291 return status;
294 outbuf = val_blob.data;
295 outbuf_size = val_blob.length;
296 *r->out.type = val->type;
299 *r->out.data_length = outbuf_size;
301 if ( *r->in.data_size == 0 || !r->out.data ) {
302 status = WERR_OK;
303 } else if ( *r->out.data_length > *r->in.data_size ) {
304 status = WERR_MORE_DATA;
305 } else {
306 memcpy( r->out.data, outbuf, *r->out.data_length );
307 status = WERR_OK;
310 *r->out.data_size = *r->out.data_length;
312 if (free_prs) prs_mem_free(&prs_hkpd);
313 if (free_buf) SAFE_FREE(outbuf);
315 return status;
318 /*****************************************************************************
319 Implementation of REG_QUERY_KEY
320 ****************************************************************************/
322 WERROR _winreg_QueryInfoKey(pipes_struct *p, struct winreg_QueryInfoKey *r)
324 WERROR status = WERR_OK;
325 struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
327 if ( !regkey )
328 return WERR_BADFID;
330 r->out.classname->name = NULL;
332 status = reg_queryinfokey(regkey, r->out.num_subkeys, r->out.max_subkeylen,
333 r->out.max_classlen, r->out.num_values, r->out.max_valnamelen,
334 r->out.max_valbufsize, r->out.secdescsize,
335 r->out.last_changed_time);
336 if (!W_ERROR_IS_OK(status)) {
337 return status;
341 * These calculations account for the registry buffers being
342 * UTF-16. They are inexact at best, but so far they worked.
345 *r->out.max_subkeylen *= 2;
347 *r->out.max_valnamelen += 1;
348 *r->out.max_valnamelen *= 2;
350 return WERR_OK;
354 /*****************************************************************************
355 Implementation of REG_GETVERSION
356 ****************************************************************************/
358 WERROR _winreg_GetVersion(pipes_struct *p, struct winreg_GetVersion *r)
360 struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
362 if ( !regkey )
363 return WERR_BADFID;
365 return reg_getversion(r->out.version);
369 /*****************************************************************************
370 Implementation of REG_ENUM_KEY
371 ****************************************************************************/
373 WERROR _winreg_EnumKey(pipes_struct *p, struct winreg_EnumKey *r)
375 WERROR err;
376 struct registry_key *key = find_regkey_by_hnd( p, r->in.handle );
378 if ( !key )
379 return WERR_BADFID;
381 if ( !r->in.name || !r->in.keyclass )
382 return WERR_INVALID_PARAM;
384 DEBUG(8,("_reg_enum_key: enumerating key [%s]\n", key->key->name));
386 err = reg_enumkey(p->mem_ctx, key, r->in.enum_index, (char **)&r->out.name->name,
387 r->out.last_changed_time);
388 if (!W_ERROR_IS_OK(err)) {
389 return err;
391 r->out.keyclass->name = "";
392 return WERR_OK;
395 /*****************************************************************************
396 Implementation of REG_ENUM_VALUE
397 ****************************************************************************/
399 WERROR _winreg_EnumValue(pipes_struct *p, struct winreg_EnumValue *r)
401 WERROR err;
402 struct registry_key *key = find_regkey_by_hnd( p, r->in.handle );
403 char *valname;
404 struct registry_value *val;
405 DATA_BLOB value_blob;
407 if ( !key )
408 return WERR_BADFID;
410 if ( !r->in.name )
411 return WERR_INVALID_PARAM;
413 DEBUG(8,("_winreg_EnumValue: enumerating values for key [%s]\n",
414 key->key->name));
416 err = reg_enumvalue(p->mem_ctx, key, r->in.enum_index, &valname, &val);
417 if (!W_ERROR_IS_OK(err)) {
418 return err;
421 err = registry_push_value(p->mem_ctx, val, &value_blob);
422 if (!W_ERROR_IS_OK(err)) {
423 return err;
426 if (r->out.name != NULL) {
427 r->out.name->name = valname;
430 if (r->out.type != NULL) {
431 *r->out.type = val->type;
434 if (r->out.value != NULL) {
435 if ((r->out.size == NULL) || (r->out.length == NULL)) {
436 return WERR_INVALID_PARAM;
439 if (value_blob.length > *r->out.size) {
440 return WERR_MORE_DATA;
443 memcpy( r->out.value, value_blob.data, value_blob.length );
446 if (r->out.length != NULL) {
447 *r->out.length = value_blob.length;
449 if (r->out.size != NULL) {
450 *r->out.size = value_blob.length;
453 return WERR_OK;
456 /*******************************************************************
457 reg_shutdwon
458 ********************************************************************/
460 WERROR _winreg_InitiateSystemShutdown(pipes_struct *p, struct winreg_InitiateSystemShutdown *r)
462 struct winreg_InitiateSystemShutdownEx s;
464 s.in.hostname = r->in.hostname;
465 s.in.message = r->in.message;
466 s.in.timeout = r->in.timeout;
467 s.in.force_apps = r->in.force_apps;
468 s.in.do_reboot = r->in.do_reboot;
469 s.in.reason = 0;
471 /* thunk down to _winreg_InitiateSystemShutdownEx()
472 (just returns a status) */
474 return _winreg_InitiateSystemShutdownEx( p, &s );
477 /*******************************************************************
478 reg_shutdown_ex
479 ********************************************************************/
481 #define SHUTDOWN_R_STRING "-r"
482 #define SHUTDOWN_F_STRING "-f"
485 WERROR _winreg_InitiateSystemShutdownEx(pipes_struct *p, struct winreg_InitiateSystemShutdownEx *r)
487 char *shutdown_script = NULL;
488 char *msg = NULL;
489 char *chkmsg = NULL;
490 fstring str_timeout;
491 fstring str_reason;
492 fstring do_reboot;
493 fstring f;
494 int ret;
495 bool can_shutdown;
497 shutdown_script = talloc_strdup(p->mem_ctx, lp_shutdown_script());
498 if (!shutdown_script) {
499 return WERR_NOMEM;
501 if (!*shutdown_script) {
502 return WERR_ACCESS_DENIED;
505 /* pull the message string and perform necessary sanity checks on it */
507 if ( r->in.message && r->in.message->string ) {
508 if ( (msg = talloc_strdup(p->mem_ctx, r->in.message->string )) == NULL ) {
509 return WERR_NOMEM;
511 chkmsg = TALLOC_ARRAY(p->mem_ctx, char, strlen(msg)+1);
512 if (!chkmsg) {
513 return WERR_NOMEM;
515 alpha_strcpy(chkmsg, msg, NULL, strlen(msg)+1);
518 fstr_sprintf(str_timeout, "%d", r->in.timeout);
519 fstr_sprintf(do_reboot, r->in.do_reboot ? SHUTDOWN_R_STRING : "");
520 fstr_sprintf(f, r->in.force_apps ? SHUTDOWN_F_STRING : "");
521 fstr_sprintf(str_reason, "%d", r->in.reason );
523 shutdown_script = talloc_all_string_sub(p->mem_ctx,
524 shutdown_script, "%z", chkmsg ? chkmsg : "");
525 if (!shutdown_script) {
526 return WERR_NOMEM;
528 shutdown_script = talloc_all_string_sub(p->mem_ctx,
529 shutdown_script, "%t", str_timeout);
530 if (!shutdown_script) {
531 return WERR_NOMEM;
533 shutdown_script = talloc_all_string_sub(p->mem_ctx,
534 shutdown_script, "%r", do_reboot);
535 if (!shutdown_script) {
536 return WERR_NOMEM;
538 shutdown_script = talloc_all_string_sub(p->mem_ctx,
539 shutdown_script, "%f", f);
540 if (!shutdown_script) {
541 return WERR_NOMEM;
543 shutdown_script = talloc_all_string_sub(p->mem_ctx,
544 shutdown_script, "%x", str_reason);
545 if (!shutdown_script) {
546 return WERR_NOMEM;
549 can_shutdown = user_has_privileges( p->server_info->ptok,
550 &se_remote_shutdown );
552 /* IF someone has privs, run the shutdown script as root. OTHERWISE run it as not root
553 Take the error return from the script and provide it as the Windows return code. */
555 /********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/
557 if ( can_shutdown )
558 become_root();
560 ret = smbrun( shutdown_script, NULL );
562 if ( can_shutdown )
563 unbecome_root();
565 /********** END SeRemoteShutdownPrivilege BLOCK **********/
567 DEBUG(3,("_reg_shutdown_ex: Running the command `%s' gave %d\n",
568 shutdown_script, ret));
570 return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED;
573 /*******************************************************************
574 reg_abort_shutdwon
575 ********************************************************************/
577 WERROR _winreg_AbortSystemShutdown(pipes_struct *p, struct winreg_AbortSystemShutdown *r)
579 const char *abort_shutdown_script;
580 int ret;
581 bool can_shutdown;
583 abort_shutdown_script = lp_abort_shutdown_script();
585 if (!*abort_shutdown_script)
586 return WERR_ACCESS_DENIED;
588 can_shutdown = user_has_privileges( p->server_info->ptok,
589 &se_remote_shutdown );
591 /********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/
593 if ( can_shutdown )
594 become_root();
596 ret = smbrun( abort_shutdown_script, NULL );
598 if ( can_shutdown )
599 unbecome_root();
601 /********** END SeRemoteShutdownPrivilege BLOCK **********/
603 DEBUG(3,("_reg_abort_shutdown: Running the command `%s' gave %d\n",
604 abort_shutdown_script, ret));
606 return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED;
609 /*******************************************************************
610 ********************************************************************/
612 static int validate_reg_filename(TALLOC_CTX *ctx, char **pp_fname )
614 char *p = NULL;
615 int num_services = lp_numservices();
616 int snum = -1;
617 const char *share_path;
618 char *fname = *pp_fname;
620 /* convert to a unix path, stripping the C:\ along the way */
622 if (!(p = valid_share_pathname(ctx, fname))) {
623 return -1;
626 /* has to exist within a valid file share */
628 for (snum=0; snum<num_services; snum++) {
629 if (!lp_snum_ok(snum) || lp_print_ok(snum)) {
630 continue;
633 share_path = lp_pathname(snum);
635 /* make sure we have a path (e.g. [homes] ) */
636 if (strlen(share_path) == 0) {
637 continue;
640 if (strncmp(share_path, p, strlen(share_path)) == 0) {
641 break;
645 *pp_fname = p;
646 return (snum < num_services) ? snum : -1;
649 /*******************************************************************
650 ********************************************************************/
652 WERROR _winreg_RestoreKey(pipes_struct *p, struct winreg_RestoreKey *r)
654 struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
655 char *fname = NULL;
656 int snum;
658 if ( !regkey )
659 return WERR_BADFID;
661 if ( !r->in.filename || !r->in.filename->name )
662 return WERR_INVALID_PARAM;
664 fname = talloc_strdup(p->mem_ctx, r->in.filename->name);
665 if (!fname) {
666 return WERR_NOMEM;
669 DEBUG(8,("_winreg_RestoreKey: verifying restore of key [%s] from "
670 "\"%s\"\n", regkey->key->name, fname));
672 if ((snum = validate_reg_filename(p->mem_ctx, &fname)) == -1)
673 return WERR_OBJECT_PATH_INVALID;
675 /* user must posses SeRestorePrivilege for this this proceed */
677 if ( !user_has_privileges( p->server_info->ptok, &se_restore ) )
678 return WERR_ACCESS_DENIED;
680 DEBUG(2,("_winreg_RestoreKey: Restoring [%s] from %s in share %s\n",
681 regkey->key->name, fname, lp_servicename(snum) ));
683 return reg_restorekey(regkey, fname);
686 WERROR _winreg_SaveKey(pipes_struct *p, struct winreg_SaveKey *r)
688 struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
689 char *fname = NULL;
690 int snum = -1;
692 if ( !regkey )
693 return WERR_BADFID;
695 if ( !r->in.filename || !r->in.filename->name )
696 return WERR_INVALID_PARAM;
698 fname = talloc_strdup(p->mem_ctx, r->in.filename->name);
699 if (!fname) {
700 return WERR_NOMEM;
703 DEBUG(8,("_winreg_SaveKey: verifying backup of key [%s] to \"%s\"\n",
704 regkey->key->name, fname));
706 if ((snum = validate_reg_filename(p->mem_ctx, &fname)) == -1 )
707 return WERR_OBJECT_PATH_INVALID;
709 DEBUG(2,("_winreg_SaveKey: Saving [%s] to %s in share %s\n",
710 regkey->key->name, fname, lp_servicename(snum) ));
712 return reg_savekey(regkey, fname);
715 /*******************************************************************
716 ********************************************************************/
718 WERROR _winreg_SaveKeyEx(pipes_struct *p, struct winreg_SaveKeyEx *r)
720 /* fill in your code here if you think this call should
721 do anything */
723 p->rng_fault_state = True;
724 return WERR_NOT_SUPPORTED;
727 /*******************************************************************
728 ********************************************************************/
730 WERROR _winreg_CreateKey( pipes_struct *p, struct winreg_CreateKey *r)
732 struct registry_key *parent = find_regkey_by_hnd(p, r->in.handle);
733 struct registry_key *new_key;
734 WERROR result;
736 if ( !parent )
737 return WERR_BADFID;
739 DEBUG(10, ("_winreg_CreateKey called with parent key '%s' and "
740 "subkey name '%s'\n", parent->key->name, r->in.name.name));
742 result = reg_createkey(NULL, parent, r->in.name.name, r->in.access_mask,
743 &new_key, r->out.action_taken);
744 if (!W_ERROR_IS_OK(result)) {
745 return result;
748 if (!create_policy_hnd(p, r->out.new_handle, new_key)) {
749 TALLOC_FREE(new_key);
750 return WERR_BADFILE;
753 return WERR_OK;
756 /*******************************************************************
757 ********************************************************************/
759 WERROR _winreg_SetValue(pipes_struct *p, struct winreg_SetValue *r)
761 struct registry_key *key = find_regkey_by_hnd(p, r->in.handle);
762 struct registry_value *val;
763 WERROR status;
765 if ( !key )
766 return WERR_BADFID;
768 DEBUG(8,("_reg_set_value: Setting value for [%s:%s]\n",
769 key->key->name, r->in.name.name));
771 status = registry_pull_value(p->mem_ctx, &val, r->in.type, r->in.data,
772 r->in.size, r->in.size);
773 if (!W_ERROR_IS_OK(status)) {
774 return status;
777 return reg_setvalue(key, r->in.name.name, val);
780 /*******************************************************************
781 ********************************************************************/
783 WERROR _winreg_DeleteKey(pipes_struct *p, struct winreg_DeleteKey *r)
785 struct registry_key *parent = find_regkey_by_hnd(p, r->in.handle);
787 if ( !parent )
788 return WERR_BADFID;
790 return reg_deletekey(parent, r->in.key.name);
794 /*******************************************************************
795 ********************************************************************/
797 WERROR _winreg_DeleteValue(pipes_struct *p, struct winreg_DeleteValue *r)
799 struct registry_key *key = find_regkey_by_hnd(p, r->in.handle);
801 if ( !key )
802 return WERR_BADFID;
804 return reg_deletevalue(key, r->in.value.name);
807 /*******************************************************************
808 ********************************************************************/
810 WERROR _winreg_GetKeySecurity(pipes_struct *p, struct winreg_GetKeySecurity *r)
812 struct registry_key *key = find_regkey_by_hnd(p, r->in.handle);
813 WERROR err;
814 struct security_descriptor *secdesc;
815 uint8 *data;
816 size_t len;
818 if ( !key )
819 return WERR_BADFID;
821 /* access checks first */
823 if ( !(key->key->access_granted & STD_RIGHT_READ_CONTROL_ACCESS) )
824 return WERR_ACCESS_DENIED;
826 err = reg_getkeysecurity(p->mem_ctx, key, &secdesc);
827 if (!W_ERROR_IS_OK(err)) {
828 return err;
831 err = ntstatus_to_werror(marshall_sec_desc(p->mem_ctx, secdesc,
832 &data, &len));
833 if (!W_ERROR_IS_OK(err)) {
834 return err;
837 if (len > r->out.sd->size) {
838 r->out.sd->size = len;
839 return WERR_INSUFFICIENT_BUFFER;
842 r->out.sd->size = len;
843 r->out.sd->len = len;
844 r->out.sd->data = data;
846 return WERR_OK;
849 /*******************************************************************
850 ********************************************************************/
852 WERROR _winreg_SetKeySecurity(pipes_struct *p, struct winreg_SetKeySecurity *r)
854 struct registry_key *key = find_regkey_by_hnd(p, r->in.handle);
855 struct security_descriptor *secdesc;
856 WERROR err;
858 if ( !key )
859 return WERR_BADFID;
861 /* access checks first */
863 if ( !(key->key->access_granted & STD_RIGHT_WRITE_DAC_ACCESS) )
864 return WERR_ACCESS_DENIED;
866 err = ntstatus_to_werror(unmarshall_sec_desc(p->mem_ctx, r->in.sd->data,
867 r->in.sd->len, &secdesc));
868 if (!W_ERROR_IS_OK(err)) {
869 return err;
872 return reg_setkeysecurity(key, secdesc);
875 /*******************************************************************
876 ********************************************************************/
878 WERROR _winreg_FlushKey(pipes_struct *p, struct winreg_FlushKey *r)
880 /* I'm just replying OK because there's not a lot
881 here I see to do i --jerry */
883 return WERR_OK;
886 /*******************************************************************
887 ********************************************************************/
889 WERROR _winreg_UnLoadKey(pipes_struct *p, struct winreg_UnLoadKey *r)
891 /* fill in your code here if you think this call should
892 do anything */
894 p->rng_fault_state = True;
895 return WERR_NOT_SUPPORTED;
898 /*******************************************************************
899 ********************************************************************/
901 WERROR _winreg_ReplaceKey(pipes_struct *p, struct winreg_ReplaceKey *r)
903 /* fill in your code here if you think this call should
904 do anything */
906 p->rng_fault_state = True;
907 return WERR_NOT_SUPPORTED;
910 /*******************************************************************
911 ********************************************************************/
913 WERROR _winreg_LoadKey(pipes_struct *p, struct winreg_LoadKey *r)
915 /* fill in your code here if you think this call should
916 do anything */
918 p->rng_fault_state = True;
919 return WERR_NOT_SUPPORTED;
922 /*******************************************************************
923 ********************************************************************/
925 WERROR _winreg_NotifyChangeKeyValue(pipes_struct *p, struct winreg_NotifyChangeKeyValue *r)
927 /* fill in your code here if you think this call should
928 do anything */
930 p->rng_fault_state = True;
931 return WERR_NOT_SUPPORTED;
934 /*******************************************************************
935 ********************************************************************/
937 WERROR _winreg_QueryMultipleValues(pipes_struct *p, struct winreg_QueryMultipleValues *r)
939 /* fill in your code here if you think this call should
940 do anything */
942 p->rng_fault_state = True;
943 return WERR_NOT_SUPPORTED;
946 /*******************************************************************
947 ********************************************************************/
949 WERROR _winreg_QueryMultipleValues2(pipes_struct *p, struct winreg_QueryMultipleValues2 *r)
951 /* fill in your code here if you think this call should
952 do anything */
954 p->rng_fault_state = True;
955 return WERR_NOT_SUPPORTED;