mirror of https://github.com/apache/cassandra
Add guardrail to disallow DROP KEYSPACE commands for non superuser accounts
Patch by Josh McKenzie; reviewed by Aleksey Yeschenko for CASSANDRA-17767
This commit is contained in:
parent
66177be587
commit
91b86487fe
|
|
@ -1,4 +1,5 @@
|
|||
4.2
|
||||
* Add guardrail to disallow DROP KEYSPACE commands (CASSANDRA-17767)
|
||||
* Remove ephemeral snapshot marker file and introduce a flag to SnapshotManifest (CASSANDRA-16911)
|
||||
* Add a virtual table that exposes currently running queries (CASSANDRA-15241)
|
||||
* Allow sstableloader to specify table without relying on path (CASSANDRA-16584)
|
||||
|
|
|
|||
1
NEWS.txt
1
NEWS.txt
|
|
@ -70,6 +70,7 @@ New features
|
|||
- Whether ALTER TABLE commands are allowed to mutate columns
|
||||
- Whether SimpleStrategy is allowed on keyspace creation or alteration
|
||||
- Maximum replication factor
|
||||
- Whether DROP KEYSPACE commands are allowed.
|
||||
- It is possible to list ephemeral snapshots by nodetool listsnaphots command when flag "-e" is specified.
|
||||
|
||||
Upgrading
|
||||
|
|
|
|||
|
|
@ -1724,6 +1724,9 @@ drop_compact_storage_enabled: false
|
|||
# Guardrail to allow/disallow TRUNCATE and DROP TABLE statements
|
||||
# drop_truncate_table_enabled: true
|
||||
#
|
||||
# Guardrail to allow/disallow DROP KEYSPACE statements
|
||||
# drop_keyspace_enabled: true
|
||||
#
|
||||
# Guardrail to warn or fail when using a page size greater than threshold.
|
||||
# The two thresholds default to -1 to disable.
|
||||
# page_size_warn_threshold: -1
|
||||
|
|
|
|||
|
|
@ -831,6 +831,7 @@ public class Config
|
|||
public volatile boolean alter_table_enabled = true;
|
||||
public volatile boolean group_by_enabled = true;
|
||||
public volatile boolean drop_truncate_table_enabled = true;
|
||||
public volatile boolean drop_keyspace_enabled = true;
|
||||
public volatile boolean secondary_indexes_enabled = true;
|
||||
public volatile boolean uncompressed_tables_enabled = true;
|
||||
public volatile boolean compact_tables_enabled = true;
|
||||
|
|
|
|||
|
|
@ -344,6 +344,20 @@ public class GuardrailsOptions implements GuardrailsConfig
|
|||
x -> config.drop_truncate_table_enabled = x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getDropKeyspaceEnabled()
|
||||
{
|
||||
return config.drop_keyspace_enabled;
|
||||
}
|
||||
|
||||
public void setDropKeyspaceEnabled(boolean enabled)
|
||||
{
|
||||
updatePropertyWithLogging("drop_keyspace_enabled",
|
||||
enabled,
|
||||
() -> config.drop_keyspace_enabled,
|
||||
x -> config.drop_keyspace_enabled = x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getSecondaryIndexesEnabled()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import org.apache.cassandra.audit.AuditLogContext;
|
|||
import org.apache.cassandra.audit.AuditLogEntryType;
|
||||
import org.apache.cassandra.auth.Permission;
|
||||
import org.apache.cassandra.cql3.CQLStatement;
|
||||
import org.apache.cassandra.db.guardrails.Guardrails;
|
||||
import org.apache.cassandra.schema.Keyspaces;
|
||||
import org.apache.cassandra.schema.Keyspaces.KeyspacesDiff;
|
||||
import org.apache.cassandra.service.ClientState;
|
||||
|
|
@ -39,6 +40,8 @@ public final class DropKeyspaceStatement extends AlterSchemaStatement
|
|||
|
||||
public Keyspaces apply(Keyspaces schema)
|
||||
{
|
||||
Guardrails.dropKeyspaceEnabled.ensureEnabled(state);
|
||||
|
||||
if (schema.containsKeyspace(keyspaceName))
|
||||
return schema.without(keyspaceName);
|
||||
|
||||
|
|
|
|||
|
|
@ -153,11 +153,22 @@ public final class Guardrails implements GuardrailsMBean
|
|||
state -> CONFIG_PROVIDER.getOrCreate(state).getAlterTableEnabled(),
|
||||
"User access to ALTER TABLE statement for column mutation");
|
||||
|
||||
/**
|
||||
* Guardrail disabling DROP / TRUNCATE TABLE behavior
|
||||
*/
|
||||
public static final EnableFlag dropTruncateTableEnabled =
|
||||
new EnableFlag("drop_truncate_table_enabled",
|
||||
state -> CONFIG_PROVIDER.getOrCreate(state).getDropTruncateTableEnabled(),
|
||||
"DROP and TRUNCATE TABLE functionality");
|
||||
|
||||
/**
|
||||
* Guardrail disabling DROP KEYSPACE behavior
|
||||
*/
|
||||
public static final EnableFlag dropKeyspaceEnabled =
|
||||
new EnableFlag("drop_keyspace_enabled",
|
||||
state -> CONFIG_PROVIDER.getOrCreate(state).getDropKeyspaceEnabled(),
|
||||
"DROP KEYSPACE functionality");
|
||||
|
||||
/**
|
||||
* Guardrail disabling user's ability to turn off compression
|
||||
*/
|
||||
|
|
@ -648,6 +659,18 @@ public final class Guardrails implements GuardrailsMBean
|
|||
DEFAULT_CONFIG.setDropTruncateTableEnabled(enabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getDropKeyspaceEnabled()
|
||||
{
|
||||
return DEFAULT_CONFIG.getDropKeyspaceEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDropKeyspaceEnabled(boolean enabled)
|
||||
{
|
||||
DEFAULT_CONFIG.setDropKeyspaceEnabled(enabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPageSizeWarnThreshold()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -167,6 +167,13 @@ public interface GuardrailsConfig
|
|||
*/
|
||||
boolean getDropTruncateTableEnabled();
|
||||
|
||||
/**
|
||||
* Returns whether DROP on keyspaces is allowed
|
||||
*
|
||||
* @return {@code true} if allowed, {@code false} otherwise.
|
||||
*/
|
||||
boolean getDropKeyspaceEnabled();
|
||||
|
||||
/**
|
||||
* @return The threshold to warn when page size exceeds given size.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -304,6 +304,18 @@ public interface GuardrailsMBean
|
|||
*/
|
||||
void setDropTruncateTableEnabled(boolean enabled);
|
||||
|
||||
/**
|
||||
* Returns whether users can DROP a keyspace
|
||||
*
|
||||
* @return {@code true} if allowed, {@code false} otherwise.
|
||||
*/
|
||||
boolean getDropKeyspaceEnabled();
|
||||
|
||||
/**
|
||||
* Sets whether users can DROP a keyspace
|
||||
*/
|
||||
void setDropKeyspaceEnabled(boolean enabled);
|
||||
|
||||
/**
|
||||
* @return The threshold to warn when requested page size greater than threshold.
|
||||
* -1 means disabled.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* 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.db.guardrails;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
|
||||
public class GuardrailDropKeyspaceTest extends GuardrailTester
|
||||
{
|
||||
private String keyspaceQuery = "CREATE KEYSPACE dkdt WITH replication = {'class': 'SimpleStrategy', 'replication_factor' : 1}";
|
||||
|
||||
private void setGuardrail(boolean enabled)
|
||||
{
|
||||
Guardrails.instance.setDropKeyspaceEnabled(enabled);
|
||||
}
|
||||
|
||||
public GuardrailDropKeyspaceTest()
|
||||
{
|
||||
super(Guardrails.dropKeyspaceEnabled);
|
||||
}
|
||||
|
||||
@After
|
||||
public void afterTest() throws Throwable
|
||||
{
|
||||
setGuardrail(true);
|
||||
execute("DROP KEYSPACE IF EXISTS dkdt");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCanDropWhileFeatureEnabled() throws Throwable
|
||||
{
|
||||
setGuardrail(true);
|
||||
createKeyspace(keyspaceQuery);
|
||||
execute("DROP KEYSPACE dkdt");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCannotDropWhileFeatureDisabled() throws Throwable
|
||||
{
|
||||
setGuardrail(false);
|
||||
createKeyspace(keyspaceQuery);
|
||||
assertFails("DROP KEYSPACE dkdt", "DROP KEYSPACE functionality is not allowed");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIfExistsDoesNotBypassCheck() throws Throwable
|
||||
{
|
||||
setGuardrail(false);
|
||||
createKeyspace(keyspaceQuery);
|
||||
assertFails("DROP KEYSPACE IF EXISTS dkdt", "DROP KEYSPACE functionality is not allowed");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testToggle() throws Throwable
|
||||
{
|
||||
setGuardrail(false);
|
||||
createKeyspace(keyspaceQuery);
|
||||
assertFails("DROP KEYSPACE IF EXISTS dkdt", "DROP KEYSPACE functionality is not allowed");
|
||||
|
||||
setGuardrail(true);
|
||||
execute("DROP KEYSPACE dkdt");
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue