mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
Pre requiste MDEV-9245: add host to validate password interface
Hostname added to the interface. Cracklib plugin fixed according to the new interface.
This commit is contained in:
@@ -30,7 +30,7 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define MariaDB_PASSWORD_VALIDATION_INTERFACE_VERSION 0x0100
|
#define MariaDB_PASSWORD_VALIDATION_INTERFACE_VERSION 0x0101
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Password validation plugin descriptor
|
Password validation plugin descriptor
|
||||||
@@ -43,7 +43,8 @@ struct st_mariadb_password_validation
|
|||||||
and return 0 if the password has passed the validation.
|
and return 0 if the password has passed the validation.
|
||||||
*/
|
*/
|
||||||
int (*validate_password)(const MYSQL_CONST_LEX_STRING *username,
|
int (*validate_password)(const MYSQL_CONST_LEX_STRING *username,
|
||||||
const MYSQL_CONST_LEX_STRING *password);
|
const MYSQL_CONST_LEX_STRING *password,
|
||||||
|
const MYSQL_CONST_LEX_STRING *hostname);
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@@ -649,6 +649,7 @@ struct st_mariadb_password_validation
|
|||||||
{
|
{
|
||||||
int interface_version;
|
int interface_version;
|
||||||
int (*validate_password)(const MYSQL_CONST_LEX_STRING *username,
|
int (*validate_password)(const MYSQL_CONST_LEX_STRING *username,
|
||||||
const MYSQL_CONST_LEX_STRING *password);
|
const MYSQL_CONST_LEX_STRING *password,
|
||||||
|
const MYSQL_CONST_LEX_STRING *hostname);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@@ -4,7 +4,7 @@ PLUGIN_NAME cracklib_password_check
|
|||||||
PLUGIN_VERSION 1.0
|
PLUGIN_VERSION 1.0
|
||||||
PLUGIN_STATUS ACTIVE
|
PLUGIN_STATUS ACTIVE
|
||||||
PLUGIN_TYPE PASSWORD VALIDATION
|
PLUGIN_TYPE PASSWORD VALIDATION
|
||||||
PLUGIN_TYPE_VERSION 1.0
|
PLUGIN_TYPE_VERSION 1.1
|
||||||
PLUGIN_LIBRARY cracklib_password_check.so
|
PLUGIN_LIBRARY cracklib_password_check.so
|
||||||
PLUGIN_LIBRARY_VERSION 1.15
|
PLUGIN_LIBRARY_VERSION 1.15
|
||||||
PLUGIN_AUTHOR Sergei Golubchik
|
PLUGIN_AUTHOR Sergei Golubchik
|
||||||
@@ -37,6 +37,18 @@ show warnings;
|
|||||||
Level Code Message
|
Level Code Message
|
||||||
Warning 1819 cracklib: it is based on a dictionary word
|
Warning 1819 cracklib: it is based on a dictionary word
|
||||||
Error 1819 Your password does not satisfy the current policy requirements
|
Error 1819 Your password does not satisfy the current policy requirements
|
||||||
|
grant select on *.* to foocar@localhost identified by 'localhost';
|
||||||
|
ERROR HY000: Your password does not satisfy the current policy requirements
|
||||||
|
show warnings;
|
||||||
|
Level Code Message
|
||||||
|
Warning 1819 cracklib: it is based upon your password entry
|
||||||
|
Error 1819 Your password does not satisfy the current policy requirements
|
||||||
|
grant select on *.* to foocar@localhost identified by 'foocar@localhost';
|
||||||
|
ERROR HY000: Your password does not satisfy the current policy requirements
|
||||||
|
show warnings;
|
||||||
|
Level Code Message
|
||||||
|
Warning 1819 cracklib: it is derived from your password entry
|
||||||
|
Error 1819 Your password does not satisfy the current policy requirements
|
||||||
grant select on *.* to foobar identified by 'q$%^&*rty';
|
grant select on *.* to foobar identified by 'q$%^&*rty';
|
||||||
drop user foobar;
|
drop user foobar;
|
||||||
#
|
#
|
||||||
|
@@ -4,7 +4,7 @@ PLUGIN_NAME simple_password_check
|
|||||||
PLUGIN_VERSION 1.0
|
PLUGIN_VERSION 1.0
|
||||||
PLUGIN_STATUS ACTIVE
|
PLUGIN_STATUS ACTIVE
|
||||||
PLUGIN_TYPE PASSWORD VALIDATION
|
PLUGIN_TYPE PASSWORD VALIDATION
|
||||||
PLUGIN_TYPE_VERSION 1.0
|
PLUGIN_TYPE_VERSION 1.1
|
||||||
PLUGIN_LIBRARY simple_password_check.so
|
PLUGIN_LIBRARY simple_password_check.so
|
||||||
PLUGIN_LIBRARY_VERSION 1.15
|
PLUGIN_LIBRARY_VERSION 1.15
|
||||||
PLUGIN_AUTHOR Sergei Golubchik
|
PLUGIN_AUTHOR Sergei Golubchik
|
||||||
|
@@ -27,6 +27,14 @@ show warnings;
|
|||||||
grant select on *.* to foobar identified by 'qwerty';
|
grant select on *.* to foobar identified by 'qwerty';
|
||||||
show warnings;
|
show warnings;
|
||||||
|
|
||||||
|
--error ER_NOT_VALID_PASSWORD
|
||||||
|
grant select on *.* to foocar@localhost identified by 'localhost';
|
||||||
|
show warnings;
|
||||||
|
|
||||||
|
--error ER_NOT_VALID_PASSWORD
|
||||||
|
grant select on *.* to foocar@localhost identified by 'foocar@localhost';
|
||||||
|
show warnings;
|
||||||
|
|
||||||
grant select on *.* to foobar identified by 'q$%^&*rty';
|
grant select on *.* to foobar identified by 'q$%^&*rty';
|
||||||
drop user foobar;
|
drop user foobar;
|
||||||
|
|
||||||
|
@@ -22,18 +22,21 @@
|
|||||||
static char *dictionary;
|
static char *dictionary;
|
||||||
|
|
||||||
static int crackme(const MYSQL_CONST_LEX_STRING *username,
|
static int crackme(const MYSQL_CONST_LEX_STRING *username,
|
||||||
const MYSQL_CONST_LEX_STRING *password)
|
const MYSQL_CONST_LEX_STRING *password,
|
||||||
|
const MYSQL_CONST_LEX_STRING *hostname)
|
||||||
{
|
{
|
||||||
char *user= alloca(username->length + 1);
|
char *user= alloca(username->length + 1);
|
||||||
char *host;
|
char *full_name= alloca(hostname->length + username->length + 2);
|
||||||
const char *res;
|
const char *res;
|
||||||
|
|
||||||
memcpy(user, username->str, username->length);
|
memcpy(user, username->str, username->length);
|
||||||
user[username->length]= 0;
|
user[username->length]= 0;
|
||||||
if ((host= strchr(user, '@')))
|
memcpy(full_name, username->str, username->length);
|
||||||
*host++= 0;
|
full_name[username->length]= '@';
|
||||||
|
memcpy(full_name + username->length + 1, hostname->str, hostname->length);
|
||||||
|
full_name[hostname->length+ username->length + 1]= 0;
|
||||||
|
|
||||||
if ((res= FascistCheckUser(password->str, dictionary, user, host)))
|
if ((res= FascistCheckUser(password->str, dictionary, user, full_name)))
|
||||||
{
|
{
|
||||||
my_printf_error(ER_NOT_VALID_PASSWORD, "cracklib: %s",
|
my_printf_error(ER_NOT_VALID_PASSWORD, "cracklib: %s",
|
||||||
ME_WARNING, res);
|
ME_WARNING, res);
|
||||||
|
@@ -23,7 +23,9 @@
|
|||||||
static unsigned min_length, min_digits, min_letters, min_others;
|
static unsigned min_length, min_digits, min_letters, min_others;
|
||||||
|
|
||||||
static int validate(const MYSQL_CONST_LEX_STRING *username,
|
static int validate(const MYSQL_CONST_LEX_STRING *username,
|
||||||
const MYSQL_CONST_LEX_STRING *password)
|
const MYSQL_CONST_LEX_STRING *password,
|
||||||
|
const MYSQL_CONST_LEX_STRING *hostname
|
||||||
|
__attribute__((unused)))
|
||||||
{
|
{
|
||||||
unsigned digits=0 , uppers=0 , lowers=0, others=0, length= (unsigned)password->length;
|
unsigned digits=0 , uppers=0 , lowers=0, others=0, length= (unsigned)password->length;
|
||||||
const char *ptr= password->str, *end= ptr + length;
|
const char *ptr= password->str, *end= ptr + length;
|
||||||
|
@@ -2168,24 +2168,26 @@ static bool has_validation_plugins()
|
|||||||
MariaDB_PASSWORD_VALIDATION_PLUGIN, NULL);
|
MariaDB_PASSWORD_VALIDATION_PLUGIN, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct validation_data { const LEX_CSTRING *user, *password; };
|
struct validation_data { const LEX_CSTRING *user, *password, *host; };
|
||||||
|
|
||||||
static my_bool do_validate(THD *, plugin_ref plugin, void *arg)
|
static my_bool do_validate(THD *, plugin_ref plugin, void *arg)
|
||||||
{
|
{
|
||||||
struct validation_data *data= (struct validation_data *)arg;
|
struct validation_data *data= (struct validation_data *)arg;
|
||||||
struct st_mariadb_password_validation *handler=
|
struct st_mariadb_password_validation *handler=
|
||||||
(st_mariadb_password_validation *)plugin_decl(plugin)->info;
|
(st_mariadb_password_validation *)plugin_decl(plugin)->info;
|
||||||
return handler->validate_password(data->user, data->password);
|
return handler->validate_password(data->user, data->password, data->host);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static bool validate_password(THD *thd, const LEX_CSTRING &user,
|
static bool validate_password(THD *thd, const LEX_CSTRING &user,
|
||||||
|
const LEX_CSTRING &host,
|
||||||
const LEX_CSTRING &pwtext, bool has_hash)
|
const LEX_CSTRING &pwtext, bool has_hash)
|
||||||
{
|
{
|
||||||
if (pwtext.length || !has_hash)
|
if (pwtext.length || !has_hash)
|
||||||
{
|
{
|
||||||
struct validation_data data= { &user,
|
struct validation_data data= { &user,
|
||||||
pwtext.str ? &pwtext : &empty_clex_str };
|
pwtext.str ? &pwtext : &empty_clex_str,
|
||||||
|
&host };
|
||||||
if (plugin_foreach(NULL, do_validate,
|
if (plugin_foreach(NULL, do_validate,
|
||||||
MariaDB_PASSWORD_VALIDATION_PLUGIN, &data))
|
MariaDB_PASSWORD_VALIDATION_PLUGIN, &data))
|
||||||
{
|
{
|
||||||
@@ -2239,6 +2241,7 @@ static int set_user_salt(ACL_USER::AUTH *auth, plugin_ref plugin)
|
|||||||
not loaded, if the auth_string is invalid, if the password is not applicable
|
not loaded, if the auth_string is invalid, if the password is not applicable
|
||||||
*/
|
*/
|
||||||
static int set_user_auth(THD *thd, const LEX_CSTRING &user,
|
static int set_user_auth(THD *thd, const LEX_CSTRING &user,
|
||||||
|
const LEX_CSTRING &host,
|
||||||
ACL_USER::AUTH *auth, const LEX_CSTRING &pwtext)
|
ACL_USER::AUTH *auth, const LEX_CSTRING &pwtext)
|
||||||
{
|
{
|
||||||
const char *plugin_name= auth->plugin.str;
|
const char *plugin_name= auth->plugin.str;
|
||||||
@@ -2264,7 +2267,7 @@ static int set_user_auth(THD *thd, const LEX_CSTRING &user,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (info->hash_password &&
|
if (info->hash_password &&
|
||||||
validate_password(thd, user, pwtext, auth->auth_string.length))
|
validate_password(thd, user, host, pwtext, auth->auth_string.length))
|
||||||
{
|
{
|
||||||
res= ER_NOT_VALID_PASSWORD;
|
res= ER_NOT_VALID_PASSWORD;
|
||||||
goto end;
|
goto end;
|
||||||
@@ -3373,7 +3376,10 @@ static int acl_user_update(THD *thd, ACL_USER *acl_user, uint nauth,
|
|||||||
acl_user->auth[i].auth_string= safe_lexcstrdup_root(&acl_memroot, auth->auth_str);
|
acl_user->auth[i].auth_string= safe_lexcstrdup_root(&acl_memroot, auth->auth_str);
|
||||||
if (fix_user_plugin_ptr(acl_user->auth + i))
|
if (fix_user_plugin_ptr(acl_user->auth + i))
|
||||||
acl_user->auth[i].plugin= safe_lexcstrdup_root(&acl_memroot, auth->plugin);
|
acl_user->auth[i].plugin= safe_lexcstrdup_root(&acl_memroot, auth->plugin);
|
||||||
if (set_user_auth(thd, acl_user->user, acl_user->auth + i, auth->pwtext))
|
LEX_CSTRING host= { acl_user->host.hostname ,
|
||||||
|
acl_user->hostname_length};
|
||||||
|
if (set_user_auth(thd, acl_user->user, host,
|
||||||
|
acl_user->auth + i, auth->pwtext))
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3976,7 +3982,8 @@ bool change_password(THD *thd, LEX_USER *user)
|
|||||||
{
|
{
|
||||||
auth= acl_user->auth[i];
|
auth= acl_user->auth[i];
|
||||||
auth.auth_string= safe_lexcstrdup_root(&acl_memroot, user->auth->auth_str);
|
auth.auth_string= safe_lexcstrdup_root(&acl_memroot, user->auth->auth_str);
|
||||||
int r= set_user_auth(thd, user->user, &auth, user->auth->pwtext);
|
int r= set_user_auth(thd, user->user, user->host,
|
||||||
|
&auth, user->auth->pwtext);
|
||||||
if (r == ER_SET_PASSWORD_AUTH_PLUGIN)
|
if (r == ER_SET_PASSWORD_AUTH_PLUGIN)
|
||||||
password_plugin= auth.plugin.str;
|
password_plugin= auth.plugin.str;
|
||||||
else if (r)
|
else if (r)
|
||||||
|
Reference in New Issue
Block a user