SCHEMA上有什么免费使用的功能?


121

我正在尝试首次创建Postgres数据库,因此这可能是一个愚蠢的问题。我为db角色分配了基本的只读权限,该角色必须从我的php脚本访问数据库,并且我有一个好奇心:如果执行

GRANT some_or_all_privileges ON ALL TABLES IN SCHEMA schema TO role;

有没有必要执行

GRANT USAGE ON SCHEMA schema TO role;

文档

用法:对于模式,允许访问指定模式中包含的对象(假设还满足对象自己的特权要求)。本质上,这允许被授予者在架构内“查找”对象。

我认为,如果我可以选择或操作架构中包含的任何数据,则可以访问架构本身的任何对象。我错了吗?如果没有,它的作用是什么GRANT USAGE ON SCHEMA?该文档对“假设还满足对象自己的特权要求”到底意味着什么?

Answers:


126

GRANT不同对象上的s是分开的。GRANT在数据库上GRANT访问对内部架构无权。GRANT类似地,在架构上注册不会授予其中表的权限。

如果您有权访问SELECT某个表,但没有权限在包含该表的架构中查看它,那么您将无法访问该表。

权限测试按顺序进行:

Do you have `USAGE` on the schema? 
    No:  Reject access. 
    Yes: Do you also have the appropriate rights on the table? 
        No:  Reject access. 
        Yes: Check column privileges.

您可能会因为以下事实而感到困惑:public架构默认拥有GRANT角色的所有权利public,每个用户/组都是该角色的成员。因此,每个人都已经在该架构上使用过。

词组:

(假设还满足对象自己的特权要求)

就是说,您必须拥有USAGE一个架构才能使用其中的对象,但是拥有USAGE一个架构本身不足以使用该架构中的对象,您还必须拥有这些对象本身的权限。

就像目录树一样。如果您在其中创建somedir带有文件的目录,请somefile对其进行设置,以便只有您自己的用户才能访问该目录或文件(rwx------dir模式rw-------,dir模式,文件模式),然后没有其他人可以列出目录以查看该文件是否存在。

如果您要授予文件的全球读取权限(模式rw-r--r--),但不更改目录权限,则没有任何区别。没有人可以看到文件来读取它,因为他们没有列出目录的权限。

如果您改为rwx-r-xr-x在目录上进行设置,进行设置,以便人们可以列出和遍历目录,但不更改文件权限,则人们可以列出文件,但无法读取它,因为他们无权访问该文件。

你需要设置 两个权限,以使人们能够实际查看文件。

在Pg中也是一样。您需要两个模式USAGE权限和对象权限才能对对象执行操作,例如SELECT从表中进行操作。

(类比下降了一点,因为PostgreSQL还没有行级安全性,因此用户仍然可以SELECT通过pg_class直接引用来“看到”该表存在于模式中。他们无法以任何方式与其进行交互,因此,只是“列表”部分并不完全相同。)


2
现在,使用目录示例非常清楚:)如果您用超级用户插入某些表或行,例如,当您使用添加时,我必须说这是一个问题CREATE EXTENSION。在您使用时,在Linux上创建的文件或多或少都存在相同的问题su。如果sudo -epqsl中有某种for语句,那会很好。
Marco Sulla

无论如何,现在我意识到GRANT不是特定于表的语句不是我想要的,因为它们会影响所有数据库...:s
Marco Sulla 2013年

1
@LucasMalor Er ...不,他们没有。GRANT模式上的内容会影响该模式。GRANT ... ON ALL TABLES IN SCHEMA ...影响特定数据库中架构中的所有表。不会GRANT影响所有数据库(可以,除了将GRANT角色成员身份授予用户)。
Craig Ringer 2013年

不好意思,当我以“ postgres”超级用户身份登录时,我执行了这些语句,它们影响了“ postgres”数据库。我以为,如果您在运行时psql没有-d db在任何数据库“外部”进行操作,但是您始终连接到数据库,并且默认情况下,您将以与您角色相同的名称连接到数据库。db =角色=用户=组...这有点令人困惑:D
Marco Sulla

@LucasMalor这样想。默认情况下,您使用与连接所用的登录角色(“用户”)相同的名称连接到数据库。“用户”只是具有的角色WITH LOGIN;本质上,一切都可以是一组,和组可以设置为能够登录。
克雷格·林格

72

对于生产系统,可以使用以下配置:

--ACCESS DB
REVOKE CONNECT ON DATABASE nova FROM PUBLIC;
GRANT  CONNECT ON DATABASE nova  TO user;

