Frequentemente é conveniente agrupar usuários para facilitar o gerenciamento de privilégios: dessa forma, os privilégios podem ser concedidos ou revogados para um grupo como um todo. No PostgreSQL isto é feito criando uma função de banco de dados (role) que representa o grupo e, em seguida, concedendo a participação de usuários individualmente nesta função de banco de dados de grupo, tornando-os membros dessa função de banco de dados.
Para definir uma função de banco de dados de grupo, primeiro é criada a função de banco de dados:
CREATE ROLE nome;
Normalmente, a função de banco de dados a ser utilizada como um
grupo não possui o atributo LOGIN definido,
embora se possa defini-lo se assim desejar.
Após a função de banco de dados de grupo ter sido criada, será possível adicionar e remover membros usando os comandos GRANT e REVOKE:
GRANTnome_da_role_de_grupoTOrole1, ... ; REVOKEnome_da_role_de_grupoFROMrole1, ... ;
Também pode ser concedida participação a outras funções de banco
de dados de grupo
(já que não existe realmente nenhuma distinção entre funções de banco
de dados de grupo e funções de banco de dados que não são de grupo).
O banco de dados não permitirá que se configure laços de participação
circulares.
Além disso, não é permitido conceder participação em uma função
de banco de dados para PUBLIC.
Os membros de uma função de banco de dados de grupo podem utilizar
os privilégios da função de banco de dados de duas maneiras.
Primeiro, as funções de banco de dados membro às quais foi
concedida a participação com a opção SET podem
executar SET ROLE para se tornarem
temporariamente a função de banco de dados de grupo.
Neste estado, a sessão de banco de dados tem acesso aos privilégios
da função de banco de dados de grupo, em vez da função de banco de
dados da conexão original, e quaisquer objetos de banco de dados
criados são considerados de propriedade da função de banco de dados
de grupo, e não da função de banco de dados da conexão.
Em segundo lugar, as funções de banco de dados membro às quais
foi concedida a participação com a opção INHERIT
herdam automaticamente os privilégios das funções de banco de dados
das quais são membros (direta ou indiretamente), embora a cadeia seja
interrompida em participações que não possuam a opção de herança.
Como exemplo, supondo que tenha sido executado:
CREATE ROLE joe LOGIN; CREATE ROLE admin; CREATE ROLE wheel; CREATE ROLE island; GRANT admin TO joe WITH INHERIT TRUE; GRANT wheel TO admin WITH INHERIT FALSE; GRANT island TO joe WITH INHERIT TRUE, SET FALSE;
Imediatamente após conectar-se como a função de banco de dados
joe, a sessão de banco de dados terá acesso aos
privilégios concedidos diretamente a joe,
mais quaisquer privilégios concedidos a admin e
island,
porque joe “herda” estes privilégios.
Entretanto, os privilégios concedidos à wheel não
estão disponíveis, porque embora joe seja
indiretamente membro de wheel, a participação é
feita via admin, que foi concedida usando
WITH INHERIT FALSE.
Após
SET ROLE admin;
a sessão utilizaria apenas os privilégios concedidos a
admin, e não aqueles concedidos a
joe ou island.
Após
SET ROLE wheel;
a sessão teria acesso apenas aos privilégios concedidos a
wheel, e não aqueles concedidos a
joe ou a admin.
O estado inicial de privilégios pode ser restaurado por qualquer
um dos seguintes comandos:
SET ROLE joe; SET ROLE NONE; RESET ROLE;
O comando SET ROLE sempre permite selecionar
qualquer função de banco de dados da qual a função de banco de dados
da conexão original seja membro direta ou indiretamente, desde que
exista uma cadeia de associação de concessões em que cada uma delas
tenha SET TRUE (que é o padrão).
Assim, no exemplo acima, não é necessário tornar-se
admin antes de tornar-se wheel.
Por outro lado, não é possível tornar-se island
de forma alguma; joe só pode acessar estes
privilégios por meio de herança.
No padrão SQL há uma distinção clara entre
usuários e funções de banco de dados, e os usuários não herdam
privilégios automaticamente, enquanto as funções de banco de dados
sim.
Este comportamento pode ser emulado no
PostgreSQL atribuindo às funções
de banco de dados sendo usadas como funções de banco de
dados do SQL o atributo INHERIT,
enquanto dando às funções de banco de dados que estão sendo usadas
como usuários do SQL o atributo
NOINHERIT.
Entretanto, o padrão do PostgreSQL
é dar a todas as funções de banco de dados o atributo
INHERIT, para manter a compatibilidade com as
versões anteriores à versão 8.1, nas quais os usuários sempre tiveram
acesso às permissões concedidas a grupos dos quais eram membros.
Os atributos de função de banco de dados LOGIN,
SUPERUSER, CREATEDB e
CREATEROLE podem ser vistos como privilégios
especiais, mas nunca são herdados como privilégios comuns em objetos
de banco de dados.
Na verdade, é necessário usar SET ROLE para uma
função de banco de dados específica com um desses atributos
para poder usar o atributo.
Continuando o exemplo acima, pode-se optar por conceder
CREATEDB e CREATEROLE para a
função de banco de dados admin.
Então uma sessão conectando como a função de banco de dados
joe não teria estes privilégios imediatamente,
somente após executar SET ROLE admin.
Para remover uma função de banco de dados de grupo, é usado o comando DROP ROLE:
DROP ROLE nome_da_role_de_grupo;
Quaisquer participações na função de banco de dados de grupo são revogadas automaticamente (mas as funções de banco de dados dos membros não são afetadas de outra forma).