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(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( pipes_struct
*p
, struct policy_handle
*hnd
,
58 struct registry_key
*parent
,
59 const char *subkeyname
,
60 uint32 access_desired
)
62 WERROR result
= WERR_OK
;
63 struct registry_key
*key
;
66 result
= reg_openhive(p
->mem_ctx
, subkeyname
, access_desired
,
67 p
->server_info
->ptok
, &key
);
70 result
= reg_openkey(p
->mem_ctx
, parent
, subkeyname
,
71 access_desired
, &key
);
74 if ( !W_ERROR_IS_OK(result
) ) {
78 if ( !create_policy_hnd( p
, hnd
, key
) ) {
85 /*******************************************************************
86 Function for open a new registry handle and creating a handle
87 Note that P should be valid & hnd should already have space
88 *******************************************************************/
90 static bool close_registry_key(pipes_struct
*p
, struct policy_handle
*hnd
)
92 struct registry_key
*regkey
= find_regkey_by_hnd(p
, hnd
);
95 DEBUG(2,("close_registry_key: Invalid handle (%s:%u:%u)\n",
100 close_policy_hnd(p
, hnd
);
105 /********************************************************************
107 ********************************************************************/
109 WERROR
_winreg_CloseKey(pipes_struct
*p
, struct winreg_CloseKey
*r
)
111 /* close the policy handle */
113 if (!close_registry_key(p
, r
->in
.handle
))
116 ZERO_STRUCTP(r
->out
.handle
);
121 /*******************************************************************
123 ********************************************************************/
125 WERROR
_winreg_OpenHKLM(pipes_struct
*p
, struct winreg_OpenHKLM
*r
)
127 return open_registry_key(p
, r
->out
.handle
, NULL
, KEY_HKLM
, r
->in
.access_mask
);
130 /*******************************************************************
132 ********************************************************************/
134 WERROR
_winreg_OpenHKPD(pipes_struct
*p
, struct winreg_OpenHKPD
*r
)
136 return open_registry_key(p
, r
->out
.handle
, NULL
, KEY_HKPD
, r
->in
.access_mask
);
139 /*******************************************************************
141 ********************************************************************/
143 WERROR
_winreg_OpenHKPT(pipes_struct
*p
, struct winreg_OpenHKPT
*r
)
145 return open_registry_key(p
, r
->out
.handle
, NULL
, KEY_HKPT
, r
->in
.access_mask
);
148 /*******************************************************************
150 ********************************************************************/
152 WERROR
_winreg_OpenHKCR(pipes_struct
*p
, struct winreg_OpenHKCR
*r
)
154 return open_registry_key(p
, r
->out
.handle
, NULL
, KEY_HKCR
, r
->in
.access_mask
);
157 /*******************************************************************
159 ********************************************************************/
161 WERROR
_winreg_OpenHKU(pipes_struct
*p
, struct winreg_OpenHKU
*r
)
163 return open_registry_key(p
, r
->out
.handle
, NULL
, KEY_HKU
, r
->in
.access_mask
);
166 /*******************************************************************
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 /*******************************************************************
177 ********************************************************************/
179 WERROR
_winreg_OpenHKCC(pipes_struct
*p
, struct winreg_OpenHKCC
*r
)
181 return open_registry_key(p
, r
->out
.handle
, NULL
, KEY_HKCC
, r
->in
.access_mask
);
184 /*******************************************************************
186 ********************************************************************/
188 WERROR
_winreg_OpenHKDD(pipes_struct
*p
, struct winreg_OpenHKDD
*r
)
190 return open_registry_key(p
, r
->out
.handle
, NULL
, KEY_HKDD
, r
->in
.access_mask
);
193 /*******************************************************************
195 ********************************************************************/
197 WERROR
_winreg_OpenHKPN(pipes_struct
*p
, struct winreg_OpenHKPN
*r
)
199 return open_registry_key(p
, r
->out
.handle
, NULL
, KEY_HKPN
, r
->in
.access_mask
);
202 /*******************************************************************
204 ********************************************************************/
206 WERROR
_winreg_OpenKey(pipes_struct
*p
, struct winreg_OpenKey
*r
)
208 struct registry_key
*parent
= find_regkey_by_hnd(p
, r
->in
.parent_handle
);
213 return open_registry_key(p
, r
->out
.handle
, parent
, r
->in
.keyname
.name
, r
->in
.access_mask
);
216 /*******************************************************************
218 ********************************************************************/
220 WERROR
_winreg_QueryValue(pipes_struct
*p
, struct winreg_QueryValue
*r
)
222 WERROR status
= WERR_BADFILE
;
223 struct registry_key
*regkey
= find_regkey_by_hnd( p
, r
->in
.handle
);
227 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 outbuf
= val
->data
.data
;
308 outbuf_size
= val
->data
.length
;
309 *r
->out
.type
= val
->type
;
312 status
= WERR_BADFILE
;
314 if (*r
->in
.data_size
< outbuf_size
) {
315 *r
->out
.data_size
= outbuf_size
;
316 status
= r
->in
.data
? WERR_MORE_DATA
: WERR_OK
;
318 *r
->out
.data_length
= outbuf_size
;
319 *r
->out
.data_size
= outbuf_size
;
321 memcpy(r
->out
.data
, outbuf
, outbuf_size
);
326 if (free_prs
) prs_mem_free(&prs_hkpd
);
327 if (free_buf
) SAFE_FREE(outbuf
);
332 /*****************************************************************************
334 ****************************************************************************/
336 WERROR
_winreg_QueryInfoKey(pipes_struct
*p
, struct winreg_QueryInfoKey
*r
)
338 WERROR status
= WERR_OK
;
339 struct registry_key
*regkey
= find_regkey_by_hnd( p
, r
->in
.handle
);
344 r
->out
.classname
->name
= NULL
;
346 status
= reg_queryinfokey(regkey
, r
->out
.num_subkeys
, r
->out
.max_subkeylen
,
347 r
->out
.max_classlen
, r
->out
.num_values
, r
->out
.max_valnamelen
,
348 r
->out
.max_valbufsize
, r
->out
.secdescsize
,
349 r
->out
.last_changed_time
);
350 if (!W_ERROR_IS_OK(status
)) {
355 * These calculations account for the registry buffers being
356 * UTF-16. They are inexact at best, but so far they worked.
359 *r
->out
.max_subkeylen
*= 2;
361 *r
->out
.max_valnamelen
+= 1;
362 *r
->out
.max_valnamelen
*= 2;
368 /*****************************************************************************
370 ****************************************************************************/
372 WERROR
_winreg_GetVersion(pipes_struct
*p
, struct winreg_GetVersion
*r
)
374 struct registry_key
*regkey
= find_regkey_by_hnd( p
, r
->in
.handle
);
379 return reg_getversion(r
->out
.version
);
383 /*****************************************************************************
385 ****************************************************************************/
387 WERROR
_winreg_EnumKey(pipes_struct
*p
, struct winreg_EnumKey
*r
)
390 struct registry_key
*key
= find_regkey_by_hnd( p
, r
->in
.handle
);
395 if ( !r
->in
.name
|| !r
->in
.keyclass
)
396 return WERR_INVALID_PARAM
;
398 DEBUG(8,("_winreg_EnumKey: enumerating key [%s]\n", key
->key
->name
));
400 err
= reg_enumkey(p
->mem_ctx
, key
, r
->in
.enum_index
, (char **)&r
->out
.name
->name
,
401 r
->out
.last_changed_time
);
402 if (!W_ERROR_IS_OK(err
)) {
405 r
->out
.keyclass
->name
= "";
409 /*****************************************************************************
411 ****************************************************************************/
413 WERROR
_winreg_EnumValue(pipes_struct
*p
, struct winreg_EnumValue
*r
)
416 struct registry_key
*key
= find_regkey_by_hnd( p
, r
->in
.handle
);
418 struct registry_value
*val
;
424 return WERR_INVALID_PARAM
;
426 DEBUG(8,("_winreg_EnumValue: enumerating values for key [%s]\n",
429 err
= reg_enumvalue(p
->mem_ctx
, key
, r
->in
.enum_index
, &valname
, &val
);
430 if (!W_ERROR_IS_OK(err
)) {
434 if (r
->out
.name
!= NULL
) {
435 r
->out
.name
->name
= valname
;
438 if (r
->out
.type
!= NULL
) {
439 *r
->out
.type
= val
->type
;
442 if (r
->out
.value
!= NULL
) {
443 if ((r
->out
.size
== NULL
) || (r
->out
.length
== NULL
)) {
444 return WERR_INVALID_PARAM
;
447 if (val
->data
.length
> *r
->out
.size
) {
448 return WERR_MORE_DATA
;
451 memcpy( r
->out
.value
, val
->data
.data
, val
->data
.length
);
454 if (r
->out
.length
!= NULL
) {
455 *r
->out
.length
= val
->data
.length
;
457 if (r
->out
.size
!= NULL
) {
458 *r
->out
.size
= val
->data
.length
;
464 /*******************************************************************
465 _winreg_InitiateSystemShutdown
466 ********************************************************************/
468 WERROR
_winreg_InitiateSystemShutdown(pipes_struct
*p
, struct winreg_InitiateSystemShutdown
*r
)
470 struct winreg_InitiateSystemShutdownEx s
;
472 s
.in
.hostname
= r
->in
.hostname
;
473 s
.in
.message
= r
->in
.message
;
474 s
.in
.timeout
= r
->in
.timeout
;
475 s
.in
.force_apps
= r
->in
.force_apps
;
476 s
.in
.do_reboot
= r
->in
.do_reboot
;
479 /* thunk down to _winreg_InitiateSystemShutdownEx()
480 (just returns a status) */
482 return _winreg_InitiateSystemShutdownEx( p
, &s
);
485 /*******************************************************************
486 _winreg_InitiateSystemShutdownEx
487 ********************************************************************/
489 #define SHUTDOWN_R_STRING "-r"
490 #define SHUTDOWN_F_STRING "-f"
493 WERROR
_winreg_InitiateSystemShutdownEx(pipes_struct
*p
, struct winreg_InitiateSystemShutdownEx
*r
)
495 char *shutdown_script
= NULL
;
505 shutdown_script
= talloc_strdup(p
->mem_ctx
, lp_shutdown_script());
506 if (!shutdown_script
) {
509 if (!*shutdown_script
) {
510 return WERR_ACCESS_DENIED
;
513 /* pull the message string and perform necessary sanity checks on it */
515 if ( r
->in
.message
&& r
->in
.message
->string
) {
516 if ( (msg
= talloc_strdup(p
->mem_ctx
, r
->in
.message
->string
)) == NULL
) {
519 chkmsg
= TALLOC_ARRAY(p
->mem_ctx
, char, strlen(msg
)+1);
523 alpha_strcpy(chkmsg
, msg
, NULL
, strlen(msg
)+1);
526 fstr_sprintf(str_timeout
, "%d", r
->in
.timeout
);
527 fstr_sprintf(do_reboot
, r
->in
.do_reboot
? SHUTDOWN_R_STRING
: "");
528 fstr_sprintf(f
, r
->in
.force_apps
? SHUTDOWN_F_STRING
: "");
529 fstr_sprintf(str_reason
, "%d", r
->in
.reason
);
531 shutdown_script
= talloc_all_string_sub(p
->mem_ctx
,
532 shutdown_script
, "%z", chkmsg
? chkmsg
: "");
533 if (!shutdown_script
) {
536 shutdown_script
= talloc_all_string_sub(p
->mem_ctx
,
537 shutdown_script
, "%t", str_timeout
);
538 if (!shutdown_script
) {
541 shutdown_script
= talloc_all_string_sub(p
->mem_ctx
,
542 shutdown_script
, "%r", do_reboot
);
543 if (!shutdown_script
) {
546 shutdown_script
= talloc_all_string_sub(p
->mem_ctx
,
547 shutdown_script
, "%f", f
);
548 if (!shutdown_script
) {
551 shutdown_script
= talloc_all_string_sub(p
->mem_ctx
,
552 shutdown_script
, "%x", str_reason
);
553 if (!shutdown_script
) {
557 can_shutdown
= user_has_privileges( p
->server_info
->ptok
,
558 &se_remote_shutdown
);
560 /* IF someone has privs, run the shutdown script as root. OTHERWISE run it as not root
561 Take the error return from the script and provide it as the Windows return code. */
563 /********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/
568 ret
= smbrun( shutdown_script
, NULL
);
573 /********** END SeRemoteShutdownPrivilege BLOCK **********/
575 DEBUG(3,("_reg_shutdown_ex: Running the command `%s' gave %d\n",
576 shutdown_script
, ret
));
578 return (ret
== 0) ? WERR_OK
: WERR_ACCESS_DENIED
;
581 /*******************************************************************
582 _winreg_AbortSystemShutdown
583 ********************************************************************/
585 WERROR
_winreg_AbortSystemShutdown(pipes_struct
*p
, struct winreg_AbortSystemShutdown
*r
)
587 const char *abort_shutdown_script
;
591 abort_shutdown_script
= lp_abort_shutdown_script();
593 if (!*abort_shutdown_script
)
594 return WERR_ACCESS_DENIED
;
596 can_shutdown
= user_has_privileges( p
->server_info
->ptok
,
597 &se_remote_shutdown
);
599 /********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/
604 ret
= smbrun( abort_shutdown_script
, NULL
);
609 /********** END SeRemoteShutdownPrivilege BLOCK **********/
611 DEBUG(3,("_winreg_AbortSystemShutdown: 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 /*******************************************************************
659 ********************************************************************/
661 WERROR
_winreg_RestoreKey(pipes_struct
*p
, struct winreg_RestoreKey
*r
)
663 struct registry_key
*regkey
= find_regkey_by_hnd( p
, r
->in
.handle
);
670 if ( !r
->in
.filename
|| !r
->in
.filename
->name
)
671 return WERR_INVALID_PARAM
;
673 fname
= talloc_strdup(p
->mem_ctx
, r
->in
.filename
->name
);
678 DEBUG(8,("_winreg_RestoreKey: verifying restore of key [%s] from "
679 "\"%s\"\n", regkey
->key
->name
, fname
));
681 if ((snum
= validate_reg_filename(p
->mem_ctx
, &fname
)) == -1)
682 return WERR_OBJECT_PATH_INVALID
;
684 /* user must posses SeRestorePrivilege for this this proceed */
686 if ( !user_has_privileges( p
->server_info
->ptok
, &se_restore
) )
687 return WERR_ACCESS_DENIED
;
689 DEBUG(2,("_winreg_RestoreKey: Restoring [%s] from %s in share %s\n",
690 regkey
->key
->name
, fname
, lp_servicename(snum
) ));
692 return reg_restorekey(regkey
, fname
);
695 /*******************************************************************
697 ********************************************************************/
699 WERROR
_winreg_SaveKey(pipes_struct
*p
, struct winreg_SaveKey
*r
)
701 struct registry_key
*regkey
= find_regkey_by_hnd( p
, r
->in
.handle
);
708 if ( !r
->in
.filename
|| !r
->in
.filename
->name
)
709 return WERR_INVALID_PARAM
;
711 fname
= talloc_strdup(p
->mem_ctx
, r
->in
.filename
->name
);
716 DEBUG(8,("_winreg_SaveKey: verifying backup of key [%s] to \"%s\"\n",
717 regkey
->key
->name
, fname
));
719 if ((snum
= validate_reg_filename(p
->mem_ctx
, &fname
)) == -1 )
720 return WERR_OBJECT_PATH_INVALID
;
722 DEBUG(2,("_winreg_SaveKey: Saving [%s] to %s in share %s\n",
723 regkey
->key
->name
, fname
, lp_servicename(snum
) ));
725 return reg_savekey(regkey
, fname
);
728 /*******************************************************************
730 ********************************************************************/
732 WERROR
_winreg_SaveKeyEx(pipes_struct
*p
, struct winreg_SaveKeyEx
*r
)
734 /* fill in your code here if you think this call should
737 p
->rng_fault_state
= True
;
738 return WERR_NOT_SUPPORTED
;
741 /*******************************************************************
743 ********************************************************************/
745 WERROR
_winreg_CreateKey( pipes_struct
*p
, struct winreg_CreateKey
*r
)
747 struct registry_key
*parent
= find_regkey_by_hnd(p
, r
->in
.handle
);
748 struct registry_key
*new_key
;
754 DEBUG(10, ("_winreg_CreateKey called with parent key '%s' and "
755 "subkey name '%s'\n", parent
->key
->name
, r
->in
.name
.name
));
757 result
= reg_createkey(NULL
, parent
, r
->in
.name
.name
, r
->in
.access_mask
,
758 &new_key
, r
->out
.action_taken
);
759 if (!W_ERROR_IS_OK(result
)) {
763 if (!create_policy_hnd(p
, r
->out
.new_handle
, new_key
)) {
764 TALLOC_FREE(new_key
);
771 /*******************************************************************
773 ********************************************************************/
775 WERROR
_winreg_SetValue(pipes_struct
*p
, struct winreg_SetValue
*r
)
777 struct registry_key
*key
= find_regkey_by_hnd(p
, r
->in
.handle
);
778 struct registry_value
*val
;
783 DEBUG(8,("_winreg_SetValue: Setting value for [%s:%s]\n",
784 key
->key
->name
, r
->in
.name
.name
));
786 val
= talloc_zero(p
->mem_ctx
, struct registry_value
);
791 val
->type
= r
->in
.type
;
792 val
->data
= data_blob_talloc(p
->mem_ctx
, r
->in
.data
, r
->in
.size
);
794 return reg_setvalue(key
, r
->in
.name
.name
, val
);
797 /*******************************************************************
799 ********************************************************************/
801 WERROR
_winreg_DeleteKey(pipes_struct
*p
, struct winreg_DeleteKey
*r
)
803 struct registry_key
*parent
= find_regkey_by_hnd(p
, r
->in
.handle
);
808 return reg_deletekey(parent
, r
->in
.key
.name
);
812 /*******************************************************************
814 ********************************************************************/
816 WERROR
_winreg_DeleteValue(pipes_struct
*p
, struct winreg_DeleteValue
*r
)
818 struct registry_key
*key
= find_regkey_by_hnd(p
, r
->in
.handle
);
823 return reg_deletevalue(key
, r
->in
.value
.name
);
826 /*******************************************************************
827 _winreg_GetKeySecurity
828 ********************************************************************/
830 WERROR
_winreg_GetKeySecurity(pipes_struct
*p
, struct winreg_GetKeySecurity
*r
)
832 struct registry_key
*key
= find_regkey_by_hnd(p
, r
->in
.handle
);
834 struct security_descriptor
*secdesc
;
841 /* access checks first */
843 if ( !(key
->key
->access_granted
& SEC_STD_READ_CONTROL
) )
844 return WERR_ACCESS_DENIED
;
846 err
= reg_getkeysecurity(p
->mem_ctx
, key
, &secdesc
);
847 if (!W_ERROR_IS_OK(err
)) {
851 err
= ntstatus_to_werror(marshall_sec_desc(p
->mem_ctx
, secdesc
,
853 if (!W_ERROR_IS_OK(err
)) {
857 if (len
> r
->out
.sd
->size
) {
858 r
->out
.sd
->size
= len
;
859 return WERR_INSUFFICIENT_BUFFER
;
862 r
->out
.sd
->size
= len
;
863 r
->out
.sd
->len
= len
;
864 r
->out
.sd
->data
= data
;
869 /*******************************************************************
870 _winreg_SetKeySecurity
871 ********************************************************************/
873 WERROR
_winreg_SetKeySecurity(pipes_struct
*p
, struct winreg_SetKeySecurity
*r
)
875 struct registry_key
*key
= find_regkey_by_hnd(p
, r
->in
.handle
);
876 struct security_descriptor
*secdesc
;
882 /* access checks first */
884 if ( !(key
->key
->access_granted
& SEC_STD_WRITE_DAC
) )
885 return WERR_ACCESS_DENIED
;
887 err
= ntstatus_to_werror(unmarshall_sec_desc(p
->mem_ctx
, r
->in
.sd
->data
,
888 r
->in
.sd
->len
, &secdesc
));
889 if (!W_ERROR_IS_OK(err
)) {
893 return reg_setkeysecurity(key
, secdesc
);
896 /*******************************************************************
898 ********************************************************************/
900 WERROR
_winreg_FlushKey(pipes_struct
*p
, struct winreg_FlushKey
*r
)
902 /* I'm just replying OK because there's not a lot
903 here I see to do i --jerry */
908 /*******************************************************************
910 ********************************************************************/
912 WERROR
_winreg_UnLoadKey(pipes_struct
*p
, struct winreg_UnLoadKey
*r
)
914 /* fill in your code here if you think this call should
917 p
->rng_fault_state
= True
;
918 return WERR_NOT_SUPPORTED
;
921 /*******************************************************************
923 ********************************************************************/
925 WERROR
_winreg_ReplaceKey(pipes_struct
*p
, struct winreg_ReplaceKey
*r
)
927 /* fill in your code here if you think this call should
930 p
->rng_fault_state
= True
;
931 return WERR_NOT_SUPPORTED
;
934 /*******************************************************************
936 ********************************************************************/
938 WERROR
_winreg_LoadKey(pipes_struct
*p
, struct winreg_LoadKey
*r
)
940 /* fill in your code here if you think this call should
943 p
->rng_fault_state
= True
;
944 return WERR_NOT_SUPPORTED
;
947 /*******************************************************************
948 _winreg_NotifyChangeKeyValue
949 ********************************************************************/
951 WERROR
_winreg_NotifyChangeKeyValue(pipes_struct
*p
, struct winreg_NotifyChangeKeyValue
*r
)
953 return WERR_NOT_SUPPORTED
;
956 /*******************************************************************
957 _winreg_QueryMultipleValues
958 ********************************************************************/
960 WERROR
_winreg_QueryMultipleValues(pipes_struct
*p
,
961 struct winreg_QueryMultipleValues
*r
)
963 struct winreg_QueryMultipleValues2 r2
;
966 r2
.in
.key_handle
= r
->in
.key_handle
;
967 r2
.in
.values_in
= r
->in
.values_in
;
968 r2
.in
.num_values
= r
->in
.num_values
;
969 r2
.in
.offered
= r
->in
.buffer_size
;
970 r2
.in
.buffer
= r
->in
.buffer
;
971 r2
.out
.values_out
= r
->out
.values_out
;
972 r2
.out
.needed
= &needed
;
973 r2
.out
.buffer
= r
->out
.buffer
;
975 return _winreg_QueryMultipleValues2(p
, &r2
);
978 /*******************************************************************
979 ********************************************************************/
981 static WERROR
construct_multiple_entry(TALLOC_CTX
*mem_ctx
,
982 const char *valuename
,
983 uint32_t value_length
,
985 enum winreg_Type type
,
986 struct QueryMultipleValue
*r
)
988 r
->ve_valuename
= talloc_zero(mem_ctx
, struct winreg_ValNameBuf
);
989 if (r
->ve_valuename
== NULL
) {
993 r
->ve_valuename
->name
= talloc_strdup(r
->ve_valuename
, valuename
? valuename
: "");
994 if (r
->ve_valuename
->name
== NULL
) {
998 r
->ve_valuename
->size
= strlen_m_term(r
->ve_valuename
->name
)*2;
999 r
->ve_valuelen
= value_length
;
1000 r
->ve_valueptr
= offset
;
1006 /*******************************************************************
1007 _winreg_QueryMultipleValues2
1008 ********************************************************************/
1010 WERROR
_winreg_QueryMultipleValues2(pipes_struct
*p
,
1011 struct winreg_QueryMultipleValues2
*r
)
1013 struct registry_key
*regkey
= find_regkey_by_hnd(p
, r
->in
.key_handle
);
1014 struct registry_value
*vals
= NULL
;
1015 const char **names
= NULL
;
1016 uint32_t offset
= 0, num_vals
= 0;
1025 names
= talloc_zero_array(p
->mem_ctx
, const char *, r
->in
.num_values
);
1026 if (names
== NULL
) {
1030 for (i
=0; i
< r
->in
.num_values
; i
++) {
1031 if (r
->in
.values_in
[i
].ve_valuename
&&
1032 r
->in
.values_in
[i
].ve_valuename
->name
) {
1033 names
[i
] = talloc_strdup(names
,
1034 r
->in
.values_in
[i
].ve_valuename
->name
);
1035 if (names
[i
] == NULL
) {
1041 err
= reg_querymultiplevalues(p
->mem_ctx
, regkey
,
1042 r
->in
.num_values
, names
,
1044 if (!W_ERROR_IS_OK(err
)) {
1048 result
= data_blob_talloc(p
->mem_ctx
, NULL
, 0);
1050 for (i
=0; i
< r
->in
.num_values
; i
++) {
1051 const char *valuename
= NULL
;
1053 if (vals
[i
].data
.length
> 0) {
1054 if (!data_blob_append(p
->mem_ctx
, &result
,
1056 vals
[i
].data
.length
)) {
1061 if (r
->in
.values_in
[i
].ve_valuename
&&
1062 r
->in
.values_in
[i
].ve_valuename
->name
) {
1063 valuename
= r
->in
.values_in
[i
].ve_valuename
->name
;
1066 err
= construct_multiple_entry(r
->out
.values_out
,
1068 vals
[i
].data
.length
,
1071 &r
->out
.values_out
[i
]);
1072 if (!W_ERROR_IS_OK(err
)) {
1076 offset
+= vals
[i
].data
.length
;
1079 *r
->out
.needed
= result
.length
;
1081 if (r
->in
.num_values
!= num_vals
) {
1082 return WERR_BADFILE
;
1085 if (*r
->in
.offered
>= *r
->out
.needed
) {
1086 if (r
->out
.buffer
) {
1087 memcpy(r
->out
.buffer
, result
.data
, MIN(result
.length
, *r
->in
.offered
));
1091 return WERR_MORE_DATA
;
1095 /*******************************************************************
1097 ********************************************************************/
1099 WERROR
_winreg_DeleteKeyEx(pipes_struct
*p
, struct winreg_DeleteKeyEx
*r
)
1101 /* fill in your code here if you think this call should
1104 p
->rng_fault_state
= True
;
1105 return WERR_NOT_SUPPORTED
;