【问题标题】:What is the difference between user postgres and a superuser?用户 postgres 和超级用户有什么区别?
【发布时间】:2016-12-18 18:03:22
【问题描述】:

我创建了一个新的超级用户,以便该用户可以运行 COPY 命令。 请注意,非超级用户无法运行复制命令。 由于备份应用程序,我需要此用户,并且该应用程序需要运行 COPY 命令

但是我指定的所有限制都没有生效(见下文)。 用户 postgres 和超级用户有什么区别?

有没有更好的方法来实现我想要的?我研究了一个带有安全定义器作为 postgres 的函数......这对于多个表来说似乎有很多工作。

DROP ROLE IF EXISTS mynewuser;
CREATE ROLE mynewuser PASSWORD 'somepassword' SUPERUSER NOCREATEDB NOCREATEROLE NOINHERIT LOGIN;
-- ISSUE: the user can still CREATEDB, CREATEROLE

REVOKE UPDATE,DELETE,TRUNCATE ON ALL TABLES IN SCHEMA public, schema1, schema2, schema3 FROM mynewuser;
-- ISSUE: the user can still UPDATE, DELETE, TRUNCATE

REVOKE CREATE ON DATABASE ip2_sync_master FROM mynewuser;
-- ISSUE: the user can still create table;

【问题讨论】:

  • 你想要什么?可以COPY? 的非超级用户角色

标签: database postgresql role


【解决方案1】:

COPY 具有除写入STDOUT 和从STDIN 读取之外的选项仅允许用于数据库超级用户 角色,因为它允许读取或写入服务器有权访问的任何文件.

\copy 是一个 psql 客户端命令,它提供与COPY 相同的功能,但不是服务器端的,因此只能处理本地文件 - 这意味着它调用COPY 但调用... FROM STDIN / ... TO STDOUT,这样服务器上的文件就不会被“触及”。

您不能撤销超级用户的特定权限。我引用了这个文档:

Docs: Access DB

成为超级用户意味着您不受访问控制的约束。

Docs: CREATE ROLE

“超级用户”,可以覆盖数据库中的所有访问限制。超级用户状态很危险,应该只在真正需要时使用。

【讨论】:

  • 严格来说,COPY 允许非超级用户使用,但仅限COPY ...TO STDOUT / COPY ... FROM STDIN。这是\copy 使用的。这很重要,因为即使没有超级用户,其他客户端(如 psycopg2、PgJDBC 等)也可以使用COPY,只是将行传输到客户端/从客户端传输,而不是传输到/从服务器磁盘上的文件传输。
  • @CraigRinger 我已经阐明了COPY 部分。感谢您的贡献。
【解决方案2】:

您正在描述一种情况,用户可以将文件写入运行数据库但不是超级用户的服务器。虽然不是不可能,但绝对是不正常的。我会非常谨慎地选择允许谁访问我的数据库服务器。

也就是说,如果是这种情况,我会创建一个函数来加载表(使用copy),该函数由postgres 用户拥有,并授予用户执行该函数的权限。您可以将文件名作为参数传递。

如果你想变得花哨,你可以创建一个用户表和表来定义哪些用户可以上传到哪些表,并将表名也作为参数。

这很不规范,但这是一个想法。

这是一个基本的例子:

CREATE OR REPLACE FUNCTION load_table(TABLENAME text, FILENAME text)
  RETURNS character varying AS
$BODY$
DECLARE
  can_upload integer;
BEGIN

  select count (*)
  into can_upload
  from upload_permissions p
  where p.user_name = current_user and p.table_name = TABLENAME;

  if can_upload = 0 then
    return 'Permission denied';
  end if;

  execute 'copy ' || TABLENAME ||
    ' from ''' || FILENAME || '''' ||
    ' csv';

  return '';
END;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;

【讨论】:

  • 你有一个 sql 注入漏洞,(在execute 在表名上添加quote_identifier() 并在文件名上使用quote_literal()
  • 这个想法非常好,通过postgres成为函数的所有者,并由普通用户执行,但这对我不起作用。仍然收到错误说 CO​​PY 需要有超级用户。
  • @pilesoft -- 函数的所有者是超级用户吗?
猜你喜欢
  • 2014-08-21
  • 1970-01-01
  • 1970-01-01
  • 2013-12-26
  • 2012-06-01
  • 2015-02-26
  • 1970-01-01
  • 1970-01-01
  • 2018-03-24
相关资源
最近更新 更多