Mysql 密码哈希方法旧与新
我正在尝试从位于 slicehost (两个不同的托管公司)服务器中的 php 脚本连接到 dreamhost 的 mysql 服务器。 我需要这样做,以便我可以将 slicehost 上的新数据传输到 dreamhost。使用转储不是一个选项,因为表结构不同,我只需要传输一小部分数据(100-200 条每日记录) 问题是我在 slicehost 使用新的 MySQL 密码哈希方法,而 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 作为桥梁来标准化数据
- 已经用 google 搜索过
- 已经与支持人员交谈过对
我来说更明显的选择是开始在 dreamhost 使用新的 MySQL 密码哈希方法,但他们不会改变它,而且我不是 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>设置全局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'
,我不是 root...
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';
会是一个好的开始吗?
I'm trying to connect to a mysql server at dreamhost from a php scrip located in a server at slicehost (two different hosting companies).
I need to do this so I can transfer new data at slicehost to dreamhost. Using a dump is not an option because the table structures are different and i only need to transfer a small subset of data (100-200 daily records)
The problem is that I'm using the new MySQL Password Hashing method at slicehost, and dreamhost uses the old one, So i get
$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)
facts:
- I need to continue using the new method at slicehost and i can't use an older php version/library
- The database is too big to transfer it every day with a dump
- Even if i did this, the tables have different structures
- I need to copy only a small subset of it, in a daily basis (only the changes of the day, 100-200 records)
- Since the tables are so different, i need to use php as a bridge to normalize the data
- Already googled it
- Already talked to both support stafs
The more obvious option to me would be to start using the new MySQL Password Hashing method at dreamhost, but they will not change it and i'm not root so i can't do this myself.
Any wild idea?
By VolkerK sugestion:
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)
The obvious thing now would be run a
mysql> SET GLOBAL old_passwords=0;
But i need SUPER privilege to do that and they wont give it to me
if I run the query
SET PASSWORD FOR 'nodari'@'HOSTNAME' = PASSWORD('new password');
I get the error
ERROR 1044 (42000): Access denied for user 'nodari'@'67.205.0.0/255.255.192.0' to database 'mysql'
I'm not root...
The guy at dreamhost support insist saying thet the problem is at my end. But he said he will run any query I tell him since it's a private server.
So, I need to tell this guy EXACTLY what to run.
So, telling him to run
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';
would be a good start?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
在某些情况下,您仍然可以设置和使用“新的哈希算法密码”。
MySQL 4.1+ 服务器能够处理这两种登录算法。使用哪一个与旧密码变量无关。如果 MySQL 找到以 * 开头的 41 个字符长的哈希值,它将使用新系统。 PASSWORD() 函数也可以使用这两种算法。如果字段 mysql.user.Password 足够宽,可以存储 41 个字符,并且旧密码变量为 0,它将创建一个“新”密码。
old_passwords 的文档说
变量范围两者
,这样您就可以为您的会话更改它。连接到 MySQL 服务器(使用尽管全局 old_passwords=1 也能够执行此操作的客户端),例如 HeidiSQL 并尝试以下操作:
如果它打印
1, 0, 41
(意味着全局 old_passwords 已打开,但对于会话而言,它已关闭并且 PASSWORD() 返回了“新”密码)您应该能够使用新密码设置新密码同一会话中您的帐户的算法。但是,如果 dreamhost 确实想要禁用新密码算法,则 mysql.user.Password 字段的长度将小于 41 个字符,并且您对此无能为力(除了唠叨他们)。
On some conditions you may still be able to set and use a "new hashing algorithm password".
MySQL 4.1+ servers are able to handle both login algorithms. Which one is used is independent from the old-passwords variable. If MySQL finds a 41 character long hash starting with * it uses the new system. And the PASSWORD() function is also able to use both algorithms. If the field mysql.user.Password is wide enough to store 41 characters and the old-passwords variable is 0 it will create a "new" password.
The documention for old_passwords says
Variable Scope Both
so you might be able to change it for your session.Connect to the MySQL server (with a client that is able to do so despite the global old_passwords=1), e.g. HeidiSQL and try the following:
If it prints
1, 0, 41
(meaning the global old_passwords is on, but for the session it's off and PASSWORD() returned a "new" password) you should be able to set a new password using the new algorithm for your account within the same session.But if dreamhost really wants to disable the new passwords algorithm the mysql.user.Password field will be less than 41 characters long and there's nothing you can do about it (except nagging them).
我刚刚遇到了这个问题,并且能够解决它。
首先,使用不介意 old_passwords 的旧客户端连接到 MySQL 数据库。使用您的脚本将使用的用户进行连接。
运行这些查询:
在 PHP 脚本中,更改 mysql_connect 函数以包含客户端标志 1:
这使我能够成功连接。
I just had this issue, and was able to work around it.
First, connect to the MySQL database with an older client that doesn't mind old_passwords. Connect using the user that your script will be using.
Run these queries:
In your PHP script, change your mysql_connect function to include the client flag 1:
This allowed me to connect successfully.
是的,这看起来像个硬汉。如果没有主机的合作或无法更改密码格式或客户端库,您就没有很多选择。
老实说,我的第一选择是放弃 Dreamhost。这可能需要大量工作,但如果他们要继续使用旧的不兼容的东西,那么问题仍然会存在。
如果这不是一个选择,那么联合自动化流程怎么样?您可以将 Slicehost 端的数据导出到 CSV 文件中,并将其转换为 Dreamhost 所需的任何格式,然后将其上传到 Dreamhost 服务器。您可以在 Dreamhost 服务器上设置一个 cron 脚本,定期检查上传的文件并对其进行处理(确保在成功处理后将其移动或删除)。
Yeah, that looks like a toughie. Without cooperation from your hosts or the ability to change password formats or client libraries, you don't have a lot of options.
Honestly, my first choice would be to ditch Dreamhost. That's probably a lot of work, but if they're going to be stuck using old incompatible stuff, it will continue to be problematic.
If that's not an option, what about a joint automated process? You could export the data on the Slicehost side into a CSV file and massage it into whatever format is necessary for Dreamhost, and then upload it to the Dreamhost server. You could have a cron script on the Dreamhost server check periodically for the uploaded file and process it (making sure to move or delete it after it was successfully processed).
我将通过使用 SELECT ... INTO OUTFILE 将数据转储到 Slicehost 来解决此问题。
这允许您设计查询以确保输出的格式与目标站点的表结构匹配。
然后将转储文件传输到 Dreamhost 并使用
LOAD DATA INFILE
。顺便说一句,Dreamhost 真的还在使用 MySQL 4.0 吗?它们已经非常过时了——甚至 MySQL 4.1 的扩展支持也本月到期 (2009 年 12 月)。
I would solve this by dumping the data at Slicehost, using
SELECT ... INTO OUTFILE
.This allows you to design your query to make sure the output is in the format matching the table structure at the destination site.
Then transfer the dump file to Dreamhost and use
LOAD DATA INFILE
.As an aside, Dreamhost is really still using MySQL 4.0? They're extremely outdated -- even MySQL 4.1's extended support is expiring this month (December 2009).
我认为你应该从 slicehost 制作 WebServices/RPC 并在上面编写相应的服务来处理它。
I think you should make WebServices/RPC from slicehost and write the corresponding service on the to handle it.
我有同样的问题。为了解决这个问题,我做了以下操作:
I had the same issue. To solve it, I did the following: