0

我用 Plpython 做了一个小 PostgreSQL 触发器。这个触发器在文件系统上播放了一下,创建和删除我的一些文件。创建的文件归“postgres”unix 用户所有,但我希望它们归另一个用户所有,比如说 foobar。触发器与用户“foobar”一起安装,并与用户“foobar”一起执行。

有没有办法使用 PostgreSQL 或 Plpython 使用 unix 用户 'foobar' 执行 SQL 触发器?我应该使用SET ROLE foobar吗?

玩起来SECURITY INVOKER似乎SECURITY DEFINER还不够好。

4

2 回答 2

3

您混淆了操作系统用户和 PostgreSQL 用户。

SECURITY DEFINER允许您以定义postgresql用户的身份运行函数。但无论 PostgreSQL 用户运行的是哪个操作系统用户,后端服务器的运行方式始终相同——通常是操作系统用户postgres

按照设计,PostgreSQL 服务器不能像其他操作系统用户一样运行操作系统命令或系统调用。那将是一个令人讨厌的安全漏洞。

但是,如果你想允许,你可以。你可以:

  • 授予postgres用户sudo以其他用户身份运行部分或全部命令的权限;或者
  • 编写一个程序以执行setuid您想要的操作并授予postgres用户执行它的权限。

在任何一种情况下,运行这些程序的唯一方法是从不受信任的过程语言(如 plpython 或 plperl)或从 C 扩展启动它们。

目前尚不清楚为什么要首先设置这样的文件所有权,但我怀疑这可能不是一个好主意。如果 PostgreSQL 客户端和服务器甚至不在同一台计算机上怎么办?如果该 PostgreSQL 用户没有操作系统用户,或者用户名不同怎么办?等等

于 2014-07-25T14:59:40.660 回答
2

您的用户在 Postgres 中承担的“角色”是数据库本地的。您在数据库中的角色强制执行数据库权限。所以,你可以说 foobar 可以运行这个存储过程,或者选择这个表,Postgres 会强制执行。如果您使用 SECURITY INVOKER 创建您的过程,这意味着正在运行的过程将使用当前登录的 Postgres 用户运行。SECURITY DEFINER 意味着该过程将使用创建该过程的角色运行。无论哪种方式,如果您的程序在 Postgres 之外执行任何操作(例如创建文件),它将作为启动 Postgres 的身份来完成(正如您所发现的那样)。就我而言,我有一个名为“postgres”的 Unix 用户,当我启动 Postgres 时,我以该用户身份进行操作。因此,创建的任何文件都将归“postgres”用户所有。

你没有告诉我们你的操作系统。Windows 将不同于 *nix。此答案适用于 *nix。

您确实提到您的存储过程语言是 plpython。因此,您可以创建该文件,然后在您的过程中创建它之后更改它的所有权。像:

import os
import pwd

f = open('/tmp/myfile','w')
f.write('hello')
f.close()
user_id = pwd.getpwnam("foobar").pw_uid    
os.chown('/tmp/myfile', user_id, -1)

假设在运行 Postgres 的主机上有一个 foobar 用户,这应该可以工作。

-G

于 2014-07-25T13:56:12.747 回答