select into outfile access deny问题

    技术2026-01-15  12

    为应用建立了rnd的帐号,专门为他们查询线上数据库用的,当然,只有他们上了生产网络以后才能连上数据库,安全方面我们还是很注意的,呵呵。授权的语句如下:grant select on armory.* to rnd;flush privileges;

    select查询数据没有问题,但是有的用户有了更多的需求,他想把数据导出来,简单的处理的话,可以用select into outfile导出来。自己指定字段的分隔,行分隔等等。但是用户一查询就报:access deny的错误,权限不对。rnd@localhost : armory 09:26:31> select * into outfile ‘/tmp/1.txt’ from os limit 5;ERROR 1045 (28000): Access denied for user ‘rnd’@'%’ (using password: NO)郁闷的是MySQL没有说缺少了那个权限。

    在本机测试了一下,grant all on armory.* to rnd;flush privileges;给rnd所有的权限以后,还是报权限错误。这个就奇怪了,所有的权限都给它了,还报错?不可理喻阿。实在搞不定,最后让用户:mysql -urnd -p -e ’select * from os limit 5;’ >1.txt的变通方法。

    一直被这个纠结着,突然后来有一天,查询了一下MySQL的文档,找到是file的权限没有加上去,但是当时MySQL对应的库的所有权限我都加上去了阿。灵光一闪,file是全局的权限,在MySQL中对单个库是没有这个权限概念的,所以就算我把库上的所有权限给了rnd,file的权限其实还是没有附权给它的。不信的话,我们这就试试:root@localhost : (none) 09:55:14> grant file on armory.* to rnd;ERROR 1221 (HY000): Incorrect usage of DB GRANT and GLOBAL PRIVILEGES果然,File权限是GLOBAL权限,不能附权给数据库。GLOBAL FILE附权以后root@localhost : mysql 09:58:21> grant file on *.* to rnd;Query OK, 0 rows affected (0.00 sec)select查询就可以执行了:rnd@localhost : armory 10:00:42> select * into outfile ‘/tmp/1.txt’ from os limit 5;Query OK, 5 rows affected (0.00 sec)

    其实MySQL的权限可能比较拗,让我们一下子适应不过来。MySQL的权限可以精细到列,权限判断是根据GLOBAL,DB,TABLE,COLUMN来授权的,可以简单的理解为他们对应到mysql库中的四个表:user,db,tables_priv,columns_priv这几个表。当然,MySQL没有这么简单拉。有兴趣的话可以好好看一下MySQL的reference或者其他介绍。举个例子:rnd@localhost : armory 10:00:43> show grants for rnd;+————————————————-+| Grants for rnd@%                                |+————————————————-+| GRANT FILE ON *.* TO ‘rnd’@'%’                  || GRANT ALL PRIVILEGES ON `armory`.* TO ‘rnd’@'%’ |+————————————————-+2 rows in set (0.00 sec)grant对同一个用户就分了两行,分别对应着user和db里面的两行:root@localhost : mysql 10:18:34> select * from mysql.user where user=’rnd’/G*************************** 1. row ***************************Host: %User: rndPassword:Select_priv: NInsert_priv: NUpdate_priv: NDelete_priv: NCreate_priv: NDrop_priv: NReload_priv: NShutdown_priv: NProcess_priv: NFile_priv: YGrant_priv: NReferences_priv: NIndex_priv: NAlter_priv: NShow_db_priv: NSuper_priv: NCreate_tmp_table_priv: NLock_tables_priv: NExecute_priv: NRepl_slave_priv: NRepl_client_priv: NCreate_view_priv: NShow_view_priv: NCreate_routine_priv: NAlter_routine_priv: NCreate_user_priv: NEvent_priv: NTrigger_priv: Nssl_type:ssl_cipher:x509_issuer:x509_subject:max_questions: 0max_updates: 0max_connections: 0max_user_connections: 01 row in set (0.00 sec)

    root@localhost : mysql 10:18:41> select * from mysql.db where user=’rnd’/G*************************** 1. row ***************************Host: %Db: armoryUser: rndSelect_priv: YInsert_priv: YUpdate_priv: YDelete_priv: YCreate_priv: YDrop_priv: YGrant_priv: NReferences_priv: YIndex_priv: YAlter_priv: YCreate_tmp_table_priv: YLock_tables_priv: YCreate_view_priv: YShow_view_priv: YCreate_routine_priv: YAlter_routine_priv: YExecute_priv: YEvent_priv: YTrigger_priv: Y1 row in set (0.00 sec)MySQL的权限检查也是通过检查这两个表来进行判断的。

    附上tables_priv和columns_priv的两个表的字段,和user和db还是有点不同的,用到了set类型。root@localhost : mysql 10:18:58> desc tables_priv;+————-+———————————————————————————————————————————–+——+—–+——————-+—————————–+| Field       | Type                                                                                                                              | Null | Key | Default           | Extra                       |+————-+———————————————————————————————————————————–+——+—–+——————-+—————————–+| Host        | char(60)                                                                                                                          | NO   | PRI |                   |                             || Db          | char(64)                                                                                                                          | NO   | PRI |                   |                             || User        | char(16)                                                                                                                          | NO   | PRI |                   |                             || Table_name  | char(64)                                                                                                                          | NO   | PRI |                   |                             || Grantor     | char(77)                                                                                                                          | NO   | MUL |                   |                             || Timestamp   | timestamp                                                                                                                         | NO   |     | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP || Table_priv  | set(‘Select’,'Insert’,'Update’,'Delete’,'Create’,'Drop’,'Grant’,'References’,'Index’,'Alter’,'Create View’,'Show view’,'Trigger’) | NO   |     |                   |                             || Column_priv | set(‘Select’,'Insert’,'Update’,'References’)                                                                                      | NO   |     |                   |                             |+————-+———————————————————————————————————————————–+——+—–+——————-+—————————–+8 rows in set (0.00 sec)

    root@localhost : mysql 10:21:24> desc columns_priv;+————-+———————————————-+——+—–+——————-+—————————–+| Field       | Type                                         | Null | Key | Default           | Extra                       |+————-+———————————————-+——+—–+——————-+—————————–+| Host        | char(60)                                     | NO   | PRI |                   |                             || Db          | char(64)                                     | NO   | PRI |                   |                             || User        | char(16)                                     | NO   | PRI |                   |                             || Table_name  | char(64)                                     | NO   | PRI |                   |                             || Column_name | char(64)                                     | NO   | PRI |                   |                             || Timestamp   | timestamp                                    | NO   |     | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP || Column_priv | set(‘Select’,'Insert’,'Update’,'References’) | NO   |     |                   |                             |+————-+———————————————-+——+—–+——————-+—————————–+7 rows in set (0.00 sec)

    may your success.

    最新回复(0)