首页 > 解决方案 > 枚举远程服务

问题描述

ServiceController.GetServices()from System.ServiceProcessnamespace 可用于枚举本地机器或远程机器上的服务器,方法是将其 netbios 名称作为参数传递。

在幕后,这是通过 Windows NT RPC 完成的——这当然意味着它是使用用户凭据进行身份验证的。

在 Active Directory(以前的 Windows NT 域)环境中,这意味着在目标 PC 上检查 AD 用户的权限,以查看他是否已被分配访问服务列表所需的权限 - 例如 - 域管理员通常会.

在软件没有在AD域管理员账户下运行的环境中,或者只是在没有使用AD账户控制访问但远程设置了一些非AD账户的环境中,我们需要确保正确的远程正在使用帐户。

在原生世界中,我们将调用LogonUser传递一个克隆当前访问令牌的标志 - 确保所有本地访问保持不变,但将远程凭据更改为提供的凭据(不进行任何检查),然后调用'ImpersonateUser以使该新令牌成为当前令牌,并且然后执行操作而不是调用 RPC。

.Net 通过 System.Security.Principal 命名空间中的 WindowsIdentity.Impersonate() 提供此功能。我们所需要的只是一个代表当前用户但具有更改/提供的远程凭据的 WindowsIdentity...

这里的小路很冷。WindowsIdentity 对象似乎总是由某些框架提供,和/或该Impersonate方法的静态变体采用 IntPtr 参数,该参数是从 返回的本机句柄LogonUser,但我们已经走到了这一步,没有求助于 PInvoke,当然我们可以关闭循环而不离开托管代码?

不。在 .net 功能覆盖范围内似乎存在一个奇怪的差距:一堆看似得到良好支持和记录的对象,如果没有 PInvoke(或使用 3rd 方库来隐藏 PInvoke)根本无法使用。

我甚至看到有关这些功能的 MSDN 文章都公然包含对 advapi:LogonUser 本机 API 的调用,但我的想法是反抗。当然,肯定有某种方法可以在不留下托管代码的情况下使用远程凭据构建 WindowsIdentity?

标签: .net

解决方案


推荐阅读