Commit c3710738 authored by Sergei Golubchik's avatar Sergei Golubchik

cleanup: LEX_USER::pwtext and LEX_USER::pwhash

Was:
* LEX_USER::password was storing sometimes
  plaintext password and sometimes password hash
* LEX_USER::auth was storing sometimes password hash and
  sometimes plugin authentication string

Now:
* LEX_USER::pwtext stores the password in plain-text
* LEX_USER::pwhash stores the password hash
* LEX_USER::auth stores the plugin authentication string
parent 1fea7e78
...@@ -988,12 +988,13 @@ static bool fix_user_plugin_ptr(ACL_USER *user) ...@@ -988,12 +988,13 @@ static bool fix_user_plugin_ptr(ACL_USER *user)
to match the next case (that is, user->plugin is cleared). to match the next case (that is, user->plugin is cleared).
- if user->plugin is NOT specified, built-in auth is assumed, that is - if user->plugin is NOT specified, built-in auth is assumed, that is
mysql_native_password or mysql_old_password. In that case, mysql_native_password or mysql_old_password. In that case,
user->auth is the password hash. And user->password is the original user->pwhash is the password hash. And user->pwtext is the original
plain-text password. Either one can be set or even both. plain-text password. Either one can be set or both.
Upon exiting this function: Upon exiting this function:
- user->password is the password hash, as the mysql.user.password column - user->pwtext is left untouched
- user->pwhash is the password hash, as the mysql.user.password column
- user->plugin is the plugin name, as the mysql.user.plugin column - user->plugin is the plugin name, as the mysql.user.plugin column
- user->auth is the plugin auth data, as the mysql.user.authentication_string column - user->auth is the plugin auth data, as the mysql.user.authentication_string column
*/ */
...@@ -1001,6 +1002,9 @@ static bool fix_lex_user(THD *thd, LEX_USER *user) ...@@ -1001,6 +1002,9 @@ static bool fix_lex_user(THD *thd, LEX_USER *user)
{ {
size_t check_length; size_t check_length;
DBUG_ASSERT(user->plugin.length || !user->auth.length);
DBUG_ASSERT(!(user->plugin.length && (user->pwtext.length || user->pwhash.length)));
if (my_strcasecmp(system_charset_info, user->plugin.str, if (my_strcasecmp(system_charset_info, user->plugin.str,
native_password_plugin_name.str) == 0) native_password_plugin_name.str) == 0)
check_length= SCRAMBLED_PASSWORD_CHAR_LENGTH; check_length= SCRAMBLED_PASSWORD_CHAR_LENGTH;
...@@ -1011,21 +1015,28 @@ static bool fix_lex_user(THD *thd, LEX_USER *user) ...@@ -1011,21 +1015,28 @@ static bool fix_lex_user(THD *thd, LEX_USER *user)
else else
if (user->plugin.length) if (user->plugin.length)
return false; // nothing else to do return false; // nothing else to do
else else if (thd->variables.old_passwords == 1 ||
if (user->auth.length == SCRAMBLED_PASSWORD_CHAR_LENGTH_323) user->pwhash.length == SCRAMBLED_PASSWORD_CHAR_LENGTH_323)
check_length= 0; // length is valid, no need to re-check check_length= SCRAMBLED_PASSWORD_CHAR_LENGTH_323;
else else
check_length= SCRAMBLED_PASSWORD_CHAR_LENGTH; check_length= SCRAMBLED_PASSWORD_CHAR_LENGTH;
if (check_length && user->auth.length && user->auth.length != check_length) if (user->plugin.length)
{
user->pwhash= user->auth;
user->plugin= empty_lex_str;
user->auth= empty_lex_str;
}
if (user->pwhash.length && user->pwhash.length != check_length)
{ {
my_error(ER_PASSWD_LENGTH, MYF(0), check_length); my_error(ER_PASSWD_LENGTH, MYF(0), check_length);
return true; return true;
} }
if (user->password.length || !user->auth.length) if (user->pwtext.length || !user->pwhash.length)
{ {
if (validate_password(&user->user, &user->password)) if (validate_password(&user->user, &user->pwtext))
{ {
my_error(ER_NOT_VALID_PASSWORD, MYF(0)); my_error(ER_NOT_VALID_PASSWORD, MYF(0));
return true; return true;
...@@ -1040,7 +1051,7 @@ static bool fix_lex_user(THD *thd, LEX_USER *user) ...@@ -1040,7 +1051,7 @@ static bool fix_lex_user(THD *thd, LEX_USER *user)
} }
} }
if (user->password.length && !user->auth.length) if (user->pwtext.length && !user->pwhash.length)
{ {
size_t scramble_length; size_t scramble_length;
void (*make_scramble)(char *, const char *, size_t); void (*make_scramble)(char *, const char *, size_t);
...@@ -1059,14 +1070,11 @@ static bool fix_lex_user(THD *thd, LEX_USER *user) ...@@ -1059,14 +1070,11 @@ static bool fix_lex_user(THD *thd, LEX_USER *user)
char *buff= (char *) thd->alloc(scramble_length + 1); char *buff= (char *) thd->alloc(scramble_length + 1);
if (buff == NULL) if (buff == NULL)
return true; return true;
make_scramble(buff, user->password.str, user->password.length); make_scramble(buff, user->pwtext.str, user->pwtext.length);
user->auth.str= buff; user->pwhash.str= buff;
user->auth.length= scramble_length; user->pwhash.length= scramble_length;
} }
user->password= user->auth.length ? user->auth : null_lex_str;
user->plugin= empty_lex_str;
user->auth= empty_lex_str;
return false; return false;
} }
...@@ -2767,7 +2775,7 @@ bool change_password(THD *thd, LEX_USER *user) ...@@ -2767,7 +2775,7 @@ bool change_password(THD *thd, LEX_USER *user)
const CSET_STRING query_save __attribute__((unused)) = thd->query_string; const CSET_STRING query_save __attribute__((unused)) = thd->query_string;
DBUG_ENTER("change_password"); DBUG_ENTER("change_password");
DBUG_PRINT("enter",("host: '%s' user: '%s' new_password: '%s'", DBUG_PRINT("enter",("host: '%s' user: '%s' new_password: '%s'",
user->host.str, user->user.str, user->password.str)); user->host.str, user->user.str, user->pwhash.str));
DBUG_ASSERT(user->host.str != 0); // Ensured by parent DBUG_ASSERT(user->host.str != 0); // Ensured by parent
/* /*
...@@ -2784,7 +2792,7 @@ bool change_password(THD *thd, LEX_USER *user) ...@@ -2784,7 +2792,7 @@ bool change_password(THD *thd, LEX_USER *user)
{ {
query_length= sprintf(buff, "SET PASSWORD FOR '%-.120s'@'%-.120s'='%-.120s'", query_length= sprintf(buff, "SET PASSWORD FOR '%-.120s'@'%-.120s'='%-.120s'",
safe_str(user->user.str), safe_str(user->host.str), safe_str(user->user.str), safe_str(user->host.str),
safe_str(user->password.str)); safe_str(user->pwhash.str));
} }
if (WSREP(thd) && !IF_WSREP(thd->wsrep_applier, 0)) if (WSREP(thd) && !IF_WSREP(thd->wsrep_applier, 0))
...@@ -2812,10 +2820,10 @@ bool change_password(THD *thd, LEX_USER *user) ...@@ -2812,10 +2820,10 @@ bool change_password(THD *thd, LEX_USER *user)
if (acl_user->plugin.str == native_password_plugin_name.str || if (acl_user->plugin.str == native_password_plugin_name.str ||
acl_user->plugin.str == old_password_plugin_name.str) acl_user->plugin.str == old_password_plugin_name.str)
{ {
acl_user->auth_string.str= strmake_root(&acl_memroot, user->password.str, user->password.length); acl_user->auth_string.str= strmake_root(&acl_memroot, user->pwhash.str, user->pwhash.length);
acl_user->auth_string.length= user->password.length; acl_user->auth_string.length= user->pwhash.length;
set_user_salt(acl_user, user->password.str, user->password.length); set_user_salt(acl_user, user->pwhash.str, user->pwhash.length);
set_user_plugin(acl_user, user->password.length); set_user_plugin(acl_user, user->pwhash.length);
} }
else else
push_warning(thd, Sql_condition::WARN_LEVEL_NOTE, push_warning(thd, Sql_condition::WARN_LEVEL_NOTE,
...@@ -2825,7 +2833,7 @@ bool change_password(THD *thd, LEX_USER *user) ...@@ -2825,7 +2833,7 @@ bool change_password(THD *thd, LEX_USER *user)
if (update_user_table(thd, tables[USER_TABLE].table, if (update_user_table(thd, tables[USER_TABLE].table,
safe_str(acl_user->host.hostname), safe_str(acl_user->host.hostname),
safe_str(acl_user->user.str), safe_str(acl_user->user.str),
user->password.str, user->password.length)) user->pwhash.str, user->pwhash.length))
{ {
mysql_mutex_unlock(&acl_cache->lock); /* purecov: deadcode */ mysql_mutex_unlock(&acl_cache->lock); /* purecov: deadcode */
goto end; goto end;
...@@ -3366,17 +3374,18 @@ static int replace_user_table(THD *thd, TABLE *table, LEX_USER &combo, ...@@ -3366,17 +3374,18 @@ static int replace_user_table(THD *thd, TABLE *table, LEX_USER &combo,
mysql_mutex_assert_owner(&acl_cache->lock); mysql_mutex_assert_owner(&acl_cache->lock);
if (combo.password.str && combo.password.str[0]) if (combo.pwhash.str && combo.pwhash.str[0])
{ {
if (combo.password.length != SCRAMBLED_PASSWORD_CHAR_LENGTH && if (combo.pwhash.length != SCRAMBLED_PASSWORD_CHAR_LENGTH &&
combo.password.length != SCRAMBLED_PASSWORD_CHAR_LENGTH_323) combo.pwhash.length != SCRAMBLED_PASSWORD_CHAR_LENGTH_323)
{ {
DBUG_ASSERT(0);
my_error(ER_PASSWD_LENGTH, MYF(0), SCRAMBLED_PASSWORD_CHAR_LENGTH); my_error(ER_PASSWD_LENGTH, MYF(0), SCRAMBLED_PASSWORD_CHAR_LENGTH);
DBUG_RETURN(-1); DBUG_RETURN(-1);
} }
} }
else else
combo.password= empty_lex_str; combo.pwhash= empty_lex_str;
/* if the user table is not up to date, we can't handle role updates */ /* if the user table is not up to date, we can't handle role updates */
if (table->s->fields <= ROLE_ASSIGN_COLUMN_IDX && handle_as_role) if (table->s->fields <= ROLE_ASSIGN_COLUMN_IDX && handle_as_role)
...@@ -3418,7 +3427,7 @@ static int replace_user_table(THD *thd, TABLE *table, LEX_USER &combo, ...@@ -3418,7 +3427,7 @@ static int replace_user_table(THD *thd, TABLE *table, LEX_USER &combo,
see also test_if_create_new_users() see also test_if_create_new_users()
*/ */
else if (!combo.password.length && !combo.plugin.length && no_auto_create) else if (!combo.pwhash.length && !combo.plugin.length && no_auto_create)
{ {
my_error(ER_PASSWORD_NO_MATCH, MYF(0)); my_error(ER_PASSWORD_NO_MATCH, MYF(0));
goto end; goto end;
...@@ -3465,8 +3474,8 @@ static int replace_user_table(THD *thd, TABLE *table, LEX_USER &combo, ...@@ -3465,8 +3474,8 @@ static int replace_user_table(THD *thd, TABLE *table, LEX_USER &combo,
} }
rights= get_access(table, 3, &next_field); rights= get_access(table, 3, &next_field);
DBUG_PRINT("info",("table fields: %d",table->s->fields)); DBUG_PRINT("info",("table fields: %d",table->s->fields));
if (combo.password.str[0]) if (combo.pwhash.str[0])
table->field[2]->store(combo.password.str, combo.password.length, system_charset_info); table->field[2]->store(combo.pwhash.str, combo.pwhash.length, system_charset_info);
if (table->s->fields >= 31) /* From 4.0.0 we have more fields */ if (table->s->fields >= 31) /* From 4.0.0 we have more fields */
{ {
/* We write down SSL related ACL stuff */ /* We write down SSL related ACL stuff */
...@@ -3529,14 +3538,14 @@ static int replace_user_table(THD *thd, TABLE *table, LEX_USER &combo, ...@@ -3529,14 +3538,14 @@ static int replace_user_table(THD *thd, TABLE *table, LEX_USER &combo,
table->field[next_field + 1]->set_notnull(); table->field[next_field + 1]->set_notnull();
if (combo.plugin.str[0]) if (combo.plugin.str[0])
{ {
DBUG_ASSERT(combo.password.str[0] == 0); DBUG_ASSERT(combo.pwhash.str[0] == 0);
table->field[2]->reset(); table->field[2]->reset();
table->field[next_field]->store(combo.plugin.str, combo.plugin.length, table->field[next_field]->store(combo.plugin.str, combo.plugin.length,
system_charset_info); system_charset_info);
table->field[next_field + 1]->store(combo.auth.str, combo.auth.length, table->field[next_field + 1]->store(combo.auth.str, combo.auth.length,
system_charset_info); system_charset_info);
} }
if (combo.password.str[0]) if (combo.pwhash.str[0])
{ {
DBUG_ASSERT(combo.plugin.str[0] == 0); DBUG_ASSERT(combo.plugin.str[0] == 0);
table->field[next_field]->reset(); table->field[next_field]->reset();
...@@ -3605,7 +3614,7 @@ end: ...@@ -3605,7 +3614,7 @@ end:
acl_update_role(combo.user.str, rights); acl_update_role(combo.user.str, rights);
else else
acl_update_user(combo.user.str, combo.host.str, acl_update_user(combo.user.str, combo.host.str,
combo.password.str, combo.password.length, combo.pwhash.str, combo.pwhash.length,
lex->ssl_type, lex->ssl_type,
lex->ssl_cipher, lex->ssl_cipher,
lex->x509_issuer, lex->x509_issuer,
...@@ -3621,7 +3630,7 @@ end: ...@@ -3621,7 +3630,7 @@ end:
acl_insert_role(combo.user.str, rights); acl_insert_role(combo.user.str, rights);
else else
acl_insert_user(combo.user.str, combo.host.str, acl_insert_user(combo.user.str, combo.host.str,
combo.password.str, combo.password.length, combo.pwhash.str, combo.pwhash.length,
lex->ssl_type, lex->ssl_type,
lex->ssl_cipher, lex->ssl_cipher,
lex->x509_issuer, lex->x509_issuer,
...@@ -5679,7 +5688,7 @@ static bool merge_one_role_privileges(ACL_ROLE *grantee) ...@@ -5679,7 +5688,7 @@ static bool merge_one_role_privileges(ACL_ROLE *grantee)
static bool has_auth(LEX_USER *user, LEX *lex) static bool has_auth(LEX_USER *user, LEX *lex)
{ {
return user->password.str || user->plugin.length || user->auth.length || return user->pwtext.length || user->pwhash.length || user->plugin.length || user->auth.length ||
lex->ssl_type != SSL_TYPE_NOT_SPECIFIED || lex->ssl_cipher || lex->ssl_type != SSL_TYPE_NOT_SPECIFIED || lex->ssl_cipher ||
lex->x509_issuer || lex->x509_subject || lex->x509_issuer || lex->x509_subject ||
lex->mqh.specified_limits; lex->mqh.specified_limits;
...@@ -5690,7 +5699,8 @@ static bool fix_and_copy_user(LEX_USER *to, LEX_USER *from, THD *thd) ...@@ -5690,7 +5699,8 @@ static bool fix_and_copy_user(LEX_USER *to, LEX_USER *from, THD *thd)
if (to != from) if (to != from)
{ {
/* preserve authentication information, if LEX_USER was reallocated */ /* preserve authentication information, if LEX_USER was reallocated */
to->password= from->password; to->pwtext= from->pwtext;
to->pwhash= from->pwhash;
to->plugin= from->plugin; to->plugin= from->plugin;
to->auth= from->auth; to->auth= from->auth;
} }
...@@ -10160,8 +10170,6 @@ bool sp_grant_privileges(THD *thd, const char *sp_db, const char *sp_name, ...@@ -10160,8 +10170,6 @@ bool sp_grant_privileges(THD *thd, const char *sp_db, const char *sp_name,
if(au) if(au)
{ {
if (au->plugin.str != native_password_plugin_name.str &&
au->plugin.str != old_password_plugin_name.str)
combo->plugin= au->plugin; combo->plugin= au->plugin;
combo->auth= au->auth_string; combo->auth= au->auth_string;
} }
......
...@@ -15067,14 +15067,14 @@ opt_for_user: ...@@ -15067,14 +15067,14 @@ opt_for_user:
; ;
text_or_password: text_or_password:
TEXT_STRING { Lex->definer->auth= $1;} TEXT_STRING { Lex->definer->pwhash= $1;}
| PASSWORD_SYM '(' TEXT_STRING ')' { Lex->definer->password= $3; } | PASSWORD_SYM '(' TEXT_STRING ')' { Lex->definer->pwtext= $3; }
| OLD_PASSWORD_SYM '(' TEXT_STRING ')' | OLD_PASSWORD_SYM '(' TEXT_STRING ')'
{ {
Lex->definer->password= $3; Lex->definer->pwtext= $3;
Lex->definer->auth.str= Item_func_password::alloc(thd, Lex->definer->pwhash.str= Item_func_password::alloc(thd,
$3.str, $3.length, Item_func_password::OLD); $3.str, $3.length, Item_func_password::OLD);
Lex->definer->auth.length= SCRAMBLED_PASSWORD_CHAR_LENGTH_323; Lex->definer->pwhash.length= SCRAMBLED_PASSWORD_CHAR_LENGTH_323;
} }
; ;
...@@ -15648,14 +15648,15 @@ using_or_as: USING | AS ; ...@@ -15648,14 +15648,15 @@ using_or_as: USING | AS ;
grant_user: grant_user:
user IDENTIFIED_SYM BY TEXT_STRING user IDENTIFIED_SYM BY TEXT_STRING
{ {
$$=$1; $1->password=$4; $$= $1;
$1->pwtext= $4;
if (Lex->sql_command == SQLCOM_REVOKE) if (Lex->sql_command == SQLCOM_REVOKE)
MYSQL_YYABORT; MYSQL_YYABORT;
} }
| user IDENTIFIED_SYM BY PASSWORD_SYM TEXT_STRING | user IDENTIFIED_SYM BY PASSWORD_SYM TEXT_STRING
{ {
$$= $1; $$= $1;
$1->auth= $5; $1->pwhash= $5;
} }
| user IDENTIFIED_SYM via_or_with ident_or_text | user IDENTIFIED_SYM via_or_with ident_or_text
{ {
......
...@@ -202,7 +202,8 @@ extern const char *show_comp_option_name[]; ...@@ -202,7 +202,8 @@ extern const char *show_comp_option_name[];
typedef int *(*update_var)(THD *, struct st_mysql_show_var *); typedef int *(*update_var)(THD *, struct st_mysql_show_var *);
typedef struct st_lex_user { typedef struct st_lex_user {
LEX_STRING user, host, password, plugin, auth; LEX_STRING user, host, plugin, auth;
LEX_STRING pwtext, pwhash;
bool is_role() { return user.str[0] && !host.str[0]; } bool is_role() { return user.str[0] && !host.str[0]; }
void set_lex_string(LEX_STRING *l, char *buf) void set_lex_string(LEX_STRING *l, char *buf)
{ {
...@@ -213,8 +214,8 @@ typedef struct st_lex_user { ...@@ -213,8 +214,8 @@ typedef struct st_lex_user {
} }
void reset_auth() void reset_auth()
{ {
password.length= plugin.length= auth.length= 0; pwtext.length= pwhash.length= plugin.length= auth.length= 0;
password.str= 0; pwtext.str= pwhash.str= 0;
plugin.str= auth.str= const_cast<char*>(""); plugin.str= auth.str= const_cast<char*>("");
} }
} LEX_USER; } LEX_USER;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment