2020-02-04 22:37:04 +00:00
|
|
|
#include <Interpreters/InterpreterGrantQuery.h>
|
|
|
|
#include <Parsers/ASTGrantQuery.h>
|
2020-05-30 20:10:45 +00:00
|
|
|
#include <Parsers/ASTRolesOrUsersSet.h>
|
2020-02-04 22:37:04 +00:00
|
|
|
#include <Interpreters/Context.h>
|
2020-04-05 23:03:20 +00:00
|
|
|
#include <Interpreters/DDLWorker.h>
|
2020-02-04 22:37:04 +00:00
|
|
|
#include <Access/AccessControlManager.h>
|
2020-03-07 17:37:38 +00:00
|
|
|
#include <Access/ContextAccess.h>
|
2020-05-30 20:10:45 +00:00
|
|
|
#include <Access/RolesOrUsersSet.h>
|
2020-02-04 22:37:04 +00:00
|
|
|
#include <Access/User.h>
|
2020-02-17 02:59:56 +00:00
|
|
|
#include <Access/Role.h>
|
|
|
|
#include <boost/range/algorithm/copy.hpp>
|
2020-02-04 22:37:04 +00:00
|
|
|
|
|
|
|
|
|
|
|
namespace DB
|
|
|
|
{
|
2020-02-21 19:27:12 +00:00
|
|
|
namespace
|
2020-02-04 22:37:04 +00:00
|
|
|
{
|
2020-02-21 19:27:12 +00:00
|
|
|
template <typename T>
|
2020-06-20 22:44:52 +00:00
|
|
|
void updateFromQueryImpl(T & grantee, const ASTGrantQuery & query, const std::vector<UUID> & roles_from_query)
|
2020-02-04 22:37:04 +00:00
|
|
|
{
|
2020-02-21 19:27:12 +00:00
|
|
|
using Kind = ASTGrantQuery::Kind;
|
2020-02-17 02:59:56 +00:00
|
|
|
if (!query.access_rights_elements.empty())
|
|
|
|
{
|
|
|
|
if (query.kind == Kind::GRANT)
|
|
|
|
{
|
|
|
|
if (query.grant_option)
|
2020-06-20 22:44:52 +00:00
|
|
|
grantee.access.grantWithGrantOption(query.access_rights_elements);
|
2020-04-20 22:07:00 +00:00
|
|
|
else
|
2020-06-20 22:44:52 +00:00
|
|
|
grantee.access.grant(query.access_rights_elements);
|
2020-02-17 02:59:56 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-04-20 22:07:00 +00:00
|
|
|
if (query.grant_option)
|
2020-06-20 22:44:52 +00:00
|
|
|
grantee.access.revokeGrantOption(query.access_rights_elements);
|
2020-04-20 22:07:00 +00:00
|
|
|
else
|
2020-06-20 22:44:52 +00:00
|
|
|
grantee.access.revoke(query.access_rights_elements);
|
2020-02-17 02:59:56 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-02-21 19:27:12 +00:00
|
|
|
if (!roles_from_query.empty())
|
2020-02-04 22:37:04 +00:00
|
|
|
{
|
2020-02-17 02:59:56 +00:00
|
|
|
if (query.kind == Kind::GRANT)
|
|
|
|
{
|
|
|
|
if (query.admin_option)
|
2020-04-20 22:07:00 +00:00
|
|
|
grantee.granted_roles.grantWithAdminOption(roles_from_query);
|
|
|
|
else
|
|
|
|
grantee.granted_roles.grant(roles_from_query);
|
2020-02-17 02:59:56 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-04-20 22:07:00 +00:00
|
|
|
if (query.admin_option)
|
|
|
|
grantee.granted_roles.revokeAdminOption(roles_from_query);
|
|
|
|
else
|
|
|
|
grantee.granted_roles.revoke(roles_from_query);
|
|
|
|
|
|
|
|
if constexpr (std::is_same_v<T, User>)
|
2020-02-17 02:59:56 +00:00
|
|
|
{
|
2020-04-20 22:07:00 +00:00
|
|
|
for (const UUID & role_from_query : roles_from_query)
|
2020-02-21 19:27:12 +00:00
|
|
|
grantee.default_roles.ids.erase(role_from_query);
|
2020-02-17 02:59:56 +00:00
|
|
|
}
|
|
|
|
}
|
2020-02-04 22:37:04 +00:00
|
|
|
}
|
2020-02-21 19:27:12 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
BlockIO InterpreterGrantQuery::execute()
|
|
|
|
{
|
2020-04-05 23:03:20 +00:00
|
|
|
auto & query = query_ptr->as<ASTGrantQuery &>();
|
2020-06-20 22:44:52 +00:00
|
|
|
query.replaceCurrentUserTagWithName(context.getUserName());
|
2020-03-07 17:37:38 +00:00
|
|
|
auto access = context.getAccess();
|
2020-06-20 22:44:52 +00:00
|
|
|
auto & access_control = context.getAccessControlManager();
|
2020-02-21 19:27:12 +00:00
|
|
|
|
|
|
|
std::vector<UUID> roles_from_query;
|
|
|
|
if (query.roles)
|
|
|
|
{
|
2020-05-30 20:10:45 +00:00
|
|
|
roles_from_query = RolesOrUsersSet{*query.roles, access_control}.getMatchingIDs(access_control);
|
2020-02-21 19:27:12 +00:00
|
|
|
for (const UUID & role_from_query : roles_from_query)
|
2020-03-07 17:37:38 +00:00
|
|
|
access->checkAdminOption(role_from_query);
|
2020-02-21 19:27:12 +00:00
|
|
|
}
|
|
|
|
|
2020-04-05 23:03:20 +00:00
|
|
|
if (!query.cluster.empty())
|
2020-06-20 22:44:52 +00:00
|
|
|
return executeDDLQueryOnCluster(query_ptr, context, query.access_rights_elements, true);
|
|
|
|
|
|
|
|
query.replaceEmptyDatabaseWithCurrent(context.getCurrentDatabase());
|
|
|
|
access->checkGrantOption(query.access_rights_elements);
|
2020-04-05 23:03:20 +00:00
|
|
|
|
2020-05-30 20:10:45 +00:00
|
|
|
std::vector<UUID> to_roles = RolesOrUsersSet{*query.to_roles, access_control, context.getUserID()}.getMatchingIDs(access_control);
|
2020-02-21 19:27:12 +00:00
|
|
|
|
|
|
|
auto update_func = [&](const AccessEntityPtr & entity) -> AccessEntityPtr
|
|
|
|
{
|
|
|
|
auto clone = entity->clone();
|
|
|
|
if (auto user = typeid_cast<std::shared_ptr<User>>(clone))
|
|
|
|
{
|
2020-06-20 22:44:52 +00:00
|
|
|
updateFromQueryImpl(*user, query, roles_from_query);
|
2020-02-21 19:27:12 +00:00
|
|
|
return user;
|
|
|
|
}
|
|
|
|
else if (auto role = typeid_cast<std::shared_ptr<Role>>(clone))
|
|
|
|
{
|
2020-06-20 22:44:52 +00:00
|
|
|
updateFromQueryImpl(*role, query, roles_from_query);
|
2020-02-21 19:27:12 +00:00
|
|
|
return role;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return entity;
|
2020-02-04 22:37:04 +00:00
|
|
|
};
|
|
|
|
|
2020-02-10 02:26:56 +00:00
|
|
|
access_control.update(to_roles, update_func);
|
|
|
|
|
2020-02-04 22:37:04 +00:00
|
|
|
return {};
|
|
|
|
}
|
|
|
|
|
2020-02-21 19:27:12 +00:00
|
|
|
|
|
|
|
void InterpreterGrantQuery::updateUserFromQuery(User & user, const ASTGrantQuery & query)
|
|
|
|
{
|
|
|
|
std::vector<UUID> roles_from_query;
|
|
|
|
if (query.roles)
|
2020-05-30 20:10:45 +00:00
|
|
|
roles_from_query = RolesOrUsersSet{*query.roles}.getMatchingIDs();
|
2020-06-20 22:44:52 +00:00
|
|
|
updateFromQueryImpl(user, query, roles_from_query);
|
2020-02-21 19:27:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void InterpreterGrantQuery::updateRoleFromQuery(Role & role, const ASTGrantQuery & query)
|
|
|
|
{
|
|
|
|
std::vector<UUID> roles_from_query;
|
|
|
|
if (query.roles)
|
2020-05-30 20:10:45 +00:00
|
|
|
roles_from_query = RolesOrUsersSet{*query.roles}.getMatchingIDs();
|
2020-06-20 22:44:52 +00:00
|
|
|
updateFromQueryImpl(role, query, roles_from_query);
|
2020-02-21 19:27:12 +00:00
|
|
|
}
|
|
|
|
|
2020-02-04 22:37:04 +00:00
|
|
|
}
|