Mysql метод хеширования паролей старый против нового
Я пытаюсь подключиться к серверу MySQL на Dreamhost с помощью PHP-скрипта, расположенного на сервере на SliceHost (две разные хостинговые компании). Мне нужно сделать это, чтобы я мог передавать новые данные на slicehost на dreamhost. Использование дампа не вариант, потому что структуры таблиц разные, и мне нужно только передать небольшое подмножество данных (100-200 ежедневных записей). Проблема в том, что я использую новый метод хеширования паролей MySQL на slicehost и dreamhost использует старый, так что я получаю
$link = mysql_connect($mysqlHost, $mysqlUser, $mysqlPass, FALSE);
Warning: mysql_connect() [function.mysql-connect]: OK packet 6 bytes shorter than expected
Warning: mysql_connect() [function.mysql-connect]: mysqlnd cannot connect to MySQL 4.1+ using old authentication
Warning: mysql_query() [function.mysql-query]: Access denied for user 'nodari'@'localhost' (using password: NO)
факты:
- Мне нужно продолжать использовать новый метод на slicehost, и я не могу использовать старую версию / библиотеку php
- База данных слишком велика, чтобы переносить ее каждый день с помощью дампа
- Даже если бы я сделал это, таблицы имеют разные структуры
- Мне нужно копировать только небольшое его подмножество, ежедневно (только изменения дня, 100-200 записей)
- Поскольку таблицы очень разные, мне нужно использовать php в качестве моста для нормализации данных
- Уже гуглил
- Уже поговорили с обоими сотрудниками службы поддержки
Для меня более очевидным вариантом было бы начать использовать новый метод хеширования паролей MySQL на dreamhost, но они не изменят его, и я не root, поэтому я не могу сделать это сам.
Любая дикая идея?
По предложению VolkerK:
mysql> SET SESSION old_passwords=0;
Query OK, 0 rows affected (0.01 sec)
mysql> SELECT @@global.old_passwords,@@session.old_passwords, Length(PASSWORD('abc'));
+------------------------+-------------------------+-------------------------+
| @@global.old_passwords | @@session.old_passwords | Length(PASSWORD('abc')) |
+------------------------+-------------------------+-------------------------+
| 1 | 0 | 41 |
+------------------------+-------------------------+-------------------------+
1 row in set (0.00 sec)
Теперь очевидным будет запустить mysql> SET GLOBAL old_passwords=0; Но мне нужна СУПЕР привилегия, чтобы сделать это, и они не дадут мне это
если я выполню запрос
SET PASSWORD FOR 'nodari'@'HOSTNAME' = PASSWORD('new password');
Я получаю ошибку
ERROR 1044 (42000): Access denied for user 'nodari'@'67.205.0.0/255.255.192.0' to database 'mysql'
Я не рут...
Парень из службы поддержки Dreamhost настаивает на том, что проблема в моем конце. Но он сказал, что выполнит любой запрос, который я ему скажу, поскольку это частный сервер. Итак, я должен сказать этому парню ТОЧНО, что бежать. Так, сказав ему бежать
SET SESSION old_passwords=0;
SET GLOBAL old_passwords=0;
SET PASSWORD FOR 'nodari'@'HOSTNAME' = PASSWORD('new password');
grant all privileges on *.* to nodari@HOSTNAME identified by 'new password';
будет хорошим началом?
6 ответов
Да, это выглядит как крепкий орешек. Без сотрудничества с вашими хостами или возможности менять форматы паролей или клиентских библиотек у вас не так много вариантов.
Честно говоря, мой первый выбор - угробить Dreamhost. Это, вероятно, большая работа, но если они застрянут, используя старые несовместимые вещи, это будет по-прежнему проблематично.
Если это не вариант, как насчет совместного автоматизированного процесса? Вы можете экспортировать данные со стороны Slicehost в файл CSV и преобразовать их в любой формат, необходимый для Dreamhost, а затем загрузить их на сервер Dreamhost. Сценарий cron на сервере Dreamhost может периодически проверять загруженный файл и обрабатывать его (не забудьте переместить или удалить его после успешной обработки).
В некоторых случаях вы все равно сможете установить и использовать "новый пароль алгоритма хеширования".
Серверы MySQL 4.1+ могут обрабатывать оба алгоритма входа. Какой из них используется, не зависит от переменной old-passwords. Если MySQL находит хэш длиной 41 символ, начинающийся с *, он использует новую систему. И функция PASSWORD() также может использовать оба алгоритма. Если поле mysql.user.Password достаточно велико для хранения 41 символа, а переменная old-passwords равна 0, это создаст "новый" пароль. Документация для old_passwords говорит Variable Scope Both
так что вы можете изменить его для вашего сеанса.
Подключитесь к серверу MySQL (с клиентом, который может это сделать, несмотря на глобальный old_passwords=1), например, HeidiSQL, и попробуйте следующее:
SET SESSION old_passwords=0;
SELECT @@global.old_passwords,@@session.old_passwords, Length(PASSWORD('abc'));
Если это печатает 1, 0, 41
(это означает, что глобальные old_passwords включены, но для сеанса он выключен, а PASSWORD() вернул "новый" пароль), вы должны иметь возможность установить новый пароль, используя новый алгоритм для вашей учетной записи в том же сеансе.
Но если dreamhost действительно хочет отключить алгоритм новых паролей, поле mysql.user.Password будет иметь длину менее 41 символа, и вы ничего не можете с этим поделать (кроме как ворчать).
У меня просто была эта проблема, и я смог обойти ее.
Сначала подключитесь к базе данных MySQL со старым клиентом, который не обращает внимания на old_passwords. Подключитесь, используя пользователя, который будет использовать ваш скрипт.
Запустите эти запросы:
SET SESSION old_passwords=FALSE;
SET PASSWORD = PASSWORD('[your password]');
В вашем скрипте PHP измените функцию mysql_connect, чтобы включить флаг клиента 1:
define('CLIENT_LONG_PASSWORD', 1);
mysql_connect('[your server]', '[your username]', '[your password]', false, CLIENT_LONG_PASSWORD);
Это позволило мне успешно подключиться.
Я бы решил это, сбросив данные на Slicehost, используя SELECT ... INTO OUTFILE
,
Это позволяет спроектировать ваш запрос, чтобы убедиться, что выходные данные имеют формат, соответствующий структуре таблицы на целевом сайте.
Затем перенесите файл дампа в Dreamhost и используйте LOAD DATA INFILE
,
Кроме того, Dreamhost все еще использует MySQL 4.0? Они чрезвычайно устарели - даже расширенная поддержка MySQL 4.1 истекает в этом месяце (декабрь 2009).
Я думаю, что вы должны сделать WebServices/RPC из slicehost и написать соответствующий сервис для обработки.
Я была такая же проблема. Чтобы решить это, я сделал следующее:
SET PASSWORD = PASSWORD('[your password]');