LDAP query returns data in parent domain but not from child domain

Discussion in 'Scripting' started by Howard Bullock, Dec 10, 2007.

  1. My query:
    select objectSid from 'LDAP://dc=child,dc=company,dc=com' where memberof =
    'CN=GatdWillHamatyU,CN=Users,DC=child,DC=company,DC=com'

    This format work fine for querying membership of groups in
    DC=company,DC=com' where my user account resides.

    One thing I suspected was that I needed to tell the query where to bind so I
    modified it to be:
    select objectSid from 'LDAP://child.company.com/dc=child,dc=company,dc=com'
    where memberof = 'CN=GatdWillHamatyU,CN=Users,DC=child,DC=company,DC=com'.

    This also failed. I even used a FQDN of a domain controller in the child
    domain.

    How should I structure the ADO connection and LDAP SQL dialect query to list
    the full membership of all groups in a child domain? Incidentally my computer
    is currently in the child domain.
     
    Howard Bullock, Dec 10, 2007
    #1
    1. Advertisements

  2. Try using GC:// instead of LDAP://. The memberOf attribute is in the global
    catalog.
     
    Richard Mueller [MVP], Dec 10, 2007
    #2
    1. Advertisements

  3. Sorry, I'm mistaken. It's the member attribute that's replicated to the GC,
    not memberOf, so GC:// won't work with your query. However, you should be
    able to retrieve the member attribute of the group from the GC. Instead of
    one row per user you will retrieve one array of distinguished names.
    Perhaps:

    "SELECT member FROM 'GC://dc=child,dc=company,dc=com' " _
    & "where
    distinguishedName='cn=GatdWillHamatyU,cn=Users,dc=child,dc=company,dc=com'"

    For membership of all groups in the child domain, perhaps:

    "SELECT distinguishedName, member FROM 'GC://dc=child,dc=company,dc=com' " _
    & "where objectCategory='group'"
     
    Richard Mueller [MVP], Dec 10, 2007
    #3
  4. Using the GC did not seem to work. Although the ADO object RecordCount
    reports one row was returned, I could not retrieve any data from the object.
    It appears to be empty.

    This acts like my failed query; no error just no data.

    There still seems to be a simple issue that should be resolvable. If the
    query of the parent domain works:
    select objectSid from 'LDAP://dc=company,dc=com' where memberof
    ='CN=somegroup,CN=Users,DC=company,DC=com'

    Then why wouldn't the same query construct, pointed to a child AD domain,
    not work as well?

    This fails:
    select objectSid from 'LDAP://dc=child,dc=company,dc=com' where memberof =
    'CN=GatdWillHamatyU,CN=Users,DC=child,DC=company,DC=com'

    The groups in question could be any group type.

    Are there other binding options that make sense?
    Do LDAP queries to child domains default to using the parent domain's
    available GC entries?
     
    Howard Bullock, Dec 10, 2007
    #4
  5. If you ran the query I suggested, using the GC provider and querying for the
    member attribute of one group, then RecordCount would be one. However you
    must enumerate the retrieved member attribute as an array. You don't say
    what language or tool you are using, but the following should work in
    VBScript (I use LDAP syntax rather than SQL, but that should not matter):
    ============
    Option Explicit

    Dim adoCommand, adoConnection, strBase, strFilter, strAttributes

    Dim objRootDSE, strDNSDomain, strQuery, adoRecordset

    Dim arrMembers, strMember



    ' Setup ADO objects.

    Set adoCommand = CreateObject("ADODB.Command")
    Set adoConnection = CreateObject("ADODB.Connection")
    adoConnection.Provider = "ADsDSOObject"
    adoConnection.Open "Active Directory Provider"
    adoCommand.ActiveConnection = adoConnection



    ' Search entire Active Directory domain.

    Set objRootDSE = GetObject("LDAP://RootDSE")

    strDNSDomain = objRootDSE.Get("defaultNamingContext")
    strBase = "<GC://" & strDNSDomain & ">"


    ' Filter on a specific group.
    strFilter =
    "(distinguishedName=CN=GatdWillHamatyU,CN=Users,DC=child,DC=company,DC=com)"



    ' Comma delimited list of attribute values to retrieve.
    strAttributes = "member"



    ' Construct the LDAP syntax query.
    strQuery = strBase & ";" & strFilter & ";" & strAttributes & ";subtree"
    adoCommand.CommandText = strQuery
    adoCommand.Properties("Page Size") = 100
    adoCommand.Properties("Timeout") = 30
    adoCommand.Properties("Cache Results") = False



    ' Run the query.
    Set adoRecordset = adoCommand.Execute


    ' Enumerate the resulting recordset.
    Do Until adoRecordset.EOF

    ' Retrieve values and display.

    arrMembers = adoRecordset.Fields("member").Value

    If IsNull(arrMembers) Then

    Wscript.Echo "No members"

    Else

    For Each strMember In arrMembers

    Wscript.Echo "Member: " & strMember

    Next

    End If
    ' Move to the next record in the recordset.
    adoRecordset.MoveNext
    Loop



    ' Clean up.

    adoRecordset.Close

    adoConnection.Close

    ===============

    I don't have a multi-domain setup to experiment with, so I'm not sure why
    your query of a child domain doesn't work. You may need to post some code.
    You can also use Joe Richards' free utility adfind to run queries.



    http://joeware.net/freetools/tools/adfind/index.htm
     
    Richard Mueller [MVP], Dec 10, 2007
    #5
  6. After further reflection, I think that the MemberOf property is associated
    with the user account in the parent domain. Therefore, querying for
    memberOf=somegroup in a child domain where the accounts reside in the parent
    make little sense.

    Would you agree?

    So my question becomes: What is an efficient ADO query that would list the
    members of a local group (or any group) in a child domain where most of the
    members are accounts from the parent domain?

    I do not want to use ADSI GetObject and Members method as it is very
    inefficient consuming excessive memory for the IDsipatch objects.
     
    Howard Bullock, Dec 10, 2007
    #6
  7. Maybe the issue is that these are Domain Local Groups. Users in other
    domains can be members of these groups, but the groups are not visible in
    other domains. I think you must retrieve the member attribute of the group
    object. ADO returns this attribute value as an array of distinguished names.
    However, it makes more sense to bind to the group directly and enumerate the
    member attribute, which is multi-valued. No need to search when you know the
    group DN.

    The Members method must bind to every member, which takes time. Retrieving
    the member attribute should be fast.
     
    Richard Mueller [MVP], Dec 10, 2007
    #7
  8.  
    Howard Bullock, Dec 10, 2007
    #8
  9. My detailed response was somehow lost.

    In short, using the GC:// did not work. Changing back to LDAP:// made
    everything work.

    "select member from 'LDAP://" . $Server . "/". $rootNC . "' where
    distinguishedName='" . $GrpDN . "'"

    My original issue was that I started using the "MemberOf" attribute which
    was actually a search of user account properties to collect members of a
    specific group. Since the parent domain accounts do not maintain information
    about child domain group memberships, the query failed with regard to group
    in the child domain.

    Using the "Members" attribute on the groups was much faster and now works
    for all domain and groups that I query.

    Thanks for your help.
     
    Howard Bullock, Dec 11, 2007
    #9
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.