When performing a database security audit various informations about users, roles and privileges have to be collected, including “who has unlimited tablespace on SYSTEM”. It is quite easy to find user with UNLIMITED TABLESPACE or a UNLIMITED quota on SYSTEM. But what when the system privilege is assigned to a role or over several roles? It is still easy if you use hierarchical queries to drill down the cascaded roles, but there is plenty to write.
Ok, why do we want to know who has unlimited quota on the SYSTEM tablespace?
User who have unlimited quota on SYSTEM as well the privilege to create tables or clusters could do some kind of denial of service attack to the database. The just have to fill up the free space in the SYSTEM tablespace. If there default tablespace is as well SYSTEM the could even do this without intention.
Then let’s find them
First find the user with direct quota on tablespace SYSTEM.
SELECT username,tablespace_name, bytes, max_bytes FROM dba_ts_quotas WHERE max_bytes = -1 AND tablespace_name ='SYSTEM'; USERNAME TABLESPACE_NAME BYTES MAX_BYTES ------------------------- ------------------------- ---------- ---------- SCOTT SYSTEM 0 -1 TEST SYSTEM 0 -1
As mentioned above it is quite easy to find user with system privilege UNLIMITED TABLESPACE.
select * from dba_sys_privs where privilege = 'UNLIMITED TABLESPACE' GRANTEE PRIVILEGE ADM ------------------------------ ------------------------------ --- WMSYS UNLIMITED TABLESPACE NO RRDOMREG UNLIMITED TABLESPACE NO HR UNLIMITED TABLESPACE NO OE UNLIMITED TABLESPACE NO SYS UNLIMITED TABLESPACE NO LOGSTDBY_ADMINISTRATOR UNLIMITED TABLESPACE NO SCOTT UNLIMITED TABLESPACE NO BI UNLIMITED TABLESPACE NO OUTLN UNLIMITED TABLESPACE NO DBSNMP UNLIMITED TABLESPACE NO IX UNLIMITED TABLESPACE NO SH UNLIMITED TABLESPACE NO DBA UNLIMITED TABLESPACE YES SYSTEM UNLIMITED TABLESPACE YES 14 rows selected.
What about cascaded roles?
Mmh, but since Oracle 11g it is possible to grant UNLIMITED TABLESPACE to a role and this can be granted to an other role which is granted again to an other role. It could be a role concept or somebody who want to hide a little bit some privileges. To test it I’ve created three roles DBA3, DBA2 and DBA1, granted UNLIMITED TABLESPACE to DBA3.
SELECT
grantee,
privilege,
DECODE(p,'=>'||grantee,'direct',p) path
FROM (
SELECT
grantee,
privilege,
SYS_CONNECT_BY_PATH(grantee, '=>') p
FROM (
SELECT
grantee,
privilege
FROM dba_sys_privs
UNION ALL
SELECT
grantee,
granted_role privilege
FROM
dba_role_privs)
START WITH privilege = 'UNLIMITED TABLESPACE'
CONNECT BY PRIOR grantee = privilege )
WHERE
(grantee in (SELECT username FROM dba_users)
OR grantee = 'PUBLIC');
GRANTEE PRIVILEGE PATH
--------- ----------------------- -------------------------------
BI UNLIMITED TABLESPACE direct
SYS DBA =>DBA=>SYS
SYSTEM DBA =>DBA=>SYSTEM
SCOTT DBA1 =>DBA3=>DBA2=>DBA1=>SCOTT
SYS DBA1 =>DBA3=>DBA2=>DBA1=>SYS
SYS DBA2 =>DBA3=>DBA2=>SYS
SYS DBA3 =>DBA3=>SYS
DBSNMP UNLIMITED TABLESPACE direct
HR UNLIMITED TABLESPACE direct
IX UNLIMITED TABLESPACE direct
SYS LOGSTDBY_ADMINISTRATOR =>LOGSTDBY_ADMINISTRATOR=>SYS
OE UNLIMITED TABLESPACE direct
OUTLN UNLIMITED TABLESPACE direct
RRDOMREG UNLIMITED TABLESPACE direct
SH UNLIMITED TABLESPACE direct
SYS UNLIMITED TABLESPACE direct
SYSTEM UNLIMITED TABLESPACE direct
WMSYS UNLIMITED TABLESPACE direct
18 rows selected.
We now see that SCOTT has UNLIMITED TABLESPACE through DBA3, DBA2 and DBA1
All wrapped up
Ok, create one to find user’s with direct quotas as well through a system privilege will give something like this.
SELECT
username,
tablespace_name,
privilege
FROM (
SELECT
grantee username, 'Any Tablespace' tablespace_name, privilege
FROM (
-- first get the users with direct grants
SELECT
p1.grantee grantee, privilege
FROM
dba_sys_privs p1
WHERE
p1.privilege='UNLIMITED TABLESPACE'
UNION ALL
-- and then the ones with UNLIMITED TABLESPACE through a role...
SELECT
r3.grantee, granted_role privilege
FROM
dba_role_privs r3
START WITH r3.granted_role IN (
SELECT
DISTINCT p4.grantee
FROM
dba_role_privs r4, dba_sys_privs p4
WHERE
r4.granted_role=p4.grantee
AND p4.privilege = 'UNLIMITED TABLESPACE')
CONNECT BY PRIOR grantee = granted_role)
-- we just whant to see the users not the roles
WHERE grantee IN (SELECT username FROM dba_users) OR grantee = 'PUBLIC'
UNION ALL
-- list the user with unimited quota on a dedicated tablespace
SELECT
username,tablespace_name,'DBA_TS_QUOTA' privilege
FROM
dba_ts_quotas
WHERE
max_bytes = -1 )
WHERE tablespace_name LIKE UPPER('SYSTEM')
OR tablespace_name = 'Any Tablespace';
USERNAME TABLESPACE_NAME PRIVILEGE
------------------------- ------------------------- ------------------------------
...
SYSTEM Any Tablespace UNLIMITED TABLESPACE
SYS Any Tablespace DBA
SYSTEM Any Tablespace DBA
SCOTT Any Tablespace DBA1
SYS Any Tablespace DBA1
SYS Any Tablespace DBA2
SYS Any Tablespace DBA3
SYS Any Tablespace LOGSTDBY_ADMINISTRATOR
TEST SYSTEM DBA_TS_QUOTA
19 rows selected.
Due to the fact that the query is far to long to write more than one time, I’ve put everything in one script.
@tsq SYSTEM User Name Tablespace Name Privilege ------------- ---------------------- ------------------------- BI Any Tablespace UNLIMITED TABLESPACE DBSNMP Any Tablespace UNLIMITED TABLESPACE HR Any Tablespace UNLIMITED TABLESPACE IX Any Tablespace UNLIMITED TABLESPACE OE Any Tablespace UNLIMITED TABLESPACE OUTLN Any Tablespace UNLIMITED TABLESPACE ....
The tsq.sql script can be downloaded at the script section of OraDBA or direct (
tsq.sql). All OraDBA scripts can also be downloaded as a complete archive (
oradba.tgz).
