web-dev-qa-db-ja.com

MySQLは1つのテーブルを除くすべての権限をデータベースに付与します

私は以下を達成するための合理的な解決策を見つけることができませんでした:

データベース(または同じスキーマを持つ一連のデータベース)に対するすべての権限を持つユーザー、つまり、SELECT権限のみを持つ1つのテーブルに対してexceptが必要です。

基本的に、ユーザーがデータベースを自由に統治できるようにしたいが、特定のテーブルを更新できないようにしたい。

これまでのところ、役に立たなかった:

  • そのデータベース(db_name。*)に対するすべての特権を付与し、次に、目的のテーブルに対する選択特権のみを明確に付与します( "all"が上書きされることを願っています)。

  • そのデータベース(db_name。*)に対するすべての特権を付与し、挿入、更新、および削除を取り消します。しかし、これにより、db_name.table_nameの付与ルールがないというエラーが発生しました。

収集できたことから、読み取り専用テーブルを除く、データベースの各テーブルに対するすべての権限を個別に付与する必要があります。

誰かがもっと簡単な方法があると教えてください

:MySQL 5.1を実行しています。 Ubuntu 10.04で利用可能な最新版。

28
xzyfer

これは古い投稿であることは知っていますが、@ tdammersの質問に追加して他の人に見てもらえると思いました。 information_schema.tablesでSELECT CONCATを実行して、grantコマンドを作成することもできます。別のスクリプトを記述する必要はありません。

まず、そのdbからすべての特権を取り消します。

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クライアントに貼り付け、すべて実行します。

32
Carlos

AFAIK、はい、テーブルごとに個別に付与する必要があります。しかし、ちょっと、あなたはそこにコンピュータを持っています。コンピューターは反復的なタスクの自動化に優れているので、次のようなスクリプトを作成してみませんか。

  1. データベース内のすべてのテーブルのリストを取得します(SHOW TABLES;
  2. リストの項目ごとに、すべての権限を付与します
  3. 特別なテーブルの権限を取り消す

または、代わりに:2.リストの各項目について、それが特別な表であるかどうかを確認します。 notの場合、すべての権限を付与します

私がコードを提供していない理由は、MySQL機能を備えた任意のスクリプト言語で実行でき、シェルスクリプトでも実行できるためです。最も使いやすいものを使用してください。

7
tdammers

以下は、MariaDBでロールを付与するために使用するもののドラフトです。多分イベントを設定することはそれをよりクールにするでしょう:-)

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;
1
Igor

残念ながら、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/

https://youtu.be/8fWQbtIISdc

0
user628176