c# sid

¿Cómo puedo convertir desde un SID a un nombre de cuenta en C#



(10)

Este es un stumper. Estás en un entorno de Active Directory ¿verdad? Solo revisando:)

De todos modos, en lugar de vincular con sid.Value,

string str = "LDAP://<SID=" + sid.Value + ">";

Intentaría convertir la matriz de bytes del SID en una cadena de octetos y enlazar con eso en su lugar.

Hay un ejemplo dulce aquí en la página 78. Esto te acercará más. Para ser sincero, no he intentado enlazar con un SID antes. Pero he tenido éxito vinculante con el GUID de un usuario, aunque :)

Buena suerte y dejame saber como va.

Tengo una aplicación C # que escanea un directorio y recopila cierta información. Me gustaría mostrar el nombre de la cuenta para cada archivo. Puedo hacer esto en el sistema local obteniendo el SID para el objeto FileInfo, y luego hacer:

string GetNameFromSID( SecurityIdentifier sid ) { NTAccount ntAccount = (NTAccount)sid.Translate( typeof( NTAccount ) ); return ntAccount.ToString(); }

Sin embargo, esto no funciona para archivos en una red, presumiblemente porque la función Translate () solo funciona con cuentas de usuario locales. Pensé que tal vez podría hacer una búsqueda LDAP en el SID, así que probé lo siguiente:

string GetNameFromSID( SecurityIdentifier sid ) { string str = "LDAP://<SID=" + sid.Value + ">"; DirectoryEntry dirEntry = new DirectoryEntry( str ); return dirEntry.Name; }

Parece que funcionará, ya que el acceso a "dirEntry.Name" se bloquea durante unos segundos, como si se está apagando y consultando la red, pero luego arroja un System.Runtime.InteropServices.COMException

¿Alguien sabe cómo puedo obtener el nombre de cuenta de un archivo arbitrario o SID? No sé mucho sobre redes o LDAP ni nada. Hay una clase llamada DirectorySearcher que quizás se supone que debo usar, pero quiere un nombre de dominio, y tampoco sé cómo obtenerlo, todo lo que tengo es la ruta al directorio que estoy escaneando.

Gracias por adelantado.


El método de conversión del objeto SecurityReference funciona en SID no locales, pero solo para cuentas de dominio. Para las cuentas locales a otra máquina o en una configuración que no sea de dominio, deberá invocar la función LookupAccountSid especificando el nombre específico de la máquina en la que se debe realizar la búsqueda.


Ooh, entonces es posible que la llamada LDAP no funcione porque es posible que no esté en un entorno de Active Directory. Si este es el caso, entonces cada una de sus máquinas es responsable de su propia tienda de identidades. Y su primer ejemplo de código no funciona en la red porque la máquina en la que está ejecutando su código no sabe cómo resolver el SID que solo tiene sentido en la máquina remota.

Realmente debería verificar si sus máquinas son parte de un Directorio Activo. Usted sabría esto durante el proceso de inicio de sesión. O puede verificar haciendo clic con el botón derecho en "Mi PC", seleccionar "Propiedades", la pestaña "Nombre del ordenador", y luego ver si su computadora es parte de un dominio.


Estupendo. Comprimí un código de LookupAccountSid () desde aquí:

http://www.pinvoke.net/default.aspx/advapi32.LookupAccountSid

Y eso funcionó, aunque tuve que proporcionar el nombre de host. En el caso de una ruta UNC, simplemente puedo tomar el primer componente de la misma. Cuando se trata de una unidad mapeada, utilizo este código para convertir la ruta a una de UNC:

http://www.wiredprairie.us/blog/index.php/archives/22

Parece que funciona, así es como lo haré, a menos que a alguien se le ocurra una situación en la que el primer componente de una ruta UNC no sea el nombre de host ...

Gracias por toda tu ayuda.


Obtener el dominio actual:

System.DirectoryServices.ActiveDirectory.Domain.GetCurrentDomain();

Obtenga una entrada de directorio de ldap y del nombre de dominio:

DirectoryEntry de = new DirectoryEntry(string.Format("LDAP://{0}", domain));

Obtenga el sid de un ActiveDirectoryMembershipProvider ActiveDirectoryMembershipUser:

