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"
27 #define DBGC_CLASS DBGC_RPC_SRV
29 /******************************************************************
30 Find a registry key handle and return a struct registry_key *
31 *****************************************************************/
33 static struct registry_key
*find_regkey_by_hnd(pipes_struct
*p
,
34 struct policy_handle
*hnd
)
36 struct registry_key
*regkey
= NULL
;
38 if(!find_policy_by_hnd(p
,hnd
,(void **)(void *)®key
)) {
39 DEBUG(2,("find_regkey_index_by_hnd: Registry Key not found: "));
46 /*******************************************************************
47 Function for open a new registry handle and creating a handle
48 Note that P should be valid & hnd should already have space
50 When we open a key, we store the full path to the key as
51 HK[LM|U]\<key>\<key>\...
52 *******************************************************************/
54 static WERROR
open_registry_key( pipes_struct
*p
, struct policy_handle
*hnd
,
55 struct registry_key
*parent
,
56 const char *subkeyname
,
57 uint32 access_desired
)
59 WERROR result
= WERR_OK
;
60 struct registry_key
*key
;
63 result
= reg_openhive(p
->mem_ctx
, subkeyname
, access_desired
,
64 p
->server_info
->ptok
, &key
);
67 result
= reg_openkey(p
->mem_ctx
, parent
, subkeyname
,
68 access_desired
, &key
);
71 if ( !W_ERROR_IS_OK(result
) ) {
75 if ( !create_policy_hnd( p
, hnd
, key
) ) {
82 /*******************************************************************
83 Function for open a new registry handle and creating a handle
84 Note that P should be valid & hnd should already have space
85 *******************************************************************/
87 static bool close_registry_key(pipes_struct
*p
, struct policy_handle
*hnd
)
89 struct registry_key
*regkey
= find_regkey_by_hnd(p
, hnd
);
92 DEBUG(2,("close_registry_key: Invalid handle (%s:%u:%u)\n",
97 close_policy_hnd(p
, hnd
);
102 /********************************************************************
104 ********************************************************************/
106 WERROR
_winreg_CloseKey(pipes_struct
*p
, struct winreg_CloseKey
*r
)
108 /* close the policy handle */
110 if (!close_registry_key(p
, r
->in
.handle
))
113 ZERO_STRUCTP(r
->out
.handle
);
118 /*******************************************************************
120 ********************************************************************/
122 WERROR
_winreg_OpenHKLM(pipes_struct
*p
, struct winreg_OpenHKLM
*r
)
124 return open_registry_key(p
, r
->out
.handle
, NULL
, KEY_HKLM
, r
->in
.access_mask
);
127 /*******************************************************************
129 ********************************************************************/
131 WERROR
_winreg_OpenHKPD(pipes_struct
*p
, struct winreg_OpenHKPD
*r
)
133 return open_registry_key(p
, r
->out
.handle
, NULL
, KEY_HKPD
, r
->in
.access_mask
);
136 /*******************************************************************
138 ********************************************************************/
140 WERROR
_winreg_OpenHKPT(pipes_struct
*p
, struct winreg_OpenHKPT
*r
)
142 return open_registry_key(p
, r
->out
.handle
, NULL
, KEY_HKPT
, r
->in
.access_mask
);
145 /*******************************************************************
147 ********************************************************************/
149 WERROR
_winreg_OpenHKCR(pipes_struct
*p
, struct winreg_OpenHKCR
*r
)
151 return open_registry_key(p
, r
->out
.handle
, NULL
, KEY_HKCR
, r
->in
.access_mask
);
154 /*******************************************************************
156 ********************************************************************/
158 WERROR
_winreg_OpenHKU(pipes_struct
*p
, struct winreg_OpenHKU
*r
)
160 return open_registry_key(p
, r
->out
.handle
, NULL
, KEY_HKU
, r
->in
.access_mask
);
163 /*******************************************************************
165 ********************************************************************/
167 WERROR
_winreg_OpenHKCU(pipes_struct
*p
, struct winreg_OpenHKCU
*r
)
169 return open_registry_key(p
, r
->out
.handle
, NULL
, KEY_HKCU
, r
->in
.access_mask
);
172 /*******************************************************************
174 ********************************************************************/
176 WERROR
_winreg_OpenHKCC(pipes_struct
*p
, struct winreg_OpenHKCC
*r
)
178 return open_registry_key(p
, r
->out
.handle
, NULL
, KEY_HKCC
, r
->in
.access_mask
);
181 /*******************************************************************
183 ********************************************************************/
185 WERROR
_winreg_OpenHKDD(pipes_struct
*p
, struct winreg_OpenHKDD
*r
)
187 return open_registry_key(p
, r
->out
.handle
, NULL
, KEY_HKDD
, r
->in
.access_mask
);
190 /*******************************************************************
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
->in
.value_name
->name
== NULL
) {
234 return WERR_INVALID_PARAM
;
237 if ((r
->out
.data_length
== NULL
) || (r
->out
.type
== NULL
) || (r
->out
.data_size
== NULL
)) {
238 return WERR_INVALID_PARAM
;
241 DEBUG(7,("_winreg_QueryValue: policy key name = [%s]\n", regkey
->key
->name
));
242 DEBUG(7,("_winreg_QueryValue: policy key type = [%08x]\n", regkey
->key
->type
));
244 /* Handle QueryValue calls on HKEY_PERFORMANCE_DATA */
245 if(regkey
->key
->type
== REG_KEY_HKPD
)
247 if (strequal(r
->in
.value_name
->name
, "Global")) {
248 if (!prs_init(&prs_hkpd
, *r
->in
.data_size
, p
->mem_ctx
, MARSHALL
))
250 status
= reg_perfcount_get_hkpd(
251 &prs_hkpd
, *r
->in
.data_size
, &outbuf_size
, NULL
);
252 outbuf
= (uint8_t *)prs_hkpd
.data_p
;
255 else if (strequal(r
->in
.value_name
->name
, "Counter 009")) {
256 outbuf_size
= reg_perfcount_get_counter_names(
257 reg_perfcount_get_base_index(),
258 (char **)(void *)&outbuf
);
261 else if (strequal(r
->in
.value_name
->name
, "Explain 009")) {
262 outbuf_size
= reg_perfcount_get_counter_help(
263 reg_perfcount_get_base_index(),
264 (char **)(void *)&outbuf
);
267 else if (isdigit(r
->in
.value_name
->name
[0])) {
268 /* we probably have a request for a specific object
270 if (!prs_init(&prs_hkpd
, *r
->in
.data_size
, p
->mem_ctx
, MARSHALL
))
272 status
= reg_perfcount_get_hkpd(
273 &prs_hkpd
, *r
->in
.data_size
, &outbuf_size
,
274 r
->in
.value_name
->name
);
275 outbuf
= (uint8_t *)prs_hkpd
.data_p
;
279 DEBUG(3,("Unsupported key name [%s] for HKPD.\n",
280 r
->in
.value_name
->name
));
284 *r
->out
.type
= REG_BINARY
;
287 struct registry_value
*val
;
289 status
= reg_queryvalue(p
->mem_ctx
, regkey
, r
->in
.value_name
->name
,
291 if (!W_ERROR_IS_OK(status
)) {
293 DEBUG(10,("_winreg_QueryValue: reg_queryvalue failed with: %s\n",
294 win_errstr(status
)));
296 if (r
->out
.data_size
) {
297 *r
->out
.data_size
= 0;
299 if (r
->out
.data_length
) {
300 *r
->out
.data_length
= 0;
305 status
= registry_push_value(p
->mem_ctx
, val
, &val_blob
);
306 if (!W_ERROR_IS_OK(status
)) {
310 outbuf
= val_blob
.data
;
311 outbuf_size
= val_blob
.length
;
312 *r
->out
.type
= val
->type
;
315 status
= WERR_BADFILE
;
317 if (*r
->in
.data_size
< outbuf_size
) {
318 *r
->out
.data_size
= outbuf_size
;
319 status
= r
->in
.data
? WERR_MORE_DATA
: WERR_OK
;
321 *r
->out
.data_length
= outbuf_size
;
322 *r
->out
.data_size
= outbuf_size
;
323 memcpy(r
->out
.data
, outbuf
, outbuf_size
);
327 if (free_prs
) prs_mem_free(&prs_hkpd
);
328 if (free_buf
) SAFE_FREE(outbuf
);
333 /*****************************************************************************
335 ****************************************************************************/
337 WERROR
_winreg_QueryInfoKey(pipes_struct
*p
, struct winreg_QueryInfoKey
*r
)
339 WERROR status
= WERR_OK
;
340 struct registry_key
*regkey
= find_regkey_by_hnd( p
, r
->in
.handle
);
345 r
->out
.classname
->name
= NULL
;
347 status
= reg_queryinfokey(regkey
, r
->out
.num_subkeys
, r
->out
.max_subkeylen
,
348 r
->out
.max_classlen
, r
->out
.num_values
, r
->out
.max_valnamelen
,
349 r
->out
.max_valbufsize
, r
->out
.secdescsize
,
350 r
->out
.last_changed_time
);
351 if (!W_ERROR_IS_OK(status
)) {
356 * These calculations account for the registry buffers being
357 * UTF-16. They are inexact at best, but so far they worked.
360 *r
->out
.max_subkeylen
*= 2;
362 *r
->out
.max_valnamelen
+= 1;
363 *r
->out
.max_valnamelen
*= 2;
369 /*****************************************************************************
371 ****************************************************************************/
373 WERROR
_winreg_GetVersion(pipes_struct
*p
, struct winreg_GetVersion
*r
)
375 struct registry_key
*regkey
= find_regkey_by_hnd( p
, r
->in
.handle
);
380 return reg_getversion(r
->out
.version
);
384 /*****************************************************************************
386 ****************************************************************************/
388 WERROR
_winreg_EnumKey(pipes_struct
*p
, struct winreg_EnumKey
*r
)
391 struct registry_key
*key
= find_regkey_by_hnd( p
, r
->in
.handle
);
396 if ( !r
->in
.name
|| !r
->in
.keyclass
)
397 return WERR_INVALID_PARAM
;
399 DEBUG(8,("_winreg_EnumKey: enumerating key [%s]\n", key
->key
->name
));
401 err
= reg_enumkey(p
->mem_ctx
, key
, r
->in
.enum_index
, (char **)&r
->out
.name
->name
,
402 r
->out
.last_changed_time
);
403 if (!W_ERROR_IS_OK(err
)) {
406 r
->out
.keyclass
->name
= "";
410 /*****************************************************************************
412 ****************************************************************************/
414 WERROR
_winreg_EnumValue(pipes_struct
*p
, struct winreg_EnumValue
*r
)
417 struct registry_key
*key
= find_regkey_by_hnd( p
, r
->in
.handle
);
419 struct registry_value
*val
;
420 DATA_BLOB value_blob
;
426 return WERR_INVALID_PARAM
;
428 DEBUG(8,("_winreg_EnumValue: enumerating values for key [%s]\n",
431 err
= reg_enumvalue(p
->mem_ctx
, key
, r
->in
.enum_index
, &valname
, &val
);
432 if (!W_ERROR_IS_OK(err
)) {
436 err
= registry_push_value(p
->mem_ctx
, val
, &value_blob
);
437 if (!W_ERROR_IS_OK(err
)) {
441 if (r
->out
.name
!= NULL
) {
442 r
->out
.name
->name
= valname
;
445 if (r
->out
.type
!= NULL
) {
446 *r
->out
.type
= val
->type
;
449 if (r
->out
.value
!= NULL
) {
450 if ((r
->out
.size
== NULL
) || (r
->out
.length
== NULL
)) {
451 return WERR_INVALID_PARAM
;
454 if (value_blob
.length
> *r
->out
.size
) {
455 return WERR_MORE_DATA
;
458 memcpy( r
->out
.value
, value_blob
.data
, value_blob
.length
);
461 if (r
->out
.length
!= NULL
) {
462 *r
->out
.length
= value_blob
.length
;
464 if (r
->out
.size
!= NULL
) {
465 *r
->out
.size
= value_blob
.length
;
471 /*******************************************************************
472 _winreg_InitiateSystemShutdown
473 ********************************************************************/
475 WERROR
_winreg_InitiateSystemShutdown(pipes_struct
*p
, struct winreg_InitiateSystemShutdown
*r
)
477 struct winreg_InitiateSystemShutdownEx s
;
479 s
.in
.hostname
= r
->in
.hostname
;
480 s
.in
.message
= r
->in
.message
;
481 s
.in
.timeout
= r
->in
.timeout
;
482 s
.in
.force_apps
= r
->in
.force_apps
;
483 s
.in
.do_reboot
= r
->in
.do_reboot
;
486 /* thunk down to _winreg_InitiateSystemShutdownEx()
487 (just returns a status) */
489 return _winreg_InitiateSystemShutdownEx( p
, &s
);
492 /*******************************************************************
493 _winreg_InitiateSystemShutdownEx
494 ********************************************************************/
496 #define SHUTDOWN_R_STRING "-r"
497 #define SHUTDOWN_F_STRING "-f"
500 WERROR
_winreg_InitiateSystemShutdownEx(pipes_struct
*p
, struct winreg_InitiateSystemShutdownEx
*r
)
502 char *shutdown_script
= NULL
;
512 shutdown_script
= talloc_strdup(p
->mem_ctx
, lp_shutdown_script());
513 if (!shutdown_script
) {
516 if (!*shutdown_script
) {
517 return WERR_ACCESS_DENIED
;
520 /* pull the message string and perform necessary sanity checks on it */
522 if ( r
->in
.message
&& r
->in
.message
->string
) {
523 if ( (msg
= talloc_strdup(p
->mem_ctx
, r
->in
.message
->string
)) == NULL
) {
526 chkmsg
= TALLOC_ARRAY(p
->mem_ctx
, char, strlen(msg
)+1);
530 alpha_strcpy(chkmsg
, msg
, NULL
, strlen(msg
)+1);
533 fstr_sprintf(str_timeout
, "%d", r
->in
.timeout
);
534 fstr_sprintf(do_reboot
, r
->in
.do_reboot
? SHUTDOWN_R_STRING
: "");
535 fstr_sprintf(f
, r
->in
.force_apps
? SHUTDOWN_F_STRING
: "");
536 fstr_sprintf(str_reason
, "%d", r
->in
.reason
);
538 shutdown_script
= talloc_all_string_sub(p
->mem_ctx
,
539 shutdown_script
, "%z", chkmsg
? chkmsg
: "");
540 if (!shutdown_script
) {
543 shutdown_script
= talloc_all_string_sub(p
->mem_ctx
,
544 shutdown_script
, "%t", str_timeout
);
545 if (!shutdown_script
) {
548 shutdown_script
= talloc_all_string_sub(p
->mem_ctx
,
549 shutdown_script
, "%r", do_reboot
);
550 if (!shutdown_script
) {
553 shutdown_script
= talloc_all_string_sub(p
->mem_ctx
,
554 shutdown_script
, "%f", f
);
555 if (!shutdown_script
) {
558 shutdown_script
= talloc_all_string_sub(p
->mem_ctx
,
559 shutdown_script
, "%x", str_reason
);
560 if (!shutdown_script
) {
564 can_shutdown
= user_has_privileges( p
->server_info
->ptok
,
565 &se_remote_shutdown
);
567 /* IF someone has privs, run the shutdown script as root. OTHERWISE run it as not root
568 Take the error return from the script and provide it as the Windows return code. */
570 /********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/
575 ret
= smbrun( shutdown_script
, NULL
);
580 /********** END SeRemoteShutdownPrivilege BLOCK **********/
582 DEBUG(3,("_reg_shutdown_ex: Running the command `%s' gave %d\n",
583 shutdown_script
, ret
));
585 return (ret
== 0) ? WERR_OK
: WERR_ACCESS_DENIED
;
588 /*******************************************************************
589 _winreg_AbortSystemShutdown
590 ********************************************************************/
592 WERROR
_winreg_AbortSystemShutdown(pipes_struct
*p
, struct winreg_AbortSystemShutdown
*r
)
594 const char *abort_shutdown_script
;
598 abort_shutdown_script
= lp_abort_shutdown_script();
600 if (!*abort_shutdown_script
)
601 return WERR_ACCESS_DENIED
;
603 can_shutdown
= user_has_privileges( p
->server_info
->ptok
,
604 &se_remote_shutdown
);
606 /********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/
611 ret
= smbrun( abort_shutdown_script
, NULL
);
616 /********** END SeRemoteShutdownPrivilege BLOCK **********/
618 DEBUG(3,("_winreg_AbortSystemShutdown: Running the command `%s' gave %d\n",
619 abort_shutdown_script
, ret
));
621 return (ret
== 0) ? WERR_OK
: WERR_ACCESS_DENIED
;
624 /*******************************************************************
625 ********************************************************************/
627 static int validate_reg_filename(TALLOC_CTX
*ctx
, char **pp_fname
)
630 int num_services
= lp_numservices();
632 const char *share_path
;
633 char *fname
= *pp_fname
;
635 /* convert to a unix path, stripping the C:\ along the way */
637 if (!(p
= valid_share_pathname(ctx
, fname
))) {
641 /* has to exist within a valid file share */
643 for (snum
=0; snum
<num_services
; snum
++) {
644 if (!lp_snum_ok(snum
) || lp_print_ok(snum
)) {
648 share_path
= lp_pathname(snum
);
650 /* make sure we have a path (e.g. [homes] ) */
651 if (strlen(share_path
) == 0) {
655 if (strncmp(share_path
, p
, strlen(share_path
)) == 0) {
661 return (snum
< num_services
) ? snum
: -1;
664 /*******************************************************************
666 ********************************************************************/
668 WERROR
_winreg_RestoreKey(pipes_struct
*p
, struct winreg_RestoreKey
*r
)
670 struct registry_key
*regkey
= find_regkey_by_hnd( p
, r
->in
.handle
);
677 if ( !r
->in
.filename
|| !r
->in
.filename
->name
)
678 return WERR_INVALID_PARAM
;
680 fname
= talloc_strdup(p
->mem_ctx
, r
->in
.filename
->name
);
685 DEBUG(8,("_winreg_RestoreKey: verifying restore of key [%s] from "
686 "\"%s\"\n", regkey
->key
->name
, fname
));
688 if ((snum
= validate_reg_filename(p
->mem_ctx
, &fname
)) == -1)
689 return WERR_OBJECT_PATH_INVALID
;
691 /* user must posses SeRestorePrivilege for this this proceed */
693 if ( !user_has_privileges( p
->server_info
->ptok
, &se_restore
) )
694 return WERR_ACCESS_DENIED
;
696 DEBUG(2,("_winreg_RestoreKey: Restoring [%s] from %s in share %s\n",
697 regkey
->key
->name
, fname
, lp_servicename(snum
) ));
699 return reg_restorekey(regkey
, fname
);
702 /*******************************************************************
704 ********************************************************************/
706 WERROR
_winreg_SaveKey(pipes_struct
*p
, struct winreg_SaveKey
*r
)
708 struct registry_key
*regkey
= find_regkey_by_hnd( p
, r
->in
.handle
);
715 if ( !r
->in
.filename
|| !r
->in
.filename
->name
)
716 return WERR_INVALID_PARAM
;
718 fname
= talloc_strdup(p
->mem_ctx
, r
->in
.filename
->name
);
723 DEBUG(8,("_winreg_SaveKey: verifying backup of key [%s] to \"%s\"\n",
724 regkey
->key
->name
, fname
));
726 if ((snum
= validate_reg_filename(p
->mem_ctx
, &fname
)) == -1 )
727 return WERR_OBJECT_PATH_INVALID
;
729 DEBUG(2,("_winreg_SaveKey: Saving [%s] to %s in share %s\n",
730 regkey
->key
->name
, fname
, lp_servicename(snum
) ));
732 return reg_savekey(regkey
, fname
);
735 /*******************************************************************
737 ********************************************************************/
739 WERROR
_winreg_SaveKeyEx(pipes_struct
*p
, struct winreg_SaveKeyEx
*r
)
741 /* fill in your code here if you think this call should
744 p
->rng_fault_state
= True
;
745 return WERR_NOT_SUPPORTED
;
748 /*******************************************************************
750 ********************************************************************/
752 WERROR
_winreg_CreateKey( pipes_struct
*p
, struct winreg_CreateKey
*r
)
754 struct registry_key
*parent
= find_regkey_by_hnd(p
, r
->in
.handle
);
755 struct registry_key
*new_key
;
761 DEBUG(10, ("_winreg_CreateKey called with parent key '%s' and "
762 "subkey name '%s'\n", parent
->key
->name
, r
->in
.name
.name
));
764 result
= reg_createkey(NULL
, parent
, r
->in
.name
.name
, r
->in
.access_mask
,
765 &new_key
, r
->out
.action_taken
);
766 if (!W_ERROR_IS_OK(result
)) {
770 if (!create_policy_hnd(p
, r
->out
.new_handle
, new_key
)) {
771 TALLOC_FREE(new_key
);
778 /*******************************************************************
780 ********************************************************************/
782 WERROR
_winreg_SetValue(pipes_struct
*p
, struct winreg_SetValue
*r
)
784 struct registry_key
*key
= find_regkey_by_hnd(p
, r
->in
.handle
);
785 struct registry_value
*val
;
791 DEBUG(8,("_winreg_SetValue: Setting value for [%s:%s]\n",
792 key
->key
->name
, r
->in
.name
.name
));
794 status
= registry_pull_value(p
->mem_ctx
, &val
, r
->in
.type
, r
->in
.data
,
795 r
->in
.size
, r
->in
.size
);
796 if (!W_ERROR_IS_OK(status
)) {
800 return reg_setvalue(key
, r
->in
.name
.name
, val
);
803 /*******************************************************************
805 ********************************************************************/
807 WERROR
_winreg_DeleteKey(pipes_struct
*p
, struct winreg_DeleteKey
*r
)
809 struct registry_key
*parent
= find_regkey_by_hnd(p
, r
->in
.handle
);
814 return reg_deletekey(parent
, r
->in
.key
.name
);
818 /*******************************************************************
820 ********************************************************************/
822 WERROR
_winreg_DeleteValue(pipes_struct
*p
, struct winreg_DeleteValue
*r
)
824 struct registry_key
*key
= find_regkey_by_hnd(p
, r
->in
.handle
);
829 return reg_deletevalue(key
, r
->in
.value
.name
);
832 /*******************************************************************
833 _winreg_GetKeySecurity
834 ********************************************************************/
836 WERROR
_winreg_GetKeySecurity(pipes_struct
*p
, struct winreg_GetKeySecurity
*r
)
838 struct registry_key
*key
= find_regkey_by_hnd(p
, r
->in
.handle
);
840 struct security_descriptor
*secdesc
;
847 /* access checks first */
849 if ( !(key
->key
->access_granted
& STD_RIGHT_READ_CONTROL_ACCESS
) )
850 return WERR_ACCESS_DENIED
;
852 err
= reg_getkeysecurity(p
->mem_ctx
, key
, &secdesc
);
853 if (!W_ERROR_IS_OK(err
)) {
857 err
= ntstatus_to_werror(marshall_sec_desc(p
->mem_ctx
, secdesc
,
859 if (!W_ERROR_IS_OK(err
)) {
863 if (len
> r
->out
.sd
->size
) {
864 r
->out
.sd
->size
= len
;
865 return WERR_INSUFFICIENT_BUFFER
;
868 r
->out
.sd
->size
= len
;
869 r
->out
.sd
->len
= len
;
870 r
->out
.sd
->data
= data
;
875 /*******************************************************************
876 _winreg_SetKeySecurity
877 ********************************************************************/
879 WERROR
_winreg_SetKeySecurity(pipes_struct
*p
, struct winreg_SetKeySecurity
*r
)
881 struct registry_key
*key
= find_regkey_by_hnd(p
, r
->in
.handle
);
882 struct security_descriptor
*secdesc
;
888 /* access checks first */
890 if ( !(key
->key
->access_granted
& STD_RIGHT_WRITE_DAC_ACCESS
) )
891 return WERR_ACCESS_DENIED
;
893 err
= ntstatus_to_werror(unmarshall_sec_desc(p
->mem_ctx
, r
->in
.sd
->data
,
894 r
->in
.sd
->len
, &secdesc
));
895 if (!W_ERROR_IS_OK(err
)) {
899 return reg_setkeysecurity(key
, secdesc
);
902 /*******************************************************************
904 ********************************************************************/
906 WERROR
_winreg_FlushKey(pipes_struct
*p
, struct winreg_FlushKey
*r
)
908 /* I'm just replying OK because there's not a lot
909 here I see to do i --jerry */
914 /*******************************************************************
916 ********************************************************************/
918 WERROR
_winreg_UnLoadKey(pipes_struct
*p
, struct winreg_UnLoadKey
*r
)
920 /* fill in your code here if you think this call should
923 p
->rng_fault_state
= True
;
924 return WERR_NOT_SUPPORTED
;
927 /*******************************************************************
929 ********************************************************************/
931 WERROR
_winreg_ReplaceKey(pipes_struct
*p
, struct winreg_ReplaceKey
*r
)
933 /* fill in your code here if you think this call should
936 p
->rng_fault_state
= True
;
937 return WERR_NOT_SUPPORTED
;
940 /*******************************************************************
942 ********************************************************************/
944 WERROR
_winreg_LoadKey(pipes_struct
*p
, struct winreg_LoadKey
*r
)
946 /* fill in your code here if you think this call should
949 p
->rng_fault_state
= True
;
950 return WERR_NOT_SUPPORTED
;
953 /*******************************************************************
954 _winreg_NotifyChangeKeyValue
955 ********************************************************************/
957 WERROR
_winreg_NotifyChangeKeyValue(pipes_struct
*p
, struct winreg_NotifyChangeKeyValue
*r
)
959 return WERR_NOT_SUPPORTED
;
962 /*******************************************************************
963 _winreg_QueryMultipleValues
964 ********************************************************************/
966 WERROR
_winreg_QueryMultipleValues(pipes_struct
*p
, struct winreg_QueryMultipleValues
*r
)
968 /* fill in your code here if you think this call should
971 p
->rng_fault_state
= True
;
972 return WERR_NOT_SUPPORTED
;
975 /*******************************************************************
976 _winreg_QueryMultipleValues2
977 ********************************************************************/
979 WERROR
_winreg_QueryMultipleValues2(pipes_struct
*p
, struct winreg_QueryMultipleValues2
*r
)
981 /* fill in your code here if you think this call should
984 p
->rng_fault_state
= True
;
985 return WERR_NOT_SUPPORTED
;