You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by sa...@apache.org on 2016/10/28 15:20:23 UTC

[01/10] cassandra git commit: Prepare legacy auth statements if tables initialised after node startup

Repository: cassandra
Updated Branches:
  refs/heads/cassandra-2.2 eaf46a1c9 -> 312e21bda
  refs/heads/cassandra-3.0 e9ff6ae6f -> e4f840aa1
  refs/heads/cassandra-3.X 49ce0a495 -> 9be467a22
  refs/heads/trunk 0919ae2c2 -> 9e8b7c0d0


Prepare legacy auth statements if tables initialised after node startup

Patch by Alex Petrov; reviewed by Sam Tunnicliffe for CASSANDRA-12813


Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/312e21bd
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/312e21bd
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/312e21bd

Branch: refs/heads/cassandra-2.2
Commit: 312e21bda7c50f05fc5f8868740b513022385951
Parents: eaf46a1
Author: Alex Petrov <ol...@gmail.com>
Authored: Fri Oct 21 16:58:33 2016 +0200
Committer: Sam Tunnicliffe <sa...@beobal.com>
Committed: Fri Oct 28 16:04:36 2016 +0100

----------------------------------------------------------------------
 CHANGES.txt                                     |  1 +
 .../cassandra/auth/CassandraAuthorizer.java     | 14 +++++--
 .../cassandra/auth/PasswordAuthenticator.java   | 40 ++++++++++++++------
 3 files changed, 40 insertions(+), 15 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/312e21bd/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index a22439b..b33ef8d 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,5 @@
 2.2.9
+ * Prepare legacy authenticate statement if credentials table initialised after node startup (CASSANDRA-12813)
  * Change cassandra.wait_for_tracing_events_timeout_secs default to 0 (CASSANDRA-12754)
  * Clean up permissions when a UDA is dropped (CASSANDRA-12720)
  * Limit colUpdateTimeDelta histogram updates to reasonable deltas (CASSANDRA-11117)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/312e21bd/src/java/org/apache/cassandra/auth/CassandraAuthorizer.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/auth/CassandraAuthorizer.java b/src/java/org/apache/cassandra/auth/CassandraAuthorizer.java
index 88069a2..360d59a 100644
--- a/src/java/org/apache/cassandra/auth/CassandraAuthorizer.java
+++ b/src/java/org/apache/cassandra/auth/CassandraAuthorizer.java
@@ -209,11 +209,19 @@ public class CassandraAuthorizer implements IAuthorizer
                                                              Lists.newArrayList(ByteBufferUtil.bytes(role.getRoleName()),
                                                                                 ByteBufferUtil.bytes(resource.getName())));
 
+        SelectStatement statement;
         // If it exists, read from the legacy user permissions table to handle the case where the cluster
         // is being upgraded and so is running with mixed versions of the authz schema
-        SelectStatement statement = Schema.instance.getCFMetaData(AuthKeyspace.NAME, USER_PERMISSIONS) == null
-                                    ? authorizeRoleStatement
-                                    : legacyAuthorizeRoleStatement;
+        if (Schema.instance.getCFMetaData(AuthKeyspace.NAME, USER_PERMISSIONS) == null)
+            statement = authorizeRoleStatement;
+        else
+        {
+            // If the permissions table was initialised only after the statement got prepared, re-prepare (CASSANDRA-12813)
+            if (legacyAuthorizeRoleStatement == null)
+                legacyAuthorizeRoleStatement = prepare(USERNAME, USER_PERMISSIONS);
+            statement = legacyAuthorizeRoleStatement;
+        }
+
         ResultMessage.Rows rows = statement.execute(QueryState.forInternalCalls(), options) ;
         UntypedResultSet result = UntypedResultSet.create(rows.result);
 

http://git-wip-us.apache.org/repos/asf/cassandra/blob/312e21bd/src/java/org/apache/cassandra/auth/PasswordAuthenticator.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/auth/PasswordAuthenticator.java b/src/java/org/apache/cassandra/auth/PasswordAuthenticator.java
index c0d2283..20f8790 100644
--- a/src/java/org/apache/cassandra/auth/PasswordAuthenticator.java
+++ b/src/java/org/apache/cassandra/auth/PasswordAuthenticator.java
@@ -77,11 +77,7 @@ public class PasswordAuthenticator implements IAuthenticator
     {
         try
         {
-            // If the legacy users table exists try to verify credentials there. This is to handle the case
-            // where the cluster is being upgraded and so is running with mixed versions of the authn tables
-            SelectStatement authenticationStatement = Schema.instance.getCFMetaData(AuthKeyspace.NAME, LEGACY_CREDENTIALS_TABLE) == null
-                                                    ? authenticateStatement
-                                                    : legacyAuthenticateStatement;
+            SelectStatement authenticationStatement = authenticationStatement();
             return doAuthenticate(username, password, authenticationStatement);
         }
         catch (RequestExecutionException e)
@@ -91,6 +87,23 @@ public class PasswordAuthenticator implements IAuthenticator
         }
     }
 
+    /**
+     * If the legacy users table exists try to verify credentials there. This is to handle the case
+     * where the cluster is being upgraded and so is running with mixed versions of the authn tables
+     */
+    private SelectStatement authenticationStatement()
+    {
+        if (Schema.instance.getCFMetaData(AuthKeyspace.NAME, LEGACY_CREDENTIALS_TABLE) == null)
+            return authenticateStatement;
+        else
+        {
+            // If the credentials was initialised only after statement got prepared, re-prepare (CASSANDRA-12813).
+            if (legacyAuthenticateStatement == null)
+                prepareLegacyAuthenticateStatement();
+            return legacyAuthenticateStatement;
+        }
+    }
+
     public Set<DataResource> protectedResources()
     {
         // Also protected by CassandraRoleManager, but the duplication doesn't hurt and is more explicit
@@ -110,13 +123,16 @@ public class PasswordAuthenticator implements IAuthenticator
         authenticateStatement = prepare(query);
 
         if (Schema.instance.getCFMetaData(AuthKeyspace.NAME, LEGACY_CREDENTIALS_TABLE) != null)
-        {
-            query = String.format("SELECT %s from %s.%s WHERE username = ?",
-                                  SALTED_HASH,
-                                  AuthKeyspace.NAME,
-                                  LEGACY_CREDENTIALS_TABLE);
-            legacyAuthenticateStatement = prepare(query);
-        }
+            prepareLegacyAuthenticateStatement();
+    }
+
+    private void prepareLegacyAuthenticateStatement()
+    {
+        String query = String.format("SELECT %s from %s.%s WHERE username = ?",
+                                     SALTED_HASH,
+                                     AuthKeyspace.NAME,
+                                     LEGACY_CREDENTIALS_TABLE);
+        legacyAuthenticateStatement = prepare(query);
     }
 
     public AuthenticatedUser legacyAuthenticate(Map<String, String> credentials) throws AuthenticationException


[09/10] cassandra git commit: Merge branch 'cassandra-3.0' into cassandra-3.X

Posted by sa...@apache.org.
Merge branch 'cassandra-3.0' into cassandra-3.X


Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/9be467a2
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/9be467a2
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/9be467a2

