summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGerald Carter <jerry@samba.org>2006-09-29 20:31:09 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 12:14:56 -0500
commitff8f68840d78e8ffad2dcc09d404ee30b852f228 (patch)
treefbc7b0b42eaf1d8f2c20aee9cf6736605c27cf3a
parent88a98e35c780b1665bc21006b9c8c096e6b06f3f (diff)
downloadsamba-ff8f68840d78e8ffad2dcc09d404ee30b852f228.tar.gz
samba-ff8f68840d78e8ffad2dcc09d404ee30b852f228.tar.bz2
samba-ff8f68840d78e8ffad2dcc09d404ee30b852f228.zip
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 used to be commit c3d1c3ca4d9b23bdbba131563c751b8e0dc4c01f)
-rw-r--r--source3/libmsrpc/cac_winreg.c256
1 files changed, 158 insertions, 98 deletions
diff --git a/source3/libmsrpc/cac_winreg.c b/source3/libmsrpc/cac_winreg.c
index d52f319cb7..4836e01893 100644
--- a/source3/libmsrpc/cac_winreg.c
+++ b/source3/libmsrpc/cac_winreg.c
@@ -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;
+
+ NTTIME modtime;
+ uint32 secdescsize;
- while ( W_ERROR_IS_OK( err ) ) {
+ /* 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