非超级用户无法连接,如果服务器在使用dblink时不要求密码。

16

我想在我的应用程序中进行一些跨数据库引用。简而言之,我有两个名为meta和op的数据库。我想从meta数据库中选择查询op数据库中的一个表,如下所示,但是出现以下错误。我尝试了有密码和无密码的方式。顺便说一下,caixa用户是非超级用户,我的目标服务器(op db服务器)采用MD5认证模式。

meta=> select * from dblink('dbname=op password=caixa','SELECT op_col from op_table') AS t(op_col varchar);

错误: 必须输入密码

详细信息: 如果服务器不要求密码,则非超级用户无法连接。

提示: 必须更改目标服务器的身份验证方法。

上述错误消息中的提示意味着什么?我需要更改服务器的身份验证模式吗?如果不更改服务器的身份验证模式(MD5),我是否无法运行上述查询?

6个回答

20

来自文档

只有超级用户可以使用dblink_connect创建非密码身份验证连接。如果非超级用户需要此功能,请改用dblink_connect_u

以及

dblink_connect_u()与dblink_connect()相同,不同之处在于它允许非超级用户使用任何身份验证方法进行连接。

这意味着您的dblink调用隐式地使用dblink_connect。请改为使用dblink_connect_u或更改您的身份验证方法,例如MD5。

请注意,您还需要向caixa角色授予执行权限,例如:

GRANT EXECUTE ON FUNCTION dblink_connect_u(text) TO caixa;
GRANT EXECUTE ON FUNCTION dblink_connect_u(text, text) TO caixa;

示例(在GRANT之后):

meta=> SELECT dblink_connect_u('conn1', 'dbname=op');
meta=> SELECT * FROM dblink('conn1','SELECT op_col from op_table')
            AS t(op_col varchar);
 op_col 
--------
 aaa
 bbb
 ccc
(3 rows)
meta=> SELECT dblink_disconnect('conn1');

编辑:

抱歉之前回答有些误导。当然你不需要使用dblink_connect_u进行md5身份验证的连接。我发现PostgreSQL有两种不同的连接类型: 主机本地

运行:

psql -h localhost ..

采用的是主机连接,但是

dblink_connect('mycon','dbname=vchitta_op user=caixa password=caixa');

使用的是本地类型,所以如果你有非密码方法的本地连接(例如ident方法或信任),那么它会返回

ERROR:  password is required
DETAIL:  Non-superuser cannot connect if the server does not request a password.
HINT:  Target server's authentication method must be changed.

检查

dblink_connect('mycon','hostaddr=127.0.0.1 dbname=vchitta_op user=caixa password=caixa')

用于主机连接。如果可能,请发布您的pg_hba.conf以获得更清晰的说明。

我还检查了对vchitta_op数据库的CONNECT权限,但错误消息不同:

REVOKE CONNECT ON DATABASE vchitta_op FROM PUBLIC;
REVOKE CONNECT ON DATABASE vchitta_op FROM caixa;

SELECT dblink_connect('mycon','dbname=vchitta_op user=caixa password=caixa');
ERROR:  could not establish connection
DETAIL:  FATAL:  permission denied for database "vchitta_op"
DETAIL:  User does not have CONNECT privilege.

@vchitta:检查 select dblink_connect('mycon','dbname=vchitta_op user=caixa password=yourpass');。此外,如果您已经有md5,则不需要整个dblink_connect_u方法。 - Grzegorz Szpetkowski
这是我按照您的建议尝试后得到的结果:-bash-3.2$ psql -h localhost -d vchitta_meta -U postgres vchitta_meta=# grant execute on function dblink_connect_u(text) to caixa; GRANT vchitta_meta=# grant execute on function dblink_connect_u(text,text) to caixa; GRANT vchitta_meta=# \q-bash-3.2$ psql -h localhost -d vchitta_meta -U caixavchitta_meta=> select dblink_connect_u('conn1','dbname=vchitta_op'); 错误:需要密码 详细信息:非超级用户必须在连接字符串中提供密码。 - vchitta
这次错误略有变化。<br> vchitta_meta=> select dblink_connect('mycon','dbname=vchitta_op user=caixa password=caixa'); ERROR: password is required <b>DETAIL: 如果服务器不要求密码,则非超级用户无法连接。<b> HINT: 必须更改目标服务器的身份验证方法。 - vchitta
实际上这不是一个新错误,而是从一开始就存在的。 - vchitta
vchitta:它发生了变化,因为您授予了dblink_connect_u的权限,但实际上调用了dblink_connect - 这是两个不同的函数。 - vol7ron
显示剩余4条评论

5
我有一个解决方案可帮助您。如果设置了“SECURITY DEFINER”选项,非超级用户也可以以超级用户的特权执行函数。 ( http://www.postgresql.org/docs/9.1/static/sql-createfunction.html )
这意味着您可以创建一个带有超级用户所有者和SECURITY DEFINER选项的函数,用于跨多个数据库操作(使用dblink()但不需要密码),并在非超级用户下执行它。

3
我有一个类似但不同的问题。我有两个服务器,它们的postgres.conf和pg_hba.conf相同。然而,一个运行版本9.2.3,另一个运行版本9.2.4。
9.2.3 pg_hba.conf文件如下:
    local   all     dblinkuser      trust

然后我使用任何普通用户连接到数据库

    theater_map=# select dblink_connect('dbname=TheaterDB user=dblinkuser password=dbl123');
    dblink_connect 
    ----------------
    OK
    (1 row)

连接成功

9.2.4

我的pg_hba.conf与上述条目相同。

    theater_map=> select dblink_connect('dbname=TheaterDB user=dblinkuser password=dbl123');
    ERROR:  password is required
    DETAIL:  Non-superuser cannot connect if the server does not request a password.
    HINT:  Target server's authentication method must be changed.

现在,我按照以下方式更改了9.2.4上的pg_hba.conf文件:

    local   all     dblinkuser      md5

并重新启动Postgres

    theater_map=> select dblink_connect('dbname=TheaterDB user=dblinkuser password=dbl123');
    dblink_connect 
    ----------------
   OK
   (1 row)

我查看了9.2.3和9.2.4版本之间的变更日志,但没有找到任何细节。

注意:将认证方法从trust更改为md5在9.2.3上并没有任何区别,仍然有效。


1
我在谷歌搜索同样的错误信息时发现了这个问题,尽管我使用的是fdw扩展而不是db_link。以下步骤有助于解决我的问题:
  • 找到没有密码的用户并设置密码 - alter user myuser with password 'mypassword'
  • 找到身份验证方法为trust并将其设置为md5 - vim /var/lib/postgresql/data_/pg_hba.conf
  • 重新加载pg_hba.conf - 从psql选择SELECT pg_reload_conf();(注销并登录以验证需要密码)
  • (可选)尝试从远程机器、数据库浏览器等访问。
  • 设置外部服务器及其用户映射 - CREATE USER MAPPING FOR CURRENT_USER SERVER myserver OPTIONS (user 'myuser', password 'mypassword');

0

添加新用户为:
ALTER USER test WITH SUPERUSER ENCRYPTED PASSWORD 'testpassword';
在pg_hba.conf中添加以下行:
host database_name test 0.0.0.0/0 md5
enter image description here


-1

PostgreSQL 11.10

SELECT ext.column1 from
dblink('hostaddr=192.192.192.192 dbname=yourDbname user=yourUsername password=yourpass',
'select a."column1" from "Table1" a where a."column2"=2')
as ext(column1 text)

请提供要翻译的具体文本。 - D.A.H

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接