1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-28 07:21:54 +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:
Gerald Carter 2006-09-29 20:31:09 +00:00 committed by Gerald (Jerry) Carter
parent d086babf9d
commit c3d1c3ca4d

View File

@ -233,7 +233,10 @@ int cac_RegEnumKeys( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
if ( !hnd ) if ( !hnd )
return CAC_FAILURE; 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 ) == if ( NT_STATUS_V( hnd->status ) ==
NT_STATUS_V( NT_STATUS_GUIDS_EXHAUSTED ) ) NT_STATUS_V( NT_STATUS_GUIDS_EXHAUSTED ) )
return CAC_FAILURE; return CAC_FAILURE;
@ -254,7 +257,9 @@ int cac_RegEnumKeys( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
return CAC_FAILURE; 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 ); key_names_out = TALLOC_ARRAY( mem_ctx, char *, op->in.max_keys );
if ( !key_names_out ) { if ( !key_names_out ) {
hnd->status = NT_STATUS_NO_MEMORY; 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; resume_idx = op->out.resume_idx;
do { do {
#if 0 /* FIXME!!! */ #if 0
hnd->status = hnd->status =
rpccli_winreg_EnumKey( pipe_hnd, mem_ctx, op->in.key, rpccli_winreg_EnumKey( pipe_hnd, mem_ctx, op->in.key,
resume_idx, key_name_in, resume_idx, key_name_in,
class_name_in, class_name_in,
&mod_times_out &mod_times_out );
[num_keys_out] );
#endif #endif
if ( !NT_STATUS_IS_OK( hnd->status ) ) { if ( !NT_STATUS_IS_OK( hnd->status ) ) {
/*don't increment any values */ /*don't increment any values */
break; 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 ) 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; POLICY_HND subkey;
fstring subkey_name; fstring subkey_name;
fstring class_buf;
time_t mod_time_buf;
int cur_key = 0; int cur_key = 0;
while ( W_ERROR_IS_OK( err ) ) {
struct winreg_String key_string;
NTSTATUS status; NTSTATUS status;
uint32 num_subkeys, max_subkeylen, max_classlen;
uint32 num_values, max_valnamelen, maxvalbufsize;
char *name_buffer;
struct winreg_String class_string;
#if 0 /* FIXME!!! */ NTTIME modtime;
status = rpccli_winreg_enum_key( pipe_hnd, mem_ctx, key, uint32 secdescsize;
cur_key, subkey_name,
class_buf, &mod_time_buf ); /* First get the max subkey name length */
#endif
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;
struct winreg_StringBuf subkey_string;
fstring subkeyname;
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 ) ) if ( !NT_STATUS_IS_OK( status ) )
break; 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 */ /*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, status = rpccli_winreg_OpenKey( pipe_hnd, mem_ctx, key,
key_string, 0, REG_KEY_ALL, key_string, 0, REG_KEY_ALL,
&subkey ); &subkey );
@ -428,11 +462,11 @@ WERROR cac_delete_subkeys_recursive( struct rpc_pipe_client * pipe_hnd,
if ( !NT_STATUS_IS_OK( status ) ) if ( !NT_STATUS_IS_OK( status ) )
break; break;
err = cac_delete_subkeys_recursive( pipe_hnd, mem_ctx, status = cac_delete_subkeys_recursive( pipe_hnd, mem_ctx,
&subkey ); &subkey );
if ( !W_ERROR_EQUAL( err, WERR_NO_MORE_ITEMS ) if ( !W_ERROR_EQUAL( ntstatus_to_werror(status), WERR_NO_MORE_ITEMS )
&& !W_ERROR_IS_OK( err ) ) && !NT_STATUS_IS_OK( status ) )
break; break;
/*flush the key just to be safe */ /*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; key_string.name = subkey_name;
status = rpccli_winreg_DeleteKey( pipe_hnd, mem_ctx, key, status = rpccli_winreg_DeleteKey( pipe_hnd, mem_ctx, key,
key_string ); key_string );
err = ntstatus_to_werror( status );
cur_key++; cur_key++;
} }
return err; return status;
} }
@ -461,7 +493,6 @@ int cac_RegDeleteKey( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
struct RegDeleteKey *op ) struct RegDeleteKey *op )
{ {
struct rpc_pipe_client *pipe_hnd = NULL; struct rpc_pipe_client *pipe_hnd = NULL;
WERROR err;
struct winreg_String key_string; struct winreg_String key_string;
if ( !hnd ) if ( !hnd )
@ -484,7 +515,10 @@ int cac_RegDeleteKey( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
} }
if ( op->in.recursive ) { 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; struct RegOpenKey rok;
ZERO_STRUCT( rok ); ZERO_STRUCT( rok );
@ -496,14 +530,12 @@ int cac_RegDeleteKey( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
if ( !cac_RegOpenKey( hnd, mem_ctx, &rok ) ) if ( !cac_RegOpenKey( hnd, mem_ctx, &rok ) )
return CAC_FAILURE; 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 ); rok.out.key );
/*close the key that we opened */ /*close the key that we opened */
cac_RegClose( hnd, mem_ctx, rok.out.key ); cac_RegClose( hnd, mem_ctx, rok.out.key );
hnd->status = werror_to_ntstatus( err );
if ( NT_STATUS_V( hnd->status ) != if ( NT_STATUS_V( hnd->status ) !=
NT_STATUS_V( NT_STATUS_GUIDS_EXHAUSTED ) NT_STATUS_V( NT_STATUS_GUIDS_EXHAUSTED )
&& !NT_STATUS_IS_OK( hnd->status ) ) && !NT_STATUS_IS_OK( hnd->status ) )
@ -561,21 +593,10 @@ int cac_RegDeleteValue( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
return CAC_SUCCESS; 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, int cac_RegQueryKeyInfo( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
struct RegQueryKeyInfo *op ) struct RegQueryKeyInfo *op )
{ {
struct rpc_pipe_client *pipe_hnd = NULL; struct rpc_pipe_client *pipe_hnd = NULL;
WERROR err;
char *class_name_out = NULL;
uint32 class_len = 0;
uint32 num_subkeys_out = 0; uint32 num_subkeys_out = 0;
uint32 long_subkey_out = 0; uint32 long_subkey_out = 0;
uint32 long_class_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 long_data_out = 0;
uint32 secdesc_size = 0; uint32 secdesc_size = 0;
NTTIME mod_time; NTTIME mod_time;
struct winreg_String class_string;
if ( !hnd ) if ( !hnd )
return CAC_FAILURE; return CAC_FAILURE;
@ -604,9 +626,9 @@ int cac_RegQueryKeyInfo( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
return CAC_FAILURE; return CAC_FAILURE;
} }
err = rpccli_reg_query_key( pipe_hnd, mem_ctx, op->in.key, hnd->status = rpccli_winreg_QueryInfoKey( pipe_hnd, mem_ctx,
class_name_out, op->in.key,
&class_len, &class_string,
&num_subkeys_out, &num_subkeys_out,
&long_subkey_out, &long_subkey_out,
&long_class_out, &long_class_out,
@ -615,24 +637,13 @@ int cac_RegQueryKeyInfo( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
&long_data_out, &long_data_out,
&secdesc_size, &mod_time ); &secdesc_size, &mod_time );
hnd->status = werror_to_ntstatus( err );
if ( !NT_STATUS_IS_OK( hnd->status ) ) if ( !NT_STATUS_IS_OK( hnd->status ) )
return CAC_FAILURE; return CAC_FAILURE;
if ( !class_name_out ) { if ( !class_string.name ) {
op->out.class_name = talloc_strdup( mem_ctx, "" ); op->out.class_name = talloc_strdup( mem_ctx, "" );
} else if ( class_len != 0 && class_name_out[class_len - 1] != '\0' ) { } else {
/*then we need to add a '\0' */ op->out.class_name = talloc_strdup( mem_ctx, class_string.name );
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 );
} }
if ( !op->out.class_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_name = long_value_out;
op->out.longest_value_data = long_data_out; op->out.longest_value_data = long_data_out;
op->out.security_desc_size = secdesc_size; 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; return CAC_FAILURE;
} }
#endif
int cac_RegQueryValue( CacServerHandle * hnd, TALLOC_CTX * mem_ctx, int cac_RegQueryValue( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
struct RegQueryValue *op ) struct RegQueryValue *op )
@ -721,22 +731,27 @@ int cac_RegEnumValues( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
struct RegEnumValues *op ) struct RegEnumValues *op )
{ {
struct rpc_pipe_client *pipe_hnd = NULL; struct rpc_pipe_client *pipe_hnd = NULL;
char *name_buffer;
/*buffers for rpccli_reg_enum_key call */
fstring val_name_buf;
REGVAL_BUFFER val_buf; REGVAL_BUFFER val_buf;
/*output buffers */
uint32 *types_out = NULL; uint32 *types_out = NULL;
REG_VALUE_DATA **values_out = NULL; REG_VALUE_DATA **values_out = NULL;
char **val_names_out = NULL; char **val_names_out = NULL;
uint32 num_values_out = 0; uint32 num_values_out = 0;
uint32 resume_idx = 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 ) if ( !hnd )
return CAC_FAILURE; 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 ) == if ( NT_STATUS_V( hnd->status ) ==
NT_STATUS_V( NT_STATUS_GUIDS_EXHAUSTED ) ) NT_STATUS_V( NT_STATUS_GUIDS_EXHAUSTED ) )
return CAC_FAILURE; 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 */ /*we need to assume that the max number of values will be enumerated */
types_out = types_out = talloc_array( mem_ctx, uint32, op->in.max_values );
( uint32 * ) talloc_array( mem_ctx, int, op->in.max_values );
if ( !types_out ) { if ( !types_out ) {
hnd->status = NT_STATUS_NO_MEMORY; hnd->status = NT_STATUS_NO_MEMORY;
return CAC_FAILURE; return CAC_FAILURE;
} }
values_out = values_out = talloc_array( mem_ctx, REG_VALUE_DATA *,
talloc_array( mem_ctx, REG_VALUE_DATA *, op->in.max_values ); op->in.max_values );
if ( !values_out ) { if ( !values_out ) {
TALLOC_FREE( types_out ); TALLOC_FREE( types_out );
hnd->status = NT_STATUS_NO_MEMORY; 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 ); val_names_out = talloc_array( mem_ctx, char *, op->in.max_values );
if ( !val_names_out ) { if ( !val_names_out ) {
TALLOC_FREE( types_out ); TALLOC_FREE( types_out );
TALLOC_FREE( values_out ); TALLOC_FREE( values_out );
@ -782,26 +799,65 @@ int cac_RegEnumValues( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
} }
resume_idx = op->out.resume_idx; resume_idx = op->out.resume_idx;
do {
ZERO_STRUCT( val_buf );
#if 0 class_string.name = NULL;
hnd->status = hnd->status = rpccli_winreg_QueryInfoKey( pipe_hnd, mem_ctx, op->in.key,
rpccli_winreg_enum_val( pipe_hnd, mem_ctx, op->in.key, &class_string, &num_subkeys,
resume_idx, val_name_buf, &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], &types_out[num_values_out],
&val_buf ); buffer, &data_size, &data_length );
#endif
if ( !NT_STATUS_IS_OK( hnd->status ) ) if ( !NT_STATUS_IS_OK( hnd->status ) )
break; break;
values_out[num_values_out] = ZERO_STRUCT( val_buf );
cac_MakeRegValueData( mem_ctx, init_regval_buffer( &val_buf, buffer, data_length );
values_out[num_values_out] = cac_MakeRegValueData( mem_ctx,
types_out[num_values_out], types_out[num_values_out],
val_buf ); val_buf );
val_names_out[num_values_out] = val_names_out[num_values_out] = TALLOC_ARRAY( mem_ctx, char, name_buf.length+1 );
talloc_strdup( mem_ctx, val_name_buf );
if ( !val_names_out[num_values_out] if ( !val_names_out[num_values_out]
|| !values_out[num_values_out] ) { || !values_out[num_values_out] ) {
@ -809,6 +865,9 @@ int cac_RegEnumValues( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
break; 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++; num_values_out++;
resume_idx++; resume_idx++;
} while ( num_values_out < op->in.max_values ); } while ( num_values_out < op->in.max_values );
@ -954,6 +1013,7 @@ int cac_RegGetKeySecurity( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
if ( !NT_STATUS_IS_OK( hnd->status ) ) { if ( !NT_STATUS_IS_OK( hnd->status ) ) {
return CAC_FAILURE; 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.size = buf.sd_size;
op->out.descriptor = dup_sec_desc( mem_ctx, buf.sd ); op->out.descriptor = dup_sec_desc( mem_ctx, buf.sd );