Merge branch 'QA_5_0'
[phpmyadmin.git] / libraries / classes / UserPassword.php
blob65aaecc2b966b84029c50b68b3c757a3ce5ddd5c
1 <?php
2 /**
3 * Holds the PhpMyAdmin\UserPassword class
4 */
5 declare(strict_types=1);
7 namespace PhpMyAdmin;
9 use PhpMyAdmin\Html\Generator;
10 use PhpMyAdmin\Server\Privileges;
11 use function strlen;
13 /**
14 * Functions for user password
16 class UserPassword
18 /** @var Privileges */
19 private $serverPrivileges;
21 /**
22 * @param Privileges $serverPrivileges Privileges object
24 public function __construct(Privileges $serverPrivileges)
26 $this->serverPrivileges = $serverPrivileges;
29 /**
30 * Send the message as an ajax request
32 * @param array $change_password_message Message to display
33 * @param string $sql_query SQL query executed
35 * @return void
37 public function getChangePassMessage(array $change_password_message, $sql_query = '')
39 $response = Response::getInstance();
40 if ($response->isAjax()) {
41 /**
42 * If in an Ajax request, we don't need to show the rest of the page
44 if ($change_password_message['error']) {
45 $response->addJSON('message', $change_password_message['msg']);
46 $response->setRequestStatus(false);
47 } else {
48 $sql_query = Generator::getMessage(
49 $change_password_message['msg'],
50 $sql_query,
51 'success'
53 $response->addJSON('message', $sql_query);
55 exit;
59 /**
60 * Generate the message
62 * @return array error value and message
64 public function setChangePasswordMsg()
66 $error = false;
67 $message = Message::success(__('The profile has been updated.'));
69 if ($_POST['nopass'] != '1') {
70 if (strlen($_POST['pma_pw']) === 0 || strlen($_POST['pma_pw2']) === 0) {
71 $message = Message::error(__('The password is empty!'));
72 $error = true;
73 } elseif ($_POST['pma_pw'] !== $_POST['pma_pw2']) {
74 $message = Message::error(
75 __('The passwords aren\'t the same!')
77 $error = true;
78 } elseif (strlen($_POST['pma_pw']) > 256) {
79 $message = Message::error(__('Password is too long!'));
80 $error = true;
83 return [
84 'error' => $error,
85 'msg' => $message,
89 /**
90 * Change the password
92 * @param string $password New password
93 * @param string $message Message
94 * @param array $change_password_message Message to show
96 * @return void
98 public function changePassword($password, $message, array $change_password_message)
100 global $auth_plugin;
102 $hashing_function = $this->changePassHashingFunction();
104 [$username, $hostname] = $GLOBALS['dbi']->getCurrentUserAndHost();
106 $serverType = Util::getServerType();
107 $serverVersion = $GLOBALS['dbi']->getVersion();
109 if (isset($_POST['authentication_plugin'])
110 && ! empty($_POST['authentication_plugin'])
112 $orig_auth_plugin = $_POST['authentication_plugin'];
113 } else {
114 $orig_auth_plugin = $this->serverPrivileges->getCurrentAuthenticationPlugin(
115 'change',
116 $username,
117 $hostname
121 $sql_query = 'SET password = '
122 . ($password == '' ? '\'\'' : $hashing_function . '(\'***\')');
124 if ($serverType == 'MySQL'
125 && $serverVersion >= 50706
127 $sql_query = 'ALTER USER \'' . $GLOBALS['dbi']->escapeString($username)
128 . '\'@\'' . $GLOBALS['dbi']->escapeString($hostname)
129 . '\' IDENTIFIED WITH ' . $orig_auth_plugin . ' BY '
130 . ($password == '' ? '\'\'' : '\'***\'');
131 } elseif (($serverType == 'MySQL'
132 && $serverVersion >= 50507)
133 || ($serverType == 'MariaDB'
134 && $serverVersion >= 50200)
136 // For MySQL versions 5.5.7+ and MariaDB versions 5.2+,
137 // explicitly set value of `old_passwords` so that
138 // it does not give an error while using
139 // the PASSWORD() function
140 if ($orig_auth_plugin == 'sha256_password') {
141 $value = 2;
142 } else {
143 $value = 0;
145 $GLOBALS['dbi']->tryQuery('SET `old_passwords` = ' . $value . ';');
148 $this->changePassUrlParamsAndSubmitQuery(
149 $username,
150 $hostname,
151 $password,
152 $sql_query,
153 $hashing_function,
154 $orig_auth_plugin
157 $auth_plugin->handlePasswordChange($password);
158 $this->getChangePassMessage($change_password_message, $sql_query);
159 $this->changePassDisplayPage($message, $sql_query);
163 * Generate the hashing function
165 * @return string
167 private function changePassHashingFunction()
169 if (Core::isValid(
170 $_POST['authentication_plugin'],
171 'identical',
172 'mysql_old_password'
173 )) {
174 $hashing_function = 'OLD_PASSWORD';
175 } else {
176 $hashing_function = 'PASSWORD';
178 return $hashing_function;
182 * Changes password for a user
184 * @param string $username Username
185 * @param string $hostname Hostname
186 * @param string $password Password
187 * @param string $sql_query SQL query
188 * @param string $hashing_function Hashing function
189 * @param string $orig_auth_plugin Original Authentication Plugin
191 * @return void
193 private function changePassUrlParamsAndSubmitQuery(
194 $username,
195 $hostname,
196 $password,
197 $sql_query,
198 $hashing_function,
199 $orig_auth_plugin
201 $err_url = Url::getFromRoute('/user-password');
203 $serverType = Util::getServerType();
204 $serverVersion = $GLOBALS['dbi']->getVersion();
206 if ($serverType == 'MySQL' && $serverVersion >= 50706) {
207 $local_query = 'ALTER USER \'' . $GLOBALS['dbi']->escapeString($username)
208 . '\'@\'' . $GLOBALS['dbi']->escapeString($hostname) . '\''
209 . ' IDENTIFIED with ' . $orig_auth_plugin . ' BY '
210 . ($password == ''
211 ? '\'\''
212 : '\'' . $GLOBALS['dbi']->escapeString($password) . '\'');
213 } elseif ($serverType == 'MariaDB'
214 && $serverVersion >= 50200
215 && $serverVersion < 100100
216 && $orig_auth_plugin !== ''
218 if ($orig_auth_plugin == 'mysql_native_password') {
219 // Set the hashing method used by PASSWORD()
220 // to be 'mysql_native_password' type
221 $GLOBALS['dbi']->tryQuery('SET old_passwords = 0;');
222 } elseif ($orig_auth_plugin == 'sha256_password') {
223 // Set the hashing method used by PASSWORD()
224 // to be 'sha256_password' type
225 $GLOBALS['dbi']->tryQuery('SET `old_passwords` = 2;');
228 $hashedPassword = $this->serverPrivileges->getHashedPassword($_POST['pma_pw']);
230 $local_query = 'UPDATE `mysql`.`user` SET'
231 . " `authentication_string` = '" . $hashedPassword
232 . "', `Password` = '', "
233 . " `plugin` = '" . $orig_auth_plugin . "'"
234 . " WHERE `User` = '" . $GLOBALS['dbi']->escapeString($username)
235 . "' AND Host = '" . $GLOBALS['dbi']->escapeString($hostname) . "';";
236 } else {
237 $local_query = 'SET password = ' . ($password == ''
238 ? '\'\''
239 : $hashing_function . '(\''
240 . $GLOBALS['dbi']->escapeString($password) . '\')');
242 if (! @$GLOBALS['dbi']->tryQuery($local_query)) {
243 Generator::mysqlDie(
244 $GLOBALS['dbi']->getError(),
245 $sql_query,
246 false,
247 $err_url
251 // Flush privileges after successful password change
252 $GLOBALS['dbi']->tryQuery('FLUSH PRIVILEGES;');
256 * Display the page
258 * @param string $message Message
259 * @param string $sql_query SQL query
261 * @return void
263 private function changePassDisplayPage($message, $sql_query)
265 echo '<h1>' , __('Change password') , '</h1>' , "\n\n";
266 echo Generator::getMessage(
267 $message,
268 $sql_query,
269 'success'
271 $template = new Template();
272 echo $template->render('user_password');
273 exit;