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