Security Advisory |
If you build a house on a bad foundation you should not be surprised when walls start cracking and the house collapses.
Building an Oracle Database based application with a "normal" user and expecting it to be secure is a guarantee that any attacker with half a skill set can take it down at will.
Read, with care, the demo posted in the "How Oracle Works" section to see one way to create the foundations for a secure environment.
And, what is demonstrated in the demo code can be back ported to any application without breaking it. You may have an issue with the application vendor's support policies ...
but if you do that says more about their lack of interest in securing their product and their level of caring for their customers than it does Proxy User accounts.
With the information on this page you can achieve the following goals:
- Secure an existing application by converting the application user into a user that has no privileges: Not even the privilege to connect to the database
- Make it possible to change application passwords at will with zero downtime
- Limit the number of accounts with escalated privileges to as small a number as you wish
- Not pay a single additional dollar and purchase, subscribe, or license anything from any vendor
Sound too good to be true? Most of this technology has been available in Oracle for more than a decade. One part of the demo uses, but does not require, a new technology introduced with Oracle 18c.
Note: There is a wealth of syntaxes available for creating, altering, and dropping users.
This website is focused on security and primarily security through configuration rather than trying to spend vast fortunes to make some account executive happy with his or her commissions and bonuses.
So, if you want to look into all of the available syntaxes visit MorgansLibrary.org or the online docs at https://docs.oracle.com.
What you will find here will be what you need to lock down your data and your databases and vastly reduce their attack surface. |
|
Recommended Security Rules |
NEVER
- Use the standard Oracle CREATE USER syntax to create a user that connects to the database whether that user is human or mechanical, whether that user connects through an application or runs ad hoc
SQL.
WITH GREAT CARE
- Design all database access using Proxy Users and users created with the "NO AUTHENTICATION" syntax when possible.
CAUTIONS
- Limit the number of users connecting with any privilege, including CREATE SESSION to the bare minimum. Note in the demo below that the application server users have no privileges ... zero ... they do not even have CREATE SESSION ... they don't need them.
- Carefully monitor the default users created by Oracle Corp. for unexplained accesses. For example, why would anyone log in as WMSYS or XDB?
|
|
How Oracle Works |
The demo that follow is based on the this three level mapping:
Application objects are owned by the user MECHID.
Application maintenance will be performed by an APPDBA.
Privileges on application objects is granted to a
schema with no objects other than SYNONYMS named NOOBJ.
The NOOBJ schema is accessible via proxy users named PROXYA and PROXYB.
The application schema containing sensitive (PII, PHI, PCI) data is not owned by a person ... it is owned by a mechid.
A mechid is a non-human user. We named that schema "mechid" to make that clear through-out the demo.
In Oracle 18c and above the mechid schema should be created with the NO AUTHENTICATION syntax. In older versions the mechid schema should be created with a normal user and then the password should be expired and the account locked.
The demo, below, shows the syntax for both.
Proxy users should be
Warning:
Before you start reviewing the following demo, if your organization is an Oracle Database Enterprise Edition customer, nothing in this demo requires the purchase of any additional infrastructure, subscriptions, software, or licenses.
Your organization has already purchased everything required to replicate this technique. |
Create mechid, proxy, and application access schemas |
Let's start by creating all 5 of our required users.
-- in version 18c+
CREATE USER mechid
NO AUTHENTICATION
DEFAULT TABLESPACE uwdata
QUOTA 1G ON uwdata
TEMPORARY TABLESPACE temp
PROFILE default;
/* in versions 12c and earlier
SELECT sys_guid() FROM dual;
SYS_GUID()
--------------------------------
1112F7969A2742989447204B859D462D
CREATE USER mechid
IDENTIFIED BY "F7969A2742989447204B859D462D11"
DEFAULT TABLESPACE uwdata
QUOTA 1G ON uwdata
TEMPORARY TABLESPACE temp
PROFILE default
PASSWORD EXPIRE
ACCOUNT LOCK;
*/
CREATE USER APPDBA
IDENTIFIED BY
"D462D11F7969a2742989447204B89!"
TEMPORARY TABLESPACE temp
PROFILE ora_stig_profile;
-- Grant to APPDBA only those specific privs required to create
-- and maintain the application. Nothing more, nothing less.
-- The following system privileges, in the real world, would be
-- put into a password protected role that is assigned to appdba.
GRANT alter user TO appdba;
GRANT audit any TO appdba;
GRANT create session TO appdba;
GRANT create any synonym TO appdba;
GRANT create any table TO appdba;
GRANT grant any object privilege TO appdba;
-- create a user that owns no objects but will be granted
-- privileges and synonyms necessary for working with the
-- application's. Because it is created with NO AUTHENTICATION
-- no one can connect to it except by proxy.
CREATE USER NOOBJ
NO AUTHENTICATION
TEMPORARY TABLESPACE temp
PROFILE default;
GRANT create session to noobj;
-- note, NOOBJ is the only schema created that has the create session privilege.
-- proxya will be used by the application servers
until a password change is required.
CREATE USER PROXYA
IDENTIFIED BY "PROXY65!PWD"
TEMPORARY TABLESPACE temp
PROFILE default;
-- when a password change is required application servers are incrementally
-- altered to use proxyb to connect.
CREATE USER PROXYB
IDENTIFIED BY "PROXY66!PWD"
TEMPORARY TABLESPACE temp
PROFILE default;
-- when all application servers are migrated to proxyb the password for proxya
-- can be altered and proxya will be ready to use for the next password change. |
Provision schemas, enable auditing, and grant CONNECT THROUGH to enable proxy access |
-- note access is via the Application DBA user ... not the application owner,
-- or SYS, or any account with DBA privs
sqlplus appdba@pdbdev
Enter Password:
-- this is the application table for this demo
CREATE TABLE mechid.db_assets AS
SELECT * FROM all_all_tables;
-- this grants access to MECHID's table to NOOBJ.
GRANT READ, INSERT, DELETE ON mechid.db_assets TO NOOBJ;
GRANT UPDATE (skip_corrupt, inmemory_priority) ON mechid.db_assets TO NOOBJ;
-- this creates a synonym to schemaless access to mechid.db_assets.
CREATE OR REPLACE SYNONYM noobj.db_assets FOR mechid.db_assets;
-- this enables auditing of the proxy schemas.
AUDIT CONNECT BY proxya ON BEHALF OF noobj;
AUDIT CONNECT BY proxyb ON BEHALF OF noobj;
-- grant proxy access
ALTER USER noobj GRANT CONNECT THROUGH proxya;
ALTER USER noobj GRANT CONNECT THROUGH proxyb;
-- revoke the ability to connect except as a proxy
ALTER USER proxyb PROXY
ONLY CONNECT;
ALTER USER proxyb PROXY
ONLY CONNECT; |
Access test |
-- note the following ... proxya tries to connect on its own.
conn proxya/"PROXY65!PWD"@pdbdev
ERROR:
ORA-01045: user PROXYA lacks CREATE SESSION privilege; logon denied
Warning: You are no longer connected to ORACLE.
SQL> Connected.
-- without the CREATE SESSION privilege the user proxya can do nothing.
-- if someone phishes the userid and password ... they are worthless.
-- proxya can only connect when it proxy's NOOBJ and only has the privs
-- granted by NOOBJ ... proxya owns no objects, can create no objects,
-- and has all other access limited solely to objects with privs granted
-- to PUBLIC. Which is why it is so important to revoke grants to PUBLIC
-- to as great an extent as possible.
conn proxya[noobj]/"PROXY65!PWD"@pdbdev
SELECT COUNT(*) FROM noobj.db_assets;
COUNT(*)
---------
2255
If you think this is a lot of complexity and work ... writing this demo took 7 minutes: Testing 5.
Expanding this one object application to 100 or 1000 is far less than one days work and here at
DBSecWorx we have a tool that completely automates the entire process once we have access
to the application's schema(s).
But consider, how much complexity and work are you expecting if your organization's databases are broken into and trade secrets, PII, PHI, PCI, and other data is stolen?
And how much if those that were victimized by the data loss hire an attorney's decide to subpoena members of the DBA team for depositions and interrogatories?
Data and database security are not the result of buying expensive tools.
They are the result of properly using and configuring the basic capabilities that Oracle has already included in your existing licenses. |
|
General Information |
Data Dictionary Objects |
ALL_TS_QUOTAS |
DBA_USERS |
USER_PASSWORD_LIMITS |
ALL_USERS |
DEFAULT_PWD$ |
USER_RESOURCE_LIMITS |
CDB_TS_QUOTAS |
PROXY_INFO$ |
USER_TS_QUOTAS |
CDB_USERS |
PROXY_USERS |
USER_USERS |
DBA_TS_QUOTAS |
USER$ |
|
|
Users Created On Default Installation |
ANONYMOUS |
GGSYS |
OUTLN |
APEX_050100 |
GSMADMIN_INTERNAL |
PDBADMIN |
APEX_INSTANCE_ADMIN_USER |
GSMCATUSER |
REMOTE_SCHEDULER_AGENT |
APEX_LISTENER |
GSMUSER |
SCOTT |
APEX_PUBLIC_USER |
LBACSYS |
SI_INFORMTN_SCHEMA |
APEX_REST_PUBLIC_USER |
MDDATA |
SYS |
APPQOSSYS |
MDSYS |
SYS$UMF |
AUDSYS |
OJVMSYS |
SYSBACKUP |
CTXSYS |
OLAPSYS |
SYSDG |
DBSFWUSER |
ORACLE_OCM |
SYSKM |
DBSNMP |
ORDDATA |
SYSRAC |
DIP |
ORDPLUGINS |
SYSTEM |
DVF |
ORDSYS |
WMSYS |
DVSYS |
ORDS_METADATA |
XDB |
FLOWS_FILES |
ORDS_PUBLIC_USER |
XS$NULL |
|
Exceptions |
Error Code |
Reason |
ORA-65096 |
invalid common user or role name |
|
System Privileges |
ALTER USER |
CREATE_USER |
DROP_USER |
BECOME USER |
|
|
|
|
Secure Environment USER Statements |
Create User with Complex Password |
CREATE USER <user_name>
IDENTIFIED BY "<password>"; |
CREATE USER oracle3
IDENTIFIED BY "N0t!4N0W"; |
Create user without authentication |
CREATE USER <user_name>
NO AUTHENTICATION
DEFAULT TABLESPACE <tablespace_name>
[LOCAL]
TEMPORARY TABLESPACE <temp_tablespace_name>
QUOTA <quota_amount> ON <tablespace_name>
PROFILE <profile_name>
<DISABLE | ENABLE> EDITIONS; |
CREATE USER oracle11
NO AUTHENTICATION; |
Include Access To A Default Tablespace
Thanks Teresa Robinson for the correction |
CREATE USER <user_name>
IDENTIFIED BY <password>;
DEFAULT TABLESPACE <tablespace_name>
QUOTA <integer><K | M | G | T | P | E | UNLIMITED>; |
SELECT tablespace_name
FROM dba_tablespaces
WHERE contents NOT IN ('TEMPORARY', 'UNDO')
AND tablespace_name NOT IN (
SELECT tablespace_name
FROM dba_rollback_segs)
AND tablespace_name NOT LIKE 'SYS%';
CREATE USER oracle4
IDENTIFIED BY oracle4
DEFAULT TABLESPACE uwdata
QUOTA 100G
ON uwdata;
SELECT username, default_tablespace
FROM dba_users
WHERE username LIKE 'ORA%'
ORDER BY 1;
USERNAME DEFAULT_TABLESPACE
----------- -------------------
ORACLE4 UWDATA
ORACLE_OCM USERS
col max_bytes format 99999999999999
SELECT username, tablespace_name, max_bytes/1024/1024/1024 AS MAX_GB
FROM dba_ts_quotas
WHERE username LIKE '%ORA%';
USERNAME TABLESPACE_NAME MAX_GB
--------------- ---------------- -------------
ORACLE4 UWDATA 100 |
Include Access To A Temporary Tablespace |
CREATE USER <user_name>
IDENTIFIED BY <password>
[LOCAL]
TEMPORARY TABLESPACE <temporary_tablespace_name | temporary_tablespace_group>; |
SELECT tablespace_name
FROM dba_tablespaces
WHERE contents = 'TEMPORARY';
CREATE USER oracle5
IDENTIFIED BY oracle5
DEFAULT TABLE uwdata
TEMPORARY TABLESPACE temp;
SELECT username, default_tablespace, temporary_tablespace
FROM dba_users
ORDER BY 1; |
Include Quota On Tablespaces |
CREATE USER <user_name>
IDENTIFIED BY <password>
DEFAULT TABLESPACE <tablespace_name>
[LOCAL]
TEMPORARY TABLESPACE <temp_tablespace_name>
QUOTA <quota_amount> ON <tablespace_name>
QUOTA <quota_amount> ON <tablespace_name>
QUOTA <quota_amount> ON <tablespace_name>; |
CREATE USER oracle6
IDENTIFIED BY oracle6
DEFAULT TABLESPACE uwdata
TEMPORARY TABLESPACE temp
QUOTA 0 ON SYSTEM
QUOTA 0 ON SYSAUX
QUOTA UNLIMITED ON uwdata
QUOTA 10M ON data_med;
SELECT username, tablespace_name, max_bytes, max_blocks
FROM dba_ts_quotas
ORDER BY 1; |
Include Profile
Follow PROFILE link at page bottom for more information |
CREATE USER <user_name>
IDENTIFIED BY <password>
DEFAULT TABLESPACE <tablespace_name>
[LOCAL]
TEMPORARY TABLESPACE <temp_tablespace_name>
QUOTA <quota_amount> ON <tablespace_name>
PROFILE <profile_name>; |
SELECT DISTINCT profile
FROM dba_profiles;
CREATE USER oracle7
IDENTIFIED BY "N0Way!"
DEFAULT TABLESPACE uwdata
TEMPORARY TABLESPACE temp
QUOTA 0 ON SYSTEM
QUOTA 0 ON SYSAUX
QUOTA UNLIMITED ON uwdata
PROFILE monitoring_profile;
SELECT username, profile
FROM dba_users
ORDER BY 1; |
Expire the password on creation forcing the first user connecting to set their own password |
CREATE USER <user_name>
IDENTIFIED BY <password>
DEFAULT TABLESPACE <tablespace_name>
[LOCAL]
TEMPORARY TABLESPACE <temp_tablespace_name>
QUOTA <quota_amount> ON <tablespace_name>
PROFILE <profile_name>
PASSWORD EXPIRE; |
CREATE USER oracle8
IDENTIFIED BY oracle8
DEFAULT TABLESPACE uwdata
TEMPORARY TABLESPACE temp
QUOTA UNLIMITED ON uwdata
PASSWORD EXPIRE;
SELECT username, expiry_date, account_status
FROM dba_users; |
Lock or unlock the account on creation |
CREATE USER <user_name>
IDENTIFIED BY <password>
DEFAULT TABLESPACE <tablespace_name>
[LOCAL]
TEMPORARY TABLESPACE <temp_tablespace_name>
QUOTA <quota_amount> ON <tablespace_name>
PROFILE <profile_name>
ACCOUNT <LOCK | UNLOCK>; |
CREATE USER oracle9
IDENTIFIED BY oracle9
DEFAULT TABLESPACE uwdata
TEMPORARY TABLESPACE temp
QUOTA UNLIMITED ON uwdata
ACCOUNT LOCK;
SELECT username, lock_date, account_status
FROM dba_users; |
Container specific clause. To specify a local user in a single container specify CURRENT |
CREATE USER <user_name>
IDENTIFIED BY <password>
CONTAINER = <ALL | CURRENT>; |
-- in the following example uwapp is an Application Root container
conn sys@uwapp as sysdba
CREATE USER uwapp_user1
IDENTIFIED BY oracle12
CONTAINER = CURRENT; |
|
Insecure Environment USER Statements |
Common User with Simple Password |
CREATE USER c##<user_name>
IDENTIFIED BY <password>; |
conn / as sysdba
CREATE USER oracle1
IDENTIFIED BY oracle1;
create user oracle1 identified by oracle1
*
ERROR at line 1:
ORA-65096: invalid common user or role name
CREATE USER c##oracle1
IDENTIFIED BY oracle1; |
PDB User with Simple Password |
CREATE USER <user_name>
IDENTIFIED BY <password>; |
CREATE USER oracle2
IDENTIFIED BY oracle2;
SELECT username, created, password_versions
FROM dba_users
ORDER BY 1; |
Create proxy-only user
It is an interesting syntax but not as secure as just not granting CREATE SESSION
Error messages that give an attacker a hint as to how to succeed the next time are not recommended and this error message tells them everything about why they failed. |
ALTER USER <user_name> PROXY ONLY CONNECT;
ALTER USER <user_name> CANCEL PROXY ONLY CONNECT; |
CREATE USER oracle13
IDENTIFIED BY secret;
User created.
SELECT username, created, authentication_type, proxy_only_connect
FROM dba_users
WHERE username LIKE '%ORA%';
USERNAME CREATED AUTHENTI P
--------------- -------------------- -------- -
ORACLE_OCM 30-MAY-2019 03:53:38 NONE N
ORACLE13 17-DEC-2019 21:48:47 PASSWORD N
ALTER USER oracle13
PROXY ONLY CONNECT;
User altered.
USERNAME CREATED AUTHENTI P
--------------- -------------------- -------- -
ORACLE_OCM 30-MAY-2019 03:53:38 NONE N
ORACLE13 17-DEC-2019 21:48:47 PASSWORD Y
conn oracle13@pdbdev
Password:
SQL> conn oracle13@pdbdev
Enter password:
ERROR:
ORA-28058: login is allowed only through a proxy
Warning: You are no longer connected to ORACLE. |
Enable editions on user creation
There is nothing about enabling editions that is a security issue in and of itself. But if you do enable editioning then you must rewrite management scripts to look at dba_objects_ae rather than dba_objects as well as any references to the other _ae views.
Edition Based Redefinition, as wonderful as it is, adds the possibility that objects may be hidden in a non-default edition so you must pay close attention. |
CREATE USER <user_name>
IDENTIFIED BY <password>
DEFAULT TABLESPACE <tablespace_name>
TEMPORARY TABLESPACE <temp_tablespace_name>
QUOTA <quota_amount> ON <tablespace_name>
PROFILE <profile_name>
ACCOUNT <LOCK | UNLOCK>
<DISABLE | ENABLE> EDITIONS; |
SELECT username, editions_enabled
FROM dba_users
ORDER BY 2,1;
CREATE USER oracle10
IDENTIFIED BY oracle10
ENABLE EDITIONS;
SELECT username, editions_enabled
FROM dba_users
ORDER BY 2,1; |
|
Creating Operating System Authenticated User: These Are All Insecure And Should Not Be Used |
Required changes to allow external authentication ... and changes we do not recommend you make as operating system authentication compromises security |
ALTER SYSTEM SET remote_os_authent=TRUE SID='*' SCOPE=SPFILE;
ALTER SYSTEM SET os_authent_prefix="OPS$" SID = '*' SCOPE=SPFILE;
-- restart the database
-- add the following to the sqlnet.ora
sqlnet.authentication_services = (NTS) |
The syntax for CREATE USER where authentication is performed by the operating system on the server and, again, we do not recommend this due to the security compromise |
CREATE USER <user_name> IDENTIFIED EXTERNALLY; |
Step 1: Connect as system/manager in SQL*Plus and create the Oracle user:
CREATE USER ops$oracle IDENTIFIED EXTERNALLY;
SELECT username, external_name
FROM dba_users
ORDER BY 1;
GRANT create session TO ops$oracle;
Step 2: Create a user in the operating system named oracle if one does not already exist.
Step 3: Go to command line (terminal window in UNIX, cmd in Windows. Type 'sqlplus' (without the single quotes). You should be connected to the database without having to enter username/password. |
The syntax for CREATE USER where authentication is performed by the operating system on the client |
CREATE USER <machine_name\user_name> IDENTIFIED EXTERNALLY; |
Step 1: Connect as system/manager in SQL*Plus and create the Oracle user:
CREATE USER "PC100\USER" IDENTIFIED EXTERNALLY;
where PC100 is the name of the client computer. Then:
GRANT CREATE SESSION TO "PC100\USER";
Step 2 - Create a user in Windows named USER.
Step 3 - Log on Windows as USER and go to the C:\> command line.
Type 'sqlplus' (without the single quotes). You should be connected to your database without having to enter any username/password. |
|
Password Changes |
Password change by user or DBA |
ALTER USER <user_name> IDENTIFIED <new_password>; |
ALTER USER uwclass IDENTIFIED BY "N0Access!";
User altered. |
Password change by optimized for application submission |
ALTER USER <user_name> IDENTIFIED <new_password> REPLACE <old_password>; |
ALTER USER uwclass IDENTIFIED BY secret REPLACE uwclass;
User altered. |
Password change by DBA using password hash |
ALTER USER <user_name> IDENTIFIED BY VALUES <'recovered_password_hash'>; |
Note ... the password hashes recovered from USER$ in this demo are broken into multiple (5) lines to accommodate the website format.
To work they need to be reconstructed as a single line from starting single-quote to ending single_quote.
conn sys@pdbdev as sysdba
Password:
-- set the inital password for user uwclass and capture the password hash
ALTER USER uwclass IDENTIFIED BY uwclass;
SELECT spare4 FROM sys.user$ WHERE name='UWCLASS';
SPARE4
---------------------------------------------------------------
S:29AA882F714866653497FE679E15ECFD8B46342407C7AE5C229610A76043;
H:33026143E040882C64C2375E7086F96B;
T:E78343A31ADD6ADD4BF1B203D50B2B58355F45EBA2A19650C3525
E7F956EDCDEE1FB9581D5A530232730AC4DEF8B8D9F0EE8ECC51C19
219AC430A88188694EE72778CAA657281E3F3360F8C8D2951329
-- change the password for user uwclass and capture
the new password hash
ALTER USER uwclass IDENTIFIED BY secret;
SELECT spare4 FROM sys.user$ WHERE name='UWCLASS';
SPARE4
---------------------------------------------------------------
S:C8839A12FA077E78CC63418BC0EF65F0EDCF4CBA39476C225C10408F9EEE;
H:73B095C3A1DE0547DF2726296C64BC37;
T:C420AFD3814CA9BE36A3274A941331000650C9816F5F13956DA8E069036
DDCF95CAC249E35B9302549AEA71BFEEBEC55DFE44954F8C26A
2319FD252F73614319662CC9FD86A982060E9C75D51E0DFA4F
-- using the hash for the first password return the
user password to the first value
ALTER USER uwclass IDENTIFIED BY VALUES '
S:29AA882F714866653497FE679E15ECFD8B46342407C7AE5C229610A76043;
H:33026143E040882C64C2375E7086F96B;
T:E78343A31ADD6ADD4BF1B203D50B2B58355F45EBA2A19650C3525
E7F956EDCDEE1FB9581D5A530232730AC4DEF8B8D9F0EE8ECC51C19
219AC430A88188694EE72778CAA657281E3F3360F8C8D2951329';
-- the user logs on and the first value has been restored
conn uwclass/uwclass@pdbdev
Connected.
SQL> |
|
Operating System Accounts |
Group membership in UNIX |
Operating system accounts that are members of the operating system's DBA group are not required to provide a userid and password when logging in. |
Group membership in Windows |
Operating system accounts that are members of the operating system's ORA_DBA group are not required to provide a userid and password when logging in. |
Windows logins |
Automatic logins with the Windows operating system are not secure. Anyone can edit the Oracle configuration file and change their user ID.
For security reasons, if users of these systems are logging in over the network, Oracle Corporation recommends that you disable the ops$ logins in the listener.ora. |
|
Related Queries |
Active Connected Users |
SELECT sid, username, action
FROM v$session
WHERE username IS NOT NULL
AND status = 'ACTIVE'; |
Find dynamic SQL in unwrapped database source code.
In version 18.3 this query returns more than 1,500 rows |
conn / as sysdba
SELECT owner, name, type, line, text, 'DBMS_SQL used' AS REASON
FROM dba_source
WHERE UPPER(text) LIKE '%DBMS_SQL%'
UNION ALL
SELECT owner, name, type, line, text, 'Native Dynamic used'
FROM dba_source
WHERE UPPER(text) LIKE '%EXECUTE IMMEDIATE%'
ORDER BY 1,2,3; |
Get Connection Information |
set linesize 141
col authentication_type format a20
col osuser format a20
col client_charset format a20
col network_service_banner format a60
desc gv$session_connect_info;
SELECT sid, authentication_type, osuser, network_service_banner
FROM gv$session_connect_info;
SELECT sid, client_charset, client_connection, client_oci_library, client_version
FROM gv$session_connect_info; |
Get Idle Time |
col SID format 999
col IDLE format a20
col PROGRAM format a20
col USERNAME format a20
SELECT sid, osuser, username, status, TO_CHAR(logon_time, 'DAY HH24:MI:SS') LOGON_TIME, FLOOR(last_call_et/3600) || ':' || FLOOR(MOD(last_call_et, 3600) / 60) || ':' || MOD(MOD(last_call_et, 3600), 60) IDLE, program
FROM v$session
WHERE username IS NOT NULL
ORDER BY last_call_et; |
Get User Memory Usage |
SELECT username, program, value || 'bytes' "Current UGA memory"
FROM v$session sess, v$sesstat sstat, v$statname sname
WHERE sess.sid = sstat.sid
AND sstat.statistic# = sname.statistic#
AND sname.name = 'session uga memory'; |
Get User Waits |
SELECT SUBSTR(s.USERNAME,1,15) USERNAME, SUBSTR(s.status,1,8) STATUS, SUBSTR(s.server,1,10) SERVER,
SUBSTR(s.type,1,10) TYPE, SUBSTR(s.event,1,20) "WAIT EVENT",
DECODE(s.command,
1,'Create Table',
2,'Insert',
3,'Select',
6,'Update',
7,'Delete',
8,'Drop',
9,'Create Index',
10,'Drop Index',
12,'Drop Table',
17,'Grant',
26,'Lock Table',
42,'Alter Session',
43,'Alter User',
44,'Commit',
45,'Rollback',
s.command) COMMAND
FROM v$session s, v$session_wait w
WHERE s.sid = w.sid
AND s.username != 'SYS'
ORDER BY 1; |
Identify the current session |
SELECT user, osuser, terminal, program
FROM gv$session
WHERE sid = (SELECT sid FROM v$mystat WHERE rownum = 1); |
Identify current users |
col name format a20
col process format a12
col program format a17
SELECT sid, serial#, SUBSTR(username,1,10) NAME, SUBSTR(machine,1,10) COMPUTER, command, status, SUBSTR(osuser,1,8) OSUSER, process, program
FROM v_$session
ORDER BY name; |
Identify current users |
col username format a21
col profile format a10
col "tmp tbs" format a10
SELECT u.username, u.default_tablespace, u.temporary_tablespace "TMP TBS", u.profile, r.granted_role, r.admin_option, r.default_role
FROM sys.dba_users u, sys.dba_role_privs r
WHERE u.username = r.grantee (+)
GROUP BY u.username, u.default_tablespace, u.temporary_tablespace, u.profile, r.granted_role, r.admin_option, r.default_role; |
Identify default users and passwords |
col user_name format a30
col pwd_verifier format a20
SELECT *
FROM default_pwd$
ORDER BY 1; |
Identify privileged users |
SELECT *
FROM gv$pwfile_users;
-- for this to be meaningful you must be using an exclusive password file to authenticate privileged users |