Branch: refs/heads/trunk
Commit: 9be467a22ab646c23710eb2b23dd21e5a46b07bd
Parents: 49ce0a4 e4f840a
Author: Sam Tunnicliffe <sa...@beobal.com>
Authored: Fri Oct 28 16:11:13 2016 +0100
Committer: Sam Tunnicliffe <sa...@beobal.com>
Committed: Fri Oct 28 16:17:52 2016 +0100

----------------------------------------------------------------------
 CHANGES.txt                                     |  1 +
 .../cassandra/auth/CassandraAuthorizer.java     | 13 ++++--
 .../cassandra/auth/PasswordAuthenticator.java   | 42 ++++++++++++++------
 3 files changed, 41 insertions(+), 15 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/9be467a2/CHANGES.txt
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/cassandra/blob/9be467a2/src/java/org/apache/cassandra/auth/CassandraAuthorizer.java
----------------------------------------------------------------------
diff --cc src/java/org/apache/cassandra/auth/CassandraAuthorizer.java
index 8c3485d,7ffef27..7f44eef
--- a/src/java/org/apache/cassandra/auth/CassandraAuthorizer.java
+++ b/src/java/org/apache/cassandra/auth/CassandraAuthorizer.java
@@@ -215,12 -209,20 +215,19 @@@ public class CassandraAuthorizer implem
                                                               Lists.newArrayList(ByteBufferUtil.bytes(role.getRoleName()),
                                                                                  ByteBufferUtil.bytes(resource.getName())));
  
+         SelectStatement statement;
          // If it exists, read from the legacy user permissions table to handle the case where the cluster
          // is being upgraded and so is running with mixed versions of the authz schema
-         SelectStatement statement = Schema.instance.getCFMetaData(SchemaConstants.AUTH_KEYSPACE_NAME, USER_PERMISSIONS) == null
-                                     ? authorizeRoleStatement
-                                     : legacyAuthorizeRoleStatement;
 -        if (Schema.instance.getCFMetaData(AuthKeyspace.NAME, USER_PERMISSIONS) == null)
++        if (Schema.instance.getCFMetaData(SchemaConstants.AUTH_KEYSPACE_NAME, USER_PERMISSIONS) == null)
+             statement = authorizeRoleStatement;
+         else
+         {
+             // If the permissions table was initialised only after the statement got prepared, re-prepare (CASSANDRA-12813)
+             if (legacyAuthorizeRoleStatement == null)
+                 legacyAuthorizeRoleStatement = prepare(USERNAME, USER_PERMISSIONS);
+             statement = legacyAuthorizeRoleStatement;
+         }
 -
 -        ResultMessage.Rows rows = statement.execute(QueryState.forInternalCalls(), options) ;
 +        ResultMessage.Rows rows = statement.execute(QueryState.forInternalCalls(), options, System.nanoTime());
          UntypedResultSet result = UntypedResultSet.create(rows.result);
  
          if (!result.isEmpty() && result.one().has(PERMISSIONS))

http://git-wip-us.apache.org/repos/asf/cassandra/blob/9be467a2/src/java/org/apache/cassandra/auth/PasswordAuthenticator.java
----------------------------------------------------------------------
diff --cc src/java/org/apache/cassandra/auth/PasswordAuthenticator.java
index b0317f3,ca610d1..4b667ae
--- a/src/java/org/apache/cassandra/auth/PasswordAuthenticator.java
+++ b/src/java/org/apache/cassandra/auth/PasswordAuthenticator.java
@@@ -86,56 -78,8 +86,52 @@@ public class PasswordAuthenticator impl
      {
          try
          {
 +            String hash = cache.get(username);
 +            if (!BCrypt.checkpw(password, hash))
 +                throw new AuthenticationException(String.format("Provided username %s and/or password are incorrect", username));
 +
 +            return new AuthenticatedUser(username);
 +        }
 +        catch (ExecutionException | UncheckedExecutionException e)
 +        {
 +            // the credentials were somehow invalid - either a non-existent role, or one without a defined password
 +            if (e.getCause() instanceof NoSuchCredentialsException)
 +                throw new AuthenticationException(String.format("Provided username %s and/or password are incorrect", username));
 +
 +            // an unanticipated exception occured whilst querying the credentials table
 +            if (e.getCause() instanceof RequestExecutionException)
 +            {
 +                logger.trace("Error performing internal authentication", e);
 +                throw new AuthenticationException(String.format("Error during authentication of user %s : %s", username, e.getMessage()));
 +            }
 +
 +            throw new RuntimeException(e);
 +        }
 +    }
 +
 +    private String queryHashedPassword(String username) throws NoSuchCredentialsException
 +    {
 +        try
 +        {
-             // If the legacy users table exists try to verify credentials there. This is to handle the case
-             // where the cluster is being upgraded and so is running with mixed versions of the authn tables
-             SelectStatement authenticationStatement = Schema.instance.getCFMetaData(SchemaConstants.AUTH_KEYSPACE_NAME, LEGACY_CREDENTIALS_TABLE) == null
-                                                     ? authenticateStatement
-                                                     : legacyAuthenticateStatement;
+             SelectStatement authenticationStatement = authenticationStatement();
 -            return doAuthenticate(username, password, authenticationStatement);
 +
 +            ResultMessage.Rows rows =
 +                authenticationStatement.execute(QueryState.forInternalCalls(),
 +                                                QueryOptions.forInternalCalls(consistencyForRole(username),
 +                                                                              Lists.newArrayList(ByteBufferUtil.bytes(username))),
 +                                                System.nanoTime());
 +
 +            // If either a non-existent role name was supplied, or no credentials
 +            // were found for that role we don't want to cache the result so we throw
 +            // a specific, but unchecked, exception to keep LoadingCache happy.
 +            if (rows.result.isEmpty())
 +                throw new NoSuchCredentialsException();
 +
 +            UntypedResultSet result = UntypedResultSet.create(rows.result);
 +            if (!result.one().has(SALTED_HASH))
 +                throw new NoSuchCredentialsException();
 +
 +            return result.one().getString(SALTED_HASH);
          }
          catch (RequestExecutionException e)
          {
@@@ -144,6 -88,23 +140,25 @@@
          }
      }
  
+     /**
+      * If the legacy users table exists try to verify credentials there. This is to handle the case
+      * where the cluster is being upgraded and so is running with mixed versions of the authn tables
+      */
+     private SelectStatement authenticationStatement()
+     {
 -        if (Schema.instance.getCFMetaData(AuthKeyspace.NAME, LEGACY_CREDENTIALS_TABLE) == null)
++        if (Schema.instance.getCFMetaData(SchemaConstants.AUTH_KEYSPACE_NAME, LEGACY_CREDENTIALS_TABLE) == null)
+             return authenticateStatement;
+         else
+         {
++            // the statement got prepared, we to try preparing it again.
+             // If the credentials was initialised only after statement got prepared, re-prepare (CASSANDRA-12813).
+             if (legacyAuthenticateStatement == null)
+                 prepareLegacyAuthenticateStatement();
+             return legacyAuthenticateStatement;
+         }
+     }
+ 
++
      public Set<DataResource> protectedResources()
      {
          // Also protected by CassandraRoleManager, but the duplication doesn't hurt and is more explicit
@@@ -162,18 -123,19 +177,21 @@@
                                       AuthKeyspace.ROLES);
          authenticateStatement = prepare(query);
  
 -        if (Schema.instance.getCFMetaData(AuthKeyspace.NAME, LEGACY_CREDENTIALS_TABLE) != null)
 +        if (Schema.instance.getCFMetaData(SchemaConstants.AUTH_KEYSPACE_NAME, LEGACY_CREDENTIALS_TABLE) != null)
