MINI MINI MANI MO

Path : /opt/oracle/product/18c/dbhomeXE/rdbms/admin/
File Upload :
Current File : //opt/oracle/product/18c/dbhomeXE/rdbms/admin/olsaudup.sql

Rem
Rem $Header: rdbms/admin/olsaudup.sql /main/3 2017/05/12 13:12:17 risgupta Exp $
Rem
Rem olsaudup.sql
Rem
Rem Copyright (c) 2014, 2017, Oracle and/or its affiliates. 
Rem All rights reserved.
Rem
Rem    NAME
Rem      olsaudup.sql - Oracle Label Security AUD$ pre-UPgrade.
Rem
Rem    DESCRIPTION
Rem      This script is used to move audit records from SYSTEM schema
Rem      to SYS schema.
Rem
Rem    NOTES
Rem      Called from c1102000.sql
Rem
Rem    BEGIN SQL_FILE_METADATA 
Rem    SQL_SOURCE_FILE: rdbms/admin/olsaudup.sql 
Rem    SQL_SHIPPED_FILE: rdbms/admin/olsaudup.sql 
Rem    SQL_PHASE: UPGRADE
Rem    SQL_STARTUP_MODE: UPGRADE 
Rem    SQL_IGNORABLE_ERRORS: NONE 
Rem    SQL_CALLING_FILE: rdbms/admin/c1102000.sql
Rem    END SQL_FILE_METADATA
Rem
Rem    MODIFIED   (MM/DD/YY)
Rem    risgupta    05/08/17 - Bug 26001269: Modify SQL_FILE_METADATA
Rem    pmojjada    02/05/15 - Bug# 20421634: Long identifier changes
Rem    risgupta    05/16/14 - Created
Rem

@@?/rdbms/admin/sqlsessstart.sql

-- Alter preupg_aud$ to change VARCHAR2 columns max lengths

-- bug 16317592: Require to move this block here because we should not
-- alter column lengths AFTER invoking olspreupgrade.sql below since 
-- this ends up resetting our updates to tab$.cols

-- Note: This block returns without altering preupg_aud$ if the user never
-- ran olspreupgrade.sql before starting upgrade. When olspreupgrade is
-- invoked after this block below, the CTAS would create preupg_aud$ from 
-- the "upgraded" aud$, so these alter ddls are not needed on preupg_aud$
DECLARE
  cnt NUMBER;
BEGIN
  -- Find out if preupg_aud$ exists.
  SELECT count(*) INTO cnt FROM dba_tables
  WHERE table_name = 'PREUPG_AUD$' AND owner = 'SYS';

  -- If preupg_aud$ exists, alter it.
  IF (cnt = 1) THEN
    begin
      execute immediate 'alter table preupg_aud$ 
                           modify (clientid     varchar2(128),
                                   userid       varchar2(128),
                                   obj$creator  varchar2(128),
                                   auth$grantee varchar2(128),
                                   new$owner    varchar2(128),
                                   obj$edition  varchar2(128)
                                  )';
    exception when others then
      if sqlcode in (-904, -942) then null;
      else raise;
      end if;
    end;
  END IF;
END;
/

-- bug 16317592: start moving audit records to temp table. This
-- post processing is needed before we finally move all records
-- to SYS.aud$ and remove SYSTEM.aud$ contents. olspreupgrade.sql 
-- returns without any processing if it was run before upgrade
@@olspreupgrade.sql

-- Bug 13529466: Move Audit Records from SYSTEM.AUD$ to SYS.AUD$
-- Drop aud$ synonym
DROP SYNONYM AUD$;


-- Create a utility procedure to populate SYS.aud$ table
CREATE OR REPLACE PROCEDURE populate_aud(col_str      VARCHAR2,
                                         orignal_rows NUMBER)
AS
counter      NUMBER := 0;
nrows        NUMBER := 0;
column_list  VARCHAR2(4000);
type ctyp is ref cursor;

