Thursday 9 May 2019

How to Recover archive gaps in standby database - using 2 methods


Using Both Methods
  1. Manually Log Shipping (when the missing logs are very less approx 400)
  2. Performing Incremental Backup (When there is a very huge gap)

METHOD 1:
When the logs missing or corrupt is less in number (say below 15), we can ship the logs which were missing in the standby site from the primary site (scp/sftp/ftp) and then we can register the log file in the standby so that the gap can be resolved.
This is easy process if you have missing or corrupt logs in lesser number.
Otherwise we can use the incremental backup strategy, and perform the recovery at standby site.
Lets go through the Archive log Shipping process
First, Find the archives which are missing by issuing the following command. This would give the gap sequences
SQL> select * from v$archive_gap
Or you can use the v$managed_standby view to find where the log apply stuck.
SQL> select sequence#,process,status from v$managed_standby;

Now, Copy the logs to the standby site from the primary site
Using the below command
$ scp log_file_name_n.arc oracle@standby:/log/file/location/log_file_name_n.arc

At standby site, Do the log file registration at the standby site until all the missing log files are registered, Use this below command.
SQL> alter database register logfile '/log/file/location/log_file_name_n.arc';

Now apply would take place and your standby will become sync with the primary.
METHOD 2 :
when the difference is huge (say around 500 logs) the above method is very time consuming and not a proper approach. Else you have to rebuild the standby database from scratch.
As an enhancement from 10g, an incremental backup created with BACKUP INCREMENTAL... FROM SCN can be used to refresh the standby database with changes at the primary database since the last SCN at Standby and then managed recovery can resume.

Step 1:
Use this below command to find the SCN difference, on both the database – Primary DB & Standby DB
SQL> select current_scn from v$database;
Step 2 :
Stop the managed standby apply process:
SQL> alter database recover managed standby database cancel;
Step 3:
Now Shutdown the standby database
SQL> shut immediate
Step 4:
On the primary, take an incremental backup from the SCN number where the standby has been stuck:
RMAN> run {
allocate channel c1 type disk format '/u01/backup/%U.bkp';
backup incremental from scn ********* database;
}
Step 5: On the primary, create a new standby controlfile and copy this file to standby side:
SQL> alter database create standby controlfile as '/u01/backup/for_standby.ctl';
$ scp * oracle@dataguard : /u01/backup
Step 6 :
Bring up the Standby instance in nomount mode:
SQL> startup nomount
Step 7
Now, replace the previous controlfile with this new one created at primary , and Bring the database to MOUNT state.
(Because, this Primary Side control file has the information of the SCN and we have to perform the recovery using this controlfile)
SQL> alter database mount standby database;
Step 8 :
Open the RMAN prompt and Catalog the backup piece.
(Because , RMAN does not know about these files yet; so you must let it know – by a process called cataloging)
$ rman target=/
RMAN> catalog start with '/u01/backup';

Step 9 :
Recover these files:
RMAN> recover database;
Step 10 :
After performing the recovery , exit RMAN and start managed recovery process:
SQL> alter database recover managed standby database disconnect from session;
Step 11 :
Again Check the SCN’s in primary and standby to make sure that both are in SYNc:
SQL> select current_scn from v$database;

Wednesday 10 April 2019

ORA-16737: the redo transport service for standby database 'aaa' has an error


ORA-16737: the redo transport service for standby database "aaa" has an error
#1
CHECK: when you have the above problem, you will get the protection mode in the    Primary & standby v$database.protection_level shows  as "RESYNCHRONIZATION"
select protection_mode, protection_level from v$database; 
#2
CHECK: whether you are getting any in the archive location 

select dest_id,status,error from v$archive_dest;
#3
CHECK: Check whether online redo log are configured in the primary & standby database properly, it includes size & accessibility 
Note: primary &standby online redo log should be same
select group#,thread#,sequence#,bytes,archived,status from v$log;  
#4
CHECK: Check whether standby redo log are configured in the primary &standby database properly, it includes size & accessibility 
Note: primary &standby standby redo log should be same 
select member from v$logfile where type='STANDBY'; 
#5
CHECK: Check parameters are configured properly; some times instance parameters have a different value. Ex: some common parameter will have different value for each instance in the cluster database. You need to check on the primary &standby cluster database environment.
#6
Check whether maximum Availability is enabled, when you have LogXptMode is synchronization
SYMP:
ORA-16629: database reports a different protection level from the protection mode
In DG Broker
DGMGRL> EDIT CONFIGURATION SET PROTECTION MODE AS MAXAVAILABILITY;
Succeeded.

