IIS6 启动的应用程序(作为 HTTP 请求的结果)未能初始化 dll。如果我在本地通过双击登录时以管理员身份启动它,一切都很好。
此应用通过名为 cryptlib 的第三方 DLL 使用 TLS 加密。 http://www.coastrd.com/smtps/cryptlib 这本身应该没什么大不了的,因为我的大多数 CGI 应用程序都使用 MySQL/zlib/... 等 dll 没有问题。在这种情况下(可能是由于创建 SSL/TLS 会话的性质),如果以管理员身份双击启动,应用程序运行良好,但由于传入请求而由 IIS 启动时不会运行。IIS 使用帐户“Internet Guest Account... (...IUSR)”(我们假设)从一个简单的网页 HTTP POST 请求执行 CGI 应用程序。
我尝试完全控制应用程序、dll 和文件夹上的 IUSR 帐户,但没有任何乐趣。接下来我打开 ProcMon 并寻找“拒绝访问”的结果。我唯一能找到的是由于 CreateFile Desired Access: Read Attributes, Delete, Synchronize, Disposition: Open, Options: Synchronous IO Non-Alert, C:\WINDOWS\Debug\UserMode\ChkAcc.log
这令人费解,因为我的应用程序没有写入该日志文件(我假设 IIS 是这样,为什么会出现问题?)
接下来,我将成功启动管理员的 ProcMon 输出与 IUSR 启动进行比较,发现失败的启动中不存在“ReadFile”操作。我没有收到 ACCESS DENIED 错误,操作只是没有发生。
cl32.dll 的顺序操作顺序应该是: QueryOpen CreateFile CreateFileMapping QueryStandardInformationFile CreateFileMapping CreateFileMapping CloseFile Load Image ReadFile
我假设这是将 DLL 加载到内存中以供使用的地方。
而不是 ReadFile 操作(在失败的启动中)有:RegOpenKey HKU\S-1-5-21-4122272316-1273673783-4216733774-1003 NAME NOT FOUND
它有点像这里描述的“绕过遍历检查”问题 http://forums.iis.net/t/1153139.aspx http://technet.microsoft.com/en-us/library/cc739389(WS.10 ).aspx 但这并没有解决问题。
在这一点上,我们已经大大超出了我对用户帐户和权限的了解。有一点很清楚,这是一个权限问题。问题是,哪个权限?
添加
将 ISUR 添加到管理员: 1. 右键单击桌面上的我的电脑,然后单击管理。2. 当计算机管理窗口打开时,展开本地用户和组 3. 选择组并双击右窗格中的管理员。4. 单击添加按钮 5. 单击高级,然后单击立即查找并选择 IUSR 6. 单击确定。7.重启IIS
这并没有解决问题。我挖出了 Filemon v7.3,它是 IUSR
er.exe:2240 OPEN C:\WINDOWS\system32\USERENV.dll SUCCESS Options: Open Access: 00100021
er.exe:2240 CLOSE C:\WINDOWS\system32\USERENV.dll SUCCESS
er.exe:2240 OPEN C:\WINDOWS\debug\UserMode\ChkAcc.log ACCESS DENIED MY-SERVER\IUSR_MY-SERVER
er.exe:2240 CREATE C:\WINDOWS\debug\UserMode\ChkAcc.log ACCESS DENIED MY-SERVER\IUSR_MY-SERVER
在这一点上,我会在黑暗中采取任何行动,这可能是什么许可:)
添加
我更改了文件 ChkAcc.log 和文件夹 UserMode 的权限,我还检查了高级权限,发现应用程序和 Dll 被拒绝。我把它们都删了。我重新启动了 IIS,甚至重新启动了机器。仍然没有运气。
我想知道 ACCESS DENIED 是否真的是问题所在。我重写了该应用程序以创建并写入该文件夹中的文件,并且它起作用了:
OPEN C:\WINDOWS\debug\UserMode\ChkAcc.txt SUCCESS Options: OpenIf Access: 00120196
SET INFORMATION C:\WINDOWS\debug\UserMode\ChkAcc.txt SUCCESS Length: 0
SET INFORMATION C:\WINDOWS\debug\UserMode\ChkAcc.txt SUCCESS Length: 0
WRITE C:\WINDOWS\debug\UserMode\ChkAcc.txt SUCCESS Offset: 0 Length: 41
WRITE C:\WINDOWS\debug\UserMode\ChkAcc.txt SUCCESS Offset: 41 Length: 2
SET INFORMATION C:\WINDOWS\debug\UserMode\ChkAcc.txt SUCCESS Length: 43
SET INFORMATION C:\WINDOWS\debug\UserMode\ChkAcc.txt SUCCESS Length: 43
CLOSE C:\WINDOWS\debug\UserMode\ChkAcc.txt SUCCESS
这让我怀疑文件夹权限根本不是问题,但 DLL 由于某种原因未能初始化。
有什么方法可以给 IUSR 与 ADMIN 相同的权限吗?那么也许我可以将它们一一删除。也许我什至可以创建第二个具有 ADMIN 权限的用户并让 IIS 使用它而不是 IUSR 来处理传入的 CGI 请求?
显然,将 IUSR 添加到 ADMIN 组与以 ADMIN 身份运行应用程序不同。
添加
实际上问题是由于 dll 在启动时执行了各种健全性检查测试,包括读取文件的能力。为此,它会尝试读取用户的主目录(或在 Windows 术语中为用户的配置文件目录)
在 Windows 2003 Server 机器上的测试中,我发现
IUSR
CSIDL_APPDATA = C:\WINDOWS\system32\config\systemprofile\应用程序数据
行政人员
CSIDL_APPDATA = C:\Documents and Settings\Administrator.MY-SERVER\Application Data
我怀疑 cgi 进程被拒绝访问任何 system32 文件夹。在将IUSR添加到管理员之前,这是我所期望的行为,然后我希望这可以工作....但事实并非如此。解决办法是重新编写dll,但我仍然对此感到困惑
请注意您拥有的两行:
第一行可能是应用程序检查它是否存在,而第二行是“如果文件不存在则创建文件”的情况。我要寻找的是IUSR帐户不是“USERS”组的一部分,而是“GUESTS”的一部分,并且通常来宾的权限甚至低于“USERS”。您可能希望确保 IUSR 帐户能够遍历其上方的文件夹。尝试让 IUSR 帐户显式访问文件夹以遍历文件夹,并将“UserMode”文件夹的权限授予“创建文件”(但“仅限此文件夹”)。
最后,可能对来宾有明确的“拒绝”权限,这可能会阻止您访问文件夹。这些是我要检查的东西。