svn commit: samba r19006 - in branches/SAMBA_3_0/source/libmsrpc: .

jerry at samba.org jerry at samba.org
Fri Sep 29 20:31:09 GMT 2006


Author: jerry
Date: 2006-09-29 20:31:09 +0000 (Fri, 29 Sep 2006)
New Revision: 19006

WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=19006

Log:
Final cleanups for the winreg libmsrpc functions.
Needs thorough testing but the code has been adapted
to the new rpccli_winreg_XX() API.





Modified:
   branches/SAMBA_3_0/source/libmsrpc/cac_winreg.c


Changeset:
Modified: branches/SAMBA_3_0/source/libmsrpc/cac_winreg.c
===================================================================
--- branches/SAMBA_3_0/source/libmsrpc/cac_winreg.c	2006-09-29 19:44:08 UTC (rev 19005)
+++ branches/SAMBA_3_0/source/libmsrpc/cac_winreg.c	2006-09-29 20:31:09 UTC (rev 19006)
@@ -233,7 +233,10 @@
 	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 @@
 		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 @@
 	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
 
-#endif
 		if ( !NT_STATUS_IS_OK( hnd->status ) ) {
 			/*don't increment any values */
 			break;
@@ -391,36 +394,67 @@
 
 }
 
-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 @@
 		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 @@
 		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 @@
 		      struct RegDeleteKey *op )
 {
 	struct rpc_pipe_client *pipe_hnd = NULL;
-	WERROR err;
 	struct winreg_String key_string;
 
 	if ( !hnd )
@@ -484,7 +515,10 @@
 	}
 
 	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 @@
 		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 @@
 	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 @@
 	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 @@
 		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 = 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 );
 
-	hnd->status = werror_to_ntstatus( err );
-
 	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 @@
 	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 @@
 		       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 @@
 	}
 
 	/*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 @@
 	}
 
 	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,33 +799,75 @@
 	}
 
 	resume_idx = op->out.resume_idx;
+
+	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 {
-		ZERO_STRUCT( val_buf );
+		uint32 data_size = maxvalbufsize;
+		uint32 data_length = 0;
+		struct winreg_StringBuf name_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
+		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] ) {
 			hnd->status = NT_STATUS_NO_MEMORY;
 			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 @@
 	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



More information about the samba-cvs mailing list