UserPassword.php 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. <?php
  2. /* vim: set expandtab sw=4 ts=4 sts=4: */
  3. /**
  4. * Holds the PhpMyAdmin\UserPassword class
  5. *
  6. * @package PhpMyAdmin
  7. */
  8. namespace PhpMyAdmin;
  9. use PhpMyAdmin\Core;
  10. use PhpMyAdmin\Message;
  11. use PhpMyAdmin\Response;
  12. use PhpMyAdmin\Server\Privileges;
  13. use PhpMyAdmin\Url;
  14. use PhpMyAdmin\Util;
  15. /**
  16. * Functions for user_password.php
  17. *
  18. * @package PhpMyAdmin
  19. */
  20. class UserPassword
  21. {
  22. /**
  23. * Send the message as an ajax request
  24. *
  25. * @param array $change_password_message Message to display
  26. * @param string $sql_query SQL query executed
  27. *
  28. * @return void
  29. */
  30. public function getChangePassMessage(array $change_password_message, $sql_query = '')
  31. {
  32. $response = Response::getInstance();
  33. if ($response->isAjax()) {
  34. /**
  35. * If in an Ajax request, we don't need to show the rest of the page
  36. */
  37. if ($change_password_message['error']) {
  38. $response->addJSON('message', $change_password_message['msg']);
  39. $response->setRequestStatus(false);
  40. } else {
  41. $sql_query = Util::getMessage(
  42. $change_password_message['msg'],
  43. $sql_query,
  44. 'success'
  45. );
  46. $response->addJSON('message', $sql_query);
  47. }
  48. exit;
  49. }
  50. }
  51. /**
  52. * Generate the message
  53. *
  54. * @return array error value and message
  55. */
  56. public function setChangePasswordMsg()
  57. {
  58. $error = false;
  59. $message = Message::success(__('The profile has been updated.'));
  60. if (($_POST['nopass'] != '1')) {
  61. if (strlen($_POST['pma_pw']) === 0 || strlen($_POST['pma_pw2']) === 0) {
  62. $message = Message::error(__('The password is empty!'));
  63. $error = true;
  64. } elseif ($_POST['pma_pw'] !== $_POST['pma_pw2']) {
  65. $message = Message::error(
  66. __('The passwords aren\'t the same!')
  67. );
  68. $error = true;
  69. } elseif (strlen($_POST['pma_pw']) > 256) {
  70. $message = Message::error(__('Password is too long!'));
  71. $error = true;
  72. }
  73. }
  74. return array('error' => $error, 'msg' => $message);
  75. }
  76. /**
  77. * Change the password
  78. *
  79. * @param string $password New password
  80. * @param string $message Message
  81. * @param array $change_password_message Message to show
  82. *
  83. * @return void
  84. */
  85. public function changePassword($password, $message, array $change_password_message)
  86. {
  87. global $auth_plugin;
  88. $hashing_function = $this->changePassHashingFunction();
  89. list($username, $hostname) = $GLOBALS['dbi']->getCurrentUserAndHost();
  90. $serverType = Util::getServerType();
  91. $serverVersion = $GLOBALS['dbi']->getVersion();
  92. if (isset($_POST['authentication_plugin'])
  93. && ! empty($_POST['authentication_plugin'])
  94. ) {
  95. $orig_auth_plugin = $_POST['authentication_plugin'];
  96. } else {
  97. $orig_auth_plugin = Privileges::getCurrentAuthenticationPlugin(
  98. 'change', $username, $hostname
  99. );
  100. }
  101. $sql_query = 'SET password = '
  102. . (($password == '') ? '\'\'' : $hashing_function . '(\'***\')');
  103. if ($serverType == 'MySQL'
  104. && $serverVersion >= 50706
  105. ) {
  106. $sql_query = 'ALTER USER \'' . $GLOBALS['dbi']->escapeString($username)
  107. . '\'@\'' . $GLOBALS['dbi']->escapeString($hostname)
  108. . '\' IDENTIFIED WITH ' . $orig_auth_plugin . ' BY '
  109. . (($password == '') ? '\'\'' : '\'***\'');
  110. } elseif (($serverType == 'MySQL'
  111. && $serverVersion >= 50507)
  112. || ($serverType == 'MariaDB'
  113. && $serverVersion >= 50200)
  114. ) {
  115. // For MySQL versions 5.5.7+ and MariaDB versions 5.2+,
  116. // explicitly set value of `old_passwords` so that
  117. // it does not give an error while using
  118. // the PASSWORD() function
  119. if ($orig_auth_plugin == 'sha256_password') {
  120. $value = 2;
  121. } else {
  122. $value = 0;
  123. }
  124. $GLOBALS['dbi']->tryQuery('SET `old_passwords` = ' . $value . ';');
  125. }
  126. $this->changePassUrlParamsAndSubmitQuery(
  127. $username, $hostname, $password,
  128. $sql_query, $hashing_function, $orig_auth_plugin
  129. );
  130. $auth_plugin->handlePasswordChange($password);
  131. $this->getChangePassMessage($change_password_message, $sql_query);
  132. $this->changePassDisplayPage($message, $sql_query);
  133. }
  134. /**
  135. * Generate the hashing function
  136. *
  137. * @return string $hashing_function
  138. */
  139. private function changePassHashingFunction()
  140. {
  141. if (Core::isValid(
  142. $_POST['authentication_plugin'], 'identical', 'mysql_old_password'
  143. )) {
  144. $hashing_function = 'OLD_PASSWORD';
  145. } else {
  146. $hashing_function = 'PASSWORD';
  147. }
  148. return $hashing_function;
  149. }
  150. /**
  151. * Changes password for a user
  152. *
  153. * @param string $username Username
  154. * @param string $hostname Hostname
  155. * @param string $password Password
  156. * @param string $sql_query SQL query
  157. * @param string $hashing_function Hashing function
  158. * @param string $orig_auth_plugin Original Authentication Plugin
  159. *
  160. * @return void
  161. */
  162. private function changePassUrlParamsAndSubmitQuery(
  163. $username, $hostname, $password, $sql_query, $hashing_function, $orig_auth_plugin
  164. ) {
  165. $err_url = 'user_password.php' . Url::getCommon();
  166. $serverType = Util::getServerType();
  167. $serverVersion = $GLOBALS['dbi']->getVersion();
  168. if ($serverType == 'MySQL' && $serverVersion >= 50706) {
  169. $local_query = 'ALTER USER \'' . $GLOBALS['dbi']->escapeString($username)
  170. . '\'@\'' . $GLOBALS['dbi']->escapeString($hostname) . '\''
  171. . ' IDENTIFIED with ' . $orig_auth_plugin . ' BY '
  172. . (($password == '')
  173. ? '\'\''
  174. : '\'' . $GLOBALS['dbi']->escapeString($password) . '\'');
  175. } elseif ($serverType == 'MariaDB'
  176. && $serverVersion >= 50200
  177. && $serverVersion < 100100
  178. && $orig_auth_plugin !== ''
  179. ) {
  180. if ($orig_auth_plugin == 'mysql_native_password') {
  181. // Set the hashing method used by PASSWORD()
  182. // to be 'mysql_native_password' type
  183. $GLOBALS['dbi']->tryQuery('SET old_passwords = 0;');
  184. } elseif ($orig_auth_plugin == 'sha256_password') {
  185. // Set the hashing method used by PASSWORD()
  186. // to be 'sha256_password' type
  187. $GLOBALS['dbi']->tryQuery('SET `old_passwords` = 2;');
  188. }
  189. $hashedPassword = Privileges::getHashedPassword($_POST['pma_pw']);
  190. $local_query = "UPDATE `mysql`.`user` SET"
  191. . " `authentication_string` = '" . $hashedPassword
  192. . "', `Password` = '', "
  193. . " `plugin` = '" . $orig_auth_plugin . "'"
  194. . " WHERE `User` = '" . $GLOBALS['dbi']->escapeString($username)
  195. . "' AND Host = '" . $GLOBALS['dbi']->escapeString($hostname) . "';";
  196. } else {
  197. $local_query = 'SET password = ' . (($password == '')
  198. ? '\'\''
  199. : $hashing_function . '(\''
  200. . $GLOBALS['dbi']->escapeString($password) . '\')');
  201. }
  202. if (! @$GLOBALS['dbi']->tryQuery($local_query)) {
  203. Util::mysqlDie(
  204. $GLOBALS['dbi']->getError(),
  205. $sql_query,
  206. false,
  207. $err_url
  208. );
  209. }
  210. // Flush privileges after successful password change
  211. $GLOBALS['dbi']->tryQuery("FLUSH PRIVILEGES;");
  212. }
  213. /**
  214. * Display the page
  215. *
  216. * @param string $message Message
  217. * @param string $sql_query SQL query
  218. *
  219. * @return void
  220. */
  221. private function changePassDisplayPage($message, $sql_query)
  222. {
  223. echo '<h1>' , __('Change password') , '</h1>' , "\n\n";
  224. echo Util::getMessage(
  225. $message, $sql_query, 'success'
  226. );
  227. echo '<a href="index.php' , Url::getCommon()
  228. , ' target="_parent">' , "\n"
  229. , '<strong>' , __('Back') , '</strong></a>';
  230. exit;
  231. }
  232. }