DWORD LwLdapDirectoryOnePagedSearch( HANDLE hDirectory, PCSTR pszObjectDN, PCSTR pszQuery, PSTR* ppszAttributeList, DWORD dwPageSize, PLW_SEARCH_COOKIE pCookie, int scope, LDAPMessage** ppMessage ) { DWORD dwError = LW_ERROR_SUCCESS; PLW_LDAP_DIRECTORY_CONTEXT pDirectory = NULL; ber_int_t pageCount = 0; CHAR pagingCriticality = 'T'; LDAPControl *pPageControl = NULL; LDAPControl *ppInputControls[2] = { NULL, NULL }; LDAPControl **ppReturnedControls = NULL; int errorcodep = 0; LDAPMessage* pMessage = NULL; BOOLEAN bSearchFinished = FALSE; struct berval * pBerCookie = (struct berval *)pCookie->pvData; LW_ASSERT(pCookie->pfnFree == NULL || pCookie->pfnFree == LwLdapFreeCookie); pDirectory = (PLW_LDAP_DIRECTORY_CONTEXT)hDirectory; // dwError = ADEnablePageControlOption(hDirectory); // BAIL_ON_LW_ERROR(dwError); dwError = ldap_create_page_control(pDirectory->ld, dwPageSize, pBerCookie, pagingCriticality, &pPageControl); BAIL_ON_LDAP_ERROR(dwError); ppInputControls[0] = pPageControl; dwError = LwLdapDirectorySearchEx( hDirectory, pszObjectDN, scope, pszQuery, ppszAttributeList, ppInputControls, 0, &pMessage); BAIL_ON_LW_ERROR(dwError); dwError = ldap_parse_result(pDirectory->ld, pMessage, &errorcodep, NULL, NULL, NULL, &ppReturnedControls, 0); BAIL_ON_LDAP_ERROR(dwError); if (pBerCookie != NULL) { ber_bvfree(pBerCookie); pBerCookie = NULL; } dwError = ldap_parse_page_control(pDirectory->ld, ppReturnedControls, &pageCount, &pBerCookie); BAIL_ON_LDAP_ERROR(dwError); if (pBerCookie == NULL || pBerCookie->bv_len < 1) { bSearchFinished = TRUE; } if (ppReturnedControls) { ldap_controls_free(ppReturnedControls); ppReturnedControls = NULL; } ppInputControls[0] = NULL; ldap_control_free(pPageControl); pPageControl = NULL; pCookie->bSearchFinished = bSearchFinished; *ppMessage = pMessage; pCookie->pvData = pBerCookie; pCookie->pfnFree = LwLdapFreeCookie; cleanup: /* dwError_disable = ADDisablePageControlOption(hDirectory); if (dwError_disable) LW_RTL_LOG_ERROR("Error: LDAP Disable PageControl Info: failed");*/ if (ppReturnedControls) { ldap_controls_free(ppReturnedControls); } ppInputControls[0] = NULL; if (pPageControl) { ldap_control_free(pPageControl); } return (dwError); error: *ppMessage = NULL; pCookie->pvData = NULL; pCookie->pfnFree = NULL; pCookie->bSearchFinished = TRUE; if (pBerCookie != NULL) { ber_bvfree(pBerCookie); pBerCookie = NULL; } goto cleanup; }
/* LDAP search function for internal use. Returns a Python list of LDAPEntries. The `basestr` is the base DN of the searching, `scope` is the search scope (BASE|ONELEVEL|SUB), `filterstr` is the LDAP search filter string, `attrs` is a null-terminated string list of attributes' names to get only the selected attributes. If `attrsonly` is 1 get only attributes' name without values. If `firstonly` is 1, get only the first LDAP entry of the messages. The `timeout` is an integer of seconds for timelimit, `sizelimit` is a limit for size. */ PyObject * LDAPConnection_Searching(LDAPConnection *self, PyObject *iterator) { int rc; int num_of_ctrls = 0; LDAPMessage *res, *entry; PyObject *entrylist = NULL; LDAPEntry *entryobj = NULL; LDAPControl *page_ctrl = NULL; LDAPControl *sort_ctrl = NULL; LDAPControl **server_ctrls = NULL; LDAPControl **returned_ctrls = NULL; LDAPSearchIter *search_iter = (LDAPSearchIter *)iterator; entrylist = PyList_New(0); if (entrylist == NULL) { return PyErr_NoMemory(); } /* Check the number of server controls and allocate it. */ if (self->page_size > 1) num_of_ctrls++; if (self->sort_list != NULL) num_of_ctrls++; if (num_of_ctrls > 0) { server_ctrls = (LDAPControl **)malloc(sizeof(LDAPControl *) * (num_of_ctrls + 1)); if (server_ctrls == NULL) return PyErr_NoMemory(); num_of_ctrls = 0; } if (self->page_size > 1) { /* Create page control and add to the server controls. */ rc = ldap_create_page_control(self->ld, (ber_int_t)(self->page_size), search_iter->cookie, 0, &page_ctrl); if (rc != LDAP_SUCCESS) { PyErr_BadInternalCall(); return NULL; } server_ctrls[num_of_ctrls++] = page_ctrl; server_ctrls[num_of_ctrls] = NULL; } if (self->sort_list != NULL) { rc = ldap_create_sort_control(self->ld, self->sort_list, 0, &sort_ctrl); if (rc != LDAP_SUCCESS) { PyErr_BadInternalCall(); return NULL; } server_ctrls[num_of_ctrls++] = sort_ctrl; server_ctrls[num_of_ctrls] = NULL; } rc = ldap_search_ext_s(self->ld, search_iter->base, search_iter->scope, search_iter->filter, search_iter->attrs, search_iter->attrsonly, server_ctrls, NULL, search_iter->timeout, search_iter->sizelimit, &res); if (rc == LDAP_NO_SUCH_OBJECT) { return entrylist; } if (rc != LDAP_SUCCESS && rc != LDAP_PARTIAL_RESULTS) { Py_DECREF(entrylist); PyObject *ldaperror = get_error_by_code(rc); PyErr_SetString(ldaperror, ldap_err2string(rc)); Py_DECREF(ldaperror); return NULL; } rc = ldap_parse_result(self->ld, res, NULL, NULL, NULL, NULL, &returned_ctrls, 0); #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) if (search_iter->cookie != NULL && search_iter->cookie->bv_val != NULL) { ber_bvfree(search_iter->cookie); search_iter->cookie = NULL; } rc = ldap_parse_page_control(self->ld, returned_ctrls, NULL, &(search_iter->cookie)); #else rc = ldap_parse_pageresponse_control(self->ld, ldap_control_find(LDAP_CONTROL_PAGEDRESULTS, returned_ctrls, NULL), NULL, search_iter->cookie); #endif /* Iterate over the response LDAP messages. */ for (entry = ldap_first_entry(self->ld, res); entry != NULL; entry = ldap_next_entry(self->ld, entry)) { entryobj = LDAPEntry_FromLDAPMessage(entry, self); if (entryobj == NULL) { Py_DECREF(entrylist); return NULL; } if ((entryobj == NULL) || (PyList_Append(entrylist, (PyObject *)entryobj)) != 0) { Py_XDECREF(entryobj); Py_DECREF(entrylist); return PyErr_NoMemory(); } Py_DECREF(entryobj); } /* Cleanup. */ if (returned_ctrls != NULL) ldap_controls_free(returned_ctrls); if (page_ctrl != NULL) ldap_control_free(page_ctrl); if (sort_ctrl != NULL) ldap_control_free(sort_ctrl); if (server_ctrls != NULL) free(server_ctrls); ldap_msgfree(res); return entrylist; }