#7 check your password with the setting
A)
1) check for the "sec_case_sensitive_logon" parameter.
2) if the problem exist, create the password file with ignorecase option in the orapwd password creation.
3) after recreating the password, restart both the primary & standby database.

Sunday 24 February 2019

ORA-27475 Case sensitive

When you need to work with case-sensitive identifiers, you need to put them between double quotation marks, otherwise the database handles them as case-insensitive and automatically converts to uppercase.
begin
  dbms_scheduler.create_job
  (
   job_name             => '"job1"',
   job_type             => 'plsql_block',
   job_action           => 'begin null; end;'
  );
end;
/

select job_name from dba_scheduler_jobs where job_name = 'job1';

JOB_NAME                      
------------------------------
job1
This fails:
begin
  dbms_scheduler.drop_job('job1');
end;
/

Error report -
ORA-27475: "BP.JOB1" must be a job
...
But this works:
begin
  dbms_scheduler.drop_job('"job1"');
end;
/

PL/SQL procedure successfully completed.

Friday 22 February 2019

Fatal NI connect error 12170.

From Mos Doc ID 1286376.1

Fatal NI Connect Error 12170, 'TNS-12535: TNS:operation timed out' Reported in 11g Alert Log   

In this Document
Symptoms
Changes
Cause
Solution
References
APPLIES TO:

Oracle Net Services - Version 11.1.0.6 to 12.1.0.2 [Release 11.1 to 12.1]
Information in this document applies to any platform.
TNS-12170, ORA-12170, TNS-12535, TNS-00505 alert.log


SYMPTOMS


nt secondary err code: 110   Monitoring of the 11g database Alert log(s) may show frequent timeout related messages such as:

- On Oracle Solaris:

***********************************************************************

Fatal NI connect error 12170.

VERSION INFORMATION:
TNS for Solaris: Version 11.2.0.1.0 - Production
Oracle Bequeath NT Protocol Adapter for Solaris: Version 11.2.0.1.0 - Production
TCP/IP NT Protocol Adapter for Solaris: Version 11.2.0.1.0 - Production
Time: 22-JAN-2011 21:48:23
Tracing not turned on.
Tns error struct:
ns main err code: 12535

TNS-12535: TNS:operation timed out
ns secondary err code: 12560
nt main err code: 505

TNS-00505: Operation timed out
nt secondary err code: 145
nt OS err code: 0
Client address: (ADDRESS=(PROTOCOL=tcp)(HOST=10.xxx.yy.117)(PORT=1092))

---------
The "nt secondary err code" will be different based on the operating system.

Linux x86 or Linux x86-64: "nt secondary err code: 110"
HP-UX Server: "nt secondary err code: 238"
AIX: "nt secondary err code: 78"




CHANGES

No changes are necessary, but may have recently upgraded the database to 11g release 1 or higher, or installed a new Oracle11g database.

Note: Prior to 11gR1 these same 'Fatal NI connect error 12170' are written to the sqlnet.log

CAUSE

These time out related messages are mostly informational in nature.  The messages indicate the specified client connection (identified by the 'Client address:' details) has experienced a time out.  The 'nt secondary err code' identifies the underlying network transport, such as (TCP/IP) timeout limits after a client has abnormally terminated the database connection.

The 'nt secondary err code' translates to underlying network transport timeouts for the following Operating Systems:

For the Solaris system: nt secondary err code: 145:
ETIMEDOUT 145 /* Connection timed out */

For the Linux operating system: nt secondary err code: 110
ETIMEDOUT 110 Connection timed out

For the HP-UX system: nt secondary err code: 238:
ETIMEDOUT 238 /* Connection timed out */

For AIX: nt secondary err code: 78:
ETIMEDOUT 78 /* Connection timed out */


For Windows based platforms: nt secondary err code: 60 (which translates to Winsock Error: 10060)

Description:  A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond.

The reason the messages are written to the alert log is related to the use of the new 11g Automatic Diagnostic Repository (ADR) feature being enabled by default.  See (Doc ID 454927.1).

SOLUTION

Suggested Actions:

- Search the corresponding text version of the listener log located on the database server for the corresponding client connection referenced by the Client address details referenced in the alert log message.

For the message incident below you would search the listener log for the 'Client address' string: 

(ADDRESS=(PROTOCOL=tcp)(HOST=10.xxx.yy.117)(PORT=1092))

The search of the listener log should find the most recent connection before the time reference displayed in the alert log message, e.g. '22-JAN-2011 21:48:23'.