rowid_cur ctyp;
rowid_tab dbms_sql.urowid_table;
BEGIN
  -- populate SYS.aud$ with the rows from SYSTEM.aud$
  -- delete the processed rows in SYSTEM.aud$
  nrows := orignal_rows;
  column_list := 'sessionid, entryid, statement, timestamp#, userid, ' ||
                 'userhost, terminal, action#, returncode, ' ||
                 'obj$creator, obj$name, auth$privileges, auth$grantee, '||
                 'new$owner, new$name, ses$actions, ses$tid, ' ||
                 'logoff$lread, logoff$pread, logoff$lwrite, ' ||
                 'logoff$dead, logoff$time, comment$text, clientid, ' ||
                 'spare1, spare2, obj$label, ses$label, priv$used, ' ||
                 'sessioncpu, ntimestamp#, proxy$sid, user$guid, ' ||
                 'instance#, process#, xid, auditid, scn, dbid, ' ||
                 'sqlbind, sqltext, obj$edition';

  column_list := column_list || col_str;

  counter := ceil(nrows/1000000);
  LOOP
    OPEN rowid_cur FOR 'select rowid from SYSTEM.aud$' ||
                       ' where rownum <= 1000000';

    -- Fetch 1st 100000 rows
    FETCH rowid_cur bulk collect into rowid_tab limit 100000;

    -- Exit, if no rows
    IF (rowid_tab.count = 0) THEN
      EXIT;
    END IF;

    -- For each row fetched
    LOOP
        -- 1. Insert into SYS.aud$
        FORALL i in 1..rowid_tab.count
          EXECUTE IMMEDIATE
          'INSERT /*APPEND*/ INTO SYS.aud$ (' || column_list ||
          ') (SELECT ' || column_list ||
          ' FROM SYSTEM.aud$ WHERE rowid = :1)' using rowid_tab(i);

        -- 2. Delete from SYSTEM.aud$
        FORALL i in 1..rowid_tab.count
          EXECUTE IMMEDIATE
          ' DELETE FROM SYSTEM.aud$ WHERE rowid = :1 ' using rowid_tab(i);

        COMMIT;

        -- Exit if total rows is less than 100000
        IF (counter = 1 and nrows <= 100000) THEN
          EXIT;
        END IF;

        nrows := nrows - 100000;

        -- Fetch next 100000 rows
        FETCH rowid_cur bulk collect into rowid_tab limit 100000;

        -- Exit, if no rows left
        IF (rowid_tab.count = 0) THEN
          EXIT;
        END IF;
    END LOOP;
    counter := counter - 1;
  END LOOP;
  CLOSE rowid_cur;
EXCEPTION
  WHEN OTHERS THEN
    ROLLBACK;
    RAISE;
END;
/
show errors;

-- Move audit records
DECLARE
tab_name  DBMS_ID; 
col_str   VARCHAR2(4000) := '';
where_str VARCHAR2(4000) := '';
sqlstmt   VARCHAR2(4000);
nrows        NUMBER := 0;
npol         NUMBER := 0;
obj_num      NUMBER;
cnt          NUMBER;
tstamp       TIMESTAMP;
col_name   DBMS_QUOTED_ID; 
col_name1  DBMS_QUOTED_ID; 
col_name2  VARCHAR2(258);

type ctyp is ref cursor;
rowid_cur ctyp;
rowid_tab dbms_sql.urowid_table;

c_policy_columns ctyp;

