s3: Fix bug #9085.
[Samba.git] / source3 / rpc_server / srv_winreg_nt.c
blobe840a8f6f364858714dc4da2fdb0d3a7cd26763d
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 = NULL;
224 uint32_t outbuf_size = 0;
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->in.value_name->name == NULL) {
234 return WERR_INVALID_PARAM;
237 if ((r->out.data_length == NULL) || (r->out.type == NULL) || (r->out.data_size == NULL)) {
238 return WERR_INVALID_PARAM;
241 DEBUG(7,("_winreg_QueryValue: policy key name = [%s]\n", regkey->key->name));
242 DEBUG(7,("_winreg_QueryValue: policy key type = [%08x]\n", regkey->key->type));
244 /* Handle QueryValue calls on HKEY_PERFORMANCE_DATA */
245 if(regkey->key->type == REG_KEY_HKPD)
247 if (strequal(r->in.value_name->name, "Global")) {
248 if (!prs_init(&prs_hkpd, *r->in.data_size, p->mem_ctx, MARSHALL))
249 return WERR_NOMEM;
250 status = reg_perfcount_get_hkpd(
251 &prs_hkpd, *r->in.data_size, &outbuf_size, NULL);
252 outbuf = (uint8_t *)prs_hkpd.data_p;
253 free_prs = True;
255 else if (strequal(r->in.value_name->name, "Counter 009")) {
256 outbuf_size = reg_perfcount_get_counter_names(
257 reg_perfcount_get_base_index(),
258 (char **)(void *)&outbuf);
259 free_buf = True;
261 else if (strequal(r->in.value_name->name, "Explain 009")) {
262 outbuf_size = reg_perfcount_get_counter_help(
263 reg_perfcount_get_base_index(),
264 (char **)(void *)&outbuf);
265 free_buf = True;
267 else if (isdigit(r->in.value_name->name[0])) {
268 /* we probably have a request for a specific object
269 * here */
270 if (!prs_init(&prs_hkpd, *r->in.data_size, p->mem_ctx, MARSHALL))
271 return WERR_NOMEM;
272 status = reg_perfcount_get_hkpd(
273 &prs_hkpd, *r->in.data_size, &outbuf_size,
274 r->in.value_name->name);
275 outbuf = (uint8_t *)prs_hkpd.data_p;
276 free_prs = True;
278 else {
279 DEBUG(3,("Unsupported key name [%s] for HKPD.\n",
280 r->in.value_name->name));
281 return WERR_BADFILE;
284 *r->out.type = REG_BINARY;
286 else {
287 struct registry_value *val;
289 status = reg_queryvalue(p->mem_ctx, regkey, r->in.value_name->name,
290 &val);
291 if (!W_ERROR_IS_OK(status)) {
293 DEBUG(10,("_winreg_QueryValue: reg_queryvalue failed with: %s\n",
294 win_errstr(status)));
296 if (r->out.data_size) {
297 *r->out.data_size = 0;
299 if (r->out.data_length) {
300 *r->out.data_length = 0;
302 return status;
305 status = registry_push_value(p->mem_ctx, val, &val_blob);
306 if (!W_ERROR_IS_OK(status)) {
307 return status;
310 outbuf = val_blob.data;
311 outbuf_size = val_blob.length;
312 *r->out.type = val->type;
315 status = WERR_BADFILE;
317 if (*r->in.data_size < outbuf_size) {
318 *r->out.data_size = outbuf_size;
319 status = r->in.data ? WERR_MORE_DATA : WERR_OK;
320 } else {
321 *r->out.data_length = outbuf_size;
322 *r->out.data_size = outbuf_size;
323 if (r->out.data) {
324 memcpy(r->out.data, outbuf, outbuf_size);
326 status = WERR_OK;
329 if (free_prs) prs_mem_free(&prs_hkpd);
330 if (free_buf) SAFE_FREE(outbuf);
332 return status;
335 /*****************************************************************************
336 _winreg_QueryInfoKey
337 ****************************************************************************/
339 WERROR _winreg_QueryInfoKey(pipes_struct *p, struct winreg_QueryInfoKey *r)
341 WERROR status = WERR_OK;
342 struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
344 if ( !regkey )
345 return WERR_BADFID;
347 r->out.classname->name = NULL;
349 status = reg_queryinfokey(regkey, r->out.num_subkeys, r->out.max_subkeylen,
350 r->out.max_classlen, r->out.num_values, r->out.max_valnamelen,
351 r->out.max_valbufsize, r->out.secdescsize,
352 r->out.last_changed_time);
353 if (!W_ERROR_IS_OK(status)) {
354 return status;
358 * These calculations account for the registry buffers being
359 * UTF-16. They are inexact at best, but so far they worked.
362 *r->out.max_subkeylen *= 2;
364 *r->out.max_valnamelen += 1;
365 *r->out.max_valnamelen *= 2;
367 return WERR_OK;
371 /*****************************************************************************
372 _winreg_GetVersion
373 ****************************************************************************/
375 WERROR _winreg_GetVersion(pipes_struct *p, struct winreg_GetVersion *r)
377 struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
379 if ( !regkey )
380 return WERR_BADFID;
382 return reg_getversion(r->out.version);
386 /*****************************************************************************
387 _winreg_EnumKey
388 ****************************************************************************/
390 WERROR _winreg_EnumKey(pipes_struct *p, struct winreg_EnumKey *r)
392 WERROR err;
393 struct registry_key *key = find_regkey_by_hnd( p, r->in.handle );
395 if ( !key )
396 return WERR_BADFID;
398 if ( !r->in.name || !r->in.keyclass )
399 return WERR_INVALID_PARAM;
401 DEBUG(8,("_reg_enum_key: enumerating key [%s]\n", key->key->name));
403 err = reg_enumkey(p->mem_ctx, key, r->in.enum_index, (char **)&r->out.name->name,
404 r->out.last_changed_time);
405 if (!W_ERROR_IS_OK(err)) {
406 return err;
408 r->out.keyclass->name = "";
409 return WERR_OK;
412 /*****************************************************************************
413 _winreg_EnumValue
414 ****************************************************************************/
416 WERROR _winreg_EnumValue(pipes_struct *p, struct winreg_EnumValue *r)
418 WERROR err;
419 struct registry_key *key = find_regkey_by_hnd( p, r->in.handle );
420 char *valname;
421 struct registry_value *val;
422 DATA_BLOB value_blob;
424 if ( !key )
425 return WERR_BADFID;
427 if ( !r->in.name )
428 return WERR_INVALID_PARAM;
430 DEBUG(8,("_winreg_EnumValue: enumerating values for key [%s]\n",
431 key->key->name));
433 err = reg_enumvalue(p->mem_ctx, key, r->in.enum_index, &valname, &val);
434 if (!W_ERROR_IS_OK(err)) {
435 return err;
438 err = registry_push_value(p->mem_ctx, val, &value_blob);
439 if (!W_ERROR_IS_OK(err)) {
440 return err;
443 if (r->out.name != NULL) {
444 r->out.name->name = valname;
447 if (r->out.type != NULL) {
448 *r->out.type = val->type;
451 if (r->out.value != NULL) {
452 if ((r->out.size == NULL) || (r->out.length == NULL)) {
453 return WERR_INVALID_PARAM;
456 if (value_blob.length > *r->out.size) {
457 return WERR_MORE_DATA;
460 memcpy( r->out.value, value_blob.data, value_blob.length );
463 if (r->out.length != NULL) {
464 *r->out.length = value_blob.length;
466 if (r->out.size != NULL) {
467 *r->out.size = value_blob.length;
470 return WERR_OK;
473 /*******************************************************************
474 _winreg_InitiateSystemShutdown
475 ********************************************************************/
477 WERROR _winreg_InitiateSystemShutdown(pipes_struct *p, struct winreg_InitiateSystemShutdown *r)
479 struct winreg_InitiateSystemShutdownEx s;
481 s.in.hostname = r->in.hostname;
482 s.in.message = r->in.message;
483 s.in.timeout = r->in.timeout;
484 s.in.force_apps = r->in.force_apps;
485 s.in.do_reboot = r->in.do_reboot;
486 s.in.reason = 0;
488 /* thunk down to _winreg_InitiateSystemShutdownEx()
489 (just returns a status) */
491 return _winreg_InitiateSystemShutdownEx( p, &s );
494 /*******************************************************************
495 _winreg_InitiateSystemShutdownEx
496 ********************************************************************/
498 #define SHUTDOWN_R_STRING "-r"
499 #define SHUTDOWN_F_STRING "-f"
502 WERROR _winreg_InitiateSystemShutdownEx(pipes_struct *p, struct winreg_InitiateSystemShutdownEx *r)
504 char *shutdown_script = NULL;
505 char *msg = NULL;
506 char *chkmsg = NULL;
507 fstring str_timeout;
508 fstring str_reason;
509 fstring do_reboot;
510 fstring f;
511 int ret;
512 bool can_shutdown;
514 shutdown_script = talloc_strdup(p->mem_ctx, lp_shutdown_script());
515 if (!shutdown_script) {
516 return WERR_NOMEM;
518 if (!*shutdown_script) {
519 return WERR_ACCESS_DENIED;
522 /* pull the message string and perform necessary sanity checks on it */
524 if ( r->in.message && r->in.message->string ) {
525 if ( (msg = talloc_strdup(p->mem_ctx, r->in.message->string )) == NULL ) {
526 return WERR_NOMEM;
528 chkmsg = TALLOC_ARRAY(p->mem_ctx, char, strlen(msg)+1);
529 if (!chkmsg) {
530 return WERR_NOMEM;
532 alpha_strcpy(chkmsg, msg, NULL, strlen(msg)+1);
535 fstr_sprintf(str_timeout, "%d", r->in.timeout);
536 fstr_sprintf(do_reboot, r->in.do_reboot ? SHUTDOWN_R_STRING : "");
537 fstr_sprintf(f, r->in.force_apps ? SHUTDOWN_F_STRING : "");
538 fstr_sprintf(str_reason, "%d", r->in.reason );
540 shutdown_script = talloc_all_string_sub(p->mem_ctx,
541 shutdown_script, "%z", chkmsg ? chkmsg : "");
542 if (!shutdown_script) {
543 return WERR_NOMEM;
545 shutdown_script = talloc_all_string_sub(p->mem_ctx,
546 shutdown_script, "%t", str_timeout);
547 if (!shutdown_script) {
548 return WERR_NOMEM;
550 shutdown_script = talloc_all_string_sub(p->mem_ctx,
551 shutdown_script, "%r", do_reboot);
552 if (!shutdown_script) {
553 return WERR_NOMEM;
555 shutdown_script = talloc_all_string_sub(p->mem_ctx,
556 shutdown_script, "%f", f);
557 if (!shutdown_script) {
558 return WERR_NOMEM;
560 shutdown_script = talloc_all_string_sub(p->mem_ctx,
561 shutdown_script, "%x", str_reason);
562 if (!shutdown_script) {
563 return WERR_NOMEM;
566 can_shutdown = user_has_privileges( p->server_info->ptok,
567 &se_remote_shutdown );
569 /* IF someone has privs, run the shutdown script as root. OTHERWISE run it as not root
570 Take the error return from the script and provide it as the Windows return code. */
572 /********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/
574 if ( can_shutdown )
575 become_root();
577 ret = smbrun( shutdown_script, NULL );
579 if ( can_shutdown )
580 unbecome_root();
582 /********** END SeRemoteShutdownPrivilege BLOCK **********/
584 DEBUG(3,("_reg_shutdown_ex: Running the command `%s' gave %d\n",
585 shutdown_script, ret));
587 return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED;
590 /*******************************************************************
591 _winreg_AbortSystemShutdown
592 ********************************************************************/
594 WERROR _winreg_AbortSystemShutdown(pipes_struct *p, struct winreg_AbortSystemShutdown *r)
596 const char *abort_shutdown_script;
597 int ret;
598 bool can_shutdown;
600 abort_shutdown_script = lp_abort_shutdown_script();
602 if (!*abort_shutdown_script)
603 return WERR_ACCESS_DENIED;
605 can_shutdown = user_has_privileges( p->server_info->ptok,
606 &se_remote_shutdown );
608 /********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/
610 if ( can_shutdown )
611 become_root();
613 ret = smbrun( abort_shutdown_script, NULL );
615 if ( can_shutdown )
616 unbecome_root();
618 /********** END SeRemoteShutdownPrivilege BLOCK **********/
620 DEBUG(3,("_reg_abort_shutdown: Running the command `%s' gave %d\n",
621 abort_shutdown_script, ret));
623 return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED;
626 /*******************************************************************
627 ********************************************************************/
629 static int validate_reg_filename(TALLOC_CTX *ctx, char **pp_fname )
631 char *p = NULL;
632 int num_services = lp_numservices();
633 int snum = -1;
634 const char *share_path;
635 char *fname = *pp_fname;
637 /* convert to a unix path, stripping the C:\ along the way */
639 if (!(p = valid_share_pathname(ctx, fname))) {
640 return -1;
643 /* has to exist within a valid file share */
645 for (snum=0; snum<num_services; snum++) {
646 if (!lp_snum_ok(snum) || lp_print_ok(snum)) {
647 continue;
650 share_path = lp_pathname(snum);
652 /* make sure we have a path (e.g. [homes] ) */
653 if (strlen(share_path) == 0) {
654 continue;
657 if (strncmp(share_path, p, strlen(share_path)) == 0) {
658 break;
662 *pp_fname = p;
663 return (snum < num_services) ? snum : -1;
666 /*******************************************************************
667 _winreg_RestoreKey
668 ********************************************************************/
670 WERROR _winreg_RestoreKey(pipes_struct *p, struct winreg_RestoreKey *r)
672 struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
673 char *fname = NULL;
674 int snum;
676 if ( !regkey )
677 return WERR_BADFID;
679 if ( !r->in.filename || !r->in.filename->name )
680 return WERR_INVALID_PARAM;
682 fname = talloc_strdup(p->mem_ctx, r->in.filename->name);
683 if (!fname) {
684 return WERR_NOMEM;
687 DEBUG(8,("_winreg_RestoreKey: verifying restore of key [%s] from "
688 "\"%s\"\n", regkey->key->name, fname));
690 if ((snum = validate_reg_filename(p->mem_ctx, &fname)) == -1)
691 return WERR_OBJECT_PATH_INVALID;
693 /* user must posses SeRestorePrivilege for this this proceed */
695 if ( !user_has_privileges( p->server_info->ptok, &se_restore ) )
696 return WERR_ACCESS_DENIED;
698 DEBUG(2,("_winreg_RestoreKey: Restoring [%s] from %s in share %s\n",
699 regkey->key->name, fname, lp_servicename(snum) ));
701 return reg_restorekey(regkey, fname);
704 /*******************************************************************
705 _winreg_SaveKey
706 ********************************************************************/
708 WERROR _winreg_SaveKey(pipes_struct *p, struct winreg_SaveKey *r)
710 struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
711 char *fname = NULL;
712 int snum = -1;
714 if ( !regkey )
715 return WERR_BADFID;
717 if ( !r->in.filename || !r->in.filename->name )
718 return WERR_INVALID_PARAM;
720 fname = talloc_strdup(p->mem_ctx, r->in.filename->name);
721 if (!fname) {
722 return WERR_NOMEM;
725 DEBUG(8,("_winreg_SaveKey: verifying backup of key [%s] to \"%s\"\n",
726 regkey->key->name, fname));
728 if ((snum = validate_reg_filename(p->mem_ctx, &fname)) == -1 )
729 return WERR_OBJECT_PATH_INVALID;
731 DEBUG(2,("_winreg_SaveKey: Saving [%s] to %s in share %s\n",
732 regkey->key->name, fname, lp_servicename(snum) ));
734 return reg_savekey(regkey, fname);
737 /*******************************************************************
738 _winreg_SaveKeyEx
739 ********************************************************************/
741 WERROR _winreg_SaveKeyEx(pipes_struct *p, struct winreg_SaveKeyEx *r)
743 /* fill in your code here if you think this call should
744 do anything */
746 p->rng_fault_state = True;
747 return WERR_NOT_SUPPORTED;
750 /*******************************************************************
751 _winreg_CreateKey
752 ********************************************************************/
754 WERROR _winreg_CreateKey( pipes_struct *p, struct winreg_CreateKey *r)
756 struct registry_key *parent = find_regkey_by_hnd(p, r->in.handle);
757 struct registry_key *new_key;
758 WERROR result;
760 if ( !parent )
761 return WERR_BADFID;
763 DEBUG(10, ("_winreg_CreateKey called with parent key '%s' and "
764 "subkey name '%s'\n", parent->key->name, r->in.name.name));
766 result = reg_createkey(NULL, parent, r->in.name.name, r->in.access_mask,
767 &new_key, r->out.action_taken);
768 if (!W_ERROR_IS_OK(result)) {
769 return result;
772 if (!create_policy_hnd(p, r->out.new_handle, new_key)) {
773 TALLOC_FREE(new_key);
774 return WERR_BADFILE;
777 return WERR_OK;
780 /*******************************************************************
781 _winreg_SetValue
782 ********************************************************************/
784 WERROR _winreg_SetValue(pipes_struct *p, struct winreg_SetValue *r)
786 struct registry_key *key = find_regkey_by_hnd(p, r->in.handle);
787 struct registry_value *val;
788 WERROR status;
790 if ( !key )
791 return WERR_BADFID;
793 DEBUG(8,("_reg_set_value: Setting value for [%s:%s]\n",
794 key->key->name, r->in.name.name));
796 status = registry_pull_value(p->mem_ctx, &val, r->in.type, r->in.data,
797 r->in.size, r->in.size);
798 if (!W_ERROR_IS_OK(status)) {
799 return status;
802 return reg_setvalue(key, r->in.name.name, val);
805 /*******************************************************************
806 _winreg_DeleteKey
807 ********************************************************************/
809 WERROR _winreg_DeleteKey(pipes_struct *p, struct winreg_DeleteKey *r)
811 struct registry_key *parent = find_regkey_by_hnd(p, r->in.handle);
813 if ( !parent )
814 return WERR_BADFID;
816 return reg_deletekey(parent, r->in.key.name);
820 /*******************************************************************
821 _winreg_DeleteValue
822 ********************************************************************/
824 WERROR _winreg_DeleteValue(pipes_struct *p, struct winreg_DeleteValue *r)
826 struct registry_key *key = find_regkey_by_hnd(p, r->in.handle);
828 if ( !key )
829 return WERR_BADFID;
831 return reg_deletevalue(key, r->in.value.name);
834 /*******************************************************************
835 _winreg_GetKeySecurity
836 ********************************************************************/
838 WERROR _winreg_GetKeySecurity(pipes_struct *p, struct winreg_GetKeySecurity *r)
840 struct registry_key *key = find_regkey_by_hnd(p, r->in.handle);
841 WERROR err;
842 struct security_descriptor *secdesc;
843 uint8 *data;
844 size_t len;
846 if ( !key )
847 return WERR_BADFID;
849 /* access checks first */
851 if ( !(key->key->access_granted & STD_RIGHT_READ_CONTROL_ACCESS) )
852 return WERR_ACCESS_DENIED;
854 err = reg_getkeysecurity(p->mem_ctx, key, &secdesc);
855 if (!W_ERROR_IS_OK(err)) {
856 return err;
859 err = ntstatus_to_werror(marshall_sec_desc(p->mem_ctx, secdesc,
860 &data, &len));
861 if (!W_ERROR_IS_OK(err)) {
862 return err;
865 if (len > r->out.sd->size) {
866 r->out.sd->size = len;
867 return WERR_INSUFFICIENT_BUFFER;
870 r->out.sd->size = len;
871 r->out.sd->len = len;
872 r->out.sd->data = data;
874 return WERR_OK;
877 /*******************************************************************
878 _winreg_SetKeySecurity
879 ********************************************************************/
881 WERROR _winreg_SetKeySecurity(pipes_struct *p, struct winreg_SetKeySecurity *r)
883 struct registry_key *key = find_regkey_by_hnd(p, r->in.handle);
884 struct security_descriptor *secdesc;
885 WERROR err;
887 if ( !key )
888 return WERR_BADFID;
890 /* access checks first */
892 if ( !(key->key->access_granted & STD_RIGHT_WRITE_DAC_ACCESS) )
893 return WERR_ACCESS_DENIED;
895 err = ntstatus_to_werror(unmarshall_sec_desc(p->mem_ctx, r->in.sd->data,
896 r->in.sd->len, &secdesc));
897 if (!W_ERROR_IS_OK(err)) {
898 return err;
901 return reg_setkeysecurity(key, secdesc);
904 /*******************************************************************
905 _winreg_FlushKey
906 ********************************************************************/
908 WERROR _winreg_FlushKey(pipes_struct *p, struct winreg_FlushKey *r)
910 /* I'm just replying OK because there's not a lot
911 here I see to do i --jerry */
913 return WERR_OK;
916 /*******************************************************************
917 _winreg_UnLoadKey
918 ********************************************************************/
920 WERROR _winreg_UnLoadKey(pipes_struct *p, struct winreg_UnLoadKey *r)
922 /* fill in your code here if you think this call should
923 do anything */
925 p->rng_fault_state = True;
926 return WERR_NOT_SUPPORTED;
929 /*******************************************************************
930 _winreg_ReplaceKey
931 ********************************************************************/
933 WERROR _winreg_ReplaceKey(pipes_struct *p, struct winreg_ReplaceKey *r)
935 /* fill in your code here if you think this call should
936 do anything */
938 p->rng_fault_state = True;
939 return WERR_NOT_SUPPORTED;
942 /*******************************************************************
943 _winreg_LoadKey
944 ********************************************************************/
946 WERROR _winreg_LoadKey(pipes_struct *p, struct winreg_LoadKey *r)
948 /* fill in your code here if you think this call should
949 do anything */
951 p->rng_fault_state = True;
952 return WERR_NOT_SUPPORTED;
955 /*******************************************************************
956 _winreg_NotifyChangeKeyValue
957 ********************************************************************/
959 WERROR _winreg_NotifyChangeKeyValue(pipes_struct *p, struct winreg_NotifyChangeKeyValue *r)
961 return WERR_NOT_SUPPORTED;
964 /*******************************************************************
965 _winreg_QueryMultipleValues
966 ********************************************************************/
968 WERROR _winreg_QueryMultipleValues(pipes_struct *p, struct winreg_QueryMultipleValues *r)
970 /* fill in your code here if you think this call should
971 do anything */
973 p->rng_fault_state = True;
974 return WERR_NOT_SUPPORTED;
977 /*******************************************************************
978 _winreg_QueryMultipleValues2
979 ********************************************************************/
981 WERROR _winreg_QueryMultipleValues2(pipes_struct *p, struct winreg_QueryMultipleValues2 *r)
983 /* fill in your code here if you think this call should
984 do anything */
986 p->rng_fault_state = True;
987 return WERR_NOT_SUPPORTED;