-Corresponding listener log entry:

22-JAN-2011 21:20:12 * (CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=AMN11264.us.oracle.com)(CID=(PROGRAM=D:\app\mcassady\product\11.2.0\dbhome_1\bin\sqlplus.exe)(HOST=mcassady-lap)(USER=mca
ssady))) * (ADDRESS=(PROTOCOL=tcp)(HOST=10.xxx.yy.117)(PORT=1092)) * establish * AMN11264.us.oracle.com * 0

- Alert log entry:
------------

Fatal NI connect error 12170.

VERSION INFORMATION:
TNS for Solaris: Version 11.2.0.1.0 - Production
Oracle Bequeath NT Protocol Adapter for Solaris: Version 11.2.0.1.0 - Production
TCP/IP NT Protocol Adapter for Solaris: Version 11.2.0.1.0 - Production
Time: 22-JAN-2011 21:48:23
Tracing not turned on.
Tns error struct:
ns main err code: 12535

TNS-12535: TNS:operation timed out
ns secondary err code: 12560
nt main err code: 505

TNS-00505: Operation timed out
nt secondary err code: 145
nt OS err code: 0
Client address: (ADDRESS=(PROTOCOL=tcp)(HOST=10.xxx.yy.117)(PORT=1092))

------------

Note the time of the client corresponding client connection(s) in the listener log.  Here you may find a particular client, set of clients or particular applications that are improperly disconnecting causing the timeout errors to be raised and recorder in the database alert log.

 

See the following for more information and a potential solution where a firewall may be causing this issue:   Note:1628949.1   Alert Log Errors: 12170 TNS-12535/TNS-00505: Operation Timed Out



You may choose to revert from the new Automatic Diagnostic Repository (ADR) method to prevent the Oracle Net diagnostic details from being written to the alert log(s) by setting the following Oracle Net configuration parameters:


To revert to Oracle Net Server tracing/logging, set following parameter in the server's sqlnet.ora :

DIAG_ADR_ENABLED = OFF

Also, to back out the ADR diag for the Listener component, set following parameter in the server's listener.ora:

DIAG_ADR_ENABLED_<listenername> = OFF

   - Where the <listenername> would be replaced with the actual name of the configured listener(s) in the listener.ora configuration file.  For example, if the listener name is 'LISTENER', the parameter would read:

DIAG_ADR_ENABLED_LISTENER = OFF

-Reload or restart the TNS Listener for the parameter change to take effect.

Thursday 21 February 2019

ORA-01403


Hiçbir sonuç döndürmeyen SELECT INTO sql cümlesi çalıştırıldığında alınır.
Exception yakalama ile hatayı geçebiliriz.
BEGIN
SELECT dogum_yeri INTO v_dogum_yeri FROM kisiler WHERE id=501;
EXCEPTION
WHEN no_data_found THEN
— <<kayıt bulunamazsa yapılacak işlem>>
v_dogum_yeri :=’Dy Girilmemiş’;
END;

Monday 11 February 2019

Someone on dba-Village forum asked about how to protect username and password for connecting to RMAN catalog database. Since I’m strongly against using remote os authentication (remote_os_auth=true) in real life production environment, I would probably choose Oracle Wallet for storing credentials for connecting to rman catalog.

Note: With Oracle Wallet implementation we’re relying on file system permissions that protects our wallet; it’s not perfect but I’m happy to trade this “risk” with (in my humble opinion) much riskier approach of using remote os authentication. Anyone with access to the wallet that has auto-login feature turned On, can connect as user stored in the wallet without a password! Approach described in this post should be used seldom and with care.

Here is a mini How-to (I was using Windows 10 and Oracle12c):

###########################################
1) Create Oracle wallet
- the result of this step is directory D:\oracle\rmancat_wallet
  with two files: cwallet.sso and ewallet.p12 .
###########################################
 
cmd> mkstore -wrl D:\oracle\rmancat_wallet -create
Enter password: mysecret
 
PASSWORD_POLICY : Passwords must have a minimum length of eight characters and
contain alphabetic characters combined with numbers or special characters.
Enter password: mysecret1
 
Enter password again: mysecret1
 
 
####################################################
2) Adding database user credentials to this wallet
ORA11   .... TNS alias for RMAN catalog database
rmancat .... database user
test    .... password for rmancat
####################################################
 
mkstore -wrl D:\oracle\rmancat_wallet -createCredential ora11 rmancat test
 
Enter wallet password:
 
Create credential oracle.security.client.connect_string1
 
 
#######################################
3) Configure sqlnet.ora at client side
#######################################
 
