How to - Como saber si el usuario actual es administrador del Dominio

11
44 How To: ¿Como saber si el usuario actual es administrador del dominio? Lluis Franco

description

Cuando desarrollas una aplicación es interesante saber si el usuario actual pertenece a un determinado grupo, y en concreto a los administradores del dominio, para habilitarles o no determinadas características. Se trata de una tarea no tan trivial como pueda parecer, y es una de las preguntas más frecuentes en muchos foros. En este artículo nuestro autor Lluis Franco nos explica cómo hacerlo.

Transcript of How to - Como saber si el usuario actual es administrador del Dominio

Page 1: How to - Como saber si el usuario actual es administrador del Dominio

44 How To: ¿Como saber si el usuario actual es administrador del dominio?

Lluis Franco

Page 2: How to - Como saber si el usuario actual es administrador del Dominio

HOW TO: ¿COMO SABER SI EL USUARIO ACTUAL ES ADMINISTRADOR DEL DOMINIO? Nivel: Intermedio por Lluis Franco

Esta es una cuestión que suscita dudas muy a menudo en todo tipo de foros de desarrolladores, ya que se trata de una necesidad muy común en las aplicaciones de gestión de escritorio. Cuando desarrollamos una aplicación podremos mostrar/ocultar/permitir/revocar ciertas acciones, u opciones sabiendo a qué grupos pertenece el usuario actual que está ejecutando la aplicación. Por ejemplo, yo acostumbro a tener un botón en la barra de estado de mis aplicaciones que permite cambiar la cadena de conexión de la base de datos, y evidentemente, solo está visible cuando el usuario pertenece al grupo “Administradores” o “Administradores del dominio”.

Método IsInRole de WindowsPrincipal Para conseguir este objetivo, el objeto WindowsPrincipal dispone de un método IsInRole, que nos dirá si un usuario pertenece a un grupo determinado. Además este método tiene varias sobrecargas, de modo que podemos usarlo pasando el RID (Relative Identifier), SID (Security Identifier), el nombre e incluso una constante basada en la enumeración WindowsBuiltInRole. En la Tabla A podemos ver los posibles valores de esta enumeración, y en la Tabla B los valores de los RID bien conocidos (ver al final del documento). De este modo para saber si nuestro usuario es administrador local, basta con hacer esto:

WindowsPrincipal wp = new WindowsPrincipal(WindowsIdentity.GetCurrent());

return wp.IsInRole(WindowsBuiltInRole.Administrator);

A partir del usuario que ejecuta nuestra aplicación (válido también en caso de que se haga suplantación de usuario), creamos un objeto Principal e invocamos al método pasándole el grupo contra el que deseamos validar. ¿A qué es sencillo? Nota: Por motivos de rendimiento, para determinar la función del usuario se recomienda utilizar la sobrecarga de IsInRole(SecurityIdentifier) como sobrecarga preferible. El problema de esta enumeración es que como su nombre indica, sólo contempla los grupos locales. Así que si queremos saber si pertenece a un grupo del dominio parece que tendremos que buscar el SID del grupo, o el nombre, y “hardcodearlo” –introducirlo a mano- en nuestra aplicación. ¿Feo verdad? Pues la verdad es que si, muy feo… vamos a investigar un poco más, a ver si encontramos otra forma.

Page 3: How to - Como saber si el usuario actual es administrador del Dominio

Identificadores de seguridad: SID Existe una enumeración llamada WellKnownSidType, que devuelve los SID (Security Identifiers, identificadores de seguridad) más utilizados. Los SID son valores únicos de longitud variable que se usan para identificar una entidad principal de seguridad (usuario) o un grupo de seguridad en sistemas operativos Windows. Los SID conocidos son un grupo de estos identificadores que representan a usuarios o grupos comunes y cuyos valores permanecen constantes en todos los sistemas operativos. Si quieres profundizar en estos elementos y su composición puedes hacerlo en este artículo de la Wikipedia (inglés). En la Tabla C, al final, se muestra la lista de los SID conocidos. Verás que hay muchos usuarios y grupos comunes, y entre ellos ¡BINGO!, está también el SID del grupo de administradores del dominio (en rojo, AccountDomainAdminSid), y parece que por lo tanto ya podemos volver a probar el método IsInRole:

WindowsPrincipal wp = new WindowsPrincipal(WindowsIdentity.GetCurrent());

SecurityIdentifier sid =

new SecurityIdentifier(WellKnownSidType.AccountDomainAdminsSid, null);

return wp.IsInRole(sid);

¡Ooops! Nuestro gozo en un pozo. Se produce un error:

Figura 1.- Excepción al intentar usar un nulo como segundo argumento

