5.7. Privilégios

Quando um objeto é criado, é atribuído um dono ao mesmo. Normalmente, o dono do objeto é a função de banco de dados (identificador de autorização/role) que executou o comando de criação. Para a maioria dos tipos de objeto, o estado inicial é de apenas o dono (ou um superusuário) poder fazer alguma coisa com o objeto. Para permitir que outros o usem, devem ser concedidos privilégios.

Existem diferentes tipos de privilégios: SELECT, INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER, CREATE, CONNECT, TEMPORARY, EXECUTE e USAGE. Os privilégios aplicáveis a um determinado objeto variam dependendo do tipo do objeto (tabela, função, etc.). Mais detalhes sobre os significados desses privilégios são mostrados abaixo. As próximas seções e capítulos também mostram como esses privilégios são usados.

O privilégio de modificar ou destruir um objeto é inerente ao dono do objeto, e não pode ser concedido ou revogado. (No entanto, assim como todos os privilégios, esse direito pode ser herdado por membros da função de banco de dados (role) dona do objeto; veja Participação em função de banco de dados.)

Um objeto pode ser atribuído a um novo dono usando o comando ALTER do tipo apropriado para o objeto, por exemplo

ALTER TABLE nome_da_tabela OWNER TO novo_dono;

Os superusuários sempre podem fazer isso; as roles comuns só podem fazer isso se forem tanto a dona corrente do objeto (ou membro da role dona), quanto membro da nova role dona.

Para conceder privilégios é usado o comando GRANT. Por exemplo, se joe for uma role existente e contas for uma tabela existente, o privilégio para atualizar a tabela pode ser concedido usando:

GRANT UPDATE ON contas TO joe;

Escrever ALL no lugar de um privilégio específico concede todos os privilégios relevantes para o tipo de objeto.

O nome especial de role PUBLIC pode ser usado para conceder um privilégio para todas as roles do sistema. Além disso, podem ser configuradas roles de grupo para ajudar a gerenciar privilégios quando houver muitos usuários no banco de dados — para obter mais detalhes veja Funções de banco de dados (roles).

Para revogar um privilégio concedido anteriormente, é usado o comando REVOKE, como no exemplo abaixo:

REVOKE ALL ON contas FROM PUBLIC;

Normalmente, somente o dono do objeto (ou um superusuário) pode conceder ou revogar privilégios para um objeto. Entretanto, é possível conceder um privilégio com a opção de concessão (with grant option), que dá a quem recebe o direito de conceder o privilégio para terceiros. Se mais tarde essa opção de concessão for revogada, então todos os que receberam o privilégio a partir desse usuário (diretamente, ou através de uma cadeia de concessões), perderão esse privilégio. Para obter mais detalhes consulte as páginas de referência dos comandos GRANT e REVOKE.

O dono do objeto pode optar por revogar seus próprios privilégios comuns, como, por exemplo, tornar uma tabela somente de leitura para si e para os outros. Mas os donos são sempre tratados como detentores de todas as opções de concessão, para que sempre possam conceder novamente seus próprios privilégios.

Os privilégios disponíveis são:

SELECT

Permite selecionar (SELECT) qualquer coluna, ou coluna(s) específica(s), de uma tabela, visão, visão materializada ou de outro objeto semelhante a uma tabela. Também permite o uso do COPY TO. Esse privilégio também é necessário para fazer referência a valores de coluna existentes no comando UPDATE ou DELETE. Para sequências, esse privilégio também permite o uso da função currval. Para objetos grandes, esse privilégio permite que o objeto seja lido.

INSERT

Permite a inserção (INSERT) de uma nova linha em uma tabela, visão, etc. Pode ser concedido a colunas específicas, nesse caso apenas essas colunas podem ter valores atribuídos no comando INSERT (portanto as outras colunas recebem o seu valor padrão). Também permite usar o COPY FROM.

UPDATE

Permite atualizar (UPDATE ) qualquer coluna, ou coluna(s) específica(s), de uma tabela, visão, etc. (Na prática, qualquer comando não trivial UPDATE exigirá o privilégio SELECT também, uma vez que deve fazer referência às colunas da tabela para determinar quais linhas atualizar e/ou calcular novos valores para colunas.) SELECT ... FOR UPDATE e SELECT ... FOR SHARE também requerem esse privilégio em pelo menos uma coluna, além do privilégio SELECT. Para as sequências, esse privilégio permite o uso das funções nextval e setval. Para objetos grandes, esse privilégio permite escrever ou truncar o objeto.

DELETE

Permite excluir (DELETE) uma linha da tabela, visão, etc. (Na prática, qualquer comando não trivial DELETE exigirá o privilégio SELECT também, porque deve fazer referência às colunas da tabela para determinar quais linhas serão excluídas.)

TRUNCATE

Permite remover todas as linhas (TRUNCATE) da tabela.

REFERENCES

