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
2007-07-09 23:25:36 +04:00
* the Free Software Foundation ; either version 3 of the License , or
2001-02-25 05:14:49 +03:00
* ( 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
2007-07-10 09:23:25 +04:00
* along with this program ; if not , see < http : //www.gnu.org/licenses/>.
2001-02-25 05:14:49 +03:00
*/
/* 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
2007-10-06 01:41:17 +04:00
static const struct generic_mapping reg_generic_map =
2005-09-30 21:13:37 +04:00
{ 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
/******************************************************************
2007-06-12 16:35:24 +04:00
free ( ) function for struct registry_key
2002-08-17 19:34:15 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-07-15 14:35:28 +04:00
2006-12-01 23:01:09 +03:00
static void free_regkey ( void * ptr )
2002-07-15 14:35:28 +04:00
{
2006-12-01 23:01:09 +03:00
struct registry_key * key = ( struct registry_key * ) ptr ;
TALLOC_FREE ( key ) ;
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
2006-12-01 23:01:09 +03:00
static struct registry_key * find_regkey_by_hnd ( pipes_struct * p ,
POLICY_HND * hnd )
2002-07-15 14:35:28 +04:00
{
2006-12-01 23:01:09 +03:00
struct 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 ,
2006-12-01 23:01:09 +03:00
struct registry_key * parent ,
2006-11-23 22:21:11 +03:00
const char * subkeyname ,
uint32 access_desired )
2002-07-15 14:35:28 +04:00
{
2006-12-01 23:01:09 +03:00
WERROR result = WERR_OK ;
struct registry_key * key ;
2003-01-19 08:04:03 +03:00
2006-12-01 23:01:09 +03:00
if ( parent = = NULL ) {
result = reg_openhive ( NULL , subkeyname , access_desired ,
p - > pipe_user . nt_user_token , & key ) ;
}
else {
result = reg_openkey ( NULL , parent , subkeyname , access_desired ,
& key ) ;
2006-11-23 22:21:11 +03:00
}
if ( ! W_ERROR_IS_OK ( result ) ) {
2005-09-30 21:13:37 +04:00
return result ;
2006-11-23 22:21:11 +03:00
}
2005-09-30 21:13:37 +04:00
2006-12-01 23:01:09 +03:00
if ( ! create_policy_hnd ( p , hnd , free_regkey , key ) ) {
2006-11-23 22:21:11 +03:00
return WERR_BADFILE ;
}
2005-06-25 02:34:40 +04:00
2007-06-12 16:01:52 +04:00
return WERR_OK ;
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
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-10-19 04:40:25 +04:00
static bool close_registry_key ( pipes_struct * p , POLICY_HND * hnd )
2002-07-15 14:35:28 +04:00
{
2006-12-01 23:01:09 +03:00
struct registry_key * regkey = find_regkey_by_hnd ( p , hnd ) ;
2002-07-15 14:35:28 +04:00
if ( ! regkey ) {
2006-12-01 23:01:09 +03:00
DEBUG ( 2 , ( " close_registry_key: Invalid handle (%s:%u:%u) \n " ,
OUR_HANDLE ( hnd ) ) ) ;
2002-07-15 14:35:28 +04:00
return False ;
}
close_policy_hnd ( p , hnd ) ;
return True ;
}
/********************************************************************
reg_close
2001-02-25 05:14:49 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-01-18 13:18:59 +03:00
WERROR _winreg_CloseKey ( pipes_struct * p , struct winreg_CloseKey * r )
2001-02-25 05:14:49 +03:00
{
/* close the policy handle */
2005-06-17 00:45:55 +04:00
2007-01-18 13:18:59 +03:00
if ( ! close_registry_key ( p , r - > in . handle ) )
2005-06-17 00:45:55 +04:00
return WERR_BADFID ;
2001-02-25 05:14:49 +03:00
2007-01-18 13:18:59 +03:00
ZERO_STRUCTP ( r - > out . handle ) ;
2006-12-03 19:18:31 +03:00
2005-01-10 23:33:41 +03:00
return WERR_OK ;
2001-02-25 05:14:49 +03:00
}
/*******************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-01-18 13:18:59 +03:00
WERROR _winreg_OpenHKLM ( pipes_struct * p , struct winreg_OpenHKLM * r )
2002-07-15 14:35:28 +04:00
{
2007-01-18 13:18:59 +03:00
return open_registry_key ( p , r - > out . handle , NULL , KEY_HKLM , r - > in . access_mask ) ;
2005-09-30 21:13:37 +04:00
}
/*******************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-01-18 13:18:59 +03:00
WERROR _winreg_OpenHKPD ( pipes_struct * p , struct winreg_OpenHKPD * r )
2005-09-30 21:13:37 +04:00
{
2007-01-18 13:18:59 +03:00
return open_registry_key ( p , r - > out . handle , NULL , KEY_HKPD , r - > in . 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
/*******************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-01-18 13:18:59 +03:00
WERROR _winreg_OpenHKPT ( pipes_struct * p , struct winreg_OpenHKPT * r )
2002-08-17 19:34:15 +04:00
{
2007-01-18 13:18:59 +03:00
return open_registry_key ( p , r - > out . handle , NULL , KEY_HKPT , r - > in . access_mask ) ;
2005-09-30 21:13:37 +04:00
}
/*******************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-01-18 13:18:59 +03:00
WERROR _winreg_OpenHKCR ( pipes_struct * p , struct winreg_OpenHKCR * r )
2005-09-30 21:13:37 +04:00
{
2007-01-18 13:18:59 +03:00
return open_registry_key ( p , r - > out . handle , NULL , KEY_HKCR , r - > in . access_mask ) ;
2002-07-15 14:35:28 +04:00
}
/*******************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-01-18 13:18:59 +03:00
WERROR _winreg_OpenHKU ( pipes_struct * p , struct winreg_OpenHKU * r )
2001-02-25 05:14:49 +03:00
{
2007-01-18 13:18:59 +03:00
return open_registry_key ( p , r - > out . handle , NULL , KEY_HKU , r - > in . access_mask ) ;
2006-09-21 21:51:06 +04:00
}
/*******************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-01-18 13:18:59 +03:00
WERROR _winreg_OpenHKCU ( pipes_struct * p , struct winreg_OpenHKCU * r )
2006-09-21 21:51:06 +04:00
{
2007-01-18 13:18:59 +03:00
return open_registry_key ( p , r - > out . handle , NULL , KEY_HKCU , r - > in . access_mask ) ;
2006-09-21 21:51:06 +04:00
}
/*******************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-01-18 13:18:59 +03:00
WERROR _winreg_OpenHKCC ( pipes_struct * p , struct winreg_OpenHKCC * r )
2006-09-21 21:51:06 +04:00
{
2007-01-18 13:18:59 +03:00
return open_registry_key ( p , r - > out . handle , NULL , KEY_HKCC , r - > in . access_mask ) ;
2006-09-21 21:51:06 +04:00
}
/*******************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-01-18 13:18:59 +03:00
WERROR _winreg_OpenHKDD ( pipes_struct * p , struct winreg_OpenHKDD * r )
2006-09-21 21:51:06 +04:00
{
2007-01-18 13:18:59 +03:00
return open_registry_key ( p , r - > out . handle , NULL , KEY_HKDD , r - > in . access_mask ) ;
2006-09-21 21:51:06 +04:00
}
/*******************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-01-18 13:18:59 +03:00
WERROR _winreg_OpenHKPN ( pipes_struct * p , struct winreg_OpenHKPN * r )
2006-09-21 21:51:06 +04:00
{
2007-01-18 13:18:59 +03:00
return open_registry_key ( p , r - > out . handle , NULL , KEY_HKPN , r - > in . access_mask ) ;
2001-02-25 05:14:49 +03:00
}
/*******************************************************************
reg_reply_open_entry
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-01-18 13:18:59 +03:00
WERROR _winreg_OpenKey ( pipes_struct * p , struct winreg_OpenKey * r )
2001-02-25 05:14:49 +03:00
{
2007-01-18 13:18:59 +03:00
struct registry_key * parent = find_regkey_by_hnd ( p , r - > in . parent_handle ) ;
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
2007-01-18 13:18:59 +03:00
return open_registry_key ( p , r - > out . handle , parent , r - > in . keyname . name , r - > in . access_mask ) ;
2001-02-25 05:14:49 +03:00
}
/*******************************************************************
reg_reply_info
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-01-18 13:18:59 +03:00
WERROR _winreg_QueryValue ( pipes_struct * p , struct winreg_QueryValue * r )
2001-02-25 05:14:49 +03:00
{
2006-11-23 19:19:06 +03:00
WERROR status = WERR_BADFILE ;
2007-01-18 13:18:59 +03:00
struct registry_key * regkey = find_regkey_by_hnd ( p , r - > in . handle ) ;
2006-11-23 19:19:06 +03:00
prs_struct prs_hkpd ;
uint8_t * outbuf ;
uint32_t outbuf_size ;
2006-12-01 23:01:09 +03:00
DATA_BLOB val_blob ;
2007-10-19 04:40:25 +04:00
bool free_buf = False ;
bool free_prs = False ;
2001-02-25 05:14:49 +03:00
2006-12-01 23:01:09 +03:00
if ( ! regkey )
2005-06-17 00:45:55 +04:00
return WERR_BADFID ;
2006-09-21 21:51:06 +04:00
2007-12-21 00:17:16 +03:00
* r - > out . value_length = * r - > out . type = REG_NONE ;
2006-09-21 22:22:51 +04:00
2006-12-01 23:01:09 +03:00
DEBUG ( 7 , ( " _reg_info: policy key name = [%s] \n " , regkey - > key - > name ) ) ;
DEBUG ( 7 , ( " _reg_info: policy key type = [%08x] \n " , regkey - > key - > type ) ) ;
2002-08-17 19:34:15 +04:00
2005-09-30 21:13:37 +04:00
/* Handle QueryValue calls on HKEY_PERFORMANCE_DATA */
2006-12-01 23:01:09 +03:00
if ( regkey - > key - > type = = REG_KEY_HKPD )
2005-09-30 21:13:37 +04:00
{
2007-01-18 13:18:59 +03:00
if ( strequal ( r - > in . value_name . name , " Global " ) ) {
prs_init ( & prs_hkpd , * r - > in . data_size , p - > mem_ctx , MARSHALL ) ;
2006-11-23 19:19:06 +03:00
status = reg_perfcount_get_hkpd (
2007-01-18 13:18:59 +03:00
& prs_hkpd , * r - > in . data_size , & outbuf_size , NULL ) ;
2006-11-23 19:19:06 +03:00
outbuf = ( uint8_t * ) prs_hkpd . data_p ;
free_prs = True ;
2005-09-30 21:13:37 +04:00
}
2007-01-18 13:18:59 +03:00
else if ( strequal ( r - > in . value_name . name , " Counter 009 " ) ) {
2006-11-23 19:19:06 +03:00
outbuf_size = reg_perfcount_get_counter_names (
reg_perfcount_get_base_index ( ) ,
2006-11-27 11:05:42 +03:00
( char * * ) ( void * ) & outbuf ) ;
2006-11-23 19:19:06 +03:00
free_buf = True ;
2005-09-30 21:13:37 +04:00
}
2007-01-18 13:18:59 +03:00
else if ( strequal ( r - > in . value_name . name , " Explain 009 " ) ) {
2006-11-23 19:19:06 +03:00
outbuf_size = reg_perfcount_get_counter_help (
reg_perfcount_get_base_index ( ) ,
2006-11-27 11:05:42 +03:00
( char * * ) ( void * ) & outbuf ) ;
2006-11-23 19:19:06 +03:00
free_buf = True ;
2005-09-30 21:13:37 +04:00
}
2007-01-18 13:18:59 +03:00
else if ( isdigit ( r - > in . value_name . name [ 0 ] ) ) {
2006-11-23 19:19:06 +03:00
/* we probably have a request for a specific object
* here */
2007-01-18 13:18:59 +03:00
prs_init ( & prs_hkpd , * r - > in . data_size , p - > mem_ctx , MARSHALL ) ;
2006-11-23 19:19:06 +03:00
status = reg_perfcount_get_hkpd (
2007-01-18 13:18:59 +03:00
& prs_hkpd , * r - > in . data_size , & outbuf_size ,
r - > in . value_name . name ) ;
2006-11-23 19:19:06 +03:00
outbuf = ( uint8_t * ) prs_hkpd . data_p ;
free_prs = True ;
2005-09-30 21:13:37 +04:00
}
2006-11-23 19:19:06 +03:00
else {
DEBUG ( 3 , ( " Unsupported key name [%s] for HKPD. \n " ,
2007-01-18 13:18:59 +03:00
r - > in . value_name . name ) ) ;
2005-09-30 21:13:37 +04:00
return WERR_BADFILE ;
}
2006-11-23 19:19:06 +03:00
2007-01-18 13:18:59 +03:00
* r - > out . type = REG_BINARY ;
2005-09-30 21:13:37 +04:00
}
2006-11-23 19:19:06 +03:00
else {
2006-12-01 23:01:09 +03:00
struct registry_value * val ;
2006-11-23 19:19:06 +03:00
2007-01-18 13:18:59 +03:00
status = reg_queryvalue ( p - > mem_ctx , regkey , r - > in . value_name . name ,
2006-12-01 23:01:09 +03:00
& val ) ;
if ( ! W_ERROR_IS_OK ( status ) ) {
2007-01-18 13:18:59 +03:00
if ( r - > out . data_size ) {
* r - > out . data_size = 0 ;
2006-11-24 01:58:50 +03:00
}
2007-01-18 13:18:59 +03:00
if ( r - > out . value_length ) {
* r - > out . value_length = 0 ;
2006-11-24 01:58:50 +03:00
}
2006-12-01 23:01:09 +03:00
return status ;
2006-09-21 21:51:06 +04:00
}
2006-09-27 02:03:52 +04:00
2006-12-01 23:01:09 +03:00
status = registry_push_value ( p - > mem_ctx , val , & val_blob ) ;
if ( ! W_ERROR_IS_OK ( status ) ) {
return status ;
}
outbuf = val_blob . data ;
outbuf_size = val_blob . length ;
2007-01-18 13:18:59 +03:00
* r - > out . type = val - > type ;
2006-11-23 19:19:06 +03:00
}
2007-01-18 13:18:59 +03:00
* r - > out . value_length = outbuf_size ;
2006-11-23 19:19:06 +03:00
2007-01-18 13:18:59 +03:00
if ( * r - > in . data_size = = 0 | | ! r - > out . data ) {
2006-11-23 19:19:06 +03:00
status = WERR_OK ;
2007-01-18 13:18:59 +03:00
} else if ( * r - > out . value_length > * r - > in . data_size ) {
2006-11-23 19:19:06 +03:00
status = WERR_MORE_DATA ;
} else {
2007-01-18 13:18:59 +03:00
memcpy ( r - > out . data , outbuf , * r - > out . value_length ) ;
2006-11-23 19:19:06 +03:00
status = WERR_OK ;
2006-09-21 21:51:06 +04:00
}
2007-01-18 13:18:59 +03:00
* r - > out . data_size = * r - > out . value_length ;
2006-11-23 19:19:06 +03:00
if ( free_prs ) prs_mem_free ( & prs_hkpd ) ;
if ( free_buf ) SAFE_FREE ( outbuf ) ;
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
2007-01-18 13:18:59 +03:00
WERROR _winreg_QueryInfoKey ( pipes_struct * p , struct winreg_QueryInfoKey * r )
2002-07-15 14:35:28 +04:00
{
2005-01-10 23:33:41 +03:00
WERROR status = WERR_OK ;
2007-01-18 13:18:59 +03:00
struct registry_key * regkey = find_regkey_by_hnd ( p , r - > in . handle ) ;
2002-07-15 14:35:28 +04:00
if ( ! regkey )
2006-12-01 23:01:09 +03:00
return WERR_BADFID ;
2007-01-18 13:18:59 +03:00
r - > out . classname - > name = NULL ;
2006-12-01 23:01:09 +03:00
2007-01-18 13:18:59 +03:00
status = reg_queryinfokey ( regkey , r - > out . num_subkeys , r - > out . max_subkeylen ,
r - > out . max_classlen , r - > out . num_values , r - > out . max_valnamelen ,
r - > out . max_valbufsize , r - > out . secdescsize ,
r - > out . last_changed_time ) ;
2006-12-01 23:01:09 +03:00
if ( ! W_ERROR_IS_OK ( status ) ) {
return status ;
2005-07-01 00:16:16 +04:00
}
2002-08-17 19:34:15 +04:00
2006-12-01 23:01:09 +03:00
/*
* These calculations account for the registry buffers being
* UTF - 16. They are inexact at best , but so far they worked .
*/
2007-01-18 13:18:59 +03:00
* r - > out . max_subkeylen * = 2 ;
2002-07-15 14:35:28 +04:00
2007-01-18 13:18:59 +03:00
* r - > out . max_valnamelen + = 1 ;
* r - > out . max_valnamelen * = 2 ;
2006-09-27 01:01:57 +04:00
2006-12-01 23:01:09 +03:00
return WERR_OK ;
2002-07-15 14:35:28 +04:00
}
/*****************************************************************************
2005-03-24 02:26:33 +03:00
Implementation of REG_GETVERSION
2002-07-15 14:35:28 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-01-18 13:18:59 +03:00
WERROR _winreg_GetVersion ( pipes_struct * p , struct winreg_GetVersion * r )
2002-07-15 14:35:28 +04:00
{
2007-01-18 13:18:59 +03:00
struct registry_key * regkey = find_regkey_by_hnd ( p , r - > in . 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
2008-01-17 13:22:01 +03:00
return reg_getversion ( r - > out . version ) ;
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
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-01-18 13:18:59 +03:00
WERROR _winreg_EnumKey ( pipes_struct * p , struct winreg_EnumKey * r )
2002-07-15 14:35:28 +04:00
{
2006-12-01 23:01:09 +03:00
WERROR err ;
2007-01-18 13:18:59 +03:00
struct registry_key * key = find_regkey_by_hnd ( p , r - > in . handle ) ;
2002-07-15 14:35:28 +04:00
2006-12-01 23:01:09 +03:00
if ( ! key )
2005-06-17 00:45:55 +04:00
return WERR_BADFID ;
2002-07-15 14:35:28 +04:00
2007-01-18 13:18:59 +03:00
if ( ! r - > in . name | | ! r - > in . keyclass )
2006-09-21 21:51:06 +04:00
return WERR_INVALID_PARAM ;
2006-12-01 23:01:09 +03:00
DEBUG ( 8 , ( " _reg_enum_key: enumerating key [%s] \n " , key - > key - > name ) ) ;
2006-11-27 10:41:59 +03:00
2007-01-18 13:18:59 +03:00
err = reg_enumkey ( p - > mem_ctx , key , r - > in . enum_index , ( char * * ) & r - > out . name - > name ,
r - > out . last_changed_time ) ;
2006-12-01 23:01:09 +03:00
if ( ! W_ERROR_IS_OK ( err ) ) {
return err ;
2006-09-21 22:54:25 +04:00
}
2007-01-18 13:18:59 +03:00
r - > out . keyclass - > name = " " ;
2006-12-01 23:01:09 +03:00
return WERR_OK ;
2002-08-17 19:34:15 +04:00
}
/*****************************************************************************
Implementation of REG_ENUM_VALUE
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2006-09-21 21:51:06 +04:00
2007-01-18 13:18:59 +03:00
WERROR _winreg_EnumValue ( pipes_struct * p , struct winreg_EnumValue * r )
2002-08-17 19:34:15 +04:00
{
2006-12-01 23:01:09 +03:00
WERROR err ;
2007-01-18 13:18:59 +03:00
struct registry_key * key = find_regkey_by_hnd ( p , r - > in . handle ) ;
2006-12-02 14:18:19 +03:00
char * valname ;
2006-12-01 23:01:09 +03:00
struct registry_value * val ;
DATA_BLOB value_blob ;
2002-08-17 19:34:15 +04:00
2006-12-01 23:01:09 +03:00
if ( ! key )
2006-11-24 01:58:50 +03:00
return WERR_BADFID ;
2002-08-17 19:34:15 +04:00
2007-01-18 13:18:59 +03:00
if ( ! r - > in . name )
2006-09-21 21:51:06 +04:00
return WERR_INVALID_PARAM ;
2006-11-24 01:58:50 +03:00
DEBUG ( 8 , ( " _winreg_EnumValue: enumerating values for key [%s] \n " ,
2006-12-01 23:01:09 +03:00
key - > key - > name ) ) ;
2002-08-17 19:34:15 +04:00
2007-01-18 13:18:59 +03:00
err = reg_enumvalue ( p - > mem_ctx , key , r - > in . enum_index , & valname , & val ) ;
2006-12-01 23:01:09 +03:00
if ( ! W_ERROR_IS_OK ( err ) ) {
return err ;
2002-08-17 19:34:15 +04:00
}
2005-10-15 01:09:56 +04:00
2006-12-01 23:01:09 +03:00
err = registry_push_value ( p - > mem_ctx , val , & value_blob ) ;
if ( ! W_ERROR_IS_OK ( err ) ) {
return err ;
2006-11-24 01:58:50 +03:00
}
2007-01-18 13:18:59 +03:00
if ( r - > out . name ! = NULL ) {
r - > out . name - > name = valname ;
2006-09-21 21:51:06 +04:00
}
2007-01-18 13:18:59 +03:00
if ( r - > out . type ! = NULL ) {
* r - > out . type = val - > type ;
2006-10-15 20:06:10 +04:00
}
2006-09-21 21:51:06 +04:00
2007-02-20 16:43:41 +03:00
if ( r - > out . value ! = NULL ) {
2007-02-16 17:50:57 +03:00
if ( ( r - > out . size = = NULL ) | | ( r - > out . length = = NULL ) ) {
2006-11-24 01:58:50 +03:00
return WERR_INVALID_PARAM ;
2006-10-15 20:06:10 +04:00
}
2007-02-16 17:50:57 +03:00
if ( value_blob . length > * r - > out . size ) {
2006-11-24 01:58:50 +03:00
return WERR_MORE_DATA ;
2006-10-15 20:06:10 +04:00
}
2007-02-20 16:43:41 +03:00
memcpy ( r - > out . value , value_blob . data , value_blob . length ) ;
2006-09-21 21:51:06 +04:00
}
2007-02-16 17:50:57 +03:00
if ( r - > out . length ! = NULL ) {
* r - > out . length = value_blob . length ;
2006-10-15 20:06:10 +04:00
}
2007-02-16 17:50:57 +03:00
if ( r - > out . size ! = NULL ) {
* r - > out . size = value_blob . length ;
2006-10-15 20:06:10 +04:00
}
2006-09-27 02:03:52 +04:00
2006-11-24 01:58:50 +03:00
return WERR_OK ;
2001-02-25 05:14:49 +03:00
}
2001-08-24 03:25:34 +04:00
/*******************************************************************
reg_shutdwon
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-01-18 13:18:59 +03:00
WERROR _winreg_InitiateSystemShutdown ( pipes_struct * p , struct winreg_InitiateSystemShutdown * r )
2001-08-24 03:25:34 +04:00
{
2007-01-18 13:18:59 +03:00
struct winreg_InitiateSystemShutdownEx s ;
s . in . hostname = r - > in . hostname ;
s . in . message = r - > in . message ;
s . in . timeout = r - > in . timeout ;
s . in . force_apps = r - > in . force_apps ;
s . in . reboot = r - > in . reboot ;
s . in . reason = 0 ;
2006-09-21 21:51:06 +04:00
/* thunk down to _winreg_InitiateSystemShutdownEx()
( just returns a status ) */
2005-03-24 02:26:33 +03:00
2007-01-18 13:18:59 +03:00
return _winreg_InitiateSystemShutdownEx ( p , & s ) ;
2005-03-24 02:26:33 +03:00
}
/*******************************************************************
reg_shutdown_ex
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# define SHUTDOWN_R_STRING "-r"
# define SHUTDOWN_F_STRING "-f"
2007-01-18 13:18:59 +03:00
WERROR _winreg_InitiateSystemShutdownEx ( pipes_struct * p , struct winreg_InitiateSystemShutdownEx * r )
2005-03-24 02:26:33 +03:00
{
2007-11-27 22:22:58 +03:00
char * shutdown_script = NULL ;
2006-09-21 21:51:06 +04:00
char * msg = NULL ;
2007-11-27 22:22:58 +03:00
char * chkmsg = NULL ;
2006-09-21 21:51:06 +04:00
fstring str_timeout ;
fstring str_reason ;
2007-01-18 13:18:59 +03:00
fstring reboot ;
2001-08-24 03:25:34 +04:00
fstring f ;
2005-03-24 02:26:33 +03:00
int ret ;
2007-10-19 04:40:25 +04:00
bool can_shutdown ;
2005-05-23 20:25:31 +04:00
2007-11-27 22:22:58 +03:00
shutdown_script = talloc_strdup ( p - > mem_ctx , lp_shutdown_script ( ) ) ;
if ( ! shutdown_script ) {
return WERR_NOMEM ;
}
if ( ! * shutdown_script ) {
2005-03-24 02:26:33 +03:00
return WERR_ACCESS_DENIED ;
2007-11-27 22:22:58 +03:00
}
2005-03-24 02:26:33 +03:00
/* pull the message string and perform necessary sanity checks on it */
2006-11-13 13:50:55 +03:00
chkmsg [ 0 ] = ' \0 ' ;
2007-01-18 13:18:59 +03:00
if ( r - > in . message & & r - > in . message - > name & & r - > in . message - > name - > name ) {
if ( ( msg = talloc_strdup ( p - > mem_ctx , r - > in . message - > name - > name ) ) = = NULL ) {
2006-09-21 21:51:06 +04:00
return WERR_NOMEM ;
}
2007-11-27 22:22:58 +03:00
chkmsg = TALLOC_ARRAY ( p - > mem_ctx , char , strlen ( msg ) + 1 ) ;
if ( ! chkmsg ) {
return WERR_NOMEM ;
}
alpha_strcpy ( chkmsg , msg , NULL , strlen ( msg ) + 1 ) ;
}
2007-01-18 13:18:59 +03:00
fstr_sprintf ( str_timeout , " %d " , r - > in . timeout ) ;
fstr_sprintf ( reboot , r - > in . reboot ? SHUTDOWN_R_STRING : " " ) ;
fstr_sprintf ( f , r - > in . force_apps ? SHUTDOWN_F_STRING : " " ) ;
fstr_sprintf ( str_reason , " %d " , r - > in . reason ) ;
2001-08-24 03:25:34 +04:00
2007-11-27 22:22:58 +03:00
shutdown_script = talloc_all_string_sub ( p - > mem_ctx ,
shutdown_script , " %z " , chkmsg ? chkmsg : " " ) ;
if ( ! shutdown_script ) {
return WERR_NOMEM ;
}
shutdown_script = talloc_all_string_sub ( p - > mem_ctx ,
shutdown_script , " %t " , str_timeout ) ;
if ( ! shutdown_script ) {
return WERR_NOMEM ;
}
shutdown_script = talloc_all_string_sub ( p - > mem_ctx ,
shutdown_script , " %r " , reboot ) ;
if ( ! shutdown_script ) {
return WERR_NOMEM ;
}
shutdown_script = talloc_all_string_sub ( p - > mem_ctx ,
shutdown_script , " %f " , f ) ;
if ( ! shutdown_script ) {
return WERR_NOMEM ;
}
shutdown_script = talloc_all_string_sub ( p - > mem_ctx ,
shutdown_script , " %x " , str_reason ) ;
if ( ! shutdown_script ) {
return WERR_NOMEM ;
}
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 ) ;
2007-11-27 22:22:58 +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 . */
2007-11-27 22:22:58 +03:00
2005-04-05 21:49:16 +04:00
/********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/
2007-11-27 22:22:58 +03:00
if ( can_shutdown )
2005-04-05 21:49:16 +04:00
become_root ( ) ;
2005-03-24 02:26:33 +03:00
ret = smbrun ( shutdown_script , NULL ) ;
2007-11-27 22:22:58 +03:00
2005-04-05 21:49:16 +04:00
if ( can_shutdown )
unbecome_root ( ) ;
/********** END SeRemoteShutdownPrivilege BLOCK **********/
2007-11-27 22:22:58 +03: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
2002-07-15 14:35:28 +04:00
/*******************************************************************
reg_abort_shutdwon
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-01-18 13:18:59 +03:00
WERROR _winreg_AbortSystemShutdown ( pipes_struct * p , struct winreg_AbortSystemShutdown * r )
2001-08-24 11:51:59 +04:00
{
2007-11-27 22:22:58 +03:00
const char * abort_shutdown_script ;
2005-03-24 02:26:33 +03:00
int ret ;
2007-10-19 04:40:25 +04:00
bool can_shutdown ;
2001-08-24 11:51:59 +04:00
2007-11-27 22:22:58 +03:00
abort_shutdown_script = lp_abort_shutdown_script ( ) ;
2001-08-24 11:51:59 +04:00
2007-11-27 22:22:58 +03:00
if ( ! * abort_shutdown_script )
2005-03-24 02:26:33 +03:00
return WERR_ACCESS_DENIED ;
2007-11-27 22:22:58 +03:00
2005-03-24 02:26:33 +03:00
can_shutdown = user_has_privileges ( p - > pipe_user . nt_user_token , & se_remote_shutdown ) ;
2007-11-27 22:22:58 +03:00
2005-04-05 21:49:16 +04:00
/********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/
2007-11-27 22:22:58 +03:00
2005-04-05 21:49:16 +04:00
if ( can_shutdown )
become_root ( ) ;
2007-11-16 01:19:52 +03:00
2005-03-24 02:26:33 +03:00
ret = smbrun ( abort_shutdown_script , NULL ) ;
2007-11-16 01:19:52 +03:00
2005-04-05 21:49:16 +04:00
if ( can_shutdown )
unbecome_root ( ) ;
2007-11-16 01:19:52 +03:00
2005-04-05 21:49:16 +04:00
/********** 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
/*******************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-11-27 22:22:58 +03:00
static int validate_reg_filename ( TALLOC_CTX * ctx , char * * pp_fname )
2005-05-23 20:25:31 +04:00
{
2007-11-27 22:22:58 +03:00
char * p = NULL ;
2005-05-23 20:25:31 +04:00
int num_services = lp_numservices ( ) ;
2007-11-27 22:22:58 +03:00
int snum = - 1 ;
const char * share_path ;
char * fname = * pp_fname ;
2007-11-16 01:19:52 +03:00
2005-05-23 20:25:31 +04:00
/* convert to a unix path, stripping the C:\ along the way */
2007-11-16 01:19:52 +03:00
2007-11-27 22:22:58 +03:00
if ( ! ( p = valid_share_pathname ( ctx , fname ) ) ) {
2005-05-23 20:25:31 +04:00
return - 1 ;
2007-11-27 22:22:58 +03:00
}
2005-05-23 20:25:31 +04:00
/* has to exist within a valid file share */
2007-11-16 01:19:52 +03:00
2007-11-27 22:22:58 +03:00
for ( snum = 0 ; snum < num_services ; snum + + ) {
if ( ! lp_snum_ok ( snum ) | | lp_print_ok ( snum ) ) {
2005-05-23 20:25:31 +04:00
continue ;
2007-11-27 22:22:58 +03:00
}
2007-11-16 01:19:52 +03:00
2007-11-27 22:22:58 +03:00
share_path = lp_pathname ( snum ) ;
2005-05-23 20:25:31 +04:00
/* make sure we have a path (e.g. [homes] ) */
2007-11-27 22:22:58 +03:00
if ( strlen ( share_path ) = = 0 ) {
2005-05-23 20:25:31 +04:00
continue ;
2007-11-27 22:22:58 +03:00
}
2005-05-23 20:25:31 +04:00
2007-11-27 22:22:58 +03:00
if ( strncmp ( share_path , p , strlen ( share_path ) ) = = 0 ) {
2005-05-23 20:25:31 +04:00
break ;
2007-11-27 22:22:58 +03:00
}
2005-05-23 20:25:31 +04:00
}
2007-11-16 01:19:52 +03:00
2007-11-27 22:22:58 +03:00
* pp_fname = p ;
2005-05-23 20:25:31 +04:00
return ( snum < num_services ) ? snum : - 1 ;
}
2005-06-09 19:20:11 +04:00
/*******************************************************************
2007-11-27 22:22:58 +03: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 ;
2007-11-27 22:22:58 +03:00
char * path = NULL ;
2005-06-09 19:20:11 +04:00
WERROR result = WERR_OK ;
2007-11-27 22:22:58 +03:00
2005-06-09 19:20:11 +04:00
/* initialize the REGISTRY_KEY structure */
2007-11-27 22:22:58 +03:00
2005-06-09 19:20:11 +04:00
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 ;
}
2007-06-27 20:52:36 +04:00
registry_key . name = talloc_strdup ( regfile - > mem_ctx , topkeypath ) ;
if ( ! registry_key . name ) {
DEBUG ( 0 , ( " reg_load_tree: Talloc failed for reg_key.name! \n " ) ) ;
return WERR_NOMEM ;
}
2007-11-27 22:22:58 +03:00
2005-06-09 19:20:11 +04:00
/* 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 ;
2007-11-27 22:22:58 +03: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 */
2007-11-27 22:22:58 +03:00
2005-06-09 19:20:11 +04:00
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 */
2007-11-27 22:22:58 +03:00
2005-06-09 19:20:11 +04:00
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
}
2007-11-27 22:22:58 +03:00
2005-06-09 19:20:11 +04:00
/* write this key and values out */
2007-11-27 22:22:58 +03:00
if ( ! store_reg_values ( & registry_key , values )
2005-08-29 18:55:40 +04:00
| | ! 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 ;
}
2007-11-27 22:22:58 +03:00
2005-08-29 18:55:40 +04:00
TALLOC_FREE ( subkeys ) ;
2007-11-27 22:22:58 +03:00
2005-06-09 19:20:11 +04:00
if ( ! W_ERROR_IS_OK ( result ) )
return result ;
2007-11-27 22:22:58 +03:00
2005-06-09 19:20:11 +04:00
/* now continue to load each subkey registry tree */
key - > subkey_index = 0 ;
while ( ( subkey = regfio_fetch_subkey ( regfile , key ) ) ) {
2007-11-27 22:22:58 +03:00
path = talloc_asprintf ( regfile - > mem_ctx ,
" %s \\ %s " ,
topkeypath ,
subkey - > keyname ) ;
if ( ! path ) {
return WERR_NOMEM ;
}
2005-06-09 19:20:11 +04:00
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
}
2007-11-27 22:22:58 +03:00
2005-06-09 19:20:11 +04:00
result = reg_load_tree ( regfile , krecord - > name , rootkey ) ;
2007-11-27 22:22:58 +03:00
2005-06-09 19:20:11 +04:00
/* cleanup */
2007-11-27 22:22:58 +03:00
2005-06-09 19:20:11 +04:00
regfio_close ( regfile ) ;
2007-11-27 22:22:58 +03:00
2005-06-09 19:20:11 +04:00
return result ;
}
2002-08-17 19:34:15 +04:00
/*******************************************************************
2005-04-05 21:49:16 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-01-18 13:18:59 +03:00
WERROR _winreg_RestoreKey ( pipes_struct * p , struct winreg_RestoreKey * r )
2005-04-05 21:49:16 +04:00
{
2007-01-18 13:18:59 +03:00
struct registry_key * regkey = find_regkey_by_hnd ( p , r - > in . handle ) ;
2007-11-27 22:22:58 +03:00
char * fname = NULL ;
2005-05-23 20:25:31 +04:00
int snum ;
2007-11-27 22:22:58 +03:00
2005-04-05 21:49:16 +04:00
if ( ! regkey )
2007-11-27 22:22:58 +03:00
return WERR_BADFID ;
2005-04-05 21:49:16 +04:00
2007-01-18 13:18:59 +03:00
if ( ! r - > in . filename | | ! r - > in . filename - > name )
2006-09-27 20:05:25 +04:00
return WERR_INVALID_PARAM ;
2007-11-28 10:00:11 +03:00
fname = talloc_strdup ( p - > mem_ctx , r - > in . filename - > name ) ;
2007-11-27 22:22:58 +03:00
if ( ! fname ) {
return WERR_NOMEM ;
}
2005-04-07 08:58:38 +04:00
2006-12-01 23:01:09 +03:00
DEBUG ( 8 , ( " _winreg_RestoreKey: verifying restore of key [%s] from "
" \" %s \" \n " , regkey - > key - > name , fname ) ) ;
2005-04-05 21:49:16 +04:00
2007-11-27 22:22:58 +03:00
if ( ( snum = validate_reg_filename ( p - > mem_ctx , & fname ) ) = = - 1 )
2005-05-23 20:25:31 +04:00
return WERR_OBJECT_PATH_INVALID ;
2007-11-27 22:22:58 +03:00
2005-06-09 19:20:11 +04:00
/* user must posses SeRestorePrivilege for this this proceed */
2007-11-27 22:22:58 +03:00
2005-06-09 19:20:11 +04:00
if ( ! user_has_privileges ( p - > pipe_user . nt_user_token , & se_restore ) )
return WERR_ACCESS_DENIED ;
2007-11-27 22:22:58 +03:00
2006-12-01 23:01:09 +03:00
DEBUG ( 2 , ( " _winreg_RestoreKey: Restoring [%s] from %s in share %s \n " ,
regkey - > key - > name , fname , lp_servicename ( snum ) ) ) ;
2005-05-23 20:25:31 +04:00
2006-12-01 23:01:09 +03:00
return restore_registry_key ( regkey - > key , fname ) ;
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 ;
2007-11-27 22:22:58 +03:00
char * key_tmp = NULL ;
2005-05-23 20:25:31 +04:00
char * keyname , * parentpath ;
2007-11-27 22:22:58 +03:00
char * subkeypath = NULL ;
2005-05-23 20:25:31 +04:00
char * subkeyname ;
REGISTRY_KEY registry_key ;
WERROR result = WERR_OK ;
2007-11-27 22:22:58 +03:00
if ( ! regfile )
2005-05-23 20:25:31 +04:00
return WERR_GENERAL_FAILURE ;
2007-11-27 22:22:58 +03:00
if ( ! keypath )
2005-05-23 20:25:31 +04:00
return WERR_OBJECT_PATH_INVALID ;
2007-11-27 22:22:58 +03:00
2005-05-23 20:25:31 +04:00
/* split up the registry key path */
2007-11-27 22:22:58 +03:00
key_tmp = talloc_strdup ( regfile - > mem_ctx , keypath ) ;
if ( ! key_tmp ) {
return WERR_NOMEM ;
}
if ( ! reg_split_key ( key_tmp , & parentpath , & keyname ) )
2005-05-23 20:25:31 +04:00
return WERR_OBJECT_PATH_INVALID ;
if ( ! keyname )
keyname = parentpath ;
/* we need a REGISTRY_KEY object here to enumerate subkeys and values */
2007-11-27 22:22:58 +03:00
2005-05-23 20:25:31 +04:00
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 */
2007-11-27 22:22:58 +03: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 */
2007-11-27 22:22:58 +03:00
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 ) ;
2007-11-27 22:22:58 +03:00
subkeypath = talloc_asprintf ( regfile - > mem_ctx ,
" %s \\ %s " , keypath , subkeyname ) ;
if ( ! subkeypath ) {
result = WERR_NOMEM ;
goto done ;
}
2005-05-23 20:25:31 +04:00
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 ;
2007-12-21 00:27:01 +03:00
if ( ( * psd = make_sec_desc ( ctx , SECURITY_DESCRIPTOR_REVISION_1 ,
SEC_DESC_SELF_RELATIVE , & owner_sid , NULL ,
NULL , psa , & sd_size ) ) = = NULL )
2005-05-23 20:25:31 +04:00
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 */
2007-11-27 22:22:58 +03:00
2005-05-23 20:25:31 +04:00
if ( ! ( regfile = regfio_open ( fname , ( O_RDWR | O_CREAT | O_EXCL ) , ( S_IREAD | S_IWRITE ) ) ) ) {
2007-11-27 22:22:58 +03:00
DEBUG ( 0 , ( " backup_registry_key: failed to open \" %s \" (%s) \n " ,
2005-05-23 20:25:31 +04:00
fname , strerror ( errno ) ) ) ;
return ( ntstatus_to_werror ( map_nt_error_from_unix ( errno ) ) ) ;
}
2007-11-27 22:22:58 +03:00
2005-05-23 20:25:31 +04:00
if ( ! W_ERROR_IS_OK ( result = make_default_reg_sd ( regfile - > mem_ctx , & sd ) ) ) {
regfio_close ( regfile ) ;
return result ;
}
2007-11-27 22:22:58 +03:00
2005-05-23 20:25:31 +04:00
/* write the registry tree to the file */
2007-11-27 22:22:58 +03:00
2005-05-23 20:25:31 +04:00
result = reg_write_tree ( regfile , krecord - > name , NULL , sd ) ;
2007-11-27 22:22:58 +03:00
2005-05-23 20:25:31 +04:00
/* cleanup */
2007-11-27 22:22:58 +03:00
2005-05-23 20:25:31 +04:00
regfio_close ( regfile ) ;
2007-11-27 22:22:58 +03:00
2005-05-23 20:25:31 +04:00
return result ;
}
2005-04-05 21:49:16 +04:00
/*******************************************************************
2002-08-17 19:34:15 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-01-18 13:18:59 +03:00
WERROR _winreg_SaveKey ( pipes_struct * p , struct winreg_SaveKey * r )
2002-08-17 19:34:15 +04:00
{
2007-01-18 13:18:59 +03:00
struct registry_key * regkey = find_regkey_by_hnd ( p , r - > in . handle ) ;
2007-11-27 22:22:58 +03:00
char * fname = NULL ;
int snum = - 1 ;
2002-08-17 19:34:15 +04:00
if ( ! regkey )
2007-11-27 22:22:58 +03:00
return WERR_BADFID ;
2002-08-17 19:34:15 +04:00
2007-01-18 13:18:59 +03:00
if ( ! r - > in . filename | | ! r - > in . filename - > name )
2006-09-27 20:05:25 +04:00
return WERR_INVALID_PARAM ;
2007-11-27 22:22:58 +03:00
fname = talloc_strdup ( p - > mem_ctx , r - > in . filename - > name ) ;
if ( ! fname ) {
return WERR_NOMEM ;
}
2005-04-07 08:58:38 +04:00
2006-12-01 23:01:09 +03:00
DEBUG ( 8 , ( " _winreg_SaveKey: verifying backup of key [%s] to \" %s \" \n " ,
regkey - > key - > name , fname ) ) ;
2007-11-27 22:22:58 +03:00
if ( ( snum = validate_reg_filename ( p - > mem_ctx , & fname ) ) = = - 1 )
2005-05-23 20:25:31 +04:00
return WERR_OBJECT_PATH_INVALID ;
2007-11-27 22:22:58 +03:00
2006-12-01 23:01:09 +03:00
DEBUG ( 2 , ( " _winreg_SaveKey: Saving [%s] to %s in share %s \n " ,
regkey - > key - > name , fname , lp_servicename ( snum ) ) ) ;
2007-11-27 22:22:58 +03:00
2006-12-01 23:01:09 +03:00
return backup_registry_key ( regkey - > key , fname ) ;
2006-09-21 21:51:06 +04:00
}
/*******************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-01-18 13:18:59 +03:00
WERROR _winreg_SaveKeyEx ( pipes_struct * p , struct winreg_SaveKeyEx * r )
2006-09-21 21:51:06 +04:00
{
2006-09-27 20:05:25 +04:00
/* fill in your code here if you think this call should
do anything */
2006-10-10 12:39:11 +04:00
p - > rng_fault_state = True ;
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
/*******************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-01-18 13:18:59 +03:00
WERROR _winreg_CreateKey ( pipes_struct * p , struct winreg_CreateKey * r )
2005-06-17 00:04:16 +04:00
{
2007-01-18 13:18:59 +03:00
struct registry_key * parent = find_regkey_by_hnd ( p , r - > in . handle ) ;
2006-12-01 23:01:09 +03:00
struct registry_key * new_key ;
2005-06-17 19:35:31 +04:00
WERROR result ;
if ( ! parent )
return WERR_BADFID ;
2006-09-21 21:51:06 +04:00
2007-01-18 13:18:59 +03:00
result = reg_createkey ( NULL , parent , r - > in . name . name , r - > in . access_mask ,
& new_key , r - > out . action_taken ) ;
2006-12-01 23:01:09 +03:00
if ( ! W_ERROR_IS_OK ( result ) ) {
return result ;
2005-08-29 18:55:40 +04:00
}
2007-01-18 13:18:59 +03:00
if ( ! create_policy_hnd ( p , r - > out . new_handle , free_regkey , new_key ) ) {
2006-12-01 23:01:09 +03:00
TALLOC_FREE ( new_key ) ;
return WERR_BADFILE ;
2006-09-27 02:39:40 +04:00
}
2005-06-17 19:35:31 +04:00
2006-12-01 23:01:09 +03:00
return WERR_OK ;
2005-06-17 00:04:16 +04:00
}
/*******************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-01-18 13:18:59 +03:00
WERROR _winreg_SetValue ( pipes_struct * p , struct winreg_SetValue * r )
2005-06-17 00:04:16 +04:00
{
2007-01-18 13:18:59 +03:00
struct registry_key * key = find_regkey_by_hnd ( p , r - > in . handle ) ;
2006-12-01 23:01:09 +03:00
struct registry_value * val ;
WERROR status ;
2005-06-17 19:35:31 +04:00
2006-12-01 23:01:09 +03:00
if ( ! key )
2005-06-17 19:35:31 +04:00
return WERR_BADFID ;
2006-11-24 01:58:50 +03:00
2007-01-18 13:18:59 +03:00
DEBUG ( 8 , ( " _reg_set_value: Setting value for [%s:%s] \n " ,
key - > key - > name , r - > in . name . name ) ) ;
2006-11-24 01:58:50 +03:00
2007-01-18 13:18:59 +03:00
status = registry_pull_value ( p - > mem_ctx , & val , r - > in . type , r - > in . data ,
r - > in . size , r - > in . size ) ;
2006-12-01 23:01:09 +03:00
if ( ! W_ERROR_IS_OK ( status ) ) {
return status ;
}
2006-11-24 01:58:50 +03:00
2007-01-18 13:18:59 +03:00
return reg_setvalue ( key , r - > in . name . name , val ) ;
2005-06-17 00:04:16 +04:00
}
2002-07-15 14:35:28 +04:00
2005-06-17 00:59:39 +04:00
/*******************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-01-18 13:18:59 +03:00
WERROR _winreg_DeleteKey ( pipes_struct * p , struct winreg_DeleteKey * r )
2005-06-17 00:59:39 +04:00
{
2007-01-18 13:18:59 +03:00
struct registry_key * parent = find_regkey_by_hnd ( p , r - > in . handle ) ;
2005-06-17 19:35:31 +04:00
if ( ! parent )
return WERR_BADFID ;
2005-09-30 21:13:37 +04:00
2007-01-18 13:18:59 +03:00
return reg_deletekey ( parent , r - > in . key . name ) ;
2005-06-17 00:59:39 +04:00
}
/*******************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-01-18 13:18:59 +03:00
WERROR _winreg_DeleteValue ( pipes_struct * p , struct winreg_DeleteValue * r )
2005-06-17 00:59:39 +04:00
{
2007-01-18 13:18:59 +03:00
struct registry_key * key = find_regkey_by_hnd ( p , r - > in . handle ) ;
2005-06-25 21:31:40 +04:00
2006-12-01 23:01:09 +03:00
if ( ! key )
2005-06-17 19:35:31 +04:00
return WERR_BADFID ;
2006-11-24 01:58:50 +03:00
2007-01-18 13:18:59 +03:00
return reg_deletevalue ( key , r - > in . value . name ) ;
2005-06-17 00:59:39 +04:00
}
2005-06-25 02:34:40 +04:00
/*******************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-01-18 13:18:59 +03:00
WERROR _winreg_GetKeySecurity ( pipes_struct * p , struct winreg_GetKeySecurity * r )
2005-06-25 02:34:40 +04:00
{
2007-01-18 13:18:59 +03:00
struct registry_key * key = find_regkey_by_hnd ( p , r - > in . handle ) ;
2006-11-30 10:38:40 +03:00
WERROR err ;
struct security_descriptor * secdesc ;
uint8 * data ;
size_t len ;
2005-06-25 02:34:40 +04:00
if ( ! key )
return WERR_BADFID ;
/* access checks first */
2006-12-01 23:01:09 +03:00
if ( ! ( key - > key - > access_granted & STD_RIGHT_READ_CONTROL_ACCESS ) )
2005-06-25 02:34:40 +04:00
return WERR_ACCESS_DENIED ;
2006-11-30 10:38:40 +03:00
2008-01-17 13:06:32 +03:00
err = reg_getkeysecurity ( p - > mem_ctx , key , & secdesc ) ;
2006-11-30 10:38:40 +03:00
if ( ! W_ERROR_IS_OK ( err ) ) {
return err ;
}
err = ntstatus_to_werror ( marshall_sec_desc ( p - > mem_ctx , secdesc ,
& data , & len ) ) ;
if ( ! W_ERROR_IS_OK ( err ) ) {
return err ;
}
2007-01-18 13:18:59 +03:00
if ( len > r - > out . sd - > size ) {
r - > out . sd - > size = len ;
2006-11-30 10:38:40 +03:00
return WERR_INSUFFICIENT_BUFFER ;
}
2007-01-18 13:18:59 +03:00
r - > out . sd - > size = len ;
r - > out . sd - > len = len ;
r - > out . sd - > data = data ;
2005-06-25 02:34:40 +04:00
2006-11-30 10:38:40 +03:00
return WERR_OK ;
2005-06-25 02:34:40 +04:00
}
/*******************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-01-18 13:18:59 +03:00
WERROR _winreg_SetKeySecurity ( pipes_struct * p , struct winreg_SetKeySecurity * r )
2005-06-25 02:34:40 +04:00
{
2007-01-18 13:18:59 +03:00
struct registry_key * key = find_regkey_by_hnd ( p , r - > in . handle ) ;
2006-11-30 10:38:40 +03:00
struct security_descriptor * secdesc ;
WERROR err ;
2005-06-25 02:34:40 +04:00
if ( ! key )
return WERR_BADFID ;
/* access checks first */
2006-12-01 23:01:09 +03:00
if ( ! ( key - > key - > access_granted & STD_RIGHT_WRITE_DAC_ACCESS ) )
2005-06-25 02:34:40 +04:00
return WERR_ACCESS_DENIED ;
2006-11-30 10:38:40 +03:00
2007-01-18 13:18:59 +03:00
err = ntstatus_to_werror ( unmarshall_sec_desc ( p - > mem_ctx , r - > in . sd - > data ,
r - > in . sd - > len , & secdesc ) ) ;
2006-11-30 10:38:40 +03:00
if ( ! W_ERROR_IS_OK ( err ) ) {
return err ;
}
2008-01-17 13:06:32 +03:00
return reg_setkeysecurity ( key , secdesc ) ;
2005-06-25 02:34:40 +04:00
}
2006-09-21 21:51:06 +04:00
/*******************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-01-18 13:18:59 +03:00
WERROR _winreg_FlushKey ( pipes_struct * p , struct winreg_FlushKey * r )
2006-09-21 21:51:06 +04:00
{
/* I'm just replying OK because there's not a lot
here I see to do i - - jerry */
return WERR_OK ;
}
/*******************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-01-18 13:18:59 +03:00
WERROR _winreg_UnLoadKey ( pipes_struct * p , struct winreg_UnLoadKey * r )
2006-09-21 21:51:06 +04:00
{
/* fill in your code here if you think this call should
do anything */
2006-10-10 12:39:11 +04:00
p - > rng_fault_state = True ;
2006-09-21 21:51:06 +04:00
return WERR_NOT_SUPPORTED ;
}
/*******************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-01-18 13:18:59 +03:00
WERROR _winreg_ReplaceKey ( pipes_struct * p , struct winreg_ReplaceKey * r )
2006-09-21 21:51:06 +04:00
{
/* fill in your code here if you think this call should
do anything */
2006-10-10 12:39:11 +04:00
p - > rng_fault_state = True ;
2006-09-21 21:51:06 +04:00
return WERR_NOT_SUPPORTED ;
}
/*******************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-01-18 13:18:59 +03:00
WERROR _winreg_LoadKey ( pipes_struct * p , struct winreg_LoadKey * r )
2006-09-21 21:51:06 +04:00
{
/* fill in your code here if you think this call should
do anything */
2006-10-10 12:39:11 +04:00
p - > rng_fault_state = True ;
2006-09-21 21:51:06 +04:00
return WERR_NOT_SUPPORTED ;
}
/*******************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-01-18 13:18:59 +03:00
WERROR _winreg_NotifyChangeKeyValue ( pipes_struct * p , struct winreg_NotifyChangeKeyValue * r )
2006-09-21 21:51:06 +04:00
{
/* fill in your code here if you think this call should
do anything */
2006-10-10 12:39:11 +04:00
p - > rng_fault_state = True ;
2006-09-21 21:51:06 +04:00
return WERR_NOT_SUPPORTED ;
}
/*******************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-01-18 13:18:59 +03:00
WERROR _winreg_QueryMultipleValues ( pipes_struct * p , struct winreg_QueryMultipleValues * r )
2006-09-21 21:51:06 +04:00
{
/* fill in your code here if you think this call should
do anything */
2006-10-10 12:39:11 +04:00
p - > rng_fault_state = True ;
2006-09-21 21:51:06 +04:00
return WERR_NOT_SUPPORTED ;
}
/*******************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-01-18 13:18:59 +03:00
WERROR _winreg_QueryMultipleValues2 ( pipes_struct * p , struct winreg_QueryMultipleValues2 * r )
2006-09-21 21:51:06 +04:00
{
/* fill in your code here if you think this call should
do anything */
2006-10-10 12:39:11 +04:00
p - > rng_fault_state = True ;
2006-09-21 21:51:06 +04:00
return WERR_NOT_SUPPORTED ;
}