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]');
Другие вопросы по тегам