Preciso ver todas as funções de um usuário, incluindo as funções herdadas de uma função.
Considere, por exemplo, este arranjo:
CREATE USER TEMPUSER1 IDENTIFIED BY "TEMPUSER1" ACCOUNT LOCK;
CREATE USER TEMPUSER2 IDENTIFIED BY "TEMPUSER2" ACCOUNT LOCK;
CREATE ROLE TEMP_ROLE1;
CREATE ROLE TEMP_ROLE2;
CREATE ROLE TEMP_ROLE3;
CREATE ROLE TEMP_ROLE4;
CREATE ROLE TEMP_ROLE5;
GRANT TEMP_ROLE1 TO TEMP_ROLE3;
GRANT TEMP_ROLE2 TO TEMP_ROLE3;
GRANT TEMP_ROLE3 TO TEMP_ROLE4;
GRANT TEMP_ROLE3 TO TEMP_ROLE5;
GRANT TEMP_ROLE4 TO TEMP_ROLE6;
GRANT TEMP_ROLE5 TO TEMP_ROLE6;
GRANT TEMP_ROLE2 TO TEMPUSER1;
GRANT TEMP_ROLE4 TO TEMPUSER1;
GRANT TEMP_ROLE6 TO TEMPUSER1;
GRANT TEMP_ROLE2 TO TEMPUSER2;
Então eu quero o resultado
GRANTED_USER | GRANTED_ROLE
---------------+---------------
TEMPUSER1 | TEMP_ROLE1
TEMPUSER1 | TEMP_ROLE2
TEMPUSER1 | TEMP_ROLE3
TEMPUSER1 | TEMP_ROLE4
TEMPUSER1 | TEMP_ROLE5
TEMPUSER2 | TEMP_ROLE1
TEMPUSER2 | TEMP_ROLE2
Estou usando o Oracle 11.2g, mas também quero respostas para futuras versões do Oracle. Eu gostaria que essa pergunta permanecesse relevante se a Oracle introduzisse novos recursos que facilitassem isso (como uma visão que apenas nos fornece isso diretamente sem escrever nossas próprias consultas).
Explicação
A visão que nos informa sobre as
GRANT
funções de ed éDBA_ROLE_PRIVS
. (Há tambémUSER_ROLE_PRIVS
, mas mostra apenas as funções concedidas ao usuário atual.) No entanto, essa visualização não nos fornece todas as funções herdadas. Seguir as funções do usuário recursivamente requer uma consulta "hierárquica" ou, mais simplesmente, conhecida como consulta recursiva.START WITH
cláusula deve garantir queGRANTEE = 'TEMPUSER1'
.GRANTEE
é uma das funções concedidas ao usuário de interesse até o momento. Isso significa que nossaCONNECT BY
cláusula deve garantir quePRIOR GRANTED_ROLE = GRANTEE
.CONNECT_BY_ROOT GRANTEE
, que nos fornecerá asGRANTEE
linhas iniciais (e começamos com nosso usuário de interesse).TEMP_ROLE6
herdaTEMP_ROLE3
. Isso significa que precisaremos de algum tipo deDISTINCT
ouGROUP BY
.A pergunta
Montar tudo isso em uma consulta nos dá:
Isto dá o resultado exato desejado.
Informações de bônus: Origem da função
Aqui está uma consulta alternativa que inclui algumas informações extras sobre como o usuário obteve a função:
Observe que a consulta mostra
'Direct GRANT'
quando a função é concedida diretamente ao usuário. Isso se destaca um pouco melhor do que apenas mostrar o nome do usuário na lista.Observe que ainda precisamos do
DISTINCT
na subconsulta. Isso é necessário porqueTEMPUSER1
obtémTEMP_ROLE4
duas vezes, uma vez de um directGRANT
e uma vez deTEMP_ROLE6
. Sem oDISTINCT
,TEMP_ROLE4
apareceria duas vezes como a fonte doTEMP_ROLE3
.O resultado fica assim:
Para todos os usuários
Essas consultas podem ser facilmente adaptadas para mostrar funções para todos os usuários no banco de dados. Tudo o que é necessário é alterar a
START WITH
cláusula para:Para funções
As consultas funcionam igualmente bem se você quiser visualizar as funções concedidas a uma função específica. Você só precisa especificar o nome da função como o
GRANTEE
. Por exemplo,Ou para todas as funções: