为除了一个/几个表以外的所有表格授予[几乎]所有mySQL权限

时间:2021-08-13 08:49:44

Question:

How can I give a new user almost all privileges, but still keep one or more tables/databases protected from them.

如何为新用户提供几乎所有权限,但仍保留一个或多个表/数据库以保护它们。

Details:

If I have one database,

如果我有一个数据库,

  • life

And three tables

三张桌子

  • passwords
  • friends
  • hobbies

How do I give this user, for example, the following privileges:

如何为此用户提供以下权限:

  • INSERT
  • UPDATE
  • DELETE
  • CREATE
  • DROP
  • ALTER

With respect to the first three, I would start with something like so:

关于前三个,我会从这样的事情开始:

GRANT INSERT, UPDATE, DELETE ON life.friends TO username@'localhost' IDENTIFIED BY 'password';
GRANT INSERT, UPDATE, DELETE ON life.hobbies TO username@'localhost' IDENTIFIED BY 'password';

But I am confused as to how to use CREATE and DROP. If I grant drop privileges on the whole database like so:

但我对如何使用CREATE和DROP感到困惑。如果我在整个数据库上授予drop权限,如下所示:

GRANT DROP ON life TO username@'localhost' IDENTIFIED BY 'password';

Then the user can drop the passwords table, which I do not want. I could instead grant it based on tables like so:

然后用户可以删除我不想要的密码表。我可以根据这样的表格来授予它:

GRANT DROP ON life.friends TO username@'localhost' IDENTIFIED BY 'password';
GRANT DROP ON life.hobbies TO username@'localhost' IDENTIFIED BY 'password';

But then what happens if I grant CREATE privileges like so:

但是如果我像这样授予CREATE权限会发生什么:

GRANT CREATE ON life TO username@'localhost' IDENTIFIED BY 'password';

Does that mean that the user can not even delete the very tables he/she creates? My question also relates to creating/dropping databases. What if I want to allow the user to create and drop as many of their own databases, but not the life database?

这是否意味着用户甚至无法删除他/她创建的表格?我的问题还涉及创建/删除数据库。如果我想允许用户创建和删除尽可能多的数据库而不是生命数据库,该怎么办?

Should I instead change my approach by moving the passwords table into another database?

我应该通过将密码表移动到另一个数据库来改变我的方法吗?

Thank you in advanced.

先谢谢你。

1 个解决方案

#1


2  

An alternative to @TheScrumMeister's suggestion of using separate databases would be to define a procedure that wraps CREATE TABLE, but also grants the invoking user the DROP permission on it:

@ TheScrumMeister建议使用单独的数据库的另一种方法是定义一个包装CREATE TABLE的过程,但也授予调用用户DROP权限:

DELIMITER ;;

CREATE PROCEDURE create_table(
  tbl_name VARCHAR(64) -- maximum length of a table name
) BEGIN
  DECLARE EXIT HANDLER FOR SQLEXCEPTION ROLLBACK;
  START TRANSACTION;
    SET @usr = SUBSTRING_INDEX(USER(), '@', 1);  -- invoking username
    SET @tbl = REPLACE(tbl_name, "`", "``");     -- prevent SQL injection

    -- just create some dummy table initially - the user can modify it after
    SET @qry = CONCAT("
      CREATE TABLE `", @tbl, "` (
        id INT NOT NULL AUTO_INCREMENT PRIMARY KEY
      );
    ");
    PREPARE stmt FROM  @qry;
    EXECUTE stmt;
    DEALLOCATE PREPARE stmt;

    -- now grant DROP to the invoking user but only from localhost
    SET @qry = CONCAT("
      GRANT DROP ON life.`", @tbl, "`
      TO CONCAT(?, \"@'localhost'\") IDENTIFIED BY 'password';
    ");
    PREPARE stmt FROM  @qry;
    EXECUTE stmt USING @usr;
    DEALLOCATE PREPARE stmt;

    -- clean up
    SET @qry = NULL;
    SET @usr = NULL;
  COMMIT;
END;;

DELIMITER ;

To be certain that the user doesn't create tables any other way, they should not have the CREATE TABLE privilege.

要确保用户不以任何其他方式创建表,它们不应具有CREATE TABLE特权。

You could do something similar for databases too.

您也可以为数据库执行类似的操作。

#1


2  

An alternative to @TheScrumMeister's suggestion of using separate databases would be to define a procedure that wraps CREATE TABLE, but also grants the invoking user the DROP permission on it:

@ TheScrumMeister建议使用单独的数据库的另一种方法是定义一个包装CREATE TABLE的过程,但也授予调用用户DROP权限:

DELIMITER ;;

CREATE PROCEDURE create_table(
  tbl_name VARCHAR(64) -- maximum length of a table name
) BEGIN
  DECLARE EXIT HANDLER FOR SQLEXCEPTION ROLLBACK;
  START TRANSACTION;
    SET @usr = SUBSTRING_INDEX(USER(), '@', 1);  -- invoking username
    SET @tbl = REPLACE(tbl_name, "`", "``");     -- prevent SQL injection

    -- just create some dummy table initially - the user can modify it after
    SET @qry = CONCAT("
      CREATE TABLE `", @tbl, "` (
        id INT NOT NULL AUTO_INCREMENT PRIMARY KEY
      );
    ");
    PREPARE stmt FROM  @qry;
    EXECUTE stmt;
    DEALLOCATE PREPARE stmt;

    -- now grant DROP to the invoking user but only from localhost
    SET @qry = CONCAT("
      GRANT DROP ON life.`", @tbl, "`
      TO CONCAT(?, \"@'localhost'\") IDENTIFIED BY 'password';
    ");
    PREPARE stmt FROM  @qry;
    EXECUTE stmt USING @usr;
    DEALLOCATE PREPARE stmt;

    -- clean up
    SET @qry = NULL;
    SET @usr = NULL;
  COMMIT;
END;;

DELIMITER ;

To be certain that the user doesn't create tables any other way, they should not have the CREATE TABLE privilege.

要确保用户不以任何其他方式创建表,它们不应具有CREATE TABLE特权。

You could do something similar for databases too.

您也可以为数据库执行类似的操作。