WALLET_LOCATION = (SOURCE=(METHOD=FILE)(METHOD_DATA=(DIRECTORY=D:\oracle\rmancat_wallet)))
SQLNET.WALLET_OVERRIDE = TRUE
 
########################################
4) Test connection
########################################
 
D:\ORACLE>sqlplus /@ora511
 
SQL*Plus: Release 11.1.0.6.0 - Production on ╚et Jul 10 13:58:00 2008
 
Copyright (c) 1982, 2007, Oracle.  All rights reserved.
 
 
Connected to:
Oracle Database 11g Enterprise Edition Release 11.1.0.6.0 - Production
With the Partitioning, Oracle Label Security, OLAP, Data Mining,
Oracle Database Vault and Real Application Testing options
 
SQL> show user
USER is "RMANCAT"
 
########################################
5) Additional security checks
########################################
 
I would recommend to save sqlnet.ora and tnsnames.ora separately
from the common oracle home, for example we can copy both files to
the wallet directory (in our example D:\ORACLE\rmancat_wallet).
Make sure that only user executing rman backup has read permissions on this
directory. By default Oracle changes permissions only on files
cwallet.sso and ewallet.p12, leaving directory permission to be inhereted from
the parent (at least that's the case on Windows, I'm not sure about Linux/Unix)!
   
Don't forget to setup environment variable TNS_ADMIN pointing
to your wallet directory at the beggining of backup script.
 
 
##############################
6) Various handy commands
##############################
 
>> ------------------------------
>> List the content of the Wallet
>> ------------------------------
 
cmd> mkstore -wrl D:\oracle\rmancat_wallet -listCredential
 
Enter wallet password:
 
List credential (index: connect_string username)
1: ora11 rmancat
 
>> -------------------------------------------------
>> Modify credential stored in the wallet
>> -------------------------------------------------
 
cmd> mkstore -wrl D:\oracle\rmancat_wallet -modifyCredential ora11 rmancat newpassword
 
Enter wallet password: mysecret1
 
Modify credential
Modify 1
 
>> -----------------------------------
>> Deleting credential from the wallet
>> -----------------------------------
 
cmd> mkstore -wrl D:\oracle\rmancat_wallet -deleteCredential ora11
 
Enter wallet password:
 
Delete credential
Delete 1
 
>> ------------------------------------
>> Adding credential
>> ------------------------------------
 
Remember, you can have only ONE user per TNS alias stored in the wallet. If you need to store
two users (schemas) for one TNS, then you'll have to use two wallets!
 
For example, this is possible:
 
> mkstore -wrl D:\oracle\rmancat_wallet -createCredential ora11 rmancat test
> mkstore -wrl D:\oracle\rmancat_wallet -createCredential ora12 scott tiger
 
If you try to add second account for the same TNS alias, you'll get error:
 
> mkstore -wrl D:\oracle\rmancat_wallet -createCredential ora12 scott2 tiger
 
Create credential Secret Store error occured:
oracle.security.pki.OracleSecretStoreException: Credential already exists
 
In this case you'll need to create new wallet for scott2.

When using command-line tools such as Oracle SQL*Plus, which can accept a plain-text password, users must use an alternative logon method that does not expose the password.

"For Oracle SQL*Plus, which cannot be configured not to accept a plain-text password, and any other essential tool with the same limitation:

1) Document the need for it, who uses it, and any relevant mitigations, and obtain AO approval.
2) Train all users of the tool in the importance of not using the plain-text password option and in how to keep the password hidden.

- - - - -
Consider wrapping the startup command with a shell or wrapper and using an Oracle external password store.

Oracle provides the capability to provide for a secure external password facility. Use the Oracle mkstore to create a secure storage area for passwords for applications, batch jobs, and scripts to use or deploy a site-authorized facility to perform this function.

Check to see what has been stored in the Oracle External Password Store.

To view all contents of a client wallet external password store, check specific credentials by viewing them. Listing the external password store contents provides information used to decide whether to add or delete credentials from the store. To list the contents of the external password store, enter the following command at the command line:

$ mkstore -wrl wallet_location -listCredential

For example:

$ mkstore -wrl c:\oracle\product\12.1.0\db_1\wallets -listCredential

The wallet_location specifies the path to the directory where the wallet, whose external password store contents is to be viewed, is located. This command lists all of the credential database service names (aliases) and the corresponding user name (schema) for that database. Passwords are not listed.

Configuring Clients to Use the External Password Store

