2010-02-03 6 views
7

Aggiungo la pubblicazione WMI a un servizio Windows basato su .net framework 3.5 in esecuzione con l'account 'servizio di rete'.Problema di autorizzazioni durante la pubblicazione su WMI nell'account di servizio di rete

In base a un document I came across on MSDN, l'account 'servizio di rete' deve avere per impostazione predefinita le autorizzazioni di pubblicazione WMI. ("Per impostazione predefinita, i seguenti utenti e gruppi sono autorizzati a pubblicare i dati e gli eventi: ... servizio di rete, ...")

Tuttavia, quando il servizio chiama Instrumentation.Publish (myStatusClassInstance), getta una 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'. 

..quindi sembra System.Management.Instrumentation tenta di generare il codice al volo, e durante l'esecuzione in servizio di rete si rivolge a un servizio di directory in cui rete non ha i permessi.

Qual è la soluzione/soluzione migliore per questo? Posso sovrascrivere la directory di destinazione del codice gen in app.config o nel codice? Io non voglio avere a smanettare con i permessi del file system quando si distribuisce il servizio ...

Aggiornamento: Penso che questo sia un 'caratteristica' dove gli scontri codice FX più anziani con le impostazioni di protezione più recenti in Win7. Internamente, le classi gestite WMI recuperano la directory di installazione WMI dal registro e la utilizzano come percorso di output per il codice generato. Sfortunatamente molti utenti non sono autorizzati a (o supposti) scrivere roba sotto% SystemRoot% ... ... Ho registrato un bug di connessione (#530392) per vedere se MSFT può portare chiarezza e/o fornire una soluzione o soluzione alternativa .

Aggiornamento 2: Suppongo che per gli account utente normali questo non sia un problema, perché la virtualizzazione del controllo dell'account utente eseguirà il kick in e memorizzerà i file altrove. Tuttavia, apparentemente l'account "servizio di rete" non è coperto dalla virtualizzazione del controllo dell'account utente. (?)

Aggiornamento 3: Aggiunto 550pt di taglie. Semplici vincoli: il servizio Windows basato su .net framework 3.5, in esecuzione come servizio di rete, deve essere in grado di pubblicare dati tramite WMI utilizzando System.Management.Instrumentation su Win7 e Win2008 [RTM & R2] con autorizzazioni/impostazioni di sicurezza predefinite e senza ricorrere a modificare i membri interni/privati ​​del framework usando la riflessione. 'Out-of-the-box' ma le soluzioni pulite sono benvenute. Aprirà una seconda taglia relativa-Q come segnaposto per un altro 550pt se SO consente.

Bounty aggiornamento: ho intenzione di raddoppiare la taglia per questo Q attraverso una seconda domanda mano nella mano che servirà come segnaposto di taglie:
https://stackoverflow.com/questions/2208341/bounty-placeholder (< - A quanto pare questo non era permesso, in modo che il questione di taglie segnaposto ottenuto chiuso dalla polizia SO galateo)

Update 4:. Questo diventa sempre meglio. Ho notato che installutil stava scrivendo i file mancanti in c: \ windows \ syswow64 ... ecc ..., quindi mi sono reso conto che stavo usando la versione a 32 bit di installutil per installare il servizio, ma il servizio era in esecuzione come Processo a 64 bit. L'ovvio effetto collaterale era che il codice generato quando installutil era in esecuzione finiva sotto syswow64 (la directory di sistema a 32 bit), mentre il servizio lo cercava nella directory di sistema a 64 bit (system32). (< - fuori tema, ma mi piace molto come MSFT sia riuscito a cambiare i nomi lì ... :)).

Così ho provato a installare il servizio con la versione 64-bit di installutil. Questo ha fallito miseramente con errori di autorizzazione nel percorso% sysroot% \ wbem \ framework ... etc .... Successivamente ho ricompilato il servizio come x86 e l'ho registrato di nuovo usando la versione di installutil a 32 bit. Quello ha provocato in modo del tutto nuova eccezione:

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 

... sempre più vicino ...

+0

Sei sicuro che il fallimento è da diritti di accesso ? Suggerisco gli strumenti di SysInternals. – lsalamon

+0

Buon punto. Stavo facendo quella supposizione basata sul servizio di rete e alla maggior parte degli altri utenti non è più permesso scrivere/creare sotto% systemroot% ... ... Verificherò se riesco a trovare qualche prova di questa eccezione possibilmente mascherandone un'altra ... – KristoferA

risposta

2

Credo che il problema non è con la pubblicazione dei dati, ma con registrazione quel tipo in WMI per la prima volta .

Se si esamina il codice System.Management.Instrumentation in reflector o qualche altro disassemblatore, si noterà che non è stato registrato l'assembly che sta per pubblicare, quindi il codice tenterà di registrare l'assembly e salvare l'assembly informazioni in una sottodirectory appositamente denominata nella cartella di installazione di WBEM.

Sospetto che se si esegue il codice per pubblicare prima i dati WMI come amministratore, esso registrerebbe l'assembly e quindi l'account Servizio di rete disporrebbe delle autorizzazioni per eseguire la pubblicazione normale.

+0

Si registra come registrato (installutil lo dice comunque). Inoltre, la chiamata a Instrumentation.IsAssemblyRegistered restituisce true, quindi almeno _thinks_ è registrato. L'eccezione viene sollevata quando chiamo Instrumentation.Publish. – KristoferA

+0

IsAssemblyRegistered restituisce true, ma RegisterAssembly genera la stessa eccezione di Pubblica. Quindi sì, stai facendo qualcosa lì ... :) – KristoferA