-         {
-             query = String.format("SELECT %s from %s.%s WHERE username = ?",
-                                   SALTED_HASH,
-                                   SchemaConstants.AUTH_KEYSPACE_NAME,
-                                   LEGACY_CREDENTIALS_TABLE);
-             legacyAuthenticateStatement = prepare(query);
-         }
+             prepareLegacyAuthenticateStatement();
 +
 +        cache = new CredentialsCache(this);
      }
  
+     private void prepareLegacyAuthenticateStatement()
+     {
+         String query = String.format("SELECT %s from %s.%s WHERE username = ?",
+                                      SALTED_HASH,
 -                                     AuthKeyspace.NAME,
++                                     SchemaConstants.AUTH_KEYSPACE_NAME,
+                                      LEGACY_CREDENTIALS_TABLE);
+         legacyAuthenticateStatement = prepare(query);
+     }
+ 
      public AuthenticatedUser legacyAuthenticate(Map<String, String> credentials) throws AuthenticationException
      {
          String username = credentials.get(USERNAME_KEY);


[06/10] cassandra git commit: Merge branch 'cassandra-2.2' into cassandra-3.0

Posted by sa...@apache.org.
Merge branch 'cassandra-2.2' into cassandra-3.0


Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/e4f840aa
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/e4f840aa
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/e4f840aa

Branch: refs/heads/cassandra-3.0
Commit: e4f840aa1f84f008cf7c14bdd6a22aebd1b41c70
Parents: e9ff6ae 312e21b
Author: Sam Tunnicliffe <sa...@beobal.com>
Authored: Fri Oct 28 16:08:29 2016 +0100
Committer: Sam Tunnicliffe <sa...@beobal.com>
Committed: Fri Oct 28 16:08:29 2016 +0100

----------------------------------------------------------------------
 CHANGES.txt                                     |  1 +
 .../cassandra/auth/CassandraAuthorizer.java     | 14 +++++--
 .../cassandra/auth/PasswordAuthenticator.java   | 40 ++++++++++++++------
 3 files changed, 40 insertions(+), 15 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/e4f840aa/CHANGES.txt
----------------------------------------------------------------------
diff --cc CHANGES.txt
index 9910245,b33ef8d..bf1e7d6
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@@ -1,30 -1,5 +1,31 @@@
 -2.2.9
 +3.0.10
 + * Fix for KeyCacheCqlTest flakiness (CASSANDRA-12801)
 + * Include SSTable filename in compacting large row message (CASSANDRA-12384)
 + * Fix potential socket leak (CASSANDRA-12329, CASSANDRA-12330)
 + * Fix ViewTest.testCompaction (CASSANDRA-12789)
 + * Improve avg aggregate functions (CASSANDRA-12417)
 + * Preserve quoted reserved keyword column names in MV creation (CASSANDRA-11803)
 + * nodetool stopdaemon errors out (CASSANDRA-12646)
 + * Split materialized view mutations on build to prevent OOM (CASSANDRA-12268)
 + * mx4j does not work in 3.0.8 (CASSANDRA-12274)
 + * Abort cqlsh copy-from in case of no answer after prolonged period of time (CASSANDRA-12740)
 + * Avoid sstable corrupt exception due to dropped static column (CASSANDRA-12582)
 + * Make stress use client mode to avoid checking commit log size on startup (CASSANDRA-12478)
 + * Fix exceptions with new vnode allocation (CASSANDRA-12715)
 + * Unify drain and shutdown processes (CASSANDRA-12509)
 + * Fix NPE in ComponentOfSlice.isEQ() (CASSANDRA-12706)
 + * Fix failure in LogTransactionTest (CASSANDRA-12632)
 + * Fix potentially incomplete non-frozen UDT values when querying with the
 +   full primary key specified (CASSANDRA-12605)
 + * Skip writing MV mutations to commitlog on mutation.applyUnsafe() (CASSANDRA-11670)
 + * Establish consistent distinction between non-existing partition and NULL value for LWTs on static columns (CASSANDRA-12060)
 + * Extend ColumnIdentifier.internedInstances key to include the type that generated the byte buffer (CASSANDRA-12516)
 + * Backport CASSANDRA-10756 (race condition in NativeTransportService shutdown) (CASSANDRA-12472)
 + * If CF has no clustering columns, any row cache is full partition cache (CASSANDRA-12499)
 + * Correct log message for statistics of offheap memtable flush (CASSANDRA-12776)
 + * Explicitly set locale for string validation (CASSANDRA-12541,CASSANDRA-12542,CASSANDRA-12543,CASSANDRA-12545)
 +Merged from 2.2:
+  * Prepare legacy authenticate statement if credentials table initialised after node startup (CASSANDRA-12813)
   * Change cassandra.wait_for_tracing_events_timeout_secs default to 0 (CASSANDRA-12754)
   * Clean up permissions when a UDA is dropped (CASSANDRA-12720)
   * Limit colUpdateTimeDelta histogram updates to reasonable deltas (CASSANDRA-11117)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/e4f840aa/src/java/org/apache/cassandra/auth/CassandraAuthorizer.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/cassandra/blob/e4f840aa/src/java/org/apache/cassandra/auth/PasswordAuthenticator.java
----------------------------------------------------------------------


[10/10] cassandra git commit: Merge branch 'cassandra-3.X' into trunk

Posted by sa...@apache.org.
Merge branch 'cassandra-3.X' into trunk


Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/9e8b7c0d
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/9e8b7c0d
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/9e8b7c0d

Branch: refs/heads/trunk
Commit: 9e8b7c0d0d00e7f75f893906c6d52951bda0579e
Parents: 0919ae2 9be467a
Author: Sam Tunnicliffe <sa...@beobal.com>
Authored: Fri Oct 28 16:18:13 2016 +0100
Committer: Sam Tunnicliffe <sa...@beobal.com>
Committed: Fri Oct 28 16:18:13 2016 +0100

----------------------------------------------------------------------
 CHANGES.txt                                     |  1 +
 .../cassandra/auth/CassandraAuthorizer.java     | 13 ++++--
 .../cassandra/auth/PasswordAuthenticator.java   | 42 ++++++++++++++------
 3 files changed, 41 insertions(+), 15 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/9e8b7c0d/CHANGES.txt
----------------------------------------------------------------------


[02/10] cassandra git commit: Prepare legacy auth statements if tables initialised after node startup

Posted by sa...@apache.org.
Prepare legacy auth statements if tables initialised after node startup

Patch by Alex Petrov; reviewed by Sam Tunnicliffe for CASSANDRA-12813


Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/312e21bd
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/312e21bd
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/312e21bd

Branch: refs/heads/cassandra-3.0
Commit: 312e21bda7c50f05fc5f8868740b513022385951
Parents: eaf46a1
Author: Alex Petrov <ol...@gmail.com>
Authored: Fri Oct 21 16:58:33 2016 +0200
Committer: Sam Tunnicliffe <sa...@beobal.com>
Committed: Fri Oct 28 16:04:36 2016 +0100

----------------------------------------------------------------------
 CHANGES.txt                                     |  1 +
 .../cassandra/auth/CassandraAuthorizer.java     | 14 +++++--
 .../cassandra/auth/PasswordAuthenticator.java   | 40 ++++++++++++++------
 3 files changed, 40 insertions(+), 15 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/312e21bd/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index a22439b..b33ef8d 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,5 @@
 2.2.9
+ * Prepare legacy authenticate statement if credentials table initialised after node startup (CASSANDRA-12813)
  * Change cassandra.wait_for_tracing_events_timeout_secs default to 0 (CASSANDRA-12754)
  * Clean up permissions when a UDA is dropped (CASSANDRA-12720)
  * Limit colUpdateTimeDelta histogram updates to reasonable deltas (CASSANDRA-11117)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/312e21bd/src/java/org/apache/cassandra/auth/CassandraAuthorizer.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/auth/CassandraAuthorizer.java b/src/java/org/apache/cassandra/auth/CassandraAuthorizer.java
index 88069a2..360d59a 100644
--- a/src/java/org/apache/cassandra/auth/CassandraAuthorizer.java
+++ b/src/java/org/apache/cassandra/auth/CassandraAuthorizer.java
@@ -209,11 +209,19 @@ public class CassandraAuthorizer implements IAuthorizer
                                                              Lists.newArrayList(ByteBufferUtil.bytes(role.getRoleName()),
                                                                                 ByteBufferUtil.bytes(resource.getName())));
 
