Merge pull request #9840 from vitlibar/fix-grants-for-introspection

Fix calculating grants for introspection
This commit is contained in:
Vitaly Baranov 2020-03-24 22:43:50 +03:00 committed by GitHub
commit db89b24948
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 34 additions and 11 deletions

View File

@ -372,17 +372,17 @@ boost::shared_ptr<const AccessRights> ContextAccess::calculateResultAccess(bool
boost::shared_ptr<const AccessRights> ContextAccess::calculateResultAccess(bool grant_option, UInt64 readonly_, bool allow_ddl_, bool allow_introspection_) const
{
size_t cache_index = static_cast<size_t>(readonly_ != params.readonly)
size_t index = static_cast<size_t>(readonly_ != params.readonly)
+ static_cast<size_t>(allow_ddl_ != params.allow_ddl) * 2 +
+ static_cast<size_t>(allow_introspection_ != params.allow_introspection) * 3
+ static_cast<size_t>(grant_option) * 4;
assert(cache_index < std::size(result_access));
auto res = result_access[cache_index].load();
assert(index < std::size(result_access));
auto res = result_access[index].load();
if (res)
return res;
std::lock_guard lock{mutex};
res = result_access[cache_index].load();
res = result_access[index].load();
if (res)
return res;
@ -412,10 +412,7 @@ boost::shared_ptr<const AccessRights> ContextAccess::calculateResultAccess(bool
| AccessType::DROP_ROLE | AccessType::DROP_POLICY | AccessType::DROP_QUOTA | AccessType::ROLE_ADMIN;
if (readonly_)
merged_access->revoke(write_table_access | all_dcl | AccessType::SYSTEM | AccessType::KILL_QUERY);
if (readonly_ || !allow_ddl_)
merged_access->revoke(table_and_dictionary_ddl);
merged_access->revoke(write_table_access | all_dcl | table_and_dictionary_ddl | AccessType::SYSTEM | AccessType::KILL_QUERY);
if (readonly_ == 1)
{
@ -424,7 +421,10 @@ boost::shared_ptr<const AccessRights> ContextAccess::calculateResultAccess(bool
merged_access->revoke(AccessType::CREATE_TEMPORARY_TABLE | AccessType::TABLE_FUNCTIONS);
}
if (!allow_introspection_)
if (!allow_ddl_ && !grant_option)
merged_access->revoke(table_and_dictionary_ddl);
if (!allow_introspection_ && !grant_option)
merged_access->revoke(AccessType::INTROSPECTION);
/// Anyone has access to the "system" database.
@ -452,10 +452,11 @@ boost::shared_ptr<const AccessRights> ContextAccess::calculateResultAccess(bool
"Current_roles: " << boost::algorithm::join(roles_info->getCurrentRolesNames(), ", ")
<< ", enabled_roles: " << boost::algorithm::join(roles_info->getEnabledRolesNames(), ", "));
}
LOG_TRACE(trace_log, "Settings: readonly=" << readonly_ << ", allow_ddl=" << allow_ddl_ << ", allow_introspection_functions=" << allow_introspection_);
}
res = std::move(merged_access);
result_access[cache_index].store(res);
result_access[index].store(res);
return res;
}

View File

@ -634,7 +634,7 @@ void Context::setUser(const String & name, const String & password, const Poco::
std::shared_ptr<const ContextAccess> new_access;
if (new_user_id)
{
new_access = getAccessControlManager().getContextAccess(*new_user_id, {}, true, {}, current_database, client_info);
new_access = getAccessControlManager().getContextAccess(*new_user_id, {}, true, settings, current_database, client_info);
if (!new_access->isClientHostAllowed() || !new_access->isCorrectPassword(password))
{
new_user_id = {};

View File

@ -104,3 +104,25 @@ def test_alter_and_drop():
assert instance.query("SELECT value FROM system.settings WHERE name = 'max_memory_usage'", user="robin") == "10000000000\n"
instance.query("SET max_memory_usage = 80000000", user="robin")
instance.query("SET max_memory_usage = 120000000", user="robin")
def test_allow_introspection():
assert "Not enough privileges" in instance.query_and_get_error("SELECT demangle('a')", user="robin")
instance.query("GRANT ALL ON *.* TO robin")
assert "Introspection functions are disabled" in instance.query_and_get_error("SELECT demangle('a')", user="robin")
instance.query("ALTER USER robin SETTINGS allow_introspection_functions=1")
assert instance.query("SELECT demangle('a')", user="robin") == "signed char\n"
instance.query("ALTER USER robin SETTINGS NONE")
assert "Introspection functions are disabled" in instance.query_and_get_error("SELECT demangle('a')", user="robin")
instance.query("CREATE SETTINGS PROFILE xyz SETTINGS allow_introspection_functions=1 TO robin")
assert instance.query("SELECT demangle('a')", user="robin") == "signed char\n"
instance.query("DROP SETTINGS PROFILE xyz")
assert "Introspection functions are disabled" in instance.query_and_get_error("SELECT demangle('a')", user="robin")
instance.query("REVOKE ALL ON *.* FROM robin")
assert "Not enough privileges" in instance.query_and_get_error("SELECT demangle('a')", user="robin")