BEGIN

  -- check if SYS.aud$ already exists. may be upgrade script was run before
  -- If SYS.aud$ exists, don't do anything
  SELECT count(*) INTO cnt FROM dba_tables
     WHERE table_name = 'AUD$' AND owner = 'SYS';

  IF cnt = 1 THEN
    RETURN;
  END IF;

  -- Check if temp aud table exists
  BEGIN
   SELECT table_name INTO tab_name FROM dba_tables
   WHERE table_name = 'PREUPG_AUD$' AND owner = 'SYS';
  EXCEPTION
   WHEN NO_DATA_FOUND THEN
      RAISE;
   /* abort the upgrade *. This should never happen as 
      we check for SYS.PREUPG_AUD$ at the beginning of upgrade */
  END;

  -- construct the col_str to be used when inserting into SYS.aud$
  -- construct the where clause of columns names to be used by update
  BEGIN
    -- make olspreupgrade.sql runnable during a upgrade rerun
    BEGIN
      OPEN c_policy_columns FOR 'SELECT column_name FROM lbacsys.lbac$pol';
    EXCEPTION
      WHEN OTHERS THEN
        IF SQLCODE != -942 THEN
          RAISE;
        ELSE
          OPEN c_policy_columns FOR 'SELECT column_name FROM lbacsys.ols$pol';
        END IF;
    END;

    LOOP
      FETCH c_policy_columns INTO col_name;
      EXIT WHEN c_policy_columns%NOTFOUND;

      npol:= npol + 1;

      -- Bug 13887731: prevent sql injection
      -- 1. Use DBMS_ASSERT.ENQUOTE_NAME for SELECT column list.
      col_name1 := dbms_assert.enquote_name(col_name, false);
      -- 2. Use DBMS_ASSERT.ENQUOTE_LITERAL for WHERE clause list
      --    since ENQUOTE_NAME will add double-quotes too.
      col_name2 := dbms_assert.enquote_literal
                     (replace((col_name), '''', ''''''));

      IF npol <> 1 THEN
        col_str := col_str || ', ' || col_name1;
        where_str := where_str || ' or name = ' || col_name2;
      ELSE
        col_str := ', ' || col_name1;
        where_str := ' name = ' || col_name2;
      END IF;

    END LOOP;
    CLOSE c_policy_columns;

  EXCEPTION 
    WHEN OTHERS THEN
      CLOSE c_policy_columns;
      RAISE;
  END;

  EXECUTE IMMEDIATE 'ALTER TABLE SYS.preupg_aud$ RENAME TO aud$';

  -- Get a count of audit records in SYSTEM.AUD$
  EXECUTE IMMEDIATE 'select count(*) from system.aud$' INTO nrows;

  IF (nrows > 0) THEN
    -- insert the rows into SYS.aud$
    populate_aud(col_str, nrows);
  END IF;

  -- Can make ols policy columns hidden since they are not last columns
  -- If an OLS Policy exists,
  IF (npol > 0) THEN
    BEGIN
      -- Update the policy columns with hidden bits in SYS.aud$ table
      -- Get obj# for SYS.aud$ table
      SELECT tab.obj# into obj_num
      FROM sys.tab$ tab, sys.obj$ obj, sys.user$ usr
      WHERE obj.name ='AUD$' AND usr.name = 'SYS'
      AND obj.obj# =tab.obj# AND usr.user# = obj.owner#
      AND obj.type#=2;

      -- set bit to KQLDCOP2_INVCQ
      sqlstmt := 'UPDATE sys.col$ set ' ||
      'property = property + 17179869184' ||
      ' WHERE (' || where_str ||
      ') AND  obj#  = '|| obj_num;
      EXECUTE IMMEDIATE sqlstmt;

      COMMIT;
    EXCEPTION
      WHEN OTHERS THEN
        ROLLBACK;
        RAISE;
    END;
  END IF;

  -- Make sure the number of rows in SYS.aud$ >= nrows
  BEGIN
    EXECUTE IMMEDIATE 'select SYSTIMESTAMP from dual  WHERE ' ||
           '(SELECT count(*) FROM SYS.aud$) >= :1'
            INTO tstamp
            USING nrows;
    EXCEPTION
      WHEN OTHERS THEN
        RAISE;
  END;

  -- Make sure there are no more rows left in SYSTEM.aud$
    BEGIN
    EXECUTE IMMEDIATE 'select SYSTIMESTAMP from dual  WHERE ' ||
           '(SELECT count(*) FROM SYSTEM.aud$) =0'
            INTO tstamp;
    EXCEPTION
      WHEN OTHERS THEN
        RAISE;
    END;

    -- drop system.aud$ if everything went ok with moving
    -- its contents to sys.aud$
    EXECUTE IMMEDIATE 'DROP TABLE SYSTEM.aud$';
END;
/
show errors;

DROP PROCEDURE populate_aud;

@?/rdbms/admin/sqlsessend.sql

OHA YOOOO