--ACCESS SCHEMA
REVOKE ALL     ON SCHEMA public FROM PUBLIC;
GRANT  USAGE   ON SCHEMA public  TO user;

--ACCESS TABLES
REVOKE ALL ON ALL TABLES IN SCHEMA public FROM PUBLIC ;
GRANT SELECT                         ON ALL TABLES IN SCHEMA public TO read_only ;
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO read_write ;
GRANT ALL                            ON ALL TABLES IN SCHEMA public TO admin ;

还不应该在模式上admin被授予CREATE吗?

2
访问权限是根据以下层次模型分配的:BD-> SCHEMA-> TABLES。使用GRANT USAGE ON SCHEMA,管理员用户无法创建表,但可以使用ALL GRANT ALL ON SCHEMA....
bilelovitch

@bilelovitch:你的意思是grant all on schema public to admin?PS:我还添加了 grant usage, select on all sequences in schema public to read_only/read_write; grant execute on all functions in schema public to read_only/read_write;
马尔科·苏拉

2

好吧,这是我针对Linux的简单数据库的最终解决方案:

# Read this before!
#
# * roles in postgres are users, and can be used also as group of users
# * $ROLE_LOCAL will be the user that access the db for maintenance and
#   administration. $ROLE_REMOTE will be the user that access the db from the webapp
# * you have to change '$ROLE_LOCAL', '$ROLE_REMOTE' and '$DB'
#   strings with your desired names
# * it's preferable that $ROLE_LOCAL == $DB

#-------------------------------------------------------------------------------

//----------- SKIP THIS PART UNTIL POSTGRES JDBC ADDS SCRAM - START ----------//

cd /etc/postgresql/$VERSION/main
sudo cp pg_hba.conf pg_hba.conf_bak
sudo -e pg_hba.conf

# change all `md5` with `scram-sha-256`
# save and exit

//------------ SKIP THIS PART UNTIL POSTGRES JDBC ADDS SCRAM - END -----------//

sudo -u postgres psql

# in psql:
create role $ROLE_LOCAL login createdb;
\password $ROLE_LOCAL
create role $ROLE_REMOTE login;
\password $ROLE_REMOTE

create database $DB owner $ROLE_LOCAL encoding "utf8";
\connect $DB $ROLE_LOCAL

# Create all tables and objects, and after that:

\connect $DB postgres

revoke connect on database $DB from public;
revoke all on schema public from public;
revoke all on all tables in schema public from public;

grant connect on database $DB to $ROLE_LOCAL;
grant all on schema public to $ROLE_LOCAL;
grant all on all tables in schema public to $ROLE_LOCAL;
grant all on all sequences in schema public to $ROLE_LOCAL;
grant all on all functions in schema public to $ROLE_LOCAL;

grant connect on database $DB to $ROLE_REMOTE;
grant usage on schema public to $ROLE_REMOTE;
grant select, insert, update, delete on all tables in schema public to $ROLE_REMOTE;
grant usage, select on all sequences in schema public to $ROLE_REMOTE;
grant execute on all functions in schema public to $ROLE_REMOTE;

alter default privileges for role $ROLE_LOCAL in schema public
    grant all on tables to $ROLE_LOCAL;

alter default privileges for role $ROLE_LOCAL in schema public
    grant all on sequences to $ROLE_LOCAL;

alter default privileges for role $ROLE_LOCAL in schema public
    grant all on functions to $ROLE_LOCAL;

alter default privileges for role $ROLE_REMOTE in schema public
    grant select, insert, update, delete on tables to $ROLE_REMOTE;

alter default privileges for role $ROLE_REMOTE in schema public
    grant usage, select on sequences to $ROLE_REMOTE;

alter default privileges for role $ROLE_REMOTE in schema public
    grant execute on functions to $ROLE_REMOTE;

# CTRL+D

1
“#创建所有表和对象以及之后:”必须使用哪个用户?在您的案例中,表和其他对象的所有者是谁?
Christophe Furmaniak,

@ChristopheFurmaniak您说得对,我已更正了该过程。数据库及其对象的所有者是$ ROLE_LOCAL,在创建数据库结构后,我们必须返回到postgres超级用户。
马可·苏拉

我相信您的“更改默认权限...”命令中存在问题。当另一用户(角色)创建对象时,此命令用于触发对一个用户(角色)的授予特权。请参阅本文档第11页的第7.1节,以进行澄清。当前,您的ROLE_REMOTE将无法访问ROLE_LOCAL将创建的任何对象。ROLE_LOCAL命令仅授予该角色作为这些对象的所有者已经拥有的特权。ROLE_REMOTE命令也是如此。
emispowder
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.