Permite a criação de uma restrição de chave estrangeira referenciando a tabela ou coluna(s) específica(s) da tabela.

TRIGGER

Permite a criação de um gatilho em uma tabela, visão, etc.

CREATE

Para bancos de dados, permite que novos esquemas e publicações sejam criados no banco de dados, e permite que extensões confiáveis sejam instaladas no banco de dados.

Para esquemas, permite que novos objetos sejam criados dentro do esquema. Para mudar o nome de um objeto existente, você deve ser o dono do objeto e ter esse privilégio para o esquema que o contém.

Para espaços de tabelas, permite que tabelas, índices e arquivos temporários sejam criados dentro do espaço de tabelas, e permite serem criados bancos de dados tendo o espaço de tabelas como seu espaço de tabelas padrão.

Note que revogar esse privilégio não vai alterar a existência ou a localização dos objetos existentes.

CONNECT

Permite que o favorecido por esse privilégio se conecte ao banco de dados. Esse privilégio é verificado na inicialização da conexão (além de verificar todas as restrições impostas no arquivo pg_hba.conf).

TEMPORARY

Permite a criação de tabelas temporárias durante o uso do banco de dados.

EXECUTE

Permite chamar uma função ou procedimento, incluindo o uso de quaisquer operadores implementados sobre a função. Esse é o único tipo de privilégio aplicável a funções e procedimentos.

USAGE

Para linguagens procedurais, permite o uso da linguagem para a criação de funções nessa linguagem. Esse é o único tipo de privilégio aplicável a linguagens procedurais.

Para esquemas, permite o acesso aos objetos contidos no esquema (assumindo que os próprios requisitos de privilégio dos objetos também sejam atendidos). Essencialmente, permite que o favorecido por esse privilégio procure por objetos dentro do esquema. Sem essa permissão, ainda é possível ver os nomes dos objetos, por exemplo, consultando os catálogos do sistema. Além disso, após revogar essa permissão, as sessões existentes podem ter instruções que executaram essa procura anteriormente, portanto essa não é uma maneira completamente segura de impedir o acesso ao objeto.

Para sequências, permite o uso das funções currval e nextval.

Para tipos de dados e domínios, permite o uso do tipo de dados ou domínio na criação de tabelas, funções e outros objetos do esquema. (Note que esse privilégio não controla todo o uso do tipo de dados, como valores do tipo de dados que aparecem nas consultas. Apenas impede a criação de objetos que dependem desse tipo de dados. O objetivo principal desse privilégio é controlar quais usuários podem criar dependências sobre o tipo de dado, o que pode impedir que o dono altere o tipo de dados posteriormente.)

Para empacotadores de dados estrangeiros, permite a criação de novos servidores utilizando um empacotador de dados estrangeiros. [32] [33]

Para servidores estrangeiros, permite a criação de tabelas remotas usando o servidor. Os favorecidos por esse privilégio também podem criar, modificar ou excluir seus próprios mapeamentos de usuário associados a esse servidor.

Os privilégios exigidos por outros comandos estão listados na página de referência do respectivo comando.

Por padrão, o PostgreSQL concede privilégios para PUBLIC em alguns tipos de objeto, quando esses objetos são criados. Nenhum privilégio é concedido para PUBLIC por padrão em tabelas, colunas de tabela, sequências, empacotadores de dados estrangeiros, servidores estrangeiros, objetos grandes, esquemas ou espaços de tabela. Para outros tipos de objeto, os privilégios padrão concedidos a PUBLIC são os seguintes: CONNECT e TEMPORARY (criar tabelas temporárias) para bancos de dados; EXECUTE para funções e procedimentos; e USAGE para idiomas e tipos de dados (incluindo domínios). O dono do objeto pode, é claro, revogar (REVOKE) os privilégios padrão e os expressamente concedidos. (Para segurança máxima, deve ser incluído o comando REVOKE na mesma transação que cria o objeto; com isso não haverá uma janela na qual outro usuário possa usar o objeto.) Além disso, essas configurações de privilégio padrão podem ser modificadas usando o comando ALTER DEFAULT PRIVILEGES.

A Tabela 5.1 mostra as abreviaturas de uma letra usadas para esses tipos de privilégio nos valores de ACL (Lista de Controle de Acesso). Você verá essas letras na saída dos comandos psql listados abaixo, ou ao examinar as colunas ACL dos catálogos do sistema.

Tabela 5.1. Abreviatura do privilégio na lista de controle de acesso (ACL)

PrivilégioAbreviaturaTipos de objetos aplicáveis
SELECTr (read) LARGE OBJECT, SEQUENCE, TABLE (e objetos tipo-tabela), coluna de tabela
INSERTa (append)TABLE, coluna de tabela
UPDATEw (write) LARGE OBJECT, SEQUENCE, TABLE, coluna de tabela
DELETEdTABLE
TRUNCATEDTABLE
REFERENCESxTABLE, coluna de tabela
TRIGGERtTABLE
CREATEC DATABASE, SCHEMA, TABLESPACE
CONNECTcDATABASE
TEMPORARYTDATABASE
EXECUTEXFUNCTION, PROCEDURE
USAGEU DOMAIN, FOREIGN DATA WRAPPER, FOREIGN SERVER, LANGUAGE, SCHEMA, SEQUENCE, TYPE

