1

我创建了一个用户并授予“创建用户”权限。我发现用户可以删除任何其他用户,包括 root。我怎样才能防止这种情况发生?

实际上,我们正在实现 Mysql as a Service,就像 AWS 的 RDS 一样。我们将创建一个超级用户,供系统管理使用。我们的客户将拥有另一个拥有大部分权限的用户,包括“CREATE USER”,这样他们就可以自己管理帐户。我想找到一种除 Mysql 普通权限之外的方法来获得它

如果您有 AWS RDS,您会发现 RDS 有一个“rdsadmin”用户帐户。如果你运行 DROP USER 'rdsadmin'@'localhost' 你会得到一个错误:ERROR 1396 (HY000): Operation DROP USER failed for 'rdsadmin'@'localhost'。我很好奇如何实现它。

我尝试在 mysq.user 表上添加触发器以在用户从表中删除“rdsadmin”时引发错误。但触发器仅适用于DELETE FROM USER ...sql 不适用于DROP USER. 你知道原因吗,或者有什么办法可以解决吗?

4

3 回答 3

1

无法向指定用户授予权限,CREATE USER 是全局权限。

例如,我建议您将 MySQL 用户分开 - 其中可能有一些:用于管理(具有 root 权限),用于开发人员(访问和更改数据库对象和表数据),等等......

于 2015-08-21T11:20:24.493 回答
1

您可以通过创建数据库 API 来解决此问题。SQL 代码应该可以帮助您。

CREATE TABLE mysql.`created_users` (
  `user_name` varchar(255) DEFAULT NULL,
  `owner` varchar(255) DEFAULT NULL
)

该表包含用户名以及创建它们的用户。 注意使用您的 root 帐户创建程序

创建 mysql 用户的过程。

DROP PROCEDURE IF EXISTS mysql.createUser;

DELIMITER //
CREATE PROCEDURE mysql.createUser(IN userName VARCHAR(255), IN userPassword VARCHAR(255))
 BEGIN

  SET @createUserQuery = CONCAT('
        CREATE USER "',userName,'"@"localhost" IDENTIFIED BY "',userPassword,'" '
        );
  PREPARE stmt FROM @createUserQuery;
  EXECUTE stmt;
  DEALLOCATE PREPARE stmt;


  SET @createcreatedUserQuery = CONCAT('
        INSERT INTO mysql.created_users (user_name, owner) VALUE("',userName,'", "',USER(),'")'
        );
  PREPARE stmt FROM @createcreatedUserQuery;
  EXECUTE stmt;
  DEALLOCATE PREPARE stmt;

 END //
DELIMITER ;

删除程序并检查 created_users 表以确保用户存在并删除权限检查。

DROP PROCEDURE IF EXISTS mysql.dropUser;

DELIMITER //
CREATE PROCEDURE mysql.dropUser(IN userName VARCHAR(255))
 BEGIN  

  SET @canDeleteUser = 0;   

  SET @createCountUserQuery = CONCAT('
        SELECT COUNT(*) FROM mysql.created_users WHERE user_name = "',userName,'" AND owner = "',USER(),'" INTO @canDeleteUser'
        );

  PREPARE stmt FROM @createCountUserQuery;
  EXECUTE stmt;
  DEALLOCATE PREPARE stmt;  

  IF @canDeleteUser = 0 THEN

      SIGNAL SQLSTATE '45000'
      SET MESSAGE_TEXT = 'The user is not known on the server or you dont have rights to delete this user';
  END IF;

  IF @canDeleteUser = 1 THEN
      SET @createDropUserQuery = CONCAT('
        DROP USER "',userName,'"@"localhost"'
        );
      PREPARE stmt FROM @createDropUserQuery;
      EXECUTE stmt;
      DEALLOCATE PREPARE stmt;

      SET @createDeleteUserQuery = CONCAT('
        DELETE FROM created_users WHERE user_name = "',userName,'" AND owner = "',USER(),'"'
        );
      PREPARE stmt FROM @createDeleteUserQuery;
      EXECUTE stmt;
      DEALLOCATE PREPARE stmt;    
  END IF;

 END //
DELIMITER ;

并赋予执行这些的权利

GRANT EXECUTE ON PROCEDURE mysql.createUser TO '[user]'@'localhost';
GRANT EXECUTE ON PROCEDURE mysql.dropUser TO '[user]'@'localhost';

您可能希望在 mysql.proc 上为用户提供 select priv,以便他们可以看到程序背后的源代码并了解参数

您可以像这样使用数据库 API。

CALL mysql.createUser('user', 'password');
CALL mysql.dropUser('user');

请注意,root 帐户只能删除具有所有者 root@localhost 的 mysql.dropUser 用户

于 2015-08-21T14:02:22.770 回答
0

正如 Devart 所说,您无法更改 CREATE USER 的权限。

但是,看起来您正在做的是将 mysql 实例配置给用户以自行控制。为此,服务器管理工​​具怎么样。那里有很多,包括 froxlor 服务器管理工​​作室(它是免费和开源的):https ://www.froxlor.org/

这只是一个想法。

于 2015-08-21T14:09:08.920 回答