Oracle is Oracle… It has good and bad things.
The bad of course… it’s closed and you’ll be crazy before getting info about how to do things.
And the good is that everythings is inside!! just at 1 query distance ;-)
Some days ago I was trying to look for grants given to a user by another user (WITH ADMIN OPTION).
I was logged with sys and I used “my” 2 wonderful querys for obtaining that info (copy/pasted from the internet),
- Direct grants:
SELECT owner, table_name, select_priv, insert_priv, delete_priv, update_priv, references_priv, alter_priv, index_priv FROM table_privileges WHERE grantee = '&theUser' ORDER BY owner, table_name;
SELECT DISTINCT owner, table_name, PRIVILEGE FROM dba_role_privs rp JOIN role_tab_privs rtp ON (rp.granted_role = rtp.role) WHERE rp.grantee = '&theUser' ORDER BY owner, table_name;
Ressult? 0 rows! WTF!
I know there’s a plenty of it!!!
Searching a bunch of time for info about that, I didn’t find any info that helps me.
Then I thought that maybe the grants where displayed logged as the grantor user?
BINGO!
But why oracle does not shows it logged as sys?
Why don’t have a look a the perf view’s metadata?
SELECT DBMS_METADATA.GET_DDL('VIEW','USER_TAB_PRIVS','SYS') FROM DUAL ;
DBMS_METADATA.GET_DDL('VIEW','USER_TAB_PRIVS','SYS')
--------------------------------------------------------------------------------
CREATE OR REPLACE FORCE VIEW "SYS"."USER_TAB_PRIVS" ("GRANTEE", "OWNER", "T
ABLE_NAME", "GRANTOR", "PRIVILEGE", "GRANTABLE", "HI
ERARCHY") AS
select ue.name, u.name, o.name, ur.name, tpm.name,
decode(mod(oa.option$,2), 1, 'YES', 'NO'),
decode(bitand(oa.option$,2), 2, 'YES', 'NO')
from sys.objauth$ oa, sys."_CURRENT_EDITION_OBJ" o, sys.user$ u,
sys.user$ ur,
sys.user$ ue, table_privilege_map tpm
where oa.obj# = o.obj#
and oa.grantor# = ur.user#
and oa.grantee# = ue.user#
and oa.col# is null
and u.user# = o.owner#
and oa.privilege# = tpm.privilege
and userenv('SCHEMAID') in (oa.grantor#, oa.grantee#, o.owner#)
YEAH!
Let’s do some test querys at that tables! ;
SELECT * FROM sys.objauth$ WHERE ROWNUM <10 ;
SELECT * FROM sys.objauth$ WHERE COL# IS NULL AND ROWNUM <10 ;
SELECT * FROM sys."_CURRENT_EDITION_OBJ" WHERE ROWNUM <10 ;
SELECT O.NAME, OA.*
FROM sys.objauth$ oa,
sys."_CURRENT_EDITION_OBJ" o
WHERE OA.OBJ#=O.OBJ#
AND OA.COL# IS NULL
AND ROWNUM<10 ;
SELECT O.NAME, OA.*
FROM sys.objauth$ oa,
sys."_CURRENT_EDITION_OBJ" o
WHERE OA.OBJ#=O.OBJ#
AND OA.COL# IS NULL
AND O.NAME LIKE '%TEST%'
AND ROWNUM<10 ;
Nice!
So let’s do a smarter query:
COL OBJECT_NAME FORMAT A35
COL OBJECT_TYPE FORMAT A25
COL OWNER FORMAT A20
COL GRANTOR FORMAT A20
COL GRANTEE FORMAT A20
SELECT OBJECT_NAME, OBJECT_TYPE, OWNER, GRANTOR, GRANTEE
FROM (
SELECT OBJECT.NAME OBJECT_NAME,
decode (OBJECT.TYPE#,
0, 'NEXT OBJECT', 1, 'INDEX', 2, 'TABLE',
3, 'CLUSTER', 4, 'VIEW', 5, 'SYNONYM', 6, 'SEQUENCE',
7, 'PROCEDURE', 8, 'FUNCTION', 9, 'PACKAGE',
11, 'PACKAGE BODY', 12, 'TRIGGER', 13, 'TYPE',
14, 'TYPE BODY', 19, 'TABLE PARTITION',
20, 'INDEX PARTITION', 21, 'LOB', 22, 'LIBRARY',
23, 'DIRECTORY', 24, 'QUEUE', 28, 'JAVA SOURCE',
29, 'JAVA CLASS', 30, 'JAVA RESOURCE',
32, 'INDEXTYPE', 33, 'OPERATOR',
34, 'TABLE SUBPARTITION', 35, 'INDEX SUBPARTITION',
40, 'LOB PARTITION', 41, 'LOB SUBPARTITION',
42, 'MATERIALIZED VIEW', 43, 'DIMENSION',
44, 'CONTEXT', 46, 'RULE SET', 47, 'RESOURCE PLAN',
48, 'CONSUMER GROUP', 55, 'XML SCHEMA',
56, 'JAVA DATA', 57, 'EDITION', 59, 'RULE',
60, 'CAPTURE', 61, 'APPLY', 62, 'EVALUATION CONTEXT',
66, 'JOB', 67, 'PROGRAM', 68, 'JOB CLASS',
69, 'WINDOW', 72, 'SCHEDULER GROUP', 74, 'SCHEDULE',
79, 'CHAIN', 81, 'FILE GROUP', 82, 'MINING MODEL',
87, 'ASSEMBLY', 90, 'CREDENTIAL',
92, 'CUBE DIMENSION', 93, 'CUBE',
94, 'MEASURE FOLDER', 95, 'CUBE BUILD PROCESS',
100, 'FILE WATCHER', 101, 'DESTINATION','UNDEFINED'
) OBJECT_TYPE,
U.NAME OWNER,
UR.NAME GRANTOR,
UE.NAME GRANTEE
FROM sys.objauth$ oa,
sys."_CURRENT_EDITION_OBJ" OBJECT,
sys.user$ U,
sys.user$ UR,
sys.user$ UE
WHERE OA.OBJ#=OBJECT.OBJ#
AND OA.COL# IS NULL
AND U.USER#=OBJECT.OWNER#
and oa.grantor# = ur.user#
and oa.grantee# = ue.user#
)
WHERE GRANTOR='<USERNAME>'
;
The final WHERE (here matching GRANTOR), you’re able to limit the ressults by any of the selected fields:
- GRANTOR
- GRANTEE
- OWNER
- OBJECT_TYPE
- OBJECT_NAME
And why decoding the OBJECT_TYPE? Cause there’s NO TABLE inside oracle with a OBJECT_TYPE, OBJECT_NAME detailed list.
I’ve obtained the list by querying the metadata of SYS.ALL_OBJECTS ¬¬’
enjoy!