пятница, 2 ноября 2012 г.

*nix su comand for Oracle


Интересную вещь надыбал.
В оракле, оказывается, есть механизм который позволяет получить результат аналогичный su - <username> под рутом, то есть переключиться на другого юзера БД без смены пароля в рамках одной сесси.

Как это реализуется?
Недокументированной процедурой
sys.kupp$proc.change_user(' ');
Эта процедура входит в состав АПИ dbms_datapump, где она проворачивает один из механизмов REMAP_SCHEMA. То есть работает в 10-ой и 11-ой версии.

Как работает?
По умолчанию такая возможность закрыта

SQL> begin
  2  sys.kupp$proc.change_user('SYSMAN');
  3  end;
  4   /
begin
*
ERROR at line 1:
ORA-31625: Schema SYSMAN is needed to import this object, but is unaccessible
ORA-06512: at "SYS.KUPP$PROC", line 45
ORA-06512: at "SYS.KUPP$PROC", line 930
ORA-06512: at line 2

Раскрывается это  через вызов функции
SQL> select sys.kupp$proc.disable_multiprocess from dual; 

DISABLE_MULTIPROCESS
--------------------
                   1

Так же сие работает и в PL/SQL

SQL> declare
  2  outp varchar2(200);
  3  begin
  4  outp := sys.kupp$proc.disable_multiprocess();
  5  sys.kupp$proc.change_user('SCOTT');
  6  select count(*) into outp from user_sys_privs;
  7  dbms_output.put_line('Scott privs: '||outp);
  8  sys.kupp$proc.change_user('DBSNMP');
  9  select count(*) into outp from user_sys_privs;
10  dbms_output.put_line('Dbsnmp privs: '||outp);
11  sys.kupp$proc.change_user('SYS');
12  select count(*) into outp from user_sys_privs;
13  dbms_output.put_line('SYS privs: '||outp);
14  end;
15  /
Scott privs: 2
Dbsnmp privs: 4
SYS privs: 200

PL/SQL procedure successfully completed.

SQL> show user
USER is "SYS"
SQL> select user from dual;

USER
------------------------------
SYS

Но не забывайте «вернуться» обратно, если вдруг чего. ;)

SQL> declare
  2  outp varchar2(200);
  3  begin
  4  outp := sys.kupp$proc.disable_multiprocess();
  5  sys.kupp$proc.change_user('SCOTT');
  6  select count(*) into outp from user_sys_privs;
  7  dbms_output.put_line('Scott privs: '||outp);
  8  sys.kupp$proc.change_user('DBSNMP');
  9  select count(*) into outp from user_sys_privs;
10  dbms_output.put_line('Dbsnmp privs: '||outp);
11  --sys.kupp$proc.change_user('SYS');
12  --select count(*) into outp from user_sys_privs;
13  --dbms_output.put_line('SYS privs: '||outp);
14  end;
15  /
Scott privs: 2
Dbsnmp privs: 4

PL/SQL procedure successfully completed.

SQL> show user
USER is "SYS"
SQL> select user from dual;

USER
------------------------------
DBSNMP

SQL> exec sys.kupp$proc.change_user('SYS');
BEGIN sys.kupp$proc.change_user('SYS'); END;

      *
ERROR at line 1:
ORA-06550: line 1, column 7:
PLS-00201: identifier 'SYS.KUPP$PROC' must be declared
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored

У кого такая возможность есть по умолчанию ?
Определяется наличием привилегии BECOME USER, так что нужно быть осторожным ;)

SQL> select privilege, grantee from dba_sys_privs where privilege  like 'BECOM%';

PRIVILEGE                                GRANTEE
---------------------------------------- ------------------------------
BECOME USER                              SYS
BECOME USER                              DBA
BECOME USER                              IMP_FULL_DATABASE


Update:
в 11.2.0.4 данная возможность не открывается с помощью

  sys.kupp$proc.disable_multiprocess();

Хотя внутренность кода на первый взгляд не отличается, но данный хак работает только в 11.2.0.3 и ниже

Комментариев нет:

Отправить комментарий