If the client is already configured to use external authentication, such as Windows native authentication or Transport Layer Security (TLS), then Oracle Database uses that authentication method. The same credentials used for this type of authentication are typically also used to log on to the database.

For clients not using such authentication methods or wanting to override them for database authentication, set the SQLNET.WALLET_OVERRIDE parameter in sqlnet.ora to TRUE. The default value for SQLNET.WALLET_OVERRIDE is FALSE, allowing standard use of authentication credentials as before.

If wanting a client to use the secure external password store feature, then perform the following configuration task:

1. Create a wallet on the client by using the following syntax at the command line:
orapki create -wallet wallet_location -auto_login_local

For example:
orapki wallet create -wallet c:\oracle\product\12.1.0\db_1\wallets -auto_login_local
Enter password: password

The wallet_location is the path to the directory where the wallet is to be created and stored. This command creates an Oracle wallet with the autologon feature enabled at the location specified. The autologon feature enables the client to access the wallet contents without supplying a password.

The mkstore utility -create option uses password complexity verification.

2. Create database connection credentials in the wallet by using the following syntax at the command line:
mkstore -wrl wallet_location -createCredential db_connect_string username
Enter password: password

For example:
mkstore -wrl c:\oracle\product\12.1.0\db_1\wallets -createCredential oracle system
Enter password: password

In this specification:
The wallet_location is the path to the directory where the wallet was created. The db_connect_string used in the CONNECT /@db_connect_string statement must be identical to the db_connect_string specified in the -createCredential command.

The db_connect_string is the TNS alias used to specify the database in the tnsnames.ora file or any service name used to identify the database on an Oracle network. By default, tnsnames.ora is located in the $ORACLE_HOME/network/admin directory on UNIX systems and in ORACLE_HOME\network\admin on Windows.

The username is the database logon credential. When prompted, enter the password for this user.

3. In the client sqlnet.ora file, enter the WALLET_LOCATION parameter and set it to the directory location of the wallet created in Step 1. For example, if the wallet was created in $ORACLE_HOME/network/admin and the Oracle home is set to /private/ora12, then need to enter the following into the client sqlnet.ora file:

WALLET_LOCATION =
(SOURCE =
(METHOD = FILE)
(METHOD_DATA =
(DIRECTORY = /private/ora12/network/admin)
)
)

4. In the client sqlnet.ora file, enter the SQLNET.WALLET_OVERRIDE parameter and set it to TRUE as follows:

SQLNET.WALLET_OVERRIDE = TRUE

This setting causes all CONNECT /@db_connect_string statements to use the information in the wallet at the specified location to authenticate to databases.

When external authentication is in use, an authenticated user with such a wallet can use the CONNECT /@db_connect_string syntax to access the previously specified databases without providing a user name and password. However, if a user fails that external authentication, then these connect statements also fail.

Below is a sample sqlnet.ora file with the WALLET_LOCATION and the SQLNET.WALLET_OVERRIDE parameters set as described in Steps 3 and 4.

Below is a sample SQLNET.ORA File with Wallet Parameters Set

WALLET_LOCATION =
(SOURCE =
(METHOD = FILE)
(METHOD_DATA =
(DIRECTORY = /private/ora12/network/admin)
)
)

SQLNET.WALLET_OVERRIDE = TRUE
SSL_CLIENT_AUTHENTICATION = FALSE
SSL_VERSION =1.2 or 1.1

(Note: This assumes that a single sqlnet.ora file, in the default location, is in use. Please see the supplemental file "Non-default sqlnet.ora configurations.pdf" for how to find multiple and/or differently located sqlnet.ora files.)

Note: ""SSL_VERSION = 1.2 or 1.1" is the actual value, not a suggestion to use one or the other."

Pete Finnigan's Oracle Security Weblog-Grant DBA to yourself - exploit or not?

Yesterday Peter from the Master of Disaster Blog sent me an email to ask if I had seen the issue in his post before and whether it was a new exploit. I looked at the post and immediately recognised that this is not an exploit. Peter cannot grant DBA two himself as an exploit but he can do it because he first had granted system privileges that allow this. I could not post a blog post yesterday as I was teaching one of my online Oracle security classes.

As well as online Oracle security classes I will also be teaching my two day class - How to perform a security audit of an Oracle database in my home city of York, UK. There are still places left and if you would like to make the trip to York, please contact me to book your place. This class is taught by me and enables you to go away and secure your own databases

Whilst I had time first thing to do a quick demo and email Peter yesterday I didn't have time till now to write up a proper post; so here it is.

