gpt4 book ai didi

postgresql - 安全定义器不能在内部工作而不是触发器?

转载 作者:行者123 更新时间:2023-11-29 12:08:16 25 4
gpt4 key购买 nike

我有一个 PostgreSQL 9.5 数据库:

  • 存储字段可能值的表 test.domain(int id, text value)。此数据是动态的。
  • 表 test.table(id int, domainn text) 其中域字段引用 test.domain 表。
  • 一个 View test.view_domain,它是 test.domain 的一个 View 。

我已经在 View 上使用安全定义器选项定义了触发器的 INSTEAD。此触发器更新表 test.domain。问题在于,尽管此触发器是以用户“系统”的身份执行的,但表 test.table 上的引用更新是由调用者用户执行的。

这是一个例子,如果作为 postgres 执行,我希望将“用户系统”作为错误而不是“用户 postgres”

drop schema IF EXISTS test  cascade;
create schema test;


create function test.modified() returns trigger as
$$
BEGIN
raise exception 'user %', ' '||current_user;
END
$$
language plpgsql;

set role system;

create function test.insert_with_system() returns trigger as
$$
DECLARE
valor text;
BEGIN

--raise exception 'user %', ' '||current_user;
update test.domain set value = ''||new.value where id = new.id;

END
$$ language plpgsql security definer;

reset role;

CREATE table test.domain(

id int primary key,
value text unique
);

create view test.domain_view as select * from test.domain;

create table test.table(
id int primary key,
domainn text
);

alter table test.table add foreign key (domainn)
references test.domain(value) on delete restrict on update cascade;

create trigger test_trigger before insert or update or delete on test.table
for each row execute procedure test.modified();

create trigger instead_ins INSTEAD OF update or delete on test.domain_view
for each row execute procedure test.insert_with_system();


insert into test.domain(id, value) values(1,'one');

alter table test.table DISABLE TRIGGER all;
insert into test.table(id, domainn) values (0,'one');
alter table test.table enable TRIGGER all;

update test.domain_view set value = 'two';
select * from test.table;

最佳答案

级联更新始终在引用表所有者的安全上下文中运行(在您的示例中为 test.table)。

参见 ri_PerformChecksrc/backend/utils/adt/ri_triggers.c :

/*
* Use the query type code to determine whether the query is run against
* the PK or FK table; we'll do the check as that table's owner
*/
if (qkey->constr_queryno <= RI_PLAN_LAST_ON_PK)
query_rel = pk_rel;
else
query_rel = fk_rel;

...

/* Switch to proper UID to perform check as */
GetUserIdAndSecContext(&save_userid, &save_sec_context);
SetUserIdAndSecContext(RelationGetForm(query_rel)->relowner,
save_sec_context | SECURITY_LOCAL_USERID_CHANGE |
SECURITY_NOFORCE_RLS);

我试图追踪代码的起源,行为似乎起源于提交 465cf168eb6151275016486fe2d2c629fed967ca .

在黑客文件中搜索相关讨论,我发现this .

因此,据我所知,该行为试图避免以下情况:

  • 用户 A拥有atable和赠款REFERENCES在该表上给用户 B .

  • 用户 B拥有btable并向 atable 添加外键与 ON UPDATE OR DELETE CASCADE .用户Abtable 没有权限.

  • 用户 A尝试更新或删除 atable 中的一行这将级联到btable并因“权限被拒绝”错误而失败。

我个人不确定目前的行为是好是坏,但我可以看出这对 A 来说是令人惊讶的一点。 ' 不能修改她拥有的表。

关于postgresql - 安全定义器不能在内部工作而不是触发器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50002566/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com