从PL / SQL调用shell脚本,但shell作为网格用户而不是oracle执行

我正在尝试使用Runtime.getRuntime().exe执行Oracle数据库内的shell脚本。

运行在Red Hat 5.5上的Oracle 11.2.0.4 EE


CREATE OR REPLACE procedure pr_executa_host(p_cmd varchar2) as language java name 'Util.RunThis(java.lang.String)'; / 

 public class Util extends Object { public static int RunThis(java.lang.String args) { Runtime rt = Runtime.getRuntime(); int rc = -1; try { Process p = rt.exec(args); int bufSize = 4096; BufferedInputStream bis = new BufferedInputStream(p.getInputStream(), bufSize); int len; byte buffer[] = new byte[bufSize]; // Echo back what the program spit out while ((len = bis.read(buffer, 0, bufSize)) != -1) System.out.write(buffer, 0, len); rc = p.waitFor(); } catch (Exception e) { e.printStackTrace(); rc = -1; } finally { return rc; } } } / 

java授予db用户的权限SCOTT:


 kind grantee type name action GRANT SCOTT java.io.FilePermission /webstart/mn500/* readFileDescriptor GRANT SCOTT java.io.FilePermission /webstart/mn500/* read,write,execute GRANT SCOTT java.io.FilePermission /webstart/mn500/* writeFileDescriptor GRANT SCOTT java.io.FilePermission /webstart/mn500/CONCLUIDO/MN457560/executa.sh execute GRANT SCOTT java.lang.RuntimePermission * writeFileDescriptor GRANT SCOTT java.lang.RuntimePermission /webstart/mn500/CONCLUIDO/MN457560/executa.sh execute 

shell脚本executa.sh,这是我试图执行的:


 #!/bin/sh echo i am `/usr/bin/whoami` echo environment `/bin/env` /bin/date>>/webstart/mn500/CONCLUIDO/MN457560/test.txt 

目录上的权限:


 p08[oracle] $ ls -larth /webstart/mn500/CONCLUIDO/MN457560 -rw-r--r-- 1 oracle oinstall 1 Jul 29 12:03 test.txt -rwxr-xr-x 1 oracle orafiles 430 Jul 29 12:04 executa.sh drwxr-xr-x 2 oracle orafiles 4.0K Jul 29 12:04 . 

事情是,当我执行过程pr_executa_host,它运行shell脚本为网格操作系统用户,而不是甲骨文! (尽pipe它保留了oracle环境variables,就像在执行shell脚本之前做了一个'su grid -m'一样)

由于网格对目录和文件都没有写权限,因此脚本不会执行任何操作,testing文件保持不变。 看一看:


 begin dbms_java.set_output(1000000); pr_executa_host('/webstart/mn500/CONCLUIDO/MN457560/executa.sh'); dbms_lock.sleep(2); end; / i am grid environment HOSTNAME=p08.XXXXXXXXXXXX.com.br SHELL=/bin/bash TERM=xterm HISTSIZE=1000 SSH_CLIENT=10.141.112.28 56029 22 NLS_LANG=AMERICAN_AMERICA.WE8MSWIN1252 QTDIR=/usr/lib64/qt-3.3 QTINC=/usr/lib64/qt-3.3/include SSH_TTY=/dev/pts/0 USER=oracle LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;0 1:mi=01;05;37;41:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01 ;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.zip=01;31:*.z=01;31:* .Z=01;31:*.dz=01;31:*.gz=01;31:*.lz=01;31:*.xz=01;31:*.bz2=01;31:*.tbz=01;31:*.tbz2=01;31:*.bz=01;31 :*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.rar=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7 z=01;31:*.rz=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01 ;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;3 5:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.ogm=01;35:* .mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm= 01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35 :*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.a ac=01;36:*.au=01;36:*.flac=01;36:*.mid=01;36:*.midi=01;36:*.mka=01;36:*.mp3=01;36:*.mpc=01;36:*.ogg= 01;36:*.ra=01;36:*.wav=01;36:*.axa=01;36:*.oga=01;36:*.spx=01;36:*.xspf=01;36: ORACLE_SID=sigepshm ORACLE_BASE=/oracle ORACLE_HOSTNAME=P08 PATH= MAIL=/var/spool/mail/oracle TNS_ADMIN=/grid/product/11.2.0/grid/network/admin PWD=/oracle/product/11.2.0/db/dbs KDE_IS_PRELINKED=1 LANG=en_US.UTF-8 ORA_NET2_DESC=27,30 KDEDIRS=/usr ORACLE_TERM=xterm ORACLE_SPAWNED_PROCESS=1 HISTCONTROL=ignoredups SSH_ASKPASS=/usr/libexec/openssh/gnome-ssh-askpass HOME=/home/oracle SHLVL=2 GRID_HOME=/oracle/product/11.2.0/grid LOGNAME=oracle CVS_RSH=ssh QTLIB=/usr/lib64/qt-3.3/lib SSH_CONNECTION=10.141.112.28 56029 10.147.0.8 22 CLASSPATH=/oracle/product/11.2.0/db/JRE:/oracle/product/11.2.0/db/jlib:/oracle/product/11.2.0/db/rdb ms/jlib LESSOPEN=|/usr/bin/lesspipe.sh %s DISPLAY=localhost:10.0 ORACLE_HOME=/oracle/product/11.2.0/db G_BROKEN_FILENAMES=1 _=/bin/env 

为什么数据库中的java调用unix命令为网格用户,而不是甲骨文?

非常感谢您的帮助,Stolf

Solutions Collecting From Web of "从PL / SQL调用shell脚本,但shell作为网格用户而不是oracle执行"

正如在注释中指出的那样,问题是Runtime.getRuntime()。exec在EXTPROC中运行,从而通过Grid listner运行。 由于我们的新配置在DB和GRID之间有操作系统用户隔离,这就引起了FS上的权限问题。

解决这个问题的方法之一是:

  • 修复FS允许网格用户写文件并将umask改为774或664之类的东西,这样grid和oracle用户都可以修改这些文件;

  • 更改sudoers文件,并允许网格执行oracle所需的命令,而无需输入密码,并将shell脚本更改为包含sudo;

  • 在另一个端口上的DB Home上创建一个新的侦听器,并将TNSNAMES.ORA条目更改为指向新端口。 然后extproc将作为OS用户oracle执行。 您将不得不在$ OH上手动编辑LISTENER.ORA并使用lsnrctl启动它,因为使用srvctl注册的监听程序将始终由网格启动;

  • 将主监听器更改为数据库主页。 我不建议(见上面的项目)。

[编辑]正如@AlexPoole和@jonearles所指出的,还有两个选项不适合我的情况,但可能适用于其他选项:

  • 如果你在sqlplus本地运行脚本,设置ORACLE_SID,FS访问将由运行sqlplus的操作系统用户进行。 所以你可以像oracle或其他用户一样运行并修复FS权限;
  • 如果您将dbms_job调度程序的作业安排为SYS,则该任务将由oracle执行(此行为可能与版本有关,因此需要进一步测试)。

问候,

丹尼尔·斯托夫

在进一步的调查中,它以启动会话的操作系统用户身份运行脚本; 但服务器用户,而不是在v$session看到的客户端osuser

如果您通过SQL * Plus进行本地连接,而不通过SQL * Net,则shell脚本将作为您自己的操作系统用户运行,而不是作为grid oracle ,除非您作为其中一个登录到该框。 所以当我执行程序时,脚本报告i am apoole

当您远程运行时,会话的OS用户是监听器所有者,默认情况下在网格环境中将成为网grid 。 您可以在侦听器启动时看到grid用户的环境。

所以如果你要通过SQL * Net连接的客户端手动远程执行,那么你自己的答案中的选项是有效的。 您可以将数据库侦听器移动到oracle帐户下运行,或者在该帐户下创建一个新的侦听器,并通过该连接进行连接。 然后,脚本将从通过该监听器连接的任何会话中调用时作为oracle执行。 或者让操作系统权限/ sudo为你工作。

如果你将会或者可能在不通过SQL * Net的情况下从本地会话中执行它,那么你需要使得操作系统权限对于可能调用它的任何用户有效 – 假设你不会从SQL * Plus启动oracle帐号。 聆听者不是图片的一部分,所以grid用户不是一个因素。


这是当它作为一个匿名块运行时, 正如@jonarles在对这个问题的评论中指出的那样,预定工作的行为是不同的。 默认情况下,它将以nobody执行脚本,这意味着你将不得不放宽OS权限。