2008-10-15 11 views
2

Nous avons une application qui installe SQL Server Express à partir de la ligne de commande et spécifie le compte de service en tant que compte LocalSystem via le paramètre SQLACCOUNT = "NT AUTHORITY \ SYSTEM".Déterminer le nom du compte LocalSystem en utilisant C#

Cela ne fonctionne pas avec différentes langues car le nom de compte pour LocalSystem est différent. Il y a un tableau répertoriant les différences ici:

http://forums.microsoft.com/MSR/ShowPost.aspx?PostID=685354&SiteID=37

Cela ne semble pas être complète (la version suédoise ne figure pas). Donc j'aimerais pouvoir déterminer le nom par programme, peut-être en utilisant le SID?

J'ai trouvé un script VB pour ce faire:

Set objWMI = GetObject("winmgmts:root\cimv2") 

Set objSid = objWMI.Get("Win32_SID.SID='S-1-5-18'") 

MsgBox objSid.ReferencedDomainName & "\" & objSid.AccountName 

Est-ce que quelqu'un sait le code équivalent qui peut être utilisé en C#?

Répondre

7

Vous pouvez utiliser la classe de .NET intégré System.Security.Principal.SecurityIdentifier à cet effet: en le traduisant en une instance de NtAccount vous pouvez obtenir le nom du compte:

using System.Security.Principal; 


SecurityIdentifier sid = new SecurityIdentifier("S-1-5-18"); 
NTAccount acct = (NTAccount)sid.Translate(typeof(NTAccount)); 
Console.WriteLine(acct.Value); 

modifier plus tard, en réponse à la question dans les commentaires: vous ne avez pas besoin de privilèges spéciaux pour faire des recherches SID-à-nom sur la machine locale - pour Par exemple, même si le compte d'utilisateur que vous utilisez est uniquement dans le groupe Invités, ce code devrait fonctionner. Les choses sont un peu différentes si le SID résout à un compte de domaine, mais même cela devrait fonctionner correctement dans la plupart des cas, tant que vous êtes connecté au domaine (et un contrôleur de domaine est disponible au moment de la recherche) .

+0

Merci mdb. Y aurait-il des problèmes lors de l'exécution de ce code sous un compte de privilèges limité? – Carl

+0

Merci encore mdb. Juste testé le code dans un exemple d'application fonctionnant sous un compte de privilèges réduits et divers langages OS. Fonctionne un régal! – Carl

+1

L'utilisation de [le constructeur SecurityIdentifier qui prend une valeur WellKnownSidType comme paramètre] (https://msdn.microsoft.com/en-us/library/214122bs.aspx) est une meilleure option que de passer une chaîne SDDL mystérieuse. Vinicius Ottoni a fourni cette solution ci-dessous. – Daniel

1

Cela devrait faire quelque chose de similaire à ce que vous avez posté. Je ne sais pas comment obtenir des propriétés spécifiques des objets WMI désinvolture, mais cela vous aider à démarrer avec la syntaxe:

ManagementObject m = new ManagementObject("winmgmts:root\cimv2"); 
m.Get(); 
MessageBox.Show(m["Win32_SID.SID='S-1-5-18'"].ToString()); 
+0

Merci aussi à vous Danny. J'apprécie toujours une réponse. – Carl

1

Le problème avec la réponse acceptée est que le nom du compte doit pouvoir être résolu par l'ordinateur local exécutant le code.

Si vous lisez les listes de contrôle d'accès sur une machine distante, il se peut que vous ne puissiez pas résoudre les identificateurs de domaine/identificateurs locaux sur la boîte distante. Ce qui suit utilise WMI et prend le paramètre de la machine distante et le SID que vous voulez que la machine distante résolve.

/// <summary> 
/// Returns the Account name for the specified SID 
// using WMI against the specified remote machine 
/// </summary> 
private string RemoteSID2AccountName(String MachineName, String SIDString) 
{ 
    ManagementScope oScope = new ManagementScope(@"\\" + MachineName +  
     @"\root\cimv2"); 
    ManagementPath oPath = new ManagementPath("Win32_SID.SID='" + SIDString + "'"); 
    ManagementObject oObject = new ManagementObject(oScope, oPath, null); 
    return oObject["AccountName"].ToString(); 
} 
3

Ou vous pouvez utiliser:

string localSystem = new SecurityIdentifier(WellKnownSidType.LocalSystemSid, null).Translate(typeof(NTAccount)).Value; 

Avec WellKnownSidType vous pouvez chercher d'autres comptes, comme NetworkService par exemple.