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_api.h"
28 #include "registry/reg_api_regf.h"
29 #include "registry/reg_perfcount.h"
33 #define DBGC_CLASS DBGC_RPC_SRV
35 /******************************************************************
36 Find a registry key handle and return a struct registry_key *
37 *****************************************************************/
39 static struct registry_key
*find_regkey_by_hnd(struct pipes_struct
*p
,
40 struct policy_handle
*hnd
)
42 struct registry_key
*regkey
= NULL
;
44 if(!find_policy_by_hnd(p
,hnd
,(void **)(void *)®key
)) {
45 DEBUG(2,("find_regkey_index_by_hnd: Registry Key not found: "));
52 /*******************************************************************
53 Function for open a new registry handle and creating a handle
54 Note that P should be valid & hnd should already have space
56 When we open a key, we store the full path to the key as
57 HK[LM|U]\<key>\<key>\...
58 *******************************************************************/
60 static WERROR
open_registry_key(struct pipes_struct
*p
,
61 struct policy_handle
*hnd
,
62 struct registry_key
*parent
,
63 const char *subkeyname
,
64 uint32_t access_desired
)
66 WERROR result
= WERR_OK
;
67 struct registry_key
*key
;
70 result
= reg_openhive(p
->mem_ctx
, subkeyname
, access_desired
,
71 p
->server_info
->security_token
, &key
);
74 result
= reg_openkey(p
->mem_ctx
, parent
, subkeyname
,
75 access_desired
, &key
);
78 if ( !W_ERROR_IS_OK(result
) ) {
82 if ( !create_policy_hnd( p
, hnd
, key
) ) {
89 /*******************************************************************
90 Function for open a new registry handle and creating a handle
91 Note that P should be valid & hnd should already have space
92 *******************************************************************/
94 static bool close_registry_key(struct pipes_struct
*p
,
95 struct policy_handle
*hnd
)
97 struct registry_key
*regkey
= find_regkey_by_hnd(p
, hnd
);
100 DEBUG(2,("close_registry_key: Invalid handle (%s:%u:%u)\n",
105 close_policy_hnd(p
, hnd
);
110 /********************************************************************
112 ********************************************************************/
114 WERROR
_winreg_CloseKey(struct pipes_struct
*p
,
115 struct winreg_CloseKey
*r
)
117 /* close the policy handle */
119 if (!close_registry_key(p
, r
->in
.handle
))
122 ZERO_STRUCTP(r
->out
.handle
);
127 /*******************************************************************
129 ********************************************************************/
131 WERROR
_winreg_OpenHKLM(struct pipes_struct
*p
,
132 struct winreg_OpenHKLM
*r
)
134 return open_registry_key(p
, r
->out
.handle
, NULL
, KEY_HKLM
, r
->in
.access_mask
);
137 /*******************************************************************
139 ********************************************************************/
141 WERROR
_winreg_OpenHKPD(struct pipes_struct
*p
,
142 struct winreg_OpenHKPD
*r
)
144 return open_registry_key(p
, r
->out
.handle
, NULL
, KEY_HKPD
, r
->in
.access_mask
);
147 /*******************************************************************
149 ********************************************************************/
151 WERROR
_winreg_OpenHKPT(struct pipes_struct
*p
,
152 struct winreg_OpenHKPT
*r
)
154 return open_registry_key(p
, r
->out
.handle
, NULL
, KEY_HKPT
, r
->in
.access_mask
);
157 /*******************************************************************
159 ********************************************************************/
161 WERROR
_winreg_OpenHKCR(struct pipes_struct
*p
,
162 struct winreg_OpenHKCR
*r
)
164 return open_registry_key(p
, r
->out
.handle
, NULL
, KEY_HKCR
, r
->in
.access_mask
);
167 /*******************************************************************
169 ********************************************************************/
171 WERROR
_winreg_OpenHKU(struct pipes_struct
*p
,
172 struct winreg_OpenHKU
*r
)
174 return open_registry_key(p
, r
->out
.handle
, NULL
, KEY_HKU
, r
->in
.access_mask
);
177 /*******************************************************************
179 ********************************************************************/
181 WERROR
_winreg_OpenHKCU(struct pipes_struct
*p
,
182 struct winreg_OpenHKCU
*r
)
184 return open_registry_key(p
, r
->out
.handle
, NULL
, KEY_HKCU
, r
->in
.access_mask
);
187 /*******************************************************************
189 ********************************************************************/
191 WERROR
_winreg_OpenHKCC(struct pipes_struct
*p
,
192 struct winreg_OpenHKCC
*r
)
194 return open_registry_key(p
, r
->out
.handle
, NULL
, KEY_HKCC
, r
->in
.access_mask
);
197 /*******************************************************************
199 ********************************************************************/
201 WERROR
_winreg_OpenHKDD(struct pipes_struct
*p
,
202 struct winreg_OpenHKDD
*r
)
204 return open_registry_key(p
, r
->out
.handle
, NULL
, KEY_HKDD
, r
->in
.access_mask
);
207 /*******************************************************************
209 ********************************************************************/
211 WERROR
_winreg_OpenHKPN(struct pipes_struct
*p
,
212 struct winreg_OpenHKPN
*r
)
214 return open_registry_key(p
, r
->out
.handle
, NULL
, KEY_HKPN
, r
->in
.access_mask
);
217 /*******************************************************************
219 ********************************************************************/
221 WERROR
_winreg_OpenKey(struct pipes_struct
*p
,
222 struct winreg_OpenKey
*r
)
224 struct registry_key
*parent
= find_regkey_by_hnd(p
, r
->in
.parent_handle
);
229 return open_registry_key(p
, r
->out
.handle
, parent
, r
->in
.keyname
.name
, r
->in
.access_mask
);
232 /*******************************************************************
234 ********************************************************************/
236 WERROR
_winreg_QueryValue(struct pipes_struct
*p
,
237 struct winreg_QueryValue
*r
)
239 WERROR status
= WERR_BADFILE
;
240 struct registry_key
*regkey
= find_regkey_by_hnd( p
, r
->in
.handle
);
243 uint8_t *outbuf
= NULL
;
244 uint32_t outbuf_size
= 0;
246 bool free_buf
= False
;
247 bool free_prs
= False
;
252 if (r
->in
.value_name
->name
== NULL
) {
253 return WERR_INVALID_PARAM
;
256 if ((r
->out
.data_length
== NULL
) || (r
->out
.type
== NULL
) || (r
->out
.data_size
== NULL
)) {
257 return WERR_INVALID_PARAM
;
260 DEBUG(7,("_winreg_QueryValue: policy key name = [%s]\n", regkey
->key
->name
));
261 DEBUG(7,("_winreg_QueryValue: policy key type = [%08x]\n", regkey
->key
->type
));
263 /* Handle QueryValue calls on HKEY_PERFORMANCE_DATA */
264 if(regkey
->key
->type
== REG_KEY_HKPD
)
266 if (strequal(r
->in
.value_name
->name
, "Global")) {
267 if (!prs_init(&prs_hkpd
, *r
->in
.data_size
, p
->mem_ctx
, MARSHALL
))
269 status
= reg_perfcount_get_hkpd(
270 &prs_hkpd
, *r
->in
.data_size
, &outbuf_size
, NULL
);
271 outbuf
= (uint8_t *)prs_hkpd
.data_p
;
274 else if (strequal(r
->in
.value_name
->name
, "Counter 009")) {
275 outbuf_size
= reg_perfcount_get_counter_names(
276 reg_perfcount_get_base_index(),
277 (char **)(void *)&outbuf
);
280 else if (strequal(r
->in
.value_name
->name
, "Explain 009")) {
281 outbuf_size
= reg_perfcount_get_counter_help(
282 reg_perfcount_get_base_index(),
283 (char **)(void *)&outbuf
);
286 else if (isdigit(r
->in
.value_name
->name
[0])) {
287 /* we probably have a request for a specific object
289 if (!prs_init(&prs_hkpd
, *r
->in
.data_size
, p
->mem_ctx
, MARSHALL
))
291 status
= reg_perfcount_get_hkpd(
292 &prs_hkpd
, *r
->in
.data_size
, &outbuf_size
,
293 r
->in
.value_name
->name
);
294 outbuf
= (uint8_t *)prs_hkpd
.data_p
;
298 DEBUG(3,("Unsupported key name [%s] for HKPD.\n",
299 r
->in
.value_name
->name
));
303 *r
->out
.type
= REG_BINARY
;
306 struct registry_value
*val
;
308 status
= reg_queryvalue(p
->mem_ctx
, regkey
, r
->in
.value_name
->name
,
310 if (!W_ERROR_IS_OK(status
)) {
312 DEBUG(10,("_winreg_QueryValue: reg_queryvalue failed with: %s\n",
313 win_errstr(status
)));
315 if (r
->out
.data_size
) {
316 *r
->out
.data_size
= 0;
318 if (r
->out
.data_length
) {
319 *r
->out
.data_length
= 0;
324 outbuf
= val
->data
.data
;
325 outbuf_size
= val
->data
.length
;
326 *r
->out
.type
= val
->type
;
329 status
= WERR_BADFILE
;
331 if (*r
->in
.data_size
< outbuf_size
) {
332 *r
->out
.data_size
= outbuf_size
;
333 status
= r
->in
.data
? WERR_MORE_DATA
: WERR_OK
;
335 *r
->out
.data_length
= outbuf_size
;
336 *r
->out
.data_size
= outbuf_size
;
338 memcpy(r
->out
.data
, outbuf
, outbuf_size
);
343 if (free_prs
) prs_mem_free(&prs_hkpd
);
344 if (free_buf
) SAFE_FREE(outbuf
);
349 /*****************************************************************************
351 ****************************************************************************/
353 WERROR
_winreg_QueryInfoKey(struct pipes_struct
*p
,
354 struct winreg_QueryInfoKey
*r
)
356 WERROR status
= WERR_OK
;
357 struct registry_key
*regkey
= find_regkey_by_hnd( p
, r
->in
.handle
);
362 r
->out
.classname
->name
= NULL
;
364 status
= reg_queryinfokey(regkey
, r
->out
.num_subkeys
, r
->out
.max_subkeylen
,
365 r
->out
.max_classlen
, r
->out
.num_values
, r
->out
.max_valnamelen
,
366 r
->out
.max_valbufsize
, r
->out
.secdescsize
,
367 r
->out
.last_changed_time
);
368 if (!W_ERROR_IS_OK(status
)) {
373 * These calculations account for the registry buffers being
374 * UTF-16. They are inexact at best, but so far they worked.
377 *r
->out
.max_subkeylen
*= 2;
379 *r
->out
.max_valnamelen
+= 1;
380 *r
->out
.max_valnamelen
*= 2;
386 /*****************************************************************************
388 ****************************************************************************/
390 WERROR
_winreg_GetVersion(struct pipes_struct
*p
,
391 struct winreg_GetVersion
*r
)
393 struct registry_key
*regkey
= find_regkey_by_hnd( p
, r
->in
.handle
);
398 return reg_getversion(r
->out
.version
);
402 /*****************************************************************************
404 ****************************************************************************/
406 WERROR
_winreg_EnumKey(struct pipes_struct
*p
,
407 struct winreg_EnumKey
*r
)
409 WERROR err
= WERR_OK
;
410 struct registry_key
*key
= find_regkey_by_hnd( p
, r
->in
.handle
);
415 if ( !r
->in
.name
|| !r
->in
.keyclass
)
416 return WERR_INVALID_PARAM
;
418 DEBUG(8,("_winreg_EnumKey: enumerating key [%s]\n", key
->key
->name
));
420 err
= reg_enumkey(p
->mem_ctx
, key
, r
->in
.enum_index
, (char **)&r
->out
.name
->name
,
421 r
->out
.last_changed_time
);
422 if (!W_ERROR_IS_OK(err
)) {
425 r
->out
.keyclass
->name
= "";
429 /*****************************************************************************
431 ****************************************************************************/
433 WERROR
_winreg_EnumValue(struct pipes_struct
*p
,
434 struct winreg_EnumValue
*r
)
436 WERROR err
= WERR_OK
;
437 struct registry_key
*key
= find_regkey_by_hnd( p
, r
->in
.handle
);
438 char *valname
= NULL
;
439 struct registry_value
*val
= NULL
;
445 return WERR_INVALID_PARAM
;
447 DEBUG(8,("_winreg_EnumValue: enumerating values for key [%s]\n",
450 err
= reg_enumvalue(p
->mem_ctx
, key
, r
->in
.enum_index
, &valname
, &val
);
451 if (!W_ERROR_IS_OK(err
)) {
455 if (r
->out
.name
!= NULL
) {
456 r
->out
.name
->name
= valname
;
459 if (r
->out
.type
!= NULL
) {
460 *r
->out
.type
= val
->type
;
463 if (r
->out
.value
!= NULL
) {
464 if ((r
->out
.size
== NULL
) || (r
->out
.length
== NULL
)) {
465 return WERR_INVALID_PARAM
;
468 if (val
->data
.length
> *r
->out
.size
) {
469 return WERR_MORE_DATA
;
472 memcpy( r
->out
.value
, val
->data
.data
, val
->data
.length
);
475 if (r
->out
.length
!= NULL
) {
476 *r
->out
.length
= val
->data
.length
;
478 if (r
->out
.size
!= NULL
) {
479 *r
->out
.size
= val
->data
.length
;
485 /*******************************************************************
486 _winreg_InitiateSystemShutdown
487 ********************************************************************/
489 WERROR
_winreg_InitiateSystemShutdown(struct pipes_struct
*p
,
490 struct winreg_InitiateSystemShutdown
*r
)
492 struct winreg_InitiateSystemShutdownEx s
;
494 s
.in
.hostname
= r
->in
.hostname
;
495 s
.in
.message
= r
->in
.message
;
496 s
.in
.timeout
= r
->in
.timeout
;
497 s
.in
.force_apps
= r
->in
.force_apps
;
498 s
.in
.do_reboot
= r
->in
.do_reboot
;
501 /* thunk down to _winreg_InitiateSystemShutdownEx()
502 (just returns a status) */
504 return _winreg_InitiateSystemShutdownEx( p
, &s
);
507 /*******************************************************************
508 _winreg_InitiateSystemShutdownEx
509 ********************************************************************/
511 #define SHUTDOWN_R_STRING "-r"
512 #define SHUTDOWN_F_STRING "-f"
515 WERROR
_winreg_InitiateSystemShutdownEx(struct pipes_struct
*p
,
516 struct winreg_InitiateSystemShutdownEx
*r
)
518 char *shutdown_script
= NULL
;
526 bool can_shutdown
= false;
528 shutdown_script
= talloc_strdup(p
->mem_ctx
, lp_shutdown_script());
529 if (!shutdown_script
) {
532 if (!*shutdown_script
) {
533 return WERR_ACCESS_DENIED
;
536 /* pull the message string and perform necessary sanity checks on it */
538 if ( r
->in
.message
&& r
->in
.message
->string
) {
539 if ( (msg
= talloc_strdup(p
->mem_ctx
, r
->in
.message
->string
)) == NULL
) {
542 chkmsg
= TALLOC_ARRAY(p
->mem_ctx
, char, strlen(msg
)+1);
546 alpha_strcpy(chkmsg
, msg
, NULL
, strlen(msg
)+1);
549 fstr_sprintf(str_timeout
, "%d", r
->in
.timeout
);
550 fstr_sprintf(do_reboot
, r
->in
.do_reboot
? SHUTDOWN_R_STRING
: "");
551 fstr_sprintf(f
, r
->in
.force_apps
? SHUTDOWN_F_STRING
: "");
552 fstr_sprintf(str_reason
, "%d", r
->in
.reason
);
554 shutdown_script
= talloc_all_string_sub(p
->mem_ctx
,
555 shutdown_script
, "%z", chkmsg
? chkmsg
: "");
556 if (!shutdown_script
) {
559 shutdown_script
= talloc_all_string_sub(p
->mem_ctx
,
560 shutdown_script
, "%t", str_timeout
);
561 if (!shutdown_script
) {
564 shutdown_script
= talloc_all_string_sub(p
->mem_ctx
,
565 shutdown_script
, "%r", do_reboot
);
566 if (!shutdown_script
) {
569 shutdown_script
= talloc_all_string_sub(p
->mem_ctx
,
570 shutdown_script
, "%f", f
);
571 if (!shutdown_script
) {
574 shutdown_script
= talloc_all_string_sub(p
->mem_ctx
,
575 shutdown_script
, "%x", str_reason
);
576 if (!shutdown_script
) {
580 can_shutdown
= security_token_has_privilege(p
->server_info
->security_token
, SEC_PRIV_REMOTE_SHUTDOWN
);
582 /* IF someone has privs, run the shutdown script as root. OTHERWISE run it as not root
583 Take the error return from the script and provide it as the Windows return code. */
585 /********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/
590 ret
= smbrun( shutdown_script
, NULL
);
595 /********** END SeRemoteShutdownPrivilege BLOCK **********/
597 DEBUG(3,("_reg_shutdown_ex: Running the command `%s' gave %d\n",
598 shutdown_script
, ret
));
600 return (ret
== 0) ? WERR_OK
: WERR_ACCESS_DENIED
;
603 /*******************************************************************
604 _winreg_AbortSystemShutdown
605 ********************************************************************/
607 WERROR
_winreg_AbortSystemShutdown(struct pipes_struct
*p
,
608 struct winreg_AbortSystemShutdown
*r
)
610 const char *abort_shutdown_script
= lp_abort_shutdown_script();
612 bool can_shutdown
= false;
614 if (!*abort_shutdown_script
)
615 return WERR_ACCESS_DENIED
;
617 can_shutdown
= security_token_has_privilege(p
->server_info
->security_token
, SEC_PRIV_REMOTE_SHUTDOWN
);
619 /********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/
624 ret
= smbrun( abort_shutdown_script
, NULL
);
629 /********** END SeRemoteShutdownPrivilege BLOCK **********/
631 DEBUG(3,("_winreg_AbortSystemShutdown: Running the command `%s' gave %d\n",
632 abort_shutdown_script
, ret
));
634 return (ret
== 0) ? WERR_OK
: WERR_ACCESS_DENIED
;
637 /*******************************************************************
638 ********************************************************************/
640 static int validate_reg_filename(TALLOC_CTX
*ctx
, char **pp_fname
)
643 int num_services
= lp_numservices();
645 const char *share_path
= NULL
;
646 char *fname
= *pp_fname
;
648 /* convert to a unix path, stripping the C:\ along the way */
650 if (!(p
= valid_share_pathname(ctx
, fname
))) {
654 /* has to exist within a valid file share */
656 for (snum
=0; snum
<num_services
; snum
++) {
657 if (!lp_snum_ok(snum
) || lp_print_ok(snum
)) {
661 share_path
= lp_pathname(snum
);
663 /* make sure we have a path (e.g. [homes] ) */
664 if (strlen(share_path
) == 0) {
668 if (strncmp(share_path
, p
, strlen(share_path
)) == 0) {
674 return (snum
< num_services
) ? snum
: -1;
677 /*******************************************************************
679 ********************************************************************/
681 WERROR
_winreg_RestoreKey(struct pipes_struct
*p
,
682 struct winreg_RestoreKey
*r
)
684 struct registry_key
*regkey
= find_regkey_by_hnd( p
, r
->in
.handle
);
691 if ( !r
->in
.filename
|| !r
->in
.filename
->name
)
692 return WERR_INVALID_PARAM
;
694 fname
= talloc_strdup(p
->mem_ctx
, r
->in
.filename
->name
);
699 DEBUG(8,("_winreg_RestoreKey: verifying restore of key [%s] from "
700 "\"%s\"\n", regkey
->key
->name
, fname
));
702 if ((snum
= validate_reg_filename(p
->mem_ctx
, &fname
)) == -1)
703 return WERR_OBJECT_PATH_INVALID
;
705 /* user must posses SeRestorePrivilege for this this proceed */
707 if ( !security_token_has_privilege(p
->server_info
->security_token
, SEC_PRIV_RESTORE
)) {
708 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
= NULL
;
774 WERROR result
= WERR_OK
;
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
= NULL
;
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
);
862 WERROR err
= WERR_OK
;
863 struct security_descriptor
*secdesc
= NULL
;
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
= NULL
;
907 WERROR err
= WERR_OK
;
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;
1052 DATA_BLOB result
= data_blob_null
;
1054 WERROR err
= WERR_OK
;
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
;