Query AD Group Membership Recursively Through SQL

前端 未结 2 1744
暗喜
暗喜 2020-12-18 01:09

Background

I\'m creating some SQL to assist with security auditing; this will take security info from various systems databases and from Active Dire

相关标签:
2条回答
  • 2020-12-18 01:35

    Like this?

    --Get all members of a group
    SELECT cn,AdsPath 
    FROM OPENQUERY (ADSI, '<LDAP: dc="corp,dc=mycorp,dc=com">;(&(objectCategory=person)(memberOf:1.2.840.113556.1.4.1941:=CN=Administrators,CN=Builtin,DC=corp,DC=mycorp,DC=com));cn, adspath;subtree')
    ORDER BY cn; 
    
    --get all groups a user is a member of
    SELECT cn,AdsPath
    FROM OPENQUERY (ADSI, '<LDAP: dc="corp,dc=mycorp,dc=com">;(&(objectClass=group)(member:1.2.840.113556.1.4.1941:=CN=John Doe,OU=Developers,OU=Staff,DC=corp,DC=mycorp,DC=com));cn, adspath;subtree')
    ORDER BY cn;
    

    See http://msdn.microsoft.com/en-us/library/aa746475(VS.85).aspx for recursive search conditions.

    0 讨论(0)
  • 2020-12-18 01:40

    Though this is an old post, Google still likes to toss it to the top of the results, so as I struggled with this same problem a great deal, I wanted to post my findings/solution, with credit to Riverway for getting me on the right track.

    Create a Stored Procedure:

    CREATE PROCEDURE [dbo].[GetLdapUserGroups]
        (
        @LdapUsername NVARCHAR(max)
        )
    AS
    BEGIN
    DECLARE @Query NVARCHAR(max), @Path NVARCHAR(max)
    
    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(max) OUTPUT', @Path = @Path OUTPUT 
    
      SET @Query = '
        SELECT cn AS [LdapGroup]
        FROM OPENQUERY (ADSI, ''<LDAP://DOMAIN.COM>;
        (&(objectClass=group)(member:1.2.840.113556.1.4.1941:= ' + @Path + '));
        cn, adspath;subtree'')
        ORDER BY cn;
    '
    
    EXEC SP_EXECUTESQL @Query
    END
    

    Then, call your SP by just passing the username:

    DECLARE @UserGroup table (LdapGroup nvarchar(max))
    INSERT INTO @UserGroup exec Datamart.dbo.GetLdapUserGroups @LdapUser
    

    I'm then using a hash table to correctly match the AD group to the SQL data and what the end user should see.

    DECLARE @RptPermissions table (ldapGroup nvarchar(max),scholarshipCode nvarchar(50),gender nvarchar(2))
    INSERT INTO @RptPermissions VALUES('EMP_Enrollment_Admissions','ALL','MF')
    

    In my case, I'm using this to pull the SSRS user variable and pass it into the query for selecting the records based on AD group membership.

    ;WITH CTE_Permissions AS
    (
        SELECT
            p.scholarshipCode
            ,p.gender
        FROM @UserGroup AS g
        JOIN @RptPermissions AS p ON
            g.ldapGroup = p.ldapGroup
    )
    

    ... Later in the query

    JOIN CTE_Permissions AS p ON
             s.SCHOLARSHIP_ID = p.scholarshipCode
             OR p.scholarshipCode = 'ALL'
    

    Hope this helps.

    0 讨论(0)
提交回复
热议问题