The blog post on Peters page has been updated to state that I sent him an explanation and the issue is not an exploit but the code he posted in the post linked above is pretty much the same. In the post Peter suggested that he could create a new user and then grant a bunch of roles and other grants to that user and then connect as the new user (although the actual connect was not shown) and then the new user was able to grant DBA to himself.

I did some tests based on Peters code. First i created a script tuser.sql based on the significant part of his script - granting IMP_FULL_DATABASE is the key. here is the script:

-- tuser.sql
create user tuser identified by tuser
default tablespace users
temporary tablespace temp;

GRANT CONNECT TO TUSER;

grant imp_full_database to tuser;

connect tuser/tuser@//192.168.1.95:1539/orcl.localdomain

grant dba to tuser;


I then ran this script as follows:

C:\_aa\PB\bin>sqlplus sys/oracle1@//192.168.1.95:1539/orcl.localdomain
as sysdba

SQL*Plus: Release 11.2.0.4.0 Production on Tue Oct 10 08:27:58 2017

Copyright (c) 1982, 2013, Oracle.  All rights reserved.


Connected to:
Oracle Database 12c Standard Edition Release 12.2.0.1.0 - 64bit Production

SQL> @tuser

User created.


Grant succeeded.


Grant succeeded.

Connected.

Grant succeeded.

SQL> sho user
USER is "TUSER"

SQL> select * from session_roles;

ROLE
--------------------------------------------------------------------------------
CONNECT
IMP_FULL_DATABASE
SELECT_CATALOG_ROLE
HS_ADMIN_SELECT_ROLE
EXECUTE_CATALOG_ROLE
HS_ADMIN_EXECUTE_ROLE

6 rows selected.


The role is not enabled as when you grant a role to yourself its not there by default. So log out and log back in at the TUSER and see if the DBA role is enabled:

SQL> connect tuser/tuser@//192.168.1.95:1539/orcl.localdomain
Connected.
SQL> select * from session_roles;

ROLE
--------------------------------------------------------------------------------
CONNECT
DBA
SELECT_CATALOG_ROLE
HS_ADMIN_SELECT_ROLE
EXECUTE_CATALOG_ROLE
HS_ADMIN_EXECUTE_ROLE
CAPTURE_ADMIN
EXP_FULL_DATABASE
IMP_FULL_DATABASE
DATAPUMP_EXP_FULL_DATABASE
DATAPUMP_IMP_FULL_DATABASE

ROLE
--------------------------------------------------------------------------------
GATHER_SYSTEM_STATISTICS
OPTIMIZER_PROCESSING_RATE
EM_EXPRESS_ALL
EM_EXPRESS_BASIC
SCHEDULER_ADMIN
XDBADMIN
XDB_SET_INVOKER
WM_ADMIN_ROLE
JAVA_ADMIN
JAVA_DEPLOY
OLAP_XS_ADMIN

ROLE
--------------------------------------------------------------------------------
OLAP_DBA

23 rows selected.

SQL>


The TUSER user now has the DBA role but as I said this is not an exploit or bug, its because the TUSER has IMP_FULL_DATABASE and in fact he needs to system privileges to grant the DBA role. GRANT ANY ROLE and GRANT ANY PRIVILEGE:

SQL> @who_has_priv



who_has_priv: Release 1.0.3.0.0 - Production on Sat Jun 10 03:57:39 2017
Copyright (c) 2004 PeteFinnigan.com Limited. All rights reserved.

PRIVILEGE TO CHECK        [SELECT ANY TABLE]: GRANT ANY ROLE
OUTPUT METHOD Screen/File                [S]:
FILE NAME FOR OUTPUT              [priv.lst]:
OUTPUT DIRECTORY [DIRECTORY  or file (/tmp)]:
EXCLUDE CERTAIN USERS                    [N]:
USER TO SKIP                         [TEST%]:

Privilege => GRANT ANY ROLE has been granted to =>
====================================================================
        User => SYS (ADM = NO)
        Role => DATAPUMP_IMP_FULL_DATABASE (ADM = NO) which is granted to =>
                Role => DBA (ADM = NO) which is granted to =>
                        User => TUSER (ADM = NO)
                        User => SYS (ADM = YES)
                        User => SYSTEM (ADM = NO)
                User => SYS (ADM = YES)
                User => GSMADMIN_INTERNAL (ADM = NO)
        Role => DBA (ADM = NO) which is granted to =>
                User => TUSER (ADM = NO)
                User => SYS (ADM = YES)
                User => SYSTEM (ADM = NO)
        Role => DV_REALM_OWNER (ADM = NO) which is granted to =>
                User => SYS (ADM = YES)
        Role => IMP_FULL_DATABASE (ADM = NO) which is granted to =>
                User => TUSER (ADM = NO)
                User => SYS (ADM = YES)
                Role => DBA (ADM = NO) which is granted to =>
                        User => TUSER (ADM = NO)
                        User => SYS (ADM = YES)
                        User => SYSTEM (ADM = NO)
                Role => DATAPUMP_IMP_FULL_DATABASE (ADM = NO) which is
