project2_core
:到目前为止,到目前为止一切都很好。现在,我创建一个用户:postgres=# \l
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
---------------+--------------+-----------+-------------+-------------+-------------------------------
postgres | postgres | SQL_ASCII | C | C |
project2_core | atm_project2 | UTF8 | de_DE.UTF-8 | de_DE.UTF-8 | project2=CTc/project2
template0 | postgres | SQL_ASCII | C | C | =c/postgres +
| | | | | postgres=CTc/postgres
template1 | postgres | SQL_ASCII | C | C | =c/postgres +
| | | | | postgres=CTc/postgres
(5 rows)
好。当我尝试连接数据库时,不允许用户这样做:
postgres=# CREATE ROLE dietrich ENCRYPTED PASSWORD 'md5XXX' LOGIN NOCREATEROLE NOCREATEDB NOSUPERUSER
这是我所期望的。现在奇怪的东西开始了。我授予用户
CONNECT
:$ psql -h localhost -p 5432 -U dietrich -W project2_core
Password for user dietrich:
psql: FATAL: permission denied for database "project2_core"
DETAIL: User does not have CONNECT privilege.
而且没有任何其他授予,允许用户创建表:
postgres=# GRANT CONNECT ON DATABASE project2_core TO dietrich;
GRANT
postgres=# \l
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
---------------+--------------+-----------+-------------+-------------+-------------------------------
postgres | postgres | SQL_ASCII | C | C |
project2_core | atm_project2 | UTF8 | de_DE.UTF-8 | de_DE.UTF-8 | project2=CTc/project2+
| | | | | dietrich=c/project2
template0 | postgres | SQL_ASCII | C | C | =c/postgres +
| | | | | postgres=CTc/postgres
template1 | postgres | SQL_ASCII | C | C | =c/postgres +
| | | | | postgres=CTc/postgres
(5 rows)
我希望用户在我对架构明确执行
GRANT USAGE
然后对表格进行GRANT SELECT
之前不允许执行任何操作。我的错误在哪里?我究竟做错了什么?我该如何实现自己想要的(新用户在明确授予她适当的权限之前不允许做任何事情。
我迷路了,非常感谢您的帮助:)
编辑按照@ daniel-verite的建议,我现在在创建数据库后立即撤销所有操作。用户Diet Diet再也不能创建表。好。但是:现在,也不允许数据库的所有者project2创建表。即使发出
GRANT ALL PRIVILEGES ON DATABASE project2_core TO project2
和GRANT ALL PRIVILEGES ON SCHEMA public TO project2
之后,我仍然收到错误ERROR:未选择要创建的架构,并且当我专门尝试CREATE TABLE public.WHATEVER ();
时,我得到ERROR:架构公共的权限被拒绝。我在做什么错?#1 楼
创建新数据库时,任何角色都可以在public
模式中创建对象。为了消除这种可能性,您可以在数据库创建后立即发出:REVOKE ALL ON schema public FROM public;
编辑:在执行上述命令之后,只有超级用户才能在
public
模式内创建新对象,这不切实际。假设应授予非超级用户foo_user
特权,可以使用以下方法完成此操作:GRANT ALL ON schema public TO foo_user;
要知道
ALL
对模式的含义,我们必须在文档(在PG 9.2中,有不少于14种形式的GRANT语句适用于不同的事物...)。看来,对于架构来说,它意味着CREATE
和USAGE
。另一方面,GRANT ALL PRIVILEGES ON DATABASE...
将授予CONNECT
和CREATE
和TEMP
,但是在此上下文中,CREATE
与架构有关,而不是永久表。 > 关于此错误:
ERROR: no schema has been selected to create in
,当尝试创建没有架构限定的对象时(如create table foo(...)
),却没有在search_path
的任何架构中创建该对象的权限,就会发生这种情况。#2 楼
这里要了解的关键是特权不是启发性的,也不是从包含对象继承的。ALL
表示此对象的所有特权,而不是此对象和所有包含的对象的所有特权。在数据库上授予
ALL
时,就是在授予CREATE, CONNECT, TEMP
。这些是对数据库对象本身的操作:CONNECT
:连接到DB CREATE
:创建模式(不是表) TEMP
:创建临时对象,包括但不限于临时表现在,每个PostgreSQL数据库默认都有一个
public
模式,该模式是在创建数据库时创建的。此架构拥有授予角色public
的所有权利,每个角色都是其隐式成员。对于架构,ALL
表示CREATE, USAGE
:CREATE
:在此架构中创建对象(包括表)USAGE
:列出架构中的对象并在权限允许的情况下访问它们如果您未指定架构以创建像表这样的对象,则数据库引擎将使用
search_path
,默认情况下,public
架构首先位于search_path
上,因此在此处创建表。每个人默认都具有对public
的权限,因此允许创建。此时,用户对数据库的权限是无关紧要的,因为用户不打算对数据库对象本身进行任何操作,而只是对其中的一个架构进行操作。没关系除了授予数据库
CONNECT
之外,您没有授予用户任何权限,因为public
模式默认情况下允许所有用户在其中创建表。 Daniel已经说明了如何根据需要撤销该权利。如果要显式委派每个权限,请从公共撤消所有权限,或直接删除公共架构。您可以根据需要应用此更改来创建新的模板数据库。另外,您也可以将其应用于
template1
,但这可能会破坏很多假设public
存在且可写的第三方代码。类比文件系统。
如果我具有目录结构(模式简化为仅显示适用于当前用户的模式):
/dir1 mode=r-x
/dir1/dir2 mode=rwx
那么我无法在
/dir1
内创建任何内容,因为我没有写权限。因此,如果我touch /dir1/somefile
会出现拒绝权限错误。但是,我确实有权查看
/dir1
的内部并访问包含的文件和目录,包括/dir1/dir2
。我对dir2
具有写权限。因此,即使我没有对touch /dir1/dir2/somefile
的写权限,dir1
也会成功。与数据库和模式相同。
#3 楼
如果只想阻止新用户创建表,则需要运行以下命令:REVOKE CREATE ON SCHEMA public FROM public;
如果您
REVOKE ALL
(如其他答案所示),您还将防止用户具有USAGE
权限。 USAGE
意味着用户可以使用分配给他们的权限,因此,如果删除该权限,则用户将无法列出或访问他们可以访问的表。或者,您也可以使用REVOKE CREATE
特定用户:REVOKE CREATE ON schema public FROM myuser;
另请参见:如何使用PostgreSQL创建只读用户。
评论
的作品:)但我还是不明白:我已经尝试了REPUKE ALL ON DATABASE project2_core FROM PUBLIC;。为什么这没有效果?
– andreas-h
13年2月23日在18:27
嗯现在数据库的所有者不再被允许创建表。参见上面的编辑。
– andreas-h
13年2月23日在18:48
@ andreas-h:编辑了更多详细信息的答案
–丹尼尔·韦里特(DanielVérité)
13年2月23日在19:33
关于错误,可以通过从问题和您的REVOKE中按顺序发出命令来轻松重现它:)
– dezso
13年2月23日在19:41
@DanielVérité我已经在一个新的答案中阐述了其背后的概念,以补充您的答案。一个健全的检查将被重视。
–克雷格·林格(Craig Ringer)
2014年12月3日,2:12