2001-02-25 05:14:49 +03:00
/*
2002-01-30 09:08:46 +03:00
* Unix SMB / CIFS implementation .
2001-02-25 05:14:49 +03:00
* RPC Pipe client / server routines
2006-09-27 20:05:25 +04:00
*
* Copyright ( C ) Gerald Carter 2002 - 2006.
2001-02-25 05:14:49 +03:00
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 2 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
/* Implementation of registry functions. */
# include "includes.h"
2005-05-23 20:25:31 +04:00
# include "regfio.h"
2001-02-25 05:14:49 +03:00
2002-07-15 14:35:28 +04:00
# undef DBGC_CLASS
# define DBGC_CLASS DBGC_RPC_SRV
2005-09-30 21:13:37 +04:00
static struct generic_mapping reg_generic_map =
{ REG_KEY_READ , REG_KEY_WRITE , REG_KEY_EXECUTE , REG_KEY_ALL } ;
2005-06-17 00:29:15 +04:00
2002-08-17 19:34:15 +04:00
/******************************************************************
free ( ) function for REGISTRY_KEY
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-07-15 14:35:28 +04:00
2002-08-17 19:34:15 +04:00
static void free_regkey_info ( void * ptr )
2002-07-15 14:35:28 +04:00
{
2005-10-07 16:14:25 +04:00
regkey_close_internal ( ( REGISTRY_KEY * ) ptr ) ;
2002-07-15 14:35:28 +04:00
}
2002-08-17 19:34:15 +04:00
/******************************************************************
Find a registry key handle and return a REGISTRY_KEY
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-07-15 14:35:28 +04:00
2002-08-17 19:34:15 +04:00
static REGISTRY_KEY * find_regkey_index_by_hnd ( pipes_struct * p , POLICY_HND * hnd )
2002-07-15 14:35:28 +04:00
{
2002-08-17 19:34:15 +04:00
REGISTRY_KEY * regkey = NULL ;
2002-07-15 14:35:28 +04:00
2005-12-03 09:46:46 +03:00
if ( ! find_policy_by_hnd ( p , hnd , ( void * * ) ( void * ) & regkey ) ) {
2002-08-17 19:34:15 +04:00
DEBUG ( 2 , ( " find_regkey_index_by_hnd: Registry Key not found: " ) ) ;
return NULL ;
2002-07-15 14:35:28 +04:00
}
2002-08-17 19:34:15 +04:00
return regkey ;
2002-07-15 14:35:28 +04:00
}
2002-08-17 19:34:15 +04:00
/*******************************************************************
Function for open a new registry handle and creating a handle
Note that P should be valid & hnd should already have space
2002-07-15 14:35:28 +04:00
2002-08-17 19:34:15 +04:00
When we open a key , we store the full path to the key as
HK [ LM | U ] \ < key > \ < key > \ . . .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-09-30 21:13:37 +04:00
static WERROR open_registry_key ( pipes_struct * p , POLICY_HND * hnd ,
REGISTRY_KEY * * keyinfo , REGISTRY_KEY * parent ,
const char * subkeyname , uint32 access_desired )
2002-07-15 14:35:28 +04:00
{
2005-09-30 21:13:37 +04:00
pstring keypath ;
int path_len ;
2005-01-10 23:33:41 +03:00
WERROR result = WERR_OK ;
2003-01-19 08:04:03 +03:00
2005-09-30 21:13:37 +04:00
/* create a full registry path and strip any trailing '\'
characters */
pstr_sprintf ( keypath , " %s%s%s " ,
parent ? parent - > name : " " ,
parent ? " \\ " : " " ,
subkeyname ) ;
2002-07-15 14:35:28 +04:00
2005-09-30 21:13:37 +04:00
path_len = strlen ( keypath ) ;
if ( path_len & & keypath [ path_len - 1 ] = = ' \\ ' )
keypath [ path_len - 1 ] = ' \0 ' ;
2002-07-15 14:35:28 +04:00
2005-09-30 21:13:37 +04:00
/* now do the internal open */
2005-06-25 02:34:40 +04:00
2005-09-30 21:13:37 +04:00
result = regkey_open_internal ( keyinfo , keypath , p - > pipe_user . nt_user_token , access_desired ) ;
if ( ! W_ERROR_IS_OK ( result ) )
return result ;
if ( ! create_policy_hnd ( p , hnd , free_regkey_info , * keyinfo ) ) {
2005-08-29 18:55:40 +04:00
result = WERR_BADFILE ;
2005-10-07 16:14:25 +04:00
regkey_close_internal ( * keyinfo ) ;
2002-08-17 19:34:15 +04:00
}
2005-06-25 02:34:40 +04:00
2002-08-17 19:34:15 +04:00
return result ;
2002-07-15 14:35:28 +04:00
}
/*******************************************************************
Function for open a new registry handle and creating a handle
Note that P should be valid & hnd should already have space
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static BOOL close_registry_key ( pipes_struct * p , POLICY_HND * hnd )
{
2002-08-17 19:34:15 +04:00
REGISTRY_KEY * regkey = find_regkey_index_by_hnd ( p , hnd ) ;
2002-07-15 14:35:28 +04:00
if ( ! regkey ) {
DEBUG ( 2 , ( " close_registry_key: Invalid handle (%s:%u:%u) \n " , OUR_HANDLE ( hnd ) ) ) ;
return False ;
}
close_policy_hnd ( p , hnd ) ;
return True ;
}
/********************************************************************
retrieve information about the subkeys
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-08-17 19:34:15 +04:00
static BOOL get_subkey_information ( REGISTRY_KEY * key , uint32 * maxnum , uint32 * maxlen )
2002-07-15 14:35:28 +04:00
{
2002-08-17 19:34:15 +04:00
int num_subkeys , i ;
uint32 max_len ;
2005-08-29 18:55:40 +04:00
REGSUBKEY_CTR * subkeys ;
2002-08-17 19:34:15 +04:00
uint32 len ;
2002-07-15 14:35:28 +04:00
if ( ! key )
return False ;
2002-08-17 19:34:15 +04:00
2005-08-29 18:55:40 +04:00
if ( ! ( subkeys = TALLOC_ZERO_P ( NULL , REGSUBKEY_CTR ) ) )
return False ;
if ( fetch_reg_keys ( key , subkeys ) = = - 1 )
2002-07-15 14:35:28 +04:00
return False ;
/* find the longest string */
max_len = 0 ;
2005-08-29 18:55:40 +04:00
num_subkeys = regsubkey_ctr_numkeys ( subkeys ) ;
2002-08-17 19:34:15 +04:00
2002-07-15 14:35:28 +04:00
for ( i = 0 ; i < num_subkeys ; i + + ) {
2005-08-29 18:55:40 +04:00
len = strlen ( regsubkey_ctr_specific_key ( subkeys , i ) ) ;
2002-07-15 14:35:28 +04:00
max_len = MAX ( max_len , len ) ;
}
* maxnum = num_subkeys ;
* maxlen = max_len * 2 ;
2005-08-29 18:55:40 +04:00
TALLOC_FREE ( subkeys ) ;
2002-07-15 14:35:28 +04:00
return True ;
}
/********************************************************************
2005-06-29 20:35:32 +04:00
retrieve information about the values .
2002-07-15 14:35:28 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-08-17 19:34:15 +04:00
static BOOL get_value_information ( REGISTRY_KEY * key , uint32 * maxnum ,
2002-07-15 14:35:28 +04:00
uint32 * maxlen , uint32 * maxsize )
{
2005-08-29 18:55:40 +04:00
REGVAL_CTR * values ;
2002-08-17 19:34:15 +04:00
REGISTRY_VALUE * val ;
uint32 sizemax , lenmax ;
int i , num_values ;
2002-07-15 14:35:28 +04:00
if ( ! key )
return False ;
2005-08-29 18:55:40 +04:00
if ( ! ( values = TALLOC_ZERO_P ( NULL , REGVAL_CTR ) ) )
return False ;
2002-08-17 19:34:15 +04:00
2005-08-29 18:55:40 +04:00
if ( fetch_reg_values ( key , values ) = = - 1 )
2002-08-17 19:34:15 +04:00
return False ;
lenmax = sizemax = 0 ;
2005-08-29 18:55:40 +04:00
num_values = regval_ctr_numvals ( values ) ;
2002-08-17 19:34:15 +04:00
2005-08-29 18:55:40 +04:00
val = regval_ctr_specific_value ( values , 0 ) ;
2002-08-17 19:34:15 +04:00
for ( i = 0 ; i < num_values & & val ; i + + )
{
2005-06-29 20:35:32 +04:00
lenmax = MAX ( lenmax , val - > valuename ? strlen ( val - > valuename ) + 1 : 0 ) ;
2002-08-17 19:34:15 +04:00
sizemax = MAX ( sizemax , val - > size ) ;
2005-08-29 18:55:40 +04:00
val = regval_ctr_specific_value ( values , i ) ;
2002-08-17 19:34:15 +04:00
}
2002-07-15 14:35:28 +04:00
2002-08-17 19:34:15 +04:00
* maxnum = num_values ;
* maxlen = lenmax ;
* maxsize = sizemax ;
2005-08-29 18:55:40 +04:00
TALLOC_FREE ( values ) ;
2002-08-17 19:34:15 +04:00
return True ;
2002-07-15 14:35:28 +04:00
}
2002-08-17 19:34:15 +04:00
2002-07-15 14:35:28 +04:00
/********************************************************************
reg_close
2001-02-25 05:14:49 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2006-09-21 21:51:06 +04:00
WERROR _winreg_CloseKey ( pipes_struct * p , struct policy_handle * handle )
2001-02-25 05:14:49 +03:00
{
/* close the policy handle */
2005-06-17 00:45:55 +04:00
2006-09-21 21:51:06 +04:00
if ( ! close_registry_key ( p , handle ) )
2005-06-17 00:45:55 +04:00
return WERR_BADFID ;
2001-02-25 05:14:49 +03:00
2005-01-10 23:33:41 +03:00
return WERR_OK ;
2001-02-25 05:14:49 +03:00
}
/*******************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2006-09-21 21:51:06 +04:00
WERROR _winreg_OpenHKLM ( pipes_struct * p , uint16_t * system_name , uint32_t access_mask , struct policy_handle * handle )
2002-07-15 14:35:28 +04:00
{
2005-09-30 21:13:37 +04:00
REGISTRY_KEY * keyinfo ;
2005-06-17 00:29:15 +04:00
2006-09-21 21:51:06 +04:00
return open_registry_key ( p , handle , & keyinfo , NULL , KEY_HKLM , access_mask ) ;
2005-09-30 21:13:37 +04:00
}
/*******************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2006-09-21 21:51:06 +04:00
WERROR _winreg_OpenHKPD ( pipes_struct * p , uint16_t * system_name , uint32_t access_mask , struct policy_handle * handle )
2005-09-30 21:13:37 +04:00
{
REGISTRY_KEY * keyinfo ;
2005-06-17 00:29:15 +04:00
2006-09-21 21:51:06 +04:00
return open_registry_key ( p , handle , & keyinfo , NULL , KEY_HKPD , access_mask ) ;
2002-08-17 19:34:15 +04:00
}
2002-07-15 14:35:28 +04:00
2002-08-17 19:34:15 +04:00
/*******************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2006-09-21 21:51:06 +04:00
WERROR _winreg_OpenHKPT ( pipes_struct * p , uint16_t * system_name , uint32_t access_mask , struct policy_handle * handle )
2002-08-17 19:34:15 +04:00
{
2005-09-30 21:13:37 +04:00
REGISTRY_KEY * keyinfo ;
2005-06-17 00:29:15 +04:00
2006-09-21 21:51:06 +04:00
return open_registry_key ( p , handle , & keyinfo , NULL , KEY_HKPT , access_mask ) ;
2005-09-30 21:13:37 +04:00
}
/*******************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2006-09-21 21:51:06 +04:00
WERROR _winreg_OpenHKCR ( pipes_struct * p , uint16_t * system_name , uint32_t access_mask , struct policy_handle * handle )
2005-09-30 21:13:37 +04:00
{
REGISTRY_KEY * keyinfo ;
2005-06-17 00:29:15 +04:00
2006-09-21 21:51:06 +04:00
return open_registry_key ( p , handle , & keyinfo , NULL , KEY_HKCR , access_mask ) ;
2002-07-15 14:35:28 +04:00
}
/*******************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2006-09-21 21:51:06 +04:00
WERROR _winreg_OpenHKU ( pipes_struct * p , uint16_t * system_name , uint32_t access_mask , struct policy_handle * handle )
2001-02-25 05:14:49 +03:00
{
2005-09-30 21:13:37 +04:00
REGISTRY_KEY * keyinfo ;
2006-09-21 21:51:06 +04:00
return open_registry_key ( p , handle , & keyinfo , NULL , KEY_HKU , access_mask ) ;
}
/*******************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
WERROR _winreg_OpenHKCU ( pipes_struct * p , uint16_t * system_name , uint32_t access_mask , struct policy_handle * handle )
{
REGISTRY_KEY * keyinfo ;
return open_registry_key ( p , handle , & keyinfo , NULL , KEY_HKCU , access_mask ) ;
}
/*******************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
WERROR _winreg_OpenHKCC ( pipes_struct * p , uint16_t * system_name , uint32_t access_mask , struct policy_handle * handle )
{
REGISTRY_KEY * keyinfo ;
return open_registry_key ( p , handle , & keyinfo , NULL , KEY_HKCC , access_mask ) ;
}
/*******************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
WERROR _winreg_OpenHKDD ( pipes_struct * p , uint16_t * system_name , uint32_t access_mask , struct policy_handle * handle )
{
REGISTRY_KEY * keyinfo ;
return open_registry_key ( p , handle , & keyinfo , NULL , KEY_HKDD , access_mask ) ;
}
/*******************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
WERROR _winreg_OpenHKPN ( pipes_struct * p , uint16_t * system_name , uint32_t access_mask , struct policy_handle * handle )
{
REGISTRY_KEY * keyinfo ;
return open_registry_key ( p , handle , & keyinfo , NULL , KEY_HKPN , access_mask ) ;
2001-02-25 05:14:49 +03:00
}
/*******************************************************************
reg_reply_open_entry
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2006-09-21 21:51:06 +04:00
WERROR _winreg_OpenKey ( pipes_struct * p , struct policy_handle * parent_handle , struct winreg_String keyname , uint32_t unknown , uint32_t access_mask , struct policy_handle * handle )
2001-02-25 05:14:49 +03:00
{
2006-09-21 21:51:06 +04:00
char * name ;
REGISTRY_KEY * parent = find_regkey_index_by_hnd ( p , parent_handle ) ;
2005-09-30 21:13:37 +04:00
REGISTRY_KEY * newkey = NULL ;
uint32 check_rights ;
2001-02-25 05:14:49 +03:00
2005-06-17 19:35:31 +04:00
if ( ! parent )
2005-06-17 00:45:55 +04:00
return WERR_BADFID ;
2005-06-25 02:34:40 +04:00
2006-09-21 21:51:06 +04:00
if ( ( name = talloc_strdup ( p - > mem_ctx , keyname . name ) ) = = NULL ) {
return WERR_INVALID_PARAM ;
}
2002-07-15 14:35:28 +04:00
2005-06-17 05:57:18 +04:00
/* check granted access first; what is the correct mask here? */
2005-09-30 21:13:37 +04:00
check_rights = ( SEC_RIGHTS_ENUM_SUBKEYS |
SEC_RIGHTS_CREATE_SUBKEY |
SEC_RIGHTS_QUERY_VALUE |
SEC_RIGHTS_SET_VALUE ) ;
2005-10-06 21:48:03 +04:00
if ( ! ( parent - > access_granted & check_rights ) ) {
DEBUG ( 8 , ( " Rights check failed, parent had %04x, check_rights %04x \n " , parent - > access_granted , check_rights ) ) ;
2005-06-17 05:57:18 +04:00
return WERR_ACCESS_DENIED ;
2005-10-06 21:48:03 +04:00
}
2005-06-25 02:34:40 +04:00
2005-09-30 21:13:37 +04:00
/*
* very crazy , but regedit . exe on Win2k will attempt to call
* REG_OPEN_ENTRY with a keyname of " " . We should return a new
* ( second ) handle here on the key - > name . regedt32 . exe does
* not do this stupidity . - - jerry
*/
2006-09-21 21:51:06 +04:00
return open_registry_key ( p , handle , & newkey , parent , name , access_mask ) ;
2001-02-25 05:14:49 +03:00
}
/*******************************************************************
reg_reply_info
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2006-09-26 23:37:37 +04:00
WERROR _winreg_QueryValue ( pipes_struct * p , struct policy_handle * handle , struct winreg_String value_name , enum winreg_Type * type , uint8_t * data , uint32_t * data_size , uint32_t * value_length )
2001-02-25 05:14:49 +03:00
{
2005-01-10 23:33:41 +03:00
WERROR status = WERR_BADFILE ;
2006-09-21 21:51:06 +04:00
char * name ;
REGISTRY_KEY * regkey = find_regkey_index_by_hnd ( p , handle ) ;
2002-08-17 19:34:15 +04:00
REGISTRY_VALUE * val = NULL ;
2005-08-29 18:55:40 +04:00
REGVAL_CTR * regvals ;
2002-08-17 19:34:15 +04:00
int i ;
2001-02-25 05:14:49 +03:00
2002-08-17 19:34:15 +04:00
if ( ! regkey )
2005-06-17 00:45:55 +04:00
return WERR_BADFID ;
2006-09-21 21:51:06 +04:00
2006-09-26 23:37:37 +04:00
* value_length = * type = 0 ;
2006-09-21 22:22:51 +04:00
2002-08-17 19:34:15 +04:00
DEBUG ( 7 , ( " _reg_info: policy key name = [%s] \n " , regkey - > name ) ) ;
2005-09-30 21:13:37 +04:00
DEBUG ( 7 , ( " _reg_info: policy key type = [%08x] \n " , regkey - > type ) ) ;
2002-08-17 19:34:15 +04:00
2006-09-21 21:51:06 +04:00
if ( ( name = talloc_strdup ( p - > mem_ctx , value_name . name ) ) = = NULL ) {
return WERR_NOMEM ;
}
2001-02-25 05:14:49 +03:00
2005-09-30 21:13:37 +04:00
DEBUG ( 5 , ( " _reg_info: looking up value: [%s] \n " , name ) ) ;
2001-02-25 05:14:49 +03:00
2005-10-15 01:09:56 +04:00
if ( ! ( regvals = TALLOC_ZERO_P ( p - > mem_ctx , REGVAL_CTR ) ) )
2005-08-29 18:55:40 +04:00
return WERR_NOMEM ;
2002-08-17 19:34:15 +04:00
2005-09-30 21:13:37 +04:00
/* Handle QueryValue calls on HKEY_PERFORMANCE_DATA */
if ( regkey - > type = = REG_KEY_HKPD )
{
if ( strequal ( name , " Global " ) )
{
uint32 outbuf_len ;
prs_struct prs_hkpd ;
2006-09-26 23:37:37 +04:00
prs_init ( & prs_hkpd , * data_size , p - > mem_ctx , MARSHALL ) ;
status = reg_perfcount_get_hkpd ( & prs_hkpd , * data_size , & outbuf_len , NULL ) ;
2005-09-30 21:13:37 +04:00
regval_ctr_addvalue ( regvals , " HKPD " , REG_BINARY ,
prs_hkpd . data_p , outbuf_len ) ;
val = dup_registry_value ( regval_ctr_specific_value ( regvals , 0 ) ) ;
prs_mem_free ( & prs_hkpd ) ;
}
else if ( strequal ( name , " Counter 009 " ) )
{
uint32 base_index ;
uint32 buffer_size ;
char * buffer ;
buffer = NULL ;
base_index = reg_perfcount_get_base_index ( ) ;
buffer_size = reg_perfcount_get_counter_names ( base_index , & buffer ) ;
regval_ctr_addvalue ( regvals , " Counter 009 " ,
REG_MULTI_SZ , buffer , buffer_size ) ;
val = dup_registry_value ( regval_ctr_specific_value ( regvals , 0 ) ) ;
if ( buffer_size > 0 )
{
SAFE_FREE ( buffer ) ;
status = WERR_OK ;
}
}
else if ( strequal ( name , " Explain 009 " ) )
{
uint32 base_index ;
uint32 buffer_size ;
char * buffer ;
buffer = NULL ;
base_index = reg_perfcount_get_base_index ( ) ;
buffer_size = reg_perfcount_get_counter_help ( base_index , & buffer ) ;
regval_ctr_addvalue ( regvals , " Explain 009 " ,
REG_MULTI_SZ , buffer , buffer_size ) ;
val = dup_registry_value ( regval_ctr_specific_value ( regvals , 0 ) ) ;
if ( buffer_size > 0 )
{
SAFE_FREE ( buffer ) ;
status = WERR_OK ;
}
}
else if ( isdigit ( name [ 0 ] ) )
{
/* we probably have a request for a specific object here */
uint32 outbuf_len ;
prs_struct prs_hkpd ;
2006-09-26 23:37:37 +04:00
prs_init ( & prs_hkpd , * data_size , p - > mem_ctx , MARSHALL ) ;
status = reg_perfcount_get_hkpd ( & prs_hkpd , * data_size , & outbuf_len , name ) ;
2005-09-30 21:13:37 +04:00
regval_ctr_addvalue ( regvals , " HKPD " , REG_BINARY ,
prs_hkpd . data_p , outbuf_len ) ;
val = dup_registry_value ( regval_ctr_specific_value ( regvals , 0 ) ) ;
prs_mem_free ( & prs_hkpd ) ;
}
else
{
DEBUG ( 3 , ( " Unsupported key name [%s] for HKPD. \n " , name ) ) ;
return WERR_BADFILE ;
}
}
/* HKPT calls can be handled out of reg_dynamic.c with the hkpt_params handler */
else
2002-08-17 19:34:15 +04:00
{
2005-09-30 21:13:37 +04:00
for ( i = 0 ; fetch_reg_values_specific ( regkey , & val , i ) ; i + + )
{
2002-08-17 19:34:15 +04:00
DEBUG ( 10 , ( " _reg_info: Testing value [%s] \n " , val - > valuename ) ) ;
2005-06-24 18:55:09 +04:00
if ( strequal ( val - > valuename , name ) ) {
2002-08-17 19:34:15 +04:00
DEBUG ( 10 , ( " _reg_info: Found match for value [%s] \n " , name ) ) ;
2005-01-10 23:33:41 +03:00
status = WERR_OK ;
2002-07-15 14:35:28 +04:00
break ;
2002-08-17 19:34:15 +04:00
}
free_registry_value ( val ) ;
2005-09-30 21:13:37 +04:00
}
2001-02-25 05:14:49 +03:00
}
2006-09-26 23:37:37 +04:00
/* if we have a value then copy it to the output */
2006-09-21 21:51:06 +04:00
if ( val ) {
2006-09-26 23:37:37 +04:00
* value_length = regval_size ( val ) ;
* type = val - > type ;
2006-09-21 21:51:06 +04:00
2006-09-27 17:24:57 +04:00
if ( * data_size = = 0 | | ! data ) {
2006-09-26 23:37:37 +04:00
status = WERR_OK ;
} else if ( * value_length > * data_size ) {
status = WERR_MORE_DATA ;
} else {
memcpy ( data , regval_data_p ( val ) , * value_length ) ;
status = WERR_OK ;
2006-09-21 21:51:06 +04:00
}
2006-09-27 02:03:52 +04:00
* data_size = * value_length ;
2006-09-21 21:51:06 +04:00
}
2005-08-29 18:55:40 +04:00
TALLOC_FREE ( regvals ) ;
2002-08-17 19:34:15 +04:00
free_registry_value ( val ) ;
2001-02-25 05:14:49 +03:00
2002-07-15 14:35:28 +04:00
return status ;
}
/*****************************************************************************
Implementation of REG_QUERY_KEY
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2006-09-21 21:51:06 +04:00
WERROR _winreg_QueryInfoKey ( pipes_struct * p , struct policy_handle * handle ,
2006-09-27 01:01:57 +04:00
struct winreg_String * classname ,
uint32_t * num_subkeys , uint32_t * max_subkeylen ,
uint32_t * max_subkeysize ,
2006-09-21 21:51:06 +04:00
uint32_t * num_values , uint32_t * max_valnamelen ,
2006-09-27 01:01:57 +04:00
uint32_t * max_valbufsize ,
uint32_t * secdescsize , NTTIME * last_changed_time )
2002-07-15 14:35:28 +04:00
{
2005-01-10 23:33:41 +03:00
WERROR status = WERR_OK ;
2006-09-21 21:51:06 +04:00
REGISTRY_KEY * regkey = find_regkey_index_by_hnd ( p , handle ) ;
2002-07-15 14:35:28 +04:00
if ( ! regkey )
2005-06-17 00:45:55 +04:00
return WERR_BADFID ;
2002-07-15 14:35:28 +04:00
2006-09-21 21:51:06 +04:00
if ( ! get_subkey_information ( regkey , num_subkeys , max_subkeylen ) ) {
2006-09-27 01:01:57 +04:00
DEBUG ( 0 , ( " _winreg_QueryInfoKey: get_subkey_information() failed! \n " ) ) ;
2005-01-10 23:33:41 +03:00
return WERR_ACCESS_DENIED ;
2005-07-01 00:16:16 +04:00
}
2002-07-15 14:35:28 +04:00
2006-09-21 21:51:06 +04:00
if ( ! get_value_information ( regkey , num_values , max_valnamelen , max_valbufsize ) ) {
2006-09-27 01:01:57 +04:00
DEBUG ( 0 , ( " _winreg_QueryInfoKey: get_value_information() failed! \n " ) ) ;
2005-01-10 23:33:41 +03:00
return WERR_ACCESS_DENIED ;
2005-07-01 00:16:16 +04:00
}
2002-08-17 19:34:15 +04:00
2006-09-27 01:01:57 +04:00
* secdescsize = 0 ; /* used to be hard coded for 0x00000078 */
2006-09-21 21:51:06 +04:00
* last_changed_time = 0 ;
2006-09-27 01:01:57 +04:00
* max_subkeysize = 0 ; /* maybe this is the classname length ? */
2002-07-15 14:35:28 +04:00
2006-09-27 01:01:57 +04:00
/* don't bother with class names for now */
classname - > name = NULL ;
2002-07-15 14:35:28 +04:00
return status ;
}
/*****************************************************************************
2005-03-24 02:26:33 +03:00
Implementation of REG_GETVERSION
2002-07-15 14:35:28 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2006-09-21 21:51:06 +04:00
WERROR _winreg_GetVersion ( pipes_struct * p , struct policy_handle * handle , uint32_t * version )
2002-07-15 14:35:28 +04:00
{
2006-09-21 21:51:06 +04:00
REGISTRY_KEY * regkey = find_regkey_index_by_hnd ( p , handle ) ;
2002-07-15 14:35:28 +04:00
if ( ! regkey )
2005-06-17 00:45:55 +04:00
return WERR_BADFID ;
2002-07-15 14:35:28 +04:00
2006-09-21 21:51:06 +04:00
* version = 0x00000005 ; /* Windows 2000 registry API version */
2002-07-15 14:35:28 +04:00
2006-09-21 21:51:06 +04:00
return WERR_OK ;
2002-07-15 14:35:28 +04:00
}
2001-02-25 05:14:49 +03:00
2002-07-15 14:35:28 +04:00
/*****************************************************************************
Implementation of REG_ENUM_KEY
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2006-09-21 21:51:06 +04:00
WERROR _winreg_EnumKey ( pipes_struct * p , struct policy_handle * handle , uint32_t enum_index , struct winreg_StringBuf * name , struct winreg_StringBuf * keyclass , NTTIME * last_changed_time )
2002-07-15 14:35:28 +04:00
{
2005-01-10 23:33:41 +03:00
WERROR status = WERR_OK ;
2006-09-21 21:51:06 +04:00
REGISTRY_KEY * regkey = find_regkey_index_by_hnd ( p , handle ) ;
2002-08-17 19:34:15 +04:00
char * subkey = NULL ;
2002-07-15 14:35:28 +04:00
if ( ! regkey )
2005-06-17 00:45:55 +04:00
return WERR_BADFID ;
2002-07-15 14:35:28 +04:00
2006-09-21 22:54:25 +04:00
if ( ! name | | ! keyclass )
2006-09-21 21:51:06 +04:00
return WERR_INVALID_PARAM ;
2002-07-15 14:35:28 +04:00
DEBUG ( 8 , ( " _reg_enum_key: enumerating key [%s] \n " , regkey - > name ) ) ;
2006-09-21 21:51:06 +04:00
if ( ! fetch_reg_keys_specific ( regkey , & subkey , enum_index ) ) {
2005-01-10 23:33:41 +03:00
status = WERR_NO_MORE_ITEMS ;
2002-07-15 14:35:28 +04:00
goto done ;
}
DEBUG ( 10 , ( " _reg_enum_key: retrieved subkey named [%s] \n " , subkey ) ) ;
2006-09-21 22:54:25 +04:00
if ( last_changed_time ) {
* last_changed_time = 0 ;
}
2006-09-21 21:51:06 +04:00
keyclass - > name = NULL ;
if ( ( name - > name = talloc_strdup ( p - > mem_ctx , subkey ) ) = = NULL ) {
status = WERR_NOMEM ;
}
2002-07-15 14:35:28 +04:00
done :
2002-08-17 19:34:15 +04:00
SAFE_FREE ( subkey ) ;
return status ;
}
/*****************************************************************************
Implementation of REG_ENUM_VALUE
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2006-09-21 21:51:06 +04:00
2006-09-27 01:01:57 +04:00
WERROR _winreg_EnumValue ( pipes_struct * p , struct policy_handle * handle , uint32_t enum_index , struct winreg_StringBuf * name , enum winreg_Type * type , uint8_t * data , uint32_t * data_size , uint32_t * value_length )
2002-08-17 19:34:15 +04:00
{
2005-01-10 23:33:41 +03:00
WERROR status = WERR_OK ;
2006-09-21 21:51:06 +04:00
REGISTRY_KEY * regkey = find_regkey_index_by_hnd ( p , handle ) ;
2002-08-17 19:34:15 +04:00
REGISTRY_VALUE * val ;
if ( ! regkey )
2005-06-17 00:45:55 +04:00
return WERR_BADFID ;
2002-08-17 19:34:15 +04:00
2006-09-27 01:01:57 +04:00
if ( ! name )
2006-09-21 21:51:06 +04:00
return WERR_INVALID_PARAM ;
2006-09-27 01:01:57 +04:00
DEBUG ( 8 , ( " _winreg_EnumValue: enumerating values for key [%s] \n " , regkey - > name ) ) ;
2002-08-17 19:34:15 +04:00
2006-09-21 21:51:06 +04:00
if ( ! fetch_reg_values_specific ( regkey , & val , enum_index ) ) {
2005-01-10 23:33:41 +03:00
status = WERR_NO_MORE_ITEMS ;
2002-08-17 19:34:15 +04:00
goto done ;
}
2005-10-15 01:09:56 +04:00
2006-09-27 01:01:57 +04:00
DEBUG ( 10 , ( " _winreg_EnumValue: retrieved value named [%s] \n " , val - > valuename ) ) ;
2002-08-17 19:34:15 +04:00
/* subkey has the string name now */
2006-09-21 21:51:06 +04:00
if ( ( name - > name = talloc_strdup ( p - > mem_ctx , val - > valuename ) ) = = NULL ) {
status = WERR_NOMEM ;
}
2006-09-27 01:01:57 +04:00
* value_length = regval_size ( val ) ;
* type = val - > type ;
2006-09-21 21:51:06 +04:00
2006-09-27 17:24:57 +04:00
if ( * data_size = = 0 | | ! data ) {
2006-09-27 01:01:57 +04:00
status = WERR_OK ;
} else if ( * value_length > * data_size ) {
status = WERR_MORE_DATA ;
} else {
memcpy ( data , regval_data_p ( val ) , * value_length ) ;
status = WERR_OK ;
2006-09-21 21:51:06 +04:00
}
2006-09-27 02:03:52 +04:00
* data_size = * value_length ;
2002-08-17 19:34:15 +04:00
done :
free_registry_value ( val ) ;
2001-02-25 05:14:49 +03:00
return status ;
}
2001-08-24 03:25:34 +04:00
2002-07-15 14:35:28 +04:00
2001-08-24 03:25:34 +04:00
/*******************************************************************
reg_shutdwon
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2006-09-21 21:51:06 +04:00
WERROR _winreg_InitiateSystemShutdown ( pipes_struct * p , uint16_t * hostname , struct initshutdown_String * message , uint32_t timeout , uint8_t force_apps , uint8_t reboot )
2001-08-24 03:25:34 +04:00
{
2006-09-21 21:51:06 +04:00
uint32_t reason = 0 ;
/* thunk down to _winreg_InitiateSystemShutdownEx()
( just returns a status ) */
2005-03-24 02:26:33 +03:00
2006-09-21 21:51:06 +04:00
return _winreg_InitiateSystemShutdownEx ( p , hostname , message , timeout ,
force_apps , reboot , reason ) ;
2005-03-24 02:26:33 +03:00
}
/*******************************************************************
reg_shutdown_ex
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# define SHUTDOWN_R_STRING "-r"
# define SHUTDOWN_F_STRING "-f"
2006-09-21 21:51:06 +04:00
WERROR _winreg_InitiateSystemShutdownEx ( pipes_struct * p , uint16_t * hostname , struct initshutdown_String * message , uint32_t timeout , uint8_t force_apps , uint8_t reboot , uint32_t reason )
2005-03-24 02:26:33 +03:00
{
2001-08-24 03:25:34 +04:00
pstring shutdown_script ;
2006-09-21 21:51:06 +04:00
char * msg = NULL ;
2001-08-24 11:51:59 +04:00
pstring chkmsg ;
2006-09-21 21:51:06 +04:00
fstring str_timeout ;
fstring str_reason ;
2001-08-24 03:25:34 +04:00
fstring r ;
fstring f ;
2005-03-24 02:26:33 +03:00
int ret ;
BOOL can_shutdown ;
2001-08-24 03:25:34 +04:00
2005-05-23 20:25:31 +04:00
2005-03-24 02:26:33 +03:00
pstrcpy ( shutdown_script , lp_shutdown_script ( ) ) ;
if ( ! * shutdown_script )
return WERR_ACCESS_DENIED ;
/* pull the message string and perform necessary sanity checks on it */
2006-09-21 21:51:06 +04:00
if ( message & & message - > name & & message - > name - > name ) {
if ( ( msg = talloc_strdup ( p - > mem_ctx , message - > name - > name ) ) = = NULL ) {
return WERR_NOMEM ;
}
}
alpha_strcpy ( chkmsg , msg ? msg : " " , NULL , strlen ( msg ) ) ;
2005-03-24 02:26:33 +03:00
2006-09-21 21:51:06 +04:00
fstr_sprintf ( str_timeout , " %d " , timeout ) ;
fstr_sprintf ( r , reboot ? SHUTDOWN_R_STRING : " " ) ;
fstr_sprintf ( f , force_apps ? SHUTDOWN_F_STRING : " " ) ;
fstr_sprintf ( str_reason , " %d " , reason ) ;
2001-08-24 03:25:34 +04:00
2005-03-24 02:26:33 +03:00
all_string_sub ( shutdown_script , " %z " , chkmsg , sizeof ( shutdown_script ) ) ;
2006-09-21 21:51:06 +04:00
all_string_sub ( shutdown_script , " %t " , str_timeout , sizeof ( shutdown_script ) ) ;
2005-03-24 02:26:33 +03:00
all_string_sub ( shutdown_script , " %r " , r , sizeof ( shutdown_script ) ) ;
all_string_sub ( shutdown_script , " %f " , f , sizeof ( shutdown_script ) ) ;
2006-09-21 21:51:06 +04:00
all_string_sub ( shutdown_script , " %x " , str_reason , sizeof ( shutdown_script ) ) ;
2005-05-23 20:25:31 +04:00
2005-03-24 02:26:33 +03:00
can_shutdown = user_has_privileges ( p - > pipe_user . nt_user_token , & se_remote_shutdown ) ;
2005-01-18 21:30:32 +03:00
2005-03-24 02:26:33 +03:00
/* IF someone has privs, run the shutdown script as root. OTHERWISE run it as not root
Take the error return from the script and provide it as the Windows return code . */
2005-04-05 21:49:16 +04:00
/********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/
if ( can_shutdown )
become_root ( ) ;
2005-03-24 02:26:33 +03:00
ret = smbrun ( shutdown_script , NULL ) ;
2005-04-05 21:49:16 +04:00
if ( can_shutdown )
unbecome_root ( ) ;
/********** END SeRemoteShutdownPrivilege BLOCK **********/
2005-05-23 20:25:31 +04:00
2005-03-24 02:26:33 +03:00
DEBUG ( 3 , ( " _reg_shutdown_ex: Running the command `%s' gave %d \n " ,
shutdown_script , ret ) ) ;
2001-08-24 03:25:34 +04:00
2005-03-24 02:26:33 +03:00
return ( ret = = 0 ) ? WERR_OK : WERR_ACCESS_DENIED ;
2001-08-24 03:25:34 +04:00
}
2001-08-24 11:51:59 +04:00
2005-03-24 02:26:33 +03:00
2002-07-15 14:35:28 +04:00
/*******************************************************************
reg_abort_shutdwon
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2006-09-21 21:51:06 +04:00
WERROR _winreg_AbortSystemShutdown ( pipes_struct * p , uint16_t * server )
2001-08-24 11:51:59 +04:00
{
pstring abort_shutdown_script ;
2005-03-24 02:26:33 +03:00
int ret ;
BOOL can_shutdown ;
2001-08-24 11:51:59 +04:00
pstrcpy ( abort_shutdown_script , lp_abort_shutdown_script ( ) ) ;
2005-03-24 02:26:33 +03:00
if ( ! * abort_shutdown_script )
return WERR_ACCESS_DENIED ;
2005-01-18 21:30:32 +03:00
2005-03-24 02:26:33 +03:00
can_shutdown = user_has_privileges ( p - > pipe_user . nt_user_token , & se_remote_shutdown ) ;
2005-01-18 21:30:32 +03:00
2005-04-05 21:49:16 +04:00
/********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/
2005-03-24 02:26:33 +03:00
2005-04-05 21:49:16 +04:00
if ( can_shutdown )
become_root ( ) ;
2005-03-24 02:26:33 +03:00
ret = smbrun ( abort_shutdown_script , NULL ) ;
2005-04-05 21:49:16 +04:00
if ( can_shutdown )
unbecome_root ( ) ;
/********** END SeRemoteShutdownPrivilege BLOCK **********/
2005-03-24 02:26:33 +03:00
DEBUG ( 3 , ( " _reg_abort_shutdown: Running the command `%s' gave %d \n " ,
abort_shutdown_script , ret ) ) ;
2001-08-24 11:51:59 +04:00
2005-03-24 02:26:33 +03:00
return ( ret = = 0 ) ? WERR_OK : WERR_ACCESS_DENIED ;
2001-08-24 11:51:59 +04:00
}
2002-07-15 14:35:28 +04:00
2005-05-23 20:25:31 +04:00
/*******************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int validate_reg_filename ( pstring fname )
{
char * p ;
int num_services = lp_numservices ( ) ;
int snum ;
pstring share_path ;
pstring unix_fname ;
/* convert to a unix path, stripping the C:\ along the way */
if ( ! ( p = valid_share_pathname ( fname ) ) )
return - 1 ;
/* has to exist within a valid file share */
for ( snum = 0 ; snum < num_services ; snum + + ) {
if ( ! lp_snum_ok ( snum ) | | lp_print_ok ( snum ) )
continue ;
pstrcpy ( share_path , lp_pathname ( snum ) ) ;
/* make sure we have a path (e.g. [homes] ) */
if ( strlen ( share_path ) = = 0 )
continue ;
if ( strncmp ( share_path , p , strlen ( share_path ) ) = = 0 )
break ;
}
/* p and fname are overlapping memory so copy out and back in again */
pstrcpy ( unix_fname , p ) ;
pstrcpy ( fname , unix_fname ) ;
return ( snum < num_services ) ? snum : - 1 ;
}
2005-06-09 19:20:11 +04:00
/*******************************************************************
2005-06-27 07:40:03 +04:00
Note : topkeypat is the * full * path that this * key will be
2005-06-09 19:20:11 +04:00
loaded into ( including the name of the key )
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static WERROR reg_load_tree ( REGF_FILE * regfile , const char * topkeypath ,
REGF_NK_REC * key )
{
REGF_NK_REC * subkey ;
REGISTRY_KEY registry_key ;
2005-08-29 18:55:40 +04:00
REGVAL_CTR * values ;
REGSUBKEY_CTR * subkeys ;
2005-06-09 19:20:11 +04:00
int i ;
pstring path ;
WERROR result = WERR_OK ;
/* initialize the REGISTRY_KEY structure */
if ( ! ( registry_key . hook = reghook_cache_find ( topkeypath ) ) ) {
DEBUG ( 0 , ( " reg_load_tree: Failed to assigned a REGISTRY_HOOK to [%s] \n " ,
topkeypath ) ) ;
return WERR_BADFILE ;
}
pstrcpy ( registry_key . name , topkeypath ) ;
/* now start parsing the values and subkeys */
2005-08-29 18:55:40 +04:00
if ( ! ( subkeys = TALLOC_ZERO_P ( regfile - > mem_ctx , REGSUBKEY_CTR ) ) )
return WERR_NOMEM ;
2005-06-09 19:20:11 +04:00
2005-08-29 18:55:40 +04:00
if ( ! ( values = TALLOC_ZERO_P ( subkeys , REGVAL_CTR ) ) )
return WERR_NOMEM ;
2005-06-09 19:20:11 +04:00
/* copy values into the REGVAL_CTR */
for ( i = 0 ; i < key - > num_values ; i + + ) {
2005-08-29 18:55:40 +04:00
regval_ctr_addvalue ( values , key - > values [ i ] . valuename , key - > values [ i ] . type ,
2005-08-30 15:33:12 +04:00
( char * ) key - > values [ i ] . data , ( key - > values [ i ] . data_size & ~ VK_DATA_IN_OFFSET ) ) ;
2005-06-09 19:20:11 +04:00
}
/* copy subkeys into the REGSUBKEY_CTR */
key - > subkey_index = 0 ;
while ( ( subkey = regfio_fetch_subkey ( regfile , key ) ) ) {
2005-08-29 18:55:40 +04:00
regsubkey_ctr_addkey ( subkeys , subkey - > keyname ) ;
2005-06-09 19:20:11 +04:00
}
/* write this key and values out */
2005-08-29 18:55:40 +04:00
if ( ! store_reg_values ( & registry_key , values )
| | ! store_reg_keys ( & registry_key , subkeys ) )
2005-06-09 19:20:11 +04:00
{
DEBUG ( 0 , ( " reg_load_tree: Failed to load %s! \n " , topkeypath ) ) ;
result = WERR_REG_IO_FAILURE ;
}
2005-08-29 18:55:40 +04:00
TALLOC_FREE ( subkeys ) ;
2005-06-09 19:20:11 +04:00
if ( ! W_ERROR_IS_OK ( result ) )
return result ;
/* now continue to load each subkey registry tree */
key - > subkey_index = 0 ;
while ( ( subkey = regfio_fetch_subkey ( regfile , key ) ) ) {
pstr_sprintf ( path , " %s%s%s " , topkeypath , " \\ " , subkey - > keyname ) ;
result = reg_load_tree ( regfile , path , subkey ) ;
if ( ! W_ERROR_IS_OK ( result ) )
break ;
}
return result ;
}
/*******************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static WERROR restore_registry_key ( REGISTRY_KEY * krecord , const char * fname )
{
REGF_FILE * regfile ;
REGF_NK_REC * rootkey ;
WERROR result ;
/* open the registry file....fail if the file already exists */
if ( ! ( regfile = regfio_open ( fname , ( O_RDONLY ) , 0 ) ) ) {
2006-09-21 21:51:06 +04:00
DEBUG ( 0 , ( " restore_registry_key: failed to open \" %s \" (%s) \n " ,
2005-06-09 19:20:11 +04:00
fname , strerror ( errno ) ) ) ;
return ( ntstatus_to_werror ( map_nt_error_from_unix ( errno ) ) ) ;
}
/* get the rootkey from the regf file and then load the tree
via recursive calls */
2006-03-12 03:03:00 +03:00
if ( ! ( rootkey = regfio_rootkey ( regfile ) ) ) {
regfio_close ( regfile ) ;
2005-06-09 19:20:11 +04:00
return WERR_REG_FILE_INVALID ;
2006-03-12 03:03:00 +03:00
}
2005-06-09 19:20:11 +04:00
result = reg_load_tree ( regfile , krecord - > name , rootkey ) ;
/* cleanup */
regfio_close ( regfile ) ;
return result ;
}
2002-08-17 19:34:15 +04:00
/*******************************************************************
2005-04-05 21:49:16 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2006-09-27 20:05:25 +04:00
WERROR _winreg_RestoreKey ( pipes_struct * p , struct policy_handle * handle , struct winreg_String * filename , uint32_t flags )
2005-04-05 21:49:16 +04:00
{
2006-09-27 20:05:25 +04:00
REGISTRY_KEY * regkey = find_regkey_index_by_hnd ( p , handle ) ;
pstring fname ;
2005-05-23 20:25:31 +04:00
int snum ;
2005-04-05 21:49:16 +04:00
if ( ! regkey )
return WERR_BADFID ;
2006-09-27 20:05:25 +04:00
if ( ! filename | | ! filename - > name )
return WERR_INVALID_PARAM ;
pstrcpy ( fname , filename - > name ) ;
2005-04-07 08:58:38 +04:00
2006-09-27 20:05:25 +04:00
DEBUG ( 8 , ( " _winreg_RestoreKey: verifying restore of key [%s] from \" %s \" \n " , regkey - > name , fname ) ) ;
2005-04-05 21:49:16 +04:00
2006-09-27 20:05:25 +04:00
if ( ( snum = validate_reg_filename ( fname ) ) = = - 1 )
2005-05-23 20:25:31 +04:00
return WERR_OBJECT_PATH_INVALID ;
2005-06-09 19:20:11 +04:00
/* user must posses SeRestorePrivilege for this this proceed */
if ( ! user_has_privileges ( p - > pipe_user . nt_user_token , & se_restore ) )
return WERR_ACCESS_DENIED ;
2006-09-27 20:05:25 +04:00
DEBUG ( 2 , ( " _winreg_RestoreKey: Restoring [%s] from %s in share %s \n " , regkey - > name , fname , lp_servicename ( snum ) ) ) ;
2005-05-23 20:25:31 +04:00
2006-09-27 20:05:25 +04:00
return restore_registry_key ( regkey , fname ) ;
2006-09-21 21:51:06 +04:00
return WERR_NOT_SUPPORTED ;
2005-04-05 21:49:16 +04:00
}
2005-05-23 20:25:31 +04:00
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static WERROR reg_write_tree ( REGF_FILE * regfile , const char * keypath ,
REGF_NK_REC * parent , SEC_DESC * sec_desc )
{
REGF_NK_REC * key ;
2005-08-29 18:55:40 +04:00
REGVAL_CTR * values ;
REGSUBKEY_CTR * subkeys ;
2005-05-23 20:25:31 +04:00
int i , num_subkeys ;
pstring key_tmp ;
char * keyname , * parentpath ;
pstring subkeypath ;
char * subkeyname ;
REGISTRY_KEY registry_key ;
WERROR result = WERR_OK ;
if ( ! regfile )
return WERR_GENERAL_FAILURE ;
if ( ! keypath )
return WERR_OBJECT_PATH_INVALID ;
/* split up the registry key path */
pstrcpy ( key_tmp , keypath ) ;
if ( ! reg_split_key ( key_tmp , & parentpath , & keyname ) )
return WERR_OBJECT_PATH_INVALID ;
if ( ! keyname )
keyname = parentpath ;
/* we need a REGISTRY_KEY object here to enumerate subkeys and values */
ZERO_STRUCT ( registry_key ) ;
2006-09-27 20:05:25 +04:00
if ( ( registry_key . name = talloc_strdup ( regfile - > mem_ctx , keypath ) ) = = NULL )
return WERR_NOMEM ;
if ( ( registry_key . hook = reghook_cache_find ( registry_key . name ) ) = = NULL )
2005-05-23 20:25:31 +04:00
return WERR_BADFILE ;
/* lookup the values and subkeys */
2006-09-27 20:05:25 +04:00
if ( ! ( subkeys = TALLOC_ZERO_P ( regfile - > mem_ctx , REGSUBKEY_CTR ) ) )
2005-08-29 18:55:40 +04:00
return WERR_NOMEM ;
if ( ! ( values = TALLOC_ZERO_P ( subkeys , REGVAL_CTR ) ) )
return WERR_NOMEM ;
fetch_reg_keys ( & registry_key , subkeys ) ;
fetch_reg_values ( & registry_key , values ) ;
2005-05-23 20:25:31 +04:00
/* write out this key */
2005-08-29 18:55:40 +04:00
if ( ! ( key = regfio_write_key ( regfile , keyname , values , subkeys , sec_desc , parent ) ) ) {
2005-05-23 20:25:31 +04:00
result = WERR_CAN_NOT_COMPLETE ;
goto done ;
}
/* write each one of the subkeys out */
2005-08-29 18:55:40 +04:00
num_subkeys = regsubkey_ctr_numkeys ( subkeys ) ;
2005-05-23 20:25:31 +04:00
for ( i = 0 ; i < num_subkeys ; i + + ) {
2005-08-29 18:55:40 +04:00
subkeyname = regsubkey_ctr_specific_key ( subkeys , i ) ;
2005-05-23 20:25:31 +04:00
pstr_sprintf ( subkeypath , " %s \\ %s " , keypath , subkeyname ) ;
result = reg_write_tree ( regfile , subkeypath , key , sec_desc ) ;
if ( ! W_ERROR_IS_OK ( result ) )
goto done ;
}
DEBUG ( 6 , ( " reg_write_tree: wrote key [%s] \n " , keypath ) ) ;
done :
2005-08-29 18:55:40 +04:00
TALLOC_FREE ( subkeys ) ;
2006-09-27 20:05:25 +04:00
TALLOC_FREE ( registry_key . name ) ;
2005-05-23 20:25:31 +04:00
return result ;
}
/*******************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static WERROR make_default_reg_sd ( TALLOC_CTX * ctx , SEC_DESC * * psd )
{
DOM_SID adm_sid , owner_sid ;
SEC_ACE ace [ 2 ] ; /* at most 2 entries */
SEC_ACCESS mask ;
SEC_ACL * psa = NULL ;
2005-09-30 21:13:37 +04:00
size_t sd_size ;
2005-05-23 20:25:31 +04:00
/* set the owner to BUILTIN\Administrator */
sid_copy ( & owner_sid , & global_sid_Builtin ) ;
sid_append_rid ( & owner_sid , DOMAIN_USER_RID_ADMIN ) ;
/* basic access for Everyone */
2005-06-29 02:39:18 +04:00
init_sec_access ( & mask , reg_generic_map . generic_execute | reg_generic_map . generic_read ) ;
2005-05-23 20:25:31 +04:00
init_sec_ace ( & ace [ 0 ] , & global_sid_World , SEC_ACE_TYPE_ACCESS_ALLOWED , mask , 0 ) ;
/* add Full Access 'BUILTIN\Administrators' */
2005-06-29 02:39:18 +04:00
init_sec_access ( & mask , reg_generic_map . generic_all ) ;
2005-05-23 20:25:31 +04:00
sid_copy ( & adm_sid , & global_sid_Builtin ) ;
sid_append_rid ( & adm_sid , BUILTIN_ALIAS_RID_ADMINS ) ;
init_sec_ace ( & ace [ 1 ] , & adm_sid , SEC_ACE_TYPE_ACCESS_ALLOWED , mask , 0 ) ;
/* create the security descriptor */
if ( ( psa = make_sec_acl ( ctx , NT4_ACL_REVISION , 2 , ace ) ) = = NULL )
return WERR_NOMEM ;
if ( ( * psd = make_sec_desc ( ctx , SEC_DESC_REVISION , SEC_DESC_SELF_RELATIVE , & owner_sid , NULL , NULL , psa , & sd_size ) ) = = NULL )
return WERR_NOMEM ;
return WERR_OK ;
}
/*******************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static WERROR backup_registry_key ( REGISTRY_KEY * krecord , const char * fname )
{
REGF_FILE * regfile ;
WERROR result ;
SEC_DESC * sd = NULL ;
/* open the registry file....fail if the file already exists */
if ( ! ( regfile = regfio_open ( fname , ( O_RDWR | O_CREAT | O_EXCL ) , ( S_IREAD | S_IWRITE ) ) ) ) {
DEBUG ( 0 , ( " backup_registry_key: failed to open \" %s \" (%s) \n " ,
fname , strerror ( errno ) ) ) ;
return ( ntstatus_to_werror ( map_nt_error_from_unix ( errno ) ) ) ;
}
if ( ! W_ERROR_IS_OK ( result = make_default_reg_sd ( regfile - > mem_ctx , & sd ) ) ) {
regfio_close ( regfile ) ;
return result ;
}
/* write the registry tree to the file */
result = reg_write_tree ( regfile , krecord - > name , NULL , sd ) ;
/* cleanup */
regfio_close ( regfile ) ;
return result ;
}
2005-04-05 21:49:16 +04:00
/*******************************************************************
2002-08-17 19:34:15 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2006-09-27 20:05:25 +04:00
WERROR _winreg_SaveKey ( pipes_struct * p , struct policy_handle * handle , struct winreg_String * filename , struct KeySecurityAttribute * sec_attrib )
2002-08-17 19:34:15 +04:00
{
2006-09-27 20:05:25 +04:00
REGISTRY_KEY * regkey = find_regkey_index_by_hnd ( p , handle ) ;
pstring fname ;
2005-05-23 20:25:31 +04:00
int snum ;
2002-08-17 19:34:15 +04:00
if ( ! regkey )
2005-04-05 21:49:16 +04:00
return WERR_BADFID ;
2002-08-17 19:34:15 +04:00
2006-09-27 20:05:25 +04:00
if ( ! filename | | ! filename - > name )
return WERR_INVALID_PARAM ;
pstrcpy ( fname , filename - > name ) ;
2005-04-07 08:58:38 +04:00
2006-09-27 20:05:25 +04:00
DEBUG ( 8 , ( " _winreg_SaveKey: verifying backup of key [%s] to \" %s \" \n " , regkey - > name , fname ) ) ;
2005-05-23 20:25:31 +04:00
2006-09-27 20:05:25 +04:00
if ( ( snum = validate_reg_filename ( fname ) ) = = - 1 )
2005-05-23 20:25:31 +04:00
return WERR_OBJECT_PATH_INVALID ;
2006-09-27 20:05:25 +04:00
DEBUG ( 2 , ( " _winreg_SaveKey: Saving [%s] to %s in share %s \n " , regkey - > name , fname , lp_servicename ( snum ) ) ) ;
2005-05-23 20:25:31 +04:00
2006-09-27 20:05:25 +04:00
return backup_registry_key ( regkey , fname ) ;
2006-09-21 21:51:06 +04:00
}
/*******************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
WERROR _winreg_SaveKeyEx ( pipes_struct * p )
{
2006-09-27 20:05:25 +04:00
/* fill in your code here if you think this call should
do anything */
2006-09-21 21:51:06 +04:00
return WERR_NOT_SUPPORTED ;
2002-08-17 19:34:15 +04:00
}
2005-06-17 00:04:16 +04:00
/*******************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2006-09-21 21:51:06 +04:00
WERROR _winreg_CreateKey ( pipes_struct * p , struct policy_handle * handle , struct winreg_String keyname ,
struct winreg_String keyclass , uint32_t options , uint32_t access_mask ,
struct winreg_SecBuf * secdesc , struct policy_handle * new_handle ,
enum winreg_CreateAction * action_taken )
2005-06-17 00:04:16 +04:00
{
2006-09-21 21:51:06 +04:00
REGISTRY_KEY * parent = find_regkey_index_by_hnd ( p , handle ) ;
2005-09-30 21:13:37 +04:00
REGISTRY_KEY * newparentinfo , * keyinfo ;
2005-06-17 19:35:31 +04:00
POLICY_HND newparent_handle ;
2005-08-29 18:55:40 +04:00
REGSUBKEY_CTR * subkeys ;
2005-06-17 19:35:31 +04:00
BOOL write_result ;
2006-09-21 21:51:06 +04:00
char * name ;
2005-06-17 19:35:31 +04:00
WERROR result ;
if ( ! parent )
return WERR_BADFID ;
2006-09-21 21:51:06 +04:00
if ( ( name = talloc_strdup ( p - > mem_ctx , keyname . name ) ) = = NULL ) {
return WERR_NOMEM ;
}
2005-06-17 19:35:31 +04:00
/* ok. Here's what we do. */
if ( strrchr ( name , ' \\ ' ) ) {
pstring newkeyname ;
char * ptr ;
/* (1) check for enumerate rights on the parent handle. CLients can try
create things like ' SOFTWARE \ Samba ' on the HKLM handle .
( 2 ) open the path to the child parent key if necessary */
if ( ! ( parent - > access_granted & SEC_RIGHTS_ENUM_SUBKEYS ) )
return WERR_ACCESS_DENIED ;
pstrcpy ( newkeyname , name ) ;
ptr = strrchr ( newkeyname , ' \\ ' ) ;
* ptr = ' \0 ' ;
2005-09-30 21:13:37 +04:00
result = open_registry_key ( p , & newparent_handle , & newparentinfo ,
parent , newkeyname , ( REG_KEY_READ | REG_KEY_WRITE ) ) ;
2005-06-17 19:35:31 +04:00
if ( ! W_ERROR_IS_OK ( result ) )
return result ;
/* copy the new key name (just the lower most keyname) */
2006-09-27 07:43:42 +04:00
if ( ( name = talloc_strdup ( p - > mem_ctx , ptr + 1 ) ) = = NULL ) {
return WERR_NOMEM ;
}
2005-06-17 19:35:31 +04:00
}
else {
/* use the existing open key information */
2005-09-30 21:13:37 +04:00
newparentinfo = parent ;
2006-09-21 21:51:06 +04:00
memcpy ( & newparent_handle , handle , sizeof ( POLICY_HND ) ) ;
2005-06-17 19:35:31 +04:00
}
/* (3) check for create subkey rights on the correct parent */
2005-09-30 21:13:37 +04:00
if ( ! ( newparentinfo - > access_granted & SEC_RIGHTS_CREATE_SUBKEY ) ) {
2005-06-17 19:35:31 +04:00
result = WERR_ACCESS_DENIED ;
goto done ;
}
2005-08-29 18:55:40 +04:00
if ( ! ( subkeys = TALLOC_ZERO_P ( p - > mem_ctx , REGSUBKEY_CTR ) ) ) {
result = WERR_NOMEM ;
goto done ;
}
2005-06-17 19:35:31 +04:00
/* (4) lookup the current keys and add the new one */
2005-09-30 21:13:37 +04:00
fetch_reg_keys ( newparentinfo , subkeys ) ;
2005-08-29 18:55:40 +04:00
regsubkey_ctr_addkey ( subkeys , name ) ;
2005-06-17 19:35:31 +04:00
/* now write to the registry backend */
2005-09-30 21:13:37 +04:00
write_result = store_reg_keys ( newparentinfo , subkeys ) ;
2005-06-17 19:35:31 +04:00
2005-08-29 18:55:40 +04:00
TALLOC_FREE ( subkeys ) ;
2005-06-17 19:35:31 +04:00
if ( ! write_result )
return WERR_REG_IO_FAILURE ;
/* (5) open the new key and return the handle. Note that it is probably
2005-09-30 21:13:37 +04:00
not correct to grant full access on this open handle . */
2005-06-17 19:35:31 +04:00
2006-09-21 21:51:06 +04:00
result = open_registry_key ( p , new_handle , & keyinfo , newparentinfo , name , REG_KEY_READ ) ;
2005-09-30 21:13:37 +04:00
keyinfo - > access_granted = REG_KEY_ALL ;
2006-09-21 21:51:06 +04:00
/* FIXME: report the truth here */
2006-09-27 02:39:40 +04:00
if ( action_taken ) {
* action_taken = REG_CREATED_NEW_KEY ;
}
2005-06-17 19:35:31 +04:00
done :
/* close any intermediate key handles */
2005-09-30 21:13:37 +04:00
if ( newparentinfo ! = parent )
2005-06-17 19:35:31 +04:00
close_registry_key ( p , & newparent_handle ) ;
return result ;
2005-06-17 00:04:16 +04:00
}
/*******************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2006-09-21 21:51:06 +04:00
WERROR _winreg_SetValue ( pipes_struct * p , struct policy_handle * handle , struct winreg_String name , enum winreg_Type type , uint8_t * data , uint32_t size )
2005-06-17 00:04:16 +04:00
{
2006-09-21 21:51:06 +04:00
REGISTRY_KEY * key = find_regkey_index_by_hnd ( p , handle ) ;
2005-08-29 18:55:40 +04:00
REGVAL_CTR * values ;
2005-06-17 19:35:31 +04:00
BOOL write_result ;
2006-09-21 21:51:06 +04:00
char * valuename ;
2005-06-17 19:35:31 +04:00
if ( ! key )
return WERR_BADFID ;
/* access checks first */
if ( ! ( key - > access_granted & SEC_RIGHTS_SET_VALUE ) )
return WERR_ACCESS_DENIED ;
2005-06-29 20:35:32 +04:00
/* verify the name */
2006-09-21 21:51:06 +04:00
if ( ( valuename = talloc_strdup ( p - > mem_ctx , name . name ) ) = = NULL ) {
2005-06-29 20:35:32 +04:00
return WERR_INVALID_PARAM ;
2006-09-21 21:51:06 +04:00
}
2005-06-29 20:35:32 +04:00
DEBUG ( 8 , ( " _reg_set_value: Setting value for [%s:%s] \n " , key - > name , valuename ) ) ;
2005-06-25 21:31:40 +04:00
2005-08-29 18:55:40 +04:00
if ( ! ( values = TALLOC_ZERO_P ( p - > mem_ctx , REGVAL_CTR ) ) )
return WERR_NOMEM ;
2005-06-17 19:35:31 +04:00
/* lookup the current values and add the new one */
2005-08-29 18:55:40 +04:00
fetch_reg_values ( key , values ) ;
2005-06-25 21:31:40 +04:00
2006-09-21 21:51:06 +04:00
regval_ctr_addvalue ( values , valuename , type , ( const char * ) data , size ) ;
2005-06-17 19:35:31 +04:00
/* now write to the registry backend */
2005-08-29 18:55:40 +04:00
write_result = store_reg_values ( key , values ) ;
2005-06-17 19:35:31 +04:00
2005-08-29 18:55:40 +04:00
TALLOC_FREE ( values ) ;
2005-06-17 19:35:31 +04:00
if ( ! write_result )
return WERR_REG_IO_FAILURE ;
return WERR_OK ;
2005-06-17 00:04:16 +04:00
}
2002-07-15 14:35:28 +04:00
2005-06-17 00:59:39 +04:00
/*******************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2006-09-21 21:51:06 +04:00
WERROR _winreg_DeleteKey ( pipes_struct * p , struct policy_handle * handle , struct winreg_String key )
2005-06-17 00:59:39 +04:00
{
2006-09-21 21:51:06 +04:00
REGISTRY_KEY * parent = find_regkey_index_by_hnd ( p , handle ) ;
2006-05-13 21:21:07 +04:00
REGISTRY_KEY * newparentinfo = NULL ;
2005-06-17 22:57:37 +04:00
POLICY_HND newparent_handle ;
2005-08-29 18:55:40 +04:00
REGSUBKEY_CTR * subkeys ;
2005-06-17 19:35:31 +04:00
BOOL write_result ;
2006-09-21 21:51:06 +04:00
char * name ;
2005-06-17 22:57:37 +04:00
WERROR result ;
2005-06-17 19:35:31 +04:00
if ( ! parent )
return WERR_BADFID ;
2005-09-30 21:13:37 +04:00
/* MSDN says parent the handle must have been opened with DELETE access */
/* (1) check for delete rights on the parent */
if ( ! ( parent - > access_granted & STD_RIGHT_DELETE_ACCESS ) ) {
result = WERR_ACCESS_DENIED ;
goto done ;
}
2005-06-17 19:35:31 +04:00
2006-09-21 21:51:06 +04:00
if ( ( name = talloc_strdup ( p - > mem_ctx , key . name ) ) = = NULL ) {
result = WERR_INVALID_PARAM ;
goto done ;
}
2005-06-17 22:57:37 +04:00
/* ok. Here's what we do. */
if ( strrchr ( name , ' \\ ' ) ) {
pstring newkeyname ;
char * ptr ;
2005-09-30 21:13:37 +04:00
/* (2) open the path to the child parent key if necessary */
/* split the registry path and save the subkeyname */
2005-06-17 19:35:31 +04:00
2005-06-17 22:57:37 +04:00
pstrcpy ( newkeyname , name ) ;
ptr = strrchr ( newkeyname , ' \\ ' ) ;
* ptr = ' \0 ' ;
2006-09-27 07:43:42 +04:00
if ( ( name = talloc_strdup ( p - > mem_ctx , ptr + 1 ) ) = = NULL ) {
result = WERR_NOMEM ;
goto done ;
}
2005-06-17 22:57:37 +04:00
2005-09-30 21:13:37 +04:00
result = open_registry_key ( p , & newparent_handle , & newparentinfo , parent , newkeyname , ( REG_KEY_READ | REG_KEY_WRITE ) ) ;
2006-09-27 07:43:42 +04:00
if ( ! W_ERROR_IS_OK ( result ) ) {
goto done ;
}
2005-06-17 22:57:37 +04:00
}
else {
/* use the existing open key information */
2005-09-30 21:13:37 +04:00
newparentinfo = parent ;
2005-06-17 22:57:37 +04:00
}
2005-08-29 18:55:40 +04:00
if ( ! ( subkeys = TALLOC_ZERO_P ( p - > mem_ctx , REGSUBKEY_CTR ) ) ) {
result = WERR_NOMEM ;
goto done ;
}
2005-06-17 19:35:31 +04:00
2005-06-17 22:57:37 +04:00
/* lookup the current keys and delete the new one */
2005-06-17 19:35:31 +04:00
2005-09-30 21:13:37 +04:00
fetch_reg_keys ( newparentinfo , subkeys ) ;
2005-06-17 19:35:31 +04:00
2005-08-29 18:55:40 +04:00
regsubkey_ctr_delkey ( subkeys , name ) ;
2005-06-17 19:35:31 +04:00
/* now write to the registry backend */
2005-09-30 21:13:37 +04:00
write_result = store_reg_keys ( newparentinfo , subkeys ) ;
2005-06-17 19:35:31 +04:00
2005-08-29 18:55:40 +04:00
TALLOC_FREE ( subkeys ) ;
2005-06-25 02:34:40 +04:00
result = write_result ? WERR_OK : WERR_REG_IO_FAILURE ;
2005-06-17 19:35:31 +04:00
2005-06-17 22:57:37 +04:00
done :
/* close any intermediate key handles */
2005-09-30 21:13:37 +04:00
if ( newparentinfo ! = parent )
2005-06-17 22:57:37 +04:00
close_registry_key ( p , & newparent_handle ) ;
2005-06-25 02:34:40 +04:00
return result ;
2005-06-17 00:59:39 +04:00
}
/*******************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2006-09-21 21:51:06 +04:00
WERROR _winreg_DeleteValue ( pipes_struct * p , struct policy_handle * handle , struct winreg_String value )
2005-06-17 00:59:39 +04:00
{
2006-09-21 21:51:06 +04:00
REGISTRY_KEY * key = find_regkey_index_by_hnd ( p , handle ) ;
2005-08-29 18:55:40 +04:00
REGVAL_CTR * values ;
2005-06-17 19:35:31 +04:00
BOOL write_result ;
2006-09-21 21:51:06 +04:00
char * valuename ;
2005-06-25 21:31:40 +04:00
2005-06-17 19:35:31 +04:00
if ( ! key )
return WERR_BADFID ;
/* access checks first */
if ( ! ( key - > access_granted & SEC_RIGHTS_SET_VALUE ) )
return WERR_ACCESS_DENIED ;
2005-06-25 21:31:40 +04:00
2006-09-21 21:51:06 +04:00
if ( ( valuename = talloc_strdup ( p - > mem_ctx , value . name ) ) = = NULL ) {
2005-06-29 20:35:32 +04:00
return WERR_INVALID_PARAM ;
2006-09-21 21:51:06 +04:00
}
2005-06-29 20:35:32 +04:00
DEBUG ( 8 , ( " _reg_delete_value: Setting value for [%s:%s] \n " , key - > name , valuename ) ) ;
2005-08-29 18:55:40 +04:00
if ( ! ( values = TALLOC_ZERO_P ( p - > mem_ctx , REGVAL_CTR ) ) )
return WERR_NOMEM ;
2005-06-17 19:35:31 +04:00
/* lookup the current values and add the new one */
2005-08-29 18:55:40 +04:00
fetch_reg_values ( key , values ) ;
2005-06-25 21:31:40 +04:00
2005-08-29 18:55:40 +04:00
regval_ctr_delvalue ( values , valuename ) ;
2005-06-17 19:35:31 +04:00
/* now write to the registry backend */
2005-08-29 18:55:40 +04:00
write_result = store_reg_values ( key , values ) ;
2005-06-17 19:35:31 +04:00
2005-08-29 18:55:40 +04:00
TALLOC_FREE ( values ) ;
2005-06-17 19:35:31 +04:00
if ( ! write_result )
return WERR_REG_IO_FAILURE ;
return WERR_OK ;
2005-06-17 00:59:39 +04:00
}
2005-06-25 02:34:40 +04:00
/*******************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2006-09-21 21:51:06 +04:00
WERROR _winreg_GetKeySecurity ( pipes_struct * p , struct policy_handle * handle , uint32_t sec_info , struct KeySecurityData * sd )
2005-06-25 02:34:40 +04:00
{
2006-09-21 21:51:06 +04:00
REGISTRY_KEY * key = find_regkey_index_by_hnd ( p , handle ) ;
2005-06-25 02:34:40 +04:00
if ( ! key )
return WERR_BADFID ;
/* access checks first */
if ( ! ( key - > access_granted & STD_RIGHT_READ_CONTROL_ACCESS ) )
return WERR_ACCESS_DENIED ;
return WERR_ACCESS_DENIED ;
}
/*******************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2006-09-21 21:51:06 +04:00
WERROR _winreg_SetKeySecurity ( pipes_struct * p , struct policy_handle * handle , uint32_t access_mask , struct KeySecurityData * sd )
2005-06-25 02:34:40 +04:00
{
2006-09-21 21:51:06 +04:00
REGISTRY_KEY * key = find_regkey_index_by_hnd ( p , handle ) ;
2005-06-25 02:34:40 +04:00
if ( ! key )
return WERR_BADFID ;
/* access checks first */
if ( ! ( key - > access_granted & STD_RIGHT_WRITE_DAC_ACCESS ) )
return WERR_ACCESS_DENIED ;
return WERR_ACCESS_DENIED ;
}
2006-09-21 21:51:06 +04:00
/*******************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
WERROR _winreg_FlushKey ( pipes_struct * p , struct policy_handle * handle )
{
/* I'm just replying OK because there's not a lot
here I see to do i - - jerry */
return WERR_OK ;
}
/*******************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
WERROR _winreg_UnLoadKey ( pipes_struct * p )
{
/* fill in your code here if you think this call should
do anything */
return WERR_NOT_SUPPORTED ;
}
/*******************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
WERROR _winreg_ReplaceKey ( pipes_struct * p )
{
/* fill in your code here if you think this call should
do anything */
return WERR_NOT_SUPPORTED ;
}
/*******************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
WERROR _winreg_LoadKey ( pipes_struct * p , struct policy_handle * handle , struct winreg_String * keyname , struct winreg_String * filename )
{
/* fill in your code here if you think this call should
do anything */
return WERR_NOT_SUPPORTED ;
}
/*******************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
WERROR _winreg_NotifyChangeKeyValue ( pipes_struct * p , struct policy_handle * handle , uint8_t watch_subtree , uint32_t notify_filter , uint32_t unknown , struct winreg_String string1 , struct winreg_String string2 , uint32_t unknown2 )
{
/* fill in your code here if you think this call should
do anything */
return WERR_NOT_SUPPORTED ;
}
/*******************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
WERROR _winreg_QueryMultipleValues ( pipes_struct * p , struct policy_handle * key_handle , struct QueryMultipleValue * values , uint32_t num_values , uint8_t * buffer , uint32_t * buffer_size )
{
/* fill in your code here if you think this call should
do anything */
return WERR_NOT_SUPPORTED ;
}
/*******************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
WERROR _winreg_QueryMultipleValues2 ( pipes_struct * p )
{
/* fill in your code here if you think this call should
do anything */
return WERR_NOT_SUPPORTED ;
}