2005-05-23 20:25:31 +04:00
/*
Samba Unix / Linux SMB client library
Distributed SMB / CIFS Server Management Utility
2006-09-28 01:37:43 +04:00
Copyright ( C ) Gerald ( Jerry ) Carter 2005 - 2006
2005-05-23 20:25:31 +04: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
2005-05-23 20:25:31 +04: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 04:52:41 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>. */
2005-05-23 20:25:31 +04:00
# include "includes.h"
2011-02-26 01:20:06 +03:00
# include "system/filesys.h"
2011-04-13 16:32:16 +04:00
# include "rpc_client/rpc_client.h"
2009-10-02 02:17:06 +04:00
# include "registry.h"
2005-05-23 20:25:31 +04:00
# include "utils/net.h"
2008-04-04 15:26:03 +04:00
# include "utils/net_registry_util.h"
2010-09-21 11:08:33 +04:00
# include "registry/regfio.h"
2011-01-13 00:53:52 +03:00
# include "../librpc/gen_ndr/ndr_winreg_c.h"
2010-05-28 04:19:32 +04:00
# include "../librpc/gen_ndr/ndr_security.h"
2010-09-20 18:45:57 +04:00
# include "registry/reg_format.h"
2010-09-20 17:32:02 +04:00
# include "registry/reg_import.h"
2010-09-20 18:45:57 +04:00
# include <assert.h>
2011-02-24 12:47:16 +03:00
# include "../libcli/security/display_sec.h"
2011-02-26 02:28:15 +03:00
# include "../libcli/registry/util_reg.h"
2011-05-06 14:53:38 +04:00
# include "client.h"
2020-07-03 09:11:20 +03:00
# include "lib/util/smb_strtox.h"
2010-09-20 18:45:57 +04:00
2005-05-23 20:25:31 +04:00
2009-10-01 03:30:45 +04:00
/*******************************************************************
connect to a registry hive root ( open a registry policy )
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2011-01-13 00:53:52 +03:00
static NTSTATUS dcerpc_winreg_Connect ( struct dcerpc_binding_handle * b , TALLOC_CTX * mem_ctx ,
2009-10-01 03:30:45 +04:00
uint32_t reg_type , uint32_t access_mask ,
2010-09-20 17:24:03 +04:00
struct policy_handle * reg_hnd , WERROR * werr )
2009-10-01 03:30:45 +04:00
{
ZERO_STRUCTP ( reg_hnd ) ;
switch ( reg_type )
{
case HKEY_CLASSES_ROOT :
2011-01-13 00:53:52 +03:00
return dcerpc_winreg_OpenHKCR ( b , mem_ctx , NULL ,
2010-09-20 17:24:03 +04:00
access_mask , reg_hnd , werr ) ;
2009-10-01 03:30:45 +04:00
case HKEY_LOCAL_MACHINE :
2011-01-13 00:53:52 +03:00
return dcerpc_winreg_OpenHKLM ( b , mem_ctx , NULL ,
2010-09-20 17:24:03 +04:00
access_mask , reg_hnd , werr ) ;
2009-10-01 03:30:45 +04:00
case HKEY_USERS :
2011-01-13 00:53:52 +03:00
return dcerpc_winreg_OpenHKU ( b , mem_ctx , NULL ,
2010-09-20 17:24:03 +04:00
access_mask , reg_hnd , werr ) ;
2009-10-01 03:30:45 +04:00
case HKEY_CURRENT_USER :
2011-01-13 00:53:52 +03:00
return dcerpc_winreg_OpenHKCU ( b , mem_ctx , NULL ,
2010-09-20 17:24:03 +04:00
access_mask , reg_hnd , werr ) ;
2009-10-01 03:30:45 +04:00
case HKEY_PERFORMANCE_DATA :
2011-01-13 00:53:52 +03:00
return dcerpc_winreg_OpenHKPD ( b , mem_ctx , NULL ,
2010-09-20 17:24:03 +04:00
access_mask , reg_hnd , werr ) ;
2009-10-01 03:30:45 +04:00
default :
/* fall through to end of function */
break ;
}
return NT_STATUS_INVALID_PARAMETER ;
}
2008-04-04 18:46:01 +04:00
static bool reg_hive_key ( TALLOC_CTX * ctx , const char * fullname ,
2015-05-07 03:00:06 +03:00
uint32_t * reg_type , const char * * key_name )
2006-11-21 13:32:08 +03:00
{
2008-04-04 18:46:01 +04:00
WERROR werr ;
char * hivename = NULL ;
2008-04-04 19:24:53 +04:00
char * tmp_keyname = NULL ;
2008-04-04 18:46:01 +04:00
bool ret = false ;
TALLOC_CTX * tmp_ctx = talloc_stackframe ( ) ;
2006-11-21 13:32:08 +03:00
2008-04-04 18:46:01 +04:00
werr = split_hive_key ( tmp_ctx , fullname , & hivename , & tmp_keyname ) ;
if ( ! W_ERROR_IS_OK ( werr ) ) {
goto done ;
2006-11-21 13:32:08 +03:00
}
2008-04-04 18:46:01 +04:00
* key_name = talloc_strdup ( ctx , tmp_keyname ) ;
if ( * key_name = = NULL ) {
goto done ;
2006-11-21 13:32:08 +03:00
}
2008-04-04 18:46:01 +04:00
if ( strequal ( hivename , " HKLM " ) | |
strequal ( hivename , " HKEY_LOCAL_MACHINE " ) )
{
2006-11-21 13:32:08 +03:00
( * reg_type ) = HKEY_LOCAL_MACHINE ;
2008-04-04 18:46:01 +04:00
} else if ( strequal ( hivename , " HKCR " ) | |
2008-05-08 13:23:38 +04:00
strequal ( hivename , " HKEY_CLASSES_ROOT " ) )
2008-04-04 18:46:01 +04:00
{
2006-11-21 13:32:08 +03:00
( * reg_type ) = HKEY_CLASSES_ROOT ;
2008-04-04 18:46:01 +04:00
} else if ( strequal ( hivename , " HKU " ) | |
strequal ( hivename , " HKEY_USERS " ) )
{
2006-11-21 13:32:08 +03:00
( * reg_type ) = HKEY_USERS ;
2008-04-04 18:46:01 +04:00
} else if ( strequal ( hivename , " HKCU " ) | |
strequal ( hivename , " HKEY_CURRENT_USER " ) )
{
2007-09-25 08:54:20 +04:00
( * reg_type ) = HKEY_CURRENT_USER ;
2008-04-04 18:46:01 +04:00
} else if ( strequal ( hivename , " HKPD " ) | |
strequal ( hivename , " HKEY_PERFORMANCE_DATA " ) )
{
2006-11-21 13:32:08 +03:00
( * reg_type ) = HKEY_PERFORMANCE_DATA ;
2008-04-04 18:46:01 +04:00
} else {
2006-11-21 13:32:08 +03:00
DEBUG ( 10 , ( " reg_hive_key: unrecognised hive key %s \n " ,
fullname ) ) ;
2008-04-04 18:46:01 +04:00
goto done ;
2006-11-21 13:32:08 +03:00
}
2008-04-04 18:46:01 +04:00
ret = true ;
done :
TALLOC_FREE ( tmp_ctx ) ;
return ret ;
2006-11-21 13:32:08 +03:00
}
static NTSTATUS registry_openkey ( TALLOC_CTX * mem_ctx ,
struct rpc_pipe_client * pipe_hnd ,
2015-05-07 03:00:06 +03:00
const char * name , uint32_t access_mask ,
2006-11-21 13:32:08 +03:00
struct policy_handle * hive_hnd ,
struct policy_handle * key_hnd )
{
2015-05-07 03:00:06 +03:00
uint32_t hive ;
2006-11-21 13:32:08 +03:00
NTSTATUS status ;
2011-01-13 00:53:52 +03:00
WERROR werr ;
2006-11-21 13:32:08 +03:00
struct winreg_String key ;
2011-01-13 00:53:52 +03:00
struct dcerpc_binding_handle * b = pipe_hnd - > binding_handle ;
2006-11-21 13:32:08 +03:00
2007-07-26 20:39:48 +04:00
ZERO_STRUCT ( key ) ;
2008-04-04 18:46:01 +04:00
if ( ! reg_hive_key ( mem_ctx , name , & hive , & key . name ) ) {
2006-11-21 13:32:08 +03:00
return NT_STATUS_INVALID_PARAMETER ;
}
2011-01-13 00:53:52 +03:00
status = dcerpc_winreg_Connect ( b , mem_ctx , hive , access_mask ,
hive_hnd , & werr ) ;
2006-11-21 13:32:08 +03:00
if ( ! ( NT_STATUS_IS_OK ( status ) ) ) {
return status ;
}
2011-01-13 00:53:52 +03:00
if ( ! W_ERROR_IS_OK ( werr ) ) {
return werror_to_ntstatus ( werr ) ;
}
2006-11-21 13:32:08 +03:00
2011-01-13 00:53:52 +03:00
status = dcerpc_winreg_OpenKey ( b , mem_ctx , hive_hnd , key , 0 ,
access_mask , key_hnd , & werr ) ;
2006-11-21 13:32:08 +03:00
if ( ! ( NT_STATUS_IS_OK ( status ) ) ) {
2011-01-13 00:53:52 +03:00
dcerpc_winreg_CloseKey ( b , mem_ctx , hive_hnd , & werr ) ;
2006-11-21 13:32:08 +03:00
return status ;
}
2011-01-13 00:53:52 +03:00
if ( ! ( W_ERROR_IS_OK ( werr ) ) ) {
WERROR _werr ;
dcerpc_winreg_CloseKey ( b , mem_ctx , hive_hnd , & _werr ) ;
return werror_to_ntstatus ( werr ) ;
}
2006-11-21 13:32:08 +03:00
return NT_STATUS_OK ;
}
2006-11-21 02:20:07 +03:00
static NTSTATUS registry_enumkeys ( TALLOC_CTX * ctx ,
struct rpc_pipe_client * pipe_hnd ,
struct policy_handle * key_hnd ,
2015-05-07 03:00:06 +03:00
uint32_t * pnum_keys , char * * * pnames ,
2006-11-21 02:20:07 +03:00
char * * * pclasses , NTTIME * * * pmodtimes )
{
TALLOC_CTX * mem_ctx ;
NTSTATUS status ;
2011-01-13 00:53:52 +03:00
WERROR werr ;
2015-05-07 03:00:06 +03:00
uint32_t num_subkeys , max_subkeylen , max_classlen ;
uint32_t num_values , max_valnamelen , max_valbufsize ;
uint32_t i ;
2006-11-21 02:20:07 +03:00
NTTIME last_changed_time ;
2015-05-07 03:00:06 +03:00
uint32_t secdescsize ;
2006-11-21 02:20:07 +03:00
struct winreg_String classname ;
char * * names , * * classes ;
NTTIME * * modtimes ;
2011-01-13 00:53:52 +03:00
struct dcerpc_binding_handle * b = pipe_hnd - > binding_handle ;
2006-11-21 02:20:07 +03:00
if ( ! ( mem_ctx = talloc_new ( ctx ) ) ) {
return NT_STATUS_NO_MEMORY ;
}
ZERO_STRUCT ( classname ) ;
2011-01-13 00:53:52 +03:00
status = dcerpc_winreg_QueryInfoKey (
b , mem_ctx , key_hnd , & classname , & num_subkeys ,
2006-11-21 02:20:07 +03:00
& max_subkeylen , & max_classlen , & num_values , & max_valnamelen ,
2011-01-13 00:53:52 +03:00
& max_valbufsize , & secdescsize , & last_changed_time , & werr ) ;
2006-11-21 02:20:07 +03:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
goto error ;
}
2011-01-13 00:53:52 +03:00
if ( ! W_ERROR_IS_OK ( werr ) ) {
status = werror_to_ntstatus ( werr ) ;
goto error ;
}
2006-11-21 02:20:07 +03:00
if ( num_subkeys = = 0 ) {
* pnum_keys = 0 ;
TALLOC_FREE ( mem_ctx ) ;
return NT_STATUS_OK ;
}
2011-06-07 05:58:39 +04:00
if ( ( ! ( names = talloc_zero_array ( mem_ctx , char * , num_subkeys ) ) ) | |
( ! ( classes = talloc_zero_array ( mem_ctx , char * , num_subkeys ) ) ) | |
( ! ( modtimes = talloc_zero_array ( mem_ctx , NTTIME * ,
2006-11-21 02:20:07 +03:00
num_subkeys ) ) ) ) {
status = NT_STATUS_NO_MEMORY ;
goto error ;
}
for ( i = 0 ; i < num_subkeys ; i + + ) {
char c , n ;
struct winreg_StringBuf class_buf ;
struct winreg_StringBuf name_buf ;
NTTIME modtime ;
c = ' \0 ' ;
class_buf . name = & c ;
class_buf . size = max_classlen + 2 ;
n = ' \0 ' ;
name_buf . name = & n ;
name_buf . size = max_subkeylen + 2 ;
ZERO_STRUCT ( modtime ) ;
2011-01-13 00:53:52 +03:00
status = dcerpc_winreg_EnumKey ( b , mem_ctx , key_hnd ,
2007-01-16 18:42:03 +03:00
i , & name_buf , & class_buf ,
2007-12-03 20:21:40 +03:00
& modtime , & werr ) ;
2011-01-13 00:53:52 +03:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
goto error ;
}
2007-12-03 20:21:40 +03:00
if ( W_ERROR_EQUAL ( werr ,
2006-11-21 02:20:07 +03:00
WERR_NO_MORE_ITEMS ) ) {
status = NT_STATUS_OK ;
break ;
}
2011-01-13 00:53:52 +03:00
if ( ! W_ERROR_IS_OK ( werr ) ) {
status = werror_to_ntstatus ( werr ) ;
2006-11-21 02:20:07 +03:00
goto error ;
}
classes [ i ] = NULL ;
2007-01-16 18:42:03 +03:00
if ( class_buf . name & &
( ! ( classes [ i ] = talloc_strdup ( classes , class_buf . name ) ) ) ) {
2006-11-21 02:20:07 +03:00
status = NT_STATUS_NO_MEMORY ;
goto error ;
}
if ( ! ( names [ i ] = talloc_strdup ( names , name_buf . name ) ) ) {
status = NT_STATUS_NO_MEMORY ;
goto error ;
}
2007-01-16 18:42:03 +03:00
if ( ( ! ( modtimes [ i ] = ( NTTIME * ) talloc_memdup (
modtimes , & modtime , sizeof ( modtime ) ) ) ) ) {
2006-11-21 02:20:07 +03:00
status = NT_STATUS_NO_MEMORY ;
goto error ;
}
}
* pnum_keys = num_subkeys ;
if ( pnames ) {
* pnames = talloc_move ( ctx , & names ) ;
}
if ( pclasses ) {
* pclasses = talloc_move ( ctx , & classes ) ;
}
if ( pmodtimes ) {
* pmodtimes = talloc_move ( ctx , & modtimes ) ;
}
status = NT_STATUS_OK ;
error :
TALLOC_FREE ( mem_ctx ) ;
return status ;
}
static NTSTATUS registry_enumvalues ( TALLOC_CTX * ctx ,
struct rpc_pipe_client * pipe_hnd ,
struct policy_handle * key_hnd ,
2015-05-07 03:00:06 +03:00
uint32_t * pnum_values , char * * * pvalnames ,
2006-11-21 02:20:07 +03:00
struct registry_value * * * pvalues )
{
TALLOC_CTX * mem_ctx ;
NTSTATUS status ;
2011-01-13 00:53:52 +03:00
WERROR werr ;
2015-05-07 03:00:06 +03:00
uint32_t num_subkeys , max_subkeylen , max_classlen ;
uint32_t num_values , max_valnamelen , max_valbufsize ;
uint32_t i ;
2006-11-21 02:20:07 +03:00
NTTIME last_changed_time ;
2015-05-07 03:00:06 +03:00
uint32_t secdescsize ;
2006-11-21 02:20:07 +03:00
struct winreg_String classname ;
struct registry_value * * values ;
char * * names ;
2011-01-13 00:53:52 +03:00
struct dcerpc_binding_handle * b = pipe_hnd - > binding_handle ;
2006-11-21 02:20:07 +03:00
if ( ! ( mem_ctx = talloc_new ( ctx ) ) ) {
return NT_STATUS_NO_MEMORY ;
}
ZERO_STRUCT ( classname ) ;
2011-01-13 00:53:52 +03:00
status = dcerpc_winreg_QueryInfoKey (
b , mem_ctx , key_hnd , & classname , & num_subkeys ,
2006-11-21 02:20:07 +03:00
& max_subkeylen , & max_classlen , & num_values , & max_valnamelen ,
2011-01-13 00:53:52 +03:00
& max_valbufsize , & secdescsize , & last_changed_time , & werr ) ;
2006-11-21 02:20:07 +03:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
goto error ;
}
2011-01-13 00:53:52 +03:00
if ( ! W_ERROR_IS_OK ( werr ) ) {
status = werror_to_ntstatus ( werr ) ;
goto error ;
}
2006-11-21 02:20:07 +03:00
if ( num_values = = 0 ) {
* pnum_values = 0 ;
TALLOC_FREE ( mem_ctx ) ;
return NT_STATUS_OK ;
}
2011-06-07 05:30:12 +04:00
if ( ( ! ( names = talloc_array ( mem_ctx , char * , num_values ) ) ) | |
( ! ( values = talloc_array ( mem_ctx , struct registry_value * ,
2006-11-21 02:20:07 +03:00
num_values ) ) ) ) {
status = NT_STATUS_NO_MEMORY ;
goto error ;
}
for ( i = 0 ; i < num_values ; i + + ) {
enum winreg_Type type = REG_NONE ;
2015-05-07 03:00:06 +03:00
uint8_t * data = NULL ;
uint32_t data_size ;
uint32_t value_length ;
2006-11-21 02:20:07 +03:00
char n ;
2009-01-16 02:25:57 +03:00
struct winreg_ValNameBuf name_buf ;
2006-12-01 23:01:09 +03:00
WERROR err ;
2006-11-21 02:20:07 +03:00
n = ' \0 ' ;
name_buf . name = & n ;
name_buf . size = max_valnamelen + 2 ;
data_size = max_valbufsize ;
2015-05-07 03:00:06 +03:00
data = ( uint8_t * ) TALLOC ( mem_ctx , data_size ) ;
2006-11-21 02:20:07 +03:00
value_length = 0 ;
2011-01-13 00:53:52 +03:00
status = dcerpc_winreg_EnumValue ( b , mem_ctx , key_hnd ,
2007-01-16 18:42:03 +03:00
i , & name_buf , & type ,
2007-02-20 16:43:41 +03:00
data , & data_size ,
2007-12-03 20:21:40 +03:00
& value_length , & err ) ;
2011-01-13 00:53:52 +03:00
if ( ! ( NT_STATUS_IS_OK ( status ) ) ) {
goto error ;
}
2006-11-21 02:20:07 +03:00
2007-12-03 20:21:40 +03:00
if ( W_ERROR_EQUAL ( err ,
2006-11-21 02:20:07 +03:00
WERR_NO_MORE_ITEMS ) ) {
status = NT_STATUS_OK ;
break ;
}
2011-01-13 00:53:52 +03:00
if ( ! W_ERROR_IS_OK ( err ) ) {
status = werror_to_ntstatus ( err ) ;
2006-11-21 02:20:07 +03:00
goto error ;
}
2007-01-16 18:42:03 +03:00
if ( name_buf . name = = NULL ) {
2006-11-21 02:20:07 +03:00
status = NT_STATUS_INVALID_PARAMETER ;
goto error ;
}
if ( ! ( names [ i ] = talloc_strdup ( names , name_buf . name ) ) ) {
status = NT_STATUS_NO_MEMORY ;
goto error ;
}
2010-06-29 18:13:15 +04:00
values [ i ] = talloc_zero ( values , struct registry_value ) ;
if ( values [ i ] = = NULL ) {
status = NT_STATUS_NO_MEMORY ;
2006-11-21 02:20:07 +03:00
goto error ;
}
2010-06-29 18:13:15 +04:00
values [ i ] - > type = type ;
values [ i ] - > data = data_blob_talloc ( values [ i ] , data , data_size ) ;
2006-11-21 02:20:07 +03:00
}
* pnum_values = num_values ;
if ( pvalnames ) {
* pvalnames = talloc_move ( ctx , & names ) ;
}
if ( pvalues ) {
* pvalues = talloc_move ( ctx , & values ) ;
}
status = NT_STATUS_OK ;
error :
TALLOC_FREE ( mem_ctx ) ;
return status ;
}
2005-05-23 20:25:31 +04:00
2010-09-20 18:45:57 +04:00
static NTSTATUS registry_enumvalues2 ( TALLOC_CTX * ctx ,
struct rpc_pipe_client * pipe_hnd ,
struct policy_handle * key_hnd ,
2015-05-07 03:00:06 +03:00
uint32_t * pnum_values , char * * * pvalnames ,
2010-09-20 18:45:57 +04:00
struct regval_blob * * * pvalues )
{
TALLOC_CTX * mem_ctx ;
NTSTATUS status ;
2011-01-13 00:53:52 +03:00
WERROR werr ;
2015-05-07 03:00:06 +03:00
uint32_t num_subkeys , max_subkeylen , max_classlen ;
uint32_t num_values , max_valnamelen , max_valbufsize ;
uint32_t i ;
2010-09-20 18:45:57 +04:00
NTTIME last_changed_time ;
2015-05-07 03:00:06 +03:00
uint32_t secdescsize ;
2010-09-20 18:45:57 +04:00
struct winreg_String classname ;
struct regval_blob * * values ;
char * * names ;
2011-01-13 00:53:52 +03:00
struct dcerpc_binding_handle * b = pipe_hnd - > binding_handle ;
2010-09-20 18:45:57 +04:00
if ( ! ( mem_ctx = talloc_new ( ctx ) ) ) {
return NT_STATUS_NO_MEMORY ;
}
ZERO_STRUCT ( classname ) ;
2011-01-13 00:53:52 +03:00
status = dcerpc_winreg_QueryInfoKey (
b , mem_ctx , key_hnd , & classname , & num_subkeys ,
2010-09-20 18:45:57 +04:00
& max_subkeylen , & max_classlen , & num_values , & max_valnamelen ,
2011-01-13 00:53:52 +03:00
& max_valbufsize , & secdescsize , & last_changed_time , & werr ) ;
2010-09-20 18:45:57 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
goto error ;
}
2011-01-13 00:53:52 +03:00
if ( ! W_ERROR_IS_OK ( werr ) ) {
status = werror_to_ntstatus ( werr ) ;
goto error ;
}
2010-09-20 18:45:57 +04:00
if ( num_values = = 0 ) {
* pnum_values = 0 ;
TALLOC_FREE ( mem_ctx ) ;
return NT_STATUS_OK ;
}
2011-06-07 05:30:12 +04:00
if ( ( ! ( names = talloc_array ( mem_ctx , char * , num_values ) ) ) | |
( ! ( values = talloc_array ( mem_ctx , struct regval_blob * ,
2010-09-20 18:45:57 +04:00
num_values ) ) ) ) {
status = NT_STATUS_NO_MEMORY ;
goto error ;
}
for ( i = 0 ; i < num_values ; i + + ) {
enum winreg_Type type = REG_NONE ;
2015-05-07 03:00:06 +03:00
uint8_t * data = NULL ;
uint32_t data_size ;
uint32_t value_length ;
2010-09-20 18:45:57 +04:00
char n ;
struct winreg_ValNameBuf name_buf ;
WERROR err ;
n = ' \0 ' ;
name_buf . name = & n ;
name_buf . size = max_valnamelen + 2 ;
data_size = max_valbufsize ;
2015-05-07 03:00:06 +03:00
data = ( uint8_t * ) TALLOC ( mem_ctx , data_size ) ;
2010-09-20 18:45:57 +04:00
value_length = 0 ;
2011-01-13 00:53:52 +03:00
status = dcerpc_winreg_EnumValue ( b , mem_ctx , key_hnd ,
2010-09-20 18:45:57 +04:00
i , & name_buf , & type ,
data , & data_size ,
& value_length , & err ) ;
2011-01-13 00:53:52 +03:00
if ( ! ( NT_STATUS_IS_OK ( status ) ) ) {
goto error ;
}
2010-09-20 18:45:57 +04:00
if ( W_ERROR_EQUAL ( err , WERR_NO_MORE_ITEMS ) ) {
status = NT_STATUS_OK ;
break ;
}
2011-01-13 00:53:52 +03:00
if ( ! W_ERROR_IS_OK ( err ) ) {
status = werror_to_ntstatus ( err ) ;
2010-09-20 18:45:57 +04:00
goto error ;
}
if ( name_buf . name = = NULL ) {
status = NT_STATUS_INVALID_PARAMETER ;
goto error ;
}
if ( ! ( names [ i ] = talloc_strdup ( names , name_buf . name ) ) ) {
status = NT_STATUS_NO_MEMORY ;
goto error ;
}
2011-10-08 09:21:49 +04:00
assert ( value_length < = data_size ) ; /*??? */
2010-09-20 18:45:57 +04:00
values [ i ] = regval_compose ( values ,
name_buf . name ,
type ,
data , value_length ) ;
if ( ! values [ i ] ) {
status = NT_STATUS_NO_MEMORY ;
goto error ;
}
}
* pnum_values = num_values ;
if ( pvalnames ) {
* pvalnames = talloc_move ( ctx , & names ) ;
}
if ( pvalues ) {
* pvalues = talloc_move ( ctx , & values ) ;
}
status = NT_STATUS_OK ;
error :
TALLOC_FREE ( mem_ctx ) ;
return status ;
}
2007-10-06 00:07:18 +04:00
static NTSTATUS registry_getsd ( TALLOC_CTX * mem_ctx ,
2011-01-13 00:53:52 +03:00
struct dcerpc_binding_handle * b ,
2007-10-06 00:07:18 +04:00
struct policy_handle * key_hnd ,
uint32_t sec_info ,
2011-01-13 00:53:52 +03:00
struct KeySecurityData * sd ,
WERROR * werr )
2007-10-06 00:07:18 +04:00
{
2011-01-13 00:53:52 +03:00
return dcerpc_winreg_GetKeySecurity ( b , mem_ctx , key_hnd ,
sec_info , sd , werr ) ;
2007-10-06 00:07:18 +04:00
}
2006-11-21 13:32:08 +03:00
static NTSTATUS registry_setvalue ( TALLOC_CTX * mem_ctx ,
struct rpc_pipe_client * pipe_hnd ,
struct policy_handle * key_hnd ,
const char * name ,
const struct registry_value * value )
{
struct winreg_String name_string ;
NTSTATUS result ;
2011-01-13 00:53:52 +03:00
WERROR werr ;
struct dcerpc_binding_handle * b = pipe_hnd - > binding_handle ;
2006-11-21 13:32:08 +03:00
2007-07-26 20:39:48 +04:00
ZERO_STRUCT ( name_string ) ;
2006-11-21 13:32:08 +03:00
name_string . name = name ;
2011-01-13 00:53:52 +03:00
result = dcerpc_winreg_SetValue ( b , mem_ctx , key_hnd ,
2006-11-21 13:32:08 +03:00
name_string , value - > type ,
2011-01-13 00:53:52 +03:00
value - > data . data , value - > data . length , & werr ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
return result ;
}
return werror_to_ntstatus ( werr ) ;
2006-11-21 13:32:08 +03:00
}
2008-05-10 01:22:12 +04:00
static NTSTATUS rpc_registry_setvalue_internal ( struct net_context * c ,
2010-05-21 05:25:01 +04:00
const struct dom_sid * domain_sid ,
2008-05-08 13:23:38 +04:00
const char * domain_name ,
2006-11-21 13:32:08 +03:00
struct cli_state * cli ,
struct rpc_pipe_client * pipe_hnd ,
2008-05-08 13:23:38 +04:00
TALLOC_CTX * mem_ctx ,
2006-11-21 13:32:08 +03:00
int argc ,
const char * * argv )
{
struct policy_handle hive_hnd , key_hnd ;
NTSTATUS status ;
2011-01-13 00:53:52 +03:00
WERROR werr ;
2006-11-21 13:32:08 +03:00
struct registry_value value ;
2011-01-13 00:53:52 +03:00
struct dcerpc_binding_handle * b = pipe_hnd - > binding_handle ;
2006-11-21 13:32:08 +03:00
2008-05-08 13:23:38 +04:00
status = registry_openkey ( mem_ctx , pipe_hnd , argv [ 0 ] ,
2009-04-15 03:12:13 +04:00
SEC_FLAG_MAXIMUM_ALLOWED ,
2006-11-21 13:32:08 +03:00
& hive_hnd , & key_hnd ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2009-08-10 20:29:50 +04:00
d_fprintf ( stderr , _ ( " registry_openkey failed: %s \n " ) ,
2006-11-21 13:32:08 +03:00
nt_errstr ( status ) ) ;
return status ;
}
if ( ! strequal ( argv [ 2 ] , " multi_sz " ) & & ( argc ! = 4 ) ) {
2009-08-10 20:29:50 +04:00
d_fprintf ( stderr , _ ( " Too many args for type %s \n " ) , argv [ 2 ] ) ;
2006-11-21 13:32:08 +03:00
return NT_STATUS_NOT_IMPLEMENTED ;
}
if ( strequal ( argv [ 2 ] , " dword " ) ) {
2019-01-28 15:36:45 +03:00
int error = 0 ;
uint32_t v ;
2019-06-04 10:04:15 +03:00
v = smb_strtoul ( argv [ 3 ] , NULL , 10 , & error , SMB_STR_STANDARD ) ;
2019-01-28 15:36:45 +03:00
if ( error ! = 0 ) {
goto error ;
}
2006-11-21 13:32:08 +03:00
value . type = REG_DWORD ;
2010-06-29 18:13:15 +04:00
value . data = data_blob_talloc ( mem_ctx , NULL , 4 ) ;
SIVAL ( value . data . data , 0 , v ) ;
2006-11-21 13:32:08 +03:00
}
else if ( strequal ( argv [ 2 ] , " sz " ) ) {
value . type = REG_SZ ;
2010-06-29 18:13:15 +04:00
if ( ! push_reg_sz ( mem_ctx , & value . data , argv [ 3 ] ) ) {
status = NT_STATUS_NO_MEMORY ;
goto error ;
}
2006-11-21 13:32:08 +03:00
}
else {
2009-08-10 20:29:50 +04:00
d_fprintf ( stderr , _ ( " type \" %s \" not implemented \n " ) , argv [ 2 ] ) ;
2006-11-21 13:32:08 +03:00
status = NT_STATUS_NOT_IMPLEMENTED ;
goto error ;
}
status = registry_setvalue ( mem_ctx , pipe_hnd , & key_hnd ,
argv [ 1 ] , & value ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2009-08-10 20:29:50 +04:00
d_fprintf ( stderr , _ ( " registry_setvalue failed: %s \n " ) ,
2006-11-21 13:32:08 +03:00
nt_errstr ( status ) ) ;
}
error :
2011-01-13 00:53:52 +03:00
dcerpc_winreg_CloseKey ( b , mem_ctx , & key_hnd , & werr ) ;
dcerpc_winreg_CloseKey ( b , mem_ctx , & hive_hnd , & werr ) ;
2006-11-21 13:32:08 +03:00
return NT_STATUS_OK ;
}
2008-05-10 01:22:12 +04:00
static int rpc_registry_setvalue ( struct net_context * c , int argc ,
const char * * argv )
2006-11-21 13:32:08 +03:00
{
2008-06-07 03:27:41 +04:00
if ( argc < 4 | | c - > display_usage ) {
2010-01-19 13:43:54 +03:00
d_fprintf ( stderr , " %s \n %s " ,
_ ( " Usage: " ) ,
_ ( " net rpc registry setvalue <key> <valuename> "
" <type> [<val>]+ \n " ) ) ;
2006-11-21 13:48:11 +03:00
return - 1 ;
}
2012-01-10 14:53:42 +04:00
return run_rpc_command ( c , NULL , & ndr_table_winreg , 0 ,
2009-11-08 21:37:26 +03:00
rpc_registry_setvalue_internal , argc , argv ) ;
2006-11-21 13:32:08 +03:00
}
2008-05-10 01:22:12 +04:00
static NTSTATUS rpc_registry_deletevalue_internal ( struct net_context * c ,
2010-05-21 05:25:01 +04:00
const struct dom_sid * domain_sid ,
2008-05-08 13:23:38 +04:00
const char * domain_name ,
2006-11-21 18:33:55 +03:00
struct cli_state * cli ,
struct rpc_pipe_client * pipe_hnd ,
2008-05-08 13:23:38 +04:00
TALLOC_CTX * mem_ctx ,
2006-11-21 18:33:55 +03:00
int argc ,
const char * * argv )
{
struct policy_handle hive_hnd , key_hnd ;
NTSTATUS status ;
2011-01-13 00:53:52 +03:00
WERROR werr ;
2006-11-21 18:33:55 +03:00
struct winreg_String valuename ;
2011-01-13 00:53:52 +03:00
struct dcerpc_binding_handle * b = pipe_hnd - > binding_handle ;
2006-11-21 18:33:55 +03:00
2007-07-26 20:39:48 +04:00
ZERO_STRUCT ( valuename ) ;
2007-08-23 19:33:25 +04:00
status = registry_openkey ( mem_ctx , pipe_hnd , argv [ 0 ] ,
2009-04-15 03:12:13 +04:00
SEC_FLAG_MAXIMUM_ALLOWED ,
2006-11-21 18:33:55 +03:00
& hive_hnd , & key_hnd ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2009-08-10 20:29:50 +04:00
d_fprintf ( stderr , _ ( " registry_openkey failed: %s \n " ) ,
2006-11-21 18:33:55 +03:00
nt_errstr ( status ) ) ;
return status ;
}
valuename . name = argv [ 1 ] ;
2011-01-13 00:53:52 +03:00
status = dcerpc_winreg_DeleteValue ( b , mem_ctx , & key_hnd ,
valuename , & werr ) ;
2006-11-21 18:33:55 +03:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2009-08-10 20:29:50 +04:00
d_fprintf ( stderr , _ ( " registry_deletevalue failed: %s \n " ) ,
2006-11-21 18:33:55 +03:00
nt_errstr ( status ) ) ;
}
2011-01-13 00:53:52 +03:00
if ( ! W_ERROR_IS_OK ( werr ) ) {
status = werror_to_ntstatus ( werr ) ;
d_fprintf ( stderr , _ ( " registry_deletevalue failed: %s \n " ) ,
win_errstr ( werr ) ) ;
}
2006-11-21 18:33:55 +03:00
2011-01-13 00:53:52 +03:00
dcerpc_winreg_CloseKey ( b , mem_ctx , & key_hnd , & werr ) ;
dcerpc_winreg_CloseKey ( b , mem_ctx , & hive_hnd , & werr ) ;
2006-11-21 18:33:55 +03:00
2008-04-04 19:52:35 +04:00
return status ;
2006-11-21 18:33:55 +03:00
}
2008-05-10 01:22:12 +04:00
static int rpc_registry_deletevalue ( struct net_context * c , int argc ,
const char * * argv )
2006-11-21 18:33:55 +03:00
{
2008-06-07 03:27:41 +04:00
if ( argc ! = 2 | | c - > display_usage ) {
2010-01-19 13:43:54 +03:00
d_fprintf ( stderr , " %s \n %s " ,
_ ( " Usage: " ) ,
_ ( " net rpc registry deletevalue <key> <valuename> \n " ) ) ;
2006-11-21 18:33:55 +03:00
return - 1 ;
}
2012-01-10 14:53:42 +04:00
return run_rpc_command ( c , NULL , & ndr_table_winreg , 0 ,
2009-11-08 21:37:26 +03:00
rpc_registry_deletevalue_internal , argc , argv ) ;
2006-11-21 18:33:55 +03:00
}
2008-05-10 01:22:12 +04:00
static NTSTATUS rpc_registry_getvalue_internal ( struct net_context * c ,
2010-05-21 05:25:01 +04:00
const struct dom_sid * domain_sid ,
2008-04-09 16:30:18 +04:00
const char * domain_name ,
struct cli_state * cli ,
struct rpc_pipe_client * pipe_hnd ,
TALLOC_CTX * mem_ctx ,
2008-05-15 18:07:06 +04:00
bool raw ,
2008-04-09 16:30:18 +04:00
int argc ,
const char * * argv )
{
struct policy_handle hive_hnd , key_hnd ;
NTSTATUS status ;
2011-01-13 00:53:52 +03:00
WERROR werr ;
2008-04-09 16:30:18 +04:00
struct winreg_String valuename ;
struct registry_value * value = NULL ;
enum winreg_Type type = REG_NONE ;
uint32_t data_size = 0 ;
uint32_t value_length = 0 ;
TALLOC_CTX * tmp_ctx = talloc_stackframe ( ) ;
2011-01-13 00:53:52 +03:00
struct dcerpc_binding_handle * b = pipe_hnd - > binding_handle ;
2008-04-09 16:30:18 +04:00
ZERO_STRUCT ( valuename ) ;
status = registry_openkey ( tmp_ctx , pipe_hnd , argv [ 0 ] ,
2009-04-15 03:12:13 +04:00
SEC_FLAG_MAXIMUM_ALLOWED ,
2008-04-09 16:30:18 +04:00
& hive_hnd , & key_hnd ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2009-08-10 20:29:50 +04:00
d_fprintf ( stderr , _ ( " registry_openkey failed: %s \n " ) ,
2008-04-09 16:30:18 +04:00
nt_errstr ( status ) ) ;
return status ;
}
valuename . name = argv [ 1 ] ;
2010-06-29 18:13:15 +04:00
value = talloc_zero ( tmp_ctx , struct registry_value ) ;
if ( value = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
2008-04-09 16:30:18 +04:00
/*
* call QueryValue once with data = = NULL to get the
* needed memory size to be allocated , then allocate
* data buffer and call again .
*/
2011-01-13 00:53:52 +03:00
status = dcerpc_winreg_QueryValue ( b , tmp_ctx , & key_hnd ,
2008-04-09 16:30:18 +04:00
& valuename ,
& type ,
2010-06-29 18:13:15 +04:00
NULL ,
2008-04-09 16:30:18 +04:00
& data_size ,
& value_length ,
2011-01-13 00:53:52 +03:00
& werr ) ;
2008-04-09 16:30:18 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2009-08-10 20:29:50 +04:00
d_fprintf ( stderr , _ ( " registry_queryvalue failed: %s \n " ) ,
2008-04-09 16:30:18 +04:00
nt_errstr ( status ) ) ;
goto done ;
}
2011-01-13 00:53:52 +03:00
if ( ! W_ERROR_IS_OK ( werr ) ) {
status = werror_to_ntstatus ( werr ) ;
d_fprintf ( stderr , _ ( " registry_queryvalue failed: %s \n " ) ,
nt_errstr ( status ) ) ;
goto done ;
}
2008-04-09 16:30:18 +04:00
2010-06-29 18:13:15 +04:00
value - > data = data_blob_talloc ( tmp_ctx , NULL , data_size ) ;
2008-04-09 16:30:18 +04:00
2011-01-13 00:53:52 +03:00
status = dcerpc_winreg_QueryValue ( b , tmp_ctx , & key_hnd ,
2008-04-09 16:30:18 +04:00
& valuename ,
& type ,
2010-06-29 18:13:15 +04:00
value - > data . data ,
2008-04-09 16:30:18 +04:00
& data_size ,
& value_length ,
2011-01-13 00:53:52 +03:00
& werr ) ;
2008-04-09 16:30:18 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2009-08-10 20:29:50 +04:00
d_fprintf ( stderr , _ ( " registry_queryvalue failed: %s \n " ) ,
2008-04-09 16:30:18 +04:00
nt_errstr ( status ) ) ;
goto done ;
}
2011-01-13 00:53:52 +03:00
if ( ! W_ERROR_IS_OK ( werr ) ) {
status = werror_to_ntstatus ( werr ) ;
d_fprintf ( stderr , _ ( " registry_queryvalue failed: %s \n " ) ,
win_errstr ( werr ) ) ;
goto done ;
}
2008-04-09 16:30:18 +04:00
2010-07-02 15:08:00 +04:00
value - > type = type ;
2008-05-15 20:06:23 +04:00
print_registry_value ( value , raw ) ;
2008-04-09 16:30:18 +04:00
done :
2011-01-13 00:53:52 +03:00
dcerpc_winreg_CloseKey ( b , tmp_ctx , & key_hnd , & werr ) ;
dcerpc_winreg_CloseKey ( b , tmp_ctx , & hive_hnd , & werr ) ;
2008-04-09 16:30:18 +04:00
TALLOC_FREE ( tmp_ctx ) ;
return status ;
}
2008-05-15 18:49:25 +04:00
static NTSTATUS rpc_registry_getvalue_full ( struct net_context * c ,
2010-05-21 05:25:01 +04:00
const struct dom_sid * domain_sid ,
2008-05-15 18:49:25 +04:00
const char * domain_name ,
struct cli_state * cli ,
struct rpc_pipe_client * pipe_hnd ,
TALLOC_CTX * mem_ctx ,
int argc ,
const char * * argv )
{
return rpc_registry_getvalue_internal ( c , domain_sid , domain_name ,
cli , pipe_hnd , mem_ctx , false ,
argc , argv ) ;
}
static int rpc_registry_getvalue ( struct net_context * c , int argc ,
const char * * argv )
{
2008-06-07 03:27:41 +04:00
if ( argc ! = 2 | | c - > display_usage ) {
2010-01-19 13:43:54 +03:00
d_fprintf ( stderr , " %s \n %s " ,
_ ( " Usage: " ) ,
_ ( " net rpc registry getvalue <key> <valuename> \n " ) ) ;
2008-05-15 18:49:25 +04:00
return - 1 ;
}
2012-01-10 14:53:42 +04:00
return run_rpc_command ( c , NULL , & ndr_table_winreg , 0 ,
2009-11-08 21:37:26 +03:00
rpc_registry_getvalue_full , argc , argv ) ;
2008-05-15 18:49:25 +04:00
}
2008-05-15 18:07:06 +04:00
static NTSTATUS rpc_registry_getvalue_raw ( struct net_context * c ,
2010-05-21 05:25:01 +04:00
const struct dom_sid * domain_sid ,
2008-05-15 18:07:06 +04:00
const char * domain_name ,
struct cli_state * cli ,
struct rpc_pipe_client * pipe_hnd ,
TALLOC_CTX * mem_ctx ,
int argc ,
const char * * argv )
{
return rpc_registry_getvalue_internal ( c , domain_sid , domain_name ,
2008-05-15 18:49:25 +04:00
cli , pipe_hnd , mem_ctx , true ,
2008-05-15 18:07:06 +04:00
argc , argv ) ;
}
2008-05-15 18:49:25 +04:00
static int rpc_registry_getvalueraw ( struct net_context * c , int argc ,
const char * * argv )
2008-04-09 16:30:18 +04:00
{
2008-06-07 03:27:41 +04:00
if ( argc ! = 2 | | c - > display_usage ) {
2010-01-19 13:43:54 +03:00
d_fprintf ( stderr , " %s \n %s " ,
_ ( " Usage: " ) ,
_ ( " net rpc registry getvalue <key> <valuename> \n " ) ) ;
2008-04-09 16:30:18 +04:00
return - 1 ;
}
2012-01-10 14:53:42 +04:00
return run_rpc_command ( c , NULL , & ndr_table_winreg , 0 ,
2009-11-08 21:37:26 +03:00
rpc_registry_getvalue_raw , argc , argv ) ;
2008-04-09 16:30:18 +04:00
}
2008-05-10 01:22:12 +04:00
static NTSTATUS rpc_registry_createkey_internal ( struct net_context * c ,
2010-05-21 05:25:01 +04:00
const struct dom_sid * domain_sid ,
2008-05-08 13:23:38 +04:00
const char * domain_name ,
2006-11-21 18:33:55 +03:00
struct cli_state * cli ,
struct rpc_pipe_client * pipe_hnd ,
2008-05-08 13:23:38 +04:00
TALLOC_CTX * mem_ctx ,
2006-11-21 18:33:55 +03:00
int argc ,
const char * * argv )
{
2015-05-07 03:00:06 +03:00
uint32_t hive ;
2006-11-21 18:33:55 +03:00
struct policy_handle hive_hnd , key_hnd ;
struct winreg_String key , keyclass ;
enum winreg_CreateAction action ;
NTSTATUS status ;
2011-01-13 00:53:52 +03:00
WERROR werr ;
struct dcerpc_binding_handle * b = pipe_hnd - > binding_handle ;
2006-11-21 18:33:55 +03:00
2007-07-26 20:39:48 +04:00
ZERO_STRUCT ( key ) ;
ZERO_STRUCT ( keyclass ) ;
2008-04-04 18:46:01 +04:00
if ( ! reg_hive_key ( mem_ctx , argv [ 0 ] , & hive , & key . name ) ) {
2006-11-21 18:33:55 +03:00
return NT_STATUS_INVALID_PARAMETER ;
}
2011-01-13 00:53:52 +03:00
status = dcerpc_winreg_Connect ( b , mem_ctx , hive ,
2009-04-15 03:12:13 +04:00
SEC_FLAG_MAXIMUM_ALLOWED ,
2011-01-13 00:53:52 +03:00
& hive_hnd , & werr ) ;
2006-11-21 18:33:55 +03:00
if ( ! ( NT_STATUS_IS_OK ( status ) ) ) {
return status ;
}
2011-01-13 00:53:52 +03:00
if ( ! W_ERROR_IS_OK ( werr ) ) {
return werror_to_ntstatus ( werr ) ;
}
2006-11-21 18:33:55 +03:00
action = REG_ACTION_NONE ;
keyclass . name = " " ;
2011-01-13 00:53:52 +03:00
status = dcerpc_winreg_CreateKey ( b , mem_ctx , & hive_hnd , key ,
2006-11-21 18:33:55 +03:00
keyclass , 0 , REG_KEY_READ , NULL ,
2011-01-13 00:53:52 +03:00
& key_hnd , & action , & werr ) ;
2006-11-21 18:33:55 +03:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2009-08-10 20:29:50 +04:00
d_fprintf ( stderr , _ ( " createkey returned %s \n " ) ,
2006-11-21 18:33:55 +03:00
nt_errstr ( status ) ) ;
2011-01-13 00:53:52 +03:00
dcerpc_winreg_CloseKey ( b , mem_ctx , & hive_hnd , & werr ) ;
2006-11-21 18:33:55 +03:00
return status ;
}
2011-01-13 00:53:52 +03:00
if ( ! W_ERROR_IS_OK ( werr ) ) {
WERROR _werr ;
d_fprintf ( stderr , _ ( " createkey returned %s \n " ) ,
win_errstr ( werr ) ) ;
dcerpc_winreg_CloseKey ( b , mem_ctx , & hive_hnd , & _werr ) ;
return werror_to_ntstatus ( werr ) ;
}
2006-11-21 18:33:55 +03:00
2007-01-16 18:42:03 +03:00
switch ( action ) {
2006-11-21 18:33:55 +03:00
case REG_ACTION_NONE :
2009-08-10 20:29:50 +04:00
d_printf ( _ ( " createkey did nothing -- huh? \n " ) ) ;
2006-11-21 18:33:55 +03:00
break ;
case REG_CREATED_NEW_KEY :
2009-08-10 20:29:50 +04:00
d_printf ( _ ( " createkey created %s \n " ) , argv [ 0 ] ) ;
2006-11-21 18:33:55 +03:00
break ;
case REG_OPENED_EXISTING_KEY :
2009-08-10 20:29:50 +04:00
d_printf ( _ ( " createkey opened existing %s \n " ) , argv [ 0 ] ) ;
2006-11-21 18:33:55 +03:00
break ;
}
2011-01-13 00:53:52 +03:00
dcerpc_winreg_CloseKey ( b , mem_ctx , & key_hnd , & werr ) ;
dcerpc_winreg_CloseKey ( b , mem_ctx , & hive_hnd , & werr ) ;
2006-11-21 18:33:55 +03:00
return status ;
}
2008-05-10 01:22:12 +04:00
static int rpc_registry_createkey ( struct net_context * c , int argc ,
const char * * argv )
2006-11-21 18:33:55 +03:00
{
2008-06-07 03:27:41 +04:00
if ( argc ! = 1 | | c - > display_usage ) {
2010-01-19 13:43:54 +03:00
d_fprintf ( stderr , " %s \n %s " ,
_ ( " Usage: " ) ,
_ ( " net rpc registry createkey <key> \n " ) ) ;
2006-11-21 18:33:55 +03:00
return - 1 ;
}
2012-01-10 14:53:42 +04:00
return run_rpc_command ( c , NULL , & ndr_table_winreg , 0 ,
2009-11-08 21:37:26 +03:00
rpc_registry_createkey_internal , argc , argv ) ;
2006-11-21 18:33:55 +03:00
}
2008-05-10 01:22:12 +04:00
static NTSTATUS rpc_registry_deletekey_internal ( struct net_context * c ,
2010-05-21 05:25:01 +04:00
const struct dom_sid * domain_sid ,
2008-05-08 13:23:38 +04:00
const char * domain_name ,
2006-11-21 18:33:55 +03:00
struct cli_state * cli ,
struct rpc_pipe_client * pipe_hnd ,
2008-05-08 13:23:38 +04:00
TALLOC_CTX * mem_ctx ,
2006-11-21 18:33:55 +03:00
int argc ,
const char * * argv )
{
2015-05-07 03:00:06 +03:00
uint32_t hive ;
2006-11-21 18:33:55 +03:00
struct policy_handle hive_hnd ;
struct winreg_String key ;
NTSTATUS status ;
2011-01-13 00:53:52 +03:00
WERROR werr ;
struct dcerpc_binding_handle * b = pipe_hnd - > binding_handle ;
2006-11-21 18:33:55 +03:00
2007-07-26 20:39:48 +04:00
ZERO_STRUCT ( key ) ;
2008-04-04 18:46:01 +04:00
if ( ! reg_hive_key ( mem_ctx , argv [ 0 ] , & hive , & key . name ) ) {
2006-11-21 18:33:55 +03:00
return NT_STATUS_INVALID_PARAMETER ;
}
2011-01-13 00:53:52 +03:00
status = dcerpc_winreg_Connect ( b , mem_ctx , hive ,
2009-04-15 03:12:13 +04:00
SEC_FLAG_MAXIMUM_ALLOWED ,
2011-01-13 00:53:52 +03:00
& hive_hnd , & werr ) ;
2006-11-21 18:33:55 +03:00
if ( ! ( NT_STATUS_IS_OK ( status ) ) ) {
return status ;
}
2011-01-13 00:53:52 +03:00
if ( ! W_ERROR_IS_OK ( werr ) ) {
return werror_to_ntstatus ( werr ) ;
}
2006-11-21 18:33:55 +03:00
2011-01-13 00:53:52 +03:00
status = dcerpc_winreg_DeleteKey ( b , mem_ctx , & hive_hnd , key , & werr ) ;
if ( is_valid_policy_hnd ( & hive_hnd ) ) {
WERROR _werr ;
dcerpc_winreg_CloseKey ( b , mem_ctx , & hive_hnd , & _werr ) ;
}
2006-11-21 18:33:55 +03:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2009-08-10 20:29:50 +04:00
d_fprintf ( stderr , _ ( " deletekey returned %s \n " ) ,
2006-11-21 18:33:55 +03:00
nt_errstr ( status ) ) ;
2011-01-13 00:53:52 +03:00
return status ;
}
if ( ! W_ERROR_IS_OK ( werr ) ) {
d_fprintf ( stderr , _ ( " deletekey returned %s \n " ) ,
win_errstr ( werr ) ) ;
return werror_to_ntstatus ( werr ) ;
2006-11-21 18:33:55 +03:00
}
return status ;
}
2008-05-10 01:22:12 +04:00
static int rpc_registry_deletekey ( struct net_context * c , int argc , const char * * argv )
2006-11-21 18:33:55 +03:00
{
2008-06-07 03:27:41 +04:00
if ( argc ! = 1 | | c - > display_usage ) {
2010-01-19 13:43:54 +03:00
d_fprintf ( stderr , " %s \n %s " ,
_ ( " Usage: " ) ,
_ ( " net rpc registry deletekey <key> \n " ) ) ;
2006-11-21 18:33:55 +03:00
return - 1 ;
}
2012-01-10 14:53:42 +04:00
return run_rpc_command ( c , NULL , & ndr_table_winreg , 0 ,
2009-11-08 21:37:26 +03:00
rpc_registry_deletekey_internal , argc , argv ) ;
2006-11-21 18:33:55 +03:00
}
2005-05-23 20:25:31 +04:00
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-05-10 01:22:12 +04:00
static NTSTATUS rpc_registry_enumerate_internal ( struct net_context * c ,
2010-05-21 05:25:01 +04:00
const struct dom_sid * domain_sid ,
2008-05-08 13:23:38 +04:00
const char * domain_name ,
2005-09-30 21:13:37 +04:00
struct cli_state * cli ,
struct rpc_pipe_client * pipe_hnd ,
2008-05-08 13:23:38 +04:00
TALLOC_CTX * mem_ctx ,
2005-09-30 21:13:37 +04:00
int argc ,
const char * * argv )
2005-05-23 20:25:31 +04:00
{
2009-03-19 00:49:41 +03:00
struct policy_handle pol_hive , pol_key ;
2006-09-26 19:15:26 +04:00
NTSTATUS status ;
2011-01-13 00:53:52 +03:00
WERROR werr ;
2015-05-07 03:00:06 +03:00
uint32_t num_subkeys = 0 ;
uint32_t num_values = 0 ;
2006-12-01 23:01:09 +03:00
char * * names = NULL , * * classes = NULL ;
NTTIME * * modtimes = NULL ;
2015-05-07 03:00:06 +03:00
uint32_t i ;
2006-12-01 23:01:09 +03:00
struct registry_value * * values = NULL ;
2011-01-13 00:53:52 +03:00
struct dcerpc_binding_handle * b = pipe_hnd - > binding_handle ;
2008-05-08 13:23:38 +04:00
2008-06-07 03:27:41 +04:00
if ( argc ! = 1 | | c - > display_usage ) {
2010-01-19 13:43:54 +03:00
d_printf ( " %s \n %s " ,
_ ( " Usage: " ) ,
_ ( " net rpc registry enumerate <path> \n " ) ) ;
d_printf ( " %s net rpc registry enumerate "
" 'HKLM \\ Software \\ Samba' \n " , _ ( " Example: " ) ) ;
2008-04-04 19:50:41 +04:00
return NT_STATUS_INVALID_PARAMETER ;
2005-05-23 20:25:31 +04:00
}
2006-11-21 13:48:11 +03:00
status = registry_openkey ( mem_ctx , pipe_hnd , argv [ 0 ] , REG_KEY_READ ,
& pol_hive , & pol_key ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2009-08-10 20:29:50 +04:00
d_fprintf ( stderr , _ ( " registry_openkey failed: %s \n " ) ,
2006-09-29 01:19:08 +04:00
nt_errstr ( status ) ) ;
2006-11-21 13:48:11 +03:00
return status ;
2005-05-23 20:25:31 +04:00
}
2006-09-29 01:19:08 +04:00
2006-11-21 02:20:07 +03:00
status = registry_enumkeys ( mem_ctx , pipe_hnd , & pol_key , & num_subkeys ,
& names , & classes , & modtimes ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2009-08-10 20:29:50 +04:00
d_fprintf ( stderr , _ ( " enumerating keys failed: %s \n " ) ,
2006-11-21 02:20:07 +03:00
nt_errstr ( status ) ) ;
2006-09-29 01:19:08 +04:00
return status ;
}
2006-11-21 02:20:07 +03:00
for ( i = 0 ; i < num_subkeys ; i + + ) {
2008-04-04 15:26:03 +04:00
print_registry_key ( names [ i ] , modtimes [ i ] ) ;
2005-05-23 20:25:31 +04:00
}
2006-11-21 02:20:07 +03:00
status = registry_enumvalues ( mem_ctx , pipe_hnd , & pol_key , & num_values ,
& names , & values ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2009-08-10 20:29:50 +04:00
d_fprintf ( stderr , _ ( " enumerating values failed: %s \n " ) ,
2006-11-21 02:20:07 +03:00
nt_errstr ( status ) ) ;
return status ;
2006-09-29 01:19:08 +04:00
}
2006-11-21 02:20:07 +03:00
for ( i = 0 ; i < num_values ; i + + ) {
2008-04-09 14:29:34 +04:00
print_registry_value_with_name ( names [ i ] , values [ i ] ) ;
2005-05-23 20:25:31 +04:00
}
2006-11-21 02:20:07 +03:00
2011-01-13 00:53:52 +03:00
dcerpc_winreg_CloseKey ( b , mem_ctx , & pol_key , & werr ) ;
dcerpc_winreg_CloseKey ( b , mem_ctx , & pol_hive , & werr ) ;
2005-05-23 20:25:31 +04:00
2006-09-26 19:15:26 +04:00
return status ;
2005-05-23 20:25:31 +04:00
}
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-05-10 01:22:12 +04:00
static int rpc_registry_enumerate ( struct net_context * c , int argc ,
const char * * argv )
2005-05-23 20:25:31 +04:00
{
2012-01-10 14:53:42 +04:00
return run_rpc_command ( c , NULL , & ndr_table_winreg , 0 ,
2009-11-08 21:37:26 +03:00
rpc_registry_enumerate_internal , argc , argv ) ;
2005-05-23 20:25:31 +04:00
}
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-05-10 01:22:12 +04:00
static NTSTATUS rpc_registry_save_internal ( struct net_context * c ,
2010-05-21 05:25:01 +04:00
const struct dom_sid * domain_sid ,
2008-05-08 13:23:38 +04:00
const char * domain_name ,
2005-09-30 21:13:37 +04:00
struct cli_state * cli ,
struct rpc_pipe_client * pipe_hnd ,
2008-05-08 13:23:38 +04:00
TALLOC_CTX * mem_ctx ,
2005-09-30 21:13:37 +04:00
int argc ,
const char * * argv )
2005-05-23 20:25:31 +04:00
{
2015-12-03 17:24:21 +03:00
WERROR result = WERR_GEN_FAILURE ;
2009-03-19 00:49:41 +03:00
struct policy_handle pol_hive , pol_key ;
2006-09-26 19:15:26 +04:00
NTSTATUS status = NT_STATUS_UNSUCCESSFUL ;
2006-09-28 01:37:43 +04:00
struct winreg_String filename ;
2011-01-13 00:53:52 +03:00
struct dcerpc_binding_handle * b = pipe_hnd - > binding_handle ;
2008-05-08 13:23:38 +04:00
2008-06-07 03:27:41 +04:00
if ( argc ! = 2 | | c - > display_usage ) {
2010-01-19 13:43:54 +03:00
d_printf ( " %s \n %s " ,
_ ( " Usage: " ) ,
_ ( " net rpc registry backup <path> <file> \n " ) ) ;
2008-04-04 19:50:41 +04:00
return NT_STATUS_INVALID_PARAMETER ;
2005-05-23 20:25:31 +04:00
}
2008-05-08 13:23:38 +04:00
2006-11-21 13:48:11 +03:00
status = registry_openkey ( mem_ctx , pipe_hnd , argv [ 0 ] , REG_KEY_ALL ,
& pol_hive , & pol_key ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2009-08-10 20:29:50 +04:00
d_fprintf ( stderr , _ ( " registry_openkey failed: %s \n " ) ,
2006-11-21 13:48:11 +03:00
nt_errstr ( status ) ) ;
2006-09-26 19:15:26 +04:00
return status ;
2005-05-23 20:25:31 +04:00
}
2006-11-21 13:48:11 +03:00
2006-09-28 01:37:43 +04:00
filename . name = argv [ 1 ] ;
2011-01-13 00:53:52 +03:00
status = dcerpc_winreg_SaveKey ( b , mem_ctx , & pol_key , & filename , NULL , & result ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_fprintf ( stderr , _ ( " Unable to save [%s] to %s:%s \n " ) , argv [ 0 ] ,
2011-07-22 18:51:19 +04:00
pipe_hnd - > desthost , argv [ 1 ] ) ;
2011-01-13 00:53:52 +03:00
}
if ( ! W_ERROR_IS_OK ( result ) ) {
status = werror_to_ntstatus ( result ) ;
2009-08-10 20:29:50 +04:00
d_fprintf ( stderr , _ ( " Unable to save [%s] to %s:%s \n " ) , argv [ 0 ] ,
2011-07-22 18:51:19 +04:00
pipe_hnd - > desthost , argv [ 1 ] ) ;
2005-05-23 20:25:31 +04:00
}
2008-05-08 13:23:38 +04:00
2005-05-23 20:25:31 +04:00
/* cleanup */
2008-05-08 13:23:38 +04:00
2011-01-13 00:53:52 +03:00
dcerpc_winreg_CloseKey ( b , mem_ctx , & pol_key , & result ) ;
dcerpc_winreg_CloseKey ( b , mem_ctx , & pol_hive , & result ) ;
2005-05-23 20:25:31 +04:00
2006-09-26 19:15:26 +04:00
return status ;
2005-05-23 20:25:31 +04:00
}
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-05-10 01:22:12 +04:00
static int rpc_registry_save ( struct net_context * c , int argc , const char * * argv )
2005-05-23 20:25:31 +04:00
{
2012-01-10 14:53:42 +04:00
return run_rpc_command ( c , NULL , & ndr_table_winreg , 0 ,
2009-11-08 21:37:26 +03:00
rpc_registry_save_internal , argc , argv ) ;
2005-05-23 20:25:31 +04:00
}
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void dump_values ( REGF_NK_REC * nk )
{
int i , j ;
2009-09-30 22:00:52 +04:00
const char * data_str = NULL ;
2015-05-07 03:00:06 +03:00
uint32_t data_size , data ;
2009-09-30 22:00:52 +04:00
DATA_BLOB blob ;
2005-05-23 20:25:31 +04:00
if ( ! nk - > values )
return ;
for ( i = 0 ; i < nk - > num_values ; i + + ) {
d_printf ( " \" %s \" = " , nk - > values [ i ] . valuename ? nk - > values [ i ] . valuename : " (default) " ) ;
2010-04-27 18:38:40 +04:00
d_printf ( " (%s) " , str_regtype ( nk - > values [ i ] . type ) ) ;
2005-05-23 20:25:31 +04:00
data_size = nk - > values [ i ] . data_size & ~ VK_DATA_IN_OFFSET ;
switch ( nk - > values [ i ] . type ) {
case REG_SZ :
2009-09-30 22:00:52 +04:00
blob = data_blob_const ( nk - > values [ i ] . data , data_size ) ;
2013-11-09 21:50:16 +04:00
if ( ! pull_reg_sz ( talloc_tos ( ) , & blob ,
& data_str ) ) {
data_str = NULL ;
}
2007-12-05 02:21:14 +03:00
if ( ! data_str ) {
break ;
}
2005-05-23 20:25:31 +04:00
d_printf ( " %s " , data_str ) ;
break ;
case REG_MULTI_SZ :
case REG_EXPAND_SZ :
for ( j = 0 ; j < data_size ; j + + ) {
d_printf ( " %c " , nk - > values [ i ] . data [ j ] ) ;
}
break ;
case REG_DWORD :
data = IVAL ( nk - > values [ i ] . data , 0 ) ;
d_printf ( " 0x%x " , data ) ;
break ;
case REG_BINARY :
for ( j = 0 ; j < data_size ; j + + ) {
d_printf ( " %x " , nk - > values [ i ] . data [ j ] ) ;
}
break ;
default :
2009-08-10 20:29:50 +04:00
d_printf ( _ ( " unknown " ) ) ;
2005-05-23 20:25:31 +04:00
break ;
}
d_printf ( " \n " ) ;
}
}
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-10-19 04:40:25 +04:00
static bool dump_registry_tree ( REGF_FILE * file , REGF_NK_REC * nk , const char * parent )
2005-05-23 20:25:31 +04:00
{
REGF_NK_REC * key ;
/* depth first dump of the registry tree */
while ( ( key = regfio_fetch_subkey ( file , nk ) ) ) {
2007-12-05 02:21:14 +03:00
char * regpath ;
if ( asprintf ( & regpath , " %s \\ %s " , parent , key - > keyname ) < 0 ) {
break ;
}
2005-05-23 20:25:31 +04:00
d_printf ( " [%s] \n " , regpath ) ;
dump_values ( key ) ;
d_printf ( " \n " ) ;
dump_registry_tree ( file , key , regpath ) ;
2007-12-05 02:21:14 +03:00
SAFE_FREE ( regpath ) ;
2005-05-23 20:25:31 +04:00
}
2006-01-18 00:22:00 +03:00
2008-05-12 13:53:23 +04:00
return true ;
2005-05-23 20:25:31 +04:00
}
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-05-08 13:23:38 +04:00
static bool write_registry_tree ( REGF_FILE * infile , REGF_NK_REC * nk ,
2005-05-23 20:25:31 +04:00
REGF_NK_REC * parent , REGF_FILE * outfile ,
const char * parentpath )
{
REGF_NK_REC * key , * subkey ;
2009-03-23 20:14:17 +03:00
struct regval_ctr * values = NULL ;
2009-02-24 17:19:18 +03:00
struct regsubkey_ctr * subkeys = NULL ;
2005-05-23 20:25:31 +04:00
int i ;
2007-12-05 02:21:14 +03:00
char * path = NULL ;
2009-02-25 16:49:30 +03:00
WERROR werr ;
2005-05-23 20:25:31 +04:00
2009-02-25 16:49:30 +03:00
werr = regsubkey_ctr_init ( infile - > mem_ctx , & subkeys ) ;
if ( ! W_ERROR_IS_OK ( werr ) ) {
DEBUG ( 0 , ( " write_registry_tree: regsubkey_ctr_init failed: "
" %s \n " , win_errstr ( werr ) ) ) ;
2008-05-12 13:53:23 +04:00
return false ;
2005-08-29 18:55:40 +04:00
}
2010-05-24 17:10:48 +04:00
werr = regval_ctr_init ( subkeys , & values ) ;
if ( ! W_ERROR_IS_OK ( werr ) ) {
2005-08-29 18:55:40 +04:00
DEBUG ( 0 , ( " write_registry_tree: talloc() failed! \n " ) ) ;
2007-12-05 02:21:14 +03:00
TALLOC_FREE ( subkeys ) ;
2008-05-12 13:53:23 +04:00
return false ;
2005-08-29 18:55:40 +04:00
}
2009-03-23 20:14:17 +03:00
/* copy values into the struct regval_ctr */
2007-12-05 02:21:14 +03:00
2005-05-23 20:25:31 +04:00
for ( i = 0 ; i < nk - > num_values ; i + + ) {
2005-08-29 18:55:40 +04:00
regval_ctr_addvalue ( values , nk - > values [ i ] . valuename , nk - > values [ i ] . type ,
2010-05-25 00:19:17 +04:00
nk - > values [ i ] . data , ( nk - > values [ i ] . data_size & ~ VK_DATA_IN_OFFSET ) ) ;
2005-05-23 20:25:31 +04:00
}
2009-02-24 17:19:18 +03:00
/* copy subkeys into the struct regsubkey_ctr */
2007-12-05 02:21:14 +03:00
2005-05-23 20:25:31 +04:00
while ( ( subkey = regfio_fetch_subkey ( infile , nk ) ) ) {
2005-08-29 18:55:40 +04:00
regsubkey_ctr_addkey ( subkeys , subkey - > keyname ) ;
2005-05-23 20:25:31 +04:00
}
2007-12-05 02:21:14 +03:00
2005-08-29 18:55:40 +04:00
key = regfio_write_key ( outfile , nk - > keyname , values , subkeys , nk - > sec_desc - > sec_desc , parent ) ;
2005-05-23 20:25:31 +04:00
/* write each one of the subkeys out */
2007-12-05 02:21:14 +03:00
path = talloc_asprintf ( subkeys ,
" %s%s%s " ,
parentpath ,
parent ? " \\ " : " " ,
nk - > keyname ) ;
if ( ! path ) {
TALLOC_FREE ( subkeys ) ;
return false ;
}
2005-05-23 20:25:31 +04:00
nk - > subkey_index = 0 ;
while ( ( subkey = regfio_fetch_subkey ( infile , nk ) ) ) {
write_registry_tree ( infile , subkey , key , outfile , path ) ;
}
d_printf ( " [%s] \n " , path ) ;
2007-12-05 02:21:14 +03:00
TALLOC_FREE ( subkeys ) ;
2008-05-12 13:53:23 +04:00
return true ;
2005-05-23 20:25:31 +04:00
}
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-05-10 01:22:12 +04:00
static int rpc_registry_dump ( struct net_context * c , int argc , const char * * argv )
2005-05-23 20:25:31 +04:00
{
REGF_FILE * registry ;
REGF_NK_REC * nk ;
2008-05-08 13:23:38 +04:00
2008-06-07 03:27:41 +04:00
if ( argc ! = 1 | | c - > display_usage ) {
2010-01-19 13:43:54 +03:00
d_printf ( " %s \n %s " ,
_ ( " Usage: " ) ,
_ ( " net rpc registry dump <file> \n " ) ) ;
2008-04-04 19:50:41 +04:00
return - 1 ;
2005-05-23 20:25:31 +04:00
}
2008-05-08 13:23:38 +04:00
2009-08-10 20:29:50 +04:00
d_printf ( _ ( " Opening %s.... " ) , argv [ 0 ] ) ;
2005-05-23 20:25:31 +04:00
if ( ! ( registry = regfio_open ( argv [ 0 ] , O_RDONLY , 0 ) ) ) {
2009-08-10 20:29:50 +04:00
d_fprintf ( stderr , _ ( " Failed to open %s for reading \n " ) , argv [ 0 ] ) ;
2005-05-23 20:25:31 +04:00
return 1 ;
}
2009-08-10 20:29:50 +04:00
d_printf ( _ ( " ok \n " ) ) ;
2008-05-08 13:23:38 +04:00
2005-05-23 20:25:31 +04:00
/* get the root of the registry file */
2008-05-08 13:23:38 +04:00
2006-06-19 23:07:39 +04:00
if ( ( nk = regfio_rootkey ( registry ) ) = = NULL ) {
2009-08-10 20:29:50 +04:00
d_fprintf ( stderr , _ ( " Could not get rootkey \n " ) ) ;
2006-06-28 08:56:23 +04:00
regfio_close ( registry ) ;
2006-06-19 23:07:39 +04:00
return 1 ;
}
2005-05-23 20:25:31 +04:00
d_printf ( " [%s] \n " , nk - > keyname ) ;
dump_values ( nk ) ;
d_printf ( " \n " ) ;
dump_registry_tree ( registry , nk , nk - > keyname ) ;
#if 0
talloc_report_full ( registry - > mem_ctx , stderr ) ;
2008-05-08 13:23:38 +04:00
# endif
2009-08-10 20:29:50 +04:00
d_printf ( _ ( " Closing registry... " ) ) ;
2005-05-23 20:25:31 +04:00
regfio_close ( registry ) ;
2009-08-10 20:29:50 +04:00
d_printf ( _ ( " ok \n " ) ) ;
2005-05-23 20:25:31 +04:00
return 0 ;
}
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-05-10 01:22:12 +04:00
static int rpc_registry_copy ( struct net_context * c , int argc , const char * * argv )
2005-05-23 20:25:31 +04:00
{
2006-06-28 08:51:23 +04:00
REGF_FILE * infile = NULL , * outfile = NULL ;
2005-05-23 20:25:31 +04:00
REGF_NK_REC * nk ;
2006-01-18 00:22:00 +03:00
int result = 1 ;
2008-05-08 13:23:38 +04:00
2008-06-07 03:27:41 +04:00
if ( argc ! = 2 | | c - > display_usage ) {
2010-01-19 13:43:54 +03:00
d_printf ( " %s \n %s " ,
_ ( " Usage: " ) ,
_ ( " net rpc registry copy <srcfile> <newfile> \n " ) ) ;
2008-04-04 19:50:41 +04:00
return - 1 ;
2005-05-23 20:25:31 +04:00
}
2008-05-08 13:23:38 +04:00
2009-08-10 20:29:50 +04:00
d_printf ( _ ( " Opening %s.... " ) , argv [ 0 ] ) ;
2005-05-23 20:25:31 +04:00
if ( ! ( infile = regfio_open ( argv [ 0 ] , O_RDONLY , 0 ) ) ) {
2009-08-10 20:29:50 +04:00
d_fprintf ( stderr , _ ( " Failed to open %s for reading \n " ) , argv [ 0 ] ) ;
2005-05-23 20:25:31 +04:00
return 1 ;
}
2009-08-10 20:29:50 +04:00
d_printf ( _ ( " ok \n " ) ) ;
2005-05-23 20:25:31 +04:00
2009-08-10 20:29:50 +04:00
d_printf ( _ ( " Opening %s.... " ) , argv [ 1 ] ) ;
2010-09-25 21:56:58 +04:00
if ( ! ( outfile = regfio_open ( argv [ 1 ] , ( O_RDWR | O_CREAT | O_TRUNC ) ,
( S_IRUSR | S_IWUSR ) ) ) ) {
2009-08-10 20:29:50 +04:00
d_fprintf ( stderr , _ ( " Failed to open %s for writing \n " ) , argv [ 1 ] ) ;
2006-06-28 08:51:23 +04:00
goto out ;
2005-05-23 20:25:31 +04:00
}
2009-08-10 20:29:50 +04:00
d_printf ( _ ( " ok \n " ) ) ;
2008-05-08 13:23:38 +04:00
2005-05-23 20:25:31 +04:00
/* get the root of the registry file */
2008-05-08 13:23:38 +04:00
2006-06-19 23:07:39 +04:00
if ( ( nk = regfio_rootkey ( infile ) ) = = NULL ) {
2009-08-10 20:29:50 +04:00
d_fprintf ( stderr , _ ( " Could not get rootkey \n " ) ) ;
2006-06-28 08:51:23 +04:00
goto out ;
2006-06-19 23:07:39 +04:00
}
2009-08-10 20:29:50 +04:00
d_printf ( _ ( " RootKey: [%s] \n " ) , nk - > keyname ) ;
2005-05-23 20:25:31 +04:00
write_registry_tree ( infile , nk , NULL , outfile , " " ) ;
2006-01-18 00:22:00 +03:00
result = 0 ;
2006-06-28 08:51:23 +04:00
out :
2009-08-10 20:29:50 +04:00
d_printf ( _ ( " Closing %s... " ) , argv [ 1 ] ) ;
2006-06-28 08:51:23 +04:00
if ( outfile ) {
regfio_close ( outfile ) ;
}
2009-08-10 20:29:50 +04:00
d_printf ( _ ( " ok \n " ) ) ;
2005-05-23 20:25:31 +04:00
2009-08-10 20:29:50 +04:00
d_printf ( _ ( " Closing %s... " ) , argv [ 0 ] ) ;
2006-06-28 08:51:23 +04:00
if ( infile ) {
regfio_close ( infile ) ;
}
2009-08-10 20:29:50 +04:00
d_printf ( _ ( " ok \n " ) ) ;
2005-05-23 20:25:31 +04:00
2006-01-18 00:22:00 +03:00
return ( result ) ;
2005-05-23 20:25:31 +04:00
}
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-05-10 01:22:12 +04:00
static NTSTATUS rpc_registry_getsd_internal ( struct net_context * c ,
2010-05-21 05:25:01 +04:00
const struct dom_sid * domain_sid ,
2007-10-06 00:07:18 +04:00
const char * domain_name ,
struct cli_state * cli ,
struct rpc_pipe_client * pipe_hnd ,
TALLOC_CTX * mem_ctx ,
int argc ,
const char * * argv )
{
2009-03-19 00:49:41 +03:00
struct policy_handle pol_hive , pol_key ;
2007-10-06 00:07:18 +04:00
NTSTATUS status ;
2011-01-13 00:53:52 +03:00
WERROR werr ;
2007-11-09 16:39:45 +03:00
enum ndr_err_code ndr_err ;
2007-10-06 00:07:18 +04:00
struct KeySecurityData * sd = NULL ;
uint32_t sec_info ;
DATA_BLOB blob ;
struct security_descriptor sec_desc ;
2010-06-21 14:32:57 +04:00
uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED |
2009-04-15 03:19:30 +04:00
SEC_FLAG_SYSTEM_SECURITY ;
2011-01-13 00:53:52 +03:00
struct dcerpc_binding_handle * b = pipe_hnd - > binding_handle ;
2007-10-06 00:07:18 +04:00
2008-06-07 03:27:41 +04:00
if ( argc < 1 | | argc > 2 | | c - > display_usage ) {
2010-01-19 13:43:54 +03:00
d_printf ( " %s \n %s " ,
_ ( " Usage: " ) ,
_ ( " net rpc registry getsd <path> <secinfo> \n " ) ) ;
d_printf ( " %s net rpc registry getsd "
" 'HKLM \\ Software \\ Samba' \n " , _ ( " Example: " ) ) ;
2008-04-04 19:50:41 +04:00
return NT_STATUS_INVALID_PARAMETER ;
2007-10-06 00:07:18 +04:00
}
2007-11-05 04:33:58 +03:00
status = registry_openkey ( mem_ctx , pipe_hnd , argv [ 0 ] ,
access_mask ,
2007-10-06 00:07:18 +04:00
& pol_hive , & pol_key ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2009-08-10 20:29:50 +04:00
d_fprintf ( stderr , _ ( " registry_openkey failed: %s \n " ) ,
2007-10-06 00:07:18 +04:00
nt_errstr ( status ) ) ;
return status ;
}
2011-06-07 05:44:43 +04:00
sd = talloc_zero ( mem_ctx , struct KeySecurityData ) ;
2007-10-06 00:07:18 +04:00
if ( ! sd ) {
status = NT_STATUS_NO_MEMORY ;
goto out ;
}
sd - > size = 0x1000 ;
2007-10-09 17:53:40 +04:00
if ( argc > = 2 ) {
sscanf ( argv [ 1 ] , " %x " , & sec_info ) ;
} else {
sec_info = SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL ;
}
2007-10-06 00:07:18 +04:00
2011-01-13 00:53:52 +03:00
status = registry_getsd ( mem_ctx , b , & pol_key , sec_info , sd , & werr ) ;
2007-10-06 00:07:18 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2009-08-10 20:29:50 +04:00
d_fprintf ( stderr , _ ( " getting sd failed: %s \n " ) ,
2007-10-06 00:07:18 +04:00
nt_errstr ( status ) ) ;
goto out ;
}
2011-01-13 00:53:52 +03:00
if ( ! W_ERROR_IS_OK ( werr ) ) {
status = werror_to_ntstatus ( werr ) ;
d_fprintf ( stderr , _ ( " getting sd failed: %s \n " ) ,
win_errstr ( werr ) ) ;
goto out ;
}
2007-10-06 00:07:18 +04:00
blob . data = sd - > data ;
blob . length = sd - > size ;
2010-05-10 02:42:06 +04:00
ndr_err = ndr_pull_struct_blob ( & blob , mem_ctx , & sec_desc ,
2007-11-09 16:39:45 +03:00
( ndr_pull_flags_fn_t ) ndr_pull_security_descriptor ) ;
if ( ! NDR_ERR_CODE_IS_SUCCESS ( ndr_err ) ) {
status = ndr_map_error2ntstatus ( ndr_err ) ;
2007-10-09 17:53:40 +04:00
goto out ;
}
2007-11-09 16:39:45 +03:00
status = NT_STATUS_OK ;
2007-10-06 00:07:18 +04:00
display_sec_desc ( & sec_desc ) ;
out :
2011-01-13 00:53:52 +03:00
dcerpc_winreg_CloseKey ( b , mem_ctx , & pol_key , & werr ) ;
dcerpc_winreg_CloseKey ( b , mem_ctx , & pol_hive , & werr ) ;
2007-10-06 00:07:18 +04:00
return status ;
}
2008-05-10 01:22:12 +04:00
static int rpc_registry_getsd ( struct net_context * c , int argc , const char * * argv )
2007-10-06 00:07:18 +04:00
{
2012-01-10 14:53:42 +04:00
return run_rpc_command ( c , NULL , & ndr_table_winreg , 0 ,
2009-11-08 21:37:26 +03:00
rpc_registry_getsd_internal , argc , argv ) ;
2007-10-06 00:07:18 +04:00
}
/********************************************************************
2010-09-20 18:45:57 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/**
* @ defgroup net_rpc_registry net rpc registry
*/
/**
* @ defgroup net_rpc_registry_export Export
* @ ingroup net_rpc_registry
* @ {
*/
static NTSTATUS registry_export ( struct rpc_pipe_client * pipe_hnd ,
TALLOC_CTX * ctx ,
struct policy_handle * key_hnd ,
struct reg_format * f ,
const char * parentfullname ,
const char * name )
{
NTSTATUS status ;
2015-05-07 03:00:06 +03:00
uint32_t num_subkeys = 0 ;
uint32_t num_values = 0 ;
2010-09-20 18:45:57 +04:00
char * * names = NULL , * * classes = NULL ;
NTTIME * * modtimes = NULL ;
struct regval_blob * * values = NULL ;
2015-05-07 03:00:06 +03:00
uint32_t i ;
2011-01-13 00:53:52 +03:00
struct dcerpc_binding_handle * b = pipe_hnd - > binding_handle ;
2010-09-20 18:45:57 +04:00
TALLOC_CTX * mem_ctx = talloc_new ( ctx ) ;
const char * fullname = name
? talloc_asprintf ( mem_ctx , " %s \\ %s " , parentfullname , name )
: parentfullname ;
reg_format_key ( f , & fullname , 1 , false ) ;
status = registry_enumvalues2 ( mem_ctx , pipe_hnd , key_hnd , & num_values ,
& names , & values ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_fprintf ( stderr , _ ( " enumerating values failed: %s \n " ) ,
nt_errstr ( status ) ) ;
goto done ;
}
for ( i = 0 ; i < num_values ; i + + ) {
reg_format_regval_blob ( f , names [ i ] , values [ i ] ) ;
}
status = registry_enumkeys ( mem_ctx , pipe_hnd , key_hnd , & num_subkeys ,
& names , & classes , & modtimes ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_fprintf ( stderr , _ ( " enumerating keys failed: %s \n " ) ,
nt_errstr ( status ) ) ;
goto done ;
}
for ( i = 0 ; i < num_subkeys ; i + + ) {
struct policy_handle subkey_hnd ;
struct winreg_String key ;
2011-01-13 00:53:52 +03:00
WERROR werr ;
2010-09-20 18:45:57 +04:00
ZERO_STRUCT ( key ) ;
/* key.name = talloc_strdup(mem_ctx, names[i]); ??? */
key . name = names [ i ] ;
2011-01-13 00:53:52 +03:00
status = dcerpc_winreg_OpenKey ( b , mem_ctx , key_hnd , key ,
2010-09-20 18:45:57 +04:00
0 , REG_KEY_READ ,
2011-01-13 00:53:52 +03:00
& subkey_hnd , & werr ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2010-09-20 18:45:57 +04:00
d_fprintf ( stderr ,
2011-01-13 00:53:52 +03:00
_ ( " dcerpc_winreg_OpenKey failed: %s %s \n " ) ,
2010-09-20 18:45:57 +04:00
names [ i ] , nt_errstr ( status ) ) ;
2011-01-13 00:53:52 +03:00
continue ;
}
if ( ! W_ERROR_IS_OK ( werr ) ) {
status = werror_to_ntstatus ( werr ) ;
d_fprintf ( stderr ,
_ ( " dcerpc_winreg_OpenKey failed: %s %s \n " ) ,
names [ i ] , win_errstr ( werr ) ) ;
continue ;
2010-09-20 18:45:57 +04:00
}
2011-01-13 00:53:52 +03:00
status = registry_export ( pipe_hnd , mem_ctx , & subkey_hnd ,
f , fullname , names [ i ] ) ;
if ( ! ( NT_STATUS_IS_OK ( status ) ) ) {
d_fprintf ( stderr ,
_ ( " export key failed: %s %s \n " ) ,
names [ i ] , nt_errstr ( status ) ) ;
}
dcerpc_winreg_CloseKey ( b , mem_ctx ,
& subkey_hnd , & werr ) ;
2010-09-20 18:45:57 +04:00
}
done :
talloc_free ( mem_ctx ) ;
return status ;
}
static NTSTATUS rpc_registry_export_internal ( struct net_context * c ,
const struct dom_sid * domain_sid ,
const char * domain_name ,
struct cli_state * cli ,
struct rpc_pipe_client * pipe_hnd ,
TALLOC_CTX * mem_ctx ,
int argc ,
const char * * argv )
{
struct policy_handle pol_hive , pol_key ;
NTSTATUS status ;
2011-01-13 00:53:52 +03:00
WERROR werr ;
2010-09-20 18:45:57 +04:00
struct reg_format * f ;
2011-01-13 00:53:52 +03:00
struct dcerpc_binding_handle * b = pipe_hnd - > binding_handle ;
2010-09-20 18:45:57 +04:00
if ( argc < 2 | | argc > 3 | | c - > display_usage ) {
d_printf ( " %s \n %s " ,
_ ( " Usage: " ) ,
_ ( " net rpc registry export <path> <file> [opt] \n " ) ) ;
d_printf ( " %s net rpc registry export "
" 'HKLM \\ Software \\ Samba' samba.reg \n " , _ ( " Example: " ) ) ;
return NT_STATUS_INVALID_PARAMETER ;
}
status = registry_openkey ( mem_ctx , pipe_hnd , argv [ 0 ] , REG_KEY_READ ,
& pol_hive , & pol_key ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_fprintf ( stderr , _ ( " registry_openkey failed: %s \n " ) ,
nt_errstr ( status ) ) ;
return status ;
}
f = reg_format_file ( mem_ctx , argv [ 1 ] , ( argc > 2 ) ? argv [ 2 ] : NULL ) ;
if ( f = = NULL ) {
d_fprintf ( stderr , _ ( " open file failed: %s \n " ) , strerror ( errno ) ) ;
return map_nt_error_from_unix ( errno ) ;
}
status = registry_export ( pipe_hnd , mem_ctx , & pol_key ,
f , argv [ 0 ] , NULL ) ;
if ( ! NT_STATUS_IS_OK ( status ) )
return status ;
2011-01-13 00:53:52 +03:00
dcerpc_winreg_CloseKey ( b , mem_ctx , & pol_key , & werr ) ;
dcerpc_winreg_CloseKey ( b , mem_ctx , & pol_hive , & werr ) ;
2010-09-20 18:45:57 +04:00
return status ;
}
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int rpc_registry_export ( struct net_context * c , int argc ,
const char * * argv )
{
2012-01-10 14:53:42 +04:00
return run_rpc_command ( c , NULL , & ndr_table_winreg , 0 ,
2010-09-20 18:45:57 +04:00
rpc_registry_export_internal , argc , argv ) ;
}
/**@}*/
2010-09-20 17:32:02 +04:00
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/**
* @ defgroup net_rpc_registry_import Import
* @ ingroup net_rpc_registry
* @ {
*/
struct import_ctx {
struct rpc_pipe_client * pipe_hnd ;
TALLOC_CTX * mem_ctx ;
} ;
static WERROR import_create_key ( struct import_ctx * ctx ,
struct policy_handle * parent , const char * name ,
void * * pkey , bool * existing )
{
WERROR werr ;
NTSTATUS status ;
void * mem_ctx = talloc_new ( ctx - > mem_ctx ) ;
struct policy_handle * key = NULL ;
struct policy_handle hive ;
struct winreg_String keyclass , keyname ;
enum winreg_CreateAction action = REG_ACTION_NONE ;
2011-01-13 00:53:52 +03:00
struct dcerpc_binding_handle * b = ctx - > pipe_hnd - > binding_handle ;
2010-09-20 17:32:02 +04:00
ZERO_STRUCT ( keyname ) ;
keyname . name = name ;
if ( parent = = NULL ) {
2015-05-07 03:00:06 +03:00
uint32_t hive_idx = 0 ;
2010-09-20 17:32:02 +04:00
if ( ! reg_hive_key ( mem_ctx , name , & hive_idx , & keyname . name ) ) {
werr = WERR_FOOBAR ;
goto done ;
}
2011-01-13 00:53:52 +03:00
status = dcerpc_winreg_Connect ( b , mem_ctx ,
2010-09-20 17:32:02 +04:00
hive_idx , SEC_FLAG_MAXIMUM_ALLOWED ,
& hive , & werr ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2011-01-13 00:53:52 +03:00
werr = ntstatus_to_werror ( status ) ;
d_fprintf ( stderr , _ ( " dcerpc_winreg_Connect returned %s \n " ) ,
2010-09-20 17:32:02 +04:00
nt_errstr ( status ) ) ;
goto done ;
}
2011-01-13 00:53:52 +03:00
if ( ! W_ERROR_IS_OK ( werr ) ) {
d_fprintf ( stderr , _ ( " dcerpc_winreg_Connect returned %s \n " ) ,
win_errstr ( werr ) ) ;
goto done ;
}
2010-09-20 17:32:02 +04:00
parent = & hive ;
}
key = talloc_zero ( mem_ctx , struct policy_handle ) ;
if ( key = = NULL ) {
2015-12-03 17:24:17 +03:00
werr = WERR_NOT_ENOUGH_MEMORY ;
2010-09-20 17:32:02 +04:00
goto done ;
}
ZERO_STRUCT ( keyclass ) ;
keyclass . name = " " ;
2011-01-13 00:53:52 +03:00
status = dcerpc_winreg_CreateKey ( b , mem_ctx ,
2010-09-20 17:32:02 +04:00
parent , keyname ,
keyclass , 0 , REG_KEY_READ , NULL ,
key , & action , & werr ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2011-01-13 00:53:52 +03:00
werr = ntstatus_to_werror ( status ) ;
d_fprintf ( stderr , _ ( " dcerpc_winreg_CreateKey returned %s \n " ) ,
2010-09-20 17:32:02 +04:00
nt_errstr ( status ) ) ;
goto done ;
}
2011-01-13 00:53:52 +03:00
if ( ! W_ERROR_IS_OK ( werr ) ) {
d_fprintf ( stderr , _ ( " dcerpc_winreg_CreateKey returned %s \n " ) ,
win_errstr ( werr ) ) ;
goto done ;
}
2010-09-20 17:32:02 +04:00
switch ( action ) {
case REG_CREATED_NEW_KEY :
d_printf ( _ ( " createkey created %s \n " ) , name ) ;
if ( existing ! = NULL )
* existing = false ;
break ;
case REG_OPENED_EXISTING_KEY :
d_printf ( _ ( " createkey opened existing %s \n " ) , name ) ;
if ( existing ! = NULL )
* existing = true ;
break ;
case REG_ACTION_NONE :
d_printf ( _ ( " createkey did nothing -- huh? \n " ) ) ;
werr = WERR_CREATE_FAILED ;
break ;
default :
assert ( false ) ;
}
done :
if ( parent = = & hive ) {
2011-01-13 00:53:52 +03:00
WERROR _result ;
dcerpc_winreg_CloseKey ( b , mem_ctx ,
parent , & _result ) ;
2010-09-20 17:32:02 +04:00
}
if ( pkey ! = NULL ) {
* pkey = talloc_steal ( ctx - > mem_ctx , key ) ;
}
talloc_free ( mem_ctx ) ;
return werr ;
}
static WERROR import_delete_key ( struct import_ctx * ctx ,
struct policy_handle * parent , const char * name )
{
WERROR werr ;
NTSTATUS status ;
void * mem_ctx = talloc_new ( ctx - > mem_ctx ) ;
2011-03-15 12:47:02 +03:00
struct winreg_String keyname = { 0 , } ;
2010-09-20 17:32:02 +04:00
struct policy_handle hive ;
2011-01-13 00:53:52 +03:00
struct dcerpc_binding_handle * b = ctx - > pipe_hnd - > binding_handle ;
2010-09-20 17:32:02 +04:00
keyname . name = name ;
if ( parent = = NULL ) {
2015-05-07 03:00:06 +03:00
uint32_t hive_idx ;
2010-09-20 17:32:02 +04:00
if ( ! reg_hive_key ( mem_ctx , name , & hive_idx , & keyname . name ) ) {
werr = WERR_FOOBAR ;
goto done ;
}
2011-01-13 00:53:52 +03:00
status = dcerpc_winreg_Connect ( b , mem_ctx , hive_idx ,
2010-09-20 17:32:02 +04:00
SEC_FLAG_MAXIMUM_ALLOWED , & hive ,
& werr ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2011-01-13 00:53:52 +03:00
werr = ntstatus_to_werror ( status ) ;
d_fprintf ( stderr , _ ( " dcerpc_winreg_Connect returned %s \n " ) ,
2010-09-20 17:32:02 +04:00
nt_errstr ( status ) ) ;
goto done ;
}
2011-01-13 00:53:52 +03:00
if ( ! W_ERROR_IS_OK ( werr ) ) {
d_fprintf ( stderr , _ ( " dcerpc_winreg_Connect returned %s \n " ) ,
win_errstr ( werr ) ) ;
goto done ;
}
2010-09-20 17:32:02 +04:00
parent = & hive ;
}
2011-01-13 00:53:52 +03:00
status = dcerpc_winreg_DeleteKey ( b , mem_ctx , parent ,
2010-09-20 17:32:02 +04:00
keyname , & werr ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2011-01-13 00:53:52 +03:00
werr = ntstatus_to_werror ( status ) ;
d_fprintf ( stderr , _ ( " dcerpc_winreg_DeleteKey returned %s \n " ) ,
2010-09-20 17:32:02 +04:00
nt_errstr ( status ) ) ;
goto done ;
}
2011-01-13 00:53:52 +03:00
if ( ! W_ERROR_IS_OK ( werr ) ) {
d_fprintf ( stderr , _ ( " dcerpc_winreg_DeleteKey returned %s \n " ) ,
win_errstr ( werr ) ) ;
goto done ;
}
2010-09-20 17:32:02 +04:00
done :
if ( parent = = & hive ) {
2011-01-13 00:53:52 +03:00
WERROR _result ;
dcerpc_winreg_CloseKey ( b , mem_ctx , parent , & _result ) ;
2010-09-20 17:32:02 +04:00
}
talloc_free ( mem_ctx ) ;
return werr ;
}
static WERROR import_close_key ( struct import_ctx * ctx ,
struct policy_handle * key )
{
WERROR werr ;
NTSTATUS status ;
void * mem_ctx = talloc_new ( ctx - > mem_ctx ) ;
2011-01-13 00:53:52 +03:00
struct dcerpc_binding_handle * b = ctx - > pipe_hnd - > binding_handle ;
2010-09-20 17:32:02 +04:00
2011-01-13 00:53:52 +03:00
status = dcerpc_winreg_CloseKey ( b , mem_ctx , key , & werr ) ;
2010-09-20 17:32:02 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2011-01-13 00:53:52 +03:00
werr = ntstatus_to_werror ( status ) ;
d_fprintf ( stderr , _ ( " dcerpc_winreg_CloseKey returned %s \n " ) ,
2010-09-20 17:32:02 +04:00
nt_errstr ( status ) ) ;
goto done ;
}
2011-01-13 00:53:52 +03:00
if ( ! W_ERROR_IS_OK ( werr ) ) {
d_fprintf ( stderr , _ ( " dcerpc_winreg_CloseKey returned %s \n " ) ,
win_errstr ( werr ) ) ;
goto done ;
}
2010-09-20 17:32:02 +04:00
2015-12-03 17:24:21 +03:00
werr = ( talloc_free ( key ) = = 0 ) ? WERR_OK : WERR_GEN_FAILURE ;
2010-09-20 17:32:02 +04:00
done :
talloc_free ( mem_ctx ) ;
return werr ;
}
static WERROR import_create_val ( struct import_ctx * ctx ,
struct policy_handle * parent , const char * name ,
uint32_t type , const uint8_t * val , uint32_t len )
{
WERROR werr ;
NTSTATUS status ;
void * mem_ctx = talloc_new ( ctx - > mem_ctx ) ;
struct winreg_String valuename ;
2011-01-13 00:53:52 +03:00
struct dcerpc_binding_handle * b = ctx - > pipe_hnd - > binding_handle ;
2010-09-20 17:32:02 +04:00
if ( parent = = NULL ) {
2015-12-03 17:24:26 +03:00
return WERR_INVALID_PARAMETER ;
2010-09-20 17:32:02 +04:00
}
ZERO_STRUCT ( valuename ) ;
valuename . name = name ;
2011-01-13 00:53:52 +03:00
status = dcerpc_winreg_SetValue ( b , mem_ctx , parent ,
2010-09-20 17:32:02 +04:00
valuename , type ,
2010-09-22 23:40:42 +04:00
( uint8_t * ) discard_const ( val ) , len , & werr ) ;
2010-09-20 17:32:02 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2011-01-13 00:53:52 +03:00
werr = ntstatus_to_werror ( status ) ;
2010-09-20 17:32:02 +04:00
d_fprintf ( stderr , _ ( " registry_setvalue failed: %s \n " ) ,
nt_errstr ( status ) ) ;
goto done ;
}
2011-01-13 00:53:52 +03:00
if ( ! W_ERROR_IS_OK ( werr ) ) {
d_fprintf ( stderr , _ ( " registry_setvalue failed: %s \n " ) ,
win_errstr ( werr ) ) ;
goto done ;
}
2010-09-20 17:32:02 +04:00
done :
talloc_free ( mem_ctx ) ;
return werr ;
}
static WERROR import_delete_val ( struct import_ctx * ctx ,
struct policy_handle * parent , const char * name )
{
WERROR werr ;
NTSTATUS status ;
void * mem_ctx = talloc_new ( ctx - > mem_ctx ) ;
struct winreg_String valuename ;
2011-01-13 00:53:52 +03:00
struct dcerpc_binding_handle * b = ctx - > pipe_hnd - > binding_handle ;
2010-09-20 17:32:02 +04:00
if ( parent = = NULL ) {
2015-12-03 17:24:26 +03:00
return WERR_INVALID_PARAMETER ;
2010-09-20 17:32:02 +04:00
}
ZERO_STRUCT ( valuename ) ;
valuename . name = name ;
2011-01-13 00:53:52 +03:00
status = dcerpc_winreg_DeleteValue ( b , mem_ctx ,
2010-09-20 17:32:02 +04:00
parent , valuename , & werr ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2011-01-13 00:53:52 +03:00
werr = ntstatus_to_werror ( status ) ;
2010-09-20 17:32:02 +04:00
d_fprintf ( stderr , _ ( " registry_deletevalue failed: %s \n " ) ,
nt_errstr ( status ) ) ;
goto done ;
}
2011-01-13 00:53:52 +03:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_fprintf ( stderr , _ ( " registry_deletevalue failed: %s \n " ) ,
win_errstr ( werr ) ) ;
goto done ;
}
2010-09-20 17:32:02 +04:00
done :
talloc_free ( mem_ctx ) ;
return werr ;
}
static NTSTATUS rpc_registry_import_internal ( struct net_context * c ,
const struct dom_sid * domain_sid ,
const char * domain_name ,
struct cli_state * cli ,
struct rpc_pipe_client * pipe_hnd ,
TALLOC_CTX * mem_ctx ,
int argc ,
const char * * argv )
{
struct import_ctx import_ctx ;
struct reg_import_callback import_callback = {
. openkey = NULL ,
. closekey = ( reg_import_callback_closekey_t ) & import_close_key ,
. createkey = ( reg_import_callback_createkey_t ) & import_create_key ,
. deletekey = ( reg_import_callback_deletekey_t ) & import_delete_key ,
. deleteval = ( reg_import_callback_deleteval_t ) & import_delete_val ,
2011-06-15 04:34:53 +04:00
. setval = {
. blob = ( reg_import_callback_setval_blob_t ) & import_create_val ,
} ,
2010-09-20 17:32:02 +04:00
. setval_type = BLOB ,
. data = & import_ctx
} ;
int ret ;
if ( argc < 1 | | argc > 2 | | c - > display_usage ) {
d_printf ( " %s \n %s " ,
_ ( " Usage: " ) ,
_ ( " net rpc registry import <file> [options] \n " ) ) ;
d_printf ( " %s net rpc registry export "
" samba.reg enc=CP1252,flags=0 \n " , _ ( " Example: " ) ) ;
return NT_STATUS_INVALID_PARAMETER ;
}
ZERO_STRUCT ( import_ctx ) ;
import_ctx . pipe_hnd = pipe_hnd ;
import_ctx . mem_ctx = mem_ctx ;
ret = reg_parse_file ( argv [ 0 ] ,
reg_import_adapter ( import_ctx . mem_ctx ,
import_callback
) ,
( argc > 1 ) ? argv [ 1 ] : NULL
) ;
return ret = = 0 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL ;
}
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int rpc_registry_import ( struct net_context * c , int argc ,
const char * * argv )
{
2012-01-10 14:53:42 +04:00
return run_rpc_command ( c , NULL , & ndr_table_winreg , 0 ,
2010-09-20 17:32:02 +04:00
rpc_registry_import_internal , argc , argv ) ;
}
/**@}*/
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-10-06 00:07:18 +04:00
2008-05-10 01:22:12 +04:00
int net_rpc_registry ( struct net_context * c , int argc , const char * * argv )
2005-05-23 20:25:31 +04:00
{
2008-06-07 04:25:08 +04:00
struct functable func [ ] = {
2008-06-07 03:27:41 +04:00
{
" enumerate " ,
rpc_registry_enumerate ,
NET_TRANSPORT_RPC ,
2009-08-10 20:29:50 +04:00
N_ ( " Enumerate registry keys and values " ) ,
N_ ( " net rpc registry enumerate \n "
" Enumerate registry keys and values " )
2008-06-07 03:27:41 +04:00
} ,
{
" createkey " ,
rpc_registry_createkey ,
NET_TRANSPORT_RPC ,
2009-08-10 20:29:50 +04:00
N_ ( " Create a new registry key " ) ,
N_ ( " net rpc registry createkey \n "
" Create a new registry key " )
2008-06-07 03:27:41 +04:00
} ,
{
" deletekey " ,
rpc_registry_deletekey ,
NET_TRANSPORT_RPC ,
2009-08-10 20:29:50 +04:00
N_ ( " Delete a registry key " ) ,
N_ ( " net rpc registry deletekey \n "
" Delete a registry key " )
2008-06-07 03:27:41 +04:00
} ,
{
" getvalue " ,
rpc_registry_getvalue ,
NET_TRANSPORT_RPC ,
2009-08-10 20:29:50 +04:00
N_ ( " Print a registry value " ) ,
N_ ( " net rpc registry getvalue \n "
" Print a registry value " )
2008-06-07 03:27:41 +04:00
} ,
{
" getvalueraw " ,
rpc_registry_getvalueraw ,
NET_TRANSPORT_RPC ,
2009-08-10 20:29:50 +04:00
N_ ( " Print a registry value " ) ,
N_ ( " net rpc registry getvalueraw \n "
" Print a registry value (raw version) " )
2008-06-07 03:27:41 +04:00
} ,
{
" setvalue " ,
rpc_registry_setvalue ,
NET_TRANSPORT_RPC ,
2009-08-10 20:29:50 +04:00
N_ ( " Set a new registry value " ) ,
N_ ( " net rpc registry setvalue \n "
" Set a new registry value " )
2008-06-07 03:27:41 +04:00
} ,
{
" deletevalue " ,
rpc_registry_deletevalue ,
NET_TRANSPORT_RPC ,
2009-08-10 20:29:50 +04:00
N_ ( " Delete a registry value " ) ,
N_ ( " net rpc registry deletevalue \n "
" Delete a registry value " )
2008-06-07 03:27:41 +04:00
} ,
{
" save " ,
rpc_registry_save ,
NET_TRANSPORT_RPC ,
2009-08-10 20:29:50 +04:00
N_ ( " Save a registry file " ) ,
N_ ( " net rpc registry save \n "
" Save a registry file " )
2008-06-07 03:27:41 +04:00
} ,
{
" dump " ,
rpc_registry_dump ,
NET_TRANSPORT_RPC ,
2009-08-10 20:29:50 +04:00
N_ ( " Dump a registry file " ) ,
N_ ( " net rpc registry dump \n "
" Dump a registry file " )
2008-06-07 03:27:41 +04:00
} ,
{
" copy " ,
rpc_registry_copy ,
NET_TRANSPORT_RPC ,
2009-08-10 20:29:50 +04:00
N_ ( " Copy a registry file " ) ,
N_ ( " net rpc registry copy \n "
" Copy a registry file " )
2008-06-07 03:27:41 +04:00
} ,
{
" getsd " ,
rpc_registry_getsd ,
NET_TRANSPORT_RPC ,
2009-08-10 20:29:50 +04:00
N_ ( " Get security descriptor " ) ,
N_ ( " net rpc registry getsd \n "
2017-02-17 22:54:26 +03:00
" Get security descriptor " )
2008-06-07 03:27:41 +04:00
} ,
2010-09-20 17:32:02 +04:00
{
" import " ,
rpc_registry_import ,
NET_TRANSPORT_RPC ,
N_ ( " Import .reg file " ) ,
N_ ( " net rpc registry import \n "
" Import .reg file " )
} ,
2010-09-20 18:45:57 +04:00
{
" export " ,
rpc_registry_export ,
NET_TRANSPORT_RPC ,
2011-02-16 13:45:52 +03:00
N_ ( " Export .reg file " ) ,
N_ ( " net rpc registry export \n "
2010-09-20 18:45:57 +04:00
" Export .reg file " )
} ,
2008-06-07 03:27:41 +04:00
{ NULL , NULL , 0 , NULL , NULL }
2005-05-23 20:25:31 +04:00
} ;
2008-06-07 04:25:08 +04:00
return net_run_function ( c , argc , argv , " net rpc registry " , func ) ;
2005-05-23 20:25:31 +04:00
}