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