db-derby-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From d..@apache.org
Subject svn commit: r659543 - in /db/derby/code/trunk/java: engine/org/apache/derby/impl/jdbc/ testing/org/apache/derbyTesting/functionTests/tests/lang/ testing/org/apache/derbyTesting/junit/
Date Fri, 23 May 2008 14:04:18 GMT
Author: dag
Date: Fri May 23 07:04:17 2008
New Revision: 659543

URL: http://svn.apache.org/viewvc?rev=659543&view=rev
Log:
DERBY-3681 When authenticating a user at connect time, verify that the user provided is not
also a defined role name.

Patch derby-3681-2, which implements this functionality plus fixes to the JUnit
framework needed for the added test case.

Modified:
    db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedConnection.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/RolesTest.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/CleanDatabaseTestSetup.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/DriverManagerConnector.java

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedConnection.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedConnection.java?rev=659543&r1=659542&r2=659543&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedConnection.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedConnection.java Fri May
23 07:04:17 2008
@@ -47,6 +47,7 @@
 import org.apache.derby.iapi.sql.execute.ExecutionContext;
 import org.apache.derby.iapi.sql.dictionary.DataDictionary;
 import org.apache.derby.iapi.store.access.XATransactionController;
+import org.apache.derby.iapi.store.access.TransactionController;
 
 import org.apache.derby.iapi.store.replication.master.MasterFactory;
 import org.apache.derby.iapi.store.replication.slave.SlaveFactory;
@@ -1124,7 +1125,11 @@
 
 			throw newSQLException(SQLState.LOGIN_FAILED, failedString);
 		}
