在 mysql 中,删除/添加用户时出现奇怪的结果

发布于 2024-12-08 19:07:16 字数 2242 浏览 0 评论 0原文

有一个安全例程,从一组用户名、密码和权限中

  • 删除一个用户
  • 创建(相同)用户
  • 授予对表、过程等的访问权限
// $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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

挽清梦 2024-12-15 19:07:16

尝试在 CREATE USER 语句之后执行 FLUSH PRIVILEGES。根据文档:

作为 GRANT 的结果,服务器将信息缓存在内存中
创建用户语句。该内存未被释放
相应的 REVOKE 和 DROP USER 语句,因此对于服务器
执行导致缓存的语句的许多实例,有
将会增加内存的使用。该缓存内存可以被释放
具有同花顺特权。

值得一试。我注意到,如果不运行此命令,对用户表的更新不会直接生效。

Try executing a FLUSH PRIVILEGES after the CREATE USER statements. Per the docs:

The server caches information in memory as a result of GRANT and
CREATE USER statements. This memory is not released by the
corresponding REVOKE and DROP USER statements, so for a server that
executes many instances of the statements that cause caching, there
will be an increase in memory use. This cached memory can be freed
with FLUSH PRIVILEGES.

Worth a shot. I've noticed updates to the users table does not directly take effect without running this command.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文