2011-01-27 17:20:58 +03:00
/*
* Unix SMB / CIFS implementation .
*
* WINREG client routines
*
* Copyright ( c ) 2011 Andreas Schneider < asn @ samba . org >
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 3 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , see < http : //www.gnu.org/licenses/>.
*/
# include "includes.h"
# include "../librpc/gen_ndr/ndr_winreg_c.h"
2011-01-31 20:40:06 +03:00
# include "../librpc/gen_ndr/ndr_security.h"
2011-01-27 17:20:58 +03:00
# include "rpc_client/cli_winreg.h"
2011-02-26 02:28:15 +03:00
# include "../libcli/registry/util_reg.h"
2011-01-27 17:20:58 +03:00
NTSTATUS dcerpc_winreg_query_dword ( TALLOC_CTX * mem_ctx ,
struct dcerpc_binding_handle * h ,
struct policy_handle * key_handle ,
const char * value ,
uint32_t * data ,
WERROR * pwerr )
{
struct winreg_String wvalue ;
2011-06-20 17:39:36 +04:00
enum winreg_Type type = REG_NONE ;
2011-01-27 17:20:58 +03:00
uint32_t value_len = 0 ;
uint32_t data_size = 0 ;
NTSTATUS status ;
DATA_BLOB blob ;
wvalue . name = value ;
status = dcerpc_winreg_QueryValue ( h ,
mem_ctx ,
key_handle ,
& wvalue ,
& type ,
NULL ,
& data_size ,
& value_len ,
2011-07-04 13:59:36 +04:00
pwerr ) ;
2011-01-27 17:20:58 +03:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
2011-07-04 13:59:36 +04:00
if ( ! W_ERROR_IS_OK ( * pwerr ) ) {
2011-01-27 17:20:58 +03:00
return status ;
}
if ( type ! = REG_DWORD ) {
2011-07-06 14:19:05 +04:00
return NT_STATUS_OBJECT_TYPE_MISMATCH ;
2011-01-27 17:20:58 +03:00
}
if ( data_size ! = 4 ) {
2011-07-06 14:19:05 +04:00
return NT_STATUS_INVALID_PARAMETER ;
2011-01-27 17:20:58 +03:00
}
2011-06-20 17:39:36 +04:00
blob = data_blob_talloc_zero ( mem_ctx , data_size ) ;
2011-01-27 17:20:58 +03:00
if ( blob . data = = NULL ) {
2011-07-06 14:19:05 +04:00
return NT_STATUS_NO_MEMORY ;
2011-01-27 17:20:58 +03:00
}
value_len = 0 ;
status = dcerpc_winreg_QueryValue ( h ,
mem_ctx ,
key_handle ,
& wvalue ,
& type ,
blob . data ,
& data_size ,
& value_len ,
2011-07-04 13:59:36 +04:00
pwerr ) ;
2011-01-27 17:20:58 +03:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
2011-07-04 13:59:36 +04:00
if ( ! W_ERROR_IS_OK ( * pwerr ) ) {
2011-01-27 17:20:58 +03:00
return status ;
}
if ( data ) {
* data = IVAL ( blob . data , 0 ) ;
}
return status ;
}
2011-01-27 18:20:30 +03:00
NTSTATUS dcerpc_winreg_query_binary ( TALLOC_CTX * mem_ctx ,
struct dcerpc_binding_handle * h ,
struct policy_handle * key_handle ,
const char * value ,
DATA_BLOB * data ,
WERROR * pwerr )
{
struct winreg_String wvalue ;
2011-06-20 17:39:36 +04:00
enum winreg_Type type = REG_NONE ;
2011-01-27 18:20:30 +03:00
uint32_t value_len = 0 ;
uint32_t data_size = 0 ;
NTSTATUS status ;
DATA_BLOB blob ;
2011-06-20 17:39:36 +04:00
ZERO_STRUCT ( wvalue ) ;
2011-01-27 18:20:30 +03:00
wvalue . name = value ;
status = dcerpc_winreg_QueryValue ( h ,
mem_ctx ,
key_handle ,
& wvalue ,
& type ,
NULL ,
& data_size ,
& value_len ,
2011-07-04 13:59:36 +04:00
pwerr ) ;
2011-01-27 18:20:30 +03:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
2011-07-04 13:59:36 +04:00
if ( ! W_ERROR_IS_OK ( * pwerr ) ) {
2011-01-27 18:20:30 +03:00
return status ;
}
if ( type ! = REG_BINARY ) {
2011-07-06 14:19:05 +04:00
return NT_STATUS_OBJECT_TYPE_MISMATCH ;
2011-01-27 18:20:30 +03:00
}
2011-06-20 17:39:36 +04:00
blob = data_blob_talloc_zero ( mem_ctx , data_size ) ;
2011-01-27 18:20:30 +03:00
if ( blob . data = = NULL ) {
2011-07-06 14:19:05 +04:00
return NT_STATUS_NO_MEMORY ;
2011-01-27 18:20:30 +03:00
}
value_len = 0 ;
status = dcerpc_winreg_QueryValue ( h ,
mem_ctx ,
key_handle ,
& wvalue ,
& type ,
blob . data ,
& data_size ,
& value_len ,
2011-07-04 13:59:36 +04:00
pwerr ) ;
2011-01-27 18:20:30 +03:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
2011-07-04 13:59:36 +04:00
if ( ! W_ERROR_IS_OK ( * pwerr ) ) {
2011-01-27 18:20:30 +03:00
return status ;
}
if ( data ) {
data - > data = blob . data ;
data - > length = blob . length ;
}
return status ;
}
2011-01-28 12:07:57 +03:00
NTSTATUS dcerpc_winreg_query_multi_sz ( TALLOC_CTX * mem_ctx ,
struct dcerpc_binding_handle * h ,
struct policy_handle * key_handle ,
const char * value ,
const char * * * data ,
WERROR * pwerr )
{
struct winreg_String wvalue ;
2011-06-20 17:39:36 +04:00
enum winreg_Type type = REG_NONE ;
2011-01-28 12:07:57 +03:00
uint32_t value_len = 0 ;
uint32_t data_size = 0 ;
NTSTATUS status ;
DATA_BLOB blob ;
wvalue . name = value ;
status = dcerpc_winreg_QueryValue ( h ,
mem_ctx ,
key_handle ,
& wvalue ,
& type ,
NULL ,
& data_size ,
& value_len ,
2011-07-04 13:59:36 +04:00
pwerr ) ;
2011-01-28 12:07:57 +03:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
2011-07-04 13:59:36 +04:00
if ( ! W_ERROR_IS_OK ( * pwerr ) ) {
2011-01-28 12:07:57 +03:00
return status ;
}
if ( type ! = REG_MULTI_SZ ) {
2011-07-06 14:19:05 +04:00
return NT_STATUS_OBJECT_TYPE_MISMATCH ;
2011-01-28 12:07:57 +03:00
}
2011-06-20 17:39:36 +04:00
blob = data_blob_talloc_zero ( mem_ctx , data_size ) ;
2011-01-28 12:07:57 +03:00
if ( blob . data = = NULL ) {
2011-07-06 14:19:05 +04:00
return NT_STATUS_NO_MEMORY ;
2011-01-28 12:07:57 +03:00
}
value_len = 0 ;
status = dcerpc_winreg_QueryValue ( h ,
mem_ctx ,
key_handle ,
& wvalue ,
& type ,
blob . data ,
& data_size ,
& value_len ,
2011-07-04 13:59:36 +04:00
pwerr ) ;
2011-01-28 12:07:57 +03:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
2011-07-04 13:59:36 +04:00
if ( ! W_ERROR_IS_OK ( * pwerr ) ) {
2011-01-28 12:07:57 +03:00
return status ;
}
if ( data ) {
bool ok ;
ok = pull_reg_multi_sz ( mem_ctx , & blob , data ) ;
if ( ! ok ) {
2011-07-06 14:19:05 +04:00
status = NT_STATUS_NO_MEMORY ;
2011-01-28 12:07:57 +03:00
}
}
return status ;
}
2011-01-31 18:39:34 +03:00
NTSTATUS dcerpc_winreg_query_sz ( TALLOC_CTX * mem_ctx ,
struct dcerpc_binding_handle * h ,
struct policy_handle * key_handle ,
const char * value ,
const char * * data ,
WERROR * pwerr )
{
struct winreg_String wvalue ;
2011-06-20 17:39:36 +04:00
enum winreg_Type type = REG_NONE ;
2011-01-31 18:39:34 +03:00
uint32_t value_len = 0 ;
uint32_t data_size = 0 ;
NTSTATUS status ;
DATA_BLOB blob ;
wvalue . name = value ;
status = dcerpc_winreg_QueryValue ( h ,
mem_ctx ,
key_handle ,
& wvalue ,
& type ,
NULL ,
& data_size ,
& value_len ,
2011-07-04 13:59:36 +04:00
pwerr ) ;
2011-01-31 18:39:34 +03:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
2011-07-04 13:59:36 +04:00
if ( ! W_ERROR_IS_OK ( * pwerr ) ) {
2011-01-31 18:39:34 +03:00
return status ;
}
if ( type ! = REG_SZ ) {
2011-07-06 14:19:05 +04:00
return NT_STATUS_OBJECT_TYPE_MISMATCH ;
2011-01-31 18:39:34 +03:00
}
2011-06-20 17:39:36 +04:00
blob = data_blob_talloc_zero ( mem_ctx , data_size ) ;
2011-01-31 18:39:34 +03:00
if ( blob . data = = NULL ) {
2011-07-06 14:19:05 +04:00
return NT_STATUS_NO_MEMORY ;
2011-01-31 18:39:34 +03:00
}
value_len = 0 ;
status = dcerpc_winreg_QueryValue ( h ,
mem_ctx ,
key_handle ,
& wvalue ,
& type ,
blob . data ,
& data_size ,
& value_len ,
2011-07-04 13:59:36 +04:00
pwerr ) ;
2011-01-31 18:39:34 +03:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
2011-07-04 13:59:36 +04:00
if ( ! W_ERROR_IS_OK ( * pwerr ) ) {
2011-01-31 18:39:34 +03:00
return status ;
}
if ( data ) {
bool ok ;
ok = pull_reg_sz ( mem_ctx , & blob , data ) ;
if ( ! ok ) {
2011-07-06 14:19:05 +04:00
status = NT_STATUS_NO_MEMORY ;
2011-01-31 18:39:34 +03:00
}
}
return status ;
}
2011-02-01 13:04:16 +03:00
NTSTATUS dcerpc_winreg_query_sd ( TALLOC_CTX * mem_ctx ,
struct dcerpc_binding_handle * h ,
struct policy_handle * key_handle ,
const char * value ,
struct security_descriptor * * data ,
WERROR * pwerr )
{
NTSTATUS status ;
DATA_BLOB blob ;
status = dcerpc_winreg_query_binary ( mem_ctx ,
h ,
key_handle ,
value ,
& blob ,
2011-07-04 13:59:36 +04:00
pwerr ) ;
2011-02-01 13:04:16 +03:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
2011-07-04 13:59:36 +04:00
if ( ! W_ERROR_IS_OK ( * pwerr ) ) {
2011-02-01 13:04:16 +03:00
return status ;
}
if ( data ) {
struct security_descriptor * sd ;
enum ndr_err_code ndr_err ;
sd = talloc_zero ( mem_ctx , struct security_descriptor ) ;
if ( sd = = NULL ) {
2011-07-06 14:19:05 +04:00
return NT_STATUS_NO_MEMORY ;
2011-02-01 13:04:16 +03:00
}
ndr_err = ndr_pull_struct_blob ( & blob ,
sd ,
sd ,
( ndr_pull_flags_fn_t ) ndr_pull_security_descriptor ) ;
if ( ! NDR_ERR_CODE_IS_SUCCESS ( ndr_err ) ) {
DEBUG ( 2 , ( " dcerpc_winreg_query_sd: Failed to marshall "
" security descriptor \n " ) ) ;
2011-07-06 14:19:05 +04:00
return NT_STATUS_NO_MEMORY ;
2011-02-01 13:04:16 +03:00
}
* data = sd ;
}
return status ;
}
2011-01-27 18:57:34 +03:00
NTSTATUS dcerpc_winreg_set_dword ( TALLOC_CTX * mem_ctx ,
struct dcerpc_binding_handle * h ,
struct policy_handle * key_handle ,
const char * value ,
uint32_t data ,
WERROR * pwerr )
{
2011-06-20 17:39:36 +04:00
struct winreg_String wvalue ;
2011-01-27 18:57:34 +03:00
DATA_BLOB blob ;
NTSTATUS status ;
2011-06-20 17:39:36 +04:00
ZERO_STRUCT ( wvalue ) ;
2011-01-27 18:57:34 +03:00
wvalue . name = value ;
2011-06-20 17:39:36 +04:00
blob = data_blob_talloc_zero ( mem_ctx , 4 ) ;
2011-01-27 18:57:34 +03:00
SIVAL ( blob . data , 0 , data ) ;
status = dcerpc_winreg_SetValue ( h ,
mem_ctx ,
key_handle ,
wvalue ,
REG_DWORD ,
blob . data ,
blob . length ,
2011-07-04 13:59:36 +04:00
pwerr ) ;
2011-01-27 18:57:34 +03:00
return status ;
}
2011-01-28 11:45:44 +03:00
NTSTATUS dcerpc_winreg_set_sz ( TALLOC_CTX * mem_ctx ,
struct dcerpc_binding_handle * h ,
struct policy_handle * key_handle ,
const char * value ,
const char * data ,
WERROR * pwerr )
{
2011-03-15 13:04:23 +03:00
struct winreg_String wvalue = { 0 , } ;
2011-01-28 11:45:44 +03:00
DATA_BLOB blob ;
NTSTATUS status ;
wvalue . name = value ;
if ( data = = NULL ) {
blob = data_blob_string_const ( " " ) ;
} else {
if ( ! push_reg_sz ( mem_ctx , & blob , data ) ) {
DEBUG ( 2 , ( " dcerpc_winreg_set_sz: Could not marshall "
" string %s for %s \n " ,
data , wvalue . name ) ) ;
2011-07-06 14:19:05 +04:00
return NT_STATUS_NO_MEMORY ;
2011-01-28 11:45:44 +03:00
}
}
status = dcerpc_winreg_SetValue ( h ,
mem_ctx ,
key_handle ,
wvalue ,
REG_SZ ,
blob . data ,
blob . length ,
2011-07-04 13:59:36 +04:00
pwerr ) ;
2011-01-28 11:45:44 +03:00
return status ;
}
2011-01-28 11:50:48 +03:00
NTSTATUS dcerpc_winreg_set_expand_sz ( TALLOC_CTX * mem_ctx ,
struct dcerpc_binding_handle * h ,
struct policy_handle * key_handle ,
const char * value ,
const char * data ,
WERROR * pwerr )
{
2011-03-15 12:52:49 +03:00
struct winreg_String wvalue = { 0 , } ;
2011-01-28 11:50:48 +03:00
DATA_BLOB blob ;
NTSTATUS status ;
wvalue . name = value ;
if ( data = = NULL ) {
blob = data_blob_string_const ( " " ) ;
} else {
if ( ! push_reg_sz ( mem_ctx , & blob , data ) ) {
DEBUG ( 2 , ( " dcerpc_winreg_set_expand_sz: Could not marshall "
" string %s for %s \n " ,
data , wvalue . name ) ) ;
2011-07-06 14:19:05 +04:00
return NT_STATUS_NO_MEMORY ;
2011-01-28 11:50:48 +03:00
}
}
status = dcerpc_winreg_SetValue ( h ,
mem_ctx ,
key_handle ,
wvalue ,
REG_EXPAND_SZ ,
blob . data ,
blob . length ,
2011-07-04 13:59:36 +04:00
pwerr ) ;
2011-01-28 11:50:48 +03:00
return status ;
}
2011-01-28 11:57:41 +03:00
NTSTATUS dcerpc_winreg_set_multi_sz ( TALLOC_CTX * mem_ctx ,
struct dcerpc_binding_handle * h ,
struct policy_handle * key_handle ,
const char * value ,
const char * * data ,
WERROR * pwerr )
{
2011-03-16 19:17:47 +03:00
struct winreg_String wvalue = { 0 , } ;
2011-01-28 11:57:41 +03:00
DATA_BLOB blob ;
NTSTATUS status ;
wvalue . name = value ;
if ( ! push_reg_multi_sz ( mem_ctx , & blob , data ) ) {
DEBUG ( 2 , ( " dcerpc_winreg_set_multi_sz: Could not marshall "
" string multi sz for %s \n " ,
wvalue . name ) ) ;
2011-07-06 14:19:05 +04:00
return NT_STATUS_NO_MEMORY ;
2011-01-28 11:57:41 +03:00
}
status = dcerpc_winreg_SetValue ( h ,
mem_ctx ,
key_handle ,
wvalue ,
REG_MULTI_SZ ,
blob . data ,
blob . length ,
2011-07-04 13:59:36 +04:00
pwerr ) ;
2011-01-28 11:57:41 +03:00
return status ;
}
2011-01-31 20:35:06 +03:00
NTSTATUS dcerpc_winreg_set_binary ( TALLOC_CTX * mem_ctx ,
struct dcerpc_binding_handle * h ,
struct policy_handle * key_handle ,
const char * value ,
DATA_BLOB * data ,
WERROR * pwerr )
{
2011-03-15 13:09:26 +03:00
struct winreg_String wvalue = { 0 , } ;
2011-01-31 20:35:06 +03:00
NTSTATUS status ;
wvalue . name = value ;
status = dcerpc_winreg_SetValue ( h ,
mem_ctx ,
key_handle ,
wvalue ,
REG_BINARY ,
data - > data ,
data - > length ,
2011-07-04 13:59:36 +04:00
pwerr ) ;
2011-01-31 20:35:06 +03:00
return status ;
}
2011-01-31 20:40:06 +03:00
NTSTATUS dcerpc_winreg_set_sd ( TALLOC_CTX * mem_ctx ,
struct dcerpc_binding_handle * h ,
struct policy_handle * key_handle ,
const char * value ,
const struct security_descriptor * data ,
WERROR * pwerr )
{
enum ndr_err_code ndr_err ;
DATA_BLOB blob ;
ndr_err = ndr_push_struct_blob ( & blob ,
mem_ctx ,
data ,
( ndr_push_flags_fn_t ) ndr_push_security_descriptor ) ;
if ( ! NDR_ERR_CODE_IS_SUCCESS ( ndr_err ) ) {
DEBUG ( 2 , ( " dcerpc_winreg_set_sd: Failed to marshall security "
" descriptor \n " ) ) ;
2011-07-06 14:19:05 +04:00
return NT_STATUS_NO_MEMORY ;
2011-01-31 20:40:06 +03:00
}
return dcerpc_winreg_set_binary ( mem_ctx ,
h ,
key_handle ,
value ,
& blob ,
pwerr ) ;
}
2011-01-28 12:43:49 +03:00
NTSTATUS dcerpc_winreg_add_multi_sz ( TALLOC_CTX * mem_ctx ,
struct dcerpc_binding_handle * h ,
struct policy_handle * key_handle ,
const char * value ,
const char * data ,
WERROR * pwerr )
{
const char * * a = NULL ;
const char * * p ;
uint32_t i ;
NTSTATUS status ;
status = dcerpc_winreg_query_multi_sz ( mem_ctx ,
h ,
key_handle ,
value ,
& a ,
2011-07-04 13:59:36 +04:00
pwerr ) ;
2011-01-28 12:43:49 +03:00
/* count the elements */
for ( p = a , i = 0 ; p & & * p ; p + + , i + + ) ;
2011-06-07 05:10:15 +04:00
p = talloc_realloc ( mem_ctx , a , const char * , i + 2 ) ;
2011-01-28 12:43:49 +03:00
if ( p = = NULL ) {
2011-07-06 14:19:05 +04:00
return NT_STATUS_NO_MEMORY ;
2011-01-28 12:43:49 +03:00
}
p [ i ] = data ;
p [ i + 1 ] = NULL ;
status = dcerpc_winreg_set_multi_sz ( mem_ctx ,
h ,
key_handle ,
value ,
p ,
pwerr ) ;
return status ;
}
2011-01-28 14:08:58 +03:00
NTSTATUS dcerpc_winreg_enum_keys ( TALLOC_CTX * mem_ctx ,
struct dcerpc_binding_handle * h ,
struct policy_handle * key_hnd ,
uint32_t * pnum_subkeys ,
const char * * * psubkeys ,
WERROR * pwerr )
{
const char * * subkeys ;
uint32_t num_subkeys , max_subkeylen , max_classlen ;
uint32_t num_values , max_valnamelen , max_valbufsize ;
uint32_t i ;
NTTIME last_changed_time ;
uint32_t secdescsize ;
struct winreg_String classname ;
NTSTATUS status ;
TALLOC_CTX * tmp_ctx ;
tmp_ctx = talloc_stackframe ( ) ;
if ( tmp_ctx = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
ZERO_STRUCT ( classname ) ;
status = dcerpc_winreg_QueryInfoKey ( h ,
tmp_ctx ,
key_hnd ,
& classname ,
& num_subkeys ,
& max_subkeylen ,
& max_classlen ,
& num_values ,
& max_valnamelen ,
& max_valbufsize ,
& secdescsize ,
& last_changed_time ,
2011-07-04 13:59:36 +04:00
pwerr ) ;
2011-01-28 14:08:58 +03:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
goto error ;
}
2011-07-04 13:59:36 +04:00
if ( ! W_ERROR_IS_OK ( * pwerr ) ) {
2011-01-28 14:08:58 +03:00
goto error ;
}
subkeys = talloc_zero_array ( tmp_ctx , const char * , num_subkeys + 2 ) ;
if ( subkeys = = NULL ) {
2011-07-06 14:19:05 +04:00
status = NT_STATUS_NO_MEMORY ;
2011-01-28 14:08:58 +03:00
goto error ;
}
if ( num_subkeys = = 0 ) {
subkeys [ 0 ] = talloc_strdup ( subkeys , " " ) ;
if ( subkeys [ 0 ] = = NULL ) {
2011-07-06 14:19:05 +04:00
status = NT_STATUS_NO_MEMORY ;
2011-01-28 14:08:58 +03:00
goto error ;
}
* pnum_subkeys = 0 ;
if ( psubkeys ) {
* psubkeys = talloc_move ( mem_ctx , & subkeys ) ;
}
TALLOC_FREE ( tmp_ctx ) ;
return NT_STATUS_OK ;
}
for ( i = 0 ; i < num_subkeys ; i + + ) {
char c = ' \0 ' ;
char n = ' \0 ' ;
char * name = NULL ;
struct winreg_StringBuf class_buf ;
struct winreg_StringBuf name_buf ;
NTTIME modtime ;
class_buf . name = & c ;
class_buf . size = max_classlen + 2 ;
class_buf . length = 0 ;
name_buf . name = & n ;
name_buf . size = max_subkeylen + 2 ;
name_buf . length = 0 ;
ZERO_STRUCT ( modtime ) ;
status = dcerpc_winreg_EnumKey ( h ,
tmp_ctx ,
key_hnd ,
i ,
& name_buf ,
& class_buf ,
& modtime ,
2011-07-04 13:59:36 +04:00
pwerr ) ;
2011-01-28 14:08:58 +03:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 5 , ( " dcerpc_winreg_enum_keys: Could not enumerate keys: %s \n " ,
nt_errstr ( status ) ) ) ;
goto error ;
}
2011-07-04 13:59:36 +04:00
if ( W_ERROR_EQUAL ( * pwerr , WERR_NO_MORE_ITEMS ) ) {
2011-01-28 14:08:58 +03:00
* pwerr = WERR_OK ;
break ;
}
2011-07-04 13:59:36 +04:00
if ( ! W_ERROR_IS_OK ( * pwerr ) ) {
2011-01-28 14:08:58 +03:00
DEBUG ( 5 , ( " dcerpc_winreg_enum_keys: Could not enumerate keys: %s \n " ,
2011-07-04 13:59:36 +04:00
win_errstr ( * pwerr ) ) ) ;
2011-01-28 14:08:58 +03:00
goto error ;
}
if ( name_buf . name = = NULL ) {
* pwerr = WERR_INVALID_PARAMETER ;
goto error ;
}
name = talloc_strdup ( subkeys , name_buf . name ) ;
if ( name = = NULL ) {
2011-07-06 14:19:05 +04:00
status = NT_STATUS_NO_MEMORY ;
2011-01-28 14:08:58 +03:00
goto error ;
}
subkeys [ i ] = name ;
}
* pnum_subkeys = num_subkeys ;
if ( psubkeys ) {
* psubkeys = talloc_move ( mem_ctx , & subkeys ) ;
}
error :
TALLOC_FREE ( tmp_ctx ) ;
return status ;
}
2011-07-12 20:37:31 +04:00
NTSTATUS dcerpc_winreg_enumvals ( TALLOC_CTX * mem_ctx ,
struct dcerpc_binding_handle * h ,
struct policy_handle * key_hnd ,
uint32_t * pnum_values ,
const char * * * pnames ,
enum winreg_Type * * _type ,
DATA_BLOB * * pdata ,
WERROR * pwerr )
{
2021-04-07 18:45:18 +03:00
TALLOC_CTX * tmp_ctx = talloc_stackframe ( ) ;
2011-07-12 20:37:31 +04:00
uint32_t num_subkeys = 0 , max_subkeylen = 0 , max_classlen = 0 ;
uint32_t num_values = 0 , max_valnamelen = 0 , max_valbufsize = 0 ;
uint32_t secdescsize = 0 ;
uint32_t i ;
NTTIME last_changed_time = 0 ;
2021-04-07 18:44:35 +03:00
struct winreg_String classname = { . name = NULL } ;
2011-07-12 20:37:31 +04:00
const char * * enum_names = NULL ;
enum winreg_Type * enum_types = NULL ;
DATA_BLOB * enum_data_blobs = NULL ;
WERROR result = WERR_OK ;
2019-09-17 17:20:03 +03:00
NTSTATUS status ;
2011-07-12 20:37:31 +04:00
status = dcerpc_winreg_QueryInfoKey ( h ,
tmp_ctx ,
key_hnd ,
& classname ,
& num_subkeys ,
& max_subkeylen ,
& max_classlen ,
& num_values ,
& max_valnamelen ,
& max_valbufsize ,
& secdescsize ,
& last_changed_time ,
& result ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 0 , ( " dcerpc_winreg_enumvals: Could not query info: %s \n " ,
nt_errstr ( status ) ) ) ;
goto error ;
}
if ( ! W_ERROR_IS_OK ( result ) ) {
DEBUG ( 0 , ( " dcerpc_winreg_enumvals: Could not query info: %s \n " ,
win_errstr ( result ) ) ) ;
* pwerr = result ;
goto error ;
}
if ( num_values = = 0 ) {
* pnum_values = 0 ;
TALLOC_FREE ( tmp_ctx ) ;
* pwerr = WERR_OK ;
return status ;
}
enum_names = talloc_zero_array ( tmp_ctx , const char * , num_values ) ;
if ( enum_names = = NULL ) {
2015-12-03 17:24:15 +03:00
* pwerr = WERR_NOT_ENOUGH_MEMORY ;
2011-07-12 20:37:31 +04:00
goto error ;
}
enum_types = talloc_zero_array ( tmp_ctx , enum winreg_Type , num_values ) ;
if ( enum_types = = NULL ) {
2015-12-03 17:24:15 +03:00
* pwerr = WERR_NOT_ENOUGH_MEMORY ;
2011-07-12 20:37:31 +04:00
goto error ;
}
enum_data_blobs = talloc_zero_array ( tmp_ctx , DATA_BLOB , num_values ) ;
if ( enum_data_blobs = = NULL ) {
2015-12-03 17:24:15 +03:00
* pwerr = WERR_NOT_ENOUGH_MEMORY ;
2011-07-12 20:37:31 +04:00
goto error ;
}
for ( i = 0 ; i < num_values ; i + + ) {
const char * name ;
struct winreg_ValNameBuf name_buf ;
enum winreg_Type type = REG_NONE ;
uint8_t * data ;
uint32_t data_size ;
uint32_t length ;
char n = ' \0 ' ;
name_buf . name = & n ;
name_buf . size = max_valnamelen + 2 ;
name_buf . length = 0 ;
data_size = max_valbufsize ;
data = NULL ;
if ( data_size ) {
data = ( uint8_t * ) TALLOC ( tmp_ctx , data_size ) ;
}
length = 0 ;
status = dcerpc_winreg_EnumValue ( h ,
tmp_ctx ,
key_hnd ,
i ,
& name_buf ,
& type ,
data ,
data_size ? & data_size : NULL ,
& length ,
& result ) ;
if ( W_ERROR_EQUAL ( result , WERR_NO_MORE_ITEMS ) ) {
result = WERR_OK ;
status = NT_STATUS_OK ;
break ;
}
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 0 , ( " dcerpc_winreg_enumvals: Could not enumerate values: %s \n " ,
nt_errstr ( status ) ) ) ;
goto error ;
}
if ( ! W_ERROR_IS_OK ( result ) ) {
DEBUG ( 0 , ( " dcerpc_winreg_enumvals: Could not enumerate values: %s \n " ,
win_errstr ( result ) ) ) ;
* pwerr = result ;
goto error ;
}
if ( name_buf . name = = NULL ) {
result = WERR_INVALID_PARAMETER ;
* pwerr = result ;
goto error ;
}
name = talloc_strdup ( enum_names , name_buf . name ) ;
if ( name = = NULL ) {
2015-12-03 17:24:15 +03:00
result = WERR_NOT_ENOUGH_MEMORY ;
2011-07-12 20:37:31 +04:00
* pwerr = result ;
goto error ;
}
/* place name, type and datablob in the enum return params */
enum_data_blobs [ i ] = data_blob_talloc ( enum_data_blobs , data , length ) ;
enum_names [ i ] = name ;
enum_types [ i ] = type ;
}
/* move to the main mem context */
* pnum_values = num_values ;
if ( pnames ) {
* pnames = talloc_move ( mem_ctx , & enum_names ) ;
}
/* can this fail in any way? */
if ( _type ) {
* _type = talloc_move ( mem_ctx , & enum_types ) ;
}
if ( pdata ) {
* pdata = talloc_move ( mem_ctx , & enum_data_blobs ) ;
}
result = WERR_OK ;
error :
TALLOC_FREE ( tmp_ctx ) ;
* pwerr = result ;
return status ;
}
2011-07-12 20:38:14 +04:00
NTSTATUS dcerpc_winreg_delete_subkeys_recursive ( TALLOC_CTX * mem_ctx ,
struct dcerpc_binding_handle * h ,
struct policy_handle * hive_handle ,
uint32_t access_mask ,
const char * key ,
WERROR * pwerr )
{
const char * * subkeys = NULL ;
uint32_t num_subkeys = 0 ;
struct policy_handle key_hnd ;
struct winreg_String wkey = { 0 , } ;
WERROR result = WERR_OK ;
2019-09-17 17:20:03 +03:00
NTSTATUS status ;
2011-07-12 20:38:14 +04:00
uint32_t i ;
ZERO_STRUCT ( key_hnd ) ;
wkey . name = key ;
DEBUG ( 2 , ( " dcerpc_winreg_delete_subkeys_recursive: delete key %s \n " , key ) ) ;
/* open the key */
status = dcerpc_winreg_OpenKey ( h ,
mem_ctx ,
hive_handle ,
wkey ,
0 ,
access_mask ,
& key_hnd ,
& result ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 0 , ( " dcerpc_winreg_delete_subkeys_recursive: Could not open key %s: %s \n " ,
wkey . name , nt_errstr ( status ) ) ) ;
goto done ;
}
if ( ! W_ERROR_IS_OK ( result ) ) {
DEBUG ( 0 , ( " dcerpc_winreg_delete_subkeys_recursive: Could not open key %s: %s \n " ,
wkey . name , win_errstr ( result ) ) ) ;
* pwerr = result ;
goto done ;
}
status = dcerpc_winreg_enum_keys ( mem_ctx ,
h ,
& key_hnd ,
& num_subkeys ,
& subkeys ,
& result ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
goto done ;
}
if ( ! W_ERROR_IS_OK ( result ) ) {
goto done ;
}
for ( i = 0 ; i < num_subkeys ; i + + ) {
/* create key + subkey */
char * subkey = talloc_asprintf ( mem_ctx , " %s \\ %s " , key , subkeys [ i ] ) ;
if ( subkey = = NULL ) {
goto done ;
}
DEBUG ( 2 , ( " dcerpc_winreg_delete_subkeys_recursive: delete subkey %s \n " , subkey ) ) ;
status = dcerpc_winreg_delete_subkeys_recursive ( mem_ctx ,
h ,
hive_handle ,
access_mask ,
subkey ,
& result ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
goto done ;
}
}
if ( is_valid_policy_hnd ( & key_hnd ) ) {
WERROR ignore ;
dcerpc_winreg_CloseKey ( h , mem_ctx , & key_hnd , & ignore ) ;
}
wkey . name = key ;
status = dcerpc_winreg_DeleteKey ( h ,
mem_ctx ,
hive_handle ,
wkey ,
& result ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
* pwerr = result ;
goto done ;
}
done :
if ( is_valid_policy_hnd ( & key_hnd ) ) {
WERROR ignore ;
dcerpc_winreg_CloseKey ( h , mem_ctx , & key_hnd , & ignore ) ;
}
* pwerr = result ;
return status ;
}
2011-01-27 17:20:58 +03:00
/* vim: set ts=8 sw=8 noet cindent syntax=c.doxygen: */