ORA-01031: insufficient privileges很明显,权限方面出了问题。想想也应该,我们的Windows服务使用的应该是NT AUTHORITY/SYSTEM(S-1-5-18)的权限在运行。于是方案A出台了。
方案A:将SYSTEM帐户加入ORA_DBA组。
从UI是看不到SYSTEM帐户的,只有用命令行的方式加。
net localgroup ORA_DBA system /add结果还是得到了ORA-01031。分析了一下,有可能是因为操作系统认证需要从操作系统的用户帐号来进行,而SYSTEM帐号是个内置帐号,在用户管理里面是看不到的。于是这个方案宣告失败。
基本上,方案A走不通的话,那就只有这种办法了。首先是建立一个Windows帐户,并加入ORA_DBA组中。密码自己随便定一个就好。
net user dbauser 1qaz2wsx /add但是具体怎么切换呢?
net localgroup ORA_DBA dbauser /add
一般RunAs服务(也就是Secondary Logon)都是启动的,所以首先想到用Windows 2000/XP/2003自带的命令runas来实现。
runas /user:dbauser "sqlplus \"/ as sysdba\" ……"没报错,可是没反应。噢,麻烦来了。这个runas命令是要问密码的。
上Google找了一下解决方案。试了一下用vbs的SendKeys那种,手动状态下似乎勉强可行,但要放在Windows服务中,没戏。因为它毕竟是模拟客户端的输入来键入密码的。有个自称可以让runas支持管道输入密码的小工具sanur也没戏,感觉它俩的原理是类似的。
既然runas这条路走不通,就彻底抛开它另寻出路了。
有个工具lsrunas自称可以替代runas,于是下载下来一试。虽然参数比较罗嗦,但的确是可以替代。不过这个替代也仅限于通常情况下,一旦放到我们的Windows服务中,就没有反应了。
另外有人推荐了一个cpau。这个工具还是不行,不过它倒是留下了一个提示信息,这个信息成了重要的线索:
ERROR: CPAU doesn't support running from LocalSystem.看来还是SYSTEM的权限问题。
看来这些工具都没问题,但是应该都不支持在SYSTEM的权限下面切换用户。听说以前某个同事也为这个问题研究了好些天,最后还是放弃了。老实说,听到这个消息我有一点点绝望感。
这SYSTEM权限吧,说它低,却能操作很多系统级别的东西。可要说它高呢,有些本来很容易的事情它又做不了。不过理论上通常还是认为SYSTEM的权限比较「高」,所以很多黑客都以获得SYSTEM权限为目标在半肉鸡上奋斗着。于是,我以SYSTEM降权为主要话题,去黑客站点看了看。
还真是有收获,得到了一段代码,是一个利用API自己实现的runas工具程序。在命令行下使用了一下,感觉挺好,比Windows那个runas好用多了。
不过,放进Windows服务里面,还是不行。真的是快绝望了。
由于我们的系统有现成的接口用来启动一个PipeCmd,所以到目前为止我都是用它去运行了一个批处理,然后在批处理中去做上述操作。该接口其实是用CreateProcess实现,因此新建的进程就继承了父进程的权限,也就是SYSTEM。
但,在那段黑客代码中,切换帐户其实是使用了CreateProcessWithLogonW来完成。估计各个工具都类似,因此应该可以跳过中间的多余步骤,用API切换帐户来直接运行sqlplus。
HANDLE hToken;想偷懒的人还是看看代码稍微理解一下吧,因为我也想偷一下懒,直接Copy/Paste可能会有问题的。
LogonUser("dbauser", NULL, "1qaz2wsx", LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, &hToken);
STARTUPINFO si;
si.cb = sizeof(STARTUPINFO);
GetStartupInfo(&si);
PROCESS_INFORMATION pi;
CreateProcessAsUser(hToken, NULL, cmdbuf, &sa, NULL, TRUE, NULL, NULL, NULL, &si, &pi);
另外说明一下,CreateProcessWithLogonW应该也是可以做到的,但是我一直没能试成功。倒是CreateProcessAsUser一次成功,于是就这样用下去了。
net localgroup Administrators dbauser /add但是在XP下面要这样做的话,就有可能会让Windows把dbauser当成了主管理员,特别是在某些装好之后默认用Administrator用户登录的系统上。这样会给用户带来不小的困扰哦,所以最佳的做法应该是判断一下操作系统的版本再去做相应的处理。