标题比较拗口,客户在安装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环境下数据库健壮性的问题。