2009-11-19 20 views
7

Tengo dos consultas que recuperan todos los grupos y todos los usuarios en un dominio, MydomainTSQL: ¿Cómo obtener una lista de grupos que pertenece a un usuario en Active Directory

--; Get all groups in domain MyDomain 
select * 
from OpenQuery(ADSI, ' 
    SELECT samaccountname,mail,sn,name, cn, objectCategory 
    FROM ''LDAP://Mydomain/CN=users,DC=Mydomain,DC=com'' 
    WHERE objectCategory=''group'' 
    ORDER BY cn 
    ') 

--; Get all users in domain MyDomain 
select * 
from OpenQuery(ADSI,' 
    SELECT objectCategory, cn, sn, mail, name, department,samaccountname 
    FROM ''LDAP://Mydomaindomain/CN=users,DC=Mydomain,DC=com'' 
    WHERE objectCategory=''user'' 
    ORDER BY cn 
    ') 
-- where samaccountname='mylogin' 

Lo que me gustaría averiguar es,

¿Cómo se recupera una lista de todos los grupos en MyDomain a los que pertenece un usuario en particular?

[ACTUALIZACIÓN] pude obtener el resultado opuesto
Dado el nombre del grupo, recuperar todos los usuarios

select * 
from OpenQuery(ADSI, 
    'SELECT objectCategory, cn, sn, mail, name, department 
    FROM ''LDAP://Mydomain/CN=users,DC=wl-domain,DC=com'' 
    WHERE MemberOf=''cn=_____GROUPNAME_____,CN=users,DC=Mydomain,DC=com'' 
    ORDER BY cn' 
    ) 

Respuesta

10

Creo que esta es una de las limitaciones de la interfaz basada AD T-SQL - no se puede recuperar los atributos de varios valores, por ejemplo atributos (como memberOf para el usuario) que tienen más de un valor en ellos.

Puede recuperar atributos de un solo valor como "sn" (apellido = apellido) o "givenName" y "mail" y demás, pero la interfaz basada en SQL no es capaz de manejar atributos como "memberOf" con varios valores asignados a ellos.

Así que me temo que tendrá que buscar otro camino para solucionar este problema, p. encuentre y complete la pertenencia al grupo en el código administrado (por separado, fuera de SQL Server, o posiblemente como un ensamblado CLR dentro de SQL Server).

ACTUALIZACIÓN: ver here (MSDN Support) para una explicación de limitación del proveedor OPENQUERY AD:

Limitaciones
El proceso de utilizar la instrucción OPENQUERY para tirar información de un servidor LDAP sufren de algún limitaciones Las limitaciones de se pueden evitar en algunos casos, pero en otros el diseño de la aplicación debe ser modificado. Un objeto aplicación externa o COM que utiliza ADSI para recuperar la información desde el servidor LDAP y luego construir una tabla en SQL mediante ADO u otros métodos de acceso de datos es otro método viable.

La primera limitación es que propiedades de varios valores no pueden ser devuelto en el conjunto de resultados a SQL Server.ADSI leerá la información del esquema del servidor LDAP que define la estructura y la sintaxis de las clases y los atributos utilizados por el servidor . Si el atributo que es solicitado desde el servidor LDAP es definido en el esquema como multivaluado, no se puede devolver en una instrucción OPENQUERY.

+0

La razón por la que estaba decidido a averiguar esto fue porque pude hacer exactamente lo contrario: dado el nombre del grupo, recupere todos los usuarios que pertenecen al grupo. (Pregunta actualizada para este propósito) – Sung

+0

sí, porque esa es una lista de todas las entradas de un solo valor, básicamente. El "memberOf" para el usuario es un único atributo que tiene múltiples valores y tiene varias entradas (algo totalmente contrario a 1NF en el diseño relacional) –

+0

con su consulta, obtiene una lista de objetos de usuario en AD - y para cada uno de ellos, solo accedes y usas atributos de un solo valor (cn, sn, objectCategory, etc.) –

-1

El Microsoft Technet Centro de scripts es un gran recurso para los scripts

http://technet.microsoft.com/en-us/scriptcenter/default.aspx

Aquí hay un script que afirma para dar a conocer exactamente lo que quiere:

http://gallery.technet.microsoft.com/ScriptCenter/en-us/ab5400e2-489a-4738-9b85-508bcb5b75f8

+3

eso no es exactamente T-SQL, sin embargo ..... –

+0

@Raj: Gracias por esos enlaces. He pasado por muchos scripts y pude hacerlo programáticamente, por ejemplo en C# o powershell, pero no pude traducirlos a consultas 'LDAP' en TSQL. – Sung

12

Puede lograr esto obteniendo todos los grupos que contienen el usuario en su atributo de miembro, o mejor la ruta LDAP del usuario (distinguishedName). Aquí hay un procedimiento simple para hacer ese trabajo.


CREATE PROCEDURE dbo.GetLdapUserGroups 
(
    @LdapUsername NVARCHAR(256) 
) 
AS 
BEGIN 
    DECLARE @Query NVARCHAR(1024), @Path NVARCHAR(1024) 

    SET @Query = ' 
     SELECT @Path = distinguishedName 
     FROM OPENQUERY(ADSI, '' 
      SELECT distinguishedName 
      FROM ''''LDAP://DC=domain,DC=com'''' 
      WHERE 
       objectClass = ''''user'''' AND 
       sAMAccountName = ''''' + @LdapUsername + ''''' 
     '') 
    ' 
    EXEC SP_EXECUTESQL @Query, N'@Path NVARCHAR(1024) OUTPUT', @Path = @Path OUTPUT 

    SET @Query = ' 
     SELECT name AS LdapGroup 
     FROM OPENQUERY(ADSI,'' 
      SELECT name 
      FROM ''''LDAP://DC=domain,DC=com'''' 
      WHERE 
       objectClass=''''group'''' AND 
       member=''''' + @Path + ''''' 
     '') 
     ORDER BY name 
    ' 
    EXEC SP_EXECUTESQL @Query 

END 

- Hilbert

1

En realidad, al recuperar la lista de todos los grupos a los que pertenece un usuario no es tan recta de avance/fácil como parece. Hasta donde yo sé, ni PowerShell ni otras secuencias de comandos pueden ofrecer resultados completamente precisos, incluso cuando se recupera el atributo tokenGroups, porque para tomar esta decisión, también se debe considerar la pertenencia a Grupos Builtin, que son específicos del dominio.

Hay un hilo muy útil en ActiveDirSec.org que creo que podría encontrar útil - How to enumerate the list of all Active Directory domain security groups that a user belongs to?

En mi experiencia, he aprendido que esto no es tan fácil como parece, y menos que tenga una La forma de verificar la salida es segura, tampoco hay manera de saber si su script está entregando los resultados correctos.

15

Procedimiento almacenado a continuación, ejecutar utilizando ejemplo:

Get_ADGroups_ForUser 'Beau.Holland' --AccountName

Nota: sustituir LDAP: // DC = dominio, DC = local con tu propio dominio

CREATE PROCEDURE dbo.Get_ADGroups_ForUser 
(
    @Username NVARCHAR(256) 
) 
AS 
BEGIN 

    DECLARE @Query NVARCHAR(1024), @Path NVARCHAR(1024) 

    -- Find the fully qualified CN e.g: CN=Beau Holland,OU=Users,OU=Australia,OU=NSO,OU=Company,DC=Domain,DC=local 
    -- replace "LDAP://DC=Domain,DC=local" with your own domain 
    SET @Query = ' 
     SELECT @Path = distinguishedName 
     FROM OPENQUERY(ADSI, '' 
      SELECT distinguishedName 
      FROM ''''LDAP://DC=Domain,DC=local'''' 
      WHERE 
       objectClass = ''''user'''' AND 
       sAMAccountName = ''''' + @Username + ''''' 
     '') 
    ' 
    EXEC SP_EXECUTESQL @Query, N'@Path NVARCHAR(1024) OUTPUT', @Path = @Path OUTPUT 

    -- get all groups for a user 
    -- replace "LDAP://DC=Domain,DC=local" with your own domain 
    SET @Query = ' 
     SELECT cn,AdsPath 
     FROM OPENQUERY (ADSI, ''<LDAP://DC=Domain,DC=local>;(&(objectClass=group)(member:1.2.840.113556.1.4.1941:=' + @Path +'));cn, adspath;subtree'')' 

    EXEC SP_EXECUTESQL @Query 

END 
GO 
+0

Esta es una gran respuesta, y merece más votos. Lo ideal sería obtener el camino en una subconsulta, pero esto funciona bien independientemente. – Elias

+1

@Elias - de acuerdo. Ese sufijo del subárbol es muy útil. Para otros interesados, en http://support2.microsoft.com/kb/187529 encontrarás más información sobre cómo configurar este tipo de cosas. –

Cuestiones relacionadas