Dav*_*ill 6 sql postgresql permissions
我有两张桌子.一个外键引用另一个表中的串行字段.我已将INSERT权限授予除所有者以外的角色,但我仍然无法插入包含外键的表中,除非我在包含引用字段的表上授予表UPDATE权限的所有者.我不太明白为什么所有者需要具有UPDATE权限才能使另一个不同的角色(具有INSERT权限)能够在这种情况下插入行.
这有点令人困惑,所以我提供了一个简短的问题示例.
createuser -U postgres testowner -DIRS --pwprompt
createdb -U postgres -O testowner testdb
createuser -U postgres testupdater -DIRS --pwprompt
psql -d testdb -U testowner
CREATE TABLE a ( id serial PRIMARY KEY );
CREATE TABLE b ( a_id integer REFERENCES a(id) );
GRANT SELECT,INSERT ON ALL TABLES IN SCHEMA public TO testupdater;
GRANT USAGE,UPDATE ON SEQUENCE a_id_seq TO testupdater;
REVOKE INSERT, UPDATE ON ALL TABLES IN SCHEMA public FROM testowner;
INSERT INTO a VALUES (DEFAULT); -- as expected: ERROR: permission denied for relation a
\q
psql -d testdb -U testupdater
INSERT INTO a VALUES (DEFAULT);
SELECT id FROM a LIMIT 1; -- selects the first id (1)
INSERT INTO b VALUES (1); -- unexpected error: see below
\q
Run Code Online (Sandbox Code Playgroud)
ERROR: permission denied for relation a
CONTEXT: SQL statement "SELECT 1 FROM ONLY "public"."a" x WHERE "id" OPERATOR(pg_catalog.=) $1 FOR SHARE OF x"
但是,如果我向testowner提供UPDATE权限(GRANT UPDATE ON a TO testowner;),则上述插入有效.为什么testowner在这种情况下需要UPDATE?
注意:GRANT UPDATE ON a TO testupdater;没有帮助; 似乎我必须向testowner角色授予更新权限.
我假设问题是该select语句中的"FOR SHARE OF" - 为了能够创建该行锁,您至少需要对该表进行某种写访问.
例如,如果我创建一个表并且只授予自己SELECT访问权限:
postgres@testdb=# create table t(t1_id serial primary key, value text);
NOTICE: CREATE TABLE will create implicit sequence "t_t1_id_seq" for serial column "t.t1_id"
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "t_pkey" for table "t"
CREATE TABLE
postgres@testdb=# insert into t(value) values('foo');
INSERT 0 1
postgres@testdb=# grant select on t to steve;
GRANT
Run Code Online (Sandbox Code Playgroud)
现在虽然我可以从表中读取行,但我无法锁定它们:
steve@testdb@[local] => select * from t;
t1_id | value
-------+-------
1 | foo
(1 row)
steve@testdb@[local] => select * from t for share;
ERROR: permission denied for relation t
Run Code Online (Sandbox Code Playgroud)
现在猜一下......推测外键的实现可以通过检查外表中存在的目标行来工作,并根据源表或目标表的所有者为其设置授权上下文... TBH I从来没有撤销表所有者的权限,所以我以前没遇到过这个.
我认为这是因为您不希望一个帐户只是因为他们创建了所有表而访问所有表?我会建议:
set session authorization"postgres"或其他一些超级用户执行架构更改,因为某些用户(例如数据库所有者)没有登录访问权限| 归档时间: |
|
| 查看次数: |
1481 次 |
| 最近记录: |