1. 程式人生 > 資料庫 >Mysql修改儲存過程相關許可權問題

Mysql修改儲存過程相關許可權問題

在使用mysql資料庫經常都會遇到這麼一個問題,其它使用者定義的儲存過程,現在使用另一個使用者卻無法修改或者刪除等;正常情況下儲存過程的定義者對它有修改、刪除的許可權;但是其它的使用者就要相於的授權,不然無法檢視、呼叫;

mysql 中使用使用者A建立一個儲存過程,現在想通過另一個使用者B來修改A建立的儲存過程;以下記錄就是基於這樣的情況產生的;

Mysql修改儲存過程相關許可權問題

使用者A對OTO3庫的許可權:

mysql> show grants for 'a'@'%';
+---------------------------------------------------+
| Grants for a@%               |
+---------------------------------------------------+
| GRANT USAGE ON *.* TO 'a'@'%'        |
| GRANT ALL PRIVILEGES ON `OTO3`.* TO 'a'@'%' |
+---------------------------------------------------+
2 rows in set (0.00 sec)

使用者B的許可權:

mysql> show grants for 'swper'@'%';
+----------------------------------------------------------------------+
| Grants for swper@%                          |
+----------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'swper'@'%'                  |
| GRANT SELECT,UPDATE,DELETE,DROP,ALTER ON `OTO3`.* TO 'swper'@'%' |
+----------------------------------------------------------------------+
2 rows in set (0.00 sec)

以使用者B的身份登陸Mysql操作;

[root@mysql ~]# mysql -h10.0.10.110 -uswper -p123456

查儲存過程列表時就提示沒有許可權了:

mysql> select `name` from mysql.proc where db = 'OTO3' and `type` = 'PROCEDURE';
ERROR 1142 (42000): SELECT command denied to user 'swper'@'mysql' for table 'proc'

以root身份給B使用者新增一個檢視儲存過程的許可權:

mysql> grant select on mysql.proc to 'swper'@'%';
Query OK,0 rows affected (0.00 sec)
 
mysql> show grants for 'swper'@'%';
+----------------------------------------------------------------------+
| Grants for swper@%                          |
+----------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'swper'@'%'                  |
| GRANT SELECT,ALTER ON `OTO3`.* TO 'swper'@'%' |
| GRANT SELECT ON `mysql`.`proc` TO 'swper'@'%'            |
+----------------------------------------------------------------------+
3 rows in set (0.00 sec)

再回到B使用者裡檢視儲存過程列表:

mysql> select `name` from mysql.proc where db = 'OTO3' and `type` = 'PROCEDURE';
+------------------------+
| name          |
+------------------------+
| proc_cs        |
+------------------------+
1 rows in set (0.00 sec)

此時發現多了一個mysql庫,但只有對mysql.proc有查詢許可權:

mysql> show databases;
+--------------------+
| Database      |
+--------------------+
| information_schema |
| OTO3        |
| mysql       |
+--------------------+
3 rows in set (0.00 sec)

mysql庫中只有一個表:proc

mysql> use mysql
mysql> show tables;
+-----------------+
| Tables_in_mysql |
+-----------------+
| proc      |
+-----------------+
1 row in set (0.00 sec)

同樣也可以看到儲存過程的詳細資訊:

mysql> show create procedure proc_cs\G
*************************** 1. row ***************************
      Procedure: proc_cs
      sql_mode: STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
  Create Procedure: CREATE DEFINER=`a`@`%` PROCEDURE `proc_cs`()
BEGIN

嘗試修改儲存過程的配置:

mysql> ALTER PROCEDURE proc_cs  MODIFIES SQL DATA SQL SECURITY INVOKER;
ERROR 1370 (42000): alter routine command denied to user 'b'@'%' for routine 'OTO3.proc_cs'

為了方便檢視在Navicat工具上嘗試修改儲存過程,在儲存的時候報如下許可權問題:

1227 -Access denied;you need(at least one of)the SUPER privilege(s) for this operation

嘗試新增一個儲存過程,報許可權資訊:

1044 - Access denied for user ‘b'@'%' to database ‘OTO3'

這裡表示b使用者沒有對OTO3有授權儲存過程的修改許可權;

以B使用者嘗試呼叫一下儲存過程:

Procedure execution failed
1370 - execute command denied to user ‘b'@'%' for routine ‘OTO3.proc_cs'

這裡很明顯連執行許可權也沒有;

嘗試刪除原有的a使用者定義的儲存過程,也會報許可權資訊,如下:

1370 - alter routine command denied to user ‘b'@'%' for routine ‘OTO3.proc_cs'

可以看出B使用者連呼叫儲存過程的許可權都沒有,這裡先加入執行許可權:

接下來新增一個執行儲存過程的許可權:

