在 mysql 中,删除/添加用户时出现奇怪的结果
有一个安全例程,从一组用户名、密码和权限中
- 删除一个用户
- 创建(相同)用户
- 授予对表、过程等的访问权限
// $users - Array of user records // $tables - list of tables from `show tables` // create users as necessary, reset password foreach( $users as $user=>$arr ) { mysql_query( "drop user {$arr['user']}" ); mysql_query( "create user {$arr['user']} identified by '{$arr['pwd']}'" ); }; // for each user set permission foreach( $users as $user=>$arr ) { if( @$arr['table_grant'] ) foreach( $tables as $table ) mysql_query( "grant {$arr['table_grant']} on $table to {$arr['user']}" ); if( @$arr['tables_revoke'] ) foreach( $arr['tables_revoke'] as $table ) mysql_query( "revoke {$arr['table_grant']} on $table from {$arr['user']}" ); if( @$arr['procedures_grant'] ) foreach( $arr['procedures_grant'] as $proc mysql_query( "grant execute on procedure $proc to {$arr['user']}" ); if( @$arr['functions_grant'] ) foreach( $arr['functions_grant'] as $func ) mysql_query( "grant execute on function $func to {$arr['user']}" ); }
如果不存在用户,则它可以正常工作。
如果用户已存在,则该用户存在,但除最后创建的用户外的所有用户都没有密码。
mysql> select user, password from mysql.user where user like 'm%'; +------------+-------------------------------------------+ | user | password | +------------+-------------------------------------------+ | massage150 | *21A196706D99436A1C8163A98AE0687C432C37E2 | | mlogin | *DE069F0ED7E311D173CB01C3DD136D282E66048D | | mselect | | | mdml | | +------------+-------------------------------------------+ 4 rows in set (0.00 sec)
使用用户和权限时,是否需要在 MySQL 中运行某种同步进程?我需要删除它们,等待几秒钟,然后重新创建吗?或者什么?
(代码在 postgreSQL 和 Oracle 中运行良好。针对 MySQL 对 GRANT 和 REVOKE 的限制进行了一些修改,即 GRANT 是在逐个表的基础上进行的(而不是在 SCHEMA 范围内),因此随后发出的 REVOKE 可以正常工作。)
KLUDGE 解决方案
为用户设置 GRANT 和 REVOKE 后,再次通过用户和SET PASSWORD
。丑陋,但它有效。
仍在寻求更好地了解正在发生的事情。
正确的 KLUDGE 解决方案
根据下面的答案(谢谢!)MySQL 有一个非 ANSI 命令 FLUSH PRIVILEGES。在 DROP USER 之后和 CREATE USER 之前发出此命令,并且 MySQL 不再删除用户密码。
have a security routine that, from an array of user names, passwords and permissions
- drops a user
- creates the (same) user
- grants access to tables, procedures, etc
// $users - Array of user records // $tables - list of tables from `show tables` // create users as necessary, reset password foreach( $users as $user=>$arr ) { mysql_query( "drop user {$arr['user']}" ); mysql_query( "create user {$arr['user']} identified by '{$arr['pwd']}'" ); }; // for each user set permission foreach( $users as $user=>$arr ) { if( @$arr['table_grant'] ) foreach( $tables as $table ) mysql_query( "grant {$arr['table_grant']} on $table to {$arr['user']}" ); if( @$arr['tables_revoke'] ) foreach( $arr['tables_revoke'] as $table ) mysql_query( "revoke {$arr['table_grant']} on $table from {$arr['user']}" ); if( @$arr['procedures_grant'] ) foreach( $arr['procedures_grant'] as $proc mysql_query( "grant execute on procedure $proc to {$arr['user']}" ); if( @$arr['functions_grant'] ) foreach( $arr['functions_grant'] as $func ) mysql_query( "grant execute on function $func to {$arr['user']}" ); }
If no users exist, it works fine.
If users already exist, the user is there, but without the password for all but the last user created.
mysql> select user, password from mysql.user where user like 'm%'; +------------+-------------------------------------------+ | user | password | +------------+-------------------------------------------+ | massage150 | *21A196706D99436A1C8163A98AE0687C432C37E2 | | mlogin | *DE069F0ED7E311D173CB01C3DD136D282E66048D | | mselect | | | mdml | | +------------+-------------------------------------------+ 4 rows in set (0.00 sec)
Is there some sort of sync
process that needs to be run in MySQL
when working with users and permission? Do I need to delete them, wait a few seconds, and recreate? Or what?
(Code works fine in postgreSQL and Oracle. Some modifications were made for MySQL's limitations with GRANT and REVOKE, viz, GRANT was made on a table by table basis (instead of SCHEMA wide) so the subsequently issued REVOKE would work correctly.)
KLUDGE Solution
After setting GRANTs and REVOKEs for users, make one more pass through the users and SET PASSWORD
. Ugly, but it works.
Still looking for better understanding of what's going on.
Correct KLUDGE Solution
As per answer below (thanks!) MySQL has a non-ANSI command FLUSH PRIVILEGES. Issued this after DROP USER and before CREATE USER and MySQL no longer dropped user password.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
尝试在 CREATE USER 语句之后执行 FLUSH PRIVILEGES。根据文档:
值得一试。我注意到,如果不运行此命令,对用户表的更新不会直接生效。
Try executing a FLUSH PRIVILEGES after the CREATE USER statements. Per the docs:
Worth a shot. I've noticed updates to the users table does not directly take effect without running this command.