mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-09-19 16:20:50 +00:00
Better
This commit is contained in:
parent
0621222737
commit
b599d0bd01
@ -476,10 +476,10 @@
|
||||
<allow_no_password>1</allow_no_password>
|
||||
<allow_implicit_no_password>1</allow_implicit_no_password>
|
||||
|
||||
<!-- Default password type when the user does not specify it.
|
||||
Accepted values are: 'plaintext', 'sha256', 'double_sha1'
|
||||
<!-- When a user does not specify a password type in the CREATE USER query, the default password type is used.
|
||||
Accepted values are: 'plaintext_password', 'sha256_password', and 'double_sha1_password'.
|
||||
-->
|
||||
<default_password_type>sha256</default_password_type>
|
||||
<default_password_type>sha256_password</default_password_type>
|
||||
|
||||
<!-- Complexity requirements for user passwords. -->
|
||||
<!-- <password_complexity>
|
||||
|
@ -271,7 +271,7 @@ void AccessControl::setUpFromMainConfig(const Poco::Util::AbstractConfiguration
|
||||
setImplicitNoPasswordAllowed(config_.getBool("allow_implicit_no_password", true));
|
||||
setNoPasswordAllowed(config_.getBool("allow_no_password", true));
|
||||
setPlaintextPasswordAllowed(config_.getBool("allow_plaintext_password", true));
|
||||
setDefaultPasswordTypeFromConfig(config_.getString("default_password_type", "sha256"));
|
||||
setDefaultPasswordTypeFromConfig(config_.getString("default_password_type", "sha256_password"));
|
||||
setPasswordComplexityRulesFromConfig(config_);
|
||||
|
||||
/// Optional improvements in access control system.
|
||||
@ -656,14 +656,18 @@ bool AccessControl::isPlaintextPasswordAllowed() const
|
||||
|
||||
void AccessControl::setDefaultPasswordTypeFromConfig(const String & type_)
|
||||
{
|
||||
if (type_ == "plaintext")
|
||||
default_password_type = AuthenticationType::PLAINTEXT_PASSWORD;
|
||||
else if (type_ == "double_sha1")
|
||||
default_password_type = AuthenticationType::DOUBLE_SHA1_PASSWORD;
|
||||
else if (type_ == "sha256")
|
||||
default_password_type = AuthenticationType::SHA256_PASSWORD;
|
||||
else
|
||||
throw Exception(ErrorCodes::UNKNOWN_ELEMENT_IN_CONFIG, "Unknown password type in 'default_password_type' in config");
|
||||
for (auto check_type : collections::range(AuthenticationType::MAX))
|
||||
{
|
||||
const auto & info = AuthenticationTypeInfo::get(check_type);
|
||||
|
||||
if (type_ == info.name && info.is_password)
|
||||
{
|
||||
default_password_type = check_type;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
throw Exception(ErrorCodes::UNKNOWN_ELEMENT_IN_CONFIG, "Unknown password type in 'default_password_type' in config");
|
||||
}
|
||||
|
||||
AuthenticationType AccessControl::getDefaultPasswordType() const
|
||||
|
@ -153,7 +153,6 @@ public:
|
||||
AuthenticationType getDefaultPasswordType() const;
|
||||
|
||||
/// Check complexity requirements for passwords
|
||||
|
||||
void setPasswordComplexityRulesFromConfig(const Poco::Util::AbstractConfiguration & config_);
|
||||
void setPasswordComplexityRules(const std::vector<std::pair<String, String>> & rules_);
|
||||
void checkPasswordComplexityRules(const String & password_) const;
|
||||
|
@ -20,11 +20,11 @@ namespace ErrorCodes
|
||||
|
||||
const AuthenticationTypeInfo & AuthenticationTypeInfo::get(AuthenticationType type_)
|
||||
{
|
||||
static constexpr auto make_info = [](const char * raw_name_)
|
||||
static constexpr auto make_info = [](const char * raw_name_, bool is_password_ = false)
|
||||
{
|
||||
String init_name = raw_name_;
|
||||
boost::to_lower(init_name);
|
||||
return AuthenticationTypeInfo{raw_name_, std::move(init_name)};
|
||||
return AuthenticationTypeInfo{raw_name_, std::move(init_name), is_password_};
|
||||
};
|
||||
|
||||
switch (type_)
|
||||
@ -36,17 +36,17 @@ const AuthenticationTypeInfo & AuthenticationTypeInfo::get(AuthenticationType ty
|
||||
}
|
||||
case AuthenticationType::PLAINTEXT_PASSWORD:
|
||||
{
|
||||
static const auto info = make_info("PLAINTEXT_PASSWORD");
|
||||
static const auto info = make_info("PLAINTEXT_PASSWORD", true);
|
||||
return info;
|
||||
}
|
||||
case AuthenticationType::SHA256_PASSWORD:
|
||||
{
|
||||
static const auto info = make_info("SHA256_PASSWORD");
|
||||
static const auto info = make_info("SHA256_PASSWORD", true);
|
||||
return info;
|
||||
}
|
||||
case AuthenticationType::DOUBLE_SHA1_PASSWORD:
|
||||
{
|
||||
static const auto info = make_info("DOUBLE_SHA1_PASSWORD");
|
||||
static const auto info = make_info("DOUBLE_SHA1_PASSWORD", true);
|
||||
return info;
|
||||
}
|
||||
case AuthenticationType::LDAP:
|
||||
|
@ -39,6 +39,7 @@ struct AuthenticationTypeInfo
|
||||
{
|
||||
const char * const raw_name;
|
||||
const String name; /// Lowercased with underscores, e.g. "sha256_password".
|
||||
bool is_password;
|
||||
static const AuthenticationTypeInfo & get(AuthenticationType type_);
|
||||
};
|
||||
|
||||
|
@ -43,7 +43,7 @@ namespace
|
||||
for (size_t i = 0; i < args_size; ++i)
|
||||
args[i] = evaluateConstantExpressionAsLiteral(query.children[i], context);
|
||||
|
||||
if (query.expect_password)
|
||||
if (query.is_password)
|
||||
{
|
||||
if (!query.type && !context)
|
||||
throw Exception(ErrorCodes::LOGICAL_ERROR, "Cannot get default password type without context");
|
||||
@ -101,23 +101,23 @@ namespace
|
||||
|
||||
AuthenticationData auth_data(*query.type);
|
||||
|
||||
if (query.expect_hash)
|
||||
if (query.is_hash)
|
||||
{
|
||||
String value = checkAndGetLiteralArgument<String>(args[0], "hash");
|
||||
auth_data.setPasswordHashHex(value);
|
||||
|
||||
if (*query.type == AuthenticationType::SHA256_PASSWORD && args_size == 2)
|
||||
if (query.type == AuthenticationType::SHA256_PASSWORD && args_size == 2)
|
||||
{
|
||||
String parsed_salt = checkAndGetLiteralArgument<String>(args[1], "salt");
|
||||
auth_data.setSalt(parsed_salt);
|
||||
}
|
||||
}
|
||||
else if (query.expect_ldap_server_name)
|
||||
else if (query.type == AuthenticationType::LDAP)
|
||||
{
|
||||
String value = checkAndGetLiteralArgument<String>(args[0], "ldap_server_name");
|
||||
auth_data.setLDAPServerName(value);
|
||||
}
|
||||
else if (query.expect_kerberos_realm)
|
||||
else if (query.type == AuthenticationType::KERBEROS)
|
||||
{
|
||||
if (!args.empty())
|
||||
{
|
||||
@ -125,7 +125,7 @@ namespace
|
||||
auth_data.setKerberosRealm(value);
|
||||
}
|
||||
}
|
||||
else if (query.expect_common_names)
|
||||
else if (query.type == AuthenticationType::SSL_CERTIFICATE)
|
||||
{
|
||||
boost::container::flat_set<String> common_names;
|
||||
for (const auto & arg : args)
|
||||
@ -133,6 +133,11 @@ namespace
|
||||
|
||||
auth_data.setSSLCertificateCommonNames(std::move(common_names));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw Exception(ErrorCodes::LOGICAL_ERROR, "Unexpected ASTAuthenticationData structure");
|
||||
}
|
||||
|
||||
|
||||
return auth_data;
|
||||
}
|
||||
|
@ -54,13 +54,13 @@ namespace
|
||||
{
|
||||
case AuthenticationType::PLAINTEXT_PASSWORD:
|
||||
{
|
||||
node->expect_password = true;
|
||||
node->is_password = true;
|
||||
node->children.push_back(std::make_shared<ASTLiteral>(auth_data.getPassword()));
|
||||
break;
|
||||
}
|
||||
case AuthenticationType::SHA256_PASSWORD:
|
||||
{
|
||||
node->expect_hash = true;
|
||||
node->is_hash = true;
|
||||
node->children.push_back(std::make_shared<ASTLiteral>(auth_data.getPasswordHashHex()));
|
||||
|
||||
if (!auth_data.getSalt().empty())
|
||||
@ -69,19 +69,17 @@ namespace
|
||||
}
|
||||
case AuthenticationType::DOUBLE_SHA1_PASSWORD:
|
||||
{
|
||||
node->expect_hash = true;
|
||||
node->is_hash = true;
|
||||
node->children.push_back(std::make_shared<ASTLiteral>(auth_data.getPasswordHashHex()));
|
||||
break;
|
||||
}
|
||||
case AuthenticationType::LDAP:
|
||||
{
|
||||
node->expect_ldap_server_name = true;
|
||||
node->children.push_back(std::make_shared<ASTLiteral>(auth_data.getLDAPServerName()));
|
||||
break;
|
||||
}
|
||||
case AuthenticationType::KERBEROS:
|
||||
{
|
||||
node->expect_kerberos_realm = true;
|
||||
const auto & realm = auth_data.getKerberosRealm();
|
||||
|
||||
if (!realm.empty())
|
||||
@ -91,7 +89,6 @@ namespace
|
||||
}
|
||||
case AuthenticationType::SSL_CERTIFICATE:
|
||||
{
|
||||
node->expect_common_names = true;
|
||||
for (const auto & name : auth_data.getSSLCertificateCommonNames())
|
||||
node->children.push_back(std::make_shared<ASTLiteral>(name));
|
||||
|
||||
|
@ -17,7 +17,7 @@ namespace ErrorCodes
|
||||
|
||||
std::optional<String> ASTAuthenticationData::getPassword() const
|
||||
{
|
||||
if (expect_password)
|
||||
if (is_password)
|
||||
{
|
||||
if (const auto * password = children[0]->as<const ASTLiteral>())
|
||||
{
|
||||
@ -70,7 +70,7 @@ void ASTAuthenticationData::formatImpl(const FormatSettings & settings, FormatSt
|
||||
}
|
||||
case AuthenticationType::SHA256_PASSWORD:
|
||||
{
|
||||
if (expect_hash)
|
||||
if (is_hash)
|
||||
auth_type_name = "sha256_hash";
|
||||
|
||||
prefix = "BY";
|
||||
@ -81,7 +81,7 @@ void ASTAuthenticationData::formatImpl(const FormatSettings & settings, FormatSt
|
||||
}
|
||||
case AuthenticationType::DOUBLE_SHA1_PASSWORD:
|
||||
{
|
||||
if (expect_hash)
|
||||
if (is_hash)
|
||||
auth_type_name = "double_sha1_hash";
|
||||
|
||||
prefix = "BY";
|
||||
|
@ -8,6 +8,15 @@
|
||||
namespace DB
|
||||
{
|
||||
|
||||
/** Represents authentication data in CREATE/ALTER USER query:
|
||||
* ... IDENTIFIED WITH sha256_password BY 'password'
|
||||
*
|
||||
* Can store password, hash and salt, LDAP server name, Kerberos Realm, or common names.
|
||||
* They are stored in children vector as ASTLiteral or ASTQueryParameter.
|
||||
* ASTAuthenticationData without a type represents authentication data with
|
||||
* the default password type that will be later inferred from the server parameters.
|
||||
*/
|
||||
|
||||
class ASTAuthenticationData : public IAST
|
||||
{
|
||||
public:
|
||||
@ -29,12 +38,8 @@ public:
|
||||
/// AuthenticationType::NO_PASSWORD is specified explicitly.
|
||||
std::optional<AuthenticationType> type;
|
||||
|
||||
/// TODO: Only expect_password and expect_hash are actually needed
|
||||
bool expect_password = false;
|
||||
bool expect_hash = false;
|
||||
bool expect_ldap_server_name = false;
|
||||
bool expect_kerberos_realm = false;
|
||||
bool expect_common_names = false;
|
||||
bool is_password = false;
|
||||
bool is_hash = false;
|
||||
|
||||
protected:
|
||||
void formatImpl(const FormatSettings & settings, FormatState &, FormatStateStacked) const override;
|
||||
|
@ -162,11 +162,8 @@ namespace
|
||||
auth_data = std::make_shared<ASTAuthenticationData>();
|
||||
|
||||
auth_data->type = type;
|
||||
auth_data->expect_password = expect_password;
|
||||
auth_data->expect_hash = expect_hash;
|
||||
auth_data->expect_ldap_server_name = expect_ldap_server_name;
|
||||
auth_data->expect_kerberos_realm = expect_kerberos_realm;
|
||||
auth_data->expect_common_names = expect_common_names;
|
||||
auth_data->is_password = expect_password;
|
||||
auth_data->is_hash = expect_hash;
|
||||
|
||||
if (value)
|
||||
auth_data->children.push_back(std::move(value));
|
||||
|
@ -1308,7 +1308,6 @@ void TCPHandler::sendHello()
|
||||
writeStringBinary(exception_message, *out);
|
||||
}
|
||||
}
|
||||
|
||||
if (client_tcp_protocol_version >= DBMS_MIN_REVISION_WITH_INTERSERVER_SECRET_V2)
|
||||
{
|
||||
chassert(!nonce.has_value());
|
||||
@ -1321,7 +1320,6 @@ void TCPHandler::sendHello()
|
||||
LOG_WARNING(LogFrequencyLimiter(log, 10),
|
||||
"Using deprecated interserver protocol because the client is too old. Consider upgrading all nodes in cluster.");
|
||||
}
|
||||
|
||||
out->next();
|
||||
}
|
||||
|
||||
|
@ -1,3 +1,3 @@
|
||||
<clickhouse>
|
||||
<default_password_type>double_sha1</default_password_type>
|
||||
<default_password_type>double_sha1_password</default_password_type>
|
||||
</clickhouse>
|
||||
|
Loading…
Reference in New Issue
Block a user