mysql> grant execute on OTO3.* to 'b'@'%';
Query OK,0 rows affected (0.00 sec)
 
mysql> show grants for 'b'@'%';
+-------------------------------------------------------------------------------+
| Grants for b@%                              |
+-------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'b'@'%'                       |
| GRANT SELECT,ALTER,EXECUTE ON `OTO3`.* TO 'b'@'%' |
| GRANT SELECT ON `mysql`.`proc` TO 'b'@'%'                 |
+-------------------------------------------------------------------------------+
3 rows in set (0.00 sec)

再次執行一下儲存過程,發現成功了;

時間: 0.080ms
Procedure executed successfully
受影響的行: 0

那再新增一下建立新增儲存過程的許可權:

mysql> grant CREATE ROUTINE on OTO3.* to 'b'@'%';
Query OK,0 rows affected (0.00 sec)
mysql> show grants for 'b'@'%';
+-----------------------------------------------------------------------------------------------+
| Grants for b@%                                      |
+-----------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'b'@'%'                              |
| GRANT SELECT,EXECUTE,CREATE ROUTINE ON `OTO3`.* TO 'b'@'%' |
| GRANT SELECT ON `mysql`.`proc` TO 'b'@'%'                         |
+-----------------------------------------------------------------------------------------------+
3 rows in set (0.00 sec)

上面新增許可權後就可以建立儲存過程了;

CREATE DEFINER=`b`@`%` PROCEDURE `aaaa`()
BEGIN
  #Routine body goes here...
SELECT * from mysql.user;
END

但是自己建立的都無法刪除;

1370 - alter routine command denied to user ‘b'@'%' for routine ‘OTO3.aaaa'

接下來再新增一個修改的許可權,也可以刪除的哦;

mysql> grant alter ROUTINE on OTO3.* to 'b'@'%';
Query OK,0 rows affected (0.01 sec)

檢視使用者許可權

mysql> show grants for 'b'@'%';
+--------------------------------------------------------------------------------------------------------------+
| Grants for b@%                                              |
+--------------------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'b'@'%'                                      |
| GRANT SELECT,CREATE ROUTINE,ALTER ROUTINE ON `OTO3`.* TO 'b'@'%' |
| GRANT SELECT ON `mysql`.`proc` TO 'b'@'%'                                |
+--------------------------------------------------------------------------------------------------------------+
3 rows in set (0.00 sec)

上面新增完alter ROUTINE許可權後就可以對OTO3所有的儲存過程有刪除許可權[自己定義的增、刪、改],別人定義的可以刪除,但是還不能修改;修改別人定義的儲存過程會有如下提示:

1227 - Access denied; you need (at least one of)the SUPER privilege(s) for this operation

這裡說明一下這個SUPER許可權在哪裡?通過檢視使用者許可權原來在這裡:

mysql> select * from mysql.user where user='b'\G
*************************** 1. row ***************************
         Host: %
         User: b
      Select_priv: N
      Insert_priv: N
      Update_priv: N
      Delete_priv: N
      Create_priv: N
       Drop_priv: N
      Reload_priv: N
     Shutdown_priv: N
     Process_priv: N
       File_priv: N
      Grant_priv: N
    References_priv: N
      Index_priv: N
      Alter_priv: N
     Show_db_priv: N
      Super_priv: N
 Create_tmp_table_priv: N
   Lock_tables_priv: N
     Execute_priv: N
    Repl_slave_priv: N
   Repl_client_priv: N
   Create_view_priv: N
    Show_view_priv: N
  Create_routine_priv: N
  Alter_routine_priv: N
   Create_user_priv: N
      Event_priv: N
     Trigger_priv: N
Create_tablespace_priv: N
       ssl_type:
      ssl_cipher:
      x509_issuer:
     x509_subject:
     max_questions: 0
      max_updates: 0
    max_connections: 0
 max_user_connections: 0
        plugin: mysql_native_password
 authentication_string: *CCB4F88E945E0E14F9BEB093EB797BB0BDBFA175
   password_expired: N
 password_last_changed: 2017-03-06 11:37:35
   password_lifetime: NULL
    account_locked: N
1 row in set (0.00 sec)

嘗試新增一下這個SUPER許可權看看:

mysql> grant SUPER on OTO3.* to 'b'@'%';
ERROR 1221 (HY000): Incorrect usage of DB GRANT and GLOBAL PRIVILEGES
 
mysql> grant SUPER on *.* to 'b'@'%';
Query OK,0 rows affected (0.00 sec)

不能對指定的庫執行這個許可權,因為SUPER為全域性的就是整個mysql的許可權;

