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"
25 #include "registry/reg_parse_prs.h"
27 #include "registry/reg_perfcount.h"
30 #define DBGC_CLASS DBGC_RPC_SRV
32 /******************************************************************
33 Find a registry key handle and return a struct registry_key *
34 *****************************************************************/
36 static struct registry_key
*find_regkey_by_hnd(struct pipes_struct
*p
,
37 struct policy_handle
*hnd
)
39 struct registry_key
*regkey
= NULL
;
41 if(!find_policy_by_hnd(p
,hnd
,(void **)(void *)®key
)) {
42 DEBUG(2,("find_regkey_index_by_hnd: Registry Key not found: "));
49 /*******************************************************************
50 Function for open a new registry handle and creating a handle
51 Note that P should be valid & hnd should already have space
53 When we open a key, we store the full path to the key as
54 HK[LM|U]\<key>\<key>\...
55 *******************************************************************/
57 static WERROR
open_registry_key(struct pipes_struct
*p
,
58 struct policy_handle
*hnd
,
59 struct registry_key
*parent
,
60 const char *subkeyname
,
61 uint32_t access_desired
)
63 WERROR result
= WERR_OK
;
64 struct registry_key
*key
;
67 result
= reg_openhive(p
->mem_ctx
, subkeyname
, access_desired
,
68 p
->server_info
->ptok
, &key
);
71 result
= reg_openkey(p
->mem_ctx
, parent
, subkeyname
,
72 access_desired
, &key
);
75 if ( !W_ERROR_IS_OK(result
) ) {
79 if ( !create_policy_hnd( p
, hnd
, key
) ) {
86 /*******************************************************************
87 Function for open a new registry handle and creating a handle
88 Note that P should be valid & hnd should already have space
89 *******************************************************************/
91 static bool close_registry_key(struct pipes_struct
*p
,
92 struct policy_handle
*hnd
)
94 struct registry_key
*regkey
= find_regkey_by_hnd(p
, hnd
);
97 DEBUG(2,("close_registry_key: Invalid handle (%s:%u:%u)\n",
102 close_policy_hnd(p
, hnd
);
107 /********************************************************************
109 ********************************************************************/
111 WERROR
_winreg_CloseKey(struct pipes_struct
*p
,
112 struct winreg_CloseKey
*r
)
114 /* close the policy handle */
116 if (!close_registry_key(p
, r
->in
.handle
))
119 ZERO_STRUCTP(r
->out
.handle
);
124 /*******************************************************************
126 ********************************************************************/
128 WERROR
_winreg_OpenHKLM(struct pipes_struct
*p
,
129 struct winreg_OpenHKLM
*r
)
131 return open_registry_key(p
, r
->out
.handle
, NULL
, KEY_HKLM
, r
->in
.access_mask
);
134 /*******************************************************************
136 ********************************************************************/
138 WERROR
_winreg_OpenHKPD(struct pipes_struct
*p
,
139 struct winreg_OpenHKPD
*r
)
141 return open_registry_key(p
, r
->out
.handle
, NULL
, KEY_HKPD
, r
->in
.access_mask
);
144 /*******************************************************************
146 ********************************************************************/
148 WERROR
_winreg_OpenHKPT(struct pipes_struct
*p
,
149 struct winreg_OpenHKPT
*r
)
151 return open_registry_key(p
, r
->out
.handle
, NULL
, KEY_HKPT
, r
->in
.access_mask
);
154 /*******************************************************************
156 ********************************************************************/
158 WERROR
_winreg_OpenHKCR(struct pipes_struct
*p
,
159 struct winreg_OpenHKCR
*r
)
161 return open_registry_key(p
, r
->out
.handle
, NULL
, KEY_HKCR
, r
->in
.access_mask
);
164 /*******************************************************************
166 ********************************************************************/
168 WERROR
_winreg_OpenHKU(struct pipes_struct
*p
,
169 struct winreg_OpenHKU
*r
)
171 return open_registry_key(p
, r
->out
.handle
, NULL
, KEY_HKU
, r
->in
.access_mask
);
174 /*******************************************************************
176 ********************************************************************/
178 WERROR
_winreg_OpenHKCU(struct pipes_struct
*p
,
179 struct winreg_OpenHKCU
*r
)
181 return open_registry_key(p
, r
->out
.handle
, NULL
, KEY_HKCU
, r
->in
.access_mask
);
184 /*******************************************************************
186 ********************************************************************/
188 WERROR
_winreg_OpenHKCC(struct pipes_struct
*p
,
189 struct winreg_OpenHKCC
*r
)
191 return open_registry_key(p
, r
->out
.handle
, NULL
, KEY_HKCC
, r
->in
.access_mask
);
194 /*******************************************************************
196 ********************************************************************/
198 WERROR
_winreg_OpenHKDD(struct pipes_struct
*p
,
199 struct winreg_OpenHKDD
*r
)
201 return open_registry_key(p
, r
->out
.handle
, NULL
, KEY_HKDD
, r
->in
.access_mask
);
204 /*******************************************************************
206 ********************************************************************/
208 WERROR
_winreg_OpenHKPN(struct pipes_struct
*p
,
209 struct winreg_OpenHKPN
*r
)
211 return open_registry_key(p
, r
->out
.handle
, NULL
, KEY_HKPN
, r
->in
.access_mask
);
214 /*******************************************************************
216 ********************************************************************/
218 WERROR
_winreg_OpenKey(struct pipes_struct
*p
,
219 struct winreg_OpenKey
*r
)
221 struct registry_key
*parent
= find_regkey_by_hnd(p
, r
->in
.parent_handle
);
226 return open_registry_key(p
, r
->out
.handle
, parent
, r
->in
.keyname
.name
, r
->in
.access_mask
);
229 /*******************************************************************
231 ********************************************************************/
233 WERROR
_winreg_QueryValue(struct pipes_struct
*p
,
234 struct winreg_QueryValue
*r
)
236 WERROR status
= WERR_BADFILE
;
237 struct registry_key
*regkey
= find_regkey_by_hnd( p
, r
->in
.handle
);
241 uint32_t outbuf_size
;
243 bool free_buf
= False
;
244 bool free_prs
= False
;
249 if (r
->in
.value_name
->name
== NULL
) {
250 return WERR_INVALID_PARAM
;
253 if ((r
->out
.data_length
== NULL
) || (r
->out
.type
== NULL
) || (r
->out
.data_size
== NULL
)) {
254 return WERR_INVALID_PARAM
;
257 DEBUG(7,("_winreg_QueryValue: policy key name = [%s]\n", regkey
->key
->name
));
258 DEBUG(7,("_winreg_QueryValue: policy key type = [%08x]\n", regkey
->key
->type
));
260 /* Handle QueryValue calls on HKEY_PERFORMANCE_DATA */
261 if(regkey
->key
->type
== REG_KEY_HKPD
)
263 if (strequal(r
->in
.value_name
->name
, "Global")) {
264 if (!prs_init(&prs_hkpd
, *r
->in
.data_size
, p
->mem_ctx
, MARSHALL
))
266 status
= reg_perfcount_get_hkpd(
267 &prs_hkpd
, *r
->in
.data_size
, &outbuf_size
, NULL
);
268 outbuf
= (uint8_t *)prs_hkpd
.data_p
;
271 else if (strequal(r
->in
.value_name
->name
, "Counter 009")) {
272 outbuf_size
= reg_perfcount_get_counter_names(
273 reg_perfcount_get_base_index(),
274 (char **)(void *)&outbuf
);
277 else if (strequal(r
->in
.value_name
->name
, "Explain 009")) {
278 outbuf_size
= reg_perfcount_get_counter_help(
279 reg_perfcount_get_base_index(),
280 (char **)(void *)&outbuf
);
283 else if (isdigit(r
->in
.value_name
->name
[0])) {
284 /* we probably have a request for a specific object
286 if (!prs_init(&prs_hkpd
, *r
->in
.data_size
, p
->mem_ctx
, MARSHALL
))
288 status
= reg_perfcount_get_hkpd(
289 &prs_hkpd
, *r
->in
.data_size
, &outbuf_size
,
290 r
->in
.value_name
->name
);
291 outbuf
= (uint8_t *)prs_hkpd
.data_p
;
295 DEBUG(3,("Unsupported key name [%s] for HKPD.\n",
296 r
->in
.value_name
->name
));
300 *r
->out
.type
= REG_BINARY
;
303 struct registry_value
*val
;
305 status
= reg_queryvalue(p
->mem_ctx
, regkey
, r
->in
.value_name
->name
,
307 if (!W_ERROR_IS_OK(status
)) {
309 DEBUG(10,("_winreg_QueryValue: reg_queryvalue failed with: %s\n",
310 win_errstr(status
)));
312 if (r
->out
.data_size
) {
313 *r
->out
.data_size
= 0;
315 if (r
->out
.data_length
) {
316 *r
->out
.data_length
= 0;
321 outbuf
= val
->data
.data
;
322 outbuf_size
= val
->data
.length
;
323 *r
->out
.type
= val
->type
;
326 status
= WERR_BADFILE
;
328 if (*r
->in
.data_size
< outbuf_size
) {
329 *r
->out
.data_size
= outbuf_size
;
330 status
= r
->in
.data
? WERR_MORE_DATA
: WERR_OK
;
332 *r
->out
.data_length
= outbuf_size
;
333 *r
->out
.data_size
= outbuf_size
;
335 memcpy(r
->out
.data
, outbuf
, outbuf_size
);
340 if (free_prs
) prs_mem_free(&prs_hkpd
);
341 if (free_buf
) SAFE_FREE(outbuf
);
346 /*****************************************************************************
348 ****************************************************************************/
350 WERROR
_winreg_QueryInfoKey(struct pipes_struct
*p
,
351 struct winreg_QueryInfoKey
*r
)
353 WERROR status
= WERR_OK
;
354 struct registry_key
*regkey
= find_regkey_by_hnd( p
, r
->in
.handle
);
359 r
->out
.classname
->name
= NULL
;
361 status
= reg_queryinfokey(regkey
, r
->out
.num_subkeys
, r
->out
.max_subkeylen
,
362 r
->out
.max_classlen
, r
->out
.num_values
, r
->out
.max_valnamelen
,
363 r
->out
.max_valbufsize
, r
->out
.secdescsize
,
364 r
->out
.last_changed_time
);
365 if (!W_ERROR_IS_OK(status
)) {
370 * These calculations account for the registry buffers being
371 * UTF-16. They are inexact at best, but so far they worked.
374 *r
->out
.max_subkeylen
*= 2;
376 *r
->out
.max_valnamelen
+= 1;
377 *r
->out
.max_valnamelen
*= 2;
383 /*****************************************************************************
385 ****************************************************************************/
387 WERROR
_winreg_GetVersion(struct pipes_struct
*p
,
388 struct winreg_GetVersion
*r
)
390 struct registry_key
*regkey
= find_regkey_by_hnd( p
, r
->in
.handle
);
395 return reg_getversion(r
->out
.version
);
399 /*****************************************************************************
401 ****************************************************************************/
403 WERROR
_winreg_EnumKey(struct pipes_struct
*p
,
404 struct winreg_EnumKey
*r
)
407 struct registry_key
*key
= find_regkey_by_hnd( p
, r
->in
.handle
);
412 if ( !r
->in
.name
|| !r
->in
.keyclass
)
413 return WERR_INVALID_PARAM
;
415 DEBUG(8,("_winreg_EnumKey: enumerating key [%s]\n", key
->key
->name
));
417 err
= reg_enumkey(p
->mem_ctx
, key
, r
->in
.enum_index
, (char **)&r
->out
.name
->name
,
418 r
->out
.last_changed_time
);
419 if (!W_ERROR_IS_OK(err
)) {
422 r
->out
.keyclass
->name
= "";
426 /*****************************************************************************
428 ****************************************************************************/
430 WERROR
_winreg_EnumValue(struct pipes_struct
*p
,
431 struct winreg_EnumValue
*r
)
434 struct registry_key
*key
= find_regkey_by_hnd( p
, r
->in
.handle
);
436 struct registry_value
*val
;
442 return WERR_INVALID_PARAM
;
444 DEBUG(8,("_winreg_EnumValue: enumerating values for key [%s]\n",
447 err
= reg_enumvalue(p
->mem_ctx
, key
, r
->in
.enum_index
, &valname
, &val
);
448 if (!W_ERROR_IS_OK(err
)) {
452 if (r
->out
.name
!= NULL
) {
453 r
->out
.name
->name
= valname
;
456 if (r
->out
.type
!= NULL
) {
457 *r
->out
.type
= val
->type
;
460 if (r
->out
.value
!= NULL
) {
461 if ((r
->out
.size
== NULL
) || (r
->out
.length
== NULL
)) {
462 return WERR_INVALID_PARAM
;
465 if (val
->data
.length
> *r
->out
.size
) {
466 return WERR_MORE_DATA
;
469 memcpy( r
->out
.value
, val
->data
.data
, val
->data
.length
);
472 if (r
->out
.length
!= NULL
) {
473 *r
->out
.length
= val
->data
.length
;
475 if (r
->out
.size
!= NULL
) {
476 *r
->out
.size
= val
->data
.length
;
482 /*******************************************************************
483 _winreg_InitiateSystemShutdown
484 ********************************************************************/
486 WERROR
_winreg_InitiateSystemShutdown(struct pipes_struct
*p
,
487 struct winreg_InitiateSystemShutdown
*r
)
489 struct winreg_InitiateSystemShutdownEx s
;
491 s
.in
.hostname
= r
->in
.hostname
;
492 s
.in
.message
= r
->in
.message
;
493 s
.in
.timeout
= r
->in
.timeout
;
494 s
.in
.force_apps
= r
->in
.force_apps
;
495 s
.in
.do_reboot
= r
->in
.do_reboot
;
498 /* thunk down to _winreg_InitiateSystemShutdownEx()
499 (just returns a status) */
501 return _winreg_InitiateSystemShutdownEx( p
, &s
);
504 /*******************************************************************
505 _winreg_InitiateSystemShutdownEx
506 ********************************************************************/
508 #define SHUTDOWN_R_STRING "-r"
509 #define SHUTDOWN_F_STRING "-f"
512 WERROR
_winreg_InitiateSystemShutdownEx(struct pipes_struct
*p
,
513 struct winreg_InitiateSystemShutdownEx
*r
)
515 char *shutdown_script
= NULL
;
525 shutdown_script
= talloc_strdup(p
->mem_ctx
, lp_shutdown_script());
526 if (!shutdown_script
) {
529 if (!*shutdown_script
) {
530 return WERR_ACCESS_DENIED
;
533 /* pull the message string and perform necessary sanity checks on it */
535 if ( r
->in
.message
&& r
->in
.message
->string
) {
536 if ( (msg
= talloc_strdup(p
->mem_ctx
, r
->in
.message
->string
)) == NULL
) {
539 chkmsg
= TALLOC_ARRAY(p
->mem_ctx
, char, strlen(msg
)+1);
543 alpha_strcpy(chkmsg
, msg
, NULL
, strlen(msg
)+1);
546 fstr_sprintf(str_timeout
, "%d", r
->in
.timeout
);
547 fstr_sprintf(do_reboot
, r
->in
.do_reboot
? SHUTDOWN_R_STRING
: "");
548 fstr_sprintf(f
, r
->in
.force_apps
? SHUTDOWN_F_STRING
: "");
549 fstr_sprintf(str_reason
, "%d", r
->in
.reason
);
551 shutdown_script
= talloc_all_string_sub(p
->mem_ctx
,
552 shutdown_script
, "%z", chkmsg
? chkmsg
: "");
553 if (!shutdown_script
) {
556 shutdown_script
= talloc_all_string_sub(p
->mem_ctx
,
557 shutdown_script
, "%t", str_timeout
);
558 if (!shutdown_script
) {
561 shutdown_script
= talloc_all_string_sub(p
->mem_ctx
,
562 shutdown_script
, "%r", do_reboot
);
563 if (!shutdown_script
) {
566 shutdown_script
= talloc_all_string_sub(p
->mem_ctx
,
567 shutdown_script
, "%f", f
);
568 if (!shutdown_script
) {
571 shutdown_script
= talloc_all_string_sub(p
->mem_ctx
,
572 shutdown_script
, "%x", str_reason
);
573 if (!shutdown_script
) {
577 can_shutdown
= user_has_privileges( p
->server_info
->ptok
,
578 &se_remote_shutdown
);
580 /* IF someone has privs, run the shutdown script as root. OTHERWISE run it as not root
581 Take the error return from the script and provide it as the Windows return code. */
583 /********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/
588 ret
= smbrun( shutdown_script
, NULL
);
593 /********** END SeRemoteShutdownPrivilege BLOCK **********/
595 DEBUG(3,("_reg_shutdown_ex: Running the command `%s' gave %d\n",
596 shutdown_script
, ret
));
598 return (ret
== 0) ? WERR_OK
: WERR_ACCESS_DENIED
;
601 /*******************************************************************
602 _winreg_AbortSystemShutdown
603 ********************************************************************/
605 WERROR
_winreg_AbortSystemShutdown(struct pipes_struct
*p
,
606 struct winreg_AbortSystemShutdown
*r
)
608 const char *abort_shutdown_script
;
612 abort_shutdown_script
= lp_abort_shutdown_script();
614 if (!*abort_shutdown_script
)
615 return WERR_ACCESS_DENIED
;
617 can_shutdown
= user_has_privileges( p
->server_info
->ptok
,
618 &se_remote_shutdown
);
620 /********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/
625 ret
= smbrun( abort_shutdown_script
, NULL
);
630 /********** END SeRemoteShutdownPrivilege BLOCK **********/
632 DEBUG(3,("_winreg_AbortSystemShutdown: Running the command `%s' gave %d\n",
633 abort_shutdown_script
, ret
));
635 return (ret
== 0) ? WERR_OK
: WERR_ACCESS_DENIED
;
638 /*******************************************************************
639 ********************************************************************/
641 static int validate_reg_filename(TALLOC_CTX
*ctx
, char **pp_fname
)
644 int num_services
= lp_numservices();
646 const char *share_path
;
647 char *fname
= *pp_fname
;
649 /* convert to a unix path, stripping the C:\ along the way */
651 if (!(p
= valid_share_pathname(ctx
, fname
))) {
655 /* has to exist within a valid file share */
657 for (snum
=0; snum
<num_services
; snum
++) {
658 if (!lp_snum_ok(snum
) || lp_print_ok(snum
)) {
662 share_path
= lp_pathname(snum
);
664 /* make sure we have a path (e.g. [homes] ) */
665 if (strlen(share_path
) == 0) {
669 if (strncmp(share_path
, p
, strlen(share_path
)) == 0) {
675 return (snum
< num_services
) ? snum
: -1;
678 /*******************************************************************
680 ********************************************************************/
682 WERROR
_winreg_RestoreKey(struct pipes_struct
*p
,
683 struct winreg_RestoreKey
*r
)
685 struct registry_key
*regkey
= find_regkey_by_hnd( p
, r
->in
.handle
);
692 if ( !r
->in
.filename
|| !r
->in
.filename
->name
)
693 return WERR_INVALID_PARAM
;
695 fname
= talloc_strdup(p
->mem_ctx
, r
->in
.filename
->name
);
700 DEBUG(8,("_winreg_RestoreKey: verifying restore of key [%s] from "
701 "\"%s\"\n", regkey
->key
->name
, fname
));
703 if ((snum
= validate_reg_filename(p
->mem_ctx
, &fname
)) == -1)
704 return WERR_OBJECT_PATH_INVALID
;
706 /* user must posses SeRestorePrivilege for this this proceed */
708 if ( !user_has_privileges( p
->server_info
->ptok
, &se_restore
) )
709 return WERR_ACCESS_DENIED
;
711 DEBUG(2,("_winreg_RestoreKey: Restoring [%s] from %s in share %s\n",
712 regkey
->key
->name
, fname
, lp_servicename(snum
) ));
714 return reg_restorekey(regkey
, fname
);
717 /*******************************************************************
719 ********************************************************************/
721 WERROR
_winreg_SaveKey(struct pipes_struct
*p
,
722 struct winreg_SaveKey
*r
)
724 struct registry_key
*regkey
= find_regkey_by_hnd( p
, r
->in
.handle
);
731 if ( !r
->in
.filename
|| !r
->in
.filename
->name
)
732 return WERR_INVALID_PARAM
;
734 fname
= talloc_strdup(p
->mem_ctx
, r
->in
.filename
->name
);
739 DEBUG(8,("_winreg_SaveKey: verifying backup of key [%s] to \"%s\"\n",
740 regkey
->key
->name
, fname
));
742 if ((snum
= validate_reg_filename(p
->mem_ctx
, &fname
)) == -1 )
743 return WERR_OBJECT_PATH_INVALID
;
745 DEBUG(2,("_winreg_SaveKey: Saving [%s] to %s in share %s\n",
746 regkey
->key
->name
, fname
, lp_servicename(snum
) ));
748 return reg_savekey(regkey
, fname
);
751 /*******************************************************************
753 ********************************************************************/
755 WERROR
_winreg_SaveKeyEx(struct pipes_struct
*p
,
756 struct winreg_SaveKeyEx
*r
)
758 /* fill in your code here if you think this call should
761 p
->rng_fault_state
= True
;
762 return WERR_NOT_SUPPORTED
;
765 /*******************************************************************
767 ********************************************************************/
769 WERROR
_winreg_CreateKey(struct pipes_struct
*p
,
770 struct winreg_CreateKey
*r
)
772 struct registry_key
*parent
= find_regkey_by_hnd(p
, r
->in
.handle
);
773 struct registry_key
*new_key
;
779 DEBUG(10, ("_winreg_CreateKey called with parent key '%s' and "
780 "subkey name '%s'\n", parent
->key
->name
, r
->in
.name
.name
));
782 result
= reg_createkey(NULL
, parent
, r
->in
.name
.name
, r
->in
.access_mask
,
783 &new_key
, r
->out
.action_taken
);
784 if (!W_ERROR_IS_OK(result
)) {
788 if (!create_policy_hnd(p
, r
->out
.new_handle
, new_key
)) {
789 TALLOC_FREE(new_key
);
796 /*******************************************************************
798 ********************************************************************/
800 WERROR
_winreg_SetValue(struct pipes_struct
*p
,
801 struct winreg_SetValue
*r
)
803 struct registry_key
*key
= find_regkey_by_hnd(p
, r
->in
.handle
);
804 struct registry_value
*val
;
809 DEBUG(8,("_winreg_SetValue: Setting value for [%s:%s]\n",
810 key
->key
->name
, r
->in
.name
.name
));
812 val
= talloc_zero(p
->mem_ctx
, struct registry_value
);
817 val
->type
= r
->in
.type
;
818 val
->data
= data_blob_talloc(p
->mem_ctx
, r
->in
.data
, r
->in
.size
);
820 return reg_setvalue(key
, r
->in
.name
.name
, val
);
823 /*******************************************************************
825 ********************************************************************/
827 WERROR
_winreg_DeleteKey(struct pipes_struct
*p
,
828 struct winreg_DeleteKey
*r
)
830 struct registry_key
*parent
= find_regkey_by_hnd(p
, r
->in
.handle
);
835 return reg_deletekey(parent
, r
->in
.key
.name
);
839 /*******************************************************************
841 ********************************************************************/
843 WERROR
_winreg_DeleteValue(struct pipes_struct
*p
,
844 struct winreg_DeleteValue
*r
)
846 struct registry_key
*key
= find_regkey_by_hnd(p
, r
->in
.handle
);
851 return reg_deletevalue(key
, r
->in
.value
.name
);
854 /*******************************************************************
855 _winreg_GetKeySecurity
856 ********************************************************************/
858 WERROR
_winreg_GetKeySecurity(struct pipes_struct
*p
,
859 struct winreg_GetKeySecurity
*r
)
861 struct registry_key
*key
= find_regkey_by_hnd(p
, r
->in
.handle
);
863 struct security_descriptor
*secdesc
;
870 /* access checks first */
872 if ( !(key
->key
->access_granted
& SEC_STD_READ_CONTROL
) )
873 return WERR_ACCESS_DENIED
;
875 err
= reg_getkeysecurity(p
->mem_ctx
, key
, &secdesc
);
876 if (!W_ERROR_IS_OK(err
)) {
880 err
= ntstatus_to_werror(marshall_sec_desc(p
->mem_ctx
, secdesc
,
882 if (!W_ERROR_IS_OK(err
)) {
886 if (len
> r
->out
.sd
->size
) {
887 r
->out
.sd
->size
= len
;
888 return WERR_INSUFFICIENT_BUFFER
;
891 r
->out
.sd
->size
= len
;
892 r
->out
.sd
->len
= len
;
893 r
->out
.sd
->data
= data
;
898 /*******************************************************************
899 _winreg_SetKeySecurity
900 ********************************************************************/
902 WERROR
_winreg_SetKeySecurity(struct pipes_struct
*p
,
903 struct winreg_SetKeySecurity
*r
)
905 struct registry_key
*key
= find_regkey_by_hnd(p
, r
->in
.handle
);
906 struct security_descriptor
*secdesc
;
912 /* access checks first */
914 if ( !(key
->key
->access_granted
& SEC_STD_WRITE_DAC
) )
915 return WERR_ACCESS_DENIED
;
917 err
= ntstatus_to_werror(unmarshall_sec_desc(p
->mem_ctx
, r
->in
.sd
->data
,
918 r
->in
.sd
->len
, &secdesc
));
919 if (!W_ERROR_IS_OK(err
)) {
923 return reg_setkeysecurity(key
, secdesc
);
926 /*******************************************************************
928 ********************************************************************/
930 WERROR
_winreg_FlushKey(struct pipes_struct
*p
,
931 struct winreg_FlushKey
*r
)
933 /* I'm just replying OK because there's not a lot
934 here I see to do i --jerry */
939 /*******************************************************************
941 ********************************************************************/
943 WERROR
_winreg_UnLoadKey(struct pipes_struct
*p
,
944 struct winreg_UnLoadKey
*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 /*******************************************************************
955 ********************************************************************/
957 WERROR
_winreg_ReplaceKey(struct pipes_struct
*p
,
958 struct winreg_ReplaceKey
*r
)
960 /* fill in your code here if you think this call should
963 p
->rng_fault_state
= True
;
964 return WERR_NOT_SUPPORTED
;
967 /*******************************************************************
969 ********************************************************************/
971 WERROR
_winreg_LoadKey(struct pipes_struct
*p
,
972 struct winreg_LoadKey
*r
)
974 /* fill in your code here if you think this call should
977 p
->rng_fault_state
= True
;
978 return WERR_NOT_SUPPORTED
;
981 /*******************************************************************
982 _winreg_NotifyChangeKeyValue
983 ********************************************************************/
985 WERROR
_winreg_NotifyChangeKeyValue(struct pipes_struct
*p
,
986 struct winreg_NotifyChangeKeyValue
*r
)
988 return WERR_NOT_SUPPORTED
;
991 /*******************************************************************
992 _winreg_QueryMultipleValues
993 ********************************************************************/
995 WERROR
_winreg_QueryMultipleValues(struct pipes_struct
*p
,
996 struct winreg_QueryMultipleValues
*r
)
998 struct winreg_QueryMultipleValues2 r2
;
1001 r2
.in
.key_handle
= r
->in
.key_handle
;
1002 r2
.in
.values_in
= r
->in
.values_in
;
1003 r2
.in
.num_values
= r
->in
.num_values
;
1004 r2
.in
.offered
= r
->in
.buffer_size
;
1005 r2
.in
.buffer
= r
->in
.buffer
;
1006 r2
.out
.values_out
= r
->out
.values_out
;
1007 r2
.out
.needed
= &needed
;
1008 r2
.out
.buffer
= r
->out
.buffer
;
1010 return _winreg_QueryMultipleValues2(p
, &r2
);
1013 /*******************************************************************
1014 ********************************************************************/
1016 static WERROR
construct_multiple_entry(TALLOC_CTX
*mem_ctx
,
1017 const char *valuename
,
1018 uint32_t value_length
,
1020 enum winreg_Type type
,
1021 struct QueryMultipleValue
*r
)
1023 r
->ve_valuename
= talloc_zero(mem_ctx
, struct winreg_ValNameBuf
);
1024 if (r
->ve_valuename
== NULL
) {
1028 r
->ve_valuename
->name
= talloc_strdup(r
->ve_valuename
, valuename
? valuename
: "");
1029 if (r
->ve_valuename
->name
== NULL
) {
1033 r
->ve_valuename
->size
= strlen_m_term(r
->ve_valuename
->name
)*2;
1034 r
->ve_valuelen
= value_length
;
1035 r
->ve_valueptr
= offset
;
1041 /*******************************************************************
1042 _winreg_QueryMultipleValues2
1043 ********************************************************************/
1045 WERROR
_winreg_QueryMultipleValues2(struct pipes_struct
*p
,
1046 struct winreg_QueryMultipleValues2
*r
)
1048 struct registry_key
*regkey
= find_regkey_by_hnd(p
, r
->in
.key_handle
);
1049 struct registry_value
*vals
= NULL
;
1050 const char **names
= NULL
;
1051 uint32_t offset
= 0, num_vals
= 0;
1060 names
= talloc_zero_array(p
->mem_ctx
, const char *, r
->in
.num_values
);
1061 if (names
== NULL
) {
1065 for (i
=0; i
< r
->in
.num_values
; i
++) {
1066 if (r
->in
.values_in
[i
].ve_valuename
&&
1067 r
->in
.values_in
[i
].ve_valuename
->name
) {
1068 names
[i
] = talloc_strdup(names
,
1069 r
->in
.values_in
[i
].ve_valuename
->name
);
1070 if (names
[i
] == NULL
) {
1076 err
= reg_querymultiplevalues(p
->mem_ctx
, regkey
,
1077 r
->in
.num_values
, names
,
1079 if (!W_ERROR_IS_OK(err
)) {
1083 result
= data_blob_talloc(p
->mem_ctx
, NULL
, 0);
1085 for (i
=0; i
< r
->in
.num_values
; i
++) {
1086 const char *valuename
= NULL
;
1088 if (vals
[i
].data
.length
> 0) {
1089 if (!data_blob_append(p
->mem_ctx
, &result
,
1091 vals
[i
].data
.length
)) {
1096 if (r
->in
.values_in
[i
].ve_valuename
&&
1097 r
->in
.values_in
[i
].ve_valuename
->name
) {
1098 valuename
= r
->in
.values_in
[i
].ve_valuename
->name
;
1101 err
= construct_multiple_entry(r
->out
.values_out
,
1103 vals
[i
].data
.length
,
1106 &r
->out
.values_out
[i
]);
1107 if (!W_ERROR_IS_OK(err
)) {
1111 offset
+= vals
[i
].data
.length
;
1114 *r
->out
.needed
= result
.length
;
1116 if (r
->in
.num_values
!= num_vals
) {
1117 return WERR_BADFILE
;
1120 if (*r
->in
.offered
>= *r
->out
.needed
) {
1121 if (r
->out
.buffer
) {
1122 memcpy(r
->out
.buffer
, result
.data
, MIN(result
.length
, *r
->in
.offered
));
1126 return WERR_MORE_DATA
;
1130 /*******************************************************************
1132 ********************************************************************/
1134 WERROR
_winreg_DeleteKeyEx(struct pipes_struct
*p
,
1135 struct winreg_DeleteKeyEx
*r
)
1137 /* fill in your code here if you think this call should
1140 p
->rng_fault_state
= True
;
1141 return WERR_NOT_SUPPORTED
;