Oracle – test a database link of a user as sys user


1. A database link exists in the current database owned by CURRENTSCHEMA user (you don't know the password of the CURRENTSCHEMA user)

The database link was created by the application owner as follows:

  CREATE DATABASE LINK "'DBLINKNAME.DOMAIN.COM"
   CONNECT TO "TARGETSCHEMA" IDENTIFIED by password
   USING 'TNSNAMES_ALIAS';

2. Create a table in the target database as a snapshot of the current v$session dynamic view

                       create table x as select * from v$session;

3. grant select on the table to TARGETSCHEMA

                       grant select on x to targetschema;

4. Use anonymous pl/sql block below to execute a command on the new table to prove that the database link 
   exists, works, and is pointing at the right target database.

set serverout on size unlimited (if using sqlplus)

declare
strresult varchar2(1024);
stmt_cursor NUMBER;
rc          NUMBER;
found       NUMBER := 0;
p_schema    VARCHAR2(30) := 'CURRENTSCHEMA';
p_obj       VARCHAR2(30) := 'DBLINKNAME.DOMAIN.COM';
uid    dba_users.user_id%TYPE;
BEGIN
  select user_id into uid from dba_users where username=p_schema;
  stmt_cursor := dbms_sql.open_cursor;
  sys.dbms_sys_sql.parse_as_user(stmt_cursor, 
      'BEGIN SELECT COUNT(*) INTO :found 
             FROM user_db_links
             WHERE db_link = :p_obj;
       EXCEPTION WHEN OTHERS THEN :found := 0;
       END;', dbms_sql.NATIVE,
       uid);
  --dbms_sql.bind_variable(stmt_cursor, ':p_schema', p_schema);
  dbms_sql.bind_variable(stmt_cursor, ':p_obj', p_obj);
  dbms_sql.bind_variable(stmt_cursor, ':found', found);
  rc := dbms_sql.execute(stmt_cursor);
  dbms_sql.variable_value(stmt_cursor, ':found', found);
  dbms_sql.close_cursor(stmt_cursor);
  
  dbms_output.put_line('FOUND: '||found);
  
  IF found = 1 THEN
     stmt_cursor := dbms_sql.open_cursor;
     sys.dbms_sys_sql.parse_as_user(stmt_cursor, 'select machine from sys.x@'||p_obj, dbms_sql.NATIVE,uid);
     sys.dbms_sys_sql.define_column(stmt_cursor,1,strresult,1000);
     rc := dbms_sys_sql.execute(stmt_cursor);
     dbms_output.put_line('rc is: '||to_char(rc));
     loop
         if ( dbms_sys_sql.fetch_rows(stmt_cursor) > 0 )
         then
           dbms_sys_sql.column_value(stmt_cursor, 1,strresult );
           dbms_output.put_line('table_name is: '||strresult);
         else
          exit;     
         end if;     
     end loop;
     dbms_sql.close_cursor(stmt_cursor);
     DBMS_OUTPUT.PUT_LINE(stmt_cursor);
  END IF;
END;
/

Leave a Reply

Your email address will not be published. Required fields are marked *