MySQL предоставляет все права доступа к базе данных, кроме одной таблицы - PullRequest
24 голосов
/ 09 июня 2011

Мне не удалось найти разумное решение для достижения следующих целей:

Я хочу, чтобы у пользователя был ВСЕ привилегии для базы данных (или серии баз данных с одинаковой схемой), за исключением для одной таблицы, к которой у него будут только привилегии SELECT.

По сути, я хочу, чтобы пользователь мог свободно управлять базой данных, но не мог обновлять определенную таблицу.

Пока что пробовал, безрезультатно:

  • Предоставление всех привилегий в этой базе данных (db_name. *), А затем, в частности, предоставление только привилегий выбора для этой желаемой таблицы (надеюсь, что это перезапишет «all», глупо, я знаю).

  • Предоставление всех привилегий в этой базе данных (db_name. *) С отменой вставки, обновления и удаления. Но это привело к ошибке, сообщившей, что для db_name.table_name не было правила предоставления.

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

Пожалуйста, кто-нибудь, скажите мне, что есть более простой способ

Примечание : я использую MySQL 5.1. Последняя версия доступна в Ubuntu 10.04.

Ответы [ 4 ]

29 голосов
/ 29 мая 2013

Я знаю, что это старая публикация, но я решил добавить вопрос @tdammers, чтобы другие могли его увидеть.Вы также можете выполнить SELECT CONCAT для information_schema.tables, чтобы создать команды предоставления, и вам не нужно писать отдельный скрипт.

Сначала отзовите все привилегии из этой базы данных:

REVOKE ALL PRIVILEGES ON db.* FROM user@localhost;  

Затемсоздайте свои операторы GRANT:

SELECT CONCAT("GRANT UPDATE ON db.", table_name, " TO user@localhost;")
FROM information_schema.TABLES
WHERE table_schema = "YourDB" AND table_name <> "table_to_skip";

Скопируйте и вставьте результаты в свой клиент MySQL и запустите их все.

6 голосов
/ 09 июня 2011

AFAIK, да, вам нужно предоставить индивидуально для каждой таблицы. Но эй, у тебя там есть компьютер. Компьютеры отлично подходят для автоматизации повторяющихся задач, поэтому почему бы вам не создать сценарий, который выполняет следующие действия:

  1. Получить список всех таблиц в базе данных (SHOW TABLES;)
  2. Для каждого элемента в списке предоставьте все разрешения
  3. Отзыв разрешений на специальной таблице

Или, альтернативно: 2. Для каждого элемента в списке проверьте, является ли он специальной таблицей; если это не , предоставьте все разрешения

Причина, по которой я не даю код, заключается в том, что он может быть выполнен на любом языке сценариев с использованием средств MySQL, даже сценария оболочки; используйте то, что вам удобнее всего.

1 голос
/ 05 марта 2016

Вот черновик того, что я использую для предоставления ролей в MariaDB.Может быть, установка EVENT сделает его более крутым: -)

DELIMITER $$

DROP PROCEDURE IF EXISTS refreshRoles $$
CREATE PROCEDURE refreshRoles ()
  COMMENT 'Grant SELECT on new databases/tables, revoke on deleted'
BEGIN
  DECLARE done BOOL;
  DECLARE db VARCHAR(128);
  DECLARE tb VARCHAR(128);
  DECLARE rl VARCHAR(128);
  DECLARE tables CURSOR FOR
    SELECT table_schema, table_name, '_bob_live_sg' FROM information_schema.tables
    WHERE table_schema LIKE '%bob\_live\_sg' AND
      (  false
      OR table_name LIKE 'bundle%'
      OR table_name LIKE 'cart%'
      OR table_name LIKE 'catalog%'
      OR table_name LIKE 'url%'
      );

  DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done=true;

  CREATE ROLE IF NOT EXISTS '_bob_live_sg';
  REVOKE ALL, GRANT OPTION FROM '_bob_live_sg';

  OPEN tables;
  SET done = false;
  grant_loop: LOOP
    FETCH tables INTO db, tb, rl;
    IF done THEN
      LEAVE grant_loop;
    END IF;
    SET @g = CONCAT('GRANT SELECT ON `', db, '`.`', tb, '` TO ', rl);
    PREPARE g FROM @g;
    EXECUTE g;
    DEALLOCATE PREPARE g;
  END LOOP;
  CLOSE tables;
END $$

DELIMITER ;

CALL refreshRoles;
0 голосов
/ 22 ноября 2018

К сожалению, в MySQL есть встроенные естественные способы для выполнения выборочных / исключительных задач.

Вы можете использовать приведенный ниже скрипт (скрипт командной консоли Linux)

#!/bin/bash

# Define the database and root authorization details
db_host='localhost'
db_name='adhoctuts'
db_user='root'
db_pass='Adhoctuts2018#'

# Define the query to get the needed tables
table_list=$(mysql -h $db_host -u $db_user -p"$db_pass" -se "select concat(table_schema,'.',table_name) from information_schema.tables where table_schema='$db_name' and table_name not like 'tbl1' AND table_name not like '\_\_%';" $db_name | cut -f1)

# Convert the query result into the array
table_arr=(${table_list//,/ })

# Declare the associative array of the users as username=>password pair
# e.g: declare -A user_list=(["'user1'"]="pass1" ["'user2'"]="pass2")
# In our case there is a single user
declare -A user_list=(["'aht_r'@'localhost'"]="Adhoctuts2018#")
for user in "${!user_list[@]}"
do
    pass=${user_list[$user]}
    # Recreate user
    mysql -h $db_host -u $db_user -p"$db_pass" -se "drop user if exists $user; create user $user identified by '$pass';"

    # Provide SELECT privilege
    mysql -h $db_host -u $db_user -p"$db_pass" -se "revoke all privileges, grant option from $user;" $db_name
    mysql -h $db_host -u $db_user -p"$db_pass" -se "grant usage on $db_name.* TO $user;" $db_name
    for tbl in "${table_arr[@]}"; do
        echo "grant select on $tbl TO $user"
        mysql -h $db_host -u $db_user -p"$db_pass" -se "grant select on $tbl TO $user;" $db_name    
    done
done

Если у вас есть консоль Windows, вы можете использовать следующий .bat файл:

@ECHO OFF
%= Define the database and root authorization details =% 
set db_host=192.168.70.138
set db_name=adhoctuts
set db_user=adhoctuts
set db_pass=Adhoctuts2018#

mysql -h %db_host% -u %db_user% -p"%db_pass%" -se "select concat(table_schema,'.',table_name) from information_schema.tables where table_schema='%db_name%' and table_name not like 'tbl1' AND table_name not like '\_\_%%';" %db_name% > tbls

setlocal EnableDelayedExpansion
set user_cnt=2
set user[1]='Adhoctuts1'@'192.168.%%.%%'
set pass[1]=Adhoctuts1_2018#
set user[2]='Adhoctuts2'@'192.168.%%.%%'
set pass[2]=Adhoctuts2_2018#

set i=1
:loop
    set user=!user[%i%]!
    set pass=!pass[%i%]!
    mysql -h %db_host% -u %db_user% -p"%db_pass%" -se "drop user if exists %user% ; create user %user%  identified by '%pass%';"
    mysql -h %db_host% -u %db_user% -p"%db_pass%" -se "revoke all privileges, grant option from %user%;" %db_name%      
    for /F "usebackq delims=" %%a in ("tbls") do (
        mysql -h %db_host% -u %db_user% -p"%db_pass%" -se "grant select on %%a TO %user%;" %db_name%
    )
    if %i% equ %user_cnt% goto :end_loop
    set /a i=%i%+1
goto loop

:end_loop
del /f tbls

Сначала вы пишете запрос, чтобы получить список необходимых таблиц, затем вы определяете список пользователей, для которых вы хотите предоставить доступ. Вы должны выполнять скрипт каждый раз, когда изменяется структура базы данных. Я создал отдельный краткий учебник для отдельных / исключительных задач MySQL.

https://adhoctuts.com/mysql-selective-exceptional-permissions-and-backup-restore/

https://youtu.be/8fWQbtIISdc

...