-		
+
+		if (dbname != null) {
+			checkUserIsNotARole();
+		}
+
 		// Let's authenticate now
 			
 		if (!authenticationService.authenticate(
@@ -1144,6 +1149,55 @@
 			usingNoneAuth = true;
 	}
 
+
+	/**
+	 * If applicable, check that we don't connect with a user name
+	 * that equals a role.
+	 *
+	 * @exception SQLException Will throw if the current authorization
+	 *            id in {@code lcc} (which is already normalized to
+	 *            case normal form - CNF) equals an existing role name
+	 *            (which is also stored in CNF).
+	 */
+	private void checkUserIsNotARole() throws SQLException {
+		TransactionResourceImpl tr = getTR();
+
+		try {
+			tr.startTransaction();
+			LanguageConnectionContext lcc = tr.getLcc();
+			String username = lcc.getAuthorizationId();
+
+			DataDictionary dd = lcc.getDataDictionary();
+
+			// Check is only performed if we have
+			// derby.database.sqlAuthorization == true and we have
+			// upgraded dictionary to at least level 10.4 (roles
+			// introduced in 10.4):
+			if (lcc.usesSqlAuthorization() &&
+				dd.checkVersion(DataDictionary.DD_VERSION_DERBY_10_4, null)) {
+
+				TransactionController tc = lcc.getTransactionExecute();
+
+				String failedString =
+					MessageService.getTextMessage(MessageId.AUTH_INVALID);
+
+				if (dd.getRoleDefinitionDescriptor(username) != null) {
+					throw newSQLException(SQLState.NET_CONNECT_AUTH_FAILED,
+										  failedString);
+				}
+			}
+
+			tr.rollback();
+		} catch (StandardException e) {
+			try {
+				tr.rollback();
+			} catch (StandardException ee) {
+			}
+
+			throw handleException(e);
+		}
+	}
+
 	/* Enumerate operations controlled by database owner powers */
 	private static final int OP_ENCRYPT = 0;
 	private static final int OP_SHUTDOWN = 1;

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/RolesTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/RolesTest.java?rev=659543&r1=659542&r2=659543&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/RolesTest.java
(original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/RolesTest.java
Fri May 23 07:04:17 2008
@@ -74,6 +74,7 @@
     private final static String userException            = "38000";
     private final static String userAlreadyExists        = "X0Y68";
     private final static String invalidPUBLIC            = "4251B";
+    private final static String loginFailed              = "08004";
 
     private int MAX_IDENTIFIER_LENGTH = 128;
     /**
@@ -407,7 +408,7 @@
                 sqlAuthorizationRequired, null , roleDboOnly);
 
         // Verify that we can't create a role which has the same auth
-        // id as a known user.
+        // id as a known user (DERBY-3673).
         //
         // a) built-in user:
         doStmt("create role " + users[dboIndex], sqlAuthorizationRequired,
@@ -434,6 +435,8 @@
         doStmt("create role schemaowner", sqlAuthorizationRequired,
                userAlreadyExists, roleDboOnly);
 
+        testLoginWithUsernameWhichIsARole();
+
         /*
          * GRANT <role>
          */
@@ -642,6 +645,46 @@
     }
 
 
+    /**
+     * Create a user that has the same name as a role and try to
+     * log in with it; should be denied. This will catch cases
+     * where we can't check up front when roles are created,
+     * e.g. external authentication, or users are added after the
+     * role is created (DERBY-3681).
+     * @exception Exception
+     */
+    private void testLoginWithUsernameWhichIsARole() throws SQLException {
+        if (_authLevel == SQLAUTHORIZATION && isDbo()) {
+            _stm.execute("CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY" +
+                         "('derby.user.soonarole', 'whatever')");
+
+            // should work, not defined as a role yet
+            openDefaultConnection("soonarole","whatever").close();
+
+            // remove the user so we can create a role
+            _stm.execute("CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY" +
+                         "('derby.user.soonarole', NULL)");
+            _stm.execute("create role soonarole");
+
+            // reintroduce the colliding user name now that we have a role
+            _stm.execute("CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY" +
+                         "('derby.user.soonarole', 'whatever')");
+
+            try {
+                // should fail now
+                openDefaultConnection("soonarole","whatever").close();
+                fail("Exception expected connecting with " +
+                     "user name equal to a role");
+            } catch (SQLException e) {
+                assertSQLState(loginFailed, e);
+            }
+
+            _stm.execute("drop role soonarole");
+            _stm.execute("CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY" +
+                         "('derby.user.soonarole', NULL)");
+        }
+    }
+
     protected void setUp() throws Exception
     {
         super.setUp();

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/CleanDatabaseTestSetup.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/CleanDatabaseTestSetup.java?rev=659543&r1=659542&r2=659543&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/CleanDatabaseTestSetup.java
(original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/CleanDatabaseTestSetup.java
Fri May 23 07:04:17 2008
@@ -164,6 +164,7 @@
          removeObjects(conn);
          if (compress)
              compressObjects(conn);
+         removeRoles(conn);
      }
      
      /**
@@ -240,6 +241,25 @@
         throw sqle;
     }
 
+    private static void removeRoles(Connection conn) throws SQLException {
+        // No metadata for roles, so do a query against SYSROLES
+        Statement stm = conn.createStatement();
+        Statement dropStm = conn.createStatement();
+
+        // cast to overcome territory differences in some cases:
+        ResultSet rs = stm.executeQuery(
+            "select roleid from sys.sysroles where " +
+            "cast(isdef as char(1)) = 'Y'");
+
+        while (rs.next()) {
+            dropStm.executeUpdate("DROP ROLE " + rs.getString(1));
+        }
+
+        stm.close();
+        dropStm.close();
+        conn.commit();
+    }
+
      /**
       * Set of objects that will be compressed as part of cleaning a database.
       */

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/DriverManagerConnector.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/DriverManagerConnector.java?rev=659543&r1=659542&r2=659543&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/DriverManagerConnector.java
(original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/DriverManagerConnector.java
Fri May 23 07:04:17 2008
@@ -88,8 +88,11 @@
             if (!expectedState.equals(e.getSQLState()))
                 throw e;
             
-            return getConnectionByAttributes(url,
-                    "create", "true");          
+            Properties attributes = new Properties();
+            attributes.setProperty("user", user);
+            attributes.setProperty("password", password);
+            attributes.setProperty("create", "true");
+            return DriverManager.getConnection(url, attributes);
         }
     }
 



Mime
View raw message