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"
31 #define DBGC_CLASS DBGC_RPC_SRV
33 /******************************************************************
34 Find a registry key handle and return a struct registry_key *
35 *****************************************************************/
37 static struct registry_key
*find_regkey_by_hnd(struct pipes_struct
*p
,
38 struct policy_handle
*hnd
)
40 struct registry_key
*regkey
= NULL
;
42 if(!find_policy_by_hnd(p
,hnd
,(void **)(void *)®key
)) {
43 DEBUG(2,("find_regkey_index_by_hnd: Registry Key not found: "));
50 /*******************************************************************
51 Function for open a new registry handle and creating a handle
52 Note that P should be valid & hnd should already have space
54 When we open a key, we store the full path to the key as
55 HK[LM|U]\<key>\<key>\...
56 *******************************************************************/
58 static WERROR
open_registry_key(struct pipes_struct
*p
,
59 struct policy_handle
*hnd
,
60 struct registry_key
*parent
,
61 const char *subkeyname
,
62 uint32_t access_desired
)
64 WERROR result
= WERR_OK
;
65 struct registry_key
*key
;
68 result
= reg_openhive(p
->mem_ctx
, subkeyname
, access_desired
,
69 p
->server_info
->ptok
, &key
);
72 result
= reg_openkey(p
->mem_ctx
, parent
, subkeyname
,
73 access_desired
, &key
);
76 if ( !W_ERROR_IS_OK(result
) ) {
80 if ( !create_policy_hnd( p
, hnd
, key
) ) {
87 /*******************************************************************
88 Function for open a new registry handle and creating a handle
89 Note that P should be valid & hnd should already have space
90 *******************************************************************/
92 static bool close_registry_key(struct pipes_struct
*p
,
93 struct policy_handle
*hnd
)
95 struct registry_key
*regkey
= find_regkey_by_hnd(p
, hnd
);
98 DEBUG(2,("close_registry_key: Invalid handle (%s:%u:%u)\n",
103 close_policy_hnd(p
, hnd
);
108 /********************************************************************
110 ********************************************************************/
112 WERROR
_winreg_CloseKey(struct pipes_struct
*p
,
113 struct winreg_CloseKey
*r
)
115 /* close the policy handle */
117 if (!close_registry_key(p
, r
->in
.handle
))
120 ZERO_STRUCTP(r
->out
.handle
);
125 /*******************************************************************
127 ********************************************************************/
129 WERROR
_winreg_OpenHKLM(struct pipes_struct
*p
,
130 struct winreg_OpenHKLM
*r
)
132 return open_registry_key(p
, r
->out
.handle
, NULL
, KEY_HKLM
, r
->in
.access_mask
);
135 /*******************************************************************
137 ********************************************************************/
139 WERROR
_winreg_OpenHKPD(struct pipes_struct
*p
,
140 struct winreg_OpenHKPD
*r
)
142 return open_registry_key(p
, r
->out
.handle
, NULL
, KEY_HKPD
, r
->in
.access_mask
);
145 /*******************************************************************
147 ********************************************************************/
149 WERROR
_winreg_OpenHKPT(struct pipes_struct
*p
,
150 struct winreg_OpenHKPT
*r
)
152 return open_registry_key(p
, r
->out
.handle
, NULL
, KEY_HKPT
, r
->in
.access_mask
);
155 /*******************************************************************
157 ********************************************************************/
159 WERROR
_winreg_OpenHKCR(struct pipes_struct
*p
,
160 struct winreg_OpenHKCR
*r
)
162 return open_registry_key(p
, r
->out
.handle
, NULL
, KEY_HKCR
, r
->in
.access_mask
);
165 /*******************************************************************
167 ********************************************************************/
169 WERROR
_winreg_OpenHKU(struct pipes_struct
*p
,
170 struct winreg_OpenHKU
*r
)
172 return open_registry_key(p
, r
->out
.handle
, NULL
, KEY_HKU
, r
->in
.access_mask
);
175 /*******************************************************************
177 ********************************************************************/
179 WERROR
_winreg_OpenHKCU(struct pipes_struct
*p
,
180 struct winreg_OpenHKCU
*r
)
182 return open_registry_key(p
, r
->out
.handle
, NULL
, KEY_HKCU
, r
->in
.access_mask
);
185 /*******************************************************************
187 ********************************************************************/
189 WERROR
_winreg_OpenHKCC(struct pipes_struct
*p
,
190 struct winreg_OpenHKCC
*r
)
192 return open_registry_key(p
, r
->out
.handle
, NULL
, KEY_HKCC
, r
->in
.access_mask
);
195 /*******************************************************************
197 ********************************************************************/
199 WERROR
_winreg_OpenHKDD(struct pipes_struct
*p
,
200 struct winreg_OpenHKDD
*r
)
202 return open_registry_key(p
, r
->out
.handle
, NULL
, KEY_HKDD
, r
->in
.access_mask
);
205 /*******************************************************************
207 ********************************************************************/
209 WERROR
_winreg_OpenHKPN(struct pipes_struct
*p
,
210 struct winreg_OpenHKPN
*r
)
212 return open_registry_key(p
, r
->out
.handle
, NULL
, KEY_HKPN
, r
->in
.access_mask
);
215 /*******************************************************************
217 ********************************************************************/
219 WERROR
_winreg_OpenKey(struct pipes_struct
*p
,
220 struct winreg_OpenKey
*r
)
222 struct registry_key
*parent
= find_regkey_by_hnd(p
, r
->in
.parent_handle
);
227 return open_registry_key(p
, r
->out
.handle
, parent
, r
->in
.keyname
.name
, r
->in
.access_mask
);
230 /*******************************************************************
232 ********************************************************************/
234 WERROR
_winreg_QueryValue(struct pipes_struct
*p
,
235 struct winreg_QueryValue
*r
)
237 WERROR status
= WERR_BADFILE
;
238 struct registry_key
*regkey
= find_regkey_by_hnd( p
, r
->in
.handle
);
241 uint8_t *outbuf
= NULL
;
242 uint32_t outbuf_size
= 0;
244 bool free_buf
= False
;
245 bool free_prs
= False
;
250 if (r
->in
.value_name
->name
== NULL
) {
251 return WERR_INVALID_PARAM
;
254 if ((r
->out
.data_length
== NULL
) || (r
->out
.type
== NULL
) || (r
->out
.data_size
== NULL
)) {
255 return WERR_INVALID_PARAM
;
258 DEBUG(7,("_winreg_QueryValue: policy key name = [%s]\n", regkey
->key
->name
));
259 DEBUG(7,("_winreg_QueryValue: policy key type = [%08x]\n", regkey
->key
->type
));
261 /* Handle QueryValue calls on HKEY_PERFORMANCE_DATA */
262 if(regkey
->key
->type
== REG_KEY_HKPD
)
264 if (strequal(r
->in
.value_name
->name
, "Global")) {
265 if (!prs_init(&prs_hkpd
, *r
->in
.data_size
, p
->mem_ctx
, MARSHALL
))
267 status
= reg_perfcount_get_hkpd(
268 &prs_hkpd
, *r
->in
.data_size
, &outbuf_size
, NULL
);
269 outbuf
= (uint8_t *)prs_hkpd
.data_p
;
272 else if (strequal(r
->in
.value_name
->name
, "Counter 009")) {
273 outbuf_size
= reg_perfcount_get_counter_names(
274 reg_perfcount_get_base_index(),
275 (char **)(void *)&outbuf
);
278 else if (strequal(r
->in
.value_name
->name
, "Explain 009")) {
279 outbuf_size
= reg_perfcount_get_counter_help(
280 reg_perfcount_get_base_index(),
281 (char **)(void *)&outbuf
);
284 else if (isdigit(r
->in
.value_name
->name
[0])) {
285 /* we probably have a request for a specific object
287 if (!prs_init(&prs_hkpd
, *r
->in
.data_size
, p
->mem_ctx
, MARSHALL
))
289 status
= reg_perfcount_get_hkpd(
290 &prs_hkpd
, *r
->in
.data_size
, &outbuf_size
,
291 r
->in
.value_name
->name
);
292 outbuf
= (uint8_t *)prs_hkpd
.data_p
;
296 DEBUG(3,("Unsupported key name [%s] for HKPD.\n",
297 r
->in
.value_name
->name
));
301 *r
->out
.type
= REG_BINARY
;
304 struct registry_value
*val
;
306 status
= reg_queryvalue(p
->mem_ctx
, regkey
, r
->in
.value_name
->name
,
308 if (!W_ERROR_IS_OK(status
)) {
310 DEBUG(10,("_winreg_QueryValue: reg_queryvalue failed with: %s\n",
311 win_errstr(status
)));
313 if (r
->out
.data_size
) {
314 *r
->out
.data_size
= 0;
316 if (r
->out
.data_length
) {
317 *r
->out
.data_length
= 0;
322 outbuf
= val
->data
.data
;
323 outbuf_size
= val
->data
.length
;
324 *r
->out
.type
= val
->type
;
327 status
= WERR_BADFILE
;
329 if (*r
->in
.data_size
< outbuf_size
) {
330 *r
->out
.data_size
= outbuf_size
;
331 status
= r
->in
.data
? WERR_MORE_DATA
: WERR_OK
;
333 *r
->out
.data_length
= outbuf_size
;
334 *r
->out
.data_size
= outbuf_size
;
336 memcpy(r
->out
.data
, outbuf
, outbuf_size
);
341 if (free_prs
) prs_mem_free(&prs_hkpd
);
342 if (free_buf
) SAFE_FREE(outbuf
);
347 /*****************************************************************************
349 ****************************************************************************/
351 WERROR
_winreg_QueryInfoKey(struct pipes_struct
*p
,
352 struct winreg_QueryInfoKey
*r
)
354 WERROR status
= WERR_OK
;
355 struct registry_key
*regkey
= find_regkey_by_hnd( p
, r
->in
.handle
);
360 r
->out
.classname
->name
= NULL
;
362 status
= reg_queryinfokey(regkey
, r
->out
.num_subkeys
, r
->out
.max_subkeylen
,
363 r
->out
.max_classlen
, r
->out
.num_values
, r
->out
.max_valnamelen
,
364 r
->out
.max_valbufsize
, r
->out
.secdescsize
,
365 r
->out
.last_changed_time
);
366 if (!W_ERROR_IS_OK(status
)) {
371 * These calculations account for the registry buffers being
372 * UTF-16. They are inexact at best, but so far they worked.
375 *r
->out
.max_subkeylen
*= 2;
377 *r
->out
.max_valnamelen
+= 1;
378 *r
->out
.max_valnamelen
*= 2;
384 /*****************************************************************************
386 ****************************************************************************/
388 WERROR
_winreg_GetVersion(struct pipes_struct
*p
,
389 struct winreg_GetVersion
*r
)
391 struct registry_key
*regkey
= find_regkey_by_hnd( p
, r
->in
.handle
);
396 return reg_getversion(r
->out
.version
);
400 /*****************************************************************************
402 ****************************************************************************/
404 WERROR
_winreg_EnumKey(struct pipes_struct
*p
,
405 struct winreg_EnumKey
*r
)
407 WERROR err
= WERR_OK
;
408 struct registry_key
*key
= find_regkey_by_hnd( p
, r
->in
.handle
);
413 if ( !r
->in
.name
|| !r
->in
.keyclass
)
414 return WERR_INVALID_PARAM
;
416 DEBUG(8,("_winreg_EnumKey: enumerating key [%s]\n", key
->key
->name
));
418 err
= reg_enumkey(p
->mem_ctx
, key
, r
->in
.enum_index
, (char **)&r
->out
.name
->name
,
419 r
->out
.last_changed_time
);
420 if (!W_ERROR_IS_OK(err
)) {
423 r
->out
.keyclass
->name
= "";
427 /*****************************************************************************
429 ****************************************************************************/
431 WERROR
_winreg_EnumValue(struct pipes_struct
*p
,
432 struct winreg_EnumValue
*r
)
434 WERROR err
= WERR_OK
;
435 struct registry_key
*key
= find_regkey_by_hnd( p
, r
->in
.handle
);
436 char *valname
= NULL
;
437 struct registry_value
*val
= NULL
;
443 return WERR_INVALID_PARAM
;
445 DEBUG(8,("_winreg_EnumValue: enumerating values for key [%s]\n",
448 err
= reg_enumvalue(p
->mem_ctx
, key
, r
->in
.enum_index
, &valname
, &val
);
449 if (!W_ERROR_IS_OK(err
)) {
453 if (r
->out
.name
!= NULL
) {
454 r
->out
.name
->name
= valname
;
457 if (r
->out
.type
!= NULL
) {
458 *r
->out
.type
= val
->type
;
461 if (r
->out
.value
!= NULL
) {
462 if ((r
->out
.size
== NULL
) || (r
->out
.length
== NULL
)) {
463 return WERR_INVALID_PARAM
;
466 if (val
->data
.length
> *r
->out
.size
) {
467 return WERR_MORE_DATA
;
470 memcpy( r
->out
.value
, val
->data
.data
, val
->data
.length
);
473 if (r
->out
.length
!= NULL
) {
474 *r
->out
.length
= val
->data
.length
;
476 if (r
->out
.size
!= NULL
) {
477 *r
->out
.size
= val
->data
.length
;
483 /*******************************************************************
484 _winreg_InitiateSystemShutdown
485 ********************************************************************/
487 WERROR
_winreg_InitiateSystemShutdown(struct pipes_struct
*p
,
488 struct winreg_InitiateSystemShutdown
*r
)
490 struct winreg_InitiateSystemShutdownEx s
;
492 s
.in
.hostname
= r
->in
.hostname
;
493 s
.in
.message
= r
->in
.message
;
494 s
.in
.timeout
= r
->in
.timeout
;
495 s
.in
.force_apps
= r
->in
.force_apps
;
496 s
.in
.do_reboot
= r
->in
.do_reboot
;
499 /* thunk down to _winreg_InitiateSystemShutdownEx()
500 (just returns a status) */
502 return _winreg_InitiateSystemShutdownEx( p
, &s
);
505 /*******************************************************************
506 _winreg_InitiateSystemShutdownEx
507 ********************************************************************/
509 #define SHUTDOWN_R_STRING "-r"
510 #define SHUTDOWN_F_STRING "-f"
513 WERROR
_winreg_InitiateSystemShutdownEx(struct pipes_struct
*p
,
514 struct winreg_InitiateSystemShutdownEx
*r
)
516 char *shutdown_script
= NULL
;
524 bool can_shutdown
= false;
526 shutdown_script
= talloc_strdup(p
->mem_ctx
, lp_shutdown_script());
527 if (!shutdown_script
) {
530 if (!*shutdown_script
) {
531 return WERR_ACCESS_DENIED
;
534 /* pull the message string and perform necessary sanity checks on it */
536 if ( r
->in
.message
&& r
->in
.message
->string
) {
537 if ( (msg
= talloc_strdup(p
->mem_ctx
, r
->in
.message
->string
)) == NULL
) {
540 chkmsg
= TALLOC_ARRAY(p
->mem_ctx
, char, strlen(msg
)+1);
544 alpha_strcpy(chkmsg
, msg
, NULL
, strlen(msg
)+1);
547 fstr_sprintf(str_timeout
, "%d", r
->in
.timeout
);
548 fstr_sprintf(do_reboot
, r
->in
.do_reboot
? SHUTDOWN_R_STRING
: "");
549 fstr_sprintf(f
, r
->in
.force_apps
? SHUTDOWN_F_STRING
: "");
550 fstr_sprintf(str_reason
, "%d", r
->in
.reason
);
552 shutdown_script
= talloc_all_string_sub(p
->mem_ctx
,
553 shutdown_script
, "%z", chkmsg
? chkmsg
: "");
554 if (!shutdown_script
) {
557 shutdown_script
= talloc_all_string_sub(p
->mem_ctx
,
558 shutdown_script
, "%t", str_timeout
);
559 if (!shutdown_script
) {
562 shutdown_script
= talloc_all_string_sub(p
->mem_ctx
,
563 shutdown_script
, "%r", do_reboot
);
564 if (!shutdown_script
) {
567 shutdown_script
= talloc_all_string_sub(p
->mem_ctx
,
568 shutdown_script
, "%f", f
);
569 if (!shutdown_script
) {
572 shutdown_script
= talloc_all_string_sub(p
->mem_ctx
,
573 shutdown_script
, "%x", str_reason
);
574 if (!shutdown_script
) {
578 can_shutdown
= user_has_privileges( p
->server_info
->ptok
,
579 &se_remote_shutdown
);
581 /* IF someone has privs, run the shutdown script as root. OTHERWISE run it as not root
582 Take the error return from the script and provide it as the Windows return code. */
584 /********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/
589 ret
= smbrun( shutdown_script
, NULL
);
594 /********** END SeRemoteShutdownPrivilege BLOCK **********/
596 DEBUG(3,("_reg_shutdown_ex: Running the command `%s' gave %d\n",
597 shutdown_script
, ret
));
599 return (ret
== 0) ? WERR_OK
: WERR_ACCESS_DENIED
;
602 /*******************************************************************
603 _winreg_AbortSystemShutdown
604 ********************************************************************/
606 WERROR
_winreg_AbortSystemShutdown(struct pipes_struct
*p
,
607 struct winreg_AbortSystemShutdown
*r
)
609 const char *abort_shutdown_script
= lp_abort_shutdown_script();
611 bool can_shutdown
= false;
613 if (!*abort_shutdown_script
)
614 return WERR_ACCESS_DENIED
;
616 can_shutdown
= user_has_privileges( p
->server_info
->ptok
,
617 &se_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 ( !user_has_privileges( p
->server_info
->ptok
, &se_restore
) )
708 return WERR_ACCESS_DENIED
;
710 DEBUG(2,("_winreg_RestoreKey: Restoring [%s] from %s in share %s\n",
711 regkey
->key
->name
, fname
, lp_servicename(snum
) ));
713 return reg_restorekey(regkey
, fname
);
716 /*******************************************************************
718 ********************************************************************/
720 WERROR
_winreg_SaveKey(struct pipes_struct
*p
,
721 struct winreg_SaveKey
*r
)
723 struct registry_key
*regkey
= find_regkey_by_hnd( p
, r
->in
.handle
);
730 if ( !r
->in
.filename
|| !r
->in
.filename
->name
)
731 return WERR_INVALID_PARAM
;
733 fname
= talloc_strdup(p
->mem_ctx
, r
->in
.filename
->name
);
738 DEBUG(8,("_winreg_SaveKey: verifying backup of key [%s] to \"%s\"\n",
739 regkey
->key
->name
, fname
));
741 if ((snum
= validate_reg_filename(p
->mem_ctx
, &fname
)) == -1 )
742 return WERR_OBJECT_PATH_INVALID
;
744 DEBUG(2,("_winreg_SaveKey: Saving [%s] to %s in share %s\n",
745 regkey
->key
->name
, fname
, lp_servicename(snum
) ));
747 return reg_savekey(regkey
, fname
);
750 /*******************************************************************
752 ********************************************************************/
754 WERROR
_winreg_SaveKeyEx(struct pipes_struct
*p
,
755 struct winreg_SaveKeyEx
*r
)
757 /* fill in your code here if you think this call should
760 p
->rng_fault_state
= True
;
761 return WERR_NOT_SUPPORTED
;
764 /*******************************************************************
766 ********************************************************************/
768 WERROR
_winreg_CreateKey(struct pipes_struct
*p
,
769 struct winreg_CreateKey
*r
)
771 struct registry_key
*parent
= find_regkey_by_hnd(p
, r
->in
.handle
);
772 struct registry_key
*new_key
= NULL
;
773 WERROR result
= WERR_OK
;
778 DEBUG(10, ("_winreg_CreateKey called with parent key '%s' and "
779 "subkey name '%s'\n", parent
->key
->name
, r
->in
.name
.name
));
781 result
= reg_createkey(NULL
, parent
, r
->in
.name
.name
, r
->in
.access_mask
,
782 &new_key
, r
->out
.action_taken
);
783 if (!W_ERROR_IS_OK(result
)) {
787 if (!create_policy_hnd(p
, r
->out
.new_handle
, new_key
)) {
788 TALLOC_FREE(new_key
);
795 /*******************************************************************
797 ********************************************************************/
799 WERROR
_winreg_SetValue(struct pipes_struct
*p
,
800 struct winreg_SetValue
*r
)
802 struct registry_key
*key
= find_regkey_by_hnd(p
, r
->in
.handle
);
803 struct registry_value
*val
= NULL
;
808 DEBUG(8,("_winreg_SetValue: Setting value for [%s:%s]\n",
809 key
->key
->name
, r
->in
.name
.name
));
811 val
= talloc_zero(p
->mem_ctx
, struct registry_value
);
816 val
->type
= r
->in
.type
;
817 val
->data
= data_blob_talloc(p
->mem_ctx
, r
->in
.data
, r
->in
.size
);
819 return reg_setvalue(key
, r
->in
.name
.name
, val
);
822 /*******************************************************************
824 ********************************************************************/
826 WERROR
_winreg_DeleteKey(struct pipes_struct
*p
,
827 struct winreg_DeleteKey
*r
)
829 struct registry_key
*parent
= find_regkey_by_hnd(p
, r
->in
.handle
);
834 return reg_deletekey(parent
, r
->in
.key
.name
);
838 /*******************************************************************
840 ********************************************************************/
842 WERROR
_winreg_DeleteValue(struct pipes_struct
*p
,
843 struct winreg_DeleteValue
*r
)
845 struct registry_key
*key
= find_regkey_by_hnd(p
, r
->in
.handle
);
850 return reg_deletevalue(key
, r
->in
.value
.name
);
853 /*******************************************************************
854 _winreg_GetKeySecurity
855 ********************************************************************/
857 WERROR
_winreg_GetKeySecurity(struct pipes_struct
*p
,
858 struct winreg_GetKeySecurity
*r
)
860 struct registry_key
*key
= find_regkey_by_hnd(p
, r
->in
.handle
);
861 WERROR err
= WERR_OK
;
862 struct security_descriptor
*secdesc
= NULL
;
869 /* access checks first */
871 if ( !(key
->key
->access_granted
& SEC_STD_READ_CONTROL
) )
872 return WERR_ACCESS_DENIED
;
874 err
= reg_getkeysecurity(p
->mem_ctx
, key
, &secdesc
);
875 if (!W_ERROR_IS_OK(err
)) {
879 err
= ntstatus_to_werror(marshall_sec_desc(p
->mem_ctx
, secdesc
,
881 if (!W_ERROR_IS_OK(err
)) {
885 if (len
> r
->out
.sd
->size
) {
886 r
->out
.sd
->size
= len
;
887 return WERR_INSUFFICIENT_BUFFER
;
890 r
->out
.sd
->size
= len
;
891 r
->out
.sd
->len
= len
;
892 r
->out
.sd
->data
= data
;
897 /*******************************************************************
898 _winreg_SetKeySecurity
899 ********************************************************************/
901 WERROR
_winreg_SetKeySecurity(struct pipes_struct
*p
,
902 struct winreg_SetKeySecurity
*r
)
904 struct registry_key
*key
= find_regkey_by_hnd(p
, r
->in
.handle
);
905 struct security_descriptor
*secdesc
= NULL
;
906 WERROR err
= WERR_OK
;
911 /* access checks first */
913 if ( !(key
->key
->access_granted
& SEC_STD_WRITE_DAC
) )
914 return WERR_ACCESS_DENIED
;
916 err
= ntstatus_to_werror(unmarshall_sec_desc(p
->mem_ctx
, r
->in
.sd
->data
,
917 r
->in
.sd
->len
, &secdesc
));
918 if (!W_ERROR_IS_OK(err
)) {
922 return reg_setkeysecurity(key
, secdesc
);
925 /*******************************************************************
927 ********************************************************************/
929 WERROR
_winreg_FlushKey(struct pipes_struct
*p
,
930 struct winreg_FlushKey
*r
)
932 /* I'm just replying OK because there's not a lot
933 here I see to do i --jerry */
938 /*******************************************************************
940 ********************************************************************/
942 WERROR
_winreg_UnLoadKey(struct pipes_struct
*p
,
943 struct winreg_UnLoadKey
*r
)
945 /* fill in your code here if you think this call should
948 p
->rng_fault_state
= True
;
949 return WERR_NOT_SUPPORTED
;
952 /*******************************************************************
954 ********************************************************************/
956 WERROR
_winreg_ReplaceKey(struct pipes_struct
*p
,
957 struct winreg_ReplaceKey
*r
)
959 /* fill in your code here if you think this call should
962 p
->rng_fault_state
= True
;
963 return WERR_NOT_SUPPORTED
;
966 /*******************************************************************
968 ********************************************************************/
970 WERROR
_winreg_LoadKey(struct pipes_struct
*p
,
971 struct winreg_LoadKey
*r
)
973 /* fill in your code here if you think this call should
976 p
->rng_fault_state
= True
;
977 return WERR_NOT_SUPPORTED
;
980 /*******************************************************************
981 _winreg_NotifyChangeKeyValue
982 ********************************************************************/
984 WERROR
_winreg_NotifyChangeKeyValue(struct pipes_struct
*p
,
985 struct winreg_NotifyChangeKeyValue
*r
)
987 return WERR_NOT_SUPPORTED
;
990 /*******************************************************************
991 _winreg_QueryMultipleValues
992 ********************************************************************/
994 WERROR
_winreg_QueryMultipleValues(struct pipes_struct
*p
,
995 struct winreg_QueryMultipleValues
*r
)
997 struct winreg_QueryMultipleValues2 r2
;
1000 r2
.in
.key_handle
= r
->in
.key_handle
;
1001 r2
.in
.values_in
= r
->in
.values_in
;
1002 r2
.in
.num_values
= r
->in
.num_values
;
1003 r2
.in
.offered
= r
->in
.buffer_size
;
1004 r2
.in
.buffer
= r
->in
.buffer
;
1005 r2
.out
.values_out
= r
->out
.values_out
;
1006 r2
.out
.needed
= &needed
;
1007 r2
.out
.buffer
= r
->out
.buffer
;
1009 return _winreg_QueryMultipleValues2(p
, &r2
);
1012 /*******************************************************************
1013 ********************************************************************/
1015 static WERROR
construct_multiple_entry(TALLOC_CTX
*mem_ctx
,
1016 const char *valuename
,
1017 uint32_t value_length
,
1019 enum winreg_Type type
,
1020 struct QueryMultipleValue
*r
)
1022 r
->ve_valuename
= talloc_zero(mem_ctx
, struct winreg_ValNameBuf
);
1023 if (r
->ve_valuename
== NULL
) {
1027 r
->ve_valuename
->name
= talloc_strdup(r
->ve_valuename
, valuename
? valuename
: "");
1028 if (r
->ve_valuename
->name
== NULL
) {
1032 r
->ve_valuename
->size
= strlen_m_term(r
->ve_valuename
->name
)*2;
1033 r
->ve_valuelen
= value_length
;
1034 r
->ve_valueptr
= offset
;
1040 /*******************************************************************
1041 _winreg_QueryMultipleValues2
1042 ********************************************************************/
1044 WERROR
_winreg_QueryMultipleValues2(struct pipes_struct
*p
,
1045 struct winreg_QueryMultipleValues2
*r
)
1047 struct registry_key
*regkey
= find_regkey_by_hnd(p
, r
->in
.key_handle
);
1048 struct registry_value
*vals
= NULL
;
1049 const char **names
= NULL
;
1050 uint32_t offset
= 0, num_vals
= 0;
1051 DATA_BLOB result
= data_blob_null
;
1053 WERROR err
= WERR_OK
;
1059 names
= talloc_zero_array(p
->mem_ctx
, const char *, r
->in
.num_values
);
1060 if (names
== NULL
) {
1064 for (i
=0; i
< r
->in
.num_values
; i
++) {
1065 if (r
->in
.values_in
[i
].ve_valuename
&&
1066 r
->in
.values_in
[i
].ve_valuename
->name
) {
1067 names
[i
] = talloc_strdup(names
,
1068 r
->in
.values_in
[i
].ve_valuename
->name
);
1069 if (names
[i
] == NULL
) {
1075 err
= reg_querymultiplevalues(p
->mem_ctx
, regkey
,
1076 r
->in
.num_values
, names
,
1078 if (!W_ERROR_IS_OK(err
)) {
1082 result
= data_blob_talloc(p
->mem_ctx
, NULL
, 0);
1084 for (i
=0; i
< r
->in
.num_values
; i
++) {
1085 const char *valuename
= NULL
;
1087 if (vals
[i
].data
.length
> 0) {
1088 if (!data_blob_append(p
->mem_ctx
, &result
,
1090 vals
[i
].data
.length
)) {
1095 if (r
->in
.values_in
[i
].ve_valuename
&&
1096 r
->in
.values_in
[i
].ve_valuename
->name
) {
1097 valuename
= r
->in
.values_in
[i
].ve_valuename
->name
;
1100 err
= construct_multiple_entry(r
->out
.values_out
,
1102 vals
[i
].data
.length
,
1105 &r
->out
.values_out
[i
]);
1106 if (!W_ERROR_IS_OK(err
)) {
1110 offset
+= vals
[i
].data
.length
;
1113 *r
->out
.needed
= result
.length
;
1115 if (r
->in
.num_values
!= num_vals
) {
1116 return WERR_BADFILE
;
1119 if (*r
->in
.offered
>= *r
->out
.needed
) {
1120 if (r
->out
.buffer
) {
1121 memcpy(r
->out
.buffer
, result
.data
, MIN(result
.length
, *r
->in
.offered
));
1125 return WERR_MORE_DATA
;
1129 /*******************************************************************
1131 ********************************************************************/
1133 WERROR
_winreg_DeleteKeyEx(struct pipes_struct
*p
,
1134 struct winreg_DeleteKeyEx
*r
)
1136 /* fill in your code here if you think this call should
1139 p
->rng_fault_state
= True
;
1140 return WERR_NOT_SUPPORTED
;