From d909fb4faf7de41b3cf19f19b48f962ab0e6fb32 Mon Sep 17 00:00:00 2001 From: Brandon Williams Date: Tue, 6 Nov 2012 06:23:15 -0600 Subject: [PATCH 1/2] Fix row key population with old-style mapred interface. Patch by Ben Kempe, reviewed by brandonwilliams for CASSANDRA-4834 --- .../org/apache/cassandra/hadoop/ColumnFamilyRecordReader.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/java/org/apache/cassandra/hadoop/ColumnFamilyRecordReader.java b/src/java/org/apache/cassandra/hadoop/ColumnFamilyRecordReader.java index c662932926..83e436b5a0 100644 --- a/src/java/org/apache/cassandra/hadoop/ColumnFamilyRecordReader.java +++ b/src/java/org/apache/cassandra/hadoop/ColumnFamilyRecordReader.java @@ -483,7 +483,7 @@ public class ColumnFamilyRecordReader extends RecordReader> next = wideColumns.next(); - lastColumn = next.right.values().iterator().next().name(); + lastColumn = next.right.values().iterator().next().name().duplicate(); maybeIncreaseRowCounter(next); return next; @@ -556,7 +556,7 @@ public class ColumnFamilyRecordReader extends RecordReader Date: Wed, 7 Nov 2012 10:48:23 -0600 Subject: [PATCH 2/2] remove IAuthority2 patch by Aleksey Yeschenko; reviewed by jbellis for CASSANDRA-4875 --- CHANGES.txt | 1 + .../apache/cassandra/auth/IAuthority2.java | 69 ---------------- .../cassandra/auth/IAuthorityContainer.java | 82 ------------------- .../org/apache/cassandra/auth/Permission.java | 32 +------- .../cassandra/config/DatabaseDescriptor.java | 11 --- .../apache/cassandra/cql/DeleteStatement.java | 2 +- .../apache/cassandra/cql/QueryProcessor.java | 22 ++--- .../apache/cassandra/cql/UpdateStatement.java | 2 +- .../org/apache/cassandra/cql3/CFName.java | 5 -- src/java/org/apache/cassandra/cql3/Cql.g | 66 +-------------- .../statements/AlterKeyspaceStatement.java | 2 +- .../cql3/statements/AlterTableStatement.java | 2 +- .../cql3/statements/BatchStatement.java | 2 +- .../CreateColumnFamilyStatement.java | 2 +- .../cql3/statements/CreateIndexStatement.java | 2 +- .../statements/CreateKeyspaceStatement.java | 2 +- .../statements/DropColumnFamilyStatement.java | 2 +- .../cql3/statements/DropIndexStatement.java | 2 +- .../statements/DropKeyspaceStatement.java | 2 +- .../cql3/statements/GrantStatement.java | 66 --------------- .../cql3/statements/ListGrantsStatement.java | 53 ------------ .../statements/ModificationStatement.java | 2 +- .../cql3/statements/RevokeStatement.java | 66 --------------- .../cql3/statements/SelectStatement.java | 2 +- .../cql3/statements/TruncateStatement.java | 2 +- .../apache/cassandra/service/ClientState.java | 76 ++--------------- .../cassandra/thrift/CassandraServer.java | 70 ++++++++-------- 27 files changed, 73 insertions(+), 574 deletions(-) delete mode 100644 src/java/org/apache/cassandra/auth/IAuthority2.java delete mode 100644 src/java/org/apache/cassandra/auth/IAuthorityContainer.java delete mode 100644 src/java/org/apache/cassandra/cql3/statements/GrantStatement.java delete mode 100644 src/java/org/apache/cassandra/cql3/statements/ListGrantsStatement.java delete mode 100644 src/java/org/apache/cassandra/cql3/statements/RevokeStatement.java diff --git a/CHANGES.txt b/CHANGES.txt index c033172333..2f945bb09e 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,4 +1,5 @@ 1.1.7 + * remove IAuthority2 (CASSANDRA-4875) * add get[Row|Key]CacheEntries to CacheServiceMBean (CASSANDRA-4859) * fix get_paged_slice to wrap to next row correctly (CASSANDRA-4816) * fix indexing empty column values (CASSANDRA-4832) diff --git a/src/java/org/apache/cassandra/auth/IAuthority2.java b/src/java/org/apache/cassandra/auth/IAuthority2.java deleted file mode 100644 index 14f0e53bb0..0000000000 --- a/src/java/org/apache/cassandra/auth/IAuthority2.java +++ /dev/null @@ -1,69 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.cassandra.auth; - -import org.apache.cassandra.cql3.CFName; -import org.apache.cassandra.thrift.CqlResult; -import org.apache.cassandra.thrift.InvalidRequestException; - -public interface IAuthority2 extends IAuthority -{ - /** - * Setup is called each time upon system startup - */ - public void setup(); - - /** - * GRANT ON TO [WITH GRANT OPTION]; - * - * @param granter The user who grants the permission - * @param permission The specific permission - * @param to Grantee of the permission - * @param resource The resource which is affect by permission change - * @param grantOption Does grantee has a permission to grant the same kind of permission on this particular resource? - * - * @throws InvalidRequestException upon parameter misconfiguration or internal error. - */ - public void grant(AuthenticatedUser granter, Permission permission, String to, CFName resource, boolean grantOption) throws InvalidRequestException; - - /** - * REVOKE ON FROM ; - * - * @param revoker The user know requests permission revoke - * @param permission The permission to revoke - * @param from The user to revoke permission from. - * @param resource The resource affected by permission change. - * - * @throws InvalidRequestException upon parameter misconfiguration or internal error. - */ - public void revoke(AuthenticatedUser revoker, Permission permission, String from, CFName resource) throws InvalidRequestException; - - /** - * LIST GRANTS FOR ; - * Not 'SHOW' because it's reserved for CQLsh for commands like 'show cluster' - * - * @param username The username to look for permissions. - * - * @return All of the permission of this particular user. - * - * @throws InvalidRequestException upon parameter misconfiguration or internal error. - */ - public CqlResult listPermissions(String username) throws InvalidRequestException; -} diff --git a/src/java/org/apache/cassandra/auth/IAuthorityContainer.java b/src/java/org/apache/cassandra/auth/IAuthorityContainer.java deleted file mode 100644 index 2279180169..0000000000 --- a/src/java/org/apache/cassandra/auth/IAuthorityContainer.java +++ /dev/null @@ -1,82 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.cassandra.auth; - -import org.apache.cassandra.cql3.CFName; -import org.apache.cassandra.thrift.CqlResult; -import org.apache.cassandra.thrift.InvalidRequestException; - -/** - * 1.1.x : Temporary measure to unable dynamic operations without changing IAuthority interface. - */ -public class IAuthorityContainer -{ - private final IAuthority authority; - private final IAuthority2 dynamicAuthority; - - public IAuthorityContainer(IAuthority authority) - { - this.authority = authority; - dynamicAuthority = (authority instanceof IAuthority2) ? ((IAuthority2) authority) : null; - } - - public void setup() - { - if (dynamicAuthority != null) - dynamicAuthority.setup(); - } - - public boolean isDynamic() - { - return dynamicAuthority != null; - } - - public IAuthority getAuthority() - { - return authority; - } - - public void grant(AuthenticatedUser granter, Permission permission, String to, CFName resource, boolean grantOption) throws InvalidRequestException - { - if (dynamicAuthority == null) - throw new InvalidRequestException("GRANT operation is not supported by your authority: " + authority); - - if (permission.equals(Permission.READ) || permission.equals(Permission.WRITE)) - throw new InvalidRequestException(String.format("Error setting permission to: %s, available permissions are %s", permission, Permission.GRANULAR_PERMISSIONS)); - - dynamicAuthority.grant(granter, permission, to, resource, grantOption); - } - - public void revoke(AuthenticatedUser revoker, Permission permission, String from, CFName resource) throws InvalidRequestException - { - if (dynamicAuthority == null) - throw new InvalidRequestException("REVOKE operation is not supported by your authority: " + authority); - - dynamicAuthority.revoke(revoker, permission, from, resource); - } - - public CqlResult listPermissions(String username) throws InvalidRequestException - { - if (dynamicAuthority == null) - throw new InvalidRequestException("LIST GRANTS operation is not supported by your authority: " + authority); - - return dynamicAuthority.listPermissions(username); - } -} diff --git a/src/java/org/apache/cassandra/auth/Permission.java b/src/java/org/apache/cassandra/auth/Permission.java index 65cbd29a41..4e48539cbe 100644 --- a/src/java/org/apache/cassandra/auth/Permission.java +++ b/src/java/org/apache/cassandra/auth/Permission.java @@ -22,8 +22,6 @@ package org.apache.cassandra.auth; import java.util.EnumSet; -import java.util.HashMap; -import java.util.Map; /** * An enum encapsulating the set of possible permissions that an authenticated user can have for a resource. @@ -32,35 +30,9 @@ import java.util.Map; */ public enum Permission { - READ, // for backward compatibility - WRITE, // for backward compatibility - - FULL_ACCESS, - NO_ACCESS, - - // schema management - DESCRIBE, - CREATE, - ALTER, - DROP, - - // data access - UPDATE, - DELETE, - SELECT; + READ, + WRITE; public static final EnumSet ALL = EnumSet.allOf(Permission.class); public static final EnumSet NONE = EnumSet.noneOf(Permission.class); - public static final EnumSet GRANULAR_PERMISSIONS = EnumSet.range(FULL_ACCESS, SELECT); - public static final EnumSet ALLOWED_SYSTEM_ACTIONS = EnumSet.of(DESCRIBE, UPDATE, DELETE, SELECT); - - /** - * Maps old permissions to the new ones as we want to support old client IAuthority implementations - * and new style of granular permission checking at the same time. - */ - public static final Map> oldToNew = new HashMap>(2) - {{ - put(READ, EnumSet.of(DESCRIBE, SELECT)); - put(WRITE, EnumSet.range(DESCRIBE, DELETE)); - }}; } diff --git a/src/java/org/apache/cassandra/config/DatabaseDescriptor.java b/src/java/org/apache/cassandra/config/DatabaseDescriptor.java index 20fa981d8d..0e9d705af7 100644 --- a/src/java/org/apache/cassandra/config/DatabaseDescriptor.java +++ b/src/java/org/apache/cassandra/config/DatabaseDescriptor.java @@ -72,7 +72,6 @@ public class DatabaseDescriptor private static IAuthenticator authenticator = new AllowAllAuthenticator(); private static IAuthority authority = new AllowAllAuthority(); - private static IAuthorityContainer authorityContainer; private final static String DEFAULT_CONFIGURATION = "cassandra.yaml"; @@ -204,8 +203,6 @@ public class DatabaseDescriptor authenticator.validateConfiguration(); authority.validateConfiguration(); - authorityContainer = new IAuthorityContainer(authority); - /* Hashing strategy */ if (conf.partitioner == null) { @@ -452,9 +449,6 @@ public class DatabaseDescriptor Schema.instance.addSystemTable(systemMeta); - // setup schema required for authorization - authorityContainer.setup(); - /* Load the seeds for node contact points */ if (conf.seed_provider == null) { @@ -578,11 +572,6 @@ public class DatabaseDescriptor return authority; } - public static IAuthorityContainer getAuthorityContainer() - { - return authorityContainer; - } - public static int getThriftMaxMessageLength() { return conf.thrift_max_message_length_in_mb * 1024 * 1024; diff --git a/src/java/org/apache/cassandra/cql/DeleteStatement.java b/src/java/org/apache/cassandra/cql/DeleteStatement.java index 72fee1363d..548244a6a1 100644 --- a/src/java/org/apache/cassandra/cql/DeleteStatement.java +++ b/src/java/org/apache/cassandra/cql/DeleteStatement.java @@ -73,7 +73,7 @@ public class DeleteStatement extends AbstractModification { CFMetaData metadata = validateColumnFamily(keyspace, columnFamily); - clientState.hasColumnFamilyAccess(columnFamily, Permission.DELETE); + clientState.hasColumnFamilyAccess(keyspace, columnFamily, Permission.WRITE); AbstractType keyType = Schema.instance.getCFMetaData(keyspace, columnFamily).getKeyValidator(); List rowMutations = new ArrayList(keys.size()); diff --git a/src/java/org/apache/cassandra/cql/QueryProcessor.java b/src/java/org/apache/cassandra/cql/QueryProcessor.java index 149fb833bd..5f68e2d941 100644 --- a/src/java/org/apache/cassandra/cql/QueryProcessor.java +++ b/src/java/org/apache/cassandra/cql/QueryProcessor.java @@ -249,7 +249,7 @@ public class QueryProcessor // Avoid unnecessary authorizations. if (!(cfamsSeen.contains(update.getColumnFamily()))) { - clientState.hasColumnFamilyAccess(keyspace, update.getColumnFamily(), Permission.UPDATE); + clientState.hasColumnFamilyAccess(keyspace, update.getColumnFamily(), Permission.WRITE); cfamsSeen.add(update.getColumnFamily()); } @@ -461,7 +461,7 @@ public class QueryProcessor else keyspace = oldKeyspace; - clientState.hasColumnFamilyAccess(keyspace, select.getColumnFamily(), Permission.SELECT); + clientState.hasColumnFamilyAccess(keyspace, select.getColumnFamily(), Permission.READ); metadata = validateColumnFamily(keyspace, select.getColumnFamily()); // need to do this in here because we need a CFMD.getKeyName() @@ -591,7 +591,7 @@ public class QueryProcessor case INSERT: // insert uses UpdateStatement case UPDATE: UpdateStatement update = (UpdateStatement)statement.statement; - clientState.hasColumnFamilyAccess(keyspace, update.getColumnFamily(), Permission.UPDATE); + clientState.hasColumnFamilyAccess(keyspace, update.getColumnFamily(), Permission.WRITE); ThriftValidation.validateConsistencyLevel(keyspace, update.getConsistencyLevel(), RequestType.WRITE); batchUpdate(clientState, Collections.singletonList(update), update.getConsistencyLevel(), variables); result.type = CqlResultType.VOID; @@ -648,7 +648,7 @@ public class QueryProcessor keyspace = columnFamily.left == null ? clientState.getKeyspace() : columnFamily.left; validateColumnFamily(keyspace, columnFamily.right); - clientState.hasColumnFamilyAccess(keyspace, columnFamily.right, Permission.DELETE); + clientState.hasColumnFamilyAccess(keyspace, columnFamily.right, Permission.WRITE); try { @@ -670,7 +670,7 @@ public class QueryProcessor DeleteStatement delete = (DeleteStatement)statement.statement; keyspace = delete.keyspace == null ? clientState.getKeyspace() : delete.keyspace; - clientState.hasColumnFamilyAccess(keyspace, delete.columnFamily, Permission.DELETE); + clientState.hasColumnFamilyAccess(keyspace, delete.columnFamily, Permission.WRITE); List deletions = delete.prepareRowMutations(keyspace, clientState, variables); for (IMutation deletion : deletions) { @@ -693,7 +693,7 @@ public class QueryProcessor CreateKeyspaceStatement create = (CreateKeyspaceStatement)statement.statement; create.validate(); ThriftValidation.validateKeyspaceNotSystem(create.getName()); - clientState.hasKeyspaceAccess(create.getName(), Permission.CREATE); + clientState.hasKeyspaceAccess(create.getName(), Permission.WRITE); validateSchemaAgreement(); try @@ -718,7 +718,7 @@ public class QueryProcessor case CREATE_COLUMNFAMILY: CreateColumnFamilyStatement createCf = (CreateColumnFamilyStatement)statement.statement; - clientState.hasColumnFamilySchemaAccess(keyspace, Permission.CREATE); + clientState.hasColumnFamilyAccess(keyspace, createCf.getName(), Permission.WRITE); validateSchemaAgreement(); try @@ -738,7 +738,7 @@ public class QueryProcessor case CREATE_INDEX: CreateIndexStatement createIdx = (CreateIndexStatement)statement.statement; - clientState.hasColumnFamilyAccess(keyspace, createIdx.getColumnFamily(), Permission.ALTER); + clientState.hasColumnFamilyAccess(keyspace, createIdx.getColumnFamily(), Permission.WRITE); validateSchemaAgreement(); CFMetaData oldCfm = Schema.instance.getCFMetaData(keyspace, createIdx.getColumnFamily()); if (oldCfm == null) @@ -809,7 +809,7 @@ public class QueryProcessor case DROP_KEYSPACE: String deleteKeyspace = (String)statement.statement; ThriftValidation.validateKeyspaceNotSystem(deleteKeyspace); - clientState.hasKeyspaceAccess(deleteKeyspace, Permission.DROP); + clientState.hasKeyspaceAccess(deleteKeyspace, Permission.WRITE); validateSchemaAgreement(); try @@ -829,7 +829,7 @@ public class QueryProcessor case DROP_COLUMNFAMILY: String deleteColumnFamily = (String)statement.statement; - clientState.hasColumnFamilyAccess(keyspace, deleteColumnFamily, Permission.DROP); + clientState.hasColumnFamilyAccess(keyspace, deleteColumnFamily, Permission.WRITE); validateSchemaAgreement(); try @@ -851,7 +851,7 @@ public class QueryProcessor AlterTableStatement alterTable = (AlterTableStatement) statement.statement; validateColumnFamily(keyspace, alterTable.columnFamily); - clientState.hasColumnFamilyAccess(alterTable.columnFamily, Permission.ALTER); + clientState.hasColumnFamilyAccess(keyspace, alterTable.columnFamily, Permission.WRITE); validateSchemaAgreement(); try diff --git a/src/java/org/apache/cassandra/cql/UpdateStatement.java b/src/java/org/apache/cassandra/cql/UpdateStatement.java index 2491ef7785..10d9d0b48c 100644 --- a/src/java/org/apache/cassandra/cql/UpdateStatement.java +++ b/src/java/org/apache/cassandra/cql/UpdateStatement.java @@ -155,7 +155,7 @@ public class UpdateStatement extends AbstractModification // Avoid unnecessary authorizations. if (!(cfamsSeen.contains(columnFamily))) { - clientState.hasColumnFamilyAccess(columnFamily, Permission.UPDATE); + clientState.hasColumnFamilyAccess(keyspace, columnFamily, Permission.WRITE); cfamsSeen.add(columnFamily); } diff --git a/src/java/org/apache/cassandra/cql3/CFName.java b/src/java/org/apache/cassandra/cql3/CFName.java index f48472cb17..cd6e6d3452 100644 --- a/src/java/org/apache/cassandra/cql3/CFName.java +++ b/src/java/org/apache/cassandra/cql3/CFName.java @@ -50,11 +50,6 @@ public class CFName return cfName; } - public String toResource() - { - return "/cassandra/keyspaces/" + (hasKeyspace() ? ksName + "/" + cfName : cfName); - } - @Override public String toString() { diff --git a/src/java/org/apache/cassandra/cql3/Cql.g b/src/java/org/apache/cassandra/cql3/Cql.g index 387e6947cb..1fc06a3dde 100644 --- a/src/java/org/apache/cassandra/cql3/Cql.g +++ b/src/java/org/apache/cassandra/cql3/Cql.g @@ -33,7 +33,6 @@ options { import java.util.List; import java.util.Map; - import org.apache.cassandra.auth.Permission; import org.apache.cassandra.cql3.statements.*; import org.apache.cassandra.utils.Pair; import org.apache.cassandra.thrift.ConsistencyLevel; @@ -141,10 +140,7 @@ cqlStatement returns [ParsedStatement stmt] | st12=dropColumnFamilyStatement { $stmt = st12; } | st13=dropIndexStatement { $stmt = st13; } | st14=alterTableStatement { $stmt = st14; } - | st15=grantStatement { $stmt = st15; } - | st16=revokeStatement { $stmt = st16; } - | st17=listGrantsStatement { $stmt = st17; } - | st18=alterKeyspaceStatement { $stmt = st18; } + | st15=alterKeyspaceStatement { $stmt = st15; } ; /* @@ -450,51 +446,6 @@ truncateStatement returns [TruncateStatement stmt] : K_TRUNCATE cf=columnFamilyName { $stmt = new TruncateStatement(cf); } ; -/** - * GRANT ON TO [WITH GRANT OPTION] - */ -grantStatement returns [GrantStatement stmt] - @init { boolean withGrant = false; } - : K_GRANT - permission - K_ON - resource=columnFamilyName - K_TO - user=(IDENT | STRING_LITERAL) - (K_WITH K_GRANT K_OPTION { withGrant = true; })? - { - $stmt = new GrantStatement($permission.perm, - resource, - $user.text, - withGrant); - } - ; - -/** - * REVOKE ON FROM - */ -revokeStatement returns [RevokeStatement stmt] - : K_REVOKE - permission - K_ON - resource=columnFamilyName - K_FROM - user=(IDENT | STRING_LITERAL) - { - $stmt = new RevokeStatement($permission.perm, - $user.text, - resource); - } - ; - -listGrantsStatement returns [ListGrantsStatement stmt] - : K_LIST K_GRANTS K_FOR username=(IDENT | STRING_LITERAL) { $stmt = new ListGrantsStatement($username.text); } - ; - -permission returns [Permission perm] - : p=(K_DESCRIBE | K_USE | K_CREATE | K_ALTER | K_DROP | K_SELECT | K_INSERT | K_UPDATE | K_DELETE | K_FULL_ACCESS | K_NO_ACCESS) - { $perm = Permission.valueOf($p.text.toUpperCase()); } - ; /** DEFINITIONS **/ // Column Identifiers @@ -634,11 +585,10 @@ K_UPDATE: U P D A T E; K_WITH: W I T H; K_LIMIT: L I M I T; K_USING: U S I N G; -K_ALL: A L L; K_CONSISTENCY: C O N S I S T E N C Y; K_LEVEL: ( O N E | Q U O R U M - | K_ALL + | A L L | A N Y | L O C A L '_' Q U O R U M | E A C H '_' Q U O R U M @@ -662,7 +612,6 @@ K_COLUMNFAMILY:( C O L U M N F A M I L Y | T A B L E ); K_INDEX: I N D E X; K_ON: O N; -K_TO: T O; K_DROP: D R O P; K_PRIMARY: P R I M A R Y; K_INTO: I N T O; @@ -678,17 +627,6 @@ K_ORDER: O R D E R; K_BY: B Y; K_ASC: A S C; K_DESC: D E S C; -K_GRANT: G R A N T; -K_GRANTS: G R A N T S; -K_REVOKE: R E V O K E; -K_OPTION: O P T I O N; -K_DESCRIBE: D E S C R I B E; -K_FOR: F O R; -K_LIST: L I S T; -K_FULL_ACCESS: F U L L '_' A C C E S S; -K_NO_ACCESS: N O '_' A C C E S S; - - K_CLUSTERING: C L U S T E R I N G; K_ASCII: A S C I I; K_BIGINT: B I G I N T; diff --git a/src/java/org/apache/cassandra/cql3/statements/AlterKeyspaceStatement.java b/src/java/org/apache/cassandra/cql3/statements/AlterKeyspaceStatement.java index 644fd24d31..bc40cd717b 100644 --- a/src/java/org/apache/cassandra/cql3/statements/AlterKeyspaceStatement.java +++ b/src/java/org/apache/cassandra/cql3/statements/AlterKeyspaceStatement.java @@ -45,7 +45,7 @@ public class AlterKeyspaceStatement extends SchemaAlteringStatement public void checkAccess(ClientState state) throws InvalidRequestException { - state.hasKeyspaceAccess(name, Permission.ALTER); + state.hasKeyspaceAccess(name, Permission.WRITE); } @Override diff --git a/src/java/org/apache/cassandra/cql3/statements/AlterTableStatement.java b/src/java/org/apache/cassandra/cql3/statements/AlterTableStatement.java index 965b27ed19..f3b3652c15 100644 --- a/src/java/org/apache/cassandra/cql3/statements/AlterTableStatement.java +++ b/src/java/org/apache/cassandra/cql3/statements/AlterTableStatement.java @@ -53,7 +53,7 @@ public class AlterTableStatement extends SchemaAlteringStatement public void checkAccess(ClientState state) throws InvalidRequestException { - state.hasColumnFamilyAccess(keyspace(), columnFamily(), Permission.ALTER); + state.hasColumnFamilyAccess(keyspace(), columnFamily(), Permission.WRITE); } public void announceMigration() throws InvalidRequestException, ConfigurationException diff --git a/src/java/org/apache/cassandra/cql3/statements/BatchStatement.java b/src/java/org/apache/cassandra/cql3/statements/BatchStatement.java index 155a39da09..2241b0589e 100644 --- a/src/java/org/apache/cassandra/cql3/statements/BatchStatement.java +++ b/src/java/org/apache/cassandra/cql3/statements/BatchStatement.java @@ -71,7 +71,7 @@ public class BatchStatement extends ModificationStatement // Avoid unnecessary authorizations. if (!(cfamsSeen.contains(statement.columnFamily()))) { - state.hasColumnFamilyAccess(statement.keyspace(), statement.columnFamily(), Permission.UPDATE); + state.hasColumnFamilyAccess(statement.keyspace(), statement.columnFamily(), Permission.WRITE); cfamsSeen.add(statement.columnFamily()); } } diff --git a/src/java/org/apache/cassandra/cql3/statements/CreateColumnFamilyStatement.java b/src/java/org/apache/cassandra/cql3/statements/CreateColumnFamilyStatement.java index 3d77053bab..1f0e0d350c 100644 --- a/src/java/org/apache/cassandra/cql3/statements/CreateColumnFamilyStatement.java +++ b/src/java/org/apache/cassandra/cql3/statements/CreateColumnFamilyStatement.java @@ -68,7 +68,7 @@ public class CreateColumnFamilyStatement extends SchemaAlteringStatement public void checkAccess(ClientState state) throws InvalidRequestException { - state.hasColumnFamilyAccess(keyspace(), columnFamily(), Permission.CREATE); + state.hasColumnFamilyAccess(keyspace(), columnFamily(), Permission.WRITE); } // Column definitions diff --git a/src/java/org/apache/cassandra/cql3/statements/CreateIndexStatement.java b/src/java/org/apache/cassandra/cql3/statements/CreateIndexStatement.java index 0250eb24bd..dfb6cc3391 100644 --- a/src/java/org/apache/cassandra/cql3/statements/CreateIndexStatement.java +++ b/src/java/org/apache/cassandra/cql3/statements/CreateIndexStatement.java @@ -53,7 +53,7 @@ public class CreateIndexStatement extends SchemaAlteringStatement public void checkAccess(ClientState state) throws InvalidRequestException { - state.hasColumnFamilyAccess(keyspace(), columnFamily(), Permission.ALTER); + state.hasColumnFamilyAccess(keyspace(), columnFamily(), Permission.WRITE); } public void announceMigration() throws InvalidRequestException, ConfigurationException diff --git a/src/java/org/apache/cassandra/cql3/statements/CreateKeyspaceStatement.java b/src/java/org/apache/cassandra/cql3/statements/CreateKeyspaceStatement.java index 9b36531943..045f7d1ac4 100644 --- a/src/java/org/apache/cassandra/cql3/statements/CreateKeyspaceStatement.java +++ b/src/java/org/apache/cassandra/cql3/statements/CreateKeyspaceStatement.java @@ -57,7 +57,7 @@ public class CreateKeyspaceStatement extends SchemaAlteringStatement public void checkAccess(ClientState state) throws InvalidRequestException { - state.hasKeyspaceAccess(name, Permission.CREATE); + state.hasKeyspaceAccess(name, Permission.WRITE); } /** diff --git a/src/java/org/apache/cassandra/cql3/statements/DropColumnFamilyStatement.java b/src/java/org/apache/cassandra/cql3/statements/DropColumnFamilyStatement.java index 5129431ed6..7af45b3787 100644 --- a/src/java/org/apache/cassandra/cql3/statements/DropColumnFamilyStatement.java +++ b/src/java/org/apache/cassandra/cql3/statements/DropColumnFamilyStatement.java @@ -36,7 +36,7 @@ public class DropColumnFamilyStatement extends SchemaAlteringStatement public void checkAccess(ClientState state) throws InvalidRequestException { - state.hasColumnFamilyAccess(keyspace(), columnFamily(), Permission.DROP); + state.hasColumnFamilyAccess(keyspace(), columnFamily(), Permission.WRITE); } public void announceMigration() throws ConfigurationException diff --git a/src/java/org/apache/cassandra/cql3/statements/DropIndexStatement.java b/src/java/org/apache/cassandra/cql3/statements/DropIndexStatement.java index 9c3ab5b71f..3509c7ea19 100644 --- a/src/java/org/apache/cassandra/cql3/statements/DropIndexStatement.java +++ b/src/java/org/apache/cassandra/cql3/statements/DropIndexStatement.java @@ -41,7 +41,7 @@ public class DropIndexStatement extends SchemaAlteringStatement public void checkAccess(ClientState state) throws InvalidRequestException { - state.hasColumnFamilyAccess(keyspace(), columnFamily(), Permission.ALTER); + state.hasColumnFamilyAccess(keyspace(), columnFamily(), Permission.WRITE); } public void announceMigration() throws InvalidRequestException, ConfigurationException diff --git a/src/java/org/apache/cassandra/cql3/statements/DropKeyspaceStatement.java b/src/java/org/apache/cassandra/cql3/statements/DropKeyspaceStatement.java index fb325dc1cf..3188fcaf3e 100644 --- a/src/java/org/apache/cassandra/cql3/statements/DropKeyspaceStatement.java +++ b/src/java/org/apache/cassandra/cql3/statements/DropKeyspaceStatement.java @@ -38,7 +38,7 @@ public class DropKeyspaceStatement extends SchemaAlteringStatement public void checkAccess(ClientState state) throws InvalidRequestException { - state.hasKeyspaceAccess(keyspace, Permission.DROP); + state.hasKeyspaceAccess(keyspace, Permission.WRITE); } @Override diff --git a/src/java/org/apache/cassandra/cql3/statements/GrantStatement.java b/src/java/org/apache/cassandra/cql3/statements/GrantStatement.java deleted file mode 100644 index 556501a8d5..0000000000 --- a/src/java/org/apache/cassandra/cql3/statements/GrantStatement.java +++ /dev/null @@ -1,66 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.cassandra.cql3.statements; - -import java.nio.ByteBuffer; -import java.util.List; - -import org.apache.cassandra.auth.Permission; -import org.apache.cassandra.cql3.CFName; -import org.apache.cassandra.cql3.CQLStatement; -import org.apache.cassandra.service.ClientState; -import org.apache.cassandra.thrift.*; - -public class GrantStatement extends ParsedStatement implements CQLStatement -{ - private final Permission permission; - private final CFName resource; - private final String username; - private final boolean grantOption; - - public GrantStatement(Permission permission, CFName resource, String username, boolean grantOption) - { - this.permission = permission; - this.resource = resource; - this.username = username; - this.grantOption = grantOption; - } - - public int getBoundsTerms() - { - return 0; - } - - public void checkAccess(ClientState state) throws InvalidRequestException - {} - - public void validate(ClientState state) throws InvalidRequestException, SchemaDisagreementException - {} - - public CqlResult execute(ClientState state, List variables) throws InvalidRequestException, UnavailableException, TimedOutException, SchemaDisagreementException - { - state.grantPermission(permission, username, resource, grantOption); - return null; - } - - public Prepared prepare() throws InvalidRequestException - { - return new Prepared(this); - } -} diff --git a/src/java/org/apache/cassandra/cql3/statements/ListGrantsStatement.java b/src/java/org/apache/cassandra/cql3/statements/ListGrantsStatement.java deleted file mode 100644 index c26f9cfbd2..0000000000 --- a/src/java/org/apache/cassandra/cql3/statements/ListGrantsStatement.java +++ /dev/null @@ -1,53 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.cassandra.cql3.statements; - -import java.nio.ByteBuffer; -import java.util.List; - -import org.apache.cassandra.cql3.CQLStatement; -import org.apache.cassandra.service.ClientState; -import org.apache.cassandra.thrift.*; - -public class ListGrantsStatement extends ParsedStatement implements CQLStatement -{ - private final String username; - - public ListGrantsStatement(String username) - { - this.username = username; - } - - public void checkAccess(ClientState state) throws InvalidRequestException - {} - - public void validate(ClientState state) throws InvalidRequestException, SchemaDisagreementException - {} - - public CqlResult execute(ClientState state, List variables) throws InvalidRequestException, UnavailableException, TimedOutException, SchemaDisagreementException - { - return state.listPermissions(username); - } - - @Override - public Prepared prepare() throws InvalidRequestException - { - return new Prepared(this); - } -} diff --git a/src/java/org/apache/cassandra/cql3/statements/ModificationStatement.java b/src/java/org/apache/cassandra/cql3/statements/ModificationStatement.java index 23d96e06f1..ea596bffb1 100644 --- a/src/java/org/apache/cassandra/cql3/statements/ModificationStatement.java +++ b/src/java/org/apache/cassandra/cql3/statements/ModificationStatement.java @@ -62,7 +62,7 @@ public abstract class ModificationStatement extends CFStatement implements CQLSt public void checkAccess(ClientState state) throws InvalidRequestException { - state.hasColumnFamilyAccess(keyspace(), columnFamily(), Permission.UPDATE); + state.hasColumnFamilyAccess(keyspace(), columnFamily(), Permission.WRITE); } public void validate(ClientState state) throws InvalidRequestException diff --git a/src/java/org/apache/cassandra/cql3/statements/RevokeStatement.java b/src/java/org/apache/cassandra/cql3/statements/RevokeStatement.java deleted file mode 100644 index 8236a7e9a3..0000000000 --- a/src/java/org/apache/cassandra/cql3/statements/RevokeStatement.java +++ /dev/null @@ -1,66 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.cassandra.cql3.statements; - -import java.nio.ByteBuffer; -import java.util.List; - -import org.apache.cassandra.auth.Permission; -import org.apache.cassandra.cql3.CFName; -import org.apache.cassandra.cql3.CQLStatement; -import org.apache.cassandra.service.ClientState; -import org.apache.cassandra.thrift.*; - -public class RevokeStatement extends ParsedStatement implements CQLStatement -{ - private final Permission permission; - private final String from; - private final CFName resource; - - public RevokeStatement(Permission permission, String from, CFName resource) - { - this.permission = permission; - this.from = from; - this.resource = resource; - } - - public int getBoundsTerms() - { - return 0; - } - - public void checkAccess(ClientState state) throws InvalidRequestException - { - } - - public void validate(ClientState state) throws InvalidRequestException, SchemaDisagreementException - { - } - - public CqlResult execute(ClientState state, List variables) throws InvalidRequestException, UnavailableException, TimedOutException, SchemaDisagreementException - { - state.revokePermission(permission, from, resource); - return null; - } - - public Prepared prepare() throws InvalidRequestException - { - return new Prepared(this); - } -} diff --git a/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java b/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java index 92a8d67dbd..2cb008e370 100644 --- a/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java +++ b/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java @@ -115,7 +115,7 @@ public class SelectStatement implements CQLStatement public void checkAccess(ClientState state) throws InvalidRequestException { - state.hasColumnFamilyAccess(keyspace(), columnFamily(), Permission.SELECT); + state.hasColumnFamilyAccess(keyspace(), columnFamily(), Permission.READ); } public void validate(ClientState state) throws InvalidRequestException diff --git a/src/java/org/apache/cassandra/cql3/statements/TruncateStatement.java b/src/java/org/apache/cassandra/cql3/statements/TruncateStatement.java index 9e1661e4dd..ca37daeb96 100644 --- a/src/java/org/apache/cassandra/cql3/statements/TruncateStatement.java +++ b/src/java/org/apache/cassandra/cql3/statements/TruncateStatement.java @@ -46,7 +46,7 @@ public class TruncateStatement extends CFStatement implements CQLStatement public void checkAccess(ClientState state) throws InvalidRequestException { - state.hasColumnFamilyAccess(keyspace(), columnFamily(), Permission.DELETE); + state.hasColumnFamilyAccess(keyspace(), columnFamily(), Permission.WRITE); } public void validate(ClientState state) throws InvalidRequestException diff --git a/src/java/org/apache/cassandra/service/ClientState.java b/src/java/org/apache/cassandra/service/ClientState.java index a68a778dc5..243d2d1f50 100644 --- a/src/java/org/apache/cassandra/service/ClientState.java +++ b/src/java/org/apache/cassandra/service/ClientState.java @@ -31,10 +31,8 @@ import org.apache.cassandra.auth.Resources; import org.apache.cassandra.config.DatabaseDescriptor; import org.apache.cassandra.config.Schema; import org.apache.cassandra.cql.CQLStatement; -import org.apache.cassandra.cql3.CFName; import org.apache.cassandra.db.Table; import org.apache.cassandra.thrift.AuthenticationException; -import org.apache.cassandra.thrift.CqlResult; import org.apache.cassandra.thrift.InvalidRequestException; import org.apache.cassandra.utils.SemanticVersion; @@ -152,15 +150,6 @@ public class ClientState } public void hasKeyspaceAccess(String keyspace, Permission perm) throws InvalidRequestException - { - hasColumnFamilySchemaAccess(keyspace, perm); - } - - /** - * Confirms that the client thread has the given Permission for the ColumnFamily list of - * the provided keyspace. - */ - public void hasColumnFamilySchemaAccess(String keyspace, Permission perm) throws InvalidRequestException { validateLogin(); validateKeyspace(keyspace); @@ -176,7 +165,7 @@ public class ClientState private void preventSystemKSSchemaModification(String keyspace, Permission perm) throws InvalidRequestException { - if (keyspace.equalsIgnoreCase(Table.SYSTEM_TABLE) && !Permission.ALLOWED_SYSTEM_ACTIONS.contains(perm)) + if (keyspace.equalsIgnoreCase(Table.SYSTEM_TABLE) && perm.equals(Permission.WRITE)) throw new InvalidRequestException("system keyspace is not user-modifiable."); } @@ -184,11 +173,6 @@ public class ClientState * Confirms that the client thread has the given Permission in the context of the given * ColumnFamily and the current keyspace. */ - public void hasColumnFamilyAccess(String columnFamily, Permission perm) throws InvalidRequestException - { - hasColumnFamilyAccess(keyspace, columnFamily, perm); - } - public void hasColumnFamilyAccess(String keyspace, String columnFamily, Permission perm) throws InvalidRequestException { validateLogin(); @@ -199,9 +183,8 @@ public class ClientState preventSystemKSSchemaModification(keyspace, perm); - // check if keyspace access is set to Permission.FULL_ACCESS - // (which means that user has all access on keyspace and it's underlying elements) - if (DatabaseDescriptor.getAuthority().authorize(user, resource).contains(Permission.FULL_ACCESS)) + // check if the user has the perm on the keyspace (which means same permission on the contained cfs). + if (DatabaseDescriptor.getAuthority().authorize(user, resource).contains(perm)) return; resource.add(columnFamily); @@ -226,42 +209,8 @@ public class ClientState private static void hasAccess(AuthenticatedUser user, Set perms, Permission perm, List resource) throws PermissionDenied { - if (perms.contains(Permission.FULL_ACCESS)) - return; // full access - - if (perms.contains(Permission.NO_ACCESS)) - throw new PermissionDenied(String.format("%s does not have permission %s for %s", - user, - perm, - Resources.toString(resource))); - - boolean granular = false; - - for (Permission p : perms) - { - // mixing of old and granular permissions is denied by IAuthorityContainer - // and CQL grammar so it's name to assume that once a granular permission is found - // all other permissions are going to be a subset of Permission.GRANULAR_PERMISSIONS - if (Permission.GRANULAR_PERMISSIONS.contains(p)) - { - granular = true; - break; - } - } - - if (granular) - { - if (perms.contains(perm)) - return; // user has a given permission, perm is always one of Permission.GRANULAR_PERMISSIONS - } - else - { - for (Permission p : perms) - { - if (Permission.oldToNew.get(p).contains(perm)) - return; - } - } + if (perms.contains(perm)) + return; throw new PermissionDenied(String.format("%s does not have permission %s for %s", user, @@ -318,19 +267,4 @@ public class ClientState return new SemanticVersion[]{ cql, cql3 }; } - - public void grantPermission(Permission permission, String to, CFName on, boolean grantOption) throws InvalidRequestException - { - DatabaseDescriptor.getAuthorityContainer().grant(user, permission, to, on, grantOption); - } - - public void revokePermission(Permission permission, String from, CFName resource) throws InvalidRequestException - { - DatabaseDescriptor.getAuthorityContainer().revoke(user, permission, from, resource); - } - - public CqlResult listPermissions(String username) throws InvalidRequestException - { - return DatabaseDescriptor.getAuthorityContainer().listPermissions(username); - } } diff --git a/src/java/org/apache/cassandra/thrift/CassandraServer.java b/src/java/org/apache/cassandra/thrift/CassandraServer.java index 39b57f372f..b196b2ff3c 100644 --- a/src/java/org/apache/cassandra/thrift/CassandraServer.java +++ b/src/java/org/apache/cassandra/thrift/CassandraServer.java @@ -30,8 +30,6 @@ import java.util.zip.Inflater; import com.google.common.base.Predicates; import com.google.common.collect.Maps; -import org.apache.cassandra.hadoop.ColumnFamilySplit; -import org.apache.cassandra.utils.Pair; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -51,6 +49,7 @@ import org.apache.cassandra.locator.DynamicEndpointSnitch; import org.apache.cassandra.scheduler.IRequestScheduler; import org.apache.cassandra.service.*; import org.apache.cassandra.utils.ByteBufferUtil; +import org.apache.cassandra.utils.Pair; import org.apache.thrift.TException; public class CassandraServer implements Cassandra.Iface @@ -308,8 +307,9 @@ public class CassandraServer implements Cassandra.Iface logger.debug("get_slice"); ClientState cState = state(); - cState.hasColumnFamilyAccess(column_parent.column_family, Permission.SELECT); - return multigetSliceInternal(cState.getKeyspace(), Collections.singletonList(key), column_parent, predicate, consistency_level).get(key); + String keyspace = cState.getKeyspace(); + cState.hasColumnFamilyAccess(keyspace, column_parent.column_family, Permission.READ); + return multigetSliceInternal(keyspace, Collections.singletonList(key), column_parent, predicate, consistency_level).get(key); } public Map> multiget_slice(List keys, ColumnParent column_parent, SlicePredicate predicate, ConsistencyLevel consistency_level) @@ -318,8 +318,9 @@ public class CassandraServer implements Cassandra.Iface logger.debug("multiget_slice"); ClientState cState = state(); - cState.hasColumnFamilyAccess(column_parent.column_family, Permission.SELECT); - return multigetSliceInternal(cState.getKeyspace(), keys, column_parent, predicate, consistency_level); + String keyspace = cState.getKeyspace(); + cState.hasColumnFamilyAccess(keyspace, column_parent.column_family, Permission.READ); + return multigetSliceInternal(keyspace, keys, column_parent, predicate, consistency_level); } private Map> multigetSliceInternal(String keyspace, List keys, ColumnParent column_parent, SlicePredicate predicate, ConsistencyLevel consistency_level) @@ -356,8 +357,8 @@ public class CassandraServer implements Cassandra.Iface throws InvalidRequestException, NotFoundException, UnavailableException, TimedOutException { ClientState cState = state(); - cState.hasColumnFamilyAccess(column_path.column_family, Permission.SELECT); String keyspace = cState.getKeyspace(); + cState.hasColumnFamilyAccess(keyspace, column_path.column_family, Permission.READ); CFMetaData metadata = ThriftValidation.validateColumnFamily(keyspace, column_path.column_family); ThriftValidation.validateColumnPath(metadata, column_path); @@ -395,8 +396,9 @@ public class CassandraServer implements Cassandra.Iface logger.debug("get_count"); ClientState cState = state(); - cState.hasColumnFamilyAccess(column_parent.column_family, Permission.SELECT); - Table table = Table.open(cState.getKeyspace()); + String keyspace = cState.getKeyspace(); + cState.hasColumnFamilyAccess(keyspace, column_parent.column_family, Permission.READ); + Table table = Table.open(keyspace); ColumnFamilyStore cfs = table.getColumnFamilyStore(column_parent.column_family); if (predicate.column_names != null) @@ -471,8 +473,8 @@ public class CassandraServer implements Cassandra.Iface logger.debug("multiget_count"); ClientState cState = state(); - cState.hasColumnFamilyAccess(column_parent.column_family, Permission.SELECT); String keyspace = cState.getKeyspace(); + cState.hasColumnFamilyAccess(keyspace, column_parent.column_family, Permission.READ); Map counts = new HashMap(); Map> columnFamiliesMap = multigetSliceInternal(keyspace, keys, column_parent, predicate, consistency_level); @@ -487,9 +489,10 @@ public class CassandraServer implements Cassandra.Iface throws InvalidRequestException, UnavailableException, TimedOutException { ClientState cState = state(); - cState.hasColumnFamilyAccess(column_parent.column_family, Permission.UPDATE); + String keyspace = cState.getKeyspace(); + cState.hasColumnFamilyAccess(keyspace, column_parent.column_family, Permission.WRITE); - CFMetaData metadata = ThriftValidation.validateColumnFamily(cState.getKeyspace(), column_parent.column_family, false); + CFMetaData metadata = ThriftValidation.validateColumnFamily(keyspace, column_parent.column_family, false); ThriftValidation.validateKey(metadata, key); ThriftValidation.validateColumnParent(metadata, column_parent); // SuperColumn field is usually optional, but not when we're inserting @@ -500,7 +503,7 @@ public class CassandraServer implements Cassandra.Iface ThriftValidation.validateColumnNames(metadata, column_parent, Arrays.asList(column.name)); ThriftValidation.validateColumnData(metadata, column, column_parent.super_column != null); - RowMutation rm = new RowMutation(cState.getKeyspace(), key); + RowMutation rm = new RowMutation(keyspace, key); try { rm.add(new QueryPath(column_parent.column_family, column_parent.super_column, column.name), column.value, column.timestamp, column.ttl); @@ -545,7 +548,7 @@ public class CassandraServer implements Cassandra.Iface // Avoid unneeded authorizations if (!(cfamsSeen.contains(cfName))) { - cState.hasColumnFamilyAccess(cfName, Permission.UPDATE); + cState.hasColumnFamilyAccess(keyspace, cfName, Permission.WRITE); cfamsSeen.add(cfName); } @@ -600,15 +603,16 @@ public class CassandraServer implements Cassandra.Iface throws InvalidRequestException, UnavailableException, TimedOutException { ClientState cState = state(); - cState.hasColumnFamilyAccess(column_path.column_family, Permission.DELETE); + String keyspace = cState.getKeyspace(); + cState.hasColumnFamilyAccess(keyspace, column_path.column_family, Permission.WRITE); - CFMetaData metadata = ThriftValidation.validateColumnFamily(cState.getKeyspace(), column_path.column_family, isCommutativeOp); + CFMetaData metadata = ThriftValidation.validateColumnFamily(keyspace, column_path.column_family, isCommutativeOp); ThriftValidation.validateKey(metadata, key); ThriftValidation.validateColumnPathOrParent(metadata, column_path); if (isCommutativeOp) ThriftValidation.validateCommutativeForWrite(metadata, consistency_level); - RowMutation rm = new RowMutation(cState.getKeyspace(), key); + RowMutation rm = new RowMutation(keyspace, key); rm.delete(new QueryPath(column_path), timestamp); if (isCommutativeOp) @@ -651,7 +655,7 @@ public class CassandraServer implements Cassandra.Iface public KsDef describe_keyspace(String table) throws NotFoundException, InvalidRequestException { - state().hasKeyspaceAccess(table, Permission.DESCRIBE); + state().hasKeyspaceAccess(table, Permission.READ); KSMetaData ksm = Schema.instance.getTableDefinition(table); if (ksm == null) @@ -667,7 +671,7 @@ public class CassandraServer implements Cassandra.Iface ClientState cState = state(); String keyspace = cState.getKeyspace(); - cState.hasColumnFamilyAccess(column_parent.column_family, Permission.SELECT); + cState.hasColumnFamilyAccess(keyspace, column_parent.column_family, Permission.READ); CFMetaData metadata = ThriftValidation.validateColumnFamily(keyspace, column_parent.column_family); ThriftValidation.validateColumnParent(metadata, column_parent); @@ -724,7 +728,7 @@ public class CassandraServer implements Cassandra.Iface ClientState cState = state(); String keyspace = cState.getKeyspace(); - cState.hasColumnFamilyAccess(column_family, Permission.SELECT); + cState.hasColumnFamilyAccess(keyspace, column_family, Permission.READ); CFMetaData metadata = ThriftValidation.validateColumnFamily(keyspace, column_family); ThriftValidation.validateKeyRange(metadata, null, range); @@ -794,8 +798,8 @@ public class CassandraServer implements Cassandra.Iface logger.debug("scan"); ClientState cState = state(); - cState.hasColumnFamilyAccess(column_parent.column_family, Permission.SELECT); String keyspace = cState.getKeyspace(); + cState.hasColumnFamilyAccess(keyspace, column_parent.column_family, Permission.READ); CFMetaData metadata = ThriftValidation.validateColumnFamily(keyspace, column_parent.column_family, false); ThriftValidation.validateColumnParent(metadata, column_parent); ThriftValidation.validatePredicate(metadata, column_parent, column_predicate); @@ -941,7 +945,7 @@ public class CassandraServer implements Cassandra.Iface throws InvalidRequestException, SchemaDisagreementException, TException { logger.debug("add_column_family"); - state().hasColumnFamilyAccess(cf_def.name, Permission.CREATE); + state().hasColumnFamilyAccess(cf_def.keyspace, cf_def.name, Permission.WRITE); validateSchemaAgreement(); @@ -967,12 +971,13 @@ public class CassandraServer implements Cassandra.Iface logger.debug("drop_column_family"); ClientState cState = state(); - cState.hasColumnFamilyAccess(column_family, Permission.DROP); + String keyspace = cState.getKeyspace(); + cState.hasColumnFamilyAccess(keyspace, column_family, Permission.WRITE); validateSchemaAgreement(); try { - MigrationManager.announceColumnFamilyDrop(cState.getKeyspace(), column_family); + MigrationManager.announceColumnFamilyDrop(keyspace, column_family); return Schema.instance.getVersion().toString(); } catch (ConfigurationException e) @@ -988,7 +993,7 @@ public class CassandraServer implements Cassandra.Iface { logger.debug("add_keyspace"); ThriftValidation.validateKeyspaceNotSystem(ks_def.name); - state().hasKeyspaceAccess(ks_def.name, Permission.CREATE); + state().hasKeyspaceAccess(ks_def.name, Permission.WRITE); validateSchemaAgreement(); ThriftValidation.validateKeyspaceNotYetExisting(ks_def.name); @@ -1027,7 +1032,7 @@ public class CassandraServer implements Cassandra.Iface { logger.debug("drop_keyspace"); ThriftValidation.validateKeyspaceNotSystem(keyspace); - state().hasKeyspaceAccess(keyspace, Permission.DROP); + state().hasKeyspaceAccess(keyspace, Permission.WRITE); validateSchemaAgreement(); try @@ -1051,7 +1056,7 @@ public class CassandraServer implements Cassandra.Iface { logger.debug("update_keyspace"); ThriftValidation.validateKeyspaceNotSystem(ks_def.name); - state().hasKeyspaceAccess(ks_def.name, Permission.ALTER); + state().hasKeyspaceAccess(ks_def.name, Permission.WRITE); ThriftValidation.validateTable(ks_def.name); if (ks_def.getCf_defs() != null && ks_def.getCf_defs().size() > 0) throw new InvalidRequestException("Keyspace update must not contain any column family definitions."); @@ -1074,9 +1079,9 @@ public class CassandraServer implements Cassandra.Iface throws InvalidRequestException, SchemaDisagreementException, TException { logger.debug("update_column_family"); - state().hasColumnFamilyAccess(cf_def.name, Permission.ALTER); if (cf_def.keyspace == null || cf_def.name == null) throw new InvalidRequestException("Keyspace and CF name must be set."); + state().hasColumnFamilyAccess(cf_def.keyspace, cf_def.name, Permission.WRITE); CFMetaData oldCfm = Schema.instance.getCFMetaData(cf_def.keyspace, cf_def.name); if (oldCfm == null) throw new InvalidRequestException("Could not find column family definition to modify."); @@ -1110,14 +1115,15 @@ public class CassandraServer implements Cassandra.Iface public void truncate(String cfname) throws InvalidRequestException, UnavailableException, TimedOutException, TException { ClientState cState = state(); - logger.debug("truncating {} in {}", cfname, cState.getKeyspace()); - cState.hasColumnFamilyAccess(cfname, Permission.DELETE); + String keyspace = cState.getKeyspace(); + logger.debug("truncating {} in {}", cfname, keyspace); + cState.hasColumnFamilyAccess(keyspace, cfname, Permission.WRITE); try { schedule(DatabaseDescriptor.getRpcTimeout()); try { - StorageProxy.truncateBlocking(cState.getKeyspace(), cfname); + StorageProxy.truncateBlocking(keyspace, cfname); } finally { @@ -1156,8 +1162,8 @@ public class CassandraServer implements Cassandra.Iface logger.debug("add"); ClientState cState = state(); - cState.hasColumnFamilyAccess(column_parent.column_family, Permission.UPDATE); String keyspace = cState.getKeyspace(); + cState.hasColumnFamilyAccess(keyspace, column_parent.column_family, Permission.WRITE); CFMetaData metadata = ThriftValidation.validateColumnFamily(keyspace, column_parent.column_family, true); ThriftValidation.validateKey(metadata, key);