+        SelectStatement statement;
         // If it exists, read from the legacy user permissions table to handle the case where the cluster
         // is being upgraded and so is running with mixed versions of the authz schema
-        SelectStatement statement = Schema.instance.getCFMetaData(AuthKeyspace.NAME, USER_PERMISSIONS) == null
-                                    ? authorizeRoleStatement
-                                    : legacyAuthorizeRoleStatement;
+        if (Schema.instance.getCFMetaData(AuthKeyspace.NAME, USER_PERMISSIONS) == null)
+            statement = authorizeRoleStatement;
+        else
+        {
+            // If the permissions table was initialised only after the statement got prepared, re-prepare (CASSANDRA-12813)
+            if (legacyAuthorizeRoleStatement == null)
+                legacyAuthorizeRoleStatement = prepare(USERNAME, USER_PERMISSIONS);
+            statement = legacyAuthorizeRoleStatement;
+        }
+
         ResultMessage.Rows rows = statement.execute(QueryState.forInternalCalls(), options) ;
         UntypedResultSet result = UntypedResultSet.create(rows.result);
 

http://git-wip-us.apache.org/repos/asf/cassandra/blob/312e21bd/src/java/org/apache/cassandra/auth/PasswordAuthenticator.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/auth/PasswordAuthenticator.java b/src/java/org/apache/cassandra/auth/PasswordAuthenticator.java
index c0d2283..20f8790 100644
--- a/src/java/org/apache/cassandra/auth/PasswordAuthenticator.java
+++ b/src/java/org/apache/cassandra/auth/PasswordAuthenticator.java
@@ -77,11 +77,7 @@ public class PasswordAuthenticator implements IAuthenticator
     {
         try
         {
-            // If the legacy users table exists try to verify credentials there. This is to handle the case
-            // where the cluster is being upgraded and so is running with mixed versions of the authn tables
-            SelectStatement authenticationStatement = Schema.instance.getCFMetaData(AuthKeyspace.NAME, LEGACY_CREDENTIALS_TABLE) == null
-                                                    ? authenticateStatement
-                                                    : legacyAuthenticateStatement;
+            SelectStatement authenticationStatement = authenticationStatement();
             return doAuthenticate(username, password, authenticationStatement);
         }
         catch (RequestExecutionException e)
@@ -91,6 +87,23 @@ public class PasswordAuthenticator implements IAuthenticator
         }
     }
 
+    /**
+     * If the legacy users table exists try to verify credentials there. This is to handle the case
+     * where the cluster is being upgraded and so is running with mixed versions of the authn tables
+     */
+    private SelectStatement authenticationStatement()
+    {
+        if (Schema.instance.getCFMetaData(AuthKeyspace.NAME, LEGACY_CREDENTIALS_TABLE) == null)
+            return authenticateStatement;
+        else
+        {
+            // If the credentials was initialised only after statement got prepared, re-prepare (CASSANDRA-12813).
+            if (legacyAuthenticateStatement == null)
+                prepareLegacyAuthenticateStatement();
+            return legacyAuthenticateStatement;
+        }
+    }
+
     public Set<DataResource> protectedResources()
     {
         // Also protected by CassandraRoleManager, but the duplication doesn't hurt and is more explicit
@@ -110,13 +123,16 @@ public class PasswordAuthenticator implements IAuthenticator
         authenticateStatement = prepare(query);
 
         if (Schema.instance.getCFMetaData(AuthKeyspace.NAME, LEGACY_CREDENTIALS_TABLE) != null)
-        {
-            query = String.format("SELECT %s from %s.%s WHERE username = ?",
-                                  SALTED_HASH,
-                                  AuthKeyspace.NAME,
-                                  LEGACY_CREDENTIALS_TABLE);
-            legacyAuthenticateStatement = prepare(query);
-        }
+            prepareLegacyAuthenticateStatement();
+    }
+
+    private void prepareLegacyAuthenticateStatement()
+    {
+        String query = String.format("SELECT %s from %s.%s WHERE username = ?",
+                                     SALTED_HASH,
+                                     AuthKeyspace.NAME,
+                                     LEGACY_CREDENTIALS_TABLE);
+        legacyAuthenticateStatement = prepare(query);
     }
 
     public AuthenticatedUser legacyAuthenticate(Map<String, String> credentials) throws AuthenticationException


[05/10] cassandra git commit: Merge branch 'cassandra-2.2' into cassandra-3.0

Posted by sa...@apache.org.
Merge branch 'cassandra-2.2' into cassandra-3.0


Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/e4f840aa
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/e4f840aa
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/e4f840aa

Branch: refs/heads/cassandra-3.X
Commit: e4f840aa1f84f008cf7c14bdd6a22aebd1b41c70
Parents: e9ff6ae 312e21b
Author: Sam Tunnicliffe <sa...@beobal.com>
Authored: Fri Oct 28 16:08:29 2016 +0100
Committer: Sam Tunnicliffe <sa...@beobal.com>
Committed: Fri Oct 28 16:08:29 2016 +0100

----------------------------------------------------------------------
 CHANGES.txt                                     |  1 +
 .../cassandra/auth/CassandraAuthorizer.java     | 14 +++++--
 .../cassandra/auth/PasswordAuthenticator.java   | 40 ++++++++++++++------
 3 files changed, 40 insertions(+), 15 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/e4f840aa/CHANGES.txt
