s4/torture: add more lock cancellation tests
[Samba/fernandojvsilva.git] / source3 / rpc_server / srv_winreg_nt.c
blobdcfe2b931af384caafca1e18d56208c2badef590
1 /*
2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
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"
24 #include "../librpc/gen_ndr/srv_winreg.h"
26 #undef DBGC_CLASS
27 #define DBGC_CLASS DBGC_RPC_SRV
29 /******************************************************************
30 Find a registry key handle and return a struct registry_key *
31 *****************************************************************/
33 static struct registry_key *find_regkey_by_hnd(pipes_struct *p,
34 struct policy_handle *hnd)
36 struct registry_key *regkey = NULL;
38 if(!find_policy_by_hnd(p,hnd,(void **)(void *)&regkey)) {
39 DEBUG(2,("find_regkey_index_by_hnd: Registry Key not found: "));
40 return NULL;
43 return regkey;
46 /*******************************************************************
47 Function for open a new registry handle and creating a handle
48 Note that P should be valid & hnd should already have space
50 When we open a key, we store the full path to the key as
51 HK[LM|U]\<key>\<key>\...
52 *******************************************************************/
54 static WERROR open_registry_key( pipes_struct *p, struct policy_handle *hnd,
55 struct registry_key *parent,
56 const char *subkeyname,
57 uint32 access_desired )
59 WERROR result = WERR_OK;
60 struct registry_key *key;
62 if (parent == NULL) {
63 result = reg_openhive(p->mem_ctx, subkeyname, access_desired,
64 p->server_info->ptok, &key);
66 else {
67 result = reg_openkey(p->mem_ctx, parent, subkeyname,
68 access_desired, &key);
71 if ( !W_ERROR_IS_OK(result) ) {
72 return result;
75 if ( !create_policy_hnd( p, hnd, key ) ) {
76 return WERR_BADFILE;
79 return WERR_OK;
82 /*******************************************************************
83 Function for open a new registry handle and creating a handle
84 Note that P should be valid & hnd should already have space
85 *******************************************************************/
87 static bool close_registry_key(pipes_struct *p, struct policy_handle *hnd)
89 struct registry_key *regkey = find_regkey_by_hnd(p, hnd);
91 if ( !regkey ) {
92 DEBUG(2,("close_registry_key: Invalid handle (%s:%u:%u)\n",
93 OUR_HANDLE(hnd)));
94 return False;
97 close_policy_hnd(p, hnd);
99 return True;
102 /********************************************************************
103 _winreg_CloseKey
104 ********************************************************************/
106 WERROR _winreg_CloseKey(pipes_struct *p, struct winreg_CloseKey *r)
108 /* close the policy handle */
110 if (!close_registry_key(p, r->in.handle))
111 return WERR_BADFID;
113 ZERO_STRUCTP(r->out.handle);
115 return WERR_OK;
118 /*******************************************************************
119 _winreg_OpenHKLM
120 ********************************************************************/
122 WERROR _winreg_OpenHKLM(pipes_struct *p, struct winreg_OpenHKLM *r)
124 return open_registry_key(p, r->out.handle, NULL, KEY_HKLM, r->in.access_mask);
127 /*******************************************************************
128 _winreg_OpenHKPD
129 ********************************************************************/
131 WERROR _winreg_OpenHKPD(pipes_struct *p, struct winreg_OpenHKPD *r)
133 return open_registry_key(p, r->out.handle, NULL, KEY_HKPD, r->in.access_mask);
136 /*******************************************************************
137 _winreg_OpenHKPT
138 ********************************************************************/
140 WERROR _winreg_OpenHKPT(pipes_struct *p, struct winreg_OpenHKPT *r)
142 return open_registry_key(p, r->out.handle, NULL, KEY_HKPT, r->in.access_mask);
145 /*******************************************************************
146 _winreg_OpenHKCR
147 ********************************************************************/
149 WERROR _winreg_OpenHKCR(pipes_struct *p, struct winreg_OpenHKCR *r)
151 return open_registry_key(p, r->out.handle, NULL, KEY_HKCR, r->in.access_mask);
154 /*******************************************************************
155 _winreg_OpenHKU
156 ********************************************************************/
158 WERROR _winreg_OpenHKU(pipes_struct *p, struct winreg_OpenHKU *r)
160 return open_registry_key(p, r->out.handle, NULL, KEY_HKU, r->in.access_mask);
163 /*******************************************************************
164 _winreg_OpenHKCU
165 ********************************************************************/
167 WERROR _winreg_OpenHKCU(pipes_struct *p, struct winreg_OpenHKCU *r)
169 return open_registry_key(p, r->out.handle, NULL, KEY_HKCU, r->in.access_mask);
172 /*******************************************************************
173 _winreg_OpenHKCC
174 ********************************************************************/
176 WERROR _winreg_OpenHKCC(pipes_struct *p, struct winreg_OpenHKCC *r)
178 return open_registry_key(p, r->out.handle, NULL, KEY_HKCC, r->in.access_mask);
181 /*******************************************************************
182 _winreg_OpenHKDD
183 ********************************************************************/
185 WERROR _winreg_OpenHKDD(pipes_struct *p, struct winreg_OpenHKDD *r)
187 return open_registry_key(p, r->out.handle, NULL, KEY_HKDD, r->in.access_mask);
190 /*******************************************************************
191 _winreg_OpenHKPN
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 _winreg_OpenKey
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 _winreg_QueryValue
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 if ((r->out.data_length == NULL) || (r->out.type == NULL)) {
234 return WERR_INVALID_PARAM;
237 *r->out.data_length = *r->out.type = REG_NONE;
239 DEBUG(7,("_reg_info: policy key name = [%s]\n", regkey->key->name));
240 DEBUG(7,("_reg_info: policy key type = [%08x]\n", regkey->key->type));
242 /* Handle QueryValue calls on HKEY_PERFORMANCE_DATA */
243 if(regkey->key->type == REG_KEY_HKPD)
245 if (strequal(r->in.value_name->name, "Global")) {
246 if (!prs_init(&prs_hkpd, *r->in.data_size, p->mem_ctx, MARSHALL))
247 return WERR_NOMEM;
248 status = reg_perfcount_get_hkpd(
249 &prs_hkpd, *r->in.data_size, &outbuf_size, NULL);
250 outbuf = (uint8_t *)prs_hkpd.data_p;
251 free_prs = True;
253 else if (strequal(r->in.value_name->name, "Counter 009")) {
254 outbuf_size = reg_perfcount_get_counter_names(
255 reg_perfcount_get_base_index(),
256 (char **)(void *)&outbuf);
257 free_buf = True;
259 else if (strequal(r->in.value_name->name, "Explain 009")) {
260 outbuf_size = reg_perfcount_get_counter_help(
261 reg_perfcount_get_base_index(),
262 (char **)(void *)&outbuf);
263 free_buf = True;
265 else if (isdigit(r->in.value_name->name[0])) {
266 /* we probably have a request for a specific object
267 * here */
268 if (!prs_init(&prs_hkpd, *r->in.data_size, p->mem_ctx, MARSHALL))
269 return WERR_NOMEM;
270 status = reg_perfcount_get_hkpd(
271 &prs_hkpd, *r->in.data_size, &outbuf_size,
272 r->in.value_name->name);
273 outbuf = (uint8_t *)prs_hkpd.data_p;
274 free_prs = True;
276 else {
277 DEBUG(3,("Unsupported key name [%s] for HKPD.\n",
278 r->in.value_name->name));
279 return WERR_BADFILE;
282 *r->out.type = REG_BINARY;
284 else {
285 struct registry_value *val;
287 status = reg_queryvalue(p->mem_ctx, regkey, r->in.value_name->name,
288 &val);
289 if (!W_ERROR_IS_OK(status)) {
290 if (r->out.data_size) {
291 *r->out.data_size = 0;
293 if (r->out.data_length) {
294 *r->out.data_length = 0;
296 return status;
299 status = registry_push_value(p->mem_ctx, val, &val_blob);
300 if (!W_ERROR_IS_OK(status)) {
301 return status;
304 outbuf = val_blob.data;
305 outbuf_size = val_blob.length;
306 *r->out.type = val->type;
309 *r->out.data_length = outbuf_size;
311 if ( *r->in.data_size == 0 || !r->out.data ) {
312 status = WERR_OK;
313 } else if ( *r->out.data_length > *r->in.data_size ) {
314 status = WERR_MORE_DATA;
315 } else {
316 memcpy( r->out.data, outbuf, *r->out.data_length );
317 status = WERR_OK;
320 *r->out.data_size = *r->out.data_length;
322 if (free_prs) prs_mem_free(&prs_hkpd);
323 if (free_buf) SAFE_FREE(outbuf);
325 return status;
328 /*****************************************************************************
329 _winreg_QueryInfoKey
330 ****************************************************************************/
332 WERROR _winreg_QueryInfoKey(pipes_struct *p, struct winreg_QueryInfoKey *r)
334 WERROR status = WERR_OK;
335 struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
337 if ( !regkey )
338 return WERR_BADFID;
340 r->out.classname->name = NULL;
342 status = reg_queryinfokey(regkey, r->out.num_subkeys, r->out.max_subkeylen,
343 r->out.max_classlen, r->out.num_values, r->out.max_valnamelen,
344 r->out.max_valbufsize, r->out.secdescsize,
345 r->out.last_changed_time);
346 if (!W_ERROR_IS_OK(status)) {
347 return status;
351 * These calculations account for the registry buffers being
352 * UTF-16. They are inexact at best, but so far they worked.
355 *r->out.max_subkeylen *= 2;
357 *r->out.max_valnamelen += 1;
358 *r->out.max_valnamelen *= 2;
360 return WERR_OK;
364 /*****************************************************************************
365 _winreg_GetVersion
366 ****************************************************************************/
368 WERROR _winreg_GetVersion(pipes_struct *p, struct winreg_GetVersion *r)
370 struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
372 if ( !regkey )
373 return WERR_BADFID;
375 return reg_getversion(r->out.version);
379 /*****************************************************************************
380 _winreg_EnumKey
381 ****************************************************************************/
383 WERROR _winreg_EnumKey(pipes_struct *p, struct winreg_EnumKey *r)
385 WERROR err;
386 struct registry_key *key = find_regkey_by_hnd( p, r->in.handle );
388 if ( !key )
389 return WERR_BADFID;
391 if ( !r->in.name || !r->in.keyclass )
392 return WERR_INVALID_PARAM;
394 DEBUG(8,("_reg_enum_key: enumerating key [%s]\n", key->key->name));
396 err = reg_enumkey(p->mem_ctx, key, r->in.enum_index, (char **)&r->out.name->name,
397 r->out.last_changed_time);
398 if (!W_ERROR_IS_OK(err)) {
399 return err;
401 r->out.keyclass->name = "";
402 return WERR_OK;
405 /*****************************************************************************
406 _winreg_EnumValue
407 ****************************************************************************/
409 WERROR _winreg_EnumValue(pipes_struct *p, struct winreg_EnumValue *r)
411 WERROR err;
412 struct registry_key *key = find_regkey_by_hnd( p, r->in.handle );
413 char *valname;
414 struct registry_value *val;
415 DATA_BLOB value_blob;
417 if ( !key )
418 return WERR_BADFID;
420 if ( !r->in.name )
421 return WERR_INVALID_PARAM;
423 DEBUG(8,("_winreg_EnumValue: enumerating values for key [%s]\n",
424 key->key->name));
426 err = reg_enumvalue(p->mem_ctx, key, r->in.enum_index, &valname, &val);
427 if (!W_ERROR_IS_OK(err)) {
428 return err;
431 err = registry_push_value(p->mem_ctx, val, &value_blob);
432 if (!W_ERROR_IS_OK(err)) {
433 return err;
436 if (r->out.name != NULL) {
437 r->out.name->name = valname;
440 if (r->out.type != NULL) {
441 *r->out.type = val->type;
444 if (r->out.value != NULL) {
445 if ((r->out.size == NULL) || (r->out.length == NULL)) {
446 return WERR_INVALID_PARAM;
449 if (value_blob.length > *r->out.size) {
450 return WERR_MORE_DATA;
453 memcpy( r->out.value, value_blob.data, value_blob.length );
456 if (r->out.length != NULL) {
457 *r->out.length = value_blob.length;
459 if (r->out.size != NULL) {
460 *r->out.size = value_blob.length;
463 return WERR_OK;
466 /*******************************************************************
467 _winreg_InitiateSystemShutdown
468 ********************************************************************/
470 WERROR _winreg_InitiateSystemShutdown(pipes_struct *p, struct winreg_InitiateSystemShutdown *r)
472 struct winreg_InitiateSystemShutdownEx s;
474 s.in.hostname = r->in.hostname;
475 s.in.message = r->in.message;
476 s.in.timeout = r->in.timeout;
477 s.in.force_apps = r->in.force_apps;
478 s.in.do_reboot = r->in.do_reboot;
479 s.in.reason = 0;
481 /* thunk down to _winreg_InitiateSystemShutdownEx()
482 (just returns a status) */
484 return _winreg_InitiateSystemShutdownEx( p, &s );
487 /*******************************************************************
488 _winreg_InitiateSystemShutdownEx
489 ********************************************************************/
491 #define SHUTDOWN_R_STRING "-r"
492 #define SHUTDOWN_F_STRING "-f"
495 WERROR _winreg_InitiateSystemShutdownEx(pipes_struct *p, struct winreg_InitiateSystemShutdownEx *r)
497 char *shutdown_script = NULL;
498 char *msg = NULL;
499 char *chkmsg = NULL;
500 fstring str_timeout;
501 fstring str_reason;
502 fstring do_reboot;
503 fstring f;
504 int ret;
505 bool can_shutdown;
507 shutdown_script = talloc_strdup(p->mem_ctx, lp_shutdown_script());
508 if (!shutdown_script) {
509 return WERR_NOMEM;
511 if (!*shutdown_script) {
512 return WERR_ACCESS_DENIED;
515 /* pull the message string and perform necessary sanity checks on it */
517 if ( r->in.message && r->in.message->string ) {
518 if ( (msg = talloc_strdup(p->mem_ctx, r->in.message->string )) == NULL ) {
519 return WERR_NOMEM;
521 chkmsg = TALLOC_ARRAY(p->mem_ctx, char, strlen(msg)+1);
522 if (!chkmsg) {
523 return WERR_NOMEM;
525 alpha_strcpy(chkmsg, msg, NULL, strlen(msg)+1);
528 fstr_sprintf(str_timeout, "%d", r->in.timeout);
529 fstr_sprintf(do_reboot, r->in.do_reboot ? SHUTDOWN_R_STRING : "");
530 fstr_sprintf(f, r->in.force_apps ? SHUTDOWN_F_STRING : "");
531 fstr_sprintf(str_reason, "%d", r->in.reason );
533 shutdown_script = talloc_all_string_sub(p->mem_ctx,
534 shutdown_script, "%z", chkmsg ? chkmsg : "");
535 if (!shutdown_script) {
536 return WERR_NOMEM;
538 shutdown_script = talloc_all_string_sub(p->mem_ctx,
539 shutdown_script, "%t", str_timeout);
540 if (!shutdown_script) {
541 return WERR_NOMEM;
543 shutdown_script = talloc_all_string_sub(p->mem_ctx,
544 shutdown_script, "%r", do_reboot);
545 if (!shutdown_script) {
546 return WERR_NOMEM;
548 shutdown_script = talloc_all_string_sub(p->mem_ctx,
549 shutdown_script, "%f", f);
550 if (!shutdown_script) {
551 return WERR_NOMEM;
553 shutdown_script = talloc_all_string_sub(p->mem_ctx,
554 shutdown_script, "%x", str_reason);
555 if (!shutdown_script) {
556 return WERR_NOMEM;
559 can_shutdown = user_has_privileges( p->server_info->ptok,
560 &se_remote_shutdown );
562 /* IF someone has privs, run the shutdown script as root. OTHERWISE run it as not root
563 Take the error return from the script and provide it as the Windows return code. */
565 /********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/
567 if ( can_shutdown )
568 become_root();
570 ret = smbrun( shutdown_script, NULL );
572 if ( can_shutdown )
573 unbecome_root();
575 /********** END SeRemoteShutdownPrivilege BLOCK **********/
577 DEBUG(3,("_reg_shutdown_ex: Running the command `%s' gave %d\n",
578 shutdown_script, ret));
580 return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED;
583 /*******************************************************************
584 _winreg_AbortSystemShutdown
585 ********************************************************************/
587 WERROR _winreg_AbortSystemShutdown(pipes_struct *p, struct winreg_AbortSystemShutdown *r)
589 const char *abort_shutdown_script;
590 int ret;
591 bool can_shutdown;
593 abort_shutdown_script = lp_abort_shutdown_script();
595 if (!*abort_shutdown_script)
596 return WERR_ACCESS_DENIED;
598 can_shutdown = user_has_privileges( p->server_info->ptok,
599 &se_remote_shutdown );
601 /********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/
603 if ( can_shutdown )
604 become_root();
606 ret = smbrun( abort_shutdown_script, NULL );
608 if ( can_shutdown )
609 unbecome_root();
611 /********** END SeRemoteShutdownPrivilege BLOCK **********/
613 DEBUG(3,("_reg_abort_shutdown: Running the command `%s' gave %d\n",
614 abort_shutdown_script, ret));
616 return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED;
619 /*******************************************************************
620 ********************************************************************/
622 static int validate_reg_filename(TALLOC_CTX *ctx, char **pp_fname )
624 char *p = NULL;
625 int num_services = lp_numservices();
626 int snum = -1;
627 const char *share_path;
628 char *fname = *pp_fname;
630 /* convert to a unix path, stripping the C:\ along the way */
632 if (!(p = valid_share_pathname(ctx, fname))) {
633 return -1;
636 /* has to exist within a valid file share */
638 for (snum=0; snum<num_services; snum++) {
639 if (!lp_snum_ok(snum) || lp_print_ok(snum)) {
640 continue;
643 share_path = lp_pathname(snum);
645 /* make sure we have a path (e.g. [homes] ) */
646 if (strlen(share_path) == 0) {
647 continue;
650 if (strncmp(share_path, p, strlen(share_path)) == 0) {
651 break;
655 *pp_fname = p;
656 return (snum < num_services) ? snum : -1;
659 /*******************************************************************
660 _winreg_RestoreKey
661 ********************************************************************/
663 WERROR _winreg_RestoreKey(pipes_struct *p, struct winreg_RestoreKey *r)
665 struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
666 char *fname = NULL;
667 int snum;
669 if ( !regkey )
670 return WERR_BADFID;
672 if ( !r->in.filename || !r->in.filename->name )
673 return WERR_INVALID_PARAM;
675 fname = talloc_strdup(p->mem_ctx, r->in.filename->name);
676 if (!fname) {
677 return WERR_NOMEM;
680 DEBUG(8,("_winreg_RestoreKey: verifying restore of key [%s] from "
681 "\"%s\"\n", regkey->key->name, fname));
683 if ((snum = validate_reg_filename(p->mem_ctx, &fname)) == -1)
684 return WERR_OBJECT_PATH_INVALID;
686 /* user must posses SeRestorePrivilege for this this proceed */
688 if ( !user_has_privileges( p->server_info->ptok, &se_restore ) )
689 return WERR_ACCESS_DENIED;
691 DEBUG(2,("_winreg_RestoreKey: Restoring [%s] from %s in share %s\n",
692 regkey->key->name, fname, lp_servicename(snum) ));
694 return reg_restorekey(regkey, fname);
697 /*******************************************************************
698 _winreg_SaveKey
699 ********************************************************************/
701 WERROR _winreg_SaveKey(pipes_struct *p, struct winreg_SaveKey *r)
703 struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
704 char *fname = NULL;
705 int snum = -1;
707 if ( !regkey )
708 return WERR_BADFID;
710 if ( !r->in.filename || !r->in.filename->name )
711 return WERR_INVALID_PARAM;
713 fname = talloc_strdup(p->mem_ctx, r->in.filename->name);
714 if (!fname) {
715 return WERR_NOMEM;
718 DEBUG(8,("_winreg_SaveKey: verifying backup of key [%s] to \"%s\"\n",
719 regkey->key->name, fname));
721 if ((snum = validate_reg_filename(p->mem_ctx, &fname)) == -1 )
722 return WERR_OBJECT_PATH_INVALID;
724 DEBUG(2,("_winreg_SaveKey: Saving [%s] to %s in share %s\n",
725 regkey->key->name, fname, lp_servicename(snum) ));
727 return reg_savekey(regkey, fname);
730 /*******************************************************************
731 _winreg_SaveKeyEx
732 ********************************************************************/
734 WERROR _winreg_SaveKeyEx(pipes_struct *p, struct winreg_SaveKeyEx *r)
736 /* fill in your code here if you think this call should
737 do anything */
739 p->rng_fault_state = True;
740 return WERR_NOT_SUPPORTED;
743 /*******************************************************************
744 _winreg_CreateKey
745 ********************************************************************/
747 WERROR _winreg_CreateKey( pipes_struct *p, struct winreg_CreateKey *r)
749 struct registry_key *parent = find_regkey_by_hnd(p, r->in.handle);
750 struct registry_key *new_key;
751 WERROR result;
753 if ( !parent )
754 return WERR_BADFID;
756 DEBUG(10, ("_winreg_CreateKey called with parent key '%s' and "
757 "subkey name '%s'\n", parent->key->name, r->in.name.name));
759 result = reg_createkey(NULL, parent, r->in.name.name, r->in.access_mask,
760 &new_key, r->out.action_taken);
761 if (!W_ERROR_IS_OK(result)) {
762 return result;
765 if (!create_policy_hnd(p, r->out.new_handle, new_key)) {
766 TALLOC_FREE(new_key);
767 return WERR_BADFILE;
770 return WERR_OK;
773 /*******************************************************************
774 _winreg_SetValue
775 ********************************************************************/
777 WERROR _winreg_SetValue(pipes_struct *p, struct winreg_SetValue *r)
779 struct registry_key *key = find_regkey_by_hnd(p, r->in.handle);
780 struct registry_value *val;
781 WERROR status;
783 if ( !key )
784 return WERR_BADFID;
786 DEBUG(8,("_reg_set_value: Setting value for [%s:%s]\n",
787 key->key->name, r->in.name.name));
789 status = registry_pull_value(p->mem_ctx, &val, r->in.type, r->in.data,
790 r->in.size, r->in.size);
791 if (!W_ERROR_IS_OK(status)) {
792 return status;
795 return reg_setvalue(key, r->in.name.name, val);
798 /*******************************************************************
799 _winreg_DeleteKey
800 ********************************************************************/
802 WERROR _winreg_DeleteKey(pipes_struct *p, struct winreg_DeleteKey *r)
804 struct registry_key *parent = find_regkey_by_hnd(p, r->in.handle);
806 if ( !parent )
807 return WERR_BADFID;
809 return reg_deletekey(parent, r->in.key.name);
813 /*******************************************************************
814 _winreg_DeleteValue
815 ********************************************************************/
817 WERROR _winreg_DeleteValue(pipes_struct *p, struct winreg_DeleteValue *r)
819 struct registry_key *key = find_regkey_by_hnd(p, r->in.handle);
821 if ( !key )
822 return WERR_BADFID;
824 return reg_deletevalue(key, r->in.value.name);
827 /*******************************************************************
828 _winreg_GetKeySecurity
829 ********************************************************************/
831 WERROR _winreg_GetKeySecurity(pipes_struct *p, struct winreg_GetKeySecurity *r)
833 struct registry_key *key = find_regkey_by_hnd(p, r->in.handle);
834 WERROR err;
835 struct security_descriptor *secdesc;
836 uint8 *data;
837 size_t len;
839 if ( !key )
840 return WERR_BADFID;
842 /* access checks first */
844 if ( !(key->key->access_granted & STD_RIGHT_READ_CONTROL_ACCESS) )
845 return WERR_ACCESS_DENIED;
847 err = reg_getkeysecurity(p->mem_ctx, key, &secdesc);
848 if (!W_ERROR_IS_OK(err)) {
849 return err;
852 err = ntstatus_to_werror(marshall_sec_desc(p->mem_ctx, secdesc,
853 &data, &len));
854 if (!W_ERROR_IS_OK(err)) {
855 return err;
858 if (len > r->out.sd->size) {
859 r->out.sd->size = len;
860 return WERR_INSUFFICIENT_BUFFER;
863 r->out.sd->size = len;
864 r->out.sd->len = len;
865 r->out.sd->data = data;
867 return WERR_OK;
870 /*******************************************************************
871 _winreg_SetKeySecurity
872 ********************************************************************/
874 WERROR _winreg_SetKeySecurity(pipes_struct *p, struct winreg_SetKeySecurity *r)
876 struct registry_key *key = find_regkey_by_hnd(p, r->in.handle);
877 struct security_descriptor *secdesc;
878 WERROR err;
880 if ( !key )
881 return WERR_BADFID;
883 /* access checks first */
885 if ( !(key->key->access_granted & STD_RIGHT_WRITE_DAC_ACCESS) )
886 return WERR_ACCESS_DENIED;
888 err = ntstatus_to_werror(unmarshall_sec_desc(p->mem_ctx, r->in.sd->data,
889 r->in.sd->len, &secdesc));
890 if (!W_ERROR_IS_OK(err)) {
891 return err;
894 return reg_setkeysecurity(key, secdesc);
897 /*******************************************************************
898 _winreg_FlushKey
899 ********************************************************************/
901 WERROR _winreg_FlushKey(pipes_struct *p, struct winreg_FlushKey *r)
903 /* I'm just replying OK because there's not a lot
904 here I see to do i --jerry */
906 return WERR_OK;
909 /*******************************************************************
910 _winreg_UnLoadKey
911 ********************************************************************/
913 WERROR _winreg_UnLoadKey(pipes_struct *p, struct winreg_UnLoadKey *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 _winreg_ReplaceKey
924 ********************************************************************/
926 WERROR _winreg_ReplaceKey(pipes_struct *p, struct winreg_ReplaceKey *r)
928 /* fill in your code here if you think this call should
929 do anything */
931 p->rng_fault_state = True;
932 return WERR_NOT_SUPPORTED;
935 /*******************************************************************
936 _winreg_LoadKey
937 ********************************************************************/
939 WERROR _winreg_LoadKey(pipes_struct *p, struct winreg_LoadKey *r)
941 /* fill in your code here if you think this call should
942 do anything */
944 p->rng_fault_state = True;
945 return WERR_NOT_SUPPORTED;
948 /*******************************************************************
949 _winreg_NotifyChangeKeyValue
950 ********************************************************************/
952 WERROR _winreg_NotifyChangeKeyValue(pipes_struct *p, struct winreg_NotifyChangeKeyValue *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;
961 /*******************************************************************
962 _winreg_QueryMultipleValues
963 ********************************************************************/
965 WERROR _winreg_QueryMultipleValues(pipes_struct *p, struct winreg_QueryMultipleValues *r)
967 /* fill in your code here if you think this call should
968 do anything */
970 p->rng_fault_state = True;
971 return WERR_NOT_SUPPORTED;
974 /*******************************************************************
975 _winreg_QueryMultipleValues2
976 ********************************************************************/
978 WERROR _winreg_QueryMultipleValues2(pipes_struct *p, struct winreg_QueryMultipleValues2 *r)
980 /* fill in your code here if you think this call should
981 do anything */
983 p->rng_fault_state = True;
984 return WERR_NOT_SUPPORTED;