Se necesita especificar el segundo argumento en el constructor del SID de grupo, y por lo tanto no funciona. El error habla de un AccountDomainSid. ¿Y qué es esto?

DomainSid Según la documentación del constructor debe proporcionarse el SID del dominio para que éste ueda devolver algunos identificadores WellKnownSidType, entre los cuales está el de que nos interesa de los administradores del dominio. Dicho de otro modo, o sabemos el SID de nuestro dominio o todo lo anterior no vale para nada… :-( ¿Y cómo podemos saber el SID de dominio? Después de buscar un ratito, lo único que he encontrado es una utilidad de consola llamada PsGetSid, que forma parte de las PSTools del inefable Mark Russinovich. Basta descargar esta utilidad y ejecutarla desde la consola de este

Page 4: How to - Como saber si el usuario actual es administrador del Dominio

modo para saber el SID de nuestro dominio (el nombre de dominio en formato “microsoft.com” o “net.volvo.com”):

Figura 2.- La utilidad PsGetSid en funcionamiento Sin embargo tener que hacer esto y usar el identificador “hardcodeado” en el código no sería tampoco de gran ayuda. Así que vamos a probar si podemos recuperar esta propiedad del esquema de Directorio Activo mediante un DirectoryEntry. Para ello utilizaremos la clase Domain:

Domain d = Domain.GetDomain(new DirectoryContext(DirectoryContextType.Domain,

getDomainName()));

using (DirectoryEntry de = d.GetDirectoryEntry())

{

byte[] domSid = (byte[])de.Properties["objectSid"].Value;

string sdomainSid = sIDtoString(domSid);

Console.WriteLine(sdomainSid);

}

//El código anterior hace uso de estos dos métodos adicionales:

//Obtiene el nombre del dominio actual

public static string getDomainName()

{

return IPGlobalProperties.GetIPGlobalProperties().DomainName;

}

//Transforma el array de bits del SID en su representación textual

public static string sIDtoString(byte[] sidBinary)

{

SecurityIdentifier sid = new SecurityIdentifier(sidBinary, 0);

return sid.ToString();

}

Page 5: How to - Como saber si el usuario actual es administrador del Dominio

En el código anterior obtenemos dentro de la variable sdomainSid, que se muestra por consola, el valor del SID de nuestro dominio, que era lo que buscábamos :-)

Poniéndolo todo junto Como resumen final y con el ánimo de dar un código listo para usar, vamos a encapsular todo lo explicado dentro de un método extensor de la clase WindowsIdentity de modo que podamos usarlo con mucha facilidad:

using System.DirectoryServices;

using System.DirectoryServices.ActiveDirectory;

using System.Net.NetworkInformation;

using System.Security.Principal;

namespace Alpha.Code

{

public static class SecurityExtensions

{

public static bool IsDomainAdmin (this WindowsIdentity identity)

{

Domain d = Domain.GetDomain(new

DirectoryContext(DirectoryContextType.Domain, getDomainName()));

using (DirectoryEntry de = d.GetDirectoryEntry())

{

byte[] bdomSid = (byte[])de.Properties["objectSid"].Value;

string sdomainSid = sIDtoString(bdomSid);

WindowsPrincipal wp = new WindowsPrincipal(identity);

SecurityIdentifier dsid = new SecurityIdentifier(sdomainSid);

SecurityIdentifier dasid = new SecurityIdentifier(

WellKnownSidType.AccountDomainAdminsSid, dsid);

return wp.IsInRole(dasid);

}

}

public static string getDomainName()

{

return IPGlobalProperties.GetIPGlobalProperties().DomainName;

}

public static string sIDtoString(byte[] sidBinary)

{

SecurityIdentifier sid = new SecurityIdentifier(sidBinary, 0);

return sid.ToString();

}

}

}

Y ahora la forma de usarlo sería tan sencilla como hacer algo así:

if (WindowsIdentity.GetCurrent().IsDomainAdmin())

{

//Acciones a realizar si el usuario es administrador de dominio...

}

Page 6: How to - Como saber si el usuario actual es administrador del Dominio

APÉNDICE: TABLAS Tabla A.- Miembros de la enumeración WindowsBuiltInRole para usar con IsInRole

Nombre Descripción

AccountOperator Los operadores de cuentas administran las cuentas de los usuarios de un equipo o dominio.

Administrator Los administradores tienen acceso completo y sin restricciones al equipo o dominio.

BackupOperator Los operadores de copia de seguridad pueden reemplazar las restricciones de seguridad con el único propósito de hacer copias de seguridad de los archivos o de restaurarlas.

Guest Los invitados tienen más restricciones que los usuarios.