----------------------------------------------------------------------
diff --cc CHANGES.txt
index 9910245,b33ef8d..bf1e7d6
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@@ -1,30 -1,5 +1,31 @@@
 -2.2.9
 +3.0.10
 + * Fix for KeyCacheCqlTest flakiness (CASSANDRA-12801)
 + * Include SSTable filename in compacting large row message (CASSANDRA-12384)
 + * Fix potential socket leak (CASSANDRA-12329, CASSANDRA-12330)
 + * Fix ViewTest.testCompaction (CASSANDRA-12789)
 + * Improve avg aggregate functions (CASSANDRA-12417)
 + * Preserve quoted reserved keyword column names in MV creation (CASSANDRA-11803)
 + * nodetool stopdaemon errors out (CASSANDRA-12646)
 + * Split materialized view mutations on build to prevent OOM (CASSANDRA-12268)
 + * mx4j does not work in 3.0.8 (CASSANDRA-12274)
 + * Abort cqlsh copy-from in case of no answer after prolonged period of time (CASSANDRA-12740)
 + * Avoid sstable corrupt exception due to dropped static column (CASSANDRA-12582)
 + * Make stress use client mode to avoid checking commit log size on startup (CASSANDRA-12478)
 + * Fix exceptions with new vnode allocation (CASSANDRA-12715)
 + * Unify drain and shutdown processes (CASSANDRA-12509)
 + * Fix NPE in ComponentOfSlice.isEQ() (CASSANDRA-12706)
 + * Fix failure in LogTransactionTest (CASSANDRA-12632)
 + * Fix potentially incomplete non-frozen UDT values when querying with the
 +   full primary key specified (CASSANDRA-12605)
 + * Skip writing MV mutations to commitlog on mutation.applyUnsafe() (CASSANDRA-11670)
 + * Establish consistent distinction between non-existing partition and NULL value for LWTs on static columns (CASSANDRA-12060)
 + * Extend ColumnIdentifier.internedInstances key to include the type that generated the byte buffer (CASSANDRA-12516)
 + * Backport CASSANDRA-10756 (race condition in NativeTransportService shutdown) (CASSANDRA-12472)
 + * If CF has no clustering columns, any row cache is full partition cache (CASSANDRA-12499)
 + * Correct log message for statistics of offheap memtable flush (CASSANDRA-12776)
 + * Explicitly set locale for string validation (CASSANDRA-12541,CASSANDRA-12542,CASSANDRA-12543,CASSANDRA-12545)
 +Merged from 2.2:
+  * Prepare legacy authenticate statement if credentials table initialised after node startup (CASSANDRA-12813)
   * Change cassandra.wait_for_tracing_events_timeout_secs default to 0 (CASSANDRA-12754)
   * Clean up permissions when a UDA is dropped (CASSANDRA-12720)
   * Limit colUpdateTimeDelta histogram updates to reasonable deltas (CASSANDRA-11117)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/e4f840aa/src/java/org/apache/cassandra/auth/CassandraAuthorizer.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/cassandra/blob/e4f840aa/src/java/org/apache/cassandra/auth/PasswordAuthenticator.java
----------------------------------------------------------------------


[07/10] cassandra git commit: Merge branch 'cassandra-2.2' into cassandra-3.0

Posted by sa...@apache.org.
Merge branch 'cassandra-2.2' into cassandra-3.0


Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/e4f840aa
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/e4f840aa
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/e4f840aa

Branch: refs/heads/trunk
Commit: e4f840aa1f84f008cf7c14bdd6a22aebd1b41c70
Parents: e9ff6ae 312e21b
Author: Sam Tunnicliffe <sa...@beobal.com>
Authored: Fri Oct 28 16:08:29 2016 +0100
Committer: Sam Tunnicliffe <sa...@beobal.com>
Committed: Fri Oct 28 16:08:29 2016 +0100

----------------------------------------------------------------------
 CHANGES.txt                                     |  1 +
 .../cassandra/auth/CassandraAuthorizer.java     | 14 +++++--
 .../cassandra/auth/PasswordAuthenticator.java   | 40 ++++++++++++++------
 3 files changed, 40 insertions(+), 15 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/e4f840aa/CHANGES.txt
----------------------------------------------------------------------
diff --cc CHANGES.txt
index 9910245,b33ef8d..bf1e7d6
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@@ -1,30 -1,5 +1,31 @@@
 -2.2.9
 +3.0.10
 + * Fix for KeyCacheCqlTest flakiness (CASSANDRA-12801)
 + * Include SSTable filename in compacting large row message (CASSANDRA-12384)
 + * Fix potential socket leak (CASSANDRA-12329, CASSANDRA-12330)
 + * Fix ViewTest.testCompaction (CASSANDRA-12789)
 + * Improve avg aggregate functions (CASSANDRA-12417)
 + * Preserve quoted reserved keyword column names in MV creation (CASSANDRA-11803)
 + * nodetool stopdaemon errors out (CASSANDRA-12646)
 + * Split materialized view mutations on build to prevent OOM (CASSANDRA-12268)
 + * mx4j does not work in 3.0.8 (CASSANDRA-12274)
 + * Abort cqlsh copy-from in case of no answer after prolonged period of time (CASSANDRA-12740)
 + * Avoid sstable corrupt exception due to dropped static column (CASSANDRA-12582)
 + * Make stress use client mode to avoid checking commit log size on startup (CASSANDRA-12478)
 + * Fix exceptions with new vnode allocation (CASSANDRA-12715)
 + * Unify drain and shutdown processes (CASSANDRA-12509)
 + * Fix NPE in ComponentOfSlice.isEQ() (CASSANDRA-12706)
 + * Fix failure in LogTransactionTest (CASSANDRA-12632)
 + * Fix potentially incomplete non-frozen UDT values when querying with the
 +   full primary key specified (CASSANDRA-12605)
 + * Skip writing MV mutations to commitlog on mutation.applyUnsafe() (CASSANDRA-11670)
 + * Establish consistent distinction between non-existing partition and NULL value for LWTs on static columns (CASSANDRA-12060)
 + * Extend ColumnIdentifier.internedInstances key to include the type that generated the byte buffer (CASSANDRA-12516)
 + * Backport CASSANDRA-10756 (race condition in NativeTransportService shutdown) (CASSANDRA-12472)
 + * If CF has no clustering columns, any row cache is full partition cache (CASSANDRA-12499)
 + * Correct log message for statistics of offheap memtable flush (CASSANDRA-12776)
 + * Explicitly set locale for string validation (CASSANDRA-12541,CASSANDRA-12542,CASSANDRA-12543,CASSANDRA-12545)
 +Merged from 2.2:
+  * Prepare legacy authenticate statement if credentials table initialised after node startup (CASSANDRA-12813)
   * Change cassandra.wait_for_tracing_events_timeout_secs default to 0 (CASSANDRA-12754)
   * Clean up permissions when a UDA is dropped (CASSANDRA-12720)
   * Limit colUpdateTimeDelta histogram updates to reasonable deltas (CASSANDRA-11117)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/e4f840aa/src/java/org/apache/cassandra/auth/CassandraAuthorizer.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/cassandra/blob/e4f840aa/src/java/org/apache/cassandra/auth/PasswordAuthenticator.java
----------------------------------------------------------------------


[08/10] cassandra git commit: Merge branch 'cassandra-3.0' into cassandra-3.X

Posted by sa...@apache.org.
Merge branch 'cassandra-3.0' into cassandra-3.X


Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/9be467a2
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/9be467a2
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/9be467a2

