PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

PostgreSQL - o usuário do banco de dados só deve ter permissão para chamar funções


Não há "privilégio em SELECT ". Tudo que você precisa é o privilégio de EXECUTAR funções. A função relevante pode ser executada com SECURITY DEFINIDO herdar todos os privilégios do proprietário. Para restringir o possível escalonamento de privilégios ao mínimo a priori, faça com que uma função de daemon possua funções relevantes apenas com os privilégios necessários - não um superusuário!

Receita


Como superusuário...

Crie uma função de não superusuário myuser .
CREATE ROLE myuser PASSWORD ...;

Crie uma função de grupo mygroup e faça meuusuário membro nele.
CREATE ROLE mygroup;
GRANT mygroup TO myuser;

Você pode querer adicionar mais usuários como myuser mais tarde.

não conceda nenhum privilégio para meuusuário .
Conceda-os apenas a mygroup :
  • GRANT CONNECT ON DATABASE mydb TO mygroup;
  • GRANT USUSE ON SCHEMA public TO mygroup;
  • GRANT EXECUTE ON FUNCTION foo() PARA mygroup;

Remover todos privilégios para public que meuusuário não deveria.
REVOKE ALL ON ALL TABLES IN SCHEMA myschema FROM public;

Pode haver mais. Cito o manual:

Crie uma função de daemon para possuir funções relevantes.
CREATE ROLE mydaemon;

Conceda apenas os privilégios necessários para executar essas funções para mydaemon , (incluindo EXECUTAR NA FUNÇÃO para permitir que outra função seja chamada). Novamente, você pode usar funções de grupo para agrupar privilégios e concedê-los a mydaemon
GRANT bundle1 TO mydaemon;

Além disso, você pode usar DEFAULT PRIVILEGES para conceder automaticamente certos privilégios para objetos futuros a um pacote ou ao daemon diretamente:
ALTER DEFAULT PRIVILEGES IN SCHEMA myschema GRANT SELECT ON TABLES    TO bundle1;
ALTER DEFAULT PRIVILEGES IN SCHEMA myschema GRANT USAGE  ON SEQUENCES TO bundle1;

Isso se aplica apenas à função para a qual é executado. De acordo com a documentação:

Para também abranger objetos pré-existentes no esquema (consulte comentário de rob ):
GRANT SELECT ON ALL TABLES    IN SCHEMA public TO bundle1;
GRANT USAGE  ON ALL SEQUENCES IN SCHEMA public TO bundle1;

Faça mydaemon próprias funções relevantes. Poderia ficar assim:
CREATE OR REPLACE FUNCTION foo()
  ...
SECURITY DEFINER SET search_path = myschema, pg_temp;

ALTER FUNCTION foo() OWNER TO mydaemon;
REVOKE EXECUTE ON FUNCTION foo() FROM public;
GRANT  EXECUTE ON FUNCTION foo() TO mydaemon;
GRANT  EXECUTE ON FUNCTION foo() TO mygroup;
-- possibly others ..

###Nota
Devido a este bug na versão atual 1.16.1 do pgAdmin o comando necessário

REVOKE EXECUTE ON FUNCTION foo() FROM public;

está faltando no script DDL de engenharia reversa. Lembre-se de adicioná-lo, ao recriar.
Este bug foi corrigido na versão atual pgAdmin 1.18.1.