@@ -349,6 +349,7 @@ ulong role_global_merges= 0, role_db_merges= 0, role_table_merges= 0,
349
349
#endif
350
350
351
351
#ifndef NO_EMBEDDED_ACCESS_CHECKS
352
+ static bool fix_and_copy_user (LEX_USER *to, LEX_USER *from, THD *thd);
352
353
static void update_hostname (acl_host_and_ip *host, const char *hostname);
353
354
static ulong get_sort (uint count,...);
354
355
static bool show_proxy_grants (THD *, const char *, const char *,
@@ -965,10 +966,25 @@ static bool fix_user_plugin_ptr(ACL_USER *user)
965
966
966
967
967
968
/*
968
- transform equivalent LEX_USER values to one:
969
- username IDENTIFIED BY PASSWORD xxx
970
- username IDENTIFIED VIA mysql_native_password USING xxx
971
- etc
969
+ Validates the password, calculates password hash, transforms
970
+ equivalent LEX_USER representations.
971
+
972
+ Upon entering this function:
973
+
974
+ - if user->plugin is specified, user->auth is the plugin auth data.
975
+ - if user->plugin is mysql_native_password or mysql_old_password,
976
+ user->auth if the password hash, and LEX_USER is transformed
977
+ to match the next case (that is, user->plugin is cleared).
978
+ - if user->plugin is NOT specified, built-in auth is assumed, that is
979
+ mysql_native_password or mysql_old_password. In that case,
980
+ user->auth is the password hash. And user->password is the original
981
+ plain-text password. Either one can be set or even both.
982
+
983
+ Upon exiting this function:
984
+
985
+ - user->password is the password hash, as the mysql.user.password column
986
+ - user->plugin is the plugin name, as the mysql.user.plugin column
987
+ - user->auth is the plugin auth data, as the mysql.user.authentication_string column
972
988
*/
973
989
static bool fix_lex_user (THD *thd, LEX_USER *user)
974
990
{
@@ -1005,7 +1021,7 @@ static bool fix_lex_user(THD *thd, LEX_USER *user)
1005
1021
}
1006
1022
}
1007
1023
1008
- if (user->password .length )
1024
+ if (user->password .length && !user-> auth . length )
1009
1025
{
1010
1026
size_t scramble_length;
1011
1027
void (*make_scramble)(char *, const char *, size_t );
@@ -2691,72 +2707,57 @@ static int check_alter_user(THD *thd, const char *host, const char *user)
2691
2707
Check if the user is allowed to change password
2692
2708
2693
2709
@param thd THD
2694
- @param host Hostname for the user
2695
- @param user User name
2696
- @param new_password New password
2697
- @param new_password_len The length of the new password
2698
-
2699
- new_password cannot be NULL
2710
+ @param user User, hostname, new password or password hash
2700
2711
2701
2712
@return Error status
2702
2713
@retval 0 OK
2703
2714
@retval 1 ERROR; In this case the error is sent to the client.
2704
2715
*/
2705
2716
2706
- int check_change_password (THD *thd, const char *host, const char *user,
2707
- char *new_password, uint new_password_len)
2717
+ bool check_change_password (THD *thd, LEX_USER *user)
2708
2718
{
2709
- if (check_alter_user (thd, host, user))
2710
- return 1 ;
2719
+ LEX_USER *real_user= get_current_user (thd, user);
2711
2720
2712
- size_t len= strlen (new_password);
2713
- if (len && len != SCRAMBLED_PASSWORD_CHAR_LENGTH &&
2714
- len != SCRAMBLED_PASSWORD_CHAR_LENGTH_323)
2715
- {
2716
- my_error (ER_PASSWD_LENGTH, MYF (0 ), SCRAMBLED_PASSWORD_CHAR_LENGTH);
2717
- return 1 ;
2718
- }
2719
- return 0 ;
2721
+ if (fix_and_copy_user (real_user, user, thd))
2722
+ return true ;
2723
+
2724
+ *user= *real_user;
2725
+
2726
+ return check_alter_user (thd, user->host .str , user->user .str );
2720
2727
}
2721
2728
2722
2729
2723
2730
/* *
2724
2731
Change a password for a user.
2725
2732
2726
2733
@param thd THD
2727
- @param host Hostname
2728
- @param user User name
2729
- @param new_password New password hash for host@user
2734
+ @param user User, hostname, new password hash
2730
2735
2731
2736
@return Error code
2732
2737
@retval 0 ok
2733
2738
@retval 1 ERROR; In this case the error is sent to the client.
2734
2739
*/
2735
- bool change_password (THD *thd, const char *host, const char *user,
2736
- char *new_password)
2740
+ bool change_password (THD *thd, LEX_USER *user)
2737
2741
{
2738
2742
TABLE_LIST tables[TABLES_MAX];
2739
2743
/* Buffer should be extended when password length is extended. */
2740
2744
char buff[512 ];
2741
2745
ulong query_length= 0 ;
2742
2746
enum_binlog_format save_binlog_format;
2743
- uint new_password_len= (uint) strlen (new_password);
2744
2747
int result=0 ;
2745
2748
const CSET_STRING query_save __attribute__ ((unused)) = thd->query_string ;
2746
2749
2747
2750
DBUG_ENTER (" change_password" );
2748
2751
DBUG_PRINT (" enter" ,(" host: '%s' user: '%s' new_password: '%s'" ,
2749
- host,user,new_password));
2750
- DBUG_ASSERT (host != 0 ); // Ensured by parent
2751
-
2752
- if (check_change_password (thd, host, user, new_password, new_password_len))
2753
- DBUG_RETURN (1 );
2752
+ user->host .str , user->user .str , user->password .str ));
2753
+ DBUG_ASSERT (user->host .str != 0 ); // Ensured by parent
2754
2754
2755
2755
if (mysql_bin_log.is_open () ||
2756
2756
(WSREP (thd) && !IF_WSREP (thd->wsrep_applier , 0 )))
2757
2757
{
2758
2758
query_length= sprintf (buff, " SET PASSWORD FOR '%-.120s'@'%-.120s'='%-.120s'" ,
2759
- safe_str (user), safe_str (host), new_password);
2759
+ safe_str (user->user .str ), safe_str (user->host .str ),
2760
+ safe_str (user->password .str ));
2760
2761
}
2761
2762
2762
2763
if (WSREP (thd) && !IF_WSREP (thd->wsrep_applier , 0 ))
@@ -2781,7 +2782,7 @@ bool change_password(THD *thd, const char *host, const char *user,
2781
2782
2782
2783
mysql_mutex_lock (&acl_cache->lock );
2783
2784
ACL_USER *acl_user;
2784
- if (!(acl_user= find_user_exact (host, user)))
2785
+ if (!(acl_user= find_user_exact (user-> host . str , user-> user . str )))
2785
2786
{
2786
2787
mysql_mutex_unlock (&acl_cache->lock );
2787
2788
my_message (ER_PASSWORD_NO_MATCH, ER (ER_PASSWORD_NO_MATCH), MYF (0 ));
@@ -2792,10 +2793,10 @@ bool change_password(THD *thd, const char *host, const char *user,
2792
2793
if (acl_user->plugin .str == native_password_plugin_name.str ||
2793
2794
acl_user->plugin .str == old_password_plugin_name.str )
2794
2795
{
2795
- acl_user->auth_string .str = strmake_root (&acl_memroot, new_password, new_password_len );
2796
- acl_user->auth_string .length = new_password_len ;
2797
- set_user_salt (acl_user, new_password, new_password_len );
2798
- set_user_plugin (acl_user, new_password_len );
2796
+ acl_user->auth_string .str = strmake_root (&acl_memroot, user-> password . str , user-> password . length );
2797
+ acl_user->auth_string .length = user-> password . length ;
2798
+ set_user_salt (acl_user, user-> password . str , user-> password . length );
2799
+ set_user_plugin (acl_user, user-> password . length );
2799
2800
}
2800
2801
else
2801
2802
push_warning (thd, Sql_condition::WARN_LEVEL_NOTE,
@@ -2804,7 +2805,7 @@ bool change_password(THD *thd, const char *host, const char *user,
2804
2805
if (update_user_table (thd, tables[USER_TABLE].table ,
2805
2806
safe_str (acl_user->host .hostname ),
2806
2807
safe_str (acl_user->user .str ),
2807
- new_password, new_password_len ))
2808
+ user-> password . str , user-> password . length ))
2808
2809
{
2809
2810
mysql_mutex_unlock (&acl_cache->lock ); /* purecov: deadcode */
2810
2811
goto end;
@@ -5660,11 +5661,8 @@ static bool has_auth(LEX_USER *user, LEX *lex)
5660
5661
lex->mqh .specified_limits ;
5661
5662
}
5662
5663
5663
- static bool copy_and_check_auth (LEX_USER *to, LEX_USER *from, THD *thd)
5664
+ static bool fix_and_copy_user (LEX_USER *to, LEX_USER *from, THD *thd)
5664
5665
{
5665
- if (fix_lex_user (thd, from))
5666
- return true ;
5667
-
5668
5666
if (to != from)
5669
5667
{
5670
5668
/* preserve authentication information, if LEX_USER was reallocated */
@@ -5673,6 +5671,17 @@ static bool copy_and_check_auth(LEX_USER *to, LEX_USER *from, THD *thd)
5673
5671
to->auth = from->auth ;
5674
5672
}
5675
5673
5674
+ if (fix_lex_user (thd, to))
5675
+ return true ;
5676
+
5677
+ return false ;
5678
+ }
5679
+
5680
+ static bool copy_and_check_auth (LEX_USER *to, LEX_USER *from, THD *thd)
5681
+ {
5682
+ if (fix_and_copy_user (to, from, thd))
5683
+ return true ;
5684
+
5676
5685
// if changing auth for an existing user
5677
5686
if (has_auth (to, thd->lex ) && find_user_exact (to->host .str , to->user .str ))
5678
5687
{
0 commit comments