List All Privileges For a Particular User

Users’ privilege management is usually done with a few catalogs. To name few, it is dba_roles_privs, dba_sys_privs, dba_tab_privs, and dba_col_privs. Check out those scripts below waiting to help you out 🙂

-- concise version .. good for an overall and high-level checking
SELECT a.*
FROM (SELECT 'ROLE' typ
            ,grantee grantee
            ,granted_role priv
            ,admin_option ad
            ,'--' tabnm
            ,'--' colnm
            ,'--' owner
            ,r.password_required pwd
      FROM dba_role_privs rp
      --
      JOIN dba_roles r
      ON rp.granted_role = r.role
      --
      WHERE 1 = 1
            UNION
      SELECT 'SYSTEM' typ
            ,grantee grantee
            ,privilege priv
            ,admin_option ad
            ,'--' tabnm
            ,'--' colnm
            ,'--' owner
            ,'--' pwd
      FROM dba_sys_privs
      --
      WHERE 1 = 1
            UNION
      SELECT 'TABLE' typ
            ,grantee grantee
            ,privilege priv
            ,grantable ad
            ,table_name tabnm
            ,'--' colnm
            ,owner owner
            ,'--' pwd
      FROM dba_tab_privs
      --
      WHERE 1 = 1
            UNION
      SELECT 'COLUMN' typ
            ,grantee grantee
            ,privilege priv
            ,grantable ad
            ,table_name tabnm
            ,column_name colnm
            ,owner owner
            ,'--' pwd
      FROM dba_col_privs
      --
      WHERE 1 = 1
      ) a
WHERE 1 = 1
AND grantee = 'JOHN_DOE'
--
ORDER BY DECODE(a.typ,
                'ROLE',4,
                'SYSTEM',1,
                'TABLE',2,
                'COLUMN',3,
                5)
        ,CASE
           WHEN a.priv IN ('EXECUTE') THEN 1
           WHEN a.priv IN ('SELECT', 'UPDATE', 'INSERT', 'DELETE') THEN 3
           ELSE 2
         END
        ,a.tabnm
        ,a.colnm
        ,a.priv;

If you are serious about privilege checking, have a look at this monster 🙂 It takes a little longer to proceed but will give you a very detailed overview of a particular user and his access privileges. The last row (ROLES) will show you through which role is that particular privilege granted/inherited (NULL = direct grant).

-- users --------------------------------------------------------------------------
WITH w_usr AS (
               SELECT username
               FROM dba_users
               WHERE 1=1
               --AND username in ('JOHN_DOE') 
              )
-- objects ------------------------------------------------------------------------
, w_obj AS (
            SELECT p.grantee
                  ,p.owner
                  ,p.table_name
                  ,p.privilege
                  --,p.grantor
                  --,p.grantable
                  --,p.hierarchy
            FROM dba_tab_privs p
            
              UNION ALL
              
            SELECT grantee
                  ,NULL      owner
                  ,NULL      table_name
                  ,privilege
            --,admin_option
            FROM dba_sys_privs
           )
-- roles hierachy -----------------------------------------------------------------           
, w_rol AS (
            SELECT connect_by_root r.grantee grantee
                  ,r.granted_role
                  ,LEVEL llevel
                  ,sys_connect_by_path(r.granted_role, ' -> ') roles
            FROM dba_role_privs r
            START WITH r.grantee IN (SELECT username FROM w_usr)
            CONNECT BY r.grantee = PRIOR r.granted_role
           )
-- Direct grant -------------------------------------------------------------------
, w_drc AS (
              SELECT o.grantee
                    , /*+ PARALLEL(4) */t.object_type
                    ,o.owner
                    ,o.table_name
                    ,o.privilege
                    ,0 llevel
                    ,NULL
              FROM w_obj       o
                  ,dba_objects t
              WHERE grantee IN (SELECT username FROM w_usr)
              AND o.owner = t.owner
              AND o.table_name = t.object_name
              AND t.subobject_name IS NULL
            )
--------------------------------------------------------------------------------------------------
SELECT a.*
FROM (
      SELECT /*+ PARALLEL(4) */
       r.grantee
      ,t.object_type
      ,o.owner
      ,o.table_name object_name
      ,o.privilege
      ,r.llevel
      ,substr(r.roles, 5) roles
      FROM w_rol         r
          ,w_obj         o
          ,dba_objects t
      WHERE r.granted_role = o.grantee(+)
      AND o.owner = t.owner(+)
      AND o.table_name = t.object_name(+)
      AND t.subobject_name IS NULL
      
          UNION ALL
      
      SELECT * 
      FROM w_drc
      WHERE 1=1
     ) a
WHERE 1 = 1
AND grantee IN ('JOHN_DOE')
--AND owner = 'SCHEMA_NAME'

You can limit the list of users right in the W_USR query in order to speed up the result retrieval. You can also use some masks to filter out only some user “categories” (application accounts, user accounts, system accounts only, … )