OEM安装报错不是内部或外部程序的解决过程

标题比较拗口,客户在安装OEM的时候碰到了“不是内部或外部命令,也不是可运行的程序或批处理文件”的错误。
客户环境是11.2.0.1 for Windows环境,以前配置过OEM,有一段时间没有使用,最近打算启用OEM,发现无法正常启动,尝试了多次后,只能将OEM清除掉。在卸载OEM并重新安装时,出现了这个错误。
详细的错误为:

Connecting TO DATABASE USING CONNECT string (DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=NODE)(PORT=1521)))(CONNECT_DATA=(SERVICE_NAME=DAISY))) IN home E:\app\Administrator\product\11.2.0\dbhome_1 WITH USER "SYS" ROLE "SYSDBA". 
connected TO DATABASE. 
SQL TO EXECUTE DECLARE repos_pwd varchar2(30); view_user varchar2(30); view_user_pwd varchar2(30); view_user_acc_status varchar2(30); BEGIN repos_pwd := ?; sysman.mgmt_view_priv.get_view_user(view_user); SELECT account_status INTO view_user_acc_status FROM sys.dba_users WHERE UPPER(username) = UPPER ( view_user ); IF view_user_acc_status LIKE '%LOCKED%' THEN EXECUTE immediate 'alter user ' || view_user || ' account unlock'; END IF; IF view_user_acc_status LIKE '%EXPIRED%' THEN sysman.mgmt_view_priv.set_view_user_creds ( repos_pwd ); sysman.mgmt_view_priv.GET_VIEW_USER_CREDS ( view_user, view_user_pwd ); EXECUTE immediate 'alter user ' || view_user || ' identified by ' || view_user_pwd || ''; END IF; END; 
noOfParams TO bind: 1. 
SQL EXECUTE successfully. 
2012-9-24 18:59:05 oracle.sysman.emcp.util.PlatformInterface executeCommand
配置: '??S-1-5-21-343818398-2147128839-1417001333-500' 不是内部或外部命令,也不是可运行的程序
或批处理文件。
2012-9-24 18:59:05 oracle.sysman.emcp.util.PlatformInterface executeCommand
配置: 执行 CMD /C E:\app\Administrator\product\11.2.0\dbhome_1\sysman\admin\scripts\emca\emcaDbUtil.bat "E:\app\Administrator\product\11.2.0\dbhome_1\sysman\admin\scripts;E:\app\Administrator\product\11.2.0\dbhome_1\bin;" E:/app/Administrator/product/11.2.0/dbhome_1/perl/bin\perl.exe E:\app\Administrator\product\11.2.0\dbhome_1\sysman\admin\scripts\emca\emcaDbUtil.pl E:\app\Administrator\product\11.2.0\dbhome_1 "(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=NODE)(PORT=1521)))(CONNECT_DATA=(SERVICE_NAME=DAISY)))" SYS SYSDBA DECLARE repos_pwd varchar2(30); view_user varchar2(30); view_user_pwd varchar2(30); view_user_acc_status varchar2(30); BEGIN repos_pwd := ?; sysman.mgmt_view_priv.get_view_user(view_user); SELECT account_status INTO view_user_acc_status FROM sys.dba_users WHERE UPPER(username) = UPPER ( view_user ); IF view_user_acc_status LIKE '%LOCKED%' THEN EXECUTE immediate 'alter user ' || view_user || ' account unlock'; END IF; IF view_user_acc_status LIKE '%EXPIRED%' THEN sysman.mgmt_view_priv.set_view_user_creds ( repos_pwd ); sysman.mgmt_view_priv.GET_VIEW_USER_CREDS ( view_user, view_user_pwd ); EXECUTE immediate 'alter user ' || view_user || ' identified by ' || view_user_pwd || ''; END IF; END; DAISY 1 SYSMAN_PWD 时出错
2012-9-24 18:59:05 oracle.sysman.emcp.EMReposConfig unlockMGMTAccount
配置: Failed TO UNLOCK mgmt_view account
2012-9-24 18:59:05 oracle.sysman.emcp.EMReposConfig invoke
严重: 无法对所有 EM 相关帐户解锁
2012-9-24 18:59:05 oracle.sysman.emcp.EMConfig perform
严重: 无法对所有 EM 相关帐户解锁
有关详细资料, 请参阅 E:\app\Administrator\cfgtoollogs\dbca\DAISY\emConfig.log 中的日志文件。
2012-9-24 18:59:05 oracle.sysman.emcp.EMConfig perform
配置: Stack Trace: 
oracle.sysman.emcp.exception.EMConfigException: 无法对所有 EM 相关帐户解锁
at oracle.sysman.emcp.EMReposConfig.invoke(EMReposConfig.java:349)
at oracle.sysman.emcp.EMReposConfig.invoke(EMReposConfig.java:158)
at oracle.sysman.emcp.EMConfig.perform(EMConfig.java:253)
at oracle.sysman.assistants.util.em.EMConfiguration.run(EMConfiguration.java:583)
at oracle.sysman.assistants.dbca.backend.PostDBCreationStep.executeImpl(PostDBCreationStep.java:968)
at oracle.sysman.assistants.util.step.BasicStep.execute(BasicStep.java:210)
at oracle.sysman.assistants.util.step.Step.execute(Step.java:140)
at oracle.sysman.assistants.util.step.StepContext$ModeRunner.run(StepContext.java:2667)
at java.lang.Thread.run(Thread.java:595)
2012-9-24 18:59:05 oracle.sysman.emcp.EMConfig restoreOuiLoc
配置: Restoring oracle.installer.oui_loc TO E:\app\Administrator\product\11.2.0\dbhome_1\oui

本来最先定位的是Oracle的异常“无法对所有 EM 相关帐户解锁”,前台出现的也是这个错误信息。但是在MOS找了大量的案例,发现都和当前的问题不符。仔细检查数据库中用户的配置,也未发现任何的异常。
随后把疑点逐渐转移到上面“不是内部或外部命令,也不是可运行的程序或批处理文件。”信息上。并且发现这个问题并非只有在执行OEM的脚本时报错,而是起动CMD命令窗口时都会出现这个错误。
那么其实问题就很明显了,导致问题的原因并不是发生在数据库层,而是操作系统层面,显然CMD命令被进行了恶意的篡改。
详细询问了一下情况,客户以前确实中过病毒,后来通过杀毒已经将病毒清除。怀疑虽然病毒被清除,但是CMD程序并没有完全恢复原始状态,导致目前启动CMD时会寻找一个不存在的文件。
检查CMD命令的注册表信息,并未发现有异常的修改。怀疑是CMD代码层的autorun被修改:

reg ADD "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Command Processor" /v "AutoRun" /d "" /f

通过执行上面的命令,CMD启动不会在出现前面的错误,再次安装OEM组件,安装顺利完成。
这个案例也再次反映了Windows环境下数据库健壮性的问题。

This entry was posted in ORACLE and tagged , , , . Bookmark the permalink.

Leave a Reply

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