lundi 18 septembre 2017

c++ winldap not returning all entries. Stopping at 4000

I am writing a basic ldap query in c++ that will need to return our servers/workstations. I found this example off of Microsofts site and have changed it up a little to fit what I need. http://ift.tt/1asFWPU

I am able to bind to our servers and run queries with no issue and dump it into a log file, but I am unable to return more than 4000 objects. Our domain is very large with subdomains, and we will need to query more than 4000. I am able to run a query against the same Domain Controller with powershell and that returns all the objects. Query I am running for testing purposes is: "(objectCategory=computer)"I would like to keep it in c++ since I will be integrating it with an already existing program.

According to: http://ift.tt/2hbQyfe I should be able to set the sizelimit to 0 and all entries should be returned (Unless my understanding on what they mean by entries is wrong). However, changing from ldap_search_s() to ldap_search_ext_s and setting a flag for LDAP_NO_LIMIT or 0 made no difference on the amount of entries returned. As of now I have been stuck trying to figure out why I can't return all entries with what I have.

Here is what I got for code.

`//New Class//
Search *s = new Search;
ULONG numReturned = 0; //No Limit
char *LdapServer = "Domain.com";
//Init ssl//
LDAP *ldap = ldap_sslinitA(LdapServer, LDAP_SSL_PORT, 1);
unsigned long version = LDAP_VERSION3;
ldap_set_option(ldap, LDAP_OPT_PROTOCOL_VERSION, (void*)&version);
ldap_set_option(ldap, LDAP_OPT_SIZELIMIT, (void*)&numReturned);

//Define what attributes to return//
PCHAR pMyAttributes[2];
pMyAttributes[0] = "distinguishedName";
pMyAttributes[1] = NULL;

//Message return handle//
LDAPMessage *pMsg = NULL;
unsigned long connectSuccess = ldap_connect(ldap, NULL);
if (connectSuccess == LDAP_SUCCESS) {
    std::cout << "Connection to ldap successful\n";
    ldap_simple_bind(ldap, s->user, s->pw);
    std::string beginSearch = "";
std::cout << "Enter your custom query:\n";
        std::getline(std::cin, beginSearch);
        ldap_search_ext_s(ldap, "dc=Domain,dc=com", LDAP_SCOPE_SUBTREE, 
(PSTR)beginSearch.c_str(), pMyAttributes, NULL, NULL, NULL,NULL, 
LDAP_NO_LIMIT, &pMsg);
        ULONG numberOfEntries;
        numberOfEntries = ldap_count_entries(ldap, pMsg);
        if (numberOfEntries == NULL) {
            std::cout << "Ldap entries returned fail with 0x" << 
connectSuccess << "\n";
        }
        else {
            std::cout << "Entries returned: " << numberOfEntries;
            LDAPMessage *pEntry = NULL;
            PCHAR pEntryDN = NULL;
            ULONG iCnt = 0;
            char* sMsg;
            BerElement *pBer = NULL;
            PCHAR pAttribute = NULL;
            PCHAR *ppValue = NULL;
            ULONG iValue = 0;

            //Loop through the entries//
            for (iCnt = 0; iCnt < numberOfEntries; iCnt++) {
                //Get the first/next entry//
                if (!iCnt)
                    pEntry = ldap_first_entry(ldap, pMsg);
                else
                    pEntry = ldap_next_entry(ldap, pEntry);
                //Output status message//
                sMsg = (!iCnt ? "ldap_first_entry" : "ldap_next_entry");
                if (pEntry == NULL) {
                    std::cout << "failed with 0x" << sMsg << 
LdapGetLastError();
                    ldap_unbind_s(ldap);
                    ldap_msgfree(pMsg);
                    return -1;
                }
                else
                    std::cout << "Succeeded\n" << sMsg;
                std::cout << "Entry Number: " << iCnt;
                pAttribute = ldap_first_attribute(ldap, pEntry, &pBer); 
//Session Handle, Current Entry, [out] Current BerElement


//Begin outputting the attribute names for the current object and ouput 
values//
                while (pAttribute != NULL) {
                    std::cout << "ATTR: " << pAttribute;
                    Log(pAttribute);

                    //get string values
                    ppValue = ldap_get_values(ldap, pEntry, pAttribute); 
//Session handle, current entry, current attribute
                    if (ppValue == NULL)
                        std::cout << "\nNo Attribute value returned!\n";
                    else {
                        iValue = ldap_count_values(ppValue);
                        if (!iValue)
                            std::cout << "BAD VALUE LIST!\n";
                        else {
                            //Output the first attribute//
                            std::cout << ": " << *ppValue;
                            Log(*ppValue);
                            //If there are more, continuing outputting//
                            ULONG z;
                            for (z = 1; z < iValue; z++) {
                                std::cout << ", " << ppValue[z];
                                Log(ppValue[z]);
                            }
                        }
                    }
                    if (ppValue != NULL)
                        ldap_value_free(ppValue);
                    ppValue = NULL;
                    ldap_memfree(pAttribute);
                    pAttribute = ldap_next_attribute(ldap, pEntry, pBer);
                    std::cout << "\n";
                }
                if (pBer != NULL)
                    ber_free(pBer, 0);
                pBer = NULL;
            }
            ldap_unbind(ldap);
            ldap_msgfree(pMsg);
            ldap_value_free(ppValue);
        }
    }
}
`

I appreciate any help or pointers. Sorry if my code is hard to read.

Aucun commentaire:

Enregistrer un commentaire