如何在Redshift中撤销对系统UDF的访问?

时间:2018-01-24 11:57:09

标签: sql amazon-web-services amazon-redshift

最近,我遇到了撤销新用户访问各种PUBLIC对象的默认访问权限的需求。撤销对大多数事情的访问非常简单:

REVOKE ALL PRIVILEGES ON SCHEMA public FROM PUBLIC CASCADE;
REVOKE ALL PRIVILEGES ON SCHEMA information_schema FROM PUBLIC CASCADE;
REVOKE ALL PRIVILEGES ON SCHEMA pg_internal FROM PUBLIC CASCADE;
REVOKE ALL PRIVILEGES ON SCHEMA pg_catalog FROM PUBLIC CASCADE;

但是,这并不包括功能。具体来说,我想拒绝访问System Administration Functions and System Information Functions。有人可能会争辩说,默认情况下这些不应该是可见的,但这完全是另一个话题。

我的问题分为两部分:

  1. 是否有一种简单的方法可以一次撤销对所有这些功能的访问,而不是单独撤销?
  2. 当撤销对单个函数的访问时,为什么我不能解析使用text参数的函数的签名?
  3. 第1部分

    根据我所研究的内容,我问题第一部分的答案似乎是 no ,您必须单独撤销对函数的访问权限。并且单独地,这意味着撤销对可以从查询

    获得的各个功能签名的访问
    select oid, oidvectortypes(proargtypes), * from pg_proc proc
    where proc.proname ilike '%<function_name>%'; 
    

    这会产生如下列表:

    REVOKE ALL PRIVILEGES ON FUNCTION CURRENT_SETTING(text) FROM PUBLIC;
    REVOKE ALL PRIVILEGES ON FUNCTION PG_CANCEL_BACKEND(int) FROM PUBLIC;
    REVOKE ALL PRIVILEGES ON FUNCTION PG_TERMINATE_BACKEND(int) FROM PUBLIC;
    REVOKE ALL PRIVILEGES ON FUNCTION SET_CONFIG(text, text, boolean) FROM PUBLIC;
    REVOKE ALL PRIVILEGES ON FUNCTION CURRENT_DATABASE() FROM PUBLIC;
    REVOKE ALL PRIVILEGES ON FUNCTION CURRENT_SCHEMA() FROM PUBLIC;
    REVOKE ALL PRIVILEGES ON FUNCTION CURRENT_SCHEMAS(bool) FROM PUBLIC;
    REVOKE ALL PRIVILEGES ON FUNCTION "CURRENT_USER"() FROM PUBLIC;
    REVOKE ALL PRIVILEGES ON FUNCTION "CURRENT_USER_ID"() FROM PUBLIC;
    REVOKE ALL PRIVILEGES ON FUNCTION HAS_DATABASE_PRIVILEGE(text, text) FROM PUBLIC;
    REVOKE ALL PRIVILEGES ON FUNCTION HAS_DATABASE_PRIVILEGE(oid, text) FROM PUBLIC;
    REVOKE ALL PRIVILEGES ON FUNCTION HAS_DATABASE_PRIVILEGE(name, text, text) FROM PUBLIC;
    REVOKE ALL PRIVILEGES ON FUNCTION HAS_DATABASE_PRIVILEGE(name, oid, text) FROM PUBLIC;
    REVOKE ALL PRIVILEGES ON FUNCTION HAS_DATABASE_PRIVILEGE(integer, text, text) FROM PUBLIC;
    REVOKE ALL PRIVILEGES ON FUNCTION HAS_DATABASE_PRIVILEGE(integer, oid, text) FROM PUBLIC;
    REVOKE ALL PRIVILEGES ON FUNCTION HAS_SCHEMA_PRIVILEGE(oid, text) FROM PUBLIC;
    REVOKE ALL PRIVILEGES ON FUNCTION HAS_SCHEMA_PRIVILEGE(name, text, text) FROM PUBLIC;
    REVOKE ALL PRIVILEGES ON FUNCTION HAS_SCHEMA_PRIVILEGE(name, oid, text) FROM PUBLIC;
    REVOKE ALL PRIVILEGES ON FUNCTION HAS_SCHEMA_PRIVILEGE(integer, text, text) FROM PUBLIC;
    REVOKE ALL PRIVILEGES ON FUNCTION HAS_SCHEMA_PRIVILEGE(integer, oid, text) FROM PUBLIC;
    REVOKE ALL PRIVILEGES ON FUNCTION HAS_SCHEMA_PRIVILEGE(text, text) FROM PUBLIC;
    REVOKE ALL PRIVILEGES ON FUNCTION HAS_TABLE_PRIVILEGE(name, oid, text) FROM PUBLIC;
    REVOKE ALL PRIVILEGES ON FUNCTION HAS_TABLE_PRIVILEGE(integer, text, text) FROM PUBLIC;
    REVOKE ALL PRIVILEGES ON FUNCTION HAS_TABLE_PRIVILEGE(integer, oid, text) FROM PUBLIC;
    REVOKE ALL PRIVILEGES ON FUNCTION HAS_TABLE_PRIVILEGE(text, text) FROM PUBLIC;
    REVOKE ALL PRIVILEGES ON FUNCTION HAS_TABLE_PRIVILEGE(oid, text) FROM PUBLIC;
    REVOKE ALL PRIVILEGES ON FUNCTION HAS_TABLE_PRIVILEGE(name, text, text) FROM PUBLIC;
    REVOKE ALL PRIVILEGES ON FUNCTION PG_BACKEND_PID() FROM PUBLIC;
    REVOKE ALL PRIVILEGES ON FUNCTION PG_GET_COLS(text) FROM PUBLIC;
    REVOKE ALL PRIVILEGES ON FUNCTION PG_GET_LATE_BINDING_VIEW_COLS() FROM PUBLIC;
    REVOKE ALL PRIVILEGES ON FUNCTION PG_LAST_COPY_COUNT() FROM PUBLIC;
    REVOKE ALL PRIVILEGES ON FUNCTION PG_LAST_COPY_ID() FROM PUBLIC;
    REVOKE ALL PRIVILEGES ON FUNCTION PG_LAST_QUERY_ID() FROM PUBLIC;
    REVOKE ALL PRIVILEGES ON FUNCTION PG_LAST_UNLOAD_COUNT() FROM PUBLIC;
    REVOKE ALL PRIVILEGES ON FUNCTION "SESSION_USER"() FROM PUBLIC;
    REVOKE ALL PRIVILEGES ON FUNCTION SLICE_NUM() FROM PUBLIC;
    REVOKE ALL PRIVILEGES ON FUNCTION VERSION() FROM PUBLIC;
    

    问题:有更简单的方法吗?

    第2部分

    手动方法很冗长,但它应该有效,对吧?好吧,不完全是。如果在Redshift中运行此命令,则包含带有text的函数签名的撤消语句将失败。例如,

    REVOKE ALL PRIVILEGES ON FUNCTION CURRENT_SETTING(text) FROM PUBLIC;
    

    产生错误

    ERROR:  function current_setting(character varying) does not exist
    

    在进一步调查后,我确信这是Redshift's character conversion rules的意外副作用,特别是将text转换为varchar的规则。

    通过创建如下的测试函数来说明这一点:

    create function test_udf (text, text)
      returns numeric
    stable
    as $$
      select case when $1 > $2 then 1.0
        else 2.0
      end
    $$ language sql;
    

    结果函数的签名报告为

    test_udf(character varying, character varying)
    

    问题:我无法正确撤销对签名涉及text参数的系统函数的访问权限,这似乎是Redshift中的错误。这是一个错误,还是我错过了什么?

0 个答案:

没有答案