PowerUser Los usuarios avanzados poseen la mayoría de los permisos administrativos, con algunas restricciones. De este modo, los usuarios avanzados pueden ejecutar aplicaciones heredadas, además de aplicaciones certificadas.

PrintOperator Los operadores de impresión pueden tomar el control de una impresora.

Replicator Los replicadores permiten la duplicación de archivos en un dominio.

SystemOperator Los operadores del sistema administran un equipo en particular.

User Los usuarios no pueden realizar cambios accidentales o intencionados en todo el sistema. En consecuencia, pueden ejecutar aplicaciones certificadas, pero no la mayoría de las aplicaciones heredadas.

Tabla B.- Identificadores de recursos bien conocidos (RID) para usar con IsInRole

Entidad conocida RID Tipo

Domain Administrator 500 User

Domain Guest 501 User

Domain KRBTGT 502 User

Domain Admins 512 Group

Domain Users 513 Group

Domain Guests 514 Group

Domain Computers 515 Group

Domain Controllers 516 Group

Domain Certificate Admins 517 Group

Domain Schema Admins 518 Group

Page 7: How to - Como saber si el usuario actual es administrador del Dominio

Domain Enterprise Admins 519 Group

Domain Policy Admins 520 Group

Builtin Admins 544 Alias

Builtin users 545 Alias

Builtin Guests 546 Alias

Builtin Power Users 547 Alias

Builtin Account Operators 548 Alias

Builtin System Operators 549 Alias

Builtin Print Operators 550 Alias

Builtin Backup Operators 551 Alias

Builtin Replicator 552 Alias

Builtin RAS Servers 553 Alias

Tabla C.- Miembros de la enumeración WellKnownSidType

Nombre Descripción

NullSid Indica un SID null.

WorldSid Indica un SID que coincide con todos.

LocalSid Indica un SID local.

CreatorOwnerSid Indica un SID que coincide con el propietario o creador de un objeto.

CreatorGroupSid Indica un SID que coincide con el grupo de creadores de un objeto.

CreatorOwnerServerSid Indica un SID de Creator Owner Server.

CreatorGroupServerSid Indica un SID de servidor de grupo de creadores.

NTAuthoritySid Indica un SID para la autoridad de Windows NT.

DialupSid Indica un SID para una cuenta de acceso telefónico.

NetworkSid Indica un SID para una cuenta de red. Este SID se agrega al proceso de un símbolo (token) cuando inicia sesión a través de una red.

BatchSid Indica un SID para un proceso por lotes. Este SID se agrega al proceso de un símbolo (token) cuando inicia sesión como un trabajo por lotes.

InteractiveSid Indica un SID para una cuenta interactiva. Este SID se agrega al proceso de un símbolo (token) cuando inicia sesión interactivamente.

ServiceSid Indica un SID para un servicio. Este SID se agrega al proceso de un símbolo (token) cuando inicia sesión como servicio.

AnonymousSid Indica un SID para la cuenta anónima.

ProxySid Indica un SID de servidor proxy.

Page 8: How to - Como saber si el usuario actual es administrador del Dominio

EnterpriseControllersSid Indica un SID para un controlador de empresa.

SelfSid Indica un SID para sí mismo.

AuthenticatedUserSid Indica un SID para un usuario autenticado.

RestrictedCodeSid Indica un SID para código restringido.

TerminalServerSid Indica un SID que coincide con una cuenta de Terminal Server.

RemoteLogonIdSid Indica un SID que coincide con inicios de sesión remotos.

LogonIdsSid Indica un SID que coincide con identificadores de inicio de sesión.

LocalSystemSid Indica un SID que coincide con el sistema local.

LocalServiceSid Indica un SID que coincide con un servicio local.

NetworkServiceSid Indica un SID que coincide con un servicio de red.

BuiltinDomainSid Indica un SID que coincide con la cuenta de dominio.

BuiltinAdministratorsSid Indica un SID que coincide con la cuenta de administrador.

BuiltinUsersSid Indica un SID que coincide con las cuentas de usuario integradas.

BuiltinGuestsSid Indica un SID que coincide con la cuenta de invitado.

BuiltinPowerUsersSid Indica un SID que coincide con el grupo de usuarios avanzados.

BuiltinAccountOperatorsSid Indica un SID que coincide con la cuenta de operadores de cuentas.

BuiltinSystemOperatorsSid Indica un SID que coincide con el grupo de operadores de sistema.

BuiltinPrintOperatorsSid Indica un SID que coincide con el grupo de operadores de impresión.

BuiltinBackupOperatorsSid Indica un SID que coincide con el grupo de operadores de copias de seguridad.

BuiltinReplicatorSid Indica un SID que coincide con la cuenta del replicador.