ActiveDirectoryMembershipUser user = (ActiveDirectoryMembershipUser)Membership.GetUser(); var sid = (SecurityIdentifier)user.ProviderUserKey;

Obtenga el nombre de usuario de SecurityIdentifier:

(NTAccount)sid.Translate(typeof(NTAccount));

Obtener la búsqueda de directorio realizada en un directorio activo con la entrada del directorio de dominio y el nombre de usuario:

DirectorySearcher search = new DirectorySearcher(entry); search.Filter = string.Format("(SAMAccountName={0})", username); search.PropertiesToLoad.Add("Name"); search.PropertiesToLoad.Add("displayName"); search.PropertiesToLoad.Add("company"); search.PropertiesToLoad.Add("homePhone"); search.PropertiesToLoad.Add("mail"); search.PropertiesToLoad.Add("givenName"); search.PropertiesToLoad.Add("lastLogon"); search.PropertiesToLoad.Add("userPrincipalName"); search.PropertiesToLoad.Add("st"); search.PropertiesToLoad.Add("sn"); search.PropertiesToLoad.Add("telephoneNumber"); search.PropertiesToLoad.Add("postalCode"); SearchResult result = search.FindOne(); if (result != null) { foreach (string key in result.Properties.PropertyNames) { // Each property contains a collection of its own // that may contain multiple values foreach (Object propValue in result.Properties[key]) { outputString += key + " = " + propValue + ".<br/>"; } } }

Dependiendo de los datos en su directorio activo, obtendrá una respuesta variada en la salida.

Aquí hay un sitio que tiene todas las propiedades de usuario que necesitaba:


La clase System.DirectoryServices.AccountManagement.UserPrincipal ( msdn link ) tiene una función estática FindByIdentity para convertir un SID a un objeto User. Debería poder funcionar tanto en la máquina local como en un servidor LDAP / Active Directory. Solo lo he usado contra el directorio activo.

Aquí hay un ejemplo que he usado en IIS:

// Set the search context to a specific domain in active directory var searchContext = new PrincipalContext(ContextType.Domain, "YOURDOMAIN", "OU=SomeOU,DC=YourCompany,DC=com"); // get the currently logged in user from IIS MembershipUser aspUser = Membership.GetUser(); // get the SID of the user (stored in the SecurityIdentifier class) var sid = aspUser.ProviderUserKey as System.Security.Principal.SecurityIdentifier; // get the ActiveDirectory user object using the SID (sid.Value returns the SID in string form) var adUser = UserPrincipal.FindByIdentity(searchContext, IdentityType.Sid, sid.Value); // do stuff to user, look up group membership, etc.


También puede obtener el nombre de cuenta de cuentas especiales como "Todos" con un código como este que funcionará independientemente de la configuración de idioma del usuario:

SecurityIdentifier everyoneSid = new SecurityIdentifier(WellKnownSidType.WorldSid, null); string everyone = everyoneSid.Translate(typeof(System.Security.Principal.NTAccount)).ToString();


En C #, obtenga el SID del usuario y asígnelo a una variable de cadena mediante:

string strUser = System.Security.Principal.WindowsIdentity.GetCurrent().User.ToString();

Tendrá que usar una cadena porque la capacidad de resolver con el nombre de usuario es compatible con la cadena. En otras palabras, el uso de var varUser dará como resultado un error de espacio de nombres.

string strUserName = new System.Security.Principal.SecurityIdentifier(strUser).Translate(typeof(System.Security.Principal.NTAccount)).ToString();


Estoy seguro de que podrá usar la respuesta aceptada desde aquí: Determinar el nombre de cuenta de LocalSystem usando C #

Básicamente, puede traducir una instancia de la clase SecurityIdentifier para escribir NTAccount, desde la cual puede obtener el nombre de usuario. En codigo:

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


Vea aquí para una buena respuesta:

¿La mejor manera de resolver el nombre de usuario de visualización por SID?

La esencia de esto es este bit:

string sid="S-1-5-21-789336058-507921405-854245398-9938"; string account = new System.Security.Principal.SecurityIdentifier(sid).Translate(typeof(System.Security.Principal.NTAccount)).ToString();

Este enfoque funciona para mí para SID no locales sobre el directorio activo.