db-derby-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rhille...@apache.org
Subject svn commit: r1235750 - in /db/derby/code/trunk/java: engine/org/apache/derby/iapi/services/property/ engine/org/apache/derby/iapi/sql/dictionary/ engine/org/apache/derby/impl/jdbc/authentication/ engine/org/apache/derby/impl/sql/catalog/ engine/org/apa...
Date Wed, 25 Jan 2012 14:14:04 GMT
Author: rhillegas
Date: Wed Jan 25 14:14:03 2012
New Revision: 1235750

URL: http://svn.apache.org/viewvc?rev=1235750&view=rev
Log:
DERBY-866: Prevent illegal changes to the on-disk version of derby.authentication.provider.

Modified:
    db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/property/PropertyUtil.java
    db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/DataDictionary.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/authentication/AuthenticationServiceBase.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/authentication/NativeAuthenticationServiceImpl.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/DataDictionaryImpl.java
    db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml
    db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java
    db/derby/code/trunk/java/storeless/org/apache/derby/impl/storeless/EmptyDictionary.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/NativeAuthenticationServiceTest.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/DatabaseChangeSetup.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/TestConfiguration.java

Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/property/PropertyUtil.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/property/PropertyUtil.java?rev=1235750&r1=1235749&r2=1235750&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/property/PropertyUtil.java
(original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/property/PropertyUtil.java
Wed Jan 25 14:14:03 2012
@@ -206,6 +206,17 @@ public class PropertyUtil {
 	
 		boolean dbOnly = set != null ? isDBOnly(set) : false;
 
+        //
+        // Once NATIVE authentication has been set in the database, it cannot
+        // be overridden.
+        //
+        if ( Property.AUTHENTICATION_PROVIDER_PARAMETER.equals( key ) )
+        {
+            String  dbValue = PropertyUtil.getPropertyFromSet( true, set, key );
+
+            if ( nativeAuthenticationEnabled( dbValue ) ) { return dbValue; }
+        }
+
 		return PropertyUtil.getPropertyFromSet(dbOnly, set, key);
 	}
 
@@ -563,8 +574,8 @@ public class PropertyUtil {
 	}
 
 	/**
-		Return true if NATIVE authentication has been enabled in the passed-in properties.
-	*/
+     *Return true if NATIVE authentication has been enabled in the passed-in properties.
+     */
 	public static boolean nativeAuthenticationEnabled( Properties properties )
     {
 		String authenticationProvider = getPropertyFromSet
@@ -573,11 +584,20 @@ public class PropertyUtil {
              Property.AUTHENTICATION_PROVIDER_PARAMETER
              );
 
+        return nativeAuthenticationEnabled( authenticationProvider );
+	}
+
+	/**
+     *Return true if NATIVE authentication is turned on for the passed-in
+     * value of Property.AUTHENTICATION_PROVIDER_PARAMETER.
+     */
+	private static boolean nativeAuthenticationEnabled( String authenticationProvider )
+    {
         if ( authenticationProvider ==  null ) { return false; }
 
         return StringUtil.SQLToUpperCase( authenticationProvider ).startsWith( Property.AUTHENTICATION_PROVIDER_NATIVE
);
-	}
-
+    }
+    
 	/**
 		Return true if the passed-in properties specify NATIVE authentication using LOCAL credentials.
 	*/

Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/DataDictionary.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/DataDictionary.java?rev=1235750&r1=1235749&r2=1235750&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/DataDictionary.java
(original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/DataDictionary.java
Wed Jan 25 14:14:03 2012
@@ -1696,11 +1696,10 @@ public interface DataDictionary
 	 * Return the credentials descriptor for the named user.
 	 *
 	 * @param userName      Name of the user whose credentials we want.
-	 * @param tc					The TransactionController to use
 	 *
 	 * @exception StandardException		Thrown on failure
 	 */
-	public UserDescriptor getUser( String userName, TransactionController tc )
+	public UserDescriptor getUser( String userName )
 		throws StandardException;
 
 	/** 

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/authentication/AuthenticationServiceBase.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/authentication/AuthenticationServiceBase.java?rev=1235750&r1=1235749&r2=1235750&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/authentication/AuthenticationServiceBase.java
(original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/authentication/AuthenticationServiceBase.java
Wed Jan 25 14:14:03 2012
@@ -50,6 +50,7 @@ import org.apache.derby.iapi.util.String
 import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
 import org.apache.derby.iapi.sql.dictionary.DataDictionary;
 import org.apache.derby.iapi.sql.dictionary.PasswordHasher;
+import org.apache.derby.iapi.sql.dictionary.UserDescriptor;
 
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
@@ -368,9 +369,51 @@ public abstract class AuthenticationServ
 	/**
 	  @see PropertySetCallback#validate
 	*/
-	public boolean validate(String key, Serializable value, Dictionary p)	{
-		return key.startsWith(org.apache.derby.iapi.reference.Property.USER_PROPERTY_PREFIX);
+	public boolean validate(String key, Serializable value, Dictionary p)
+        throws StandardException
+    {
+
+        // user password properties need to be remapped. nothing else needs remapping.
+		if ( key.startsWith(org.apache.derby.iapi.reference.Property.USER_PROPERTY_PREFIX) ) {
return true; }
+
+        String      stringValue = (String) value;
+        boolean     settingToNativeLocal = Property.AUTHENTICATION_PROVIDER_NATIVE_LOCAL.equals(
stringValue );
+        
+        if ( Property.AUTHENTICATION_PROVIDER_PARAMETER.equals( key ) )
+        {
+            // NATIVE + LOCAL is the only value of this property which can be persisted
+            if (
+                ( stringValue != null ) &&
+                ( stringValue.startsWith( Property.AUTHENTICATION_PROVIDER_NATIVE ) )&&
+                !settingToNativeLocal
+                )
+            { throw badNativeAuthenticationChange(); }
+
+            // once set to NATIVE authentication, you can't change it
+            String  oldValue = (String) p.get( Property.AUTHENTICATION_PROVIDER_PARAMETER
);
+            if ( (oldValue != null) && oldValue.startsWith( Property.AUTHENTICATION_PROVIDER_NATIVE
) )
+            { throw badNativeAuthenticationChange(); }
+
+            // can't turn on NATIVE + LOCAL authentication unless the DBO's credentials are
already stored.
+            // this should prevent setting NATIVE + LOCAL authentication in pre-10.9 databases
too
+            // because you can't store credentials in a pre-10.9 database.
+            if ( settingToNativeLocal )
+            {
+                DataDictionary  dd = getDataDictionary();
+                String              dbo = dd.getAuthorizationDatabaseOwner();
+                UserDescriptor  userCredentials = dd.getUser( dbo );
+
+                if ( userCredentials == null ) { throw badNativeAuthenticationChange(); }
+            }
+        }
+
+        return false;
 	}
+    private StandardException   badNativeAuthenticationChange()
+    {
+        return StandardException.newException( SQLState.PROPERTY_BAD_NATIVE_CHANGE );
+    }
+    
 	/**
 	  @see PropertySetCallback#validate
 	*/

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/authentication/NativeAuthenticationServiceImpl.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/authentication/NativeAuthenticationServiceImpl.java?rev=1235750&r1=1235749&r2=1235750&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/authentication/NativeAuthenticationServiceImpl.java
(original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/authentication/NativeAuthenticationServiceImpl.java
Wed Jan 25 14:14:03 2012
@@ -414,60 +414,50 @@ public final class NativeAuthenticationS
 	{
         userName = IdUtil.getUserAuthorizationId( userName ) ;
 
-        TransactionController   tc = getTransaction();
-        try {
-            //
-            // Special bootstrap code. If we are creating a credentials database, then
-            // we store the DBO's initial credentials in it. We also turn on NATIVE LOCAL
authentication
-            // forever.
-            //
-            if ( _creatingCredentialsDB )
-            {
-                _creatingCredentialsDB = false;
+        //
+        // Special bootstrap code. If we are creating a credentials database, then
+        // we store the DBO's initial credentials in it. We also turn on NATIVE LOCAL authentication
+        // forever.
+        //
+        if ( _creatingCredentialsDB )
+        {
+            _creatingCredentialsDB = false;
             
-                SystemProcedures.addUser( userName, userPassword, tc );
+            TransactionController   tc = getTransaction();
             
-                tc.setProperty
-                    ( Property.AUTHENTICATION_PROVIDER_PARAMETER, Property.AUTHENTICATION_PROVIDER_NATIVE_LOCAL,
true );
+            SystemProcedures.addUser( userName, userPassword, tc );
             
-                return true;
-            }
-        
-            //
-            // we expect to find a data dictionary
-            //
-            DataDictionary      dd = (DataDictionary) Monitor.getServiceModule( this, DataDictionary.MODULE
);
-        
-            //
-            // NATIVE authentication is only available if the database is at version 10.9
or later
-            //
-            dd.checkVersion( DataDictionary.DD_VERSION_DERBY_10_9, "NATIVE AUTHENTICATION"
);
-        
-            UserDescriptor      userDescriptor = dd.getUser( userName, tc );
-        
-            if ( userDescriptor == null )   { return false; }
-        
-            PasswordHasher      hasher = new PasswordHasher( userDescriptor.getHashingScheme()
);
-            char[]                     candidatePassword = hasher.hashPasswordIntoString(
userName, userPassword ).toCharArray();
-            char[]                     actualPassword = userDescriptor.getAndZeroPassword();
-        
-            if ( (candidatePassword == null) || (actualPassword == null)) { return false;
}
-            if ( candidatePassword.length != actualPassword.length ) { return false; }
+            tc.setProperty
+                ( Property.AUTHENTICATION_PROVIDER_PARAMETER, Property.AUTHENTICATION_PROVIDER_NATIVE_LOCAL,
true );
+            tc.commit();
+            
+            return true;
+        }
         
-            for ( int i = 0; i < candidatePassword.length; i++ )
-            {
-                if ( candidatePassword[ i ] != actualPassword[ i ] ) { return false; }
-            }
+        //
+        // we expect to find a data dictionary
+        //
+        DataDictionary      dd = (DataDictionary) Monitor.getServiceModule( this, DataDictionary.MODULE
);        
+        UserDescriptor      userDescriptor = dd.getUser( userName );
+        
+        if ( userDescriptor == null )   { return false; }
+        
+        PasswordHasher      hasher = new PasswordHasher( userDescriptor.getHashingScheme()
);
+        char[]                     candidatePassword = hasher.hashPasswordIntoString( userName,
userPassword ).toCharArray();
+        char[]                     actualPassword = userDescriptor.getAndZeroPassword();
         
-            Arrays.fill( candidatePassword, (char) 0 );
-            Arrays.fill( actualPassword, (char) 0 );
+        if ( (candidatePassword == null) || (actualPassword == null)) { return false; }
+        if ( candidatePassword.length != actualPassword.length ) { return false; }
         
-            return true;
-        }
-        finally
+        for ( int i = 0; i < candidatePassword.length; i++ )
         {
-            tc.commit();
+            if ( candidatePassword[ i ] != actualPassword[ i ] ) { return false; }
         }
+        
+        Arrays.fill( candidatePassword, (char) 0 );
+        Arrays.fill( actualPassword, (char) 0 );
+        
+        return true;
     }
     
 }

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/DataDictionaryImpl.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/DataDictionaryImpl.java?rev=1235750&r1=1235749&r2=1235750&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/DataDictionaryImpl.java
(original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/DataDictionaryImpl.java
Wed Jan 25 14:14:03 2012
@@ -777,6 +777,8 @@ public final class	DataDictionaryImpl
 	            newDeclaredGlobalTemporaryTablesSchemaDesc(
 	                    SchemaDescriptor.STD_DECLARED_GLOBAL_TEMPORARY_TABLES_SCHEMA_NAME);
 			
+            boolean nativeAuthenticationEnabled = PropertyUtil.nativeAuthenticationEnabled(
startParams );
+
 			if (create) {
 				String userName = IdUtil.getUserNameFromURLProps(startParams);
 				authorizationDatabaseOwner = IdUtil.getUserAuthorizationId(userName);
@@ -807,17 +809,18 @@ public final class	DataDictionaryImpl
                     DataDictionary.CREATE_DATA_DICTIONARY_VERSION,
                     dictionaryVersion, true);
 
-                boolean nativeAuthenticationEnabled = PropertyUtil.nativeAuthenticationEnabled(
startParams );
-
                 //
 				// If SqlAuthorization is set as a system property during database
 				// creation, set it as a database property also, so that it gets persisted.
                 //
                 // We also turn on SqlAuthorization if NATIVE authentication has been specified.
                 //
-				if (PropertyUtil.getSystemBoolean(Property.SQL_AUTHORIZATION_PROPERTY) || nativeAuthenticationEnabled)
+				if ( PropertyUtil.getSystemBoolean(Property.SQL_AUTHORIZATION_PROPERTY) )
 				{
 					bootingTC.setProperty(Property.SQL_AUTHORIZATION_PROPERTY,"true",true);
+				}
+				if ( PropertyUtil.getSystemBoolean(Property.SQL_AUTHORIZATION_PROPERTY) || nativeAuthenticationEnabled
)
+				{
 					usesSqlAuthorization=true;
 				}
 
@@ -889,11 +892,10 @@ public final class	DataDictionaryImpl
 					// database owner check at a hard upgrade.
 					if (dictionaryVersion.majorVersionNumber >=
 						DataDictionary.DD_VERSION_DERBY_10_2) {
-						usesSqlAuthorization = Boolean.valueOf(sqlAuth).
-							booleanValue();
+						usesSqlAuthorization = Boolean.valueOf(sqlAuth).booleanValue() || nativeAuthenticationEnabled;
 					}
 				} else {
-					if (Boolean.valueOf(sqlAuth).booleanValue()) {
+					if (Boolean.valueOf(sqlAuth).booleanValue() || nativeAuthenticationEnabled) {
 						// SQL authorization requires 10.2 or higher database
 						checkVersion(DataDictionary.DD_VERSION_DERBY_10_2,
 									 "sqlAuthorization");
@@ -7926,7 +7928,7 @@ public final class	DataDictionaryImpl
              );
 	}
 
-	public UserDescriptor getUser( String userName, TransactionController tc )
+	public UserDescriptor getUser( String userName )
 		throws StandardException
 	{
 		ExecIndexRow				keyRow;
@@ -7989,6 +7991,13 @@ public final class	DataDictionaryImpl
 		dictionaryVersion = (DD_Version)tc.getProperty(
 											DataDictionary.CORE_DATA_DICTIONARY_VERSION);
 
+        // NATIVE authentication allowed if the database is at least at level 10.9
+        boolean nativeAuthenticationEnabled = PropertyUtil.nativeAuthenticationEnabled( startParams
);
+        if ( nativeAuthenticationEnabled )
+        {
+            dictionaryVersion.checkVersion( DD_VERSION_DERBY_10_9, "NATIVE AUTHENTICATION"
);
+        }
+
         resetDatabaseOwner( tc );
         
 		softwareVersion.upgradeIfNeeded(dictionaryVersion, tc, startParams);

Modified: db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml?rev=1235750&r1=1235749&r2=1235750&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml Wed Jan 25 14:14:03
2012
@@ -4221,6 +4221,11 @@ ln=lower-case two-letter ISO-639 languag
                 <text>Invalid syntax for optimizer overrides. The syntax should be
-- DERBY-PROPERTIES propertyName = value [, propertyName = value]*</text>
             </msg>
 
+            <msg>
+                <name>XCY05.S</name>
+                <text>Invalid change of the derby.authentication.provider property.
Once set to NATIVE authentication, this property cannot be changed. NATIVE::LOCAL is the only
NATIVE value accepted by derby.authentication.provider. This property cannot be set to NATIVE::LOCAL
unless credentials for the database owner have been stored in the database using the syscs_util.syscs_create_user
procedure.</text>
+            </msg>
+
         </family>
 
 

Modified: db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java?rev=1235750&r1=1235749&r2=1235750&view=diff
==============================================================================
--- db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java
(original)
+++ db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java
Wed Jan 25 14:14:03 2012
@@ -261,6 +261,7 @@ public interface SQLState {
 	String PROPERTY_UNSUPPORTED_CHANGE  = "XCY02.S";
 	String PROPERTY_MISSING				= "XCY03.S";
 	String PROPERTY_SYNTAX_INVALID		= "XCY04.S";
+	String PROPERTY_BAD_NATIVE_CHANGE  = "XCY05.S";
 
 	/*
 	** LockManager

Modified: db/derby/code/trunk/java/storeless/org/apache/derby/impl/storeless/EmptyDictionary.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/storeless/org/apache/derby/impl/storeless/EmptyDictionary.java?rev=1235750&r1=1235749&r2=1235750&view=diff
==============================================================================
--- db/derby/code/trunk/java/storeless/org/apache/derby/impl/storeless/EmptyDictionary.java
(original)
+++ db/derby/code/trunk/java/storeless/org/apache/derby/impl/storeless/EmptyDictionary.java
Wed Jan 25 14:14:03 2012
@@ -690,7 +690,7 @@ public class EmptyDictionary implements 
 		// TODO Auto-generated method stub
     }
 
-	public UserDescriptor getUser( String userName, TransactionController tc )
+	public UserDescriptor getUser( String userName )
 			throws StandardException
 	{
 		// TODO Auto-generated method stub

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/NativeAuthenticationServiceTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/NativeAuthenticationServiceTest.java?rev=1235750&r1=1235749&r2=1235750&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/NativeAuthenticationServiceTest.java
(original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/NativeAuthenticationServiceTest.java
Wed Jan 25 14:14:03 2012
@@ -28,6 +28,7 @@ import java.util.Properties;
 import junit.extensions.TestSetup;
 import junit.framework.Test;
 import junit.framework.TestSuite;
+import org.apache.derbyTesting.junit.DatabaseChangeSetup;
 import org.apache.derbyTesting.junit.JDBC;
 import org.apache.derbyTesting.junit.TestConfiguration;
 import org.apache.derbyTesting.junit.SystemPropertyTestSetup;
@@ -49,17 +50,23 @@ public class NativeAuthenticationService
     private static  final   String  DBO = "KIWI";   
     private static  final   String  APPLE_USER = "APPLE";   
     private static  final   String  PEAR_USER = "PEAR";   
+    private static  final   String  ORANGE_USER = "ORANGE";   
 
     private static  final   String  WALNUT_USER = "WALNUT";
 
     private static  final   String  CREDENTIALS_DB = "credDB";
     private static  final   String  SECOND_DB = "secondDB";
     private static  final   String  THIRD_DB = "thirdDB";
+    private static  final   String  FOURTH_DB = "fourthDB";
 
     private static  final   String  PROVIDER_PROPERTY = "derby.authentication.provider";
 
     private static  final   String  CREDENTIALS_DB_DOES_NOT_EXIST = "4251I";
     private static  final   String  INVALID_AUTHENTICATION = "08004";
+    private static  final   String  DBO_ONLY_OPERATION = "4251D";
+    private static  final   String  INVALID_PROVIDER_CHANGE = "XCY05";
+    private static  final   String  CANT_DROP_DBO = "4251F";
+    private static  final   String  NO_COLUMN_PERMISSION = "42502";
 
     ///////////////////////////////////////////////////////////////////////////////////
     //
@@ -70,6 +77,8 @@ public class NativeAuthenticationService
     private final   boolean _nativeAuthentication;
     private final   boolean _localAuthentication;
 
+    private DatabaseChangeSetup _fourthDBSetup;
+
     ///////////////////////////////////////////////////////////////////////////////////
     //
     // CONSTRUCTOR
@@ -158,9 +167,9 @@ public class NativeAuthenticationService
     {
         TestSuite suite = new TestSuite();
 
-        suite.addTest( decorate( new NativeAuthenticationServiceTest( false, false ), clientServer
) );
-        suite.addTest( decorate( new NativeAuthenticationServiceTest( true, true ), clientServer
) );
-        suite.addTest( decorate( new NativeAuthenticationServiceTest( true, false ), clientServer
) );
+        suite.addTest( (new NativeAuthenticationServiceTest( false, false ) ).decorate( clientServer
) );
+        suite.addTest( ( new NativeAuthenticationServiceTest( true, true ) ).decorate( clientServer
) );
+        suite.addTest( ( new NativeAuthenticationServiceTest( true, false ) ).decorate( clientServer
) );
 
         return suite;
     }
@@ -172,11 +181,11 @@ public class NativeAuthenticationService
      * stored properties that can't be removed at tearDown time.
      * </p>
      */
-    private static  Test    decorate( NativeAuthenticationServiceTest nast, boolean clientServer
)
+    private Test    decorate( boolean clientServer )
     {
         String      credentialsDBPhysicalName = TestConfiguration.generateUniqueDatabaseName();
         
-        Test        result = nast;
+        Test        result = this;
 
         //
         // Putting the clientServer decorator on the inside allows the server-side
@@ -193,7 +202,7 @@ public class NativeAuthenticationService
         // before deleting the physical databases. This is because we need one of the
         // databases (the credentials db) in order to authenticate engine shutdown.
         //
-        Properties  systemProperties = nast.systemProperties( credentialsDBPhysicalName );
+        Properties  systemProperties = systemProperties( credentialsDBPhysicalName );
         if ( systemProperties != null )
         {
             result = new SystemPropertyTestSetup( result, systemProperties, true );
@@ -218,6 +227,7 @@ public class NativeAuthenticationService
             ( result, CREDENTIALS_DB, credentialsDBPhysicalName );
         result = TestConfiguration.additionalDatabaseDecoratorNoShutdown( result, SECOND_DB
);
         result = TestConfiguration.additionalDatabaseDecoratorNoShutdown( result, THIRD_DB
);
+        result = _fourthDBSetup = TestConfiguration.additionalDatabaseDecoratorNoShutdown(
result, FOURTH_DB, true );
 
         result = TestConfiguration.changeUserDecorator( result, DBO, getPassword( DBO ) );
         
@@ -239,8 +249,20 @@ public class NativeAuthenticationService
     {
         println( nameOfTest() );
 
+        vetForAllConfigurations();
+
+        if ( !_nativeAuthentication ) { vetUnauthenticatedConfiguration(); }
+    }
+
+    /**
+     * <p>
+     * These tests are run for all configurations.
+     * </p>
+     */
+    private void    vetForAllConfigurations()   throws Exception
+    {
         // can't create any database until the credentials db has been created
-        Connection  secondDBConn = createDB
+        Connection  secondDBConn = getConnection
             ( _nativeAuthentication, SECOND_DB, APPLE_USER, CREDENTIALS_DB_DOES_NOT_EXIST
);
 
         // create the credentials database
@@ -254,7 +276,6 @@ public class NativeAuthenticationService
         //
         // 1) The DBO's credentials should have been stored in SYSUSERS.
         // 2) The authentication provider should have been set to NATIVE::LOCAL
-        // 3) SQL authorization should have been turned on.
         //
         String[][]  legalUsers = _nativeAuthentication ? new String[][] { { APPLE_USER },
{ DBO } } : new String[][] {  { APPLE_USER } };
         assertResults
@@ -272,7 +293,9 @@ public class NativeAuthenticationService
              authenticationProvider,
              false
              );
-        String[][]  sqlAuthorization = _nativeAuthentication ? new String[][] { { "true"
} } : new String[][] { { null } };
+
+        // there should be no need to explicitly set the sql authorization property
+        String[][]  sqlAuthorization = new String[][] { { null } };
         assertResults
             (
              sysadminConn,
@@ -280,6 +303,7 @@ public class NativeAuthenticationService
              sqlAuthorization,
              false
              );
+        vetSQLAuthorizationOn();
 
         // Sanity-check that the creator of the credentials db is the DBO
         String[][]   dboName = new String[][] { { DBO } };
@@ -292,13 +316,13 @@ public class NativeAuthenticationService
              );
 
         // Databases can't be created by users who don't have credentials stored in the credentials
database
-        Connection  thirdDBConn = createDB
+        Connection  thirdDBConn = getConnection
             ( _nativeAuthentication, THIRD_DB, WALNUT_USER, INVALID_AUTHENTICATION );
 
         // Now let the other valid user create a database
         if ( secondDBConn == null )
         {
-            secondDBConn = createDB( false, SECOND_DB, APPLE_USER, null );
+            secondDBConn = getConnection( false, SECOND_DB, APPLE_USER, null );
         }
 
         // verify that the other valid user is the dbo in the database he just created
@@ -344,12 +368,138 @@ public class NativeAuthenticationService
         
     }
 
-    private Connection  createDB( boolean shouldFail, String dbName, String user, String
expectedSQLState )
+    /**
+     * <p>
+     * These tests are run only if authentication is turned off.
+     * </p>
+     */
+    private void    vetUnauthenticatedConfiguration()   throws Exception
+    {
+        // create an empty database without authentication turned on
+        String          dbo = ORANGE_USER;
+        Connection  dboConn = openConnection( FOURTH_DB, dbo );
+
+        addUser( dboConn, PEAR_USER );
+
+        // NATIVE authentication isn't on, so you can store oddball values for the authentication
provider
+        goodStatement
+            ( dboConn, "call syscs_util.syscs_set_database_property( 'derby.authentication.provider',
'com.acme.AcmeAuthenticator' )" );
+
+        // can't turn on NATIVE authentication until you have stored credentials for the
dbo
+        expectExecutionError
+            (
+             dboConn, INVALID_PROVIDER_CHANGE,
+             "call syscs_util.syscs_set_database_property( 'derby.authentication.provider',
'NATIVE::LOCAL' )"
+             );
+ 
+        // store credentials for the DBO
+        addUser( dboConn, dbo );
+
+        // verify that you can't drop the dbo
+        expectExecutionError
+            (
+             dboConn, CANT_DROP_DBO,
+             "call syscs_util.syscs_drop_user( '" + dbo + "' )"
+             );
+        String[][]  legalUsers = new String[][] { { dbo }, { PEAR_USER } };
+        assertResults
+            (
+             dboConn,
+             "select username from sys.sysusers order by username",
+             legalUsers,
+             false
+             );
+        
+        // NATIVE::LOCAL is the only legal value which the authentication provider property
can take on disk
+        expectExecutionError
+            (
+             dboConn, INVALID_PROVIDER_CHANGE,
+             "call syscs_util.syscs_set_database_property( 'derby.authentication.provider',
'NATIVE:db:LOCAL' )"
+             );
+        expectExecutionError
+            (
+             dboConn, INVALID_PROVIDER_CHANGE,
+             "call syscs_util.syscs_set_database_property( 'derby.authentication.provider',
'NATIVE:LOCAL' )"
+             );
+ 
+        // now turn on NATIVE + LOCAL authentication
+        goodStatement( dboConn, "call syscs_util.syscs_set_database_property( 'derby.authentication.provider',
'NATIVE::LOCAL' )" );
+
+        // once set, you can't unset or change it
+        expectExecutionError
+            (
+             dboConn, INVALID_PROVIDER_CHANGE,
+             "call syscs_util.syscs_set_database_property( 'derby.authentication.provider',
'NATIVE::LOCAL' )"
+             );
+        expectExecutionError
+            (
+             dboConn, INVALID_PROVIDER_CHANGE,
+             "call syscs_util.syscs_set_database_property( 'derby.authentication.provider',
null )"
+             );
+        expectExecutionError
+            (
+             dboConn, INVALID_PROVIDER_CHANGE,
+             "call syscs_util.syscs_set_database_property( 'derby.authentication.provider',
'com.acme.AcmeAuthenticator' )"
+             );
+
+        // verify that the authentication provider property has the value we expect
+        String[][]  authenticationProvider = new String[][] { { "NATIVE::LOCAL" } };
+        assertResults
+            (
+             dboConn,
+             "values ( syscs_util.syscs_get_database_property( 'derby.authentication.provider'
) )",
+             authenticationProvider,
+             false
+             );
+        
+        // create a table for a simple authorization check later on
+        goodStatement( dboConn, "create table t( a int )" );
+
+        // shutdown this database so that the on-disk properties will take effect on reboot
+        _fourthDBSetup.getTestConfiguration().shutdownDatabase();
+        
+        // can't connect to the database with credentials which aren't stored in it.
+        Connection  appleConn = getConnection( true, FOURTH_DB, APPLE_USER, INVALID_AUTHENTICATION
);
+
+        // ...but these credentials work
+        Connection  pearConn = openConnection( FOURTH_DB, PEAR_USER );
+
+        // should get authorization errors trying to select from a table private to the DBO
+        // and from trying to view the credentials table
+        expectExecutionError( pearConn, NO_COLUMN_PERMISSION, "select * from " + dbo + ".t"
);
+        expectCompilationError( pearConn, DBO_ONLY_OPERATION, "select username from sys.sysusers"
);
+        
+    }
+    
+    private void    vetSQLAuthorizationOn() throws Exception
+    {
+        Connection  nonDBOConn = openConnection( CREDENTIALS_DB, APPLE_USER );
+        String          query = "select username from sys.sysusers" ;
+
+        try {
+            chattyPrepare( nonDBOConn, query );
+
+            if ( _nativeAuthentication ) { fail( "SQL Authorization not on!" ); }
+        }
+        catch (SQLException se)
+        {
+            if ( _nativeAuthentication )
+            {
+                assertSQLState( DBO_ONLY_OPERATION, se );
+            }
+            else
+            {
+                fail( "Caught unexpected SQLException: " + se.getSQLState() + ": " + se.getMessage()
);
+            }
+        }
+    }
+    
+    private Connection  getConnection( boolean shouldFail, String dbName, String user, String
expectedSQLState )
         throws Exception
     {
         Connection  conn = null;
 
-        println( user + " attempting to create database " + dbName );
+        println( user + " attempting to get connection to database " + dbName );
 
         try {
             conn = openConnection( dbName, user );

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/DatabaseChangeSetup.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/DatabaseChangeSetup.java?rev=1235750&r1=1235749&r2=1235750&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/DatabaseChangeSetup.java
(original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/DatabaseChangeSetup.java
Wed Jan 25 14:14:03 2012
@@ -31,6 +31,8 @@ public  final class DatabaseChangeSetup 
     private final String logicalDbName;
     private final String dbName;
     private final boolean defaultDb;
+
+    private TestConfiguration   _myTestConfiguration;
     
     public DatabaseChangeSetup(Test test, String logicalDbName, String dbName, boolean defaultDb)
{
         super(test);
@@ -40,9 +42,12 @@ public  final class DatabaseChangeSetup 
    }
 
     TestConfiguration getNewConfiguration(TestConfiguration old) {
-        return new TestConfiguration(old, logicalDbName, dbName, defaultDb);
+        _myTestConfiguration = new TestConfiguration(old, logicalDbName, dbName, defaultDb);
+        return _myTestConfiguration;
     }
 
+    public  TestConfiguration   getTestConfiguration()  { return _myTestConfiguration; }
+    
     public  String  physicalDatabaseName() { return dbName; }
     
 }

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/TestConfiguration.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/TestConfiguration.java?rev=1235750&r1=1235749&r2=1235750&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/TestConfiguration.java
(original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/TestConfiguration.java
Wed Jan 25 14:14:03 2012
@@ -790,6 +790,29 @@ public final class TestConfiguration {
         Test test,
         String logicalDbName)
     {
+        return additionalDatabaseDecoratorNoShutdown( test, logicalDbName, false );
+    }
+
+    /**
+     * Similar to additionalDatabaseDecorator except the database will
+     * not be shutdown, only deleted. It is the responsibility of the
+     * test to shut it down.
+     *
+     * @param test Test to be decorated
+     * @param logicalDbName The logical database name. This name is
+     *                      used to identify the database in
+     *                      openConnection(String logicalDatabaseName)
+     *                      method calls.
+     * @param defaultDB True if the database should store its own name in its TestConfiguration.
+     * @return decorated test.
+     */
+    public static DatabaseChangeSetup additionalDatabaseDecoratorNoShutdown
+        (
+         Test test,
+         String logicalDbName,
+         boolean defaultDB
+        )
+    {
         return new DatabaseChangeSetup(
             new DropDatabaseSetup(test, logicalDbName)
             {
@@ -800,7 +823,7 @@ public final class TestConfiguration {
             },
             logicalDbName,
             generateUniqueDatabaseName(),
-            false);
+            defaultDB);
     }
 
     /**



Mime
View raw message