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"
29 #define DBGC_CLASS DBGC_RPC_SRV
31 /******************************************************************
32 Find a registry key handle and return a struct registry_key *
33 *****************************************************************/
35 static struct registry_key
*find_regkey_by_hnd(pipes_struct
*p
,
36 struct policy_handle
*hnd
)
38 struct registry_key
*regkey
= NULL
;
40 if(!find_policy_by_hnd(p
,hnd
,(void **)(void *)®key
)) {
41 DEBUG(2,("find_regkey_index_by_hnd: Registry Key not found: "));
48 /*******************************************************************
49 Function for open a new registry handle and creating a handle
50 Note that P should be valid & hnd should already have space
52 When we open a key, we store the full path to the key as
53 HK[LM|U]\<key>\<key>\...
54 *******************************************************************/
56 static WERROR
open_registry_key( pipes_struct
*p
, struct policy_handle
*hnd
,
57 struct registry_key
*parent
,
58 const char *subkeyname
,
59 uint32 access_desired
)
61 WERROR result
= WERR_OK
;
62 struct registry_key
*key
;
65 result
= reg_openhive(p
->mem_ctx
, subkeyname
, access_desired
,
66 p
->server_info
->ptok
, &key
);
69 result
= reg_openkey(p
->mem_ctx
, parent
, subkeyname
,
70 access_desired
, &key
);
73 if ( !W_ERROR_IS_OK(result
) ) {
77 if ( !create_policy_hnd( p
, hnd
, key
) ) {
84 /*******************************************************************
85 Function for open a new registry handle and creating a handle
86 Note that P should be valid & hnd should already have space
87 *******************************************************************/
89 static bool close_registry_key(pipes_struct
*p
, struct policy_handle
*hnd
)
91 struct registry_key
*regkey
= find_regkey_by_hnd(p
, hnd
);
94 DEBUG(2,("close_registry_key: Invalid handle (%s:%u:%u)\n",
99 close_policy_hnd(p
, hnd
);
104 /********************************************************************
106 ********************************************************************/
108 WERROR
_winreg_CloseKey(pipes_struct
*p
, struct winreg_CloseKey
*r
)
110 /* close the policy handle */
112 if (!close_registry_key(p
, r
->in
.handle
))
115 ZERO_STRUCTP(r
->out
.handle
);
120 /*******************************************************************
122 ********************************************************************/
124 WERROR
_winreg_OpenHKLM(pipes_struct
*p
, struct winreg_OpenHKLM
*r
)
126 return open_registry_key(p
, r
->out
.handle
, NULL
, KEY_HKLM
, r
->in
.access_mask
);
129 /*******************************************************************
131 ********************************************************************/
133 WERROR
_winreg_OpenHKPD(pipes_struct
*p
, struct winreg_OpenHKPD
*r
)
135 return open_registry_key(p
, r
->out
.handle
, NULL
, KEY_HKPD
, r
->in
.access_mask
);
138 /*******************************************************************
140 ********************************************************************/
142 WERROR
_winreg_OpenHKPT(pipes_struct
*p
, struct winreg_OpenHKPT
*r
)
144 return open_registry_key(p
, r
->out
.handle
, NULL
, KEY_HKPT
, r
->in
.access_mask
);
147 /*******************************************************************
149 ********************************************************************/
151 WERROR
_winreg_OpenHKCR(pipes_struct
*p
, struct winreg_OpenHKCR
*r
)
153 return open_registry_key(p
, r
->out
.handle
, NULL
, KEY_HKCR
, r
->in
.access_mask
);
156 /*******************************************************************
158 ********************************************************************/
160 WERROR
_winreg_OpenHKU(pipes_struct
*p
, struct winreg_OpenHKU
*r
)
162 return open_registry_key(p
, r
->out
.handle
, NULL
, KEY_HKU
, r
->in
.access_mask
);
165 /*******************************************************************
167 ********************************************************************/
169 WERROR
_winreg_OpenHKCU(pipes_struct
*p
, struct winreg_OpenHKCU
*r
)
171 return open_registry_key(p
, r
->out
.handle
, NULL
, KEY_HKCU
, r
->in
.access_mask
);
174 /*******************************************************************
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 /*******************************************************************
185 ********************************************************************/
187 WERROR
_winreg_OpenHKDD(pipes_struct
*p
, struct winreg_OpenHKDD
*r
)
189 return open_registry_key(p
, r
->out
.handle
, NULL
, KEY_HKDD
, r
->in
.access_mask
);
192 /*******************************************************************
194 ********************************************************************/
196 WERROR
_winreg_OpenHKPN(pipes_struct
*p
, struct winreg_OpenHKPN
*r
)
198 return open_registry_key(p
, r
->out
.handle
, NULL
, KEY_HKPN
, r
->in
.access_mask
);
201 /*******************************************************************
203 ********************************************************************/
205 WERROR
_winreg_OpenKey(pipes_struct
*p
, struct winreg_OpenKey
*r
)
207 struct registry_key
*parent
= find_regkey_by_hnd(p
, r
->in
.parent_handle
);
212 return open_registry_key(p
, r
->out
.handle
, parent
, r
->in
.keyname
.name
, r
->in
.access_mask
);
215 /*******************************************************************
217 ********************************************************************/
219 WERROR
_winreg_QueryValue(pipes_struct
*p
, struct winreg_QueryValue
*r
)
221 WERROR status
= WERR_BADFILE
;
222 struct registry_key
*regkey
= find_regkey_by_hnd( p
, r
->in
.handle
);
226 uint32_t outbuf_size
;
229 bool free_buf
= False
;
230 bool free_prs
= False
;
235 if (r
->in
.value_name
->name
== NULL
) {
236 return WERR_INVALID_PARAM
;
239 if ((r
->out
.data_length
== NULL
) || (r
->out
.type
== NULL
) || (r
->out
.data_size
== NULL
)) {
240 return WERR_INVALID_PARAM
;
243 DEBUG(7,("_winreg_QueryValue: policy key name = [%s]\n", regkey
->key
->name
));
244 DEBUG(7,("_winreg_QueryValue: policy key type = [%08x]\n", regkey
->key
->type
));
246 /* Handle QueryValue calls on HKEY_PERFORMANCE_DATA */
247 if(regkey
->key
->type
== REG_KEY_HKPD
)
249 if (strequal(r
->in
.value_name
->name
, "Global")) {
250 if (!prs_init(&prs_hkpd
, *r
->in
.data_size
, p
->mem_ctx
, MARSHALL
))
252 status
= reg_perfcount_get_hkpd(
253 &prs_hkpd
, *r
->in
.data_size
, &outbuf_size
, NULL
);
254 outbuf
= (uint8_t *)prs_hkpd
.data_p
;
257 else if (strequal(r
->in
.value_name
->name
, "Counter 009")) {
258 outbuf_size
= reg_perfcount_get_counter_names(
259 reg_perfcount_get_base_index(),
260 (char **)(void *)&outbuf
);
263 else if (strequal(r
->in
.value_name
->name
, "Explain 009")) {
264 outbuf_size
= reg_perfcount_get_counter_help(
265 reg_perfcount_get_base_index(),
266 (char **)(void *)&outbuf
);
269 else if (isdigit(r
->in
.value_name
->name
[0])) {
270 /* we probably have a request for a specific object
272 if (!prs_init(&prs_hkpd
, *r
->in
.data_size
, p
->mem_ctx
, MARSHALL
))
274 status
= reg_perfcount_get_hkpd(
275 &prs_hkpd
, *r
->in
.data_size
, &outbuf_size
,
276 r
->in
.value_name
->name
);
277 outbuf
= (uint8_t *)prs_hkpd
.data_p
;
281 DEBUG(3,("Unsupported key name [%s] for HKPD.\n",
282 r
->in
.value_name
->name
));
286 *r
->out
.type
= REG_BINARY
;
289 struct registry_value
*val
;
291 status
= reg_queryvalue(p
->mem_ctx
, regkey
, r
->in
.value_name
->name
,
293 if (!W_ERROR_IS_OK(status
)) {
295 DEBUG(10,("_winreg_QueryValue: reg_queryvalue failed with: %s\n",
296 win_errstr(status
)));
298 if (r
->out
.data_size
) {
299 *r
->out
.data_size
= 0;
301 if (r
->out
.data_length
) {
302 *r
->out
.data_length
= 0;
307 status
= registry_push_value(p
->mem_ctx
, val
, &val_blob
);
308 if (!W_ERROR_IS_OK(status
)) {
312 outbuf
= val_blob
.data
;
313 outbuf_size
= val_blob
.length
;
314 *r
->out
.type
= val
->type
;
317 status
= WERR_BADFILE
;
319 if (*r
->in
.data_size
< outbuf_size
) {
320 *r
->out
.data_size
= outbuf_size
;
321 status
= r
->in
.data
? WERR_MORE_DATA
: WERR_OK
;
323 *r
->out
.data_length
= outbuf_size
;
324 *r
->out
.data_size
= outbuf_size
;
326 memcpy(r
->out
.data
, outbuf
, outbuf_size
);
331 if (free_prs
) prs_mem_free(&prs_hkpd
);
332 if (free_buf
) SAFE_FREE(outbuf
);
337 /*****************************************************************************
339 ****************************************************************************/
341 WERROR
_winreg_QueryInfoKey(pipes_struct
*p
, struct winreg_QueryInfoKey
*r
)
343 WERROR status
= WERR_OK
;
344 struct registry_key
*regkey
= find_regkey_by_hnd( p
, r
->in
.handle
);
349 r
->out
.classname
->name
= NULL
;
351 status
= reg_queryinfokey(regkey
, r
->out
.num_subkeys
, r
->out
.max_subkeylen
,
352 r
->out
.max_classlen
, r
->out
.num_values
, r
->out
.max_valnamelen
,
353 r
->out
.max_valbufsize
, r
->out
.secdescsize
,
354 r
->out
.last_changed_time
);
355 if (!W_ERROR_IS_OK(status
)) {
360 * These calculations account for the registry buffers being
361 * UTF-16. They are inexact at best, but so far they worked.
364 *r
->out
.max_subkeylen
*= 2;
366 *r
->out
.max_valnamelen
+= 1;
367 *r
->out
.max_valnamelen
*= 2;
373 /*****************************************************************************
375 ****************************************************************************/
377 WERROR
_winreg_GetVersion(pipes_struct
*p
, struct winreg_GetVersion
*r
)
379 struct registry_key
*regkey
= find_regkey_by_hnd( p
, r
->in
.handle
);
384 return reg_getversion(r
->out
.version
);
388 /*****************************************************************************
390 ****************************************************************************/
392 WERROR
_winreg_EnumKey(pipes_struct
*p
, struct winreg_EnumKey
*r
)
395 struct registry_key
*key
= find_regkey_by_hnd( p
, r
->in
.handle
);
400 if ( !r
->in
.name
|| !r
->in
.keyclass
)
401 return WERR_INVALID_PARAM
;
403 DEBUG(8,("_winreg_EnumKey: enumerating key [%s]\n", key
->key
->name
));
405 err
= reg_enumkey(p
->mem_ctx
, key
, r
->in
.enum_index
, (char **)&r
->out
.name
->name
,
406 r
->out
.last_changed_time
);
407 if (!W_ERROR_IS_OK(err
)) {
410 r
->out
.keyclass
->name
= "";
414 /*****************************************************************************
416 ****************************************************************************/
418 WERROR
_winreg_EnumValue(pipes_struct
*p
, struct winreg_EnumValue
*r
)
421 struct registry_key
*key
= find_regkey_by_hnd( p
, r
->in
.handle
);
423 struct registry_value
*val
;
424 DATA_BLOB value_blob
;
430 return WERR_INVALID_PARAM
;
432 DEBUG(8,("_winreg_EnumValue: enumerating values for key [%s]\n",
435 err
= reg_enumvalue(p
->mem_ctx
, key
, r
->in
.enum_index
, &valname
, &val
);
436 if (!W_ERROR_IS_OK(err
)) {
440 err
= registry_push_value(p
->mem_ctx
, val
, &value_blob
);
441 if (!W_ERROR_IS_OK(err
)) {
445 if (r
->out
.name
!= NULL
) {
446 r
->out
.name
->name
= valname
;
449 if (r
->out
.type
!= NULL
) {
450 *r
->out
.type
= val
->type
;
453 if (r
->out
.value
!= NULL
) {
454 if ((r
->out
.size
== NULL
) || (r
->out
.length
== NULL
)) {
455 return WERR_INVALID_PARAM
;
458 if (value_blob
.length
> *r
->out
.size
) {
459 return WERR_MORE_DATA
;
462 memcpy( r
->out
.value
, value_blob
.data
, value_blob
.length
);
465 if (r
->out
.length
!= NULL
) {
466 *r
->out
.length
= value_blob
.length
;
468 if (r
->out
.size
!= NULL
) {
469 *r
->out
.size
= value_blob
.length
;
475 /*******************************************************************
476 _winreg_InitiateSystemShutdown
477 ********************************************************************/
479 WERROR
_winreg_InitiateSystemShutdown(pipes_struct
*p
, struct winreg_InitiateSystemShutdown
*r
)
481 struct winreg_InitiateSystemShutdownEx s
;
483 s
.in
.hostname
= r
->in
.hostname
;
484 s
.in
.message
= r
->in
.message
;
485 s
.in
.timeout
= r
->in
.timeout
;
486 s
.in
.force_apps
= r
->in
.force_apps
;
487 s
.in
.do_reboot
= r
->in
.do_reboot
;
490 /* thunk down to _winreg_InitiateSystemShutdownEx()
491 (just returns a status) */
493 return _winreg_InitiateSystemShutdownEx( p
, &s
);
496 /*******************************************************************
497 _winreg_InitiateSystemShutdownEx
498 ********************************************************************/
500 #define SHUTDOWN_R_STRING "-r"
501 #define SHUTDOWN_F_STRING "-f"
504 WERROR
_winreg_InitiateSystemShutdownEx(pipes_struct
*p
, struct winreg_InitiateSystemShutdownEx
*r
)
506 char *shutdown_script
= NULL
;
516 shutdown_script
= talloc_strdup(p
->mem_ctx
, lp_shutdown_script());
517 if (!shutdown_script
) {
520 if (!*shutdown_script
) {
521 return WERR_ACCESS_DENIED
;
524 /* pull the message string and perform necessary sanity checks on it */
526 if ( r
->in
.message
&& r
->in
.message
->string
) {
527 if ( (msg
= talloc_strdup(p
->mem_ctx
, r
->in
.message
->string
)) == NULL
) {
530 chkmsg
= TALLOC_ARRAY(p
->mem_ctx
, char, strlen(msg
)+1);
534 alpha_strcpy(chkmsg
, msg
, NULL
, strlen(msg
)+1);
537 fstr_sprintf(str_timeout
, "%d", r
->in
.timeout
);
538 fstr_sprintf(do_reboot
, r
->in
.do_reboot
? SHUTDOWN_R_STRING
: "");
539 fstr_sprintf(f
, r
->in
.force_apps
? SHUTDOWN_F_STRING
: "");
540 fstr_sprintf(str_reason
, "%d", r
->in
.reason
);
542 shutdown_script
= talloc_all_string_sub(p
->mem_ctx
,
543 shutdown_script
, "%z", chkmsg
? chkmsg
: "");
544 if (!shutdown_script
) {
547 shutdown_script
= talloc_all_string_sub(p
->mem_ctx
,
548 shutdown_script
, "%t", str_timeout
);
549 if (!shutdown_script
) {
552 shutdown_script
= talloc_all_string_sub(p
->mem_ctx
,
553 shutdown_script
, "%r", do_reboot
);
554 if (!shutdown_script
) {
557 shutdown_script
= talloc_all_string_sub(p
->mem_ctx
,
558 shutdown_script
, "%f", f
);
559 if (!shutdown_script
) {
562 shutdown_script
= talloc_all_string_sub(p
->mem_ctx
,
563 shutdown_script
, "%x", str_reason
);
564 if (!shutdown_script
) {
568 can_shutdown
= user_has_privileges( p
->server_info
->ptok
,
569 &se_remote_shutdown
);
571 /* IF someone has privs, run the shutdown script as root. OTHERWISE run it as not root
572 Take the error return from the script and provide it as the Windows return code. */
574 /********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/
579 ret
= smbrun( shutdown_script
, NULL
);
584 /********** END SeRemoteShutdownPrivilege BLOCK **********/
586 DEBUG(3,("_reg_shutdown_ex: Running the command `%s' gave %d\n",
587 shutdown_script
, ret
));
589 return (ret
== 0) ? WERR_OK
: WERR_ACCESS_DENIED
;
592 /*******************************************************************
593 _winreg_AbortSystemShutdown
594 ********************************************************************/
596 WERROR
_winreg_AbortSystemShutdown(pipes_struct
*p
, struct winreg_AbortSystemShutdown
*r
)
598 const char *abort_shutdown_script
;
602 abort_shutdown_script
= lp_abort_shutdown_script();
604 if (!*abort_shutdown_script
)
605 return WERR_ACCESS_DENIED
;
607 can_shutdown
= user_has_privileges( p
->server_info
->ptok
,
608 &se_remote_shutdown
);
610 /********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/
615 ret
= smbrun( abort_shutdown_script
, NULL
);
620 /********** END SeRemoteShutdownPrivilege BLOCK **********/
622 DEBUG(3,("_winreg_AbortSystemShutdown: Running the command `%s' gave %d\n",
623 abort_shutdown_script
, ret
));
625 return (ret
== 0) ? WERR_OK
: WERR_ACCESS_DENIED
;
628 /*******************************************************************
629 ********************************************************************/
631 static int validate_reg_filename(TALLOC_CTX
*ctx
, char **pp_fname
)
634 int num_services
= lp_numservices();
636 const char *share_path
;
637 char *fname
= *pp_fname
;
639 /* convert to a unix path, stripping the C:\ along the way */
641 if (!(p
= valid_share_pathname(ctx
, fname
))) {
645 /* has to exist within a valid file share */
647 for (snum
=0; snum
<num_services
; snum
++) {
648 if (!lp_snum_ok(snum
) || lp_print_ok(snum
)) {
652 share_path
= lp_pathname(snum
);
654 /* make sure we have a path (e.g. [homes] ) */
655 if (strlen(share_path
) == 0) {
659 if (strncmp(share_path
, p
, strlen(share_path
)) == 0) {
665 return (snum
< num_services
) ? snum
: -1;
668 /*******************************************************************
670 ********************************************************************/
672 WERROR
_winreg_RestoreKey(pipes_struct
*p
, struct winreg_RestoreKey
*r
)
674 struct registry_key
*regkey
= find_regkey_by_hnd( p
, r
->in
.handle
);
681 if ( !r
->in
.filename
|| !r
->in
.filename
->name
)
682 return WERR_INVALID_PARAM
;
684 fname
= talloc_strdup(p
->mem_ctx
, r
->in
.filename
->name
);
689 DEBUG(8,("_winreg_RestoreKey: verifying restore of key [%s] from "
690 "\"%s\"\n", regkey
->key
->name
, fname
));
692 if ((snum
= validate_reg_filename(p
->mem_ctx
, &fname
)) == -1)
693 return WERR_OBJECT_PATH_INVALID
;
695 /* user must posses SeRestorePrivilege for this this proceed */
697 if ( !user_has_privileges( p
->server_info
->ptok
, &se_restore
) )
698 return WERR_ACCESS_DENIED
;
700 DEBUG(2,("_winreg_RestoreKey: Restoring [%s] from %s in share %s\n",
701 regkey
->key
->name
, fname
, lp_servicename(snum
) ));
703 return reg_restorekey(regkey
, fname
);
706 /*******************************************************************
708 ********************************************************************/
710 WERROR
_winreg_SaveKey(pipes_struct
*p
, struct winreg_SaveKey
*r
)
712 struct registry_key
*regkey
= find_regkey_by_hnd( p
, r
->in
.handle
);
719 if ( !r
->in
.filename
|| !r
->in
.filename
->name
)
720 return WERR_INVALID_PARAM
;
722 fname
= talloc_strdup(p
->mem_ctx
, r
->in
.filename
->name
);
727 DEBUG(8,("_winreg_SaveKey: verifying backup of key [%s] to \"%s\"\n",
728 regkey
->key
->name
, fname
));
730 if ((snum
= validate_reg_filename(p
->mem_ctx
, &fname
)) == -1 )
731 return WERR_OBJECT_PATH_INVALID
;
733 DEBUG(2,("_winreg_SaveKey: Saving [%s] to %s in share %s\n",
734 regkey
->key
->name
, fname
, lp_servicename(snum
) ));
736 return reg_savekey(regkey
, fname
);
739 /*******************************************************************
741 ********************************************************************/
743 WERROR
_winreg_SaveKeyEx(pipes_struct
*p
, struct winreg_SaveKeyEx
*r
)
745 /* fill in your code here if you think this call should
748 p
->rng_fault_state
= True
;
749 return WERR_NOT_SUPPORTED
;
752 /*******************************************************************
754 ********************************************************************/
756 WERROR
_winreg_CreateKey( pipes_struct
*p
, struct winreg_CreateKey
*r
)
758 struct registry_key
*parent
= find_regkey_by_hnd(p
, r
->in
.handle
);
759 struct registry_key
*new_key
;
765 DEBUG(10, ("_winreg_CreateKey called with parent key '%s' and "
766 "subkey name '%s'\n", parent
->key
->name
, r
->in
.name
.name
));
768 result
= reg_createkey(NULL
, parent
, r
->in
.name
.name
, r
->in
.access_mask
,
769 &new_key
, r
->out
.action_taken
);
770 if (!W_ERROR_IS_OK(result
)) {
774 if (!create_policy_hnd(p
, r
->out
.new_handle
, new_key
)) {
775 TALLOC_FREE(new_key
);
782 /*******************************************************************
784 ********************************************************************/
786 WERROR
_winreg_SetValue(pipes_struct
*p
, struct winreg_SetValue
*r
)
788 struct registry_key
*key
= find_regkey_by_hnd(p
, r
->in
.handle
);
789 struct registry_value
*val
;
795 DEBUG(8,("_winreg_SetValue: Setting value for [%s:%s]\n",
796 key
->key
->name
, r
->in
.name
.name
));
798 status
= registry_pull_value(p
->mem_ctx
, &val
, r
->in
.type
, r
->in
.data
,
799 r
->in
.size
, r
->in
.size
);
800 if (!W_ERROR_IS_OK(status
)) {
804 return reg_setvalue(key
, r
->in
.name
.name
, val
);
807 /*******************************************************************
809 ********************************************************************/
811 WERROR
_winreg_DeleteKey(pipes_struct
*p
, struct winreg_DeleteKey
*r
)
813 struct registry_key
*parent
= find_regkey_by_hnd(p
, r
->in
.handle
);
818 return reg_deletekey(parent
, r
->in
.key
.name
);
822 /*******************************************************************
824 ********************************************************************/
826 WERROR
_winreg_DeleteValue(pipes_struct
*p
, struct winreg_DeleteValue
*r
)
828 struct registry_key
*key
= find_regkey_by_hnd(p
, r
->in
.handle
);
833 return reg_deletevalue(key
, r
->in
.value
.name
);
836 /*******************************************************************
837 _winreg_GetKeySecurity
838 ********************************************************************/
840 WERROR
_winreg_GetKeySecurity(pipes_struct
*p
, struct winreg_GetKeySecurity
*r
)
842 struct registry_key
*key
= find_regkey_by_hnd(p
, r
->in
.handle
);
844 struct security_descriptor
*secdesc
;
851 /* access checks first */
853 if ( !(key
->key
->access_granted
& STD_RIGHT_READ_CONTROL_ACCESS
) )
854 return WERR_ACCESS_DENIED
;
856 err
= reg_getkeysecurity(p
->mem_ctx
, key
, &secdesc
);
857 if (!W_ERROR_IS_OK(err
)) {
861 err
= ntstatus_to_werror(marshall_sec_desc(p
->mem_ctx
, secdesc
,
863 if (!W_ERROR_IS_OK(err
)) {
867 if (len
> r
->out
.sd
->size
) {
868 r
->out
.sd
->size
= len
;
869 return WERR_INSUFFICIENT_BUFFER
;
872 r
->out
.sd
->size
= len
;
873 r
->out
.sd
->len
= len
;
874 r
->out
.sd
->data
= data
;
879 /*******************************************************************
880 _winreg_SetKeySecurity
881 ********************************************************************/
883 WERROR
_winreg_SetKeySecurity(pipes_struct
*p
, struct winreg_SetKeySecurity
*r
)
885 struct registry_key
*key
= find_regkey_by_hnd(p
, r
->in
.handle
);
886 struct security_descriptor
*secdesc
;
892 /* access checks first */
894 if ( !(key
->key
->access_granted
& STD_RIGHT_WRITE_DAC_ACCESS
) )
895 return WERR_ACCESS_DENIED
;
897 err
= ntstatus_to_werror(unmarshall_sec_desc(p
->mem_ctx
, r
->in
.sd
->data
,
898 r
->in
.sd
->len
, &secdesc
));
899 if (!W_ERROR_IS_OK(err
)) {
903 return reg_setkeysecurity(key
, secdesc
);
906 /*******************************************************************
908 ********************************************************************/
910 WERROR
_winreg_FlushKey(pipes_struct
*p
, struct winreg_FlushKey
*r
)
912 /* I'm just replying OK because there's not a lot
913 here I see to do i --jerry */
918 /*******************************************************************
920 ********************************************************************/
922 WERROR
_winreg_UnLoadKey(pipes_struct
*p
, struct winreg_UnLoadKey
*r
)
924 /* fill in your code here if you think this call should
927 p
->rng_fault_state
= True
;
928 return WERR_NOT_SUPPORTED
;
931 /*******************************************************************
933 ********************************************************************/
935 WERROR
_winreg_ReplaceKey(pipes_struct
*p
, struct winreg_ReplaceKey
*r
)
937 /* fill in your code here if you think this call should
940 p
->rng_fault_state
= True
;
941 return WERR_NOT_SUPPORTED
;
944 /*******************************************************************
946 ********************************************************************/
948 WERROR
_winreg_LoadKey(pipes_struct
*p
, struct winreg_LoadKey
*r
)
950 /* fill in your code here if you think this call should
953 p
->rng_fault_state
= True
;
954 return WERR_NOT_SUPPORTED
;
957 /*******************************************************************
958 _winreg_NotifyChangeKeyValue
959 ********************************************************************/
961 WERROR
_winreg_NotifyChangeKeyValue(pipes_struct
*p
, struct winreg_NotifyChangeKeyValue
*r
)
963 return WERR_NOT_SUPPORTED
;
966 /*******************************************************************
967 _winreg_QueryMultipleValues
968 ********************************************************************/
970 WERROR
_winreg_QueryMultipleValues(pipes_struct
*p
, struct winreg_QueryMultipleValues
*r
)
972 /* fill in your code here if you think this call should
975 p
->rng_fault_state
= True
;
976 return WERR_NOT_SUPPORTED
;
979 /*******************************************************************
980 _winreg_QueryMultipleValues2
981 ********************************************************************/
983 WERROR
_winreg_QueryMultipleValues2(pipes_struct
*p
, struct winreg_QueryMultipleValues2
*r
)
985 /* fill in your code here if you think this call should
988 p
->rng_fault_state
= True
;
989 return WERR_NOT_SUPPORTED
;
992 /*******************************************************************
994 ********************************************************************/
996 WERROR
_winreg_DeleteKeyEx(pipes_struct
*p
, struct winreg_DeleteKeyEx
*r
)
998 /* fill in your code here if you think this call should
1001 p
->rng_fault_state
= True
;
1002 return WERR_NOT_SUPPORTED
;