granted to =>
                        Role => DBA (ADM = NO) which is granted to =>
                                User => TUSER (ADM = NO)
                                User => SYS (ADM = YES)
                                User => SYSTEM (ADM = NO)
                        User => SYS (ADM = YES)
                        User => GSMADMIN_INTERNAL (ADM = NO)
        Role => EM_EXPRESS_ALL (ADM = NO) which is granted to =>
                Role => DBA (ADM = NO) which is granted to =>
                        User => TUSER (ADM = NO)
                        User => SYS (ADM = YES)
                        User => SYSTEM (ADM = NO)
                User => SYS (ADM = YES)
        User => GSMADMIN_INTERNAL (ADM = NO)
        User => SPATIAL_CSW_ADMIN_USR (ADM = NO)

PL/SQL procedure successfully completed.

For updates please visit http://www.petefinnigan.com/tools.htm

SQL>
SQL> @who_has_priv



who_has_priv: Release 1.0.3.0.0 - Production on Sat Jun 10 04:25:11 2017
Copyright (c) 2004 PeteFinnigan.com Limited. All rights reserved.

PRIVILEGE TO CHECK        [SELECT ANY TABLE]: GRANT ANY PRIVILEGE
OUTPUT METHOD Screen/File                [S]:
FILE NAME FOR OUTPUT              [priv.lst]:
OUTPUT DIRECTORY [DIRECTORY  or file (/tmp)]:
EXCLUDE CERTAIN USERS                    [N]:
USER TO SKIP                         [TEST%]:

Privilege => GRANT ANY PRIVILEGE has been granted to =>
====================================================================
        User => TUSER (ADM = NO)
        Role => IMP_FULL_DATABASE (ADM = NO) which is granted to =>
                User => SYS (ADM = YES)
                Role => DBA (ADM = NO) which is granted to =>
                        User => TUSER (ADM = NO)
                        User => SYS (ADM = YES)
                        User => SYSTEM (ADM = NO)
                Role => DATAPUMP_IMP_FULL_DATABASE (ADM = NO) which is
granted to =>
                        Role => DBA (ADM = NO) which is granted to =>
                                User => TUSER (ADM = NO)
                                User => SYS (ADM = YES)
                                User => SYSTEM (ADM = NO)
                        User => SYS (ADM = YES)
                        User => GSMADMIN_INTERNAL (ADM = NO)
        Role => DV_REALM_OWNER (ADM = NO) which is granted to =>
                User => SYS (ADM = YES)
        Role => DATAPUMP_IMP_FULL_DATABASE (ADM = NO) which is granted to =>
                Role => DBA (ADM = NO) which is granted to =>
                        User => TUSER (ADM = NO)
                        User => SYS (ADM = YES)
                        User => SYSTEM (ADM = NO)
                User => SYS (ADM = YES)
                User => GSMADMIN_INTERNAL (ADM = NO)
        User => GSMADMIN_INTERNAL (ADM = NO)
        User => SYS (ADM = NO)
        Role => EM_EXPRESS_ALL (ADM = NO) which is granted to =>
                Role => DBA (ADM = NO) which is granted to =>
                        User => TUSER (ADM = NO)
                        User => SYS (ADM = YES)
                        User => SYSTEM (ADM = NO)
                User => SYS (ADM = YES)
        Role => DBA (ADM = NO) which is granted to =>
                User => TUSER (ADM = NO)
                User => SYS (ADM = YES)
                User => SYSTEM (ADM = NO)

PL/SQL procedure successfully completed.

For updates please visit http://www.petefinnigan.com/tools.htm

SQL>


As you can see from the above who_can_access script results the IMP_FULL_DATABASE has these rights. Logically you would expect that GRANT ANY ROLE would allow someone to grant the DBA role to themselves but this is not the case:

Peters-MacBook-Pro:____12_2 pxf$ sqlplus sys/oracle1@//192.168.56.95:1539/orcl.localdomain as sysdba

SQL*Plus: Release 11.2.0.3.0 Production on Wed Oct 11 11:43:29 2017

