5.8. Privilégios #

Quando um objeto é criado, é atribuído um dono a ele. 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, USAGE, SET, ALTER SYSTEM e MAINTAIN. Os privilégios aplicáveis a um determinado objeto variam dependendo do tipo do objeto (tabela, função, etc.). Mais detalhes sobre os significados destes privilégios são mostrados abaixo. As próximas seções e capítulos também mostram como estes 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 a Seção 21.3.)

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

ALTER TABLE nome_da_tabela OWNER TO novo_dono;

Os superusuários sempre podem fazer isto; as roles comuns só poderão fazer isto se forem as proprietárias atuais do objeto (ou herdarem os privilégios da role proprietária) e puderem executar SET ROLE para a nova role proprietária.

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 poderá 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 o Capítulo 21.

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 esta opção de concessão for revogada, então todos que receberam o privilégio a partir deste usuário (diretamente, ou por meio de uma cadeia de concessões), perderão este 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. Este privilégio também é necessário para fazer referência a valores atuais de colunas nos comandos UPDATE, DELETE ou MERGE. Para sequências, este privilégio também permite o uso da função currval. Para objetos grandes, este 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; neste caso, apenas estas colunas poderão ter valores atribuídos pelo 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, este 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 deverá 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, é necessário ser o dono do objeto e ter este 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 que sejam criados bancos de dados tendo o espaço de tabelas como seu espaço de tabelas padrão.

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

CONNECT #

Permite que o favorecido por este privilégio se conecte ao banco de dados. Este 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. Este é 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 esta permissão, ainda é possível ver os nomes dos objetos, por exemplo, consultando os catálogos do sistema. Além disso, após revogar esta permissão, as sessões existentes podem ter instruções que executaram esta procura anteriormente, portanto esta 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. [33] [34]

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 este servidor.

SET #

Permite que um parâmetro de configuração do servidor seja configurado com um novo valor dentro da sessão atual. (Embora este privilégio possa ser concedido a qualquer parâmetro, ele é irrelevante, exceto para parâmetros que normalmente exigiriam privilégios de superusuário para serem definidos.)

ALTER SYSTEM #

Permite que um parâmetro de configuração do servidor seja configurado com um novo valor usando o comando ALTER SYSTEM.

MAINTAIN #

Permite o uso de VACUUM, ANALYZE, CLUSTER, REFRESH MATERIALIZED VIEW, REINDEX, LOCK TABLE e funções de tratamento de estatísticas de objetos de banco de dados (veja a Tabela 9.105) em uma relação.

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 estes 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, espaços de tabela ou parâmetros de configuração. 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, estas 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 da ACL (Lista de Controle de Acesso). Estas letras são vistas na saída dos comandos psql listados abaixo ou ao examinar as colunas da ACL dos catálogos do sistema.

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

PrivilégioAbreviaturaTipos de objetos envolvidos
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
SETsPARAMETER
ALTER SYSTEMAPARAMETER
MAINTAINmTABLE

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 do 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\dl+
PARAMETERsAnenhum\dconfig+
SCHEMAUCnenhum\dn+
SEQUENCErwUnenhum\dp
TABLE (e objetos similares)arwdDxtmnenhum\dp
Coluna de tabelaarwxnenhum\dp
TABLESPACECnenhum\db+
TYPEUU\dT+

Os privilégios concedidos para um determinado objeto são exibidos como uma lista de entradas aclitem, cada uma com o seguinte formato:


beneficiário=abreviatura-do-privilégio[*].../outorgante

Cada aclitem lista todas as permissões de um beneficiário que foram concedidas por um outorgante específico. Privilégios específicos são representados por abreviaturas de uma letra da Tabela 5.1, com * apensados se o privilégio foi concedido com a opção de concessão. Por exemplo, calvin=r*w/hobbes especifica que a role calvin possui 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 role hobbes. Se calvin também tiver alguns privilégios neste mesmo objeto concedidos por um outorgante diferente, estes apareceriam como uma entrada aclitem separada. Um campo vazio em um aclitem significa PUBLIC.

Como exemplo, vamos supor que a usuária miriam tenha criado a tabela minha_tabela e executado os seguintes comandos:

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 iria mostrar:

=> \dp minha_tabela
                                    Privilégios de acesso
 Esquema |     Nome     |  Tipo  | Privilégios de acesso  | Privilégios de coluna | Políticas
---------+--------------+--------+------------------------+-----------------------+-----------
 public  | minha_tabela | tabela | miriam=arwdDxtm/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, isto significa que o objeto possui os privilégios padrão (ou seja, sua entrada de privilégios no catálogo do sistema relevante é nula). Os privilégios padrão sempre incluem todos os privilégios do dono e podem incluir alguns privilégios para PUBLIC, dependendo do tipo de objeto, conforme explicado acima. O primeiro comando GRANT ou REVOKE em um objeto irá instanciar os privilégios padrão (produzindo, por exemplo, miriam=arwdDxtm/miriam) e então modificá-los conforme a solicitação especificada. Da mesma forma, as entradas são mostradas em Privilégios de coluna somente para colunas com privilégios diferentes do padrão (Nota: para este propósito, privilégios padrão sempre significa os privilégios padrão nativos para o tipo do objeto. Um objeto cujos privilégios foram afetados por um comando ALTER DEFAULT PRIVILEGES será sempre mostrado como uma entrada de privilégio explícita que inclui os efeitos do comando 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.

A coluna Privilégios de acesso mostra (nenhum) quando a entrada de privilégios do objeto não é nula, mas está vazia. Isto significa que nenhum privilégio foi concedido, nem mesmo para o dono do objeto — uma situação rara. (Neste caso, o dono ainda possui opções de concessão implícitas e, portanto, poderia conceder novamente seus próprios privilégios; porém, no momento, não os possui.)



[33] 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.)

[34] 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.)