代码之家  ›  专栏  ›  技术社区  ›  KristoferA

在网络服务帐户下发布到wmi时出现权限问题

  •  7
  • KristoferA  · 技术社区  · 15 年前

    我正在将wmi发布添加到以“网络服务”帐户运行的基于.net framework 3.5的windows服务。

    根据A document I came across on MSDN ,默认情况下,“网络服务”帐户应具有wmi发布权限。(“ 默认情况下,允许下列用户和组发布数据和事件:… 网络服务 ,… “”

    但是,当服务调用instrumentation.publish(myStatusClassInstance)时,它抛出directoryNotFoundException;

    System.IO.DirectoryNotFoundException was unhandled
    Message: Could not find a part of the path 'C:\Windows\system32\WBEM\Framework\root\MyWMINamespace\MyService_SN__Version_1.0.3686.26280.cs'.
    

    …所以看起来system.management.instrumentation试图动态生成代码,当在network service下运行时,它以network service没有权限的目录为目标。

    最好的解决方法是什么?我可以覆盖app.config或code中的code gen target dir吗?我不想在部署服务时随意使用文件系统权限…

    更新 :我认为这是一个“功能”,旧的fx代码与win7中较新的安全设置冲突。在内部,wmi托管类从注册表检索wmi安装目录,并将其用作生成代码的输出路径。不幸的是,很多用户不允许(或应该)在%SystemRoot%下写东西……我提交了一个连接错误( #530392 )看看msft是否能带来任何清晰度和/或提供修复或解决方案。

    更新2: 我猜对于普通用户来说,这不是问题,因为uac虚拟化将启动并将文件存储在其他地方。但是,显然“网络服务”帐户不包括在uac虚拟化中。

    更新3: 增加550pt赏金。简单约束:.NET Framework 3.5为基础的Windows服务,作为网络服务运行,需要能够使用System.Management.Instrumentation在具有默认权限/安全设置的Win7和Win2008[RTM&R2]上通过WMI发布数据,而无需修改framework int使用反射的内部/私有成员。开箱即用,但干净的解决方案欢迎。如果允许,将打开第二个相关的赏金-Q作为另一个550pt的占位符。

    赏金更新: 我打算通过一个二手的问题将这个q的赏金加倍,这个问题将作为赏金占位符:
    https://stackoverflow.com/questions/2208341/bounty-placeholder (<——显然这是不允许的,所以赏金占位符问题被礼仪警察关闭了。)

    更新4: 越来越好了。我注意到installutil正在将丢失的文件写入c:\windows\syswow64…等,因此我意识到我正在使用32位版本的installutil来安装该服务,但该服务是作为64位进程运行的。明显的副作用是,installutil运行时生成的代码最终位于syswow64(32位系统目录)下,而服务则在64位系统目录(system32)下查找。(<--off topic,但我真的很喜欢msft如何在那里成功地切换名称…:)

    所以我尝试用64位版本的installutil安装服务。由于%sysroot%\wbem\framework…等中的权限错误而失败。路径。接下来,我将服务重新编译为x86,并使用32位版本的installutil再次注册它。这导致了一个全新的例外:

    System.Exception: The code generated for the instrumented assembly failed to compile.
       at System.Management.Instrumentation.InstrumentedAssembly..ctor(Assembly assembly, SchemaNaming naming)
       at System.Management.Instrumentation.Instrumentation.Initialize(Assembly assembly)
       at System.Management.Instrumentation.Instrumentation.GetInstrumentedAssembly(Assembly assembly)
       at System.Management.Instrumentation.Instrumentation.GetPublishFunction(Type type)
       at System.Management.Instrumentation.Instrumentation.Publish(Object instanceData)
       at SomeService.InstanceClass.PublishApp(String name) in e:\work\clientname\SomeService\SomeService\WMIProvider.cs:line 44
       at SomeService.SomeServiceService..ctor() in e:\work\clientname\SomeService\SomeService\SomeServiceService.cs:line 26
       at SomeService.Program.Main() in e:\work\clientname\SomeService\SomeService\Program.cs:line 17
    

    …越来越近…

    3 回复  |  直到 13 年前
        1
  •  2
  •   John Weldon user3678248    15 年前

    我认为问题不在于发布数据,而在于 注册 这是第一次在wmi中键入。

    如果你检查 System.Management.Instrumentation 代码在 reflector ,或者其他反汇编程序,您将看到即将发布的程序集尚未注册,然后代码将尝试注册程序集并将程序集信息保存在WBEM安装文件夹下的一个特别命名的子目录中。

    我怀疑,如果您先以管理员身份运行代码以发布wmi数据,它将注册程序集,然后网络服务帐户将具有执行正常发布的权限。

        2
  •  2
  •   ewall    15 年前

    你检查过你的集会 installutil ?这将为您提供安装问题的日志。(但由于您无法将其作为网络服务帐户运行,因此它可能不会显示您遇到的问题。)

    另外,你确定这项服务 必须 在网络服务帐户下运行?

    由于在特权帐户中运行Windows服务时存在漏洞风险,Microsoft对这些特殊服务帐户进行了一些限制,这些限制在Vista和Win7中得到了加强。自vista以来,微软已经限制了在这个帐户下运行的服务的数量,以支持特权较低的服务(参见 this article )网络服务帐户(也称为“NT authority\network service”)可以访问网络(充当本地计算机帐户pcname$),但它减少了对本地计算机的权限(与本地系统帐户不同)。

    是否检查了程序集正在使用的分支的wmi安全权限?跑 wmimgmt.msc 挖进去…当我快速检查一些随机分支时,我可以看到网络服务帐户没有写权限。

    最后,我建议使用 Sysinternals' ProcMon ,这将允许您仅筛选该进程,并查看文件或注册表设置中是否存在任何拒绝访问的错误。多年来,这个工具为我解决了许多问题。