Branch: refs/heads/cassandra-3.X
Commit: 9be467a22ab646c23710eb2b23dd21e5a46b07bd
Parents: 49ce0a4 e4f840a
Author: Sam Tunnicliffe <sa...@beobal.com>
Authored: Fri Oct 28 16:11:13 2016 +0100
Committer: Sam Tunnicliffe <sa...@beobal.com>
Committed: Fri Oct 28 16:17:52 2016 +0100

----------------------------------------------------------------------
 CHANGES.txt                                     |  1 +
 .../cassandra/auth/CassandraAuthorizer.java     | 13 ++++--
 .../cassandra/auth/PasswordAuthenticator.java   | 42 ++++++++++++++------
 3 files changed, 41 insertions(+), 15 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/9be467a2/CHANGES.txt
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/cassandra/blob/9be467a2/src/java/org/apache/cassandra/auth/CassandraAuthorizer.java
----------------------------------------------------------------------
diff --cc src/java/org/apache/cassandra/auth/CassandraAuthorizer.java
index 8c3485d,7ffef27..7f44eef
--- a/src/java/org/apache/cassandra/auth/CassandraAuthorizer.java
+++ b/src/java/org/apache/cassandra/auth/CassandraAuthorizer.java
@@@ -215,12 -209,20 +215,19 @@@ public class CassandraAuthorizer implem
                                                               Lists.newArrayList(ByteBufferUtil.bytes(role.getRoleName()),
                                                                                  ByteBufferUtil.bytes(resource.getName())));
  
+         SelectStatement statement;
          // If it exists, read from the legacy user permissions table to handle the case where the cluster
          // is being upgraded and so is running with mixed versions of the authz schema
-         SelectStatement statement = Schema.instance.getCFMetaData(SchemaConstants.AUTH_KEYSPACE_NAME, USER_PERMISSIONS) == null
-                                     ? authorizeRoleStatement
-                                     : legacyAuthorizeRoleStatement;
 -        if (Schema.instance.getCFMetaData(AuthKeyspace.NAME, USER_PERMISSIONS) == null)
++        if (Schema.instance.getCFMetaData(SchemaConstants.AUTH_KEYSPACE_NAME, USER_PERMISSIONS) == null)
+             statement = authorizeRoleStatement;
+         else
+         {
+             // If the permissions table was initialised only after the statement got prepared, re-prepare (CASSANDRA-12813)
+             if (legacyAuthorizeRoleStatement == null)
+                 legacyAuthorizeRoleStatement = prepare(USERNAME, USER_PERMISSIONS);
+             statement = legacyAuthorizeRoleStatement;
+         }
 -
 -        ResultMessage.Rows rows = statement.execute(QueryState.forInternalCalls(), options) ;
 +        ResultMessage.Rows rows = statement.execute(QueryState.forInternalCalls(), options, System.nanoTime());
          UntypedResultSet result = UntypedResultSet.create(rows.result);
  
          if (!result.isEmpty() && result.one().has(PERMISSIONS))

http://git-wip-us.apache.org/repos/asf/cassandra/blob/9be467a2/src/java/org/apache/cassandra/auth/PasswordAuthenticator.java
----------------------------------------------------------------------
diff --cc src/java/org/apache/cassandra/auth/PasswordAuthenticator.java
index b0317f3,ca610d1..4b667ae
--- a/src/java/org/apache/cassandra/auth/PasswordAuthenticator.java
+++ b/src/java/org/apache/cassandra/auth/PasswordAuthenticator.java
@@@ -86,56 -78,8 +86,52 @@@ public class PasswordAuthenticator impl
      {
          try
          {
 +            String hash = cache.get(username);
 +            if (!BCrypt.checkpw(password, hash))
 +                throw new AuthenticationException(String.format("Provided username %s and/or password are incorrect", username));
 +
 +            return new AuthenticatedUser(username);
 +        }
 +        catch (ExecutionException | UncheckedExecutionException e)
 +        {
 +            // the credentials were somehow invalid - either a non-existent role, or one without a defined password
 +            if (e.getCause() instanceof NoSuchCredentialsException)
 +                throw new AuthenticationException(String.format("Provided username %s and/or password are incorrect", username));
 +
 +            // an unanticipated exception occured whilst querying the credentials table
 +            if (e.getCause() instanceof RequestExecutionException)
 +            {
 +                logger.trace("Error performing internal authentication", e);
 +                throw new AuthenticationException(String.format("Error during authentication of user %s : %s", username, e.getMessage()));
 +            }
 +
 +            throw new RuntimeException(e);
 +        }
 +    }
 +
 +    private String queryHashedPassword(String username) throws NoSuchCredentialsException
 +    {
 +        try
 +        {
-             // If the legacy users table exists try to verify credentials there. This is to handle the case
-             // where the cluster is being upgraded and so is running with mixed versions of the authn tables
-             SelectStatement authenticationStatement = Schema.instance.getCFMetaData(SchemaConstants.AUTH_KEYSPACE_NAME, LEGACY_CREDENTIALS_TABLE) == null
-                                                     ? authenticateStatement
-                                                     : legacyAuthenticateStatement;
+             SelectStatement authenticationStatement = authenticationStatement();
 -            return doAuthenticate(username, password, authenticationStatement);
 +
 +            ResultMessage.Rows rows =
 +                authenticationStatement.execute(QueryState.forInternalCalls(),
 +                                                QueryOptions.forInternalCalls(consistencyForRole(username),
 +                                                                              Lists.newArrayList(ByteBufferUtil.bytes(username))),
 +                                                System.nanoTime());
 +
 +            // If either a non-existent role name was supplied, or no credentials
 +            // were found for that role we don't want to cache the result so we throw
 +            // a specific, but unchecked, exception to keep LoadingCache happy.
 +            if (rows.result.isEmpty())
 +                throw new NoSuchCredentialsException();
 +
 +            UntypedResultSet result = UntypedResultSet.create(rows.result);
 +            if (!result.one().has(SALTED_HASH))
 +                throw new NoSuchCredentialsException();
 +
 +            return result.one().getString(SALTED_HASH);
          }
          catch (RequestExecutionException e)
          {
@@@ -144,6 -88,23 +140,25 @@@
          }
      }
  
+     /**
+      * If the legacy users table exists try to verify credentials there. This is to handle the case
+      * where the cluster is being upgraded and so is running with mixed versions of the authn tables
+      */
+     private SelectStatement authenticationStatement()
+     {
 -        if (Schema.instance.getCFMetaData(AuthKeyspace.NAME, LEGACY_CREDENTIALS_TABLE) == null)
++        if (Schema.instance.getCFMetaData(SchemaConstants.AUTH_KEYSPACE_NAME, LEGACY_CREDENTIALS_TABLE) == null)
+             return authenticateStatement;
+         else
+         {
++            // the statement got prepared, we to try preparing it again.
+             // If the credentials was initialised only after statement got prepared, re-prepare (CASSANDRA-12813).
+             if (legacyAuthenticateStatement == null)
+                 prepareLegacyAuthenticateStatement();
+             return legacyAuthenticateStatement;
+         }
+     }
+ 
++
      public Set<DataResource> protectedResources()
      {
          // Also protected by CassandraRoleManager, but the duplication doesn't hurt and is more explicit
@@@ -162,18 -123,19 +177,21 @@@
                                       AuthKeyspace.ROLES);
          authenticateStatement = prepare(query);
  
 -        if (Schema.instance.getCFMetaData(AuthKeyspace.NAME, LEGACY_CREDENTIALS_TABLE) != null)
 +        if (Schema.instance.getCFMetaData(SchemaConstants.AUTH_KEYSPACE_NAME, LEGACY_CREDENTIALS_TABLE) != null)
