MySQL“命令拒绝用户表”错误和用户权限

时间:2015-07-06 19:26:40

标签: mysql case-sensitive bitnami

当我运行以下命令时:

SELECT p.*,
   (SELECT i.image
    FROM pimage i
    WHERE p.id = i.pid 
    ORDER BY i.id ASC
    LIMIT 1
   ) as image
FROM  products p
WHERE p.categories LIKE '%$subCatId%'
ORDER BY p.id ASC

在包含以下表格的数据库中:

pImage
products
sidebar
specs

我收到错误:

  

#1142 - 对表'pimage'的用户'database_user'@'localhost'拒绝SELECT命令

不幸的是,我今天下午在我的制作网站上以纯文本打印了十几次。

我在网站的本地版本发布之前测试了它,它运行得很好。我很快恢复了变更,并在开发网站上进行了测试。当存储在PHP代码中时,它在开发服务器上运行得很好。我还在开发服务器的phpMyAdmin界面上测试了它,它运行正常。我登录到生产网站的phpMyAdmin界面,然后在那里运行查询,但失败了同样的错误。我单独在每个表上运行查询,并且它们没有错误地运行。

是什么给了什么?!?

制作网站已经过时了。它正在运行FreeBSD 6.4(是的,EOL是2010年11月30日......)和MySQL 5.1(是的,EOL是2013年12月31日......)。我正在努力从共享主机移动它,所以我可以更新它。开发服务器是当前的Bitnami LAMP堆栈虚拟机,运行Ubuntu 14.04和MySQL 5.5。到目前为止,我没有兼容性问题。据我所知,查询不使用两个版本之间不同的任何语法或特殊功能。

1 个答案:

答案 0 :(得分:0)

我以管理用户身份登录数据库,并返回错误:

  

#1146 - 表'company.pimage'不存在   

可以快速解决原始问题:pimagepImage之间的愚蠢案例错误。

区分大小写

之前未检测到此错误,因为Bitnami设备更改了默认值以使其表名不区分大小写,并且因为MySQL中非管理员用户的错误消息不会泄漏信息。

MySQL文档,section 9.2.2 "Identifier Case Sensitivity"读取:

  

默认情况下,表别名在Unix上区分大小写

但这可以通过lower_case_table_names系统变量进行更改。

  

如果设置为0,表名将按指定的方式存储,并且比较区分大小写。如果设置为1,则表名称以小写形式存储在磁盘上,并且比较不区分大小写。如果设置为2,则表名存储为给定但以小写字母比较...
  在Unix上,lower_case_table_names的默认值为0.在Windows上,默认值为1.在OS X上,默认值为2.

在我的开发服务器上,SHOW VARIABLES演示了Bitnami设备将此值设置为1. mysqld --verbose --help表示已编译的默认值将此值设置为零,但是as described on the bitnami forums/opt/bitnami/mysql/scripts/ctl.sh设置--lower-case-table-names=1

隐秘错误消息

非管理员用户的错误消息很神秘:

  

#1142 - 对表'mispelled_table'的用户'user @ localhost'拒绝SELECT命令

但管理员用户的错误消息:

  

#1146 - 表'company.mispelled_table'不存在

很容易理解。管理员用户具有SHOW GRANTS FOR CURRENT_USER权限:

GRANT USAGE ON *.* TO 'admin_user'@'%' IDENTIFIED BY PASSWORD [redacted]
GRANT ALL PRIVILEGES ON `company`.* TO 'admin_user'@'%' WITH GRANT OPTION

但普通用户具有以下权限:

GRANT USAGE ON *.* TO 'user'@'localhost' IDENTIFIED BY PASSWORD [redacted]
GRANT SELECT ON `schap`.`pImage` TO 'user'@'localhost'
GRANT SELECT, SELECT (view_count), UPDATE (view_count) ON `company`.`products` TO 'user'@'localhost'
...etc.

最后一点只是猜想,因为我没有必要的权限来更改和测试它,但我认为SHOW_DATABASES privilege会给用户提供良好的错误消息。避免列出所有数据库名称可能是一个很好的策略,因为它可以防止黑客很容易地确定哪些表存在,但肯定会造成很多混乱!