mirror of
https://github.com/samba-team/samba.git
synced 2024-12-27 03:21:53 +03:00
r19006: Final cleanups for the winreg libmsrpc functions.
Needs thorough testing but the code has been adapted to the new rpccli_winreg_XX() API.
This commit is contained in:
parent
d086babf9d
commit
c3d1c3ca4d
@ -233,7 +233,10 @@ int cac_RegEnumKeys( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
|
||||
if ( !hnd )
|
||||
return CAC_FAILURE;
|
||||
|
||||
/*this is to avoid useless rpc calls, if the last call exhausted all the keys, then we don't need to go through everything again */
|
||||
/* This is to avoid useless rpc calls, if the last call
|
||||
exhausted all the keys, then we don't need to go
|
||||
through everything again */
|
||||
|
||||
if ( NT_STATUS_V( hnd->status ) ==
|
||||
NT_STATUS_V( NT_STATUS_GUIDS_EXHAUSTED ) )
|
||||
return CAC_FAILURE;
|
||||
@ -254,7 +257,9 @@ int cac_RegEnumKeys( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
|
||||
return CAC_FAILURE;
|
||||
}
|
||||
|
||||
/**the only way to know how many keys to expect is to assume max_keys keys will be found*/
|
||||
/* The only way to know how many keys to expect is to
|
||||
assume max_keys keys will be found */
|
||||
|
||||
key_names_out = TALLOC_ARRAY( mem_ctx, char *, op->in.max_keys );
|
||||
if ( !key_names_out ) {
|
||||
hnd->status = NT_STATUS_NO_MEMORY;
|
||||
@ -280,16 +285,14 @@ int cac_RegEnumKeys( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
|
||||
resume_idx = op->out.resume_idx;
|
||||
|
||||
do {
|
||||
#if 0 /* FIXME!!! */
|
||||
|
||||
#if 0
|
||||
hnd->status =
|
||||
rpccli_winreg_EnumKey( pipe_hnd, mem_ctx, op->in.key,
|
||||
resume_idx, key_name_in,
|
||||
class_name_in,
|
||||
&mod_times_out
|
||||
[num_keys_out] );
|
||||
|
||||
&mod_times_out );
|
||||
#endif
|
||||
|
||||
if ( !NT_STATUS_IS_OK( hnd->status ) ) {
|
||||
/*don't increment any values */
|
||||
break;
|
||||
@ -391,36 +394,67 @@ int cac_RegCreateKey( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
|
||||
|
||||
}
|
||||
|
||||
WERROR cac_delete_subkeys_recursive( struct rpc_pipe_client * pipe_hnd,
|
||||
NTSTATUS cac_delete_subkeys_recursive( struct rpc_pipe_client * pipe_hnd,
|
||||
TALLOC_CTX * mem_ctx, POLICY_HND * key )
|
||||
{
|
||||
/*NOTE: using cac functions might result in a big(ger) memory bloat, and would probably be far less efficient
|
||||
* so we use the cli_reg functions directly*/
|
||||
|
||||
WERROR err = WERR_OK;
|
||||
|
||||
POLICY_HND subkey;
|
||||
fstring subkey_name;
|
||||
fstring class_buf;
|
||||
time_t mod_time_buf;
|
||||
|
||||
int cur_key = 0;
|
||||
NTSTATUS status;
|
||||
uint32 num_subkeys, max_subkeylen, max_classlen;
|
||||
uint32 num_values, max_valnamelen, maxvalbufsize;
|
||||
char *name_buffer;
|
||||
struct winreg_String class_string;
|
||||
|
||||
while ( W_ERROR_IS_OK( err ) ) {
|
||||
NTTIME modtime;
|
||||
uint32 secdescsize;
|
||||
|
||||
/* First get the max subkey name length */
|
||||
|
||||
class_string.name = NULL;
|
||||
status = rpccli_winreg_QueryInfoKey( pipe_hnd, mem_ctx, key,
|
||||
&class_string, &num_subkeys,
|
||||
&max_subkeylen, &max_classlen,
|
||||
&num_values, &max_valnamelen,
|
||||
&maxvalbufsize, &secdescsize,
|
||||
&modtime );
|
||||
|
||||
|
||||
if ( !NT_STATUS_IS_OK( status ) ) {
|
||||
return status;
|
||||
}
|
||||
|
||||
if ( (name_buffer = TALLOC_ARRAY( mem_ctx, char, max_subkeylen )) == NULL ) {
|
||||
d_fprintf(stderr, "Memory allocation error.\n");
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
|
||||
while ( NT_STATUS_IS_OK( status ) ) {
|
||||
struct winreg_String key_string;
|
||||
NTSTATUS status;
|
||||
struct winreg_StringBuf subkey_string;
|
||||
fstring subkeyname;
|
||||
|
||||
#if 0 /* FIXME!!! */
|
||||
status = rpccli_winreg_enum_key( pipe_hnd, mem_ctx, key,
|
||||
cur_key, subkey_name,
|
||||
class_buf, &mod_time_buf );
|
||||
#endif
|
||||
memset( name_buffer, 0x0, max_subkeylen );
|
||||
subkey_string.name = name_buffer;
|
||||
subkey_string.length = 0;
|
||||
subkey_string.size = max_subkeylen;
|
||||
|
||||
status = rpccli_winreg_EnumKey(pipe_hnd, mem_ctx, key, cur_key,
|
||||
&subkey_string, NULL, NULL);
|
||||
|
||||
if ( !NT_STATUS_IS_OK( status ) )
|
||||
break;
|
||||
|
||||
/* copy the keyname and add the terminating NULL */
|
||||
|
||||
StrnCpy( subkeyname, subkey_string.name,
|
||||
MIN(subkey_string.length, sizeof(subkeyname)-1) );
|
||||
subkeyname[MIN(subkey_string.length, sizeof(subkeyname)-1)] = '\0';
|
||||
|
||||
/*try to open the key with full access */
|
||||
key_string.name = subkey_name;
|
||||
|
||||
key_string.name = subkeyname;
|
||||
status = rpccli_winreg_OpenKey( pipe_hnd, mem_ctx, key,
|
||||
key_string, 0, REG_KEY_ALL,
|
||||
&subkey );
|
||||
@ -428,11 +462,11 @@ WERROR cac_delete_subkeys_recursive( struct rpc_pipe_client * pipe_hnd,
|
||||
if ( !NT_STATUS_IS_OK( status ) )
|
||||
break;
|
||||
|
||||
err = cac_delete_subkeys_recursive( pipe_hnd, mem_ctx,
|
||||
status = cac_delete_subkeys_recursive( pipe_hnd, mem_ctx,
|
||||
&subkey );
|
||||
|
||||
if ( !W_ERROR_EQUAL( err, WERR_NO_MORE_ITEMS )
|
||||
&& !W_ERROR_IS_OK( err ) )
|
||||
if ( !W_ERROR_EQUAL( ntstatus_to_werror(status), WERR_NO_MORE_ITEMS )
|
||||
&& !NT_STATUS_IS_OK( status ) )
|
||||
break;
|
||||
|
||||
/*flush the key just to be safe */
|
||||
@ -445,14 +479,12 @@ WERROR cac_delete_subkeys_recursive( struct rpc_pipe_client * pipe_hnd,
|
||||
key_string.name = subkey_name;
|
||||
status = rpccli_winreg_DeleteKey( pipe_hnd, mem_ctx, key,
|
||||
key_string );
|
||||
err = ntstatus_to_werror( status );
|
||||
|
||||
|
||||
cur_key++;
|
||||
}
|
||||
|
||||
|
||||
return err;
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
@ -461,7 +493,6 @@ int cac_RegDeleteKey( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
|
||||
struct RegDeleteKey *op )
|
||||
{
|
||||
struct rpc_pipe_client *pipe_hnd = NULL;
|
||||
WERROR err;
|
||||
struct winreg_String key_string;
|
||||
|
||||
if ( !hnd )
|
||||
@ -484,7 +515,10 @@ int cac_RegDeleteKey( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
|
||||
}
|
||||
|
||||
if ( op->in.recursive ) {
|
||||
/*first open the key, and then delete all of it's subkeys recursively */
|
||||
|
||||
/* first open the key, and then delete all of
|
||||
it's subkeys recursively */
|
||||
|
||||
struct RegOpenKey rok;
|
||||
|
||||
ZERO_STRUCT( rok );
|
||||
@ -496,14 +530,12 @@ int cac_RegDeleteKey( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
|
||||
if ( !cac_RegOpenKey( hnd, mem_ctx, &rok ) )
|
||||
return CAC_FAILURE;
|
||||
|
||||
err = cac_delete_subkeys_recursive( pipe_hnd, mem_ctx,
|
||||
hnd->status = cac_delete_subkeys_recursive( pipe_hnd, mem_ctx,
|
||||
rok.out.key );
|
||||
|
||||
/*close the key that we opened */
|
||||
cac_RegClose( hnd, mem_ctx, rok.out.key );
|
||||
|
||||
hnd->status = werror_to_ntstatus( err );
|
||||
|
||||
if ( NT_STATUS_V( hnd->status ) !=
|
||||
NT_STATUS_V( NT_STATUS_GUIDS_EXHAUSTED )
|
||||
&& !NT_STATUS_IS_OK( hnd->status ) )
|
||||
@ -561,21 +593,10 @@ int cac_RegDeleteValue( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
|
||||
return CAC_SUCCESS;
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
/* JRA - disabled until fix. */
|
||||
|
||||
/* This code is currently broken so disable it - it needs to handle the ERROR_MORE_DATA
|
||||
cleanly and resubmit the query. */
|
||||
|
||||
int cac_RegQueryKeyInfo( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
|
||||
struct RegQueryKeyInfo *op )
|
||||
{
|
||||
struct rpc_pipe_client *pipe_hnd = NULL;
|
||||
WERROR err;
|
||||
|
||||
char *class_name_out = NULL;
|
||||
uint32 class_len = 0;
|
||||
uint32 num_subkeys_out = 0;
|
||||
uint32 long_subkey_out = 0;
|
||||
uint32 long_class_out = 0;
|
||||
@ -584,6 +605,7 @@ int cac_RegQueryKeyInfo( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
|
||||
uint32 long_data_out = 0;
|
||||
uint32 secdesc_size = 0;
|
||||
NTTIME mod_time;
|
||||
struct winreg_String class_string;
|
||||
|
||||
if ( !hnd )
|
||||
return CAC_FAILURE;
|
||||
@ -604,35 +626,24 @@ int cac_RegQueryKeyInfo( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
|
||||
return CAC_FAILURE;
|
||||
}
|
||||
|
||||
err = rpccli_reg_query_key( pipe_hnd, mem_ctx, op->in.key,
|
||||
class_name_out,
|
||||
&class_len,
|
||||
&num_subkeys_out,
|
||||
&long_subkey_out,
|
||||
&long_class_out,
|
||||
&num_values_out,
|
||||
&long_value_out,
|
||||
&long_data_out,
|
||||
&secdesc_size, &mod_time );
|
||||
|
||||
hnd->status = werror_to_ntstatus( err );
|
||||
hnd->status = rpccli_winreg_QueryInfoKey( pipe_hnd, mem_ctx,
|
||||
op->in.key,
|
||||
&class_string,
|
||||
&num_subkeys_out,
|
||||
&long_subkey_out,
|
||||
&long_class_out,
|
||||
&num_values_out,
|
||||
&long_value_out,
|
||||
&long_data_out,
|
||||
&secdesc_size, &mod_time );
|
||||
|
||||
if ( !NT_STATUS_IS_OK( hnd->status ) )
|
||||
return CAC_FAILURE;
|
||||
|
||||
if ( !class_name_out ) {
|
||||
if ( !class_string.name ) {
|
||||
op->out.class_name = talloc_strdup( mem_ctx, "" );
|
||||
} else if ( class_len != 0 && class_name_out[class_len - 1] != '\0' ) {
|
||||
/*then we need to add a '\0' */
|
||||
op->out.class_name =
|
||||
talloc_size( mem_ctx,
|
||||
sizeof( char ) * ( class_len + 1 ) );
|
||||
|
||||
memcpy( op->out.class_name, class_name_out, class_len );
|
||||
|
||||
op->out.class_name[class_len] = '\0';
|
||||
} else { /*then everything worked out fine in the function */
|
||||
op->out.class_name = talloc_strdup( mem_ctx, class_name_out );
|
||||
} else {
|
||||
op->out.class_name = talloc_strdup( mem_ctx, class_string.name );
|
||||
}
|
||||
|
||||
if ( !op->out.class_name ) {
|
||||
@ -647,11 +658,10 @@ int cac_RegQueryKeyInfo( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
|
||||
op->out.longest_value_name = long_value_out;
|
||||
op->out.longest_value_data = long_data_out;
|
||||
op->out.security_desc_size = secdesc_size;
|
||||
op->out.last_write_time = nt_time_to_unix( &mod_time );
|
||||
op->out.last_write_time = nt_time_to_unix( mod_time );
|
||||
|
||||
return CAC_FAILURE;
|
||||
}
|
||||
#endif
|
||||
|
||||
int cac_RegQueryValue( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
|
||||
struct RegQueryValue *op )
|
||||
@ -721,22 +731,27 @@ int cac_RegEnumValues( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
|
||||
struct RegEnumValues *op )
|
||||
{
|
||||
struct rpc_pipe_client *pipe_hnd = NULL;
|
||||
|
||||
/*buffers for rpccli_reg_enum_key call */
|
||||
fstring val_name_buf;
|
||||
char *name_buffer;
|
||||
REGVAL_BUFFER val_buf;
|
||||
|
||||
/*output buffers */
|
||||
uint32 *types_out = NULL;
|
||||
REG_VALUE_DATA **values_out = NULL;
|
||||
char **val_names_out = NULL;
|
||||
uint32 num_values_out = 0;
|
||||
uint32 resume_idx = 0;
|
||||
uint32 num_subkeys, max_subkeylen, max_classlen;
|
||||
uint32 num_values, max_valnamelen, maxvalbufsize;
|
||||
struct winreg_String class_string;
|
||||
NTTIME modtime;
|
||||
uint32 secdescsize;
|
||||
uint8 *buffer;
|
||||
|
||||
if ( !hnd )
|
||||
return CAC_FAILURE;
|
||||
|
||||
/*this is to avoid useless rpc calls, if the last call exhausted all the keys, then we don't need to go through everything again */
|
||||
/* This is to avoid useless rpc calls, if the last
|
||||
call exhausted all the keys, then we don't need
|
||||
to go through everything again */
|
||||
|
||||
if ( NT_STATUS_V( hnd->status ) ==
|
||||
NT_STATUS_V( NT_STATUS_GUIDS_EXHAUSTED ) )
|
||||
return CAC_FAILURE;
|
||||
@ -758,15 +773,16 @@ int cac_RegEnumValues( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
|
||||
}
|
||||
|
||||
/*we need to assume that the max number of values will be enumerated */
|
||||
types_out =
|
||||
( uint32 * ) talloc_array( mem_ctx, int, op->in.max_values );
|
||||
types_out = talloc_array( mem_ctx, uint32, op->in.max_values );
|
||||
|
||||
if ( !types_out ) {
|
||||
hnd->status = NT_STATUS_NO_MEMORY;
|
||||
return CAC_FAILURE;
|
||||
}
|
||||
|
||||
values_out =
|
||||
talloc_array( mem_ctx, REG_VALUE_DATA *, op->in.max_values );
|
||||
values_out = talloc_array( mem_ctx, REG_VALUE_DATA *,
|
||||
op->in.max_values );
|
||||
|
||||
if ( !values_out ) {
|
||||
TALLOC_FREE( types_out );
|
||||
hnd->status = NT_STATUS_NO_MEMORY;
|
||||
@ -774,6 +790,7 @@ int cac_RegEnumValues( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
|
||||
}
|
||||
|
||||
val_names_out = talloc_array( mem_ctx, char *, op->in.max_values );
|
||||
|
||||
if ( !val_names_out ) {
|
||||
TALLOC_FREE( types_out );
|
||||
TALLOC_FREE( values_out );
|
||||
@ -782,26 +799,65 @@ int cac_RegEnumValues( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
|
||||
}
|
||||
|
||||
resume_idx = op->out.resume_idx;
|
||||
do {
|
||||
ZERO_STRUCT( val_buf );
|
||||
|
||||
#if 0
|
||||
hnd->status =
|
||||
rpccli_winreg_enum_val( pipe_hnd, mem_ctx, op->in.key,
|
||||
resume_idx, val_name_buf,
|
||||
&types_out[num_values_out],
|
||||
&val_buf );
|
||||
#endif
|
||||
class_string.name = NULL;
|
||||
hnd->status = rpccli_winreg_QueryInfoKey( pipe_hnd, mem_ctx, op->in.key,
|
||||
&class_string, &num_subkeys,
|
||||
&max_subkeylen, &max_classlen,
|
||||
&num_values, &max_valnamelen,
|
||||
&maxvalbufsize, &secdescsize,
|
||||
&modtime );
|
||||
|
||||
if ( !NT_STATUS_IS_OK(hnd->status) ) {
|
||||
TALLOC_FREE( types_out );
|
||||
TALLOC_FREE( values_out );
|
||||
|
||||
return CAC_FAILURE;
|
||||
}
|
||||
|
||||
if ( (buffer = TALLOC_ARRAY( mem_ctx, uint8, maxvalbufsize )) == NULL ) {
|
||||
TALLOC_FREE( types_out );
|
||||
TALLOC_FREE( values_out );
|
||||
hnd->status = NT_STATUS_NO_MEMORY;
|
||||
|
||||
return CAC_FAILURE;
|
||||
}
|
||||
|
||||
if ( (name_buffer = TALLOC_ARRAY(mem_ctx, char, max_valnamelen)) == NULL ) {
|
||||
TALLOC_FREE( types_out );
|
||||
TALLOC_FREE( values_out );
|
||||
TALLOC_FREE( buffer );
|
||||
hnd->status = NT_STATUS_NO_MEMORY;
|
||||
|
||||
return CAC_FAILURE;
|
||||
}
|
||||
|
||||
do {
|
||||
uint32 data_size = maxvalbufsize;
|
||||
uint32 data_length = 0;
|
||||
struct winreg_StringBuf name_buf;
|
||||
|
||||
memset( name_buffer, 0x0, max_valnamelen );
|
||||
name_buf.name = name_buffer;
|
||||
name_buf.size = max_valnamelen;
|
||||
name_buf.length = 0;
|
||||
|
||||
hnd->status = rpccli_winreg_EnumValue( pipe_hnd, mem_ctx,
|
||||
op->in.key,
|
||||
resume_idx, &name_buf,
|
||||
&types_out[num_values_out],
|
||||
buffer, &data_size, &data_length );
|
||||
|
||||
if ( !NT_STATUS_IS_OK( hnd->status ) )
|
||||
break;
|
||||
|
||||
values_out[num_values_out] =
|
||||
cac_MakeRegValueData( mem_ctx,
|
||||
types_out[num_values_out],
|
||||
val_buf );
|
||||
val_names_out[num_values_out] =
|
||||
talloc_strdup( mem_ctx, val_name_buf );
|
||||
ZERO_STRUCT( val_buf );
|
||||
init_regval_buffer( &val_buf, buffer, data_length );
|
||||
|
||||
values_out[num_values_out] = cac_MakeRegValueData( mem_ctx,
|
||||
types_out[num_values_out],
|
||||
val_buf );
|
||||
val_names_out[num_values_out] = TALLOC_ARRAY( mem_ctx, char, name_buf.length+1 );
|
||||
|
||||
if ( !val_names_out[num_values_out]
|
||||
|| !values_out[num_values_out] ) {
|
||||
@ -809,6 +865,9 @@ int cac_RegEnumValues( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
|
||||
break;
|
||||
}
|
||||
|
||||
StrnCpy( val_names_out[num_values_out], name_buf.name, name_buf.length );
|
||||
(val_names_out[num_values_out])[name_buf.length] = '\0';
|
||||
|
||||
num_values_out++;
|
||||
resume_idx++;
|
||||
} while ( num_values_out < op->in.max_values );
|
||||
@ -954,7 +1013,8 @@ int cac_RegGetKeySecurity( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
|
||||
if ( !NT_STATUS_IS_OK( hnd->status ) ) {
|
||||
return CAC_FAILURE;
|
||||
}
|
||||
#if 0 /* FIX ME!!!! unmarshall the security descriptor */
|
||||
|
||||
#if 0 /* FIX ME!!!! unmarshall the security descriptor */
|
||||
op->out.size = buf.sd_size;
|
||||
op->out.descriptor = dup_sec_desc( mem_ctx, buf.sd );
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user