Как ограничить пользователя root от другого пользователя в MySQL?

Я создал пользователя и предоставил привилегии «СОЗДАТЬ ПОЛЬЗОВАТЕЛЯ». Я обнаружил, что пользователь может удалить любого другого пользователя, включая root. Как я могу предотвратить это?

На самом деле мы реализуем Mysql как услугу, точно так же, как RDS AWS. Мы создадим суперпользователя, который будет использоваться для управления системой. У нашего клиента будет другой пользователь, который имеет большинство привилегий, включая «СОЗДАТЬ ПОЛЬЗОВАТЕЛЯ», чтобы они могли сами управлять учетной записью. Я хочу найти подход, отличный от обычных привилегий Mysql, чтобы получить это

Если у вас есть AWS RDS, вы обнаружите, что у RDS есть учетная запись пользователя «rdsadmin». Если вы запустите DROP USER 'rdsadmin'@'localhost', вы получите сообщение об ошибке: ОШИБКА 1396 (HY000): операция DROP USER не удалась для 'rdsadmin'@'localhost'. Мне интересно, как это реализовать.

Я попытался добавить триггер в таблицу mysq.user, чтобы выдавать ошибку, когда пользователь удаляет «rdsadmin» из таблицы. но триггер работает только для DELETE FROM USER ... sql, а не для DROP USER. Вы знаете причину, или есть способ исправить это?


person user3752700    schedule 21.08.2015    source источник
comment
Это может помочь вам. dev.mysql.com/doc/refman/5.1/en/grant. html   -  person adarsh hota    schedule 21.08.2015
comment
Я знаю, что CREATE USER — это глобальная привилегия. На самом деле мы реализуем Mysql как услугу, точно так же, как RDS AWS. Мы создадим суперпользователя, который будет использоваться для управления системой. У нашего клиента будет другой пользователь, который имеет большинство привилегий, включая CREATE USER, чтобы они могли сами управлять учетной записью. Я хочу найти подход, отличный от обычных привилегий Mysql, чтобы получить это.   -  person user3752700    schedule 21.08.2015
comment
Если у вас есть AWS RDS, вы обнаружите, что у RDS есть учетная запись пользователя «rdsadmin». Если вы запустите DROP USER 'rdsadmin'@'localhost', вы получите сообщение об ошибке: ERROR 1396 (HY000): Operation DROP USER failed for 'rdsadmin'@'localhost'. Мне интересно, как это реализовать.   -  person user3752700    schedule 21.08.2015
comment
Возможно, он анализирует запросы для их проверки и выдает ошибку, если команда не разрешена.   -  person Devart    schedule 21.08.2015
comment
Я добавляю триггер в таблицу mysq.user, чтобы выдать ошибку перед удалением «rdsadmin» из таблицы. но триггер работает для DELETE FROM USER ... sql но не для DROP USER. Вы знаете причину, или есть способ исправить это?   -  person user3752700    schedule 22.08.2015
comment
Триггеры не разрешены для таблиц в базе данных mysql. dev.mysql. com/doc/refman/5.7/ru/   -  person Devart    schedule 25.08.2015
comment
Да, Mysql не позволяет запускать базу данных mysql. Но мы можем сделать это нестандартным способом: создать другую обычную базу данных foo, создать таблицу user точно такую ​​же, как база данных mysql. Затем создайте триггер с именем mytrigger в таблице user с помощью CREATE TRIGGER mytrigger ..... Вы можете найти файл mytrigger.TRG в каталоге foo каталога данных mysql. скопируйте файл TRG в каталог mysql. Триггер будет установлен в базу данных mysql после перезапуска Mysql. Проблема в том, что DROP USER ... не запускает триггер.   -  person user3752700    schedule 25.08.2015
comment
Это похоже на хак, я не думаю, что это хороший способ. Я слышал, что можно собрать сервер mysql из исходников, и вы можете изменить его поведение.   -  person Devart    schedule 26.08.2015


Ответы (3)


Невозможно предоставить привилегии указанным пользователям, CREATE USER является глобальной привилегией.

Я бы предложил вам, например, разделить пользователей MySQL - их может быть несколько: для администрирования (с правами суперпользователя), для разработчиков (для доступа и изменения объектов базы данных и данных таблиц) и так далее...

person Devart    schedule 21.08.2015
comment
Да, я знаю, что CREATE USER — это глобальная привилегия. На самом деле мы реализуем Mysql как услугу, точно так же, как RDS AWS. Мы создадим суперпользователя, который будет использоваться для управления системой. У нашего клиента будет другой пользователь, который имеет большинство привилегий, включая CREATE USER, чтобы они могли сами управлять учетной записью. Я хочу найти подход, отличный от обычных привилегий Mysql, чтобы получить это. - person user3752700; 21.08.2015
comment
Возможно, вы можете сделать это в своем приложении, если вы не даете доступ к MySQL для пользователей и управляете сервером только из своих инструментов. - person Devart; 21.08.2015
comment
@ user3752700: Я считаю, что вам следует отредактировать вопрос, включив в него описание сценария, которое вы только что предоставили. И я согласен с предложением Деварта: имеет смысл иметь панель управления пользователями, поэтому вам не нужно предоставлять разрешения CREATE/DROP USER кому-либо еще. - person jweyrich; 21.08.2015

Вы можете использовать этот обходной путь, создав 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';

И вы можете захотеть предоставить пользователю select priv в mysql.proc, чтобы он мог видеть исходный код процедур и знать параметры.

Вы можете использовать API базы данных следующим образом.

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

Обратите внимание, что учетная запись root может удалять только пользователей с mysql.dropUser, у которых есть владелец root@localhost

person Raymond Nijland    schedule 21.08.2015
comment
Спасибо. Это способ. Но я хочу, чтобы мой клиент управлял базой данных с помощью стандартных SQL DROP USER и DROP USER. Если у вас есть AWS RDS, вы обнаружите, что в базе данных есть «rdsadmin». Вы можете создать или удалить любого пользователя. Но если вы запустите DROP USER 'rdsadmin'@'localhost', вы получите ошибку: ERROR 1396 (HY000): Operation DROP USER failed for 'rdsadmin'@'localhost'. Мне интересно, как это реализовать. - person user3752700; 21.08.2015

Как сказал Деварт, вы не можете изменить привилегии CREATE USER.

Однако то, что вы делаете, похоже, предоставляет пользователям экземпляры mysql для самостоятельного контроля. С этой целью как насчет инструмента управления сервером. Их много, включая froxlor Server Management Studio (бесплатную и с открытым исходным кодом): https://www.froxlor.org/

Это просто мысль.

person arcee123    schedule 21.08.2015