Merge pull request #7793 from DeifyTheGod/master

fix zero-access user creation
This commit is contained in:
alexey-milovidov 2019-11-19 20:04:07 +03:00 committed by GitHub
commit 4d4de7da95
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 151 additions and 8 deletions

View File

@ -75,14 +75,15 @@ User::User(const String & name_, const String & config_elem, const Poco::Util::A
const auto config_sub_elem = config_elem + ".allow_databases";
if (config.has(config_sub_elem))
{
databases = DatabaseSet();
Poco::Util::AbstractConfiguration::Keys config_keys;
config.keys(config_sub_elem, config_keys);
databases.reserve(config_keys.size());
databases->reserve(config_keys.size());
for (const auto & key : config_keys)
{
const auto database_name = config.getString(config_sub_elem + "." + key);
databases.insert(database_name);
databases->insert(database_name);
}
}
@ -90,14 +91,15 @@ User::User(const String & name_, const String & config_elem, const Poco::Util::A
const auto config_dictionary_sub_elem = config_elem + ".allow_dictionaries";
if (config.has(config_dictionary_sub_elem))
{
dictionaries = DictionarySet();
Poco::Util::AbstractConfiguration::Keys config_keys;
config.keys(config_dictionary_sub_elem, config_keys);
dictionaries.reserve(config_keys.size());
dictionaries->reserve(config_keys.size());
for (const auto & key : config_keys)
{
const auto dictionary_name = config.getString(config_dictionary_sub_elem + "." + key);
dictionaries.insert(dictionary_name);
dictionaries->insert(dictionary_name);
}
}

View File

@ -36,11 +36,11 @@ struct User
/// List of allowed databases.
using DatabaseSet = std::unordered_set<std::string>;
DatabaseSet databases;
std::optional<DatabaseSet> databases;
/// List of allowed dictionaries.
using DictionarySet = std::unordered_set<std::string>;
DictionarySet dictionaries;
std::optional<DictionarySet> dictionaries;
/// Table properties.
using PropertyMap = std::unordered_map<std::string /* name */, std::string /* value */>;

View File

@ -63,7 +63,7 @@ bool UsersManager::hasAccessToDatabase(const std::string & user_name, const std:
throw Exception("Unknown user " + user_name, ErrorCodes::UNKNOWN_USER);
auto user = it->second;
return user->databases.empty() || user->databases.count(database_name);
return !user->databases.has_value() || user->databases->count(database_name);
}
bool UsersManager::hasAccessToDictionary(const std::string & user_name, const std::string & dictionary_name) const
@ -74,6 +74,6 @@ bool UsersManager::hasAccessToDictionary(const std::string & user_name, const st
throw Exception("Unknown user " + user_name, ErrorCodes::UNKNOWN_USER);
auto user = it->second;
return user->dictionaries.empty() || user->dictionaries.count(dictionary_name);
return !user->dictionaries.has_value() || user->dictionaries->count(dictionary_name);
}
}

View File

@ -0,0 +1,31 @@
<?xml version="1.0"?>
<yandex>
<logger>
<level>trace</level>
<log>/var/log/clickhouse-server/clickhouse-server.log</log>
<errorlog>/var/log/clickhouse-server/clickhouse-server.err.log</errorlog>
<size>1000M</size>
<count>10</count>
</logger>
<tcp_port>9000</tcp_port>
<listen_host>127.0.0.1</listen_host>
<openSSL>
<client>
<cacheSessions>true</cacheSessions>
<verificationMode>none</verificationMode>
<invalidCertificateHandler>
<name>AcceptCertificateHandler</name>
</invalidCertificateHandler>
</client>
</openSSL>
<max_concurrent_queries>500</max_concurrent_queries>
<mark_cache_size>5368709120</mark_cache_size>
<path>./clickhouse/</path>
<users_config>users.xml</users_config>
<max_table_size_to_drop>1</max_table_size_to_drop>
<max_partition_size_to_drop>1</max_partition_size_to_drop>
</yandex>

View File

@ -0,0 +1,46 @@
<?xml version="1.0"?>
<yandex>
<profiles>
<default>
</default>
</profiles>
<users>
<default>
<password></password>
<networks incl="networks" replace="replace">
<ip>::/0</ip>
</networks>
<profile>default</profile>
<quota>default</quota>
</default>
<no_access>
<password></password>
<networks incl="networks" replace="replace">
<ip>::/0</ip>
</networks>
<profile>default</profile>
<quota>default</quota>
<allow_databases></allow_databases>
</no_access>
<has_access>
<password></password>
<networks incl="networks" replace="replace">
<ip>::/0</ip>
</networks>
<profile>default</profile>
<quota>default</quota>
<allow_databases>
<database>test</database>
<database>db1</database>
</allow_databases>
</has_access>
</users>
<quotas>
<default>
</default>
</quotas>
</yandex>

View File

@ -0,0 +1,64 @@
import time
import pytest
from helpers.cluster import ClickHouseCluster
cluster = ClickHouseCluster(__file__)
node = cluster.add_instance('node', config_dir="configs")
@pytest.fixture(scope="module")
def start_cluster():
try:
cluster.start()
node.query("CREATE DATABASE test;")
yield cluster
finally:
cluster.shutdown()
def test_user_zero_database_access(start_cluster):
try:
node.exec_in_container(["bash", "-c", "/usr/bin/clickhouse client --user 'no_access' --query 'DROP DATABASE test'"], user='root')
assert False, "user with no access rights dropped database test"
except AssertionError:
raise
except Exception as ex:
print ex
try:
node.exec_in_container(["bash", "-c", "/usr/bin/clickhouse client --user 'has_access' --query 'DROP DATABASE test'"], user='root')
except Exception as ex:
assert False, "user with access rights can't drop database test"
try:
node.exec_in_container(["bash", "-c", "/usr/bin/clickhouse client --user 'has_access' --query 'CREATE DATABASE test'"], user='root')
except Exception as ex:
assert False, "user with access rights can't create database test"
try:
node.exec_in_container(["bash", "-c", "/usr/bin/clickhouse client --user 'no_access' --query 'CREATE DATABASE test2'"], user='root')
assert False, "user with no access rights created database test2"
except AssertionError:
raise
except Exception as ex:
print ex
try:
node.exec_in_container(["bash", "-c", "/usr/bin/clickhouse client --user 'has_access' --query 'CREATE DATABASE test2'"], user='root')
assert False, "user with limited access rights created database test2 which is outside of his scope of rights"
except AssertionError:
raise
except Exception as ex:
print ex
try:
node.exec_in_container(["bash", "-c", "/usr/bin/clickhouse client --user 'default' --query 'CREATE DATABASE test2'"], user='root')
except Exception as ex:
assert False, "user with full access rights can't create database test2"
try:
node.exec_in_container(["bash", "-c", "/usr/bin/clickhouse client --user 'default' --query 'DROP DATABASE test2'"], user='root')
except Exception as ex:
assert False, "user with full access rights can't drop database test2"