“未知错误(0x80005000)”尝试使用 DirectoryEntry 和模拟读取远程 IIS 6 配置数据库 (C#)

发布于 2024-10-31 14:17:20 字数 2927 浏览 2 评论 0原文

(编辑)情节变得更加复杂:相同的代码(无需模拟!)可以从 Windows 7 客户端成功运行,但不能从 Windows 2008 R2 客户端运行!这是有问题的代码。 (原始消息遵循下面的代码。)

var entry = new DirectoryEntry("IIS://" + tbHost.Text + "/W3SVC", tbUsername.Text, tbPassword.Password);
foreach (DirectoryEntry site in entry.Children)
{
    Console.Write("Site {0}\n", site.Name);
    foreach (PropertyValueCollection prop in site.Properties)
        Console.Write("{0}={1}\n", prop.PropertyName, prop.Value);
}

我在此处读到,对于 IIS 提供程序,创建 DirectoryEntry< 时无法传递凭据/code>对象。您必须进行模拟。因此,我尝试了以下代码,但当我尝试读取属性时,我仍然收到带有“未知错误(0x80005000)”文本的 COMException,就像我之前尝试传递 的用户名和密码时所做的那样DirectoryEntry 构造函数。以下是概要:

  • LogonUser() 成功,凭据正常。在我发现必须使用 LOGON32_LOGON_NEW_CREDENTIALS 而不是 LOGON32_LOGON_INTERACTIVE 之前,我有点头疼。
  • 远程计算机不在同一域中。实际上,它根本不在域中。事实上,我将其名称放入客户端的 hosts 文件中,这样我就可以通过名称访问它。
  • 在目标计算机中运行 Metabase Explorer 会显示我想要读取的密钥确实存在。 (参见帖子末尾的图片。

const int LOGON32_LOGON_INTERACTIVE = 2;
const int LOGON32_LOGON_NETWORK = 3;
const int LOGON32_LOGON_NEW_CREDENTIALS = 9;

const int LOGON32_PROVIDER_DEFAULT = 0;
const int LOGON32_PROVIDER_WINNT50 = 3;
const int LOGON32_PROVIDER_WINNT40 = 2;
const int LOGON32_PROVIDER_WINNT35 = 1;

[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern int LogonUser(String lpszUserName, string lpszDomain, string lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken);

[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public extern static bool CloseHandle(IntPtr handle);

[DllImport("kernel32.dll")]
extern static int GetLastError();

(...)

IntPtr myToken = IntPtr.Zero;
if (LogonUser(tbUsername.Text, tbHost.Text, tbPassword.Password, LOGON32_LOGON_NEW_CREDENTIALS, LOGON32_PROVIDER_DEFAULT, ref myToken) == 0)
{
    int causingError = GetLastError();
    throw new System.ComponentModel.Win32Exception(causingError);
}

WindowsImpersonationContext myMission = WindowsIdentity.Impersonate(myToken);

string mbUri = "IIS://" + tbHost.Text + "/MimeMap";
DirectoryEntry myDirEntry = new DirectoryEntry(mbUri);
Console.Write("{0}\n", myDirEntry.Properties["KeyType"]);

myDirEntry.Close();
myMission.Undo();
if (myToken != IntPtr.Zero)
    CloseHandle(myToken);

在此处输入图像描述

(EDIT) The plot thickens: The same code (with no need for impersonation!) runs successfully from a Windows 7 client, but NOT from a Windows 2008 R2 client! Here's the code in question. (Original message follows code below.)

var entry = new DirectoryEntry("IIS://" + tbHost.Text + "/W3SVC", tbUsername.Text, tbPassword.Password);
foreach (DirectoryEntry site in entry.Children)
{
    Console.Write("Site {0}\n", site.Name);
    foreach (PropertyValueCollection prop in site.Properties)
        Console.Write("{0}={1}\n", prop.PropertyName, prop.Value);
}

I read here that, for the IIS provider, you can't pass credentials when creating the DirectoryEntry object. You have to do impersonation. So I tried the following code, but I still get a COMException with a text of "Unknown error (0x80005000)" when I try to read a property, just as I did when I previously tried to pass username and password for the DirectoryEntry constructor. Here's the rundown:

  • LogonUser() succeeds, credentials are OK. I had banged by head a little before I found out I had to use LOGON32_LOGON_NEW_CREDENTIALS instead of LOGON32_LOGON_INTERACTIVE.
  • The remote machine is not in the same domain. Actually, it isn't in a domain at all. In fact, I put its name in the client's hosts file so I could get to it by name.
  • Running Metabase Explorer in the target machine shows me the key I want to read does exist. (See picture at end of the post.)

.

const int LOGON32_LOGON_INTERACTIVE = 2;
const int LOGON32_LOGON_NETWORK = 3;
const int LOGON32_LOGON_NEW_CREDENTIALS = 9;

const int LOGON32_PROVIDER_DEFAULT = 0;
const int LOGON32_PROVIDER_WINNT50 = 3;
const int LOGON32_PROVIDER_WINNT40 = 2;
const int LOGON32_PROVIDER_WINNT35 = 1;

[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern int LogonUser(String lpszUserName, string lpszDomain, string lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken);

[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public extern static bool CloseHandle(IntPtr handle);

[DllImport("kernel32.dll")]
extern static int GetLastError();

(...)

IntPtr myToken = IntPtr.Zero;
if (LogonUser(tbUsername.Text, tbHost.Text, tbPassword.Password, LOGON32_LOGON_NEW_CREDENTIALS, LOGON32_PROVIDER_DEFAULT, ref myToken) == 0)
{
    int causingError = GetLastError();
    throw new System.ComponentModel.Win32Exception(causingError);
}

WindowsImpersonationContext myMission = WindowsIdentity.Impersonate(myToken);

string mbUri = "IIS://" + tbHost.Text + "/MimeMap";
DirectoryEntry myDirEntry = new DirectoryEntry(mbUri);
Console.Write("{0}\n", myDirEntry.Properties["KeyType"]);

myDirEntry.Close();
myMission.Undo();
if (myToken != IntPtr.Zero)
    CloseHandle(myToken);

enter image description here

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

无声无音无过去 2024-11-07 14:17:20

知道了。我所要做的就是转到服务器管理 → 角色 → Web 服务器 (IIS) 并启用服务管理工具 → IIS 6 管理兼容性 → IIS 6 元数据库兼容性。见下图。

它位于客户端计算机中,因此您实际上不必安装 IIS 中的任何其他内容。

我想知道这对于非服务器 Windows(XP、Vista、7)如何工作。

在此处输入图像描述

Got it. All I had to do was go to Server Management → Roles → Web Server (IIS) and enable the service Management Tools → IIS 6 Management Compatibility → IIS 6 Metabase Compatibility. See pic below.

It's in the client machine, so you don't really have to have anything else from IIS installed.

I wonder how that will work for a non-server Windows (XP, Vista, 7).

enter image description here

帅气称霸 2024-11-07 14:17:20

您还可以以管理员身份打开 Powershell 并使用以下命令启用 IIS 6 管理兼容性:

Import-Module Servermanager
Add-WindowsFeature Web-Mgmt-Compat -IncludeAllSubFeature
Get-WindowsFeature #Show list of all installed features

You can also open Powershell as an administrator and use the following to enable IIS 6 Management Compatibility:

Import-Module Servermanager
Add-WindowsFeature Web-Mgmt-Compat -IncludeAllSubFeature
Get-WindowsFeature #Show list of all installed features
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文