Старый метод хеширования пароля 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';

будет хорошим началом?


person The Disintegrator    schedule 12.12.2009    source источник
comment
SET SESSION old_passwords=0 должно быть достаточно, нет необходимости изменять глобальные настройки для этого одноразового решения (иначе они могут просто перезапустить mysqld без этой опции). Я протестировал его на своем локальном сервере 5.1.37. Чтобы убедиться, что новый хэш действительно новый, позвольте парню из службы поддержки выполнить запрос SELECT `Host`, Length(`PASSWORD`) FROM mysql.user WHERE `User`='nodari'. Помните: 41 – хорошо, 16 – старо=плохо ;-)   -  person VolkerK    schedule 12.12.2009
comment
О, и я бы сначала попробовал без гранта. Это не должно быть необходимо для вашей существующей учетной записи. Это, вероятно, тоже не повредит, но вводит новый вопрос: подчиняется ли «идентифицировано» точно тем же правилам, что и PASSWORD()? Скорее всего, но мало ли ;-)   -  person VolkerK    schedule 12.12.2009
comment
это не одноразовая вещь, мне нужно будет делать это ежедневно в течение определенного времени ... И я предполагаю, что при следующей перезагрузке эта штука old_password вернется, чтобы укусить меня за задницу   -  person The Disintegrator    schedule 12.12.2009
comment
Я был с той же проблемой. Этот вопрос/ответ решает его: http://stackoverflow.com/questions/1575807/cannot-connect-to-mysql-4-1-using-old-authentication   -  person rlc    schedule 22.09.2011


Ответы (6)


Да, похоже, крутой. Без сотрудничества с вашими хостами или возможности изменять форматы паролей или клиентские библиотеки у вас не так много вариантов.

Честно говоря, моим первым выбором было бы отказаться от Dreamhost. Это, вероятно, много работы, но если они застрянут, используя старые несовместимые вещи, это будет по-прежнему проблематично.

Если это не вариант, как насчет совместного автоматизированного процесса? Вы можете экспортировать данные на стороне Slicehost в файл CSV и преобразовать их в любой формат, необходимый для Dreamhost, а затем загрузить их на сервер Dreamhost. У вас может быть скрипт cron на сервере Dreamhost, который периодически проверяет загруженный файл и обрабатывает его (убедившись, что вы переместили или удалили его после того, как он был успешно обработан).

person zombat    schedule 12.12.2009
comment
ну, прямо сейчас я пишу скрипт для генерации запроса на slicehost, который будет выполняться на dreamhost. я использую curl в качестве метода передачи. Это ужасный хак, но, по крайней мере, я могу вызвать скрипт обновления через браузер или cron... - person The Disintegrator; 12.12.2009

При некоторых условиях вы все еще можете установить и использовать «пароль нового алгоритма хеширования».
Серверы 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 символа, и вы ничего не сможете с этим поделать (кроме того, что будете придираться к ним).

person VolkerK    schedule 12.12.2009
comment
'mysql› УСТАНОВИТЬ СЕССИЯ old_passwords=0; Запрос OK, затронуто 0 строк (0,01 с) mysql› SELECT @@global.old_passwords,@@session.old_passwords, Length(PASSWORD('abc')); +---------------------------------------+---------- -+----------------------------------------+ | @@global.old_passwords | @@session.old_passwords | Длина(ПАРОЛЬ('abc')) | +---------------------------------------+---------- -+----------------------------------------+ | 1 | 0 | 41 | +---------------------------------------+---------- -+----------------------------------------+ 1 ряд в наборе (0,00 сек) - person The Disintegrator; 12.12.2009
comment
Я обновил вопрос, поле комментария не позволяет мне писать код - person The Disintegrator; 12.12.2009

У меня только что была эта проблема, и я смог ее обойти.

Во-первых, подключитесь к базе данных 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);

Это позволило мне успешно подключиться.

person TehShrike    schedule 25.05.2010
comment
да, я знаю, что вы можете сделать это таким образом, но идея заключается в том, чтобы иметь текущего клиента на slicehost. Кроме того, я не могу ничего изменить в DreamHost. И они используют метод старого пароля, потому что все пароли всех серверов хранятся где-то еще, они используют старый метод и уже могут изменить его... В этом конкретном случае нет хорошего решения. В итоге я создал сценарии на обоих концах, которые общаются с помощью CURL... - person The Disintegrator; 25.05.2010
comment
Я не знаю о Slicehost. Как оказалось, я тоже использую Dreamhost. old_passwords довольно раздражает. - person TehShrike; 25.05.2010

Я бы решил это, сбросив данные на Slicehost, используя SELECT ... INTO OUTFILE.

Это позволяет спроектировать запрос таким образом, чтобы формат вывода соответствовал структуре таблицы на целевом сайте.

Затем перенесите файл дампа на Dreamhost и используйте LOAD DATA INFILE.

Кстати, Dreamhost действительно все еще использует MySQL 4.0? Они очень устарели — даже расширенная поддержка MySQL 4.1 истечается в этом месяце (декабрь 2009 г.).

person Bill Karwin    schedule 12.12.2009
comment
самое интересное, что они используют версию 5.0. Я не понимаю, почему они до сих пор используют старый метод хэширования - person The Disintegrator; 12.12.2009
comment
Хорошо, тогда это, вероятно, потому, что изменение метода пароля, вероятно, нарушит работу сотен (или тысяч) клиентских приложений, работающих на этом хосте. Часто веб-хостинг просто оставляет такой сервер как есть и включает новые функции только на отдельном сервере. Со временем их клиенты постепенно переходят на более новый сервер и, наконец, выводят из эксплуатации старый. Вы можете попросить своего провайдера перенести вашу размещенную учетную запись на один из этих новых серверов. - person Bill Karwin; 12.12.2009
comment
это частный сервер... разве это не будет экземпляр mysql с не большим количеством пользователей, чем я? - person The Disintegrator; 12.12.2009
comment
Не знаю, надо спросить у хостинг-провайдера. Это может быть частный сервер для вашего приложения, но экземпляр MySQL находится на другом сервере, который является общим. Я не знаю. - person Bill Karwin; 12.12.2009

Я думаю, вы должны сделать WebServices/RPC из slicehost и написать соответствующий сервис для его обработки.

person Dennis C    schedule 12.12.2009

Я была такая же проблема. Чтобы ее решить, я сделал следующее:

SET PASSWORD = PASSWORD('[your password]');
person f.eberharter    schedule 04.02.2016
comment
Где выбрать пользователя? - person Volatil3; 27.10.2016