HowTo: Agrupando grupos :-)

Una entrada rápida, no como la de ayer. Aunque el tema está bastante relacionado ya que ambos tratan de Active Directory e identidades.

GroupPolicy

Hoy vamos a ver una forma sencilla de obtener todos los grupos a los que pertenece un usuario, y agruparlos por su nombre de dominio. Y todo esto mediante una sola sentencia LINQ to objects. A ver quién es el guapo o guapa que me dice que LINQ to objects no es una maravilla!

El resultado que vamos a obtener es el siguiente (algunos nombres se han omitido por razones obvias :-P):

Groups under:
  – Group name: Todos
  – Group name: LOCAL
Groups under: BUILTIN
  – Group name: Usuarios
  – Group name: Administradores
Groups under: PRIMARY_DOMAIN_NAME
  – Group name: xxx1
  – Group name: xxx2
  – Group name: xxx3
  – Group name: xxx4
  – Group name: xxxN
Groups under: NT AUTHORITY
  – Group name: INTERACTIVE
  – Group name: Usuarios autentificados

Y el código resultante es un método extensor para la clase WindowsIdentity, con dos funciones auxiliares en forma de métodos extensores de la clase NTAccount:

using System;
using System.Collections.Generic;
using System.DirectoryServices;
using System.DirectoryServices.ActiveDirectory;
using System.Linq;
using System.Net.NetworkInformation;
using System.Runtime.InteropServices;
using System.Security.Principal;
using System.Text;
 
namespace Alpha.Code
{
    public static class SecurityExtensions
    {
        public static IOrderedEnumerable<IGrouping <string, NTAccount>> 
            GetGroupsUnderDomains(this WindowsIdentity identity)
        {
            var groups =
                        from grIdentity in identity.Groups
                        where grIdentity.IsValidTargetType(typeof(NTAccount))
                        select grIdentity.Translate(typeof(NTAccount)) as NTAccount into ntAccounts
                        let domainName = ntAccounts.GetDomainName()
                        let groupName = ntAccounts.GetAccountName()
                        orderby domainName
                        group ntAccounts by domainName into domainGroups
                        orderby domainGroups.Key
                        select domainGroups;
            return groups;
        }
 
        public static string GetDomainName(this NTAccount account)
        {
            string[] split = account.Value.Split('\\');
            return split.Length == 1 ? string.Empty : split[0];
        }
 
        public static string GetAccountName(this NTAccount account)
        {
            string[] split = account.Value.Split('\\');
            return split[split.Length - 1];
        }
    }
}

Para probarlo y ver el resultado:

var groups = WindowsIdentity.GetCurrent().GetGroupsUnderDomains();
foreach (var dg in groups)
{
    Console.WriteLine(string.Format("Groups under: {0}", dg.Key));
    foreach (var g in dg)
    {
        Console.WriteLine(string.Format("  - Group name: {0}", g.GetAccountName()));
    }
}

Un saludo desde las frías tierras de Andorra :-)

Noviembre 2009

** crossposting desde el blog de Lluís Franco en geeks.ms **

One thought on “HowTo: Agrupando grupos :-)

  1. Hola Franco. Disculpa, no se si me puedas orientar, tengo una rutina para validar un usuario en LDAP, pero dicha rutina me esta fallando cuando intento probar en un Windows 7. De hecho , primero valido que estemos en registrados en un LDAP, con el siguiente codigo C#.

    DirectoryEntry entryRoot = new (“LDAP://RootDSE”);
    try
    {
    return entryRoot.Properties[“defaultNamingContext”].Count > 0;
    }
    catch
    {
    return false;
    }
    Si falla, daba por hecho que no estábamos en un ambiente LDAP, pero esto ya no me funciona cuando estoy en un Windows 7 registrado en LDAP. simplemente se queda colgado la aplicación o falla.

    De antemano mil gracias.

Leave a Reply

Your email address will not be published. Required fields are marked *


*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>