-         {
-             query = String.format("SELECT %s from %s.%s WHERE username = ?",
-                                   SALTED_HASH,
-                                   SchemaConstants.AUTH_KEYSPACE_NAME,
-                                   LEGACY_CREDENTIALS_TABLE);
-             legacyAuthenticateStatement = prepare(query);
-         }
+             prepareLegacyAuthenticateStatement();
 +
 +        cache = new CredentialsCache(this);
      }
  
+     private void prepareLegacyAuthenticateStatement()
+     {
+         String query = String.format("SELECT %s from %s.%s WHERE username = ?",
+                                      SALTED_HASH,
 -                                     AuthKeyspace.NAME,
++                                     SchemaConstants.AUTH_KEYSPACE_NAME,
+                                      LEGACY_CREDENTIALS_TABLE);
+         legacyAuthenticateStatement = prepare(query);
+     }
+ 
      public AuthenticatedUser legacyAuthenticate(Map<String, String> credentials) throws AuthenticationException
      {
          String username = credentials.get(USERNAME_KEY);


[04/10] cassandra git commit: Prepare legacy auth statements if tables initialised after node startup

Posted by sa...@apache.org.
Prepare legacy auth statements if tables initialised after node startup

Patch by Alex Petrov; reviewed by Sam Tunnicliffe for CASSANDRA-12813


Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/312e21bd
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/312e21bd
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/312e21bd

Branch: refs/heads/trunk
Commit: 312e21bda7c50f05fc5f8868740b513022385951
Parents: eaf46a1
Author: Alex Petrov <ol...@gmail.com>
Authored: Fri Oct 21 16:58:33 2016 +0200
Committer: Sam Tunnicliffe <sa...@beobal.com>
Committed: Fri Oct 28 16:04:36 2016 +0100

----------------------------------------------------------------------
 CHANGES.txt                                     |  1 +
 .../cassandra/auth/CassandraAuthorizer.java     | 14 +++++--
 .../cassandra/auth/PasswordAuthenticator.java   | 40 ++++++++++++++------
 3 files changed, 40 insertions(+), 15 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/312e21bd/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index a22439b..b33ef8d 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,5 @@
 2.2.9
+ * Prepare legacy authenticate statement if credentials table initialised after node startup (CASSANDRA-12813)
  * Change cassandra.wait_for_tracing_events_timeout_secs default to 0 (CASSANDRA-12754)
  * Clean up permissions when a UDA is dropped (CASSANDRA-12720)
  * Limit colUpdateTimeDelta histogram updates to reasonable deltas (CASSANDRA-11117)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/312e21bd/src/java/org/apache/cassandra/auth/CassandraAuthorizer.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/auth/CassandraAuthorizer.java b/src/java/org/apache/cassandra/auth/CassandraAuthorizer.java
index 88069a2..360d59a 100644
--- a/src/java/org/apache/cassandra/auth/CassandraAuthorizer.java
+++ b/src/java/org/apache/cassandra/auth/CassandraAuthorizer.java
@@ -209,11 +209,19 @@ public class CassandraAuthorizer implements IAuthorizer
                                                              Lists.newArrayList(ByteBufferUtil.bytes(role.getRoleName()),
                                                                                 ByteBufferUtil.bytes(resource.getName())));
 
+        SelectStatement statement;
         // If it exists, read from the legacy user permissions table to handle the case where the cluster
         // is being upgraded and so is running with mixed versions of the authz schema
-        SelectStatement statement = Schema.instance.getCFMetaData(AuthKeyspace.NAME, USER_PERMISSIONS) == null
-                                    ? authorizeRoleStatement
-                                    : legacyAuthorizeRoleStatement;
+        if (Schema.instance.getCFMetaData(AuthKeyspace.NAME, USER_PERMISSIONS) == null)
+            statement = authorizeRoleStatement;
+        else
+        {
+            // If the permissions table was initialised only after the statement got prepared, re-prepare (CASSANDRA-12813)
+            if (legacyAuthorizeRoleStatement == null)
+                legacyAuthorizeRoleStatement = prepare(USERNAME, USER_PERMISSIONS);
+            statement = legacyAuthorizeRoleStatement;
+        }
+
         ResultMessage.Rows rows = statement.execute(QueryState.forInternalCalls(), options) ;
         UntypedResultSet result = UntypedResultSet.create(rows.result);
 

http://git-wip-us.apache.org/repos/asf/cassandra/blob/312e21bd/src/java/org/apache/cassandra/auth/PasswordAuthenticator.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/auth/PasswordAuthenticator.java b/src/java/org/apache/cassandra/auth/PasswordAuthenticator.java
index c0d2283..20f8790 100644
--- a/src/java/org/apache/cassandra/auth/PasswordAuthenticator.java
+++ b/src/java/org/apache/cassandra/auth/PasswordAuthenticator.java
@@ -77,11 +77,7 @@ public class PasswordAuthenticator implements IAuthenticator
     {
         try
         {
-            // If the legacy users table exists try to verify credentials there. This is to handle the case
-            // where the cluster is being upgraded and so is running with mixed versions of the authn tables
-            SelectStatement authenticationStatement = Schema.instance.getCFMetaData(AuthKeyspace.NAME, LEGACY_CREDENTIALS_TABLE) == null
-                                                    ? authenticateStatement
-                                                    : legacyAuthenticateStatement;
+            SelectStatement authenticationStatement = authenticationStatement();
             return doAuthenticate(username, password, authenticationStatement);
         }
         catch (RequestExecutionException e)
@@ -91,6 +87,23 @@ public class PasswordAuthenticator implements IAuthenticator
         }
     }
 
+    /**
+     * If the legacy users table exists try to verify credentials there. This is to handle the case
+     * where the cluster is being upgraded and so is running with mixed versions of the authn tables
+     */
+    private SelectStatement authenticationStatement()
+    {
+        if (Schema.instance.getCFMetaData(AuthKeyspace.NAME, LEGACY_CREDENTIALS_TABLE) == null)
+            return authenticateStatement;
+        else
+        {
+            // If the credentials was initialised only after statement got prepared, re-prepare (CASSANDRA-12813).
+            if (legacyAuthenticateStatement == null)
+                prepareLegacyAuthenticateStatement();
+            return legacyAuthenticateStatement;
+        }
+    }
+
     public Set<DataResource> protectedResources()
     {
         // Also protected by CassandraRoleManager, but the duplication doesn't hurt and is more explicit
@@ -110,13 +123,16 @@ public class PasswordAuthenticator implements IAuthenticator
         authenticateStatement = prepare(query);
 
         if (Schema.instance.getCFMetaData(AuthKeyspace.NAME, LEGACY_CREDENTIALS_TABLE) != null)
-        {
-            query = String.format("SELECT %s from %s.%s WHERE username = ?",
-                                  SALTED_HASH,
-                                  AuthKeyspace.NAME,
-                                  LEGACY_CREDENTIALS_TABLE);
-            legacyAuthenticateStatement = prepare(query);
-        }
+            prepareLegacyAuthenticateStatement();
+    }
+
+    private void prepareLegacyAuthenticateStatement()
+    {
+        String query = String.format("SELECT %s from %s.%s WHERE username = ?",
+                                     SALTED_HASH,
+                                     AuthKeyspace.NAME,
+                                     LEGACY_CREDENTIALS_TABLE);
+        legacyAuthenticateStatement = prepare(query);
     }
 
     public AuthenticatedUser legacyAuthenticate(Map<String, String> credentials) throws AuthenticationException