Copyright (c) 1982, 2012, Oracle.  All rights reserved.


Connected to:
Oracle Database 12c Standard Edition Release 12.2.0.1.0 - 64bit Production

SQL> 
SQL> create user tuser identified by tuser;

User created.

SQL> grant create session to tuser;

Grant succeeded.

SQL> grant grant any role to tuser;

Grant succeeded.

SQL> connect tuser/tuser@//192.168.56.95:1539/orcl.localdomain
Connected.
SQL> grant dba to tuser;
grant dba to tuser
*
ERROR at line 1:
ORA-01031: insufficient privileges


SQL> 


If we also try and grant GRANT ANY PRIVILEGE then it fails differently:

SQL> connect sys/oracle1@//192.168.56.95:1539/orcl.localdomain as sysdba
Connected.
SQL> drop user tuser cascade;

User dropped.

SQL> create user tuser identified by tuser;

User created.

SQL> grant create session, grant any privilege to tuser;

Grant succeeded.

SQL> connect tuser/tuser@//192.168.56.95:1539/orcl.localdomain
Connected.
SQL> grant dba to tuser;
grant dba to tuser
      *
ERROR at line 1:
ORA-01924: role 'DBA' not granted or does not exist


SQL> 


Finally, we need to grant both rights and the it works:

SQL> connect sys/oracle1@//192.168.56.95:1539/orcl.localdomain as sysdba
Connected.
SQL> drop user tuser cascade;

User dropped.

SQL> create user tuser identified by tuser;

User created.

SQL> grant create session, grant any role, grant any privilege to tuser;

Grant succeeded.

SQL> connect tuser/tuser@//192.168.56.95:1539/orcl.localdomain
Connected.
SQL> grant dba to tuser;

Grant succeeded.

SQL> 


So we actually need CREATE SESSION to connect, GRANT ANY ROLE and GRANT ANY PRIVILEGE to be able to grant DBA to ourselves. The reason the original code by Peter works is because he granted IMP_FULL_DATABASE to his user; so no exploit and no bug. The issue is because this role has these two system privileges. The IMP_FULL_DATABASE role is very dangerous and is as good as SYSDBA. This is because it also has ALTER USER and we can then change the SYS password and become SYSDBA. Do not grant IMP_FULL_DATABASE or rights such as GRANT ANY%.

Remember about my classes and please register if you would like to join a class especially the live Work class at the end of October.

Vault : Grant object privilege to sysdba


If you enabled valut on the system and if you want to grant select on privilege to dba, it is enough to write this command :

conn hr/hr;
grant select on emp to dba;

conn yoursys/yourpasswd as sysdba;

select count(*) from emp;
(Ora-01031 ....)

conn hr/hr;
grant select on emp to yoursys;

conn yoursys/yourpasswd as sysdba;
select count(*) from emp;
(Ora-01031 ....)

In order to work, you should give this privilege to sys user;

conn hr/hr;
grant select on emp to sys;

conn yoursys/yourpasswd as sysdba;
select count(*) from emp;
ok...





Grant on V$ Views - ORA-02030

Today i was faced with an error when I try to give permission on a v$view

SQL> grant select on v$instance to hr;
grant select on v$
instance to hr
*
ERROR at line 1:
ORA-02030: can only select from fixed tables/views



What is ORA-02030?

The error ORA-02030 comes up when an attempt is made to select from a database object that is not a table or view.

SQL> select object_name
  2       , owner
  3       , object_type
  4  from all_objects
  5  where object_name like 'V$INSTANCE';

OBJECT_NAME     OWNER    OBJECT_TYPE
--------------- -------- ----------------
V$INSTANCE      PUBLIC   SYNONYM

How to resolve ORA-02030

ORA-02030 can be eliminated by granting select on the underlying table/view of the v$ synonym.
To find the underlying table/view, query all_synonyms:

SQL> select table_owner, table_name from all_synonyms
  2  where synonym_name like 'V$INSTANCE';

TABLE_OWNER                    TABLE_NAME
------------------------------ -----------
SYS                            V_$INSTANCE

That’s it – synonym v$instance points to an object with a slightly different name: v_$instance.


v_$instance is, indeed, not a table but a view:

SQL> select object_type from all_objects where object_name = 'V_$INSTANCE';

OBJECT_TYPE
-------------------
VIEW
 
Given these findings, all that’s needed is to grant select to the non-admin user on the v_$ view corresponding to the v$ synonym.

SQL> grant select on v_$instance to hr;

Grant succeeded.