mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-27 18:12:02 +00:00
fix no pwd authentication
This commit is contained in:
parent
c1250ccb35
commit
70e4933221
@ -161,7 +161,7 @@ namespace
|
||||
{
|
||||
auto basic_credentials_authentication_methods = getAuthenticationMethodsOfType(
|
||||
authentication_methods,
|
||||
{AuthenticationType::PLAINTEXT_PASSWORD, AuthenticationType::SHA256_PASSWORD,
|
||||
{AuthenticationType::NO_PASSWORD, AuthenticationType::PLAINTEXT_PASSWORD, AuthenticationType::SHA256_PASSWORD,
|
||||
AuthenticationType::DOUBLE_SHA1_PASSWORD, AuthenticationType::LDAP, AuthenticationType::BCRYPT_PASSWORD,
|
||||
AuthenticationType::HTTP});
|
||||
|
||||
@ -169,6 +169,10 @@ namespace
|
||||
{
|
||||
switch (auth_method.getType())
|
||||
{
|
||||
case AuthenticationType::NO_PASSWORD:
|
||||
{
|
||||
return true;
|
||||
}
|
||||
case AuthenticationType::PLAINTEXT_PASSWORD:
|
||||
if (checkPasswordPlainText(basic_credentials->getPassword(), auth_method.getPasswordHashBinary()))
|
||||
{
|
||||
|
@ -1903,11 +1903,11 @@ void ClientBase::processParsedSingleQuery(const String & full_query, const Strin
|
||||
|
||||
if (const auto * create_user_query = parsed_query->as<ASTCreateUserQuery>())
|
||||
{
|
||||
if (!create_user_query->attach && create_user_query->auth_data)
|
||||
if (!create_user_query->attach && !create_user_query->auth_data.empty())
|
||||
{
|
||||
if (const auto * auth_data = create_user_query->auth_data->as<ASTAuthenticationData>())
|
||||
for (const auto & authentication_method : create_user_query->auth_data)
|
||||
{
|
||||
auto password = auth_data->getPassword();
|
||||
auto password = authentication_method->getPassword();
|
||||
|
||||
if (password)
|
||||
global_context->getAccessControl().checkPasswordComplexityRules(*password);
|
||||
|
@ -33,7 +33,7 @@ namespace
|
||||
void updateUserFromQueryImpl(
|
||||
User & user,
|
||||
const ASTCreateUserQuery & query,
|
||||
const std::optional<AuthenticationData> auth_data,
|
||||
const std::vector<AuthenticationData> auth_data,
|
||||
const std::shared_ptr<ASTUserNameWithHost> & override_name,
|
||||
const std::optional<RolesOrUsersSet> & override_default_roles,
|
||||
const std::optional<SettingsProfileElements> & override_settings,
|
||||
@ -51,15 +51,19 @@ namespace
|
||||
else if (query.names->size() == 1)
|
||||
user.setName(query.names->front()->toString());
|
||||
|
||||
if (!query.attach && !query.alter && !auth_data && !allow_implicit_no_password)
|
||||
// todo arthur check if auth_data.empty makes sense
|
||||
if (!query.attach && !query.alter && !auth_data.empty() && !allow_implicit_no_password)
|
||||
throw Exception(ErrorCodes::BAD_ARGUMENTS,
|
||||
"Authentication type NO_PASSWORD must "
|
||||
"be explicitly specified, check the setting allow_implicit_no_password "
|
||||
"in the server configuration");
|
||||
|
||||
if (auth_data)
|
||||
if (!auth_data.empty())
|
||||
{
|
||||
user.authentication_methods.push_back(*auth_data);
|
||||
for (const auto & authentication_method : auth_data)
|
||||
{
|
||||
user.authentication_methods.push_back(authentication_method);
|
||||
}
|
||||
}
|
||||
else if (user.authentication_methods.empty())
|
||||
{
|
||||
@ -75,7 +79,7 @@ namespace
|
||||
user.authentication_methods.push_back(primary_authentication_method);
|
||||
}
|
||||
|
||||
if (auth_data || !query.alter)
|
||||
if (!auth_data.empty() || !query.alter)
|
||||
{
|
||||
// I suppose it is guaranteed a user will always have at least one authentication method
|
||||
auto auth_type = user.authentication_methods.back().getType();
|
||||
@ -145,9 +149,14 @@ BlockIO InterpreterCreateUserQuery::execute()
|
||||
bool no_password_allowed = access_control.isNoPasswordAllowed();
|
||||
bool plaintext_password_allowed = access_control.isPlaintextPasswordAllowed();
|
||||
|
||||
std::optional<AuthenticationData> auth_data;
|
||||
if (query.auth_data)
|
||||
auth_data = AuthenticationData::fromAST(*query.auth_data, getContext(), !query.attach);
|
||||
std::vector<AuthenticationData> auth_data;
|
||||
if (!query.auth_data.empty())
|
||||
{
|
||||
for (const auto & authentication_method_ast : query.auth_data)
|
||||
{
|
||||
auth_data.push_back(AuthenticationData::fromAST(*authentication_method_ast, getContext(), !query.attach));
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<time_t> valid_until;
|
||||
if (query.valid_until)
|
||||
@ -272,9 +281,14 @@ BlockIO InterpreterCreateUserQuery::execute()
|
||||
|
||||
void InterpreterCreateUserQuery::updateUserFromQuery(User & user, const ASTCreateUserQuery & query, bool allow_no_password, bool allow_plaintext_password)
|
||||
{
|
||||
std::optional<AuthenticationData> auth_data;
|
||||
if (query.auth_data)
|
||||
auth_data = AuthenticationData::fromAST(*query.auth_data, {}, !query.attach);
|
||||
std::vector<AuthenticationData> auth_data;
|
||||
if (!query.auth_data.empty())
|
||||
{
|
||||
for (const auto & authentication_method_ast : query.auth_data)
|
||||
{
|
||||
auth_data.emplace_back(AuthenticationData::fromAST(*authentication_method_ast, {}, !query.attach));
|
||||
}
|
||||
}
|
||||
|
||||
updateUserFromQueryImpl(user, query, auth_data, {}, {}, {}, {}, {}, query.reset_authentication_methods_to_new, allow_no_password, allow_plaintext_password, true);
|
||||
}
|
||||
|
@ -64,11 +64,13 @@ namespace
|
||||
query->default_roles = user.default_roles.toASTWithNames(*access_control);
|
||||
}
|
||||
|
||||
// todo arthur
|
||||
// to fix this, I'll need to turn `query->auth_data` into a list
|
||||
// that also means creating a user with multiple authentication methods should be allowed
|
||||
if (user.authentication_methods[0].getType() != AuthenticationType::NO_PASSWORD)
|
||||
query->auth_data = user.authentication_methods[0].toAST();
|
||||
for (const auto & authentication_method : user.authentication_methods)
|
||||
{
|
||||
if (authentication_method.getType() != AuthenticationType::NO_PASSWORD)
|
||||
{
|
||||
query->auth_data.push_back(authentication_method.toAST());
|
||||
}
|
||||
}
|
||||
|
||||
if (user.valid_until)
|
||||
{
|
||||
|
@ -18,9 +18,12 @@ namespace
|
||||
<< quoteString(new_name);
|
||||
}
|
||||
|
||||
void formatAuthenticationData(const ASTAuthenticationData & auth_data, const IAST::FormatSettings & settings)
|
||||
void formatAuthenticationData(const std::vector<std::shared_ptr<ASTAuthenticationData>> & auth_data, const IAST::FormatSettings & settings)
|
||||
{
|
||||
auth_data.format(settings);
|
||||
for (const auto & authentication_method : auth_data)
|
||||
{
|
||||
authentication_method->format(settings);
|
||||
}
|
||||
}
|
||||
|
||||
void formatValidUntil(const IAST & valid_until, const IAST::FormatSettings & settings)
|
||||
@ -180,10 +183,13 @@ ASTPtr ASTCreateUserQuery::clone() const
|
||||
if (settings)
|
||||
res->settings = std::static_pointer_cast<ASTSettingsProfileElements>(settings->clone());
|
||||
|
||||
if (auth_data)
|
||||
if (!auth_data.empty())
|
||||
{
|
||||
res->auth_data = std::static_pointer_cast<ASTAuthenticationData>(auth_data->clone());
|
||||
res->children.push_back(res->auth_data);
|
||||
for (const auto & authentication_method : auth_data)
|
||||
{
|
||||
res->auth_data.push_back(std::static_pointer_cast<ASTAuthenticationData>(authentication_method->clone()));
|
||||
res->children.push_back(res->auth_data.back());
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
@ -222,8 +228,8 @@ void ASTCreateUserQuery::formatImpl(const FormatSettings & format, FormatState &
|
||||
if (new_name)
|
||||
formatRenameTo(*new_name, format);
|
||||
|
||||
if (auth_data)
|
||||
formatAuthenticationData(*auth_data, format);
|
||||
if (!auth_data.empty())
|
||||
formatAuthenticationData(auth_data, format);
|
||||
|
||||
if (valid_until)
|
||||
formatValidUntil(*valid_until, format);
|
||||
|
@ -48,7 +48,7 @@ public:
|
||||
std::optional<String> new_name;
|
||||
String storage_name;
|
||||
|
||||
std::shared_ptr<ASTAuthenticationData> auth_data;
|
||||
std::vector<std::shared_ptr<ASTAuthenticationData>> auth_data;
|
||||
|
||||
std::optional<AllowedClientHosts> hosts;
|
||||
std::optional<AllowedClientHosts> add_hosts;
|
||||
|
@ -455,7 +455,7 @@ bool ParserCreateUserQuery::parseImpl(Pos & pos, ASTPtr & node, Expected & expec
|
||||
std::optional<AllowedClientHosts> hosts;
|
||||
std::optional<AllowedClientHosts> add_hosts;
|
||||
std::optional<AllowedClientHosts> remove_hosts;
|
||||
std::shared_ptr<ASTAuthenticationData> auth_data;
|
||||
std::vector<std::shared_ptr<ASTAuthenticationData>> auth_data;
|
||||
std::shared_ptr<ASTRolesOrUsersSet> default_roles;
|
||||
std::shared_ptr<ASTSettingsProfileElements> settings;
|
||||
std::shared_ptr<ASTRolesOrUsersSet> grantees;
|
||||
@ -467,12 +467,12 @@ bool ParserCreateUserQuery::parseImpl(Pos & pos, ASTPtr & node, Expected & expec
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (!auth_data)
|
||||
if (auth_data.empty())
|
||||
{
|
||||
std::shared_ptr<ASTAuthenticationData> new_auth_data;
|
||||
if (parseAuthenticationData(pos, expected, new_auth_data))
|
||||
{
|
||||
auth_data = std::move(new_auth_data);
|
||||
auth_data.push_back(new_auth_data);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@ -582,8 +582,14 @@ bool ParserCreateUserQuery::parseImpl(Pos & pos, ASTPtr & node, Expected & expec
|
||||
query->storage_name = std::move(storage_name);
|
||||
query->reset_authentication_methods_to_new = reset_authentication_methods_to_new.value_or(false);
|
||||
|
||||
if (query->auth_data)
|
||||
query->children.push_back(query->auth_data);
|
||||
if (!query->auth_data.empty())
|
||||
{
|
||||
// as of now, this will always have a single element, but looping just in case.
|
||||
for (const auto & authentication_method : query->auth_data)
|
||||
{
|
||||
query->children.push_back(authentication_method);
|
||||
}
|
||||
}
|
||||
|
||||
if (query->valid_until)
|
||||
query->children.push_back(query->valid_until);
|
||||
|
Loading…
Reference in New Issue
Block a user