From: Kristofer Pettersson Date: November 5 2012 10:55am Subject: bzr push into mysql-trunk branch (kristofer.pettersson:4903 to 4904) List-Archive: http://lists.mysql.com/commits/145135 Message-Id: <20121105105530.7920.40445.4904@ghost> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit 4904 Kristofer Pettersson 2012-11-05 [merge] 5.6 =>trunk modified: mysql-test/r/connect.result mysql-test/r/plugin_auth_sha256_tls.result mysql-test/t/connect.test mysql-test/t/plugin_auth_sha256_tls.test sql/sql_yacc.yy 4903 horst.hunger@stripped 2012-11-05 [merge] Merge from 5.6 === modified file 'mysql-test/r/connect.result' --- a/mysql-test/r/connect.result 2012-08-31 21:54:56 +0000 +++ b/mysql-test/r/connect.result 2012-11-05 10:54:17 +0000 @@ -340,15 +340,16 @@ SELECT last_t1(); ERROR HY000: You must SET PASSWORD before executing this statement CALL test_t1(last_t1() + 1); ERROR HY000: You must SET PASSWORD before executing this statement -# setting a password with a user name is no good +# setting a password with a user name is ok if it exactly matches the +# authenticated user. SET PASSWORD FOR must_change@localhost = PASSWORD('aha3'); -ERROR HY000: You must SET PASSWORD before executing this statement SELECT USER(); -ERROR HY000: You must SET PASSWORD before executing this statement +USER() +must_change@localhost SELECT last_t1(); -ERROR HY000: You must SET PASSWORD before executing this statement +last_t1() +4 CALL test_t1(last_t1() + 1); -ERROR HY000: You must SET PASSWORD before executing this statement # setting a password for the current user works SET PASSWORD FOR CURRENT_USER() = PASSWORD('aha3'); SELECT USER(); @@ -356,7 +357,7 @@ USER() must_change@localhost SELECT last_t1(); last_t1() -4 +5 CALL test_t1(last_t1() + 1); # testing the ALTER USER command # try a single user === modified file 'mysql-test/r/plugin_auth_sha256_tls.result' --- a/mysql-test/r/plugin_auth_sha256_tls.result 2012-10-31 15:42:45 +0000 +++ b/mysql-test/r/plugin_auth_sha256_tls.result 2012-11-05 08:50:29 +0000 @@ -30,16 +30,17 @@ Connection should fail for localhost ERROR 28000: Access denied for user 'kristofer'@'localhost' (using password: NO) DROP USER 'kristofer'@'33.33.33.33'; # -# BUG14807074 ALTER USER PASSWORD EXPIRE VS SHA256_PASSWORD +# BUG#14807074 ALTER USER PASSWORD EXPIRE VS SHA256_PASSWORD # CREATE USER 'u1'@'localhost' IDENTIFIED WITH 'sha256_password'; SET PASSWORD FOR 'u1'@'localhost' = PASSWORD('pass'); ALTER USER 'u1'@'localhost' PASSWORD EXPIRE; -SELECT * FROM t1; +SELECT USER(); ERROR HY000: You must SET PASSWORD before executing this statement SET @@OLD_PASSWORDS=2; SET PASSWORD=PASSWORD('pass2'); -SELECT * FROM no_such_table; -ERROR 42S02: Table 'test.no_such_table' doesn't exist +SELECT USER(); +USER() +u1@localhost DROP USER 'u1'@'localhost'; SET GLOBAL old_passwords= default; === modified file 'mysql-test/t/connect.test' --- a/mysql-test/t/connect.test 2012-06-04 15:35:18 +0000 +++ b/mysql-test/t/connect.test 2012-11-05 08:50:29 +0000 @@ -404,14 +404,11 @@ SELECT last_t1(); --error ER_MUST_CHANGE_PASSWORD CALL test_t1(last_t1() + 1); ---echo # setting a password with a user name is no good ---error ER_MUST_CHANGE_PASSWORD +--echo # setting a password with a user name is ok if it exactly matches the +--echo # authenticated user. SET PASSWORD FOR must_change@localhost = PASSWORD('aha3'); ---error ER_MUST_CHANGE_PASSWORD SELECT USER(); ---error ER_MUST_CHANGE_PASSWORD SELECT last_t1(); ---error ER_MUST_CHANGE_PASSWORD CALL test_t1(last_t1() + 1); --echo # setting a password for the current user works === modified file 'mysql-test/t/plugin_auth_sha256_tls.test' --- a/mysql-test/t/plugin_auth_sha256_tls.test 2012-10-31 15:42:45 +0000 +++ b/mysql-test/t/plugin_auth_sha256_tls.test 2012-11-05 08:50:29 +0000 @@ -45,20 +45,19 @@ connect(con4,127.0.0.1,kristofer,,,,,SSL DROP USER 'kristofer'@'33.33.33.33'; --echo # ---echo # BUG14807074 ALTER USER PASSWORD EXPIRE VS SHA256_PASSWORD +--echo # BUG#14807074 ALTER USER PASSWORD EXPIRE VS SHA256_PASSWORD --echo # CREATE USER 'u1'@'localhost' IDENTIFIED WITH 'sha256_password'; SET PASSWORD FOR 'u1'@'localhost' = PASSWORD('pass'); ALTER USER 'u1'@'localhost' PASSWORD EXPIRE; connect(con5,127.0.0.1,u1,pass,test,,,SSL); --error ER_MUST_CHANGE_PASSWORD -SELECT * FROM t1; +SELECT USER(); SET @@OLD_PASSWORDS=2; SET PASSWORD=PASSWORD('pass2'); connect(con6,127.0.0.1,u1,pass2,test,,,SSL); ---error ER_NO_SUCH_TABLE -SELECT * FROM no_such_table; +SELECT USER(); connection default; DROP USER 'u1'@'localhost'; === modified file 'sql/sql_yacc.yy' --- a/sql/sql_yacc.yy 2012-11-02 19:58:06 +0000 +++ b/sql/sql_yacc.yy 2012-11-05 10:54:17 +0000 @@ -925,6 +925,41 @@ static bool sp_create_assignment_instr(T return false; } +/** + Compare a LEX_USER against the current user as defined by the exact user and + host used during authentication. + + @param user A pointer to a user which needs to be matched against the + current. + + @see SET PASSWORD rules + + @retval true The specified user is the authorized user + @retval false The user doesn't match +*/ + +bool match_authorized_user(Security_context *ctx, LEX_USER *user) +{ + if(user->user.str && my_strcasecmp(system_charset_info, + ctx->priv_user, + user->user.str) == 0) + { + /* + users match; let's compare hosts. + 1. first compare with the host we actually authorized, + 2. then see if we match the host mask of the priv_host + */ + if (user->host.str && my_strcasecmp(system_charset_info, + user->host.str, + ctx->priv_host) == 0) + { + /* specified user exactly match the authorized user */ + return true; + } + } + return false; +} + %} %union { @@ -14681,8 +14716,30 @@ option_value_no_option_type: lex->autocommit= TRUE; if (lex->sphead) lex->sphead->m_flags|= sp_head::HAS_SET_AUTOCOMMIT_STMT; - if (!user->user.str) + /* + 'is_change_password' should be set if the user is setting his + own password. This is later used to determine if the password + expiration flag should be reset. + Either the user exactly matches the currently authroized user or + the CURRENT_USER keyword was used. + + If CURRENT_USER was used for the rule then + user->user.str=0. See rule below: + + user: + [..] + | CURRENT_USER optional_braces + { + [..] + memset($$, 0, sizeof(LEX_USER)); + } + */ + if (user->user.str || + match_authorized_user(¤t_thd->main_security_ctx, + user)) lex->is_change_password= TRUE; + else + lex->is_change_password= FALSE; } ; No bundle (reason: useless for push emails).