[03/10] cassandra git commit: Prepare legacy auth statements if tables initialised after node startup

Posted by sa...@apache.org.
Prepare legacy auth statements if tables initialised after node startup

Patch by Alex Petrov; reviewed by Sam Tunnicliffe for CASSANDRA-12813


Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/312e21bd
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/312e21bd
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/312e21bd

Branch: refs/heads/cassandra-3.X
Commit: 312e21bda7c50f05fc5f8868740b513022385951
Parents: eaf46a1
Author: Alex Petrov <ol...@gmail.com>
Authored: Fri Oct 21 16:58:33 2016 +0200
Committer: Sam Tunnicliffe <sa...@beobal.com>
Committed: Fri Oct 28 16:04:36 2016 +0100

----------------------------------------------------------------------
 CHANGES.txt                                     |  1 +
 .../cassandra/auth/CassandraAuthorizer.java     | 14 +++++--
 .../cassandra/auth/PasswordAuthenticator.java   | 40 ++++++++++++++------
 3 files changed, 40 insertions(+), 15 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/312e21bd/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index a22439b..b33ef8d 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,5 @@
 2.2.9
+ * Prepare legacy authenticate statement if credentials table initialised after node startup (CASSANDRA-12813)
  * Change cassandra.wait_for_tracing_events_timeout_secs default to 0 (CASSANDRA-12754)
  * Clean up permissions when a UDA is dropped (CASSANDRA-12720)
  * Limit colUpdateTimeDelta histogram updates to reasonable deltas (CASSANDRA-11117)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/312e21bd/src/java/org/apache/cassandra/auth/CassandraAuthorizer.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/auth/CassandraAuthorizer.java b/src/java/org/apache/cassandra/auth/CassandraAuthorizer.java
index 88069a2..360d59a 100644
--- a/src/java/org/apache/cassandra/auth/CassandraAuthorizer.java
+++ b/src/java/org/apache/cassandra/auth/CassandraAuthorizer.java
@@ -209,11 +209,19 @@ public class CassandraAuthorizer implements IAuthorizer
                                                              Lists.newArrayList(ByteBufferUtil.bytes(role.getRoleName()),
                                                                                 ByteBufferUtil.bytes(resource.getName())));
 
+        SelectStatement statement;
         // If it exists, read from the legacy user permissions table to handle the case where the cluster
         // is being upgraded and so is running with mixed versions of the authz schema
-        SelectStatement statement = Schema.instance.getCFMetaData(AuthKeyspace.NAME, USER_PERMISSIONS) == null
-                                    ? authorizeRoleStatement
-                                    : legacyAuthorizeRoleStatement;
+        if (Schema.instance.getCFMetaData(AuthKeyspace.NAME, USER_PERMISSIONS) == null)
+            statement = authorizeRoleStatement;
+        else
+        {
+            // If the permissions table was initialised only after the statement got prepared, re-prepare (CASSANDRA-12813)
+            if (legacyAuthorizeRoleStatement == null)
+                legacyAuthorizeRoleStatement = prepare(USERNAME, USER_PERMISSIONS);
+            statement = legacyAuthorizeRoleStatement;
+        }
+
         ResultMessage.Rows rows = statement.execute(QueryState.forInternalCalls(), options) ;
         UntypedResultSet result = UntypedResultSet.create(rows.result);
 

http://git-wip-us.apache.org/repos/asf/cassandra/blob/312e21bd/src/java/org/apache/cassandra/auth/PasswordAuthenticator.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/auth/PasswordAuthenticator.java b/src/java/org/apache/cassandra/auth/PasswordAuthenticator.java
index c0d2283..20f8790 100644
--- a/src/java/org/apache/cassandra/auth/PasswordAuthenticator.java
+++ b/src/java/org/apache/cassandra/auth/PasswordAuthenticator.java
@@ -77,11 +77,7 @@ public class PasswordAuthenticator implements IAuthenticator
     {
         try
         {
-            // If the legacy users table exists try to verify credentials there. This is to handle the case
-            // where the cluster is being upgraded and so is running with mixed versions of the authn tables
-            SelectStatement authenticationStatement = Schema.instance.getCFMetaData(AuthKeyspace.NAME, LEGACY_CREDENTIALS_TABLE) == null
-                                                    ? authenticateStatement
-                                                    : legacyAuthenticateStatement;
+            SelectStatement authenticationStatement = authenticationStatement();
             return doAuthenticate(username, password, authenticationStatement);
         }
         catch (RequestExecutionException e)
@@ -91,6 +87,23 @@ public class PasswordAuthenticator implements IAuthenticator
         }
     }
 
+    /**
+     * If the legacy users table exists try to verify credentials there. This is to handle the case
+     * where the cluster is being upgraded and so is running with mixed versions of the authn tables
+     */
+    private SelectStatement authenticationStatement()
+    {
+        if (Schema.instance.getCFMetaData(AuthKeyspace.NAME, LEGACY_CREDENTIALS_TABLE) == null)
+            return authenticateStatement;
+        else
+        {
+            // If the credentials was initialised only after statement got prepared, re-prepare (CASSANDRA-12813).
+            if (legacyAuthenticateStatement == null)
+                prepareLegacyAuthenticateStatement();
+            return legacyAuthenticateStatement;
+        }
+    }
+
     public Set<DataResource> protectedResources()
     {
         // Also protected by CassandraRoleManager, but the duplication doesn't hurt and is more explicit
@@ -110,13 +123,16 @@ public class PasswordAuthenticator implements IAuthenticator
         authenticateStatement = prepare(query);
 
         if (Schema.instance.getCFMetaData(AuthKeyspace.NAME, LEGACY_CREDENTIALS_TABLE) != null)
-        {
-            query = String.format("SELECT %s from %s.%s WHERE username = ?",
-                                  SALTED_HASH,
-                                  AuthKeyspace.NAME,
-                                  LEGACY_CREDENTIALS_TABLE);
-            legacyAuthenticateStatement = prepare(query);
-        }
+            prepareLegacyAuthenticateStatement();
+    }
+
+    private void prepareLegacyAuthenticateStatement()
+    {
+        String query = String.format("SELECT %s from %s.%s WHERE username = ?",
+                                     SALTED_HASH,
+                                     AuthKeyspace.NAME,
+                                     LEGACY_CREDENTIALS_TABLE);
+        legacyAuthenticateStatement = prepare(query);
     }
 
     public AuthenticatedUser legacyAuthenticate(Map<String, String> credentials) throws AuthenticationException