BuiltinPreWindows2000CompatibleAccessSid Indica un SID que coincide con cuentas compatibles con versiones anteriores a Windows 2000.

BuiltinRemoteDesktopUsersSid Indica un SID que coincide con usuarios de escritorio remoto.

BuiltinNetworkConfigurationOperatorsSid Indica un SID que coincide con el grupo de operadores de red.

Page 9: How to - Como saber si el usuario actual es administrador del Dominio

AccountAdministratorSid Indica un SID que coincide con el grupo de administradores de cuenta.

AccountGuestSid Indica un SID que coincide con el grupo de invitados de cuenta.

AccountKrbtgtSid Indica un SID que coincide con el grupo de destino Kerberos de la cuenta.

AccountDomainAdminsSid Indica un SID que coincide con el grupo de administradores de dominio de cuenta.

AccountDomainUsersSid Indica un SID que coincide con el grupo de usuarios de dominio de cuenta.

AccountDomainGuestsSid Indica un SID que coincide con el grupo de invitados de dominio de cuenta.

AccountComputersSid Indica un SID que coincide con el grupo de equipos de cuenta.

AccountControllersSid Indica un SID que coincide con el grupo de controladores de cuenta.

AccountCertAdminsSid Indica un SID que coincide con el grupo de administradores de certificado.

AccountSchemaAdminsSid Indica un SID que coincide con el grupo de administradores de esquema.

AccountEnterpriseAdminsSid Indica un SID que coincide con el grupo de administradores de empresa.

AccountPolicyAdminsSid Indica un SID que coincide con el grupo de administradores de directivas.

AccountRasAndIasServersSid Indica un SID que coincide con la cuenta de servidor RAS e IAS.

NtlmAuthenticationSid Indica un SID presente cuando el paquete de autenticación NTLM de Microsoft autenticó el cliente.

DigestAuthenticationSid Indica un SID presente cuando el paquete de autenticación implícita de Microsoft autenticó el cliente.

SChannelAuthenticationSid Indica un SID presente cuando el paquete de autenticación de canal seguro (SSL/TLS) autenticó el cliente.

ThisOrganizationSid Indica un SID presente cuando el usuario se autenticó desde el bosque o a través de una confianza que no tiene habilitada la opción de autenticación selectiva. Si este SID está presente, OtherOrganizationSid no puede estarlo.

Page 10: How to - Como saber si el usuario actual es administrador del Dominio

OtherOrganizationSid Indica un SID presente cuando el usuario se autenticó en un bosque con la opción de autenticación selectiva habilitada. Si este SID está presente, ThisOrganizationSid no puede estarlo.

BuiltinIncomingForestTrustBuildersSid Indica un SID que permite a un usuario crear relaciones de confianza de bosque de entrada. Se agrega al símbolo (token) de los usuarios que son miembros del grupo integrado de Creadores de confianza de bosque de entrada en el dominio raíz del bosque.

BuiltinPerformanceMonitoringUsersSid Indica un SID que coincide con el grupo de usuarios que tiene acceso remoto para programar un registro de contadores de rendimiento en este equipo.

BuiltinPerformanceLoggingUsersSid Indica un SID que coincide con el grupo de usuarios que tiene acceso remoto para supervisar el equipo.

BuiltinAuthorizationAccessSid Indica un SID que coincide con el grupo de acceso de autorización de Windows.

WinBuiltinTerminalServerLicenseServersSid Indica un SID que está presente en un servidor que puede emitir licencias de Terminal Server.

MaxDefined Indica el SID máximo definido en la enumeración WellKnownSidType.

Acerca del autor Lluís Franco es autor de campusMVP. Es gestor de proyectos y desarrollador en ‘Fimarge Societat Gestora de Patrimonis’, situada en Andorra. Desde 1994, ha estado principalmente trabajando en el desarrollo de aplicaciones sobre plataformas Windows. Está especializado en desarrollos financieros con SQL Server, Visual Basic y C#. Blog: http://geeks.ms/blogs/lfranco

Acerca de campusMVP CampusMVP te ofrece la mejor formación en tecnología Microsoft a través de nuestros cursos online y nuestros libros especializados, impartidos y escritos por conocidos MVP de Microsoft. Visita nuestra página y prueba nuestros cursos y libros gratuitamente. www-campusmvp.com

Reconocimiento - NoComercial - CompartirIgual (by-nc-sa): No se permite un uso comercial de este documento ni de las posibles obras derivadas, la distribución de las cuales se debe hacer con una licencia igual a la que regula esta obra original. Se debe citar la fuente.

Page 11: How to - Como saber si el usuario actual es administrador del Dominio