我无法找到合理的解决方案来实现以下目标:
我希望有一个用户拥有数据库(或具有相同架构的一系列数据库)的所有权限,除了一个表,他们只有SELECT权限。
基本上我希望用户可以自由统治数据库但不能更新特定的表。
到目前为止,我已经尝试过,但无济于事:
授予该数据库的所有权限(db_name。*),然后专门授予该所需表的选择权限(希望它会覆盖“全部”,我知道的愚蠢)。
授予该数据库的所有权限(db_name。*),然后撤消插入,更新和删除。但是这产生了一个错误,表明db_name.table_name没有授权规则。
从我能够收集到的内容中,除了只读表外,我必须单独授予数据库每个表的所有权限。
请有人告诉我有一种更简单的方法
注意:我正在运行MySQL 5.1。最新的Ubuntu 10.04。
答案 0 :(得分:28)
我知道这是一篇很老的帖子,但我想我会加入@tdammers的问题让别人看。您还可以在information_schema.tables上执行SELECT CONCAT以创建grant命令,而不必编写单独的脚本。
首先撤销该数据库的所有权限:
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客户端并运行它们。
答案 1 :(得分:6)
AFAIK,是的,您需要为每个表单独授予。但是,嘿,你那里有一台电脑。计算机非常适合为您自动执行重复性任务,因此您为什么不制作执行以下操作的脚本:
SHOW TABLES;
)或者,或者: 2.对于列表中的每个项目,检查它是否是特殊表格;如果不,则授予所有权限
我没有提供代码的原因是它可以使用MySQL工具的任何脚本语言完成,甚至是shell脚本;使用你最喜欢的东西。
答案 2 :(得分:1)
以下是我用于在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;
答案 3 :(得分:0)
不幸的是,MySQL中有内置的自然方法来执行选择性/例外任务。
您可以使用以下脚本(Linux控制台bash脚本)
#!/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/