A Tabela 5.2 resume os privilégios disponíveis para cada tipo de objeto SQL, usando as abreviaturas mostradas acima. Também mostra o comando psql que pode ser usado para examinar as configurações de privilégio para cada tipo de objeto.

Tabela 5.2. Resumo dos privilégios de acesso

Tipo de objetoTodos os privilégiosPrivilégios padrão para PUBLICComando psql
DATABASECTcTc\l
DOMAINUU\dD+
FUNCTION ou PROCEDUREXX\df+
FOREIGN DATA WRAPPERUnenhum\dew+
FOREIGN SERVERUnenhum\des+
LANGUAGEUU\dL+
LARGE OBJECTrwnenhum 
SCHEMAUCnenhum\dn+
SEQUENCErwUnenhum\dp
TABLE (e objetos tipo-tabela)arwdDxtnenhum\dp
Coluna de tabelaarwxnenhum\dp
TABLESPACECnenhum\db+
TYPEUU\dT+

Os privilégios concedidos a um determinado objeto são exibidos como uma lista de entradas aclitem, onde cada aclitem descreve as permissões de um favorecido concedidas por um determinado concedente. Por exemplo, calvin=r*w/hobbes especifica que a função de banco de dados (role) calvin tem o privilégio SELECT (r) com opção de concessão (*), assim como o privilégio não concedível UPDATE (w), ambos concedidos pela função de banco de dados hobbes. Se calvin também tiver alguns privilégios no mesmo objeto concedidos por outro concedente, eles vão aparecer como uma entrada aclitem separada. Um campo de favorecido vazio em um aclitem significa PUBLIC.

Como exemplo, suponha que a usuária miriam crie a tabela minha_tabela e execute:

GRANT SELECT ON minha_tabela TO PUBLIC;
GRANT SELECT, UPDATE, INSERT ON minha_tabela TO admin;
GRANT SELECT (col1), UPDATE (col1) ON minha_tabela TO miriam_rw;

Então o comando \dp do psql vai mostrar:

miriam=> \dp minha_tabela

                                    Access privileges
 Schema |     Name     | Type  |   Access privileges   |   Column privileges   | Policies
--------+--------------+-------+-----------------------+-----------------------+----------
 public | minha_tabela | table | miriam=arwdDxt/miriam+| col1:                +|
        |              |       | =r/miriam            +|   miriam_rw=rw/miriam |
        |              |       | admin=arw/miriam      |                       |
(1 linha)

Se a coluna Privilégios de acesso estiver vazia para um determinado objeto, isso significa que o objeto tem privilégios padrão (ou seja, sua entrada de privilégios no catálogo do sistema é nula). Os privilégios padrão sempre incluem todos os privilégios do dono, podendo incluir alguns privilégios para PUBLIC, dependendo do tipo de objeto, conforme explicado acima. O primeiro comando GRANT ou REVOKE em um objeto instanciará os privilégios padrão (produzindo, por exemplo, miriam=arwdDxt/miriam), e depois os modificará pela solicitação específica. Da mesma forma, as entradas são mostradas em Privilégios de coluna apenas para as colunas com privilégios diferentes do padrão. (Nota: nesse contexto, privilégios padrão sempre significa os privilégios padrão incorporados para o tipo do objeto. Um objeto cujos privilégios foram afetados pelo comando ALTER DEFAULT PRIVILEGES sempre será mostrado com uma entrada de privilégio explícita que inclui os efeitos do ALTER.)

Note que as opções de concessão implícitas do dono não são marcadas na exibição de privilégios de acesso. Um * aparecerá somente quando as opções de concessão tiverem sido concedidas explicitamente a alguém.



[32] foreign data wrapper: Um tipo comum de extensão do postgres é o empacotador de dados estrangeiros. Originalmente projetado para expor tabelas e relações em um servidor SQL estrangeiro, para poderem ser consultadas e processadas em um servidor postgres diferente, a arquitetura permite o desenvolvimento de extensões para expor muitas fontes de dados estrangeiras como tabelas para o servidor postgres. Elas podem ser consultadas e processadas usando todo o poder do mecanismo de consulta do postgres, podendo ser facilmente combinadas com dados locais ou outros dados remotos usando recursos de consulta poderosos, como junções e agregações. Creating a Postgres Foreign Data Wrapper (N. T.)

[33] foreign data wrapper: Um empacotador de dados estrangeiros é uma extensão disponível no PostgreSQL que permite acessar uma tabela ou esquema em um banco de dados a partir de outro. How to Set Up a Foreign Data Wrapper in PostgreSQL (N. T.)