2016-08-11 106 views
1

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

但是,我指定的所有限制都不会生效(请参见下文)。 用户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; 
+0

你想干什么?可以“复制”的非超级用户角色? – Nicarus

回答

1

您正在描述一种情况,用户可以将文件写入数据库运行的服务器,但不是超级用户。虽然不是不可能的,但它绝对不正常。我会对我允许访问我的数据库服务器的人选非常有选择性。这就是说,如果是这种情况,我会创建一个函数来加载postgres用户拥有的表(使用copy),并授予用户执行该函数的权限。您可以将文件名作为参数传递。

如果您想要看起来很棒,您可以创建一个用户和表格的表格来定义用户可以上传到哪些表格并将表格名称作为参数。

这是非常规的,但它是一个想法。

这里有一个基本的例子:

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; 
+1

你有一个sql注入漏洞,(在'执行'在tablename上添加'quote_identifier()'并在文件名中使用'quote_literal()') – Jasen

+0

这个想法非常适合作为postgres的函数的拥有者,并由普通用户执行,但这不适合我。仍然收到错误说COPY需要超级用户。 – pillesoft

+0

@pilesoft - 是超级用户的功能所有者? – Hambone

0

COPY比写入STDOUTSTDIN阅读其他选项只允许数据库超级用户作用因为它可以读取或写入服务器有权限访问的文件。

\copy是其用于相同的功能COPY,但并不服务器片面的,所以只有本地文件可以被处理的psql的客户机命令 - 这意味着它调用COPY... FROM STDIN/... TO STDOUT,从而在服务器上的文件不是“感动”。

您无法撤销超级用户的特定权限。我就这一个引用文档:

Docs: Access DB

作为超级用户意味着你不受访问控制。

Docs: CREATE ROLE

“超级用户”,谁可以超越数据库中的所有访问权限。超级用户状态很危险,只能在真正需要时才使用。

+1

严格地说,对于非超级用户,“COPY”是允许的,但仅限于“复制...到标准输出”/“复制...从标准”。这是'\ copy'使用的。这很重要,因为像psycopg2,PgJDBC等其他客户端也可以在不使用超级用户的情况下使用'COPY',只是为了向/从客户端流入行,而不是从服务器磁盘上的文件流入/流出。 –

+0

@CraigRinger我已经阐述了'COPY'部分。感谢您的贡献。 –

相关问题