2016-08-11 105 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'部分。感謝您的貢獻。 –

相關問題