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. */
24 #include "../librpc/gen_ndr/srv_winreg.h"
26 #include "registry/reg_perfcount.h"
27 #include "registry/reg_util_marshalling.h"
30 #define DBGC_CLASS DBGC_RPC_SRV
32 /******************************************************************
33 Find a registry key handle and return a struct registry_key *
34 *****************************************************************/
36 static struct registry_key
*find_regkey_by_hnd(pipes_struct
*p
,
37 struct policy_handle
*hnd
)
39 struct registry_key
*regkey
= NULL
;
41 if(!find_policy_by_hnd(p
,hnd
,(void **)(void *)®key
)) {
42 DEBUG(2,("find_regkey_index_by_hnd: Registry Key not found: "));
49 /*******************************************************************
50 Function for open a new registry handle and creating a handle
51 Note that P should be valid & hnd should already have space
53 When we open a key, we store the full path to the key as
54 HK[LM|U]\<key>\<key>\...
55 *******************************************************************/
57 static WERROR
open_registry_key( pipes_struct
*p
, struct policy_handle
*hnd
,
58 struct registry_key
*parent
,
59 const char *subkeyname
,
60 uint32 access_desired
)
62 WERROR result
= WERR_OK
;
63 struct registry_key
*key
;
66 result
= reg_openhive(p
->mem_ctx
, subkeyname
, access_desired
,
67 p
->server_info
->ptok
, &key
);
70 result
= reg_openkey(p
->mem_ctx
, parent
, subkeyname
,
71 access_desired
, &key
);
74 if ( !W_ERROR_IS_OK(result
) ) {
78 if ( !create_policy_hnd( p
, hnd
, key
) ) {
85 /*******************************************************************
86 Function for open a new registry handle and creating a handle
87 Note that P should be valid & hnd should already have space
88 *******************************************************************/
90 static bool close_registry_key(pipes_struct
*p
, struct policy_handle
*hnd
)
92 struct registry_key
*regkey
= find_regkey_by_hnd(p
, hnd
);
95 DEBUG(2,("close_registry_key: Invalid handle (%s:%u:%u)\n",
100 close_policy_hnd(p
, hnd
);
105 /********************************************************************
107 ********************************************************************/
109 WERROR
_winreg_CloseKey(pipes_struct
*p
, struct winreg_CloseKey
*r
)
111 /* close the policy handle */
113 if (!close_registry_key(p
, r
->in
.handle
))
116 ZERO_STRUCTP(r
->out
.handle
);
121 /*******************************************************************
123 ********************************************************************/
125 WERROR
_winreg_OpenHKLM(pipes_struct
*p
, struct winreg_OpenHKLM
*r
)
127 return open_registry_key(p
, r
->out
.handle
, NULL
, KEY_HKLM
, r
->in
.access_mask
);
130 /*******************************************************************
132 ********************************************************************/
134 WERROR
_winreg_OpenHKPD(pipes_struct
*p
, struct winreg_OpenHKPD
*r
)
136 return open_registry_key(p
, r
->out
.handle
, NULL
, KEY_HKPD
, r
->in
.access_mask
);
139 /*******************************************************************
141 ********************************************************************/
143 WERROR
_winreg_OpenHKPT(pipes_struct
*p
, struct winreg_OpenHKPT
*r
)
145 return open_registry_key(p
, r
->out
.handle
, NULL
, KEY_HKPT
, r
->in
.access_mask
);
148 /*******************************************************************
150 ********************************************************************/
152 WERROR
_winreg_OpenHKCR(pipes_struct
*p
, struct winreg_OpenHKCR
*r
)
154 return open_registry_key(p
, r
->out
.handle
, NULL
, KEY_HKCR
, r
->in
.access_mask
);
157 /*******************************************************************
159 ********************************************************************/
161 WERROR
_winreg_OpenHKU(pipes_struct
*p
, struct winreg_OpenHKU
*r
)
163 return open_registry_key(p
, r
->out
.handle
, NULL
, KEY_HKU
, r
->in
.access_mask
);
166 /*******************************************************************
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 /*******************************************************************
177 ********************************************************************/
179 WERROR
_winreg_OpenHKCC(pipes_struct
*p
, struct winreg_OpenHKCC
*r
)
181 return open_registry_key(p
, r
->out
.handle
, NULL
, KEY_HKCC
, r
->in
.access_mask
);
184 /*******************************************************************
186 ********************************************************************/
188 WERROR
_winreg_OpenHKDD(pipes_struct
*p
, struct winreg_OpenHKDD
*r
)
190 return open_registry_key(p
, r
->out
.handle
, NULL
, KEY_HKDD
, r
->in
.access_mask
);
193 /*******************************************************************
195 ********************************************************************/
197 WERROR
_winreg_OpenHKPN(pipes_struct
*p
, struct winreg_OpenHKPN
*r
)
199 return open_registry_key(p
, r
->out
.handle
, NULL
, KEY_HKPN
, r
->in
.access_mask
);
202 /*******************************************************************
204 ********************************************************************/
206 WERROR
_winreg_OpenKey(pipes_struct
*p
, struct winreg_OpenKey
*r
)
208 struct registry_key
*parent
= find_regkey_by_hnd(p
, r
->in
.parent_handle
);
213 return open_registry_key(p
, r
->out
.handle
, parent
, r
->in
.keyname
.name
, r
->in
.access_mask
);
216 /*******************************************************************
218 ********************************************************************/
220 WERROR
_winreg_QueryValue(pipes_struct
*p
, struct winreg_QueryValue
*r
)
222 WERROR status
= WERR_BADFILE
;
223 struct registry_key
*regkey
= find_regkey_by_hnd( p
, r
->in
.handle
);
227 uint32_t outbuf_size
;
230 bool free_buf
= False
;
231 bool free_prs
= False
;
236 if (r
->in
.value_name
->name
== NULL
) {
237 return WERR_INVALID_PARAM
;
240 if ((r
->out
.data_length
== NULL
) || (r
->out
.type
== NULL
) || (r
->out
.data_size
== NULL
)) {
241 return WERR_INVALID_PARAM
;
244 DEBUG(7,("_winreg_QueryValue: policy key name = [%s]\n", regkey
->key
->name
));
245 DEBUG(7,("_winreg_QueryValue: policy key type = [%08x]\n", regkey
->key
->type
));
247 /* Handle QueryValue calls on HKEY_PERFORMANCE_DATA */
248 if(regkey
->key
->type
== REG_KEY_HKPD
)
250 if (strequal(r
->in
.value_name
->name
, "Global")) {
251 if (!prs_init(&prs_hkpd
, *r
->in
.data_size
, p
->mem_ctx
, MARSHALL
))
253 status
= reg_perfcount_get_hkpd(
254 &prs_hkpd
, *r
->in
.data_size
, &outbuf_size
, NULL
);
255 outbuf
= (uint8_t *)prs_hkpd
.data_p
;
258 else if (strequal(r
->in
.value_name
->name
, "Counter 009")) {
259 outbuf_size
= reg_perfcount_get_counter_names(
260 reg_perfcount_get_base_index(),
261 (char **)(void *)&outbuf
);
264 else if (strequal(r
->in
.value_name
->name
, "Explain 009")) {
265 outbuf_size
= reg_perfcount_get_counter_help(
266 reg_perfcount_get_base_index(),
267 (char **)(void *)&outbuf
);
270 else if (isdigit(r
->in
.value_name
->name
[0])) {
271 /* we probably have a request for a specific object
273 if (!prs_init(&prs_hkpd
, *r
->in
.data_size
, p
->mem_ctx
, MARSHALL
))
275 status
= reg_perfcount_get_hkpd(
276 &prs_hkpd
, *r
->in
.data_size
, &outbuf_size
,
277 r
->in
.value_name
->name
);
278 outbuf
= (uint8_t *)prs_hkpd
.data_p
;
282 DEBUG(3,("Unsupported key name [%s] for HKPD.\n",
283 r
->in
.value_name
->name
));
287 *r
->out
.type
= REG_BINARY
;
290 struct registry_value
*val
;
292 status
= reg_queryvalue(p
->mem_ctx
, regkey
, r
->in
.value_name
->name
,
294 if (!W_ERROR_IS_OK(status
)) {
296 DEBUG(10,("_winreg_QueryValue: reg_queryvalue failed with: %s\n",
297 win_errstr(status
)));
299 if (r
->out
.data_size
) {
300 *r
->out
.data_size
= 0;
302 if (r
->out
.data_length
) {
303 *r
->out
.data_length
= 0;
308 status
= registry_push_value(p
->mem_ctx
, val
, &val_blob
);
309 if (!W_ERROR_IS_OK(status
)) {
313 outbuf
= val_blob
.data
;
314 outbuf_size
= val_blob
.length
;
315 *r
->out
.type
= val
->type
;
318 status
= WERR_BADFILE
;
320 if (*r
->in
.data_size
< outbuf_size
) {
321 *r
->out
.data_size
= outbuf_size
;
322 status
= r
->in
.data
? WERR_MORE_DATA
: WERR_OK
;
324 *r
->out
.data_length
= outbuf_size
;
325 *r
->out
.data_size
= outbuf_size
;
327 memcpy(r
->out
.data
, outbuf
, outbuf_size
);
332 if (free_prs
) prs_mem_free(&prs_hkpd
);
333 if (free_buf
) SAFE_FREE(outbuf
);
338 /*****************************************************************************
340 ****************************************************************************/
342 WERROR
_winreg_QueryInfoKey(pipes_struct
*p
, struct winreg_QueryInfoKey
*r
)
344 WERROR status
= WERR_OK
;
345 struct registry_key
*regkey
= find_regkey_by_hnd( p
, r
->in
.handle
);
350 r
->out
.classname
->name
= NULL
;
352 status
= reg_queryinfokey(regkey
, r
->out
.num_subkeys
, r
->out
.max_subkeylen
,
353 r
->out
.max_classlen
, r
->out
.num_values
, r
->out
.max_valnamelen
,
354 r
->out
.max_valbufsize
, r
->out
.secdescsize
,
355 r
->out
.last_changed_time
);
356 if (!W_ERROR_IS_OK(status
)) {
361 * These calculations account for the registry buffers being
362 * UTF-16. They are inexact at best, but so far they worked.
365 *r
->out
.max_subkeylen
*= 2;
367 *r
->out
.max_valnamelen
+= 1;
368 *r
->out
.max_valnamelen
*= 2;
374 /*****************************************************************************
376 ****************************************************************************/
378 WERROR
_winreg_GetVersion(pipes_struct
*p
, struct winreg_GetVersion
*r
)
380 struct registry_key
*regkey
= find_regkey_by_hnd( p
, r
->in
.handle
);
385 return reg_getversion(r
->out
.version
);
389 /*****************************************************************************
391 ****************************************************************************/
393 WERROR
_winreg_EnumKey(pipes_struct
*p
, struct winreg_EnumKey
*r
)
396 struct registry_key
*key
= find_regkey_by_hnd( p
, r
->in
.handle
);
401 if ( !r
->in
.name
|| !r
->in
.keyclass
)
402 return WERR_INVALID_PARAM
;
404 DEBUG(8,("_winreg_EnumKey: enumerating key [%s]\n", key
->key
->name
));
406 err
= reg_enumkey(p
->mem_ctx
, key
, r
->in
.enum_index
, (char **)&r
->out
.name
->name
,
407 r
->out
.last_changed_time
);
408 if (!W_ERROR_IS_OK(err
)) {
411 r
->out
.keyclass
->name
= "";
415 /*****************************************************************************
417 ****************************************************************************/
419 WERROR
_winreg_EnumValue(pipes_struct
*p
, struct winreg_EnumValue
*r
)
422 struct registry_key
*key
= find_regkey_by_hnd( p
, r
->in
.handle
);
424 struct registry_value
*val
;
425 DATA_BLOB value_blob
;
431 return WERR_INVALID_PARAM
;
433 DEBUG(8,("_winreg_EnumValue: enumerating values for key [%s]\n",
436 err
= reg_enumvalue(p
->mem_ctx
, key
, r
->in
.enum_index
, &valname
, &val
);
437 if (!W_ERROR_IS_OK(err
)) {
441 err
= registry_push_value(p
->mem_ctx
, val
, &value_blob
);
442 if (!W_ERROR_IS_OK(err
)) {
446 if (r
->out
.name
!= NULL
) {
447 r
->out
.name
->name
= valname
;
450 if (r
->out
.type
!= NULL
) {
451 *r
->out
.type
= val
->type
;
454 if (r
->out
.value
!= NULL
) {
455 if ((r
->out
.size
== NULL
) || (r
->out
.length
== NULL
)) {
456 return WERR_INVALID_PARAM
;
459 if (value_blob
.length
> *r
->out
.size
) {
460 return WERR_MORE_DATA
;
463 memcpy( r
->out
.value
, value_blob
.data
, value_blob
.length
);
466 if (r
->out
.length
!= NULL
) {
467 *r
->out
.length
= value_blob
.length
;
469 if (r
->out
.size
!= NULL
) {
470 *r
->out
.size
= value_blob
.length
;
476 /*******************************************************************
477 _winreg_InitiateSystemShutdown
478 ********************************************************************/
480 WERROR
_winreg_InitiateSystemShutdown(pipes_struct
*p
, struct winreg_InitiateSystemShutdown
*r
)
482 struct winreg_InitiateSystemShutdownEx s
;
484 s
.in
.hostname
= r
->in
.hostname
;
485 s
.in
.message
= r
->in
.message
;
486 s
.in
.timeout
= r
->in
.timeout
;
487 s
.in
.force_apps
= r
->in
.force_apps
;
488 s
.in
.do_reboot
= r
->in
.do_reboot
;
491 /* thunk down to _winreg_InitiateSystemShutdownEx()
492 (just returns a status) */
494 return _winreg_InitiateSystemShutdownEx( p
, &s
);
497 /*******************************************************************
498 _winreg_InitiateSystemShutdownEx
499 ********************************************************************/
501 #define SHUTDOWN_R_STRING "-r"
502 #define SHUTDOWN_F_STRING "-f"
505 WERROR
_winreg_InitiateSystemShutdownEx(pipes_struct
*p
, struct winreg_InitiateSystemShutdownEx
*r
)
507 char *shutdown_script
= NULL
;
517 shutdown_script
= talloc_strdup(p
->mem_ctx
, lp_shutdown_script());
518 if (!shutdown_script
) {
521 if (!*shutdown_script
) {
522 return WERR_ACCESS_DENIED
;
525 /* pull the message string and perform necessary sanity checks on it */
527 if ( r
->in
.message
&& r
->in
.message
->string
) {
528 if ( (msg
= talloc_strdup(p
->mem_ctx
, r
->in
.message
->string
)) == NULL
) {
531 chkmsg
= TALLOC_ARRAY(p
->mem_ctx
, char, strlen(msg
)+1);
535 alpha_strcpy(chkmsg
, msg
, NULL
, strlen(msg
)+1);
538 fstr_sprintf(str_timeout
, "%d", r
->in
.timeout
);
539 fstr_sprintf(do_reboot
, r
->in
.do_reboot
? SHUTDOWN_R_STRING
: "");
540 fstr_sprintf(f
, r
->in
.force_apps
? SHUTDOWN_F_STRING
: "");
541 fstr_sprintf(str_reason
, "%d", r
->in
.reason
);
543 shutdown_script
= talloc_all_string_sub(p
->mem_ctx
,
544 shutdown_script
, "%z", chkmsg
? chkmsg
: "");
545 if (!shutdown_script
) {
548 shutdown_script
= talloc_all_string_sub(p
->mem_ctx
,
549 shutdown_script
, "%t", str_timeout
);
550 if (!shutdown_script
) {
553 shutdown_script
= talloc_all_string_sub(p
->mem_ctx
,
554 shutdown_script
, "%r", do_reboot
);
555 if (!shutdown_script
) {
558 shutdown_script
= talloc_all_string_sub(p
->mem_ctx
,
559 shutdown_script
, "%f", f
);
560 if (!shutdown_script
) {
563 shutdown_script
= talloc_all_string_sub(p
->mem_ctx
,
564 shutdown_script
, "%x", str_reason
);
565 if (!shutdown_script
) {
569 can_shutdown
= user_has_privileges( p
->server_info
->ptok
,
570 &se_remote_shutdown
);
572 /* IF someone has privs, run the shutdown script as root. OTHERWISE run it as not root
573 Take the error return from the script and provide it as the Windows return code. */
575 /********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/
580 ret
= smbrun( shutdown_script
, NULL
);
585 /********** END SeRemoteShutdownPrivilege BLOCK **********/
587 DEBUG(3,("_reg_shutdown_ex: Running the command `%s' gave %d\n",
588 shutdown_script
, ret
));
590 return (ret
== 0) ? WERR_OK
: WERR_ACCESS_DENIED
;
593 /*******************************************************************
594 _winreg_AbortSystemShutdown
595 ********************************************************************/
597 WERROR
_winreg_AbortSystemShutdown(pipes_struct
*p
, struct winreg_AbortSystemShutdown
*r
)
599 const char *abort_shutdown_script
;
603 abort_shutdown_script
= lp_abort_shutdown_script();
605 if (!*abort_shutdown_script
)
606 return WERR_ACCESS_DENIED
;
608 can_shutdown
= user_has_privileges( p
->server_info
->ptok
,
609 &se_remote_shutdown
);
611 /********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/
616 ret
= smbrun( abort_shutdown_script
, NULL
);
621 /********** END SeRemoteShutdownPrivilege BLOCK **********/
623 DEBUG(3,("_winreg_AbortSystemShutdown: Running the command `%s' gave %d\n",
624 abort_shutdown_script
, ret
));
626 return (ret
== 0) ? WERR_OK
: WERR_ACCESS_DENIED
;
629 /*******************************************************************
630 ********************************************************************/
632 static int validate_reg_filename(TALLOC_CTX
*ctx
, char **pp_fname
)
635 int num_services
= lp_numservices();
637 const char *share_path
;
638 char *fname
= *pp_fname
;
640 /* convert to a unix path, stripping the C:\ along the way */
642 if (!(p
= valid_share_pathname(ctx
, fname
))) {
646 /* has to exist within a valid file share */
648 for (snum
=0; snum
<num_services
; snum
++) {
649 if (!lp_snum_ok(snum
) || lp_print_ok(snum
)) {
653 share_path
= lp_pathname(snum
);
655 /* make sure we have a path (e.g. [homes] ) */
656 if (strlen(share_path
) == 0) {
660 if (strncmp(share_path
, p
, strlen(share_path
)) == 0) {
666 return (snum
< num_services
) ? snum
: -1;
669 /*******************************************************************
671 ********************************************************************/
673 WERROR
_winreg_RestoreKey(pipes_struct
*p
, struct winreg_RestoreKey
*r
)
675 struct registry_key
*regkey
= find_regkey_by_hnd( p
, r
->in
.handle
);
682 if ( !r
->in
.filename
|| !r
->in
.filename
->name
)
683 return WERR_INVALID_PARAM
;
685 fname
= talloc_strdup(p
->mem_ctx
, r
->in
.filename
->name
);
690 DEBUG(8,("_winreg_RestoreKey: verifying restore of key [%s] from "
691 "\"%s\"\n", regkey
->key
->name
, fname
));
693 if ((snum
= validate_reg_filename(p
->mem_ctx
, &fname
)) == -1)
694 return WERR_OBJECT_PATH_INVALID
;
696 /* user must posses SeRestorePrivilege for this this proceed */
698 if ( !user_has_privileges( p
->server_info
->ptok
, &se_restore
) )
699 return WERR_ACCESS_DENIED
;
701 DEBUG(2,("_winreg_RestoreKey: Restoring [%s] from %s in share %s\n",
702 regkey
->key
->name
, fname
, lp_servicename(snum
) ));
704 return reg_restorekey(regkey
, fname
);
707 /*******************************************************************
709 ********************************************************************/
711 WERROR
_winreg_SaveKey(pipes_struct
*p
, struct winreg_SaveKey
*r
)
713 struct registry_key
*regkey
= find_regkey_by_hnd( p
, r
->in
.handle
);
720 if ( !r
->in
.filename
|| !r
->in
.filename
->name
)
721 return WERR_INVALID_PARAM
;
723 fname
= talloc_strdup(p
->mem_ctx
, r
->in
.filename
->name
);
728 DEBUG(8,("_winreg_SaveKey: verifying backup of key [%s] to \"%s\"\n",
729 regkey
->key
->name
, fname
));
731 if ((snum
= validate_reg_filename(p
->mem_ctx
, &fname
)) == -1 )
732 return WERR_OBJECT_PATH_INVALID
;
734 DEBUG(2,("_winreg_SaveKey: Saving [%s] to %s in share %s\n",
735 regkey
->key
->name
, fname
, lp_servicename(snum
) ));
737 return reg_savekey(regkey
, fname
);
740 /*******************************************************************
742 ********************************************************************/
744 WERROR
_winreg_SaveKeyEx(pipes_struct
*p
, struct winreg_SaveKeyEx
*r
)
746 /* fill in your code here if you think this call should
749 p
->rng_fault_state
= True
;
750 return WERR_NOT_SUPPORTED
;
753 /*******************************************************************
755 ********************************************************************/
757 WERROR
_winreg_CreateKey( pipes_struct
*p
, struct winreg_CreateKey
*r
)
759 struct registry_key
*parent
= find_regkey_by_hnd(p
, r
->in
.handle
);
760 struct registry_key
*new_key
;
766 DEBUG(10, ("_winreg_CreateKey called with parent key '%s' and "
767 "subkey name '%s'\n", parent
->key
->name
, r
->in
.name
.name
));
769 result
= reg_createkey(NULL
, parent
, r
->in
.name
.name
, r
->in
.access_mask
,
770 &new_key
, r
->out
.action_taken
);
771 if (!W_ERROR_IS_OK(result
)) {
775 if (!create_policy_hnd(p
, r
->out
.new_handle
, new_key
)) {
776 TALLOC_FREE(new_key
);
783 /*******************************************************************
785 ********************************************************************/
787 WERROR
_winreg_SetValue(pipes_struct
*p
, struct winreg_SetValue
*r
)
789 struct registry_key
*key
= find_regkey_by_hnd(p
, r
->in
.handle
);
790 struct registry_value
*val
;
796 DEBUG(8,("_winreg_SetValue: Setting value for [%s:%s]\n",
797 key
->key
->name
, r
->in
.name
.name
));
799 status
= registry_pull_value(p
->mem_ctx
, &val
, r
->in
.type
, r
->in
.data
,
800 r
->in
.size
, r
->in
.size
);
801 if (!W_ERROR_IS_OK(status
)) {
805 return reg_setvalue(key
, r
->in
.name
.name
, val
);
808 /*******************************************************************
810 ********************************************************************/
812 WERROR
_winreg_DeleteKey(pipes_struct
*p
, struct winreg_DeleteKey
*r
)
814 struct registry_key
*parent
= find_regkey_by_hnd(p
, r
->in
.handle
);
819 return reg_deletekey(parent
, r
->in
.key
.name
);
823 /*******************************************************************
825 ********************************************************************/
827 WERROR
_winreg_DeleteValue(pipes_struct
*p
, struct winreg_DeleteValue
*r
)
829 struct registry_key
*key
= find_regkey_by_hnd(p
, r
->in
.handle
);
834 return reg_deletevalue(key
, r
->in
.value
.name
);
837 /*******************************************************************
838 _winreg_GetKeySecurity
839 ********************************************************************/
841 WERROR
_winreg_GetKeySecurity(pipes_struct
*p
, struct winreg_GetKeySecurity
*r
)
843 struct registry_key
*key
= find_regkey_by_hnd(p
, r
->in
.handle
);
845 struct security_descriptor
*secdesc
;
852 /* access checks first */
854 if ( !(key
->key
->access_granted
& SEC_STD_READ_CONTROL
) )
855 return WERR_ACCESS_DENIED
;
857 err
= reg_getkeysecurity(p
->mem_ctx
, key
, &secdesc
);
858 if (!W_ERROR_IS_OK(err
)) {
862 err
= ntstatus_to_werror(marshall_sec_desc(p
->mem_ctx
, secdesc
,
864 if (!W_ERROR_IS_OK(err
)) {
868 if (len
> r
->out
.sd
->size
) {
869 r
->out
.sd
->size
= len
;
870 return WERR_INSUFFICIENT_BUFFER
;
873 r
->out
.sd
->size
= len
;
874 r
->out
.sd
->len
= len
;
875 r
->out
.sd
->data
= data
;
880 /*******************************************************************
881 _winreg_SetKeySecurity
882 ********************************************************************/
884 WERROR
_winreg_SetKeySecurity(pipes_struct
*p
, struct winreg_SetKeySecurity
*r
)
886 struct registry_key
*key
= find_regkey_by_hnd(p
, r
->in
.handle
);
887 struct security_descriptor
*secdesc
;
893 /* access checks first */
895 if ( !(key
->key
->access_granted
& SEC_STD_WRITE_DAC
) )
896 return WERR_ACCESS_DENIED
;
898 err
= ntstatus_to_werror(unmarshall_sec_desc(p
->mem_ctx
, r
->in
.sd
->data
,
899 r
->in
.sd
->len
, &secdesc
));
900 if (!W_ERROR_IS_OK(err
)) {
904 return reg_setkeysecurity(key
, secdesc
);
907 /*******************************************************************
909 ********************************************************************/
911 WERROR
_winreg_FlushKey(pipes_struct
*p
, struct winreg_FlushKey
*r
)
913 /* I'm just replying OK because there's not a lot
914 here I see to do i --jerry */
919 /*******************************************************************
921 ********************************************************************/
923 WERROR
_winreg_UnLoadKey(pipes_struct
*p
, struct winreg_UnLoadKey
*r
)
925 /* fill in your code here if you think this call should
928 p
->rng_fault_state
= True
;
929 return WERR_NOT_SUPPORTED
;
932 /*******************************************************************
934 ********************************************************************/
936 WERROR
_winreg_ReplaceKey(pipes_struct
*p
, struct winreg_ReplaceKey
*r
)
938 /* fill in your code here if you think this call should
941 p
->rng_fault_state
= True
;
942 return WERR_NOT_SUPPORTED
;
945 /*******************************************************************
947 ********************************************************************/
949 WERROR
_winreg_LoadKey(pipes_struct
*p
, struct winreg_LoadKey
*r
)
951 /* fill in your code here if you think this call should
954 p
->rng_fault_state
= True
;
955 return WERR_NOT_SUPPORTED
;
958 /*******************************************************************
959 _winreg_NotifyChangeKeyValue
960 ********************************************************************/
962 WERROR
_winreg_NotifyChangeKeyValue(pipes_struct
*p
, struct winreg_NotifyChangeKeyValue
*r
)
964 return WERR_NOT_SUPPORTED
;
967 /*******************************************************************
968 _winreg_QueryMultipleValues
969 ********************************************************************/
971 WERROR
_winreg_QueryMultipleValues(pipes_struct
*p
, struct winreg_QueryMultipleValues
*r
)
973 /* fill in your code here if you think this call should
976 p
->rng_fault_state
= True
;
977 return WERR_NOT_SUPPORTED
;
980 /*******************************************************************
981 _winreg_QueryMultipleValues2
982 ********************************************************************/
984 WERROR
_winreg_QueryMultipleValues2(pipes_struct
*p
, struct winreg_QueryMultipleValues2
*r
)
986 /* fill in your code here if you think this call should
989 p
->rng_fault_state
= True
;
990 return WERR_NOT_SUPPORTED
;
993 /*******************************************************************
995 ********************************************************************/
997 WERROR
_winreg_DeleteKeyEx(pipes_struct
*p
, struct winreg_DeleteKeyEx
*r
)
999 /* fill in your code here if you think this call should
1002 p
->rng_fault_state
= True
;
1003 return WERR_NOT_SUPPORTED
;