2010-02-03 6 views
7

Agregué la publicación WMI a un servicio de Windows basado en .NET Framework 3.5 que se ejecuta bajo la cuenta de 'servicio de red'.Problema de permisos al publicar en WMI en la cuenta de servicio de red

De acuerdo con document I came across on MSDN, la cuenta de 'servicio de red' debe tener permisos de publicación WMI por defecto. ("Por defecto, los siguientes usuarios y grupos están autorizados a publicar los datos y eventos: ... servicio de red, ...")

Sin embargo, cuando el servicio de llamadas de Instrumentation.Publish (myStatusClassInstance), arroja una excepción 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'. 

.so parece que System.Management.Instrumentation intenta generar código sobre la marcha, y cuando se ejecuta en servicio de la red que se dirige a un directorio en el servicio de red no tiene permisos.

¿Cuál es la mejor solución/solución para esto? ¿Puedo anular el directorio objetivo de code-gen en app.config o en el código? Yo no quiero tener que ver alrededor de permisos del sistema de archivos cuando se despliega el servicio ...

actualización: Creo que esto es una 'característica' donde más viejos enfrentamientos código FX con nuevos ajustes de seguridad en Win7. Internamente, las clases administradas de WMI recuperan el directorio de instalación de WMI del registro y lo utilizan como ruta de salida para el código generado. Desafortunadamente, a muchos usuarios no se les permite (o se supone que deben) escribir cosas en% SystemRoot% ... ... Archivé un error de conexión (#530392) para ver si MSFT puede aportar alguna claridad y/o proporcionar una solución o solución alternativa. .

Actualización 2: Supongo que para las cuentas de usuario normales esto no es un problema, porque la virtualización de UAC iniciará y almacenará los archivos en otro lugar. Sin embargo, aparentemente la cuenta de "servicio de red" no está cubierta por la virtualización de UAC ... (?)

Actualización 3: Se ha añadido 550 ppt de recompensa. Restricciones simples: el servicio de ventanas basado en .NET Framework 3.5, que se ejecuta como servicio de red, necesita poder publicar datos a través de WMI usando System.Management.Instrumentation en Win7 y Win2008 [RTM & R2] con configuraciones de seguridad/permisos predeterminados y sin recurrir a modificando los miembros internos/privados del marco mediante la reflexión. Soluciones "listas para usar" pero limpias bienvenidas. Se abrirá un segundo Bounty-Q relacionado como marcador de posición para otro 550pt si SO lo permite.

Bounty actualización: tengo la intención de duplicar la recompensa para este Q a través de una segunda pregunta mano a mano que va a servir como un marcador de posición de recompensas:
https://stackoverflow.com/questions/2208341/bounty-placeholder (< - Al parecer esto no se le permitió, por lo que la bounty placeholder question fue cerrada por SO etiqueta policía.)

Actualización 4: Esto se pone mejor y mejor. Me di cuenta de que installutil estaba escribiendo los archivos que faltaban en c: \ windows \ syswow64 ... etc ..., así que me di cuenta de que estaba usando la versión de 32 bits de installutil para instalar el servicio, pero el servicio se estaba ejecutando como un Proceso de 64 bits El efecto secundario obvio era que el código generado cuando installutil se ejecutaba terminaba bajo syswow64 (el directorio del sistema de 32 bits), mientras que el servicio lo buscaba en el directorio del sistema de 64 bits (system32). (< - fuera del tema, pero realmente me gusta cómo MSFT logró cambiar los nombres allí ... :)).

Así que intenté instalar el servicio con la versión de 64 bits de installutil. Eso falló miserablemente con errores de permiso en la ruta% sysroot% \ wbem \ framework ... etc ... Luego volví a compilar el servicio como x86 y lo registré nuevamente usando la versión de 32 bits de installutil. Eso dio lugar a una nueva excepción:

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 

... cada vez más cerca ...

+0

¿Seguro que el fracaso es por los derechos de acceso ? Sugiero las herramientas de SysInternals. – lsalamon

+0

Buen punto. Estaba haciendo esa suposición basada en el servicio de red y la mayoría de los demás usuarios ya no pueden escribir/crear en% systemroot% ... ... Comprobaré si puedo encontrar alguna evidencia de que esta excepción enmascare posiblemente otra ... – KristoferA

Respuesta

2

Creo que el problema no es con la publicación de datos, pero con registrarse ese tipo en WMI por primera vez .

Si examina el código System.Management.Instrumentation en reflector, o algún otro desensamblador, verá que si el ensamblaje que está a punto de publicarse no se ha registrado, entonces el código intentará registrar el ensamblaje y guardar el ensamblaje información en un subdirectorio especialmente nombrado en la carpeta de instalación WBEM.

Sospecho que si ejecuta código para publicar primero los datos de WMI como administrador, registraría el ensamblado y luego la cuenta de servicio de red tendría los permisos para hacer la publicación normal.

+0

Se informa como registrado (installutil lo dice de todos modos). Además, al llamar a Instrumentation.IsAssemblyRegistered devuelve true, al menos _thinks_ está registrado. La excepción se produce cuando llamo a Instrumentation.Publish. – KristoferA

+0

IsAssemblyRegistered devuelve verdadero, pero RegisterAssembly arroja la misma excepción que Publish. Así que sí, estás en algo allí ... :) – KristoferA

2

¿Ha inspeccionado su conjunto con el installutil? Eso debería darle un registro de los problemas de instalación. (Pero ya que no se puede ejecutar como la cuenta de servicio de red, podría no mostrar el problema que está teniendo.)

Además, ¿está seguro de este servicio debe se ejecutan en la cuenta de servicio de red?

Debido al riesgo de vulnerabilidad en la ejecución de servicios de Windows en cuentas con privilegios, Microsoft ha creado estas cuentas de servicios especiales con algunas limitaciones, que se han fortalecido en Vista y Win7. Desde Vista, Microsoft ha limitado el número de servicios que se ejecutan bajo esta cuenta a favor de los menos privilegiados (ver this article). La cuenta de servicio de red (también conocida como "NT AUTHORITY \ NETWORK SERVICE") puede acceder a la red (actuando como la cuenta de máquina local PCNAME $), pero tiene derechos reducidos en la máquina local (a diferencia de la cuenta del sistema local).

¿Ha comprobado los permisos de seguridad de WMI para la rama que está utilizando su conjunto? Ejecute wmimgmt.msc y cave en ... Cuando hice una comprobación rápida de algunas ramas aleatorias, pude ver que la cuenta de servicio de red no tenía derechos de escritura.

Por último, le sugiero que use Sysinternals' ProcMon, lo que le permitiría filtrar a ese proceso y ver si hay algún error de acceso denegado en la configuración de archivo o registro. Esta herramienta me ha solucionado muchos problemas a lo largo de los años.

+0

+1 por mencionar sysinternals. Buen material. –

+0

Gracias por la respuesta. Installutil solo informa el éxito. Procmon informa lo mismo que la excepción en la pregunta; CreateFile falla en la ruta no encontrada ... Examinaré los permisos wmi ... – KristoferA

+0

El servicio de red no tenía derechos de escritura completos en el espacio de nombres de wmi en el que iba a escribir, así que le di esos derechos. Sin embargo, desafortunadamente eso no solucionó el problema. – KristoferA

1
+1

Sí, soy yo quien archivó ese error de conexión. Incluí un enlace en la pregunta también ... – KristoferA

Cuestiones relacionadas