2014年2月28日金曜日

MySQLで「任意のテーブルのDROPは許可したい」けれど、「スキーマはDROPさせたくない」

MySQL分補充エントリー。

MyNA 15987のメール でそんな話題があっていろいろ考えてネタにしようと思ってたんですが、気が付けばこれ去年の7月じゃないですか。。

やりたいこと。

mysql56> SHOW GRANTS;
+------------------------------------------------+
| Grants for user1@localhost                     |
+------------------------------------------------+
| GRANT USAGE ON *.* TO 'user1'@'localhost'      |
| GRANT DROP ON `user1`.* TO 'user1'@'localhost' |
+------------------------------------------------+
2 rows in set (0.00 sec)
なユーザーに

mysql56> DROP TABLE user1.t1;
Query OK, 0 rows affected (0.07 sec)

は(マニュアルにあるとおり)成功させたいけれど、

mysql56> DROP DATABASE user1;
Query OK, 0 rows affected (0.15 sec)

は(フツーやると成功するところを)失敗させたい。


思い付いたやり方は2つ。

*** sql/sql_db.cc.orig  2014-01-15 00:38:00.000000000 +0900
--- sql/sql_db.cc       2014-02-28 17:13:19.383810416 +0900
***************
*** 44,49 ****
--- 44,51 ----
  #endif
  #include "debug_sync.h"

+ #include "sql_parse.h"    // check_global_access
+
  #define MAX_DROP_TABLE_Q_LEN      1024

  const char *del_exts[]= {".frm", ".BAK", ".TMD", ".opt", ".OLD", NullS};
***************
*** 772,777 ****
--- 774,782 ----

  bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent)
  {
+   if (check_global_access(thd, SUPER_ACL))
+     DBUG_RETURN(0);
+
    ulong deleted_tables= 0;
    bool error= true;
    char        path[2 * FN_REFLEN + 16];

安定の、いつものパターン。

mysql56> DROP TABLE user1.t1;
Query OK, 0 rows affected (0.02 sec)

mysql56> DROP DATABASE user1;
ERROR 1227 (42000): Access denied; you need (at least one of) the SUPER privilege(s) for this operation

書き足したのもシンプルだし、俺にしては珍しく(!)ちゃんとmtrやったので、どこかで使う機会があったら使ってもいいなくらいの出来。というか必要があったら使うわこのパッチ。

あともう1つ、ソースコードをいじることなく出来る汚い手としては、

$ pwd
/usr/mysql/5.6.16/data/user1

$ touch drop_database_prevention

$ ll
合計 112
-rw-rw---- 1 yoku0825 yoku0825    61  2月 28 17:36 2014 db.opt
-rw-rw-r-- 1 yoku0825 yoku0825     0  2月 28 17:43 2014 drop_database_prevention
-rw-rw---- 1 yoku0825 yoku0825  8558  2月 28 17:42 2014 t1.frm
-rw-rw---- 1 yoku0825 yoku0825 98304  2月 28 17:42 2014 t1.ibd

mysql56> DROP TABLE user1.t1;
Query OK, 0 rows affected (0.02 sec)

mysql56> DROP DATABASE user1;
ERROR 1010 (HY000): Error dropping database (can't rmdir './user1/', errno: 17)

$ ll
合計 0
-rw-rw-r-- 1 yoku0825 yoku0825     0  2月 28 17:43 2014 drop_database_prevention

DROP DATABASEがMySQLのテーブルに関するファイルを全部消したあとにrmdirを呼んでいるのを逆手に取った嫌がらせ 小ネタでした。

0 件のコメント :

コメントを投稿