2

Avete ispezionato il vostro gruppo con lo installutil? Questo dovrebbe darti un registro dei problemi di installazione. (Ma dal momento che non puoi eseguirlo come account Servizio di rete, potrebbe non mostrare il problema che stai riscontrando.)

Inoltre, sei sicuro che questo servizio deve essere eseguito con l'account Servizio di rete?

A causa del rischio di vulnerabilità nell'esecuzione di servizi Windows in account con privilegi, Microsoft ha reso questi account di servizio speciali con alcune limitazioni, che sono state rafforzate in Vista e Win7. Dal momento che Vista, Microsoft ha limitato il numero di servizi in esecuzione con questo account a favore di quelli meno privilegiati (vedere this article). L'account del servizio di rete (ovvero "NT AUTHORITY \ NETWORK SERVICE") può accedere alla rete (in qualità di account computer locale PCNAME $), ma ha diritti ridotti sul computer locale (a differenza dell'account di sistema locale).

Avete controllato le autorizzazioni di sicurezza WMI per il ramo che il vostro assembly sta usando? Esegui wmimgmt.msc e scavare ... Quando ho fatto un rapido controllo di alcuni rami casuali, ho potuto vedere che l'account del servizio di rete non aveva diritti di scrittura.

Infine, suggerirei di utilizzare Sysinternals' ProcMon, che consentirebbe di filtrare solo per quel processo e vedere se ci sono errori di accesso negato nelle impostazioni del file o del registro. Questo strumento ha risolto molti problemi per me nel corso degli anni.

+0

+1 per aver menzionato sysinternals. Roba buona. –

+0

Grazie per la risposta. Installutil riporta solo il successo. Procmon riporta lo stesso dell'eccezione nella domanda; CreateFile non riesce sul percorso non trovato ... Guarderò i permessi wmi ... – KristoferA

+0

Il servizio di rete non aveva pieni diritti di scrittura nello spazio dei nomi wmi a cui stavo per scrivere, quindi gli ho dato quei diritti. Tuttavia, sfortunatamente non ha risolto il problema. – KristoferA

1
+1

Sì, sono io quello che ha archiviato quel bug di connessione. Ho incluso un link ad esso anche nella domanda ... – KristoferA