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 if ((r
->out
.value_length
== NULL
) || (r
->out
.type
== NULL
)) {
234 return WERR_INVALID_PARAM
;
237 *r
->out
.value_length
= *r
->out
.type
= REG_NONE
;
239 DEBUG(7,("_reg_info: policy key name = [%s]\n", regkey
->key
->name
));
240 DEBUG(7,("_reg_info: policy key type = [%08x]\n", regkey
->key
->type
));
242 /* Handle QueryValue calls on HKEY_PERFORMANCE_DATA */
243 if(regkey
->key
->type
== REG_KEY_HKPD
)
245 if (strequal(r
->in
.value_name
->name
, "Global")) {
246 if (!prs_init(&prs_hkpd
, *r
->in
.data_size
, p
->mem_ctx
, MARSHALL
))
248 status
= reg_perfcount_get_hkpd(
249 &prs_hkpd
, *r
->in
.data_size
, &outbuf_size
, NULL
);
250 outbuf
= (uint8_t *)prs_hkpd
.data_p
;
253 else if (strequal(r
->in
.value_name
->name
, "Counter 009")) {
254 outbuf_size
= reg_perfcount_get_counter_names(
255 reg_perfcount_get_base_index(),
256 (char **)(void *)&outbuf
);
259 else if (strequal(r
->in
.value_name
->name
, "Explain 009")) {
260 outbuf_size
= reg_perfcount_get_counter_help(
261 reg_perfcount_get_base_index(),
262 (char **)(void *)&outbuf
);
265 else if (isdigit(r
->in
.value_name
->name
[0])) {
266 /* we probably have a request for a specific object
268 if (!prs_init(&prs_hkpd
, *r
->in
.data_size
, p
->mem_ctx
, MARSHALL
))
270 status
= reg_perfcount_get_hkpd(
271 &prs_hkpd
, *r
->in
.data_size
, &outbuf_size
,
272 r
->in
.value_name
->name
);
273 outbuf
= (uint8_t *)prs_hkpd
.data_p
;
277 DEBUG(3,("Unsupported key name [%s] for HKPD.\n",
278 r
->in
.value_name
->name
));
282 *r
->out
.type
= REG_BINARY
;
285 struct registry_value
*val
;
287 status
= reg_queryvalue(p
->mem_ctx
, regkey
, r
->in
.value_name
->name
,
289 if (!W_ERROR_IS_OK(status
)) {
290 if (r
->out
.data_size
) {
291 *r
->out
.data_size
= 0;
293 if (r
->out
.value_length
) {
294 *r
->out
.value_length
= 0;
299 status
= registry_push_value(p
->mem_ctx
, val
, &val_blob
);
300 if (!W_ERROR_IS_OK(status
)) {
304 outbuf
= val_blob
.data
;
305 outbuf_size
= val_blob
.length
;
306 *r
->out
.type
= val
->type
;
309 *r
->out
.value_length
= outbuf_size
;
311 if ( *r
->in
.data_size
== 0 || !r
->out
.data
) {
313 } else if ( *r
->out
.value_length
> *r
->in
.data_size
) {
314 status
= WERR_MORE_DATA
;
316 memcpy( r
->out
.data
, outbuf
, *r
->out
.value_length
);
320 *r
->out
.data_size
= *r
->out
.value_length
;
322 if (free_prs
) prs_mem_free(&prs_hkpd
);
323 if (free_buf
) SAFE_FREE(outbuf
);
328 /*****************************************************************************
329 Implementation of REG_QUERY_KEY
330 ****************************************************************************/
332 WERROR
_winreg_QueryInfoKey(pipes_struct
*p
, struct winreg_QueryInfoKey
*r
)
334 WERROR status
= WERR_OK
;
335 struct registry_key
*regkey
= find_regkey_by_hnd( p
, r
->in
.handle
);
340 r
->out
.classname
->name
= NULL
;
342 status
= reg_queryinfokey(regkey
, r
->out
.num_subkeys
, r
->out
.max_subkeylen
,
343 r
->out
.max_classlen
, r
->out
.num_values
, r
->out
.max_valnamelen
,
344 r
->out
.max_valbufsize
, r
->out
.secdescsize
,
345 r
->out
.last_changed_time
);
346 if (!W_ERROR_IS_OK(status
)) {
351 * These calculations account for the registry buffers being
352 * UTF-16. They are inexact at best, but so far they worked.
355 *r
->out
.max_subkeylen
*= 2;
357 *r
->out
.max_valnamelen
+= 1;
358 *r
->out
.max_valnamelen
*= 2;
364 /*****************************************************************************
365 Implementation of REG_GETVERSION
366 ****************************************************************************/
368 WERROR
_winreg_GetVersion(pipes_struct
*p
, struct winreg_GetVersion
*r
)
370 struct registry_key
*regkey
= find_regkey_by_hnd( p
, r
->in
.handle
);
375 return reg_getversion(r
->out
.version
);
379 /*****************************************************************************
380 Implementation of REG_ENUM_KEY
381 ****************************************************************************/
383 WERROR
_winreg_EnumKey(pipes_struct
*p
, struct winreg_EnumKey
*r
)
386 struct registry_key
*key
= find_regkey_by_hnd( p
, r
->in
.handle
);
391 if ( !r
->in
.name
|| !r
->in
.keyclass
)
392 return WERR_INVALID_PARAM
;
394 DEBUG(8,("_reg_enum_key: enumerating key [%s]\n", key
->key
->name
));
396 err
= reg_enumkey(p
->mem_ctx
, key
, r
->in
.enum_index
, (char **)&r
->out
.name
->name
,
397 r
->out
.last_changed_time
);
398 if (!W_ERROR_IS_OK(err
)) {
401 r
->out
.keyclass
->name
= "";
405 /*****************************************************************************
406 Implementation of REG_ENUM_VALUE
407 ****************************************************************************/
409 WERROR
_winreg_EnumValue(pipes_struct
*p
, struct winreg_EnumValue
*r
)
412 struct registry_key
*key
= find_regkey_by_hnd( p
, r
->in
.handle
);
414 struct registry_value
*val
;
415 DATA_BLOB value_blob
;
421 return WERR_INVALID_PARAM
;
423 DEBUG(8,("_winreg_EnumValue: enumerating values for key [%s]\n",
426 err
= reg_enumvalue(p
->mem_ctx
, key
, r
->in
.enum_index
, &valname
, &val
);
427 if (!W_ERROR_IS_OK(err
)) {
431 err
= registry_push_value(p
->mem_ctx
, val
, &value_blob
);
432 if (!W_ERROR_IS_OK(err
)) {
436 if (r
->out
.name
!= NULL
) {
437 r
->out
.name
->name
= valname
;
440 if (r
->out
.type
!= NULL
) {
441 *r
->out
.type
= val
->type
;
444 if (r
->out
.value
!= NULL
) {
445 if ((r
->out
.size
== NULL
) || (r
->out
.length
== NULL
)) {
446 return WERR_INVALID_PARAM
;
449 if (value_blob
.length
> *r
->out
.size
) {
450 return WERR_MORE_DATA
;
453 memcpy( r
->out
.value
, value_blob
.data
, value_blob
.length
);
456 if (r
->out
.length
!= NULL
) {
457 *r
->out
.length
= value_blob
.length
;
459 if (r
->out
.size
!= NULL
) {
460 *r
->out
.size
= value_blob
.length
;
466 /*******************************************************************
468 ********************************************************************/
470 WERROR
_winreg_InitiateSystemShutdown(pipes_struct
*p
, struct winreg_InitiateSystemShutdown
*r
)
472 struct winreg_InitiateSystemShutdownEx s
;
474 s
.in
.hostname
= r
->in
.hostname
;
475 s
.in
.message
= r
->in
.message
;
476 s
.in
.timeout
= r
->in
.timeout
;
477 s
.in
.force_apps
= r
->in
.force_apps
;
478 s
.in
.do_reboot
= r
->in
.do_reboot
;
481 /* thunk down to _winreg_InitiateSystemShutdownEx()
482 (just returns a status) */
484 return _winreg_InitiateSystemShutdownEx( p
, &s
);
487 /*******************************************************************
489 ********************************************************************/
491 #define SHUTDOWN_R_STRING "-r"
492 #define SHUTDOWN_F_STRING "-f"
495 WERROR
_winreg_InitiateSystemShutdownEx(pipes_struct
*p
, struct winreg_InitiateSystemShutdownEx
*r
)
497 char *shutdown_script
= NULL
;
507 shutdown_script
= talloc_strdup(p
->mem_ctx
, lp_shutdown_script());
508 if (!shutdown_script
) {
511 if (!*shutdown_script
) {
512 return WERR_ACCESS_DENIED
;
515 /* pull the message string and perform necessary sanity checks on it */
517 if ( r
->in
.message
&& r
->in
.message
->name
&& r
->in
.message
->name
->name
) {
518 if ( (msg
= talloc_strdup(p
->mem_ctx
, r
->in
.message
->name
->name
)) == NULL
) {
521 chkmsg
= TALLOC_ARRAY(p
->mem_ctx
, char, strlen(msg
)+1);
525 alpha_strcpy(chkmsg
, msg
, NULL
, strlen(msg
)+1);
528 fstr_sprintf(str_timeout
, "%d", r
->in
.timeout
);
529 fstr_sprintf(do_reboot
, r
->in
.do_reboot
? SHUTDOWN_R_STRING
: "");
530 fstr_sprintf(f
, r
->in
.force_apps
? SHUTDOWN_F_STRING
: "");
531 fstr_sprintf(str_reason
, "%d", r
->in
.reason
);
533 shutdown_script
= talloc_all_string_sub(p
->mem_ctx
,
534 shutdown_script
, "%z", chkmsg
? chkmsg
: "");
535 if (!shutdown_script
) {
538 shutdown_script
= talloc_all_string_sub(p
->mem_ctx
,
539 shutdown_script
, "%t", str_timeout
);
540 if (!shutdown_script
) {
543 shutdown_script
= talloc_all_string_sub(p
->mem_ctx
,
544 shutdown_script
, "%r", do_reboot
);
545 if (!shutdown_script
) {
548 shutdown_script
= talloc_all_string_sub(p
->mem_ctx
,
549 shutdown_script
, "%f", f
);
550 if (!shutdown_script
) {
553 shutdown_script
= talloc_all_string_sub(p
->mem_ctx
,
554 shutdown_script
, "%x", str_reason
);
555 if (!shutdown_script
) {
559 can_shutdown
= user_has_privileges( p
->pipe_user
.nt_user_token
, &se_remote_shutdown
);
561 /* IF someone has privs, run the shutdown script as root. OTHERWISE run it as not root
562 Take the error return from the script and provide it as the Windows return code. */
564 /********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/
569 ret
= smbrun( shutdown_script
, NULL
);
574 /********** END SeRemoteShutdownPrivilege BLOCK **********/
576 DEBUG(3,("_reg_shutdown_ex: Running the command `%s' gave %d\n",
577 shutdown_script
, ret
));
579 return (ret
== 0) ? WERR_OK
: WERR_ACCESS_DENIED
;
582 /*******************************************************************
584 ********************************************************************/
586 WERROR
_winreg_AbortSystemShutdown(pipes_struct
*p
, struct winreg_AbortSystemShutdown
*r
)
588 const char *abort_shutdown_script
;
592 abort_shutdown_script
= lp_abort_shutdown_script();
594 if (!*abort_shutdown_script
)
595 return WERR_ACCESS_DENIED
;
597 can_shutdown
= user_has_privileges( p
->pipe_user
.nt_user_token
, &se_remote_shutdown
);
599 /********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/
604 ret
= smbrun( abort_shutdown_script
, NULL
);
609 /********** END SeRemoteShutdownPrivilege BLOCK **********/
611 DEBUG(3,("_reg_abort_shutdown: Running the command `%s' gave %d\n",
612 abort_shutdown_script
, ret
));
614 return (ret
== 0) ? WERR_OK
: WERR_ACCESS_DENIED
;
617 /*******************************************************************
618 ********************************************************************/
620 static int validate_reg_filename(TALLOC_CTX
*ctx
, char **pp_fname
)
623 int num_services
= lp_numservices();
625 const char *share_path
;
626 char *fname
= *pp_fname
;
628 /* convert to a unix path, stripping the C:\ along the way */
630 if (!(p
= valid_share_pathname(ctx
, fname
))) {
634 /* has to exist within a valid file share */
636 for (snum
=0; snum
<num_services
; snum
++) {
637 if (!lp_snum_ok(snum
) || lp_print_ok(snum
)) {
641 share_path
= lp_pathname(snum
);
643 /* make sure we have a path (e.g. [homes] ) */
644 if (strlen(share_path
) == 0) {
648 if (strncmp(share_path
, p
, strlen(share_path
)) == 0) {
654 return (snum
< num_services
) ? snum
: -1;
657 /*******************************************************************
658 ********************************************************************/
660 WERROR
_winreg_RestoreKey(pipes_struct
*p
, struct winreg_RestoreKey
*r
)
662 struct registry_key
*regkey
= find_regkey_by_hnd( p
, r
->in
.handle
);
669 if ( !r
->in
.filename
|| !r
->in
.filename
->name
)
670 return WERR_INVALID_PARAM
;
672 fname
= talloc_strdup(p
->mem_ctx
, r
->in
.filename
->name
);
677 DEBUG(8,("_winreg_RestoreKey: verifying restore of key [%s] from "
678 "\"%s\"\n", regkey
->key
->name
, fname
));
680 if ((snum
= validate_reg_filename(p
->mem_ctx
, &fname
)) == -1)
681 return WERR_OBJECT_PATH_INVALID
;
683 /* user must posses SeRestorePrivilege for this this proceed */
685 if ( !user_has_privileges( p
->pipe_user
.nt_user_token
, &se_restore
) )
686 return WERR_ACCESS_DENIED
;
688 DEBUG(2,("_winreg_RestoreKey: Restoring [%s] from %s in share %s\n",
689 regkey
->key
->name
, fname
, lp_servicename(snum
) ));
691 return reg_restorekey(regkey
, fname
);
694 WERROR
_winreg_SaveKey(pipes_struct
*p
, struct winreg_SaveKey
*r
)
696 struct registry_key
*regkey
= find_regkey_by_hnd( p
, r
->in
.handle
);
703 if ( !r
->in
.filename
|| !r
->in
.filename
->name
)
704 return WERR_INVALID_PARAM
;
706 fname
= talloc_strdup(p
->mem_ctx
, r
->in
.filename
->name
);
711 DEBUG(8,("_winreg_SaveKey: verifying backup of key [%s] to \"%s\"\n",
712 regkey
->key
->name
, fname
));
714 if ((snum
= validate_reg_filename(p
->mem_ctx
, &fname
)) == -1 )
715 return WERR_OBJECT_PATH_INVALID
;
717 DEBUG(2,("_winreg_SaveKey: Saving [%s] to %s in share %s\n",
718 regkey
->key
->name
, fname
, lp_servicename(snum
) ));
720 return reg_savekey(regkey
, fname
);
723 /*******************************************************************
724 ********************************************************************/
726 WERROR
_winreg_SaveKeyEx(pipes_struct
*p
, struct winreg_SaveKeyEx
*r
)
728 /* fill in your code here if you think this call should
731 p
->rng_fault_state
= True
;
732 return WERR_NOT_SUPPORTED
;
735 /*******************************************************************
736 ********************************************************************/
738 WERROR
_winreg_CreateKey( pipes_struct
*p
, struct winreg_CreateKey
*r
)
740 struct registry_key
*parent
= find_regkey_by_hnd(p
, r
->in
.handle
);
741 struct registry_key
*new_key
;
747 DEBUG(10, ("_winreg_CreateKey called with parent key '%s' and "
748 "subkey name '%s'\n", parent
->key
->name
, r
->in
.name
.name
));
750 result
= reg_createkey(NULL
, parent
, r
->in
.name
.name
, r
->in
.access_mask
,
751 &new_key
, r
->out
.action_taken
);
752 if (!W_ERROR_IS_OK(result
)) {
756 if (!create_policy_hnd(p
, r
->out
.new_handle
, free_regkey
, new_key
)) {
757 TALLOC_FREE(new_key
);
764 /*******************************************************************
765 ********************************************************************/
767 WERROR
_winreg_SetValue(pipes_struct
*p
, struct winreg_SetValue
*r
)
769 struct registry_key
*key
= find_regkey_by_hnd(p
, r
->in
.handle
);
770 struct registry_value
*val
;
776 DEBUG(8,("_reg_set_value: Setting value for [%s:%s]\n",
777 key
->key
->name
, r
->in
.name
.name
));
779 status
= registry_pull_value(p
->mem_ctx
, &val
, r
->in
.type
, r
->in
.data
,
780 r
->in
.size
, r
->in
.size
);
781 if (!W_ERROR_IS_OK(status
)) {
785 return reg_setvalue(key
, r
->in
.name
.name
, val
);
788 /*******************************************************************
789 ********************************************************************/
791 WERROR
_winreg_DeleteKey(pipes_struct
*p
, struct winreg_DeleteKey
*r
)
793 struct registry_key
*parent
= find_regkey_by_hnd(p
, r
->in
.handle
);
798 return reg_deletekey(parent
, r
->in
.key
.name
);
802 /*******************************************************************
803 ********************************************************************/
805 WERROR
_winreg_DeleteValue(pipes_struct
*p
, struct winreg_DeleteValue
*r
)
807 struct registry_key
*key
= find_regkey_by_hnd(p
, r
->in
.handle
);
812 return reg_deletevalue(key
, r
->in
.value
.name
);
815 /*******************************************************************
816 ********************************************************************/
818 WERROR
_winreg_GetKeySecurity(pipes_struct
*p
, struct winreg_GetKeySecurity
*r
)
820 struct registry_key
*key
= find_regkey_by_hnd(p
, r
->in
.handle
);
822 struct security_descriptor
*secdesc
;
829 /* access checks first */
831 if ( !(key
->key
->access_granted
& STD_RIGHT_READ_CONTROL_ACCESS
) )
832 return WERR_ACCESS_DENIED
;
834 err
= reg_getkeysecurity(p
->mem_ctx
, key
, &secdesc
);
835 if (!W_ERROR_IS_OK(err
)) {
839 err
= ntstatus_to_werror(marshall_sec_desc(p
->mem_ctx
, secdesc
,
841 if (!W_ERROR_IS_OK(err
)) {
845 if (len
> r
->out
.sd
->size
) {
846 r
->out
.sd
->size
= len
;
847 return WERR_INSUFFICIENT_BUFFER
;
850 r
->out
.sd
->size
= len
;
851 r
->out
.sd
->len
= len
;
852 r
->out
.sd
->data
= data
;
857 /*******************************************************************
858 ********************************************************************/
860 WERROR
_winreg_SetKeySecurity(pipes_struct
*p
, struct winreg_SetKeySecurity
*r
)
862 struct registry_key
*key
= find_regkey_by_hnd(p
, r
->in
.handle
);
863 struct security_descriptor
*secdesc
;
869 /* access checks first */
871 if ( !(key
->key
->access_granted
& STD_RIGHT_WRITE_DAC_ACCESS
) )
872 return WERR_ACCESS_DENIED
;
874 err
= ntstatus_to_werror(unmarshall_sec_desc(p
->mem_ctx
, r
->in
.sd
->data
,
875 r
->in
.sd
->len
, &secdesc
));
876 if (!W_ERROR_IS_OK(err
)) {
880 return reg_setkeysecurity(key
, secdesc
);
883 /*******************************************************************
884 ********************************************************************/
886 WERROR
_winreg_FlushKey(pipes_struct
*p
, struct winreg_FlushKey
*r
)
888 /* I'm just replying OK because there's not a lot
889 here I see to do i --jerry */
894 /*******************************************************************
895 ********************************************************************/
897 WERROR
_winreg_UnLoadKey(pipes_struct
*p
, struct winreg_UnLoadKey
*r
)
899 /* fill in your code here if you think this call should
902 p
->rng_fault_state
= True
;
903 return WERR_NOT_SUPPORTED
;
906 /*******************************************************************
907 ********************************************************************/
909 WERROR
_winreg_ReplaceKey(pipes_struct
*p
, struct winreg_ReplaceKey
*r
)
911 /* fill in your code here if you think this call should
914 p
->rng_fault_state
= True
;
915 return WERR_NOT_SUPPORTED
;
918 /*******************************************************************
919 ********************************************************************/
921 WERROR
_winreg_LoadKey(pipes_struct
*p
, struct winreg_LoadKey
*r
)
923 /* fill in your code here if you think this call should
926 p
->rng_fault_state
= True
;
927 return WERR_NOT_SUPPORTED
;
930 /*******************************************************************
931 ********************************************************************/
933 WERROR
_winreg_NotifyChangeKeyValue(pipes_struct
*p
, struct winreg_NotifyChangeKeyValue
*r
)
935 /* fill in your code here if you think this call should
938 p
->rng_fault_state
= True
;
939 return WERR_NOT_SUPPORTED
;
942 /*******************************************************************
943 ********************************************************************/
945 WERROR
_winreg_QueryMultipleValues(pipes_struct
*p
, struct winreg_QueryMultipleValues
*r
)
947 /* fill in your code here if you think this call should
950 p
->rng_fault_state
= True
;
951 return WERR_NOT_SUPPORTED
;
954 /*******************************************************************
955 ********************************************************************/
957 WERROR
_winreg_QueryMultipleValues2(pipes_struct
*p
, struct winreg_QueryMultipleValues2
*r
)
959 /* fill in your code here if you think this call should
962 p
->rng_fault_state
= True
;
963 return WERR_NOT_SUPPORTED
;