mysql> show grants for 'swper'@'%';
+--------------------------------------------------------------------------------------------------------------+
| Grants for swper@%                                              |
+--------------------------------------------------------------------------------------------------------------+
| GRANT SUPER ON *.* TO 'swper'@'%'                                      |
| GRANT SELECT,ALTER ROUTINE ON `OTO3`.* TO 'swper'@'%' |
| GRANT SELECT ON `mysql`.`proc` TO 'swper'@'%'                                |
+--------------------------------------------------------------------------------------------------------------+
3 rows in set (0.00 sec)

再次檢查時會發現 Super_priv: Y 變化了;再修改一下別人定義的儲存過程;

mysql> select * from mysql.user where user='b'\G

檢視所有資料庫,發現mysql庫只有一張proc表有讀取的許可權,SUPER並非我所想象中那麼強大;

mysql> show databases;
+--------------------+
| Database      |
+--------------------+
| information_schema |
| OTO3        |
| mysql       |
+--------------------+
3 rows in set (0.00 sec)

仔細觀看會發現執行語句:

mysql> select * from mysql.user where user='b'\G

可以看到有 Create_routine_priv: N和 Alter_routine_priv: N 這兩個明顯就是對儲存過程的許可權嘛,能不能不用SUPER而使用這兩個許可權呢?

回收一下這個SUPER許可權;

mysql> revoke super on *.* from 'b'@'%';
Query OK,0 rows affected (0.01 sec)

再新增Alter_routine_priv,Create_routine_priv

mysql> grant alter routine,create routine on *.* to 'b'@'%';
Query OK,0 rows affected (0.00 sec)

檢視使用者b許可權

mysql> show grants for 'b'@'%';
+--------------------------------------------------------------------------------------------------------------+
| Grants for b@%                                              |
+--------------------------------------------------------------------------------------------------------------+
| GRANT CREATE ROUTINE,ALTER ROUTINE ON *.* TO 'b'@'%'                          |
| GRANT SELECT,ALTER ROUTINE ON `OTO3`.* TO 'b'@'%' |
| GRANT SELECT ON `mysql`.`proc` TO 'b'@'%'                                |
+--------------------------------------------------------------------------------------------------------------+
3 rows in set (0.00 sec)

發現還是報相同的許可權問題:

1227 - Access denied; you need (at least one of)the SUPER privilege(s) for this operation

執行上面許可權後發現,可以看到其它的系統庫:[例如sys庫也有儲存過程,由於這兩個許可權是全域性的]

mysql> show databases;
+--------------------+
| Database      |
+--------------------+
| information_schema |
| OTO3        |
| mysql       |
| performance_schema |
| sys        |
| test        |
+--------------------+
6 rows in set (0.00 sec)

這兩個許可權更大,連繫統庫sys中的儲存過程都能看到,甚至修改刪除,非常危險;決定再次回收許可權

create routine,alter routine;
mysql> revoke create routine,alter routine on *.* from 'b'@'%';

還是使用SUPER許可權比較安全;

通過上面的測試得出以下結論:

  • 檢視儲存過程許可權:SELECT #是對mysql.proc表的許可權;
  • 執行儲存過程許可權:EXECUTE #是對指定資料庫的許可權;
  • 建立儲存過程許可權:CREATE ROUTINE #是對指定資料庫的許可權;
  • 修改儲存過程許可權:ALTER ROUTINE #是對指定資料庫的中自己定義的儲存過程;
  • 修改別人定義的儲存過程許可權:SUPER #是對全域性整個mysql的許可權;

簡來說使用者A在資料庫OTO3中定義了一個儲存過程,現在想用使用者B來執行、修改儲存過程,需要對使用者B新增以下許可權:

GRANT SELECT ON MYSQL.PROC TO 'B';
GRANT EXECUTE,ALTER ROUTINE ON `OTO3`.* TO 'B';
GRANT SUPER ON *.* TO 'B';

所以使用者B的最基本的許可權:

mysql> show grants for 'b'@'%';
+----------------------------------------------------------------------------------------+
| Grants for b@%                                   |
+----------------------------------------------------------------------------------------+
| GRANT SUPER ON *.* TO 'b'@'%'                           |
| GRANT SELECT,ALTER ROUTINE ON `OTO3`.* TO 'b'@'%' |
| GRANT SELECT ON `mysql`.`proc` TO 'b'@'%'                     |
+----------------------------------------------------------------------------------------+
3 rows in set (0.00 sec)

至此,對於Mysql中以另的使用者修改其它人定義的儲存過程許可權也就非常的顯白了;

如果不是以另一個使用者身份呼叫儲存過程,可以使用root許可權修改儲存過程的定義者; 這樣就等於linux裡的所有者許可權變更了;

update mysql.proc set DEFINER='b'@'%' WHERE NAME='proc_cs' AND db='OTO3';

到此這篇關於Mysql修改儲存過程相關許可權問題的文章就介紹到這了,更多相關Mysql 儲存過程許可權內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!