不久前,我来到社区,询问我正在开发的系统触发器的定义。我仍然发现自己正在开发相同的系统,现在我对角色产生怀疑。我是使用PostgreSQL的新手,甚至在文档之后,我最后还是提出了一些问题。
为了开发我的系统,我创建了3个用户:
创建用户,表格,简单数据和设置权限后,pgAdmin向我显示以下消息:
ERROR: permission denied for relation tb_tabelas
CONTEXT: SQL statement "SELECT 1 FROM ONLY "regrast"."tb_tabelas" x WHERE "tab_id" OPERATOR(pg_catalog.=) $1 FOR KEY SHARE OF x"
********** Error **********
ERROR: permission denied for relation tb_tabelas
SQL state: 42501
Context: SQL statement "SELECT 1 FROM ONLY "regrast"."tb_tabelas" x WHERE "tab_id" OPERATOR(pg_catalog.=) $1 FOR KEY SHARE OF x"
我使用postgres用户,我不知道我做错了什么。我没有做出这些陈述(至少不是直接):
"SELECT 1 FROM ONLY "regrast"."tb_tabelas" x WHERE "tab_id" OPERATOR(pg_catalog.=) $1 FOR KEY SHARE OF x"
以下是我的用户的创建:
-- DROP OWNED BY dbadiretor CASCADE;
DROP ROLE IF EXISTS dbadiretor;
CREATE ROLE dbadiretor WITH
SUPERUSER
CREATEDB
CREATEROLE
LOGIN
REPLICATION
CONNECTION LIMIT 1
PASSWORD 'dbadiretor';
-- DROP OWNED BY dbagerente CASCADE;
DROP ROLE IF EXISTS dbagerente;
CREATE ROLE dbagerente WITH
NOSUPERUSER
NOCREATEDB
NOCREATEROLE
NOINHERIT
LOGIN
NOREPLICATION
CONNECTION LIMIT 3
PASSWORD 'dbagerente';
-- DROP OWNED BY clisistema CASCADE;
DROP ROLE IF EXISTS clisistema;
CREATE ROLE clisistema WITH
NOSUPERUSER
NOCREATEDB
NOCREATEROLE
NOINHERIT
LOGIN
NOREPLICATION
CONNECTION LIMIT 30
PASSWORD '12345';
以下是特权的分配:
-- #####################################
-- USUÁRIO: PUBLIC
-- #####################################
REVOKE ALL PRIVILEGES ON DATABASE "ELocadora" FROM PUBLIC;
-- #####################################
-- USUÁRIO: dbadiretor
-- #####################################
GRANT ALL PRIVILEGES ON SCHEMA regrast TO dbadiretor;
GRANT ALL PRIVILEGES ON DATABASE "ELocadora" TO dbadiretor;
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA regrast TO dbadiretor;
-- #####################################
-- USUÁRIO: clisistema
-- #####################################
GRANT CONNECT ON DATABASE "ELocadora" TO clisistema;
GRANT USAGE ON SCHEMA regrast TO clisistema;
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA regrast TO clisistema;
-- NÍVEL DE FILTRO 1
REVOKE TRUNCATE, REFERENCES, TRIGGER ON ALL TABLES IN SCHEMA regrast FROM clisistema;
REVOKE CREATE ON SCHEMA regrast FROM clisistema;
REVOKE TEMP ON DATABASE "ELocadora" FROM clisistema;
-- NÍVEL DE FILTRO 2
-- Tabela: TB_TABELAS
-- Revogação: CUD
REVOKE INSERT, UPDATE, DELETE ON TABLE regrast.tb_tabelas FROM clisistema;
-- Tabela: TB_DADOS
-- Revogação: CUD
REVOKE INSERT, UPDATE, DELETE ON TABLE regrast.tb_dados FROM clisistema;
-- Tabela: TB_MODIFICACOES
-- Revogação: CUD
REVOKE INSERT, UPDATE, DELETE ON TABLE regrast.tb_modificacoes FROM clisistema;
-- Tabela: TB_TIPOS_DE_LOGS
-- Revogação: CUD
REVOKE INSERT, UPDATE, DELETE ON TABLE regrast.tb_tipos_de_logs FROM clisistema;
-- Tabela: TB_LOGS
-- Revogação: CUD
REVOKE INSERT, UPDATE, DELETE ON TABLE regrast.tb_logs FROM clisistema;
-- Tabela: TB_HISTORICO_DE_PRODUTOS
-- Revogação: CUD
REVOKE INSERT, UPDATE, DELETE ON TABLE regrast.tb_historico_de_produtos FROM clisistema;
-- Tabela: TB_CONFIGURACOES
-- Revogação: CD
REVOKE INSERT, DELETE ON TABLE regrast.tb_configuracoes FROM clisistema;
-- #####################################
-- USUÁRIO: dbagerente
-- #####################################
GRANT CONNECT ON DATABASE "ELocadora" TO dbagerente;
GRANT USAGE ON SCHEMA regrast TO dbagerente;
REVOKE INSERT, SELECT, UPDATE, DELETE ON ALL TABLES IN SCHEMA regrast FROM dbagerente;
GRANT CREATE ON SCHEMA regrast TO dbagerente;
GRANT REFERENCES, TRIGGER ON ALL TABLES IN SCHEMA regrast TO dbagerente;
我正在阅读PostgreSQL documentation,如果我想以任何方式修改表格,我需要为表格设置合适的所有者。例如,关于CREATE权限:
CREATE
对于模式,允许在模式中创建新对象。 要 重命名现有对象,您必须拥有该对象 和 才能拥有此对象 包含架构的特权。
因此,我的所有表都将dbagerente用户作为所有者。作为dbagerente,我可以修改结构。但作为dbadiretor或postgres,我不能,而这不是我想要的。对我来说,dbadiretor和postgres是超级用户,他们应该能够完成任何事情......或者不是吗? :/
进一步向前看......我必须注意*小心)其他数据库对象,如函数,触发器等吗?
注意:我使用PostgreSQL 9.5 ,使用名为ELocadora的数据库和名为regrast的模式。
出现这个问题,如果可能的话(如果你不介意的话),你会为像我这样的初学者正确分配角色吗?任何链接或提示可以帮助我。
此外,为了实现日志而创建新用户是否有禁忌症?系统事务(对于某些操作)可能最终必须使用两种类型的用户才能完成。
感谢您的关注。
我怀疑由于依赖性而出现此错误 表之间。在某些外键的表格中,我正在使用 ON DELETE和ON UPDATE语句。
第一次输入数据时,输入的数据没有问题。 但是,如果我删除它们以重新插入它们,则会出现此错误。
这与此有关吗?
我错了,这些信息没有根据。请忽略它。我很抱歉。
我记录了所有过程,包括所有步骤和明显的问题。一切都是从头开始的。请看一下(4分钟):
打开的SQL文件代表正在进行的不同操作。它们分为不同的步骤。我又做错了什么?
我在代码中发现了一个小错误。非破坏性(最初)。在记录插入代码中,我改变了这个:
INSERT INTO regrast.TB_DADOS (DAD_NOME_VISUAL , DAD_NOME_COLUNA , DAD_TABELA) VALUES ('ID' , 'USU_ID' , (SELECT tba_id FROM regrast.tb_tabelas WHERE tba_nome ILIKE 'tb_usu%'));
进入这个:
INSERT INTO regrast.TB_DADOS (DAD_NOME_VISUAL , DAD_NOME_COLUNA , DAD_TABELA) VALUES ('ID' , 'USU_ID' , (SELECT tba_id FROM regrast.tb_tabelas WHERE tba_nome ILIKE 'tb_usu%' LIMIT 1));
@Chris Travers
[...]因此表所有者必须具有写入权限 任何人都可以从中删除级联表。
[...]所以这里的问题是表所有者没有访问权限。
但我使用超级帐户。我的意思是,我使用超级用户。从理论上讲,这里没有限制,因为我是超级用户,不是吗?我作为超级用户尝试插入和删除表记录。然而,我收到了这个错误。
以下代码给出了错误:
INSERT INTO regrast.TB_DADOS (DAD_NOME_VISUAL , DAD_NOME_COLUNA , DAD_TABELA) VALUES ('ID' , 'USU_ID' , (SELECT tba_id FROM regrast.tb_tabelas WHERE tba_nome ILIKE 'tb_usu%' LIMIT 1));
INSERT INTO regrast.TB_DADOS (DAD_NOME_VISUAL , DAD_NOME_COLUNA , DAD_TABELA) VALUES ('Login' , 'USU_LOGIN' , (SELECT tba_id FROM regrast.tb_tabelas WHERE tba_nome ILIKE 'tb_usu%' LIMIT 1));
INSERT INTO regrast.TB_DADOS (DAD_NOME_VISUAL , DAD_NOME_COLUNA , DAD_TABELA) VALUES ('Senha' , 'USU_SENHA' , (SELECT tba_id FROM regrast.tb_tabelas WHERE tba_nome ILIKE 'tb_usu%' LIMIT 1));
INSERT INTO regrast.TB_DADOS (DAD_NOME_VISUAL , DAD_NOME_COLUNA , DAD_TABELA) VALUES ('Apelido' , 'USU_APELIDO' , (SELECT tba_id FROM regrast.tb_tabelas WHERE tba_nome ILIKE 'tb_usu%' LIMIT 1));
INSERT INTO regrast.TB_DADOS (DAD_NOME_VISUAL , DAD_NOME_COLUNA , DAD_TABELA) VALUES ('Nascimento' , 'USU_NASCIMENTO' , (SELECT tba_id FROM regrast.tb_tabelas WHERE tba_nome ILIKE 'tb_usu%' LIMIT 1));
INSERT INTO regrast.TB_DADOS (DAD_NOME_VISUAL , DAD_NOME_COLUNA , DAD_TABELA) VALUES ('Cadastro' , 'USU_CADASTRO' , (SELECT tba_id FROM regrast.tb_tabelas WHERE tba_nome ILIKE 'tb_usu%' LIMIT 1));
INSERT INTO regrast.TB_DADOS (DAD_NOME_VISUAL , DAD_NOME_COLUNA , DAD_TABELA) VALUES ('Gênero' , 'USU_GENERO' , (SELECT tba_id FROM regrast.tb_tabelas WHERE tba_nome ILIKE 'tb_usu%' LIMIT 1));
INSERT INTO regrast.TB_DADOS (DAD_NOME_VISUAL , DAD_NOME_COLUNA , DAD_TABELA) VALUES ('Privilégio' , 'USU_PRIVILEGIO' , (SELECT tba_id FROM regrast.tb_tabelas WHERE tba_nome ILIKE 'tb_usu%' LIMIT 1));
INSERT INTO regrast.TB_DADOS (DAD_NOME_VISUAL , DAD_NOME_COLUNA , DAD_TABELA) VALUES ('CEP' , 'USU_CEP' , (SELECT tba_id FROM regrast.tb_tabelas WHERE tba_nome ILIKE 'tb_usu%' LIMIT 1));
INSERT INTO regrast.TB_DADOS (DAD_NOME_VISUAL , DAD_NOME_COLUNA , DAD_TABELA) VALUES ('Número Residencial' , 'USU_NUMERO' , (SELECT tba_id FROM regrast.tb_tabelas WHERE tba_nome ILIKE 'tb_usu%' LIMIT 1));
INSERT INTO regrast.TB_DADOS (DAD_NOME_VISUAL , DAD_NOME_COLUNA , DAD_TABELA) VALUES ('Complemento' , 'USU_COMPLEMENTO' , (SELECT tba_id FROM regrast.tb_tabelas WHERE tba_nome ILIKE 'tb_usu%' LIMIT 1));
如果我对此发表评论,一切正常。
答案 0 :(得分:1)
右。关于改变表的共享能力,您有几个选项。
您可以将dba用户变为超级用户(这会绕过此用户的权限检查)或
您可以创建另一个角色(with INHERIT NOLOGIN
)为该角色分配所有权,并将该角色授予需要修改结构的任何人。添加这些选项的原因是,这不是登录角色,而是管理共享权限的角色。授予此角色的权限(以及所有权!)将在授予此角色的所有角色之间共享。
对于select用户拒绝的权限,您使用的是dbagerente用户吗?如果是这样,那么因为你因此撤销了对此的权限。如果不是您使用的是哪个用户名?
修改即可。请注意,此类RI RI触发器作为表所有者运行,因此表所有者必须具有对级联表的写访问权限,然后才能从中删除它们。
您通过(在回滚的交易中)进行测试:
BEGIN;
ALTER TABLE ... DISABLE TRIGGER ALL;
-- statements that are failing here
ROLLBACK;
所以这里的问题是表所有者没有访问权限。根据我的经验,我必须添加授予表所有者的选择权限和删除权限(如果您还有更新,则可能需要更新)。\
EDIT2:如何重现
CREATE USER myuser;
现在以myuser身份登录:
CREATE TABLE ctest1 (id int primary key);
INSERT INTO ctest1 (id) SELECT generate_series(0, 10);
CREATE TABLE ctest2 (id int references ctest1(id) on delete cascade);
INSERT INTO ctest2 (id) SELECT generate_series(0, 10);
REVOKE ALL ON ctest2 FROM myuser; -- nonsuperuser owner
现在以postgres(超级用户)身份登录:
DELETE FROM ctest1 WHERE id = 4;
-- throws the error
GRANT DELETE ON ctest2 TO myuser;
DELETE FROM ctest1 WHERE id = 4;
-- throws the error
GRANT SELECT ON ctest2 TO myuser;
DELETE FROM ctest1 WHERE id = 4; -- success