From 3f8b38c5f239db001af277c9e4780bc49a99ed2e Mon Sep 17 00:00:00 2001 From: Timothy Pearson Date: Tue, 23 Apr 2013 11:48:24 -0500 Subject: [PATCH] Add paged search capability --- src/libtdeldap.cpp | 347 +++++++++++++++++++++++++++++++++++++++------ src/libtdeldap.h | 8 +- 2 files changed, 307 insertions(+), 48 deletions(-) diff --git a/src/libtdeldap.cpp b/src/libtdeldap.cpp index 417bc46..c454710 100644 --- a/src/libtdeldap.cpp +++ b/src/libtdeldap.cpp @@ -623,8 +623,9 @@ LDAPUserInfo LDAPManager::parseLDAPUserRecord(LDAPMessage* entry) { return userinfo; } -LDAPUserInfoList LDAPManager::users(int* mretcode) { +LDAPUserInfoList LDAPManager::users(int* mretcode, TQString *errstr) { int retcode; + int errcode; LDAPUserInfoList users; if (bind() < 0) { @@ -635,24 +636,110 @@ LDAPUserInfoList LDAPManager::users(int* mretcode) { LDAPMessage* msg; TQString ldap_base_dn = m_basedc; TQString ldap_filter = "(objectClass=posixAccount)"; + retcode = ldap_search_ext_s(m_ldap, ldap_base_dn.ascii(), LDAP_SCOPE_SUBTREE, ldap_filter.ascii(), ldap_user_and_operational_attributes, 0, NULL, NULL, NULL, 0, &msg); - if (retcode != LDAP_SUCCESS) { - KMessageBox::error(0, i18n("LDAP search failure

Reason: [%3] %4").arg(retcode).arg(ldap_err2string(retcode)), i18n("LDAP Error")); + if ((retcode != LDAP_SUCCESS) && (retcode != LDAP_SIZELIMIT_EXCEEDED)) { + if (errstr) { + *errstr = i18n("LDAP search failure

Reason: [%3] %4").arg(retcode).arg(ldap_err2string(retcode)); + } + else { + KMessageBox::error(0, i18n("LDAP search failure

Reason: [%3] %4").arg(retcode).arg(ldap_err2string(retcode)), i18n("LDAP Error")); + } if (mretcode) *mretcode = -1; return LDAPUserInfoList(); } + else if (retcode == LDAP_SUCCESS) { + // Iterate through the returned entries + LDAPMessage* entry; + for(entry = ldap_first_entry(m_ldap, msg); entry != NULL; entry = ldap_next_entry(m_ldap, entry)) { + users.append(parseLDAPUserRecord(entry)); + } - // Iterate through the returned entries - LDAPMessage* entry; - for(entry = ldap_first_entry(m_ldap, msg); entry != NULL; entry = ldap_next_entry(m_ldap, entry)) { - users.append(parseLDAPUserRecord(entry)); + // clean up + ldap_msgfree(msg); + + if (mretcode) *mretcode = 0; + return users; + } + else if (retcode == LDAP_SIZELIMIT_EXCEEDED) { + // Try paged access + bool morePages = false; + unsigned long pageSize = 100; + struct berval cookie = {0, NULL}; + char pagingCriticality = 'T'; + LDAPControl* pageControl = NULL; + LDAPControl* serverControls[2] = { NULL, NULL }; + LDAPControl** returnedControls = NULL; + + do { + retcode = ldap_create_page_control(m_ldap, pageSize, &cookie, pagingCriticality, &pageControl); + if (retcode != LDAP_SUCCESS) { + if (errstr) { + *errstr = i18n("LDAP search failure

Reason: [%3] %4").arg(retcode).arg(ldap_err2string(retcode)); + } + else { + KMessageBox::error(0, i18n("LDAP search failure

Reason: [%3] %4").arg(retcode).arg(ldap_err2string(retcode)), i18n("LDAP Error")); + } + if (mretcode) *mretcode = -1; + return LDAPUserInfoList(); + } + serverControls[0] = pageControl; + retcode = ldap_search_ext_s(m_ldap, ldap_base_dn.ascii(), LDAP_SCOPE_SUBTREE, ldap_filter.ascii(), ldap_user_and_operational_attributes, 0, serverControls, NULL, NULL, 0, &msg); + if ((retcode != LDAP_SUCCESS) && (retcode != LDAP_PARTIAL_RESULTS)) { + if (errstr) { + *errstr = i18n("LDAP search failure

Reason: [%3] %4").arg(retcode).arg(ldap_err2string(retcode)); + } + else { + KMessageBox::error(0, i18n("LDAP search failure

Reason: [%3] %4").arg(retcode).arg(ldap_err2string(retcode)), i18n("LDAP Error")); + } + if (mretcode) *mretcode = -1; + return LDAPUserInfoList(); + } + retcode = ldap_parse_result(m_ldap, msg, &errcode, NULL, NULL, NULL, &returnedControls, false); + if (retcode != LDAP_SUCCESS) { + if (errstr) { + *errstr = i18n("LDAP search failure

Reason: [%3] %4").arg(retcode).arg(ldap_err2string(retcode)); + } + else { + KMessageBox::error(0, i18n("LDAP search failure

Reason: [%3] %4").arg(retcode).arg(ldap_err2string(retcode)), i18n("LDAP Error")); + } + if (mretcode) *mretcode = -1; + return LDAPUserInfoList(); + } + if (cookie.bv_val != NULL) { + ber_memfree(cookie.bv_val); + cookie.bv_val = NULL; + cookie.bv_len = 0; + } + if (!!returnedControls) { + retcode = ldap_parse_pageresponse_control(m_ldap, returnedControls[0], NULL, &cookie); + morePages = (cookie.bv_val && (strlen(cookie.bv_val) > 0)); + } + else { + morePages = false; + } + + if (returnedControls != NULL) { + ldap_controls_free(returnedControls); + returnedControls = NULL; + } + serverControls[0] = NULL; + ldap_control_free(pageControl); + pageControl = NULL; + + // Iterate through the returned entries + LDAPMessage* entry; + for(entry = ldap_first_entry(m_ldap, msg); entry != NULL; entry = ldap_next_entry(m_ldap, entry)) { + users.append(parseLDAPUserRecord(entry)); + } + + // clean up + ldap_msgfree(msg); + } while (morePages); + + if (mretcode) *mretcode = 0; + return users; } - - // clean up - ldap_msgfree(msg); - - if (mretcode) *mretcode = 0; - return users; } return LDAPUserInfoList(); @@ -2128,8 +2215,9 @@ LDAPServiceInfo LDAPManager::parseLDAPMachineServiceRecord(LDAPMessage* entry) { return machineserviceinfo; } -LDAPGroupInfoList LDAPManager::groups(int* mretcode) { +LDAPGroupInfoList LDAPManager::groups(int* mretcode, TQString *errstr) { int retcode; + int errcode; LDAPGroupInfoList groups; if (bind() < 0) { @@ -2141,30 +2229,116 @@ LDAPGroupInfoList LDAPManager::groups(int* mretcode) { TQString ldap_base_dn = m_basedc; TQString ldap_filter = "(objectClass=posixGroup)"; retcode = ldap_search_ext_s(m_ldap, ldap_base_dn.ascii(), LDAP_SCOPE_SUBTREE, ldap_filter.ascii(), ldap_user_and_operational_attributes, 0, NULL, NULL, NULL, 0, &msg); - if (retcode != LDAP_SUCCESS) { - KMessageBox::error(0, i18n("LDAP search failure

Reason: [%3] %4").arg(retcode).arg(ldap_err2string(retcode)), i18n("LDAP Error")); + if ((retcode != LDAP_SUCCESS) && (retcode != LDAP_SIZELIMIT_EXCEEDED)) { + if (errstr) { + *errstr = i18n("LDAP search failure

Reason: [%3] %4").arg(retcode).arg(ldap_err2string(retcode)); + } + else { + KMessageBox::error(0, i18n("LDAP search failure

Reason: [%3] %4").arg(retcode).arg(ldap_err2string(retcode)), i18n("LDAP Error")); + } if (mretcode) *mretcode = -1; return LDAPGroupInfoList(); } - - // Iterate through the returned entries - LDAPMessage* entry; - for(entry = ldap_first_entry(m_ldap, msg); entry != NULL; entry = ldap_next_entry(m_ldap, entry)) { - groups.append(parseLDAPGroupRecord(entry)); - } + else if (retcode == LDAP_SUCCESS) { + // Iterate through the returned entries + LDAPMessage* entry; + for(entry = ldap_first_entry(m_ldap, msg); entry != NULL; entry = ldap_next_entry(m_ldap, entry)) { + groups.append(parseLDAPGroupRecord(entry)); + } - // clean up - ldap_msgfree(msg); - - if (mretcode) *mretcode = 0; - return groups; + // clean up + ldap_msgfree(msg); + + if (mretcode) *mretcode = 0; + return groups; + } + else if (retcode == LDAP_SIZELIMIT_EXCEEDED) { + // Try paged access + bool morePages = false; + unsigned long pageSize = 100; + struct berval cookie = {0, NULL}; + char pagingCriticality = 'T'; + LDAPControl* pageControl = NULL; + LDAPControl* serverControls[2] = { NULL, NULL }; + LDAPControl** returnedControls = NULL; + + do { + retcode = ldap_create_page_control(m_ldap, pageSize, &cookie, pagingCriticality, &pageControl); + if (retcode != LDAP_SUCCESS) { + if (errstr) { + *errstr = i18n("LDAP search failure

Reason: [%3] %4").arg(retcode).arg(ldap_err2string(retcode)); + } + else { + KMessageBox::error(0, i18n("LDAP search failure

Reason: [%3] %4").arg(retcode).arg(ldap_err2string(retcode)), i18n("LDAP Error")); + } + if (mretcode) *mretcode = -1; + return LDAPGroupInfoList(); + } + serverControls[0] = pageControl; + retcode = ldap_search_ext_s(m_ldap, ldap_base_dn.ascii(), LDAP_SCOPE_SUBTREE, ldap_filter.ascii(), ldap_user_and_operational_attributes, 0, serverControls, NULL, NULL, 0, &msg); + if ((retcode != LDAP_SUCCESS) && (retcode != LDAP_PARTIAL_RESULTS)) { + if (errstr) { + *errstr = i18n("LDAP search failure

Reason: [%3] %4").arg(retcode).arg(ldap_err2string(retcode)); + } + else { + KMessageBox::error(0, i18n("LDAP search failure

Reason: [%3] %4").arg(retcode).arg(ldap_err2string(retcode)), i18n("LDAP Error")); + } + if (mretcode) *mretcode = -1; + return LDAPGroupInfoList(); + } + retcode = ldap_parse_result(m_ldap, msg, &errcode, NULL, NULL, NULL, &returnedControls, false); + if (retcode != LDAP_SUCCESS) { + if (errstr) { + *errstr = i18n("LDAP search failure

Reason: [%3] %4").arg(retcode).arg(ldap_err2string(retcode)); + } + else { + KMessageBox::error(0, i18n("LDAP search failure

Reason: [%3] %4").arg(retcode).arg(ldap_err2string(retcode)), i18n("LDAP Error")); + } + if (mretcode) *mretcode = -1; + return LDAPGroupInfoList(); + } + if (cookie.bv_val != NULL) { + ber_memfree(cookie.bv_val); + cookie.bv_val = NULL; + cookie.bv_len = 0; + } + if (!!returnedControls) { + retcode = ldap_parse_pageresponse_control(m_ldap, returnedControls[0], NULL, &cookie); + morePages = (cookie.bv_val && (strlen(cookie.bv_val) > 0)); + } + else { + morePages = false; + } + + if (returnedControls != NULL) { + ldap_controls_free(returnedControls); + returnedControls = NULL; + } + serverControls[0] = NULL; + ldap_control_free(pageControl); + pageControl = NULL; + + // Iterate through the returned entries + LDAPMessage* entry; + for(entry = ldap_first_entry(m_ldap, msg); entry != NULL; entry = ldap_next_entry(m_ldap, entry)) { + groups.append(parseLDAPGroupRecord(entry)); + } + + // clean up + ldap_msgfree(msg); + } while (morePages); + + if (mretcode) *mretcode = 0; + return groups; + } } return LDAPGroupInfoList(); } -LDAPMachineInfoList LDAPManager::machines(int* mretcode) { +LDAPMachineInfoList LDAPManager::machines(int* mretcode, TQString *errstr) { int retcode; + int errcode; LDAPMachineInfoList machines; if (bind() < 0) { @@ -2176,29 +2350,114 @@ LDAPMachineInfoList LDAPManager::machines(int* mretcode) { TQString ldap_base_dn = m_basedc; TQString ldap_filter = "(&(objectClass=krb5Principal)(uid=host/*))"; retcode = ldap_search_ext_s(m_ldap, ldap_base_dn.ascii(), LDAP_SCOPE_SUBTREE, ldap_filter.ascii(), ldap_user_and_operational_attributes, 0, NULL, NULL, NULL, 0, &msg); - if (retcode != LDAP_SUCCESS) { - KMessageBox::error(0, i18n("LDAP search failure

Reason: [%3] %4").arg(retcode).arg(ldap_err2string(retcode)), i18n("LDAP Error")); + if ((retcode != LDAP_SUCCESS) && (retcode != LDAP_SIZELIMIT_EXCEEDED)) { + if (errstr) { + *errstr = i18n("LDAP search failure

Reason: [%3] %4").arg(retcode).arg(ldap_err2string(retcode)); + } + else { + KMessageBox::error(0, i18n("LDAP search failure

Reason: [%3] %4").arg(retcode).arg(ldap_err2string(retcode)), i18n("LDAP Error")); + } if (mretcode) *mretcode = -1; return LDAPMachineInfoList(); } - - // Iterate through the returned entries - LDAPMessage* entry; - for(entry = ldap_first_entry(m_ldap, msg); entry != NULL; entry = ldap_next_entry(m_ldap, entry)) { - machines.append(parseLDAPMachineRecord(entry)); + else if (retcode == LDAP_SUCCESS) { + // Iterate through the returned entries + LDAPMessage* entry; + for(entry = ldap_first_entry(m_ldap, msg); entry != NULL; entry = ldap_next_entry(m_ldap, entry)) { + machines.append(parseLDAPMachineRecord(entry)); + } + + // clean up + ldap_msgfree(msg); + + if (mretcode) *mretcode = 0; + return machines; + } + else if (retcode == LDAP_SIZELIMIT_EXCEEDED) { + // Try paged access + bool morePages = false; + unsigned long pageSize = 100; + struct berval cookie = {0, NULL}; + char pagingCriticality = 'T'; + LDAPControl* pageControl = NULL; + LDAPControl* serverControls[2] = { NULL, NULL }; + LDAPControl** returnedControls = NULL; + + do { + retcode = ldap_create_page_control(m_ldap, pageSize, &cookie, pagingCriticality, &pageControl); + if (retcode != LDAP_SUCCESS) { + if (errstr) { + *errstr = i18n("LDAP search failure

Reason: [%3] %4").arg(retcode).arg(ldap_err2string(retcode)); + } + else { + KMessageBox::error(0, i18n("LDAP search failure

Reason: [%3] %4").arg(retcode).arg(ldap_err2string(retcode)), i18n("LDAP Error")); + } + if (mretcode) *mretcode = -1; + return LDAPMachineInfoList(); + } + serverControls[0] = pageControl; + retcode = ldap_search_ext_s(m_ldap, ldap_base_dn.ascii(), LDAP_SCOPE_SUBTREE, ldap_filter.ascii(), ldap_user_and_operational_attributes, 0, serverControls, NULL, NULL, 0, &msg); + if ((retcode != LDAP_SUCCESS) && (retcode != LDAP_PARTIAL_RESULTS)) { + if (errstr) { + *errstr = i18n("LDAP search failure

Reason: [%3] %4").arg(retcode).arg(ldap_err2string(retcode)); + } + else { + KMessageBox::error(0, i18n("LDAP search failure

Reason: [%3] %4").arg(retcode).arg(ldap_err2string(retcode)), i18n("LDAP Error")); + } + if (mretcode) *mretcode = -1; + return LDAPMachineInfoList(); + } + retcode = ldap_parse_result(m_ldap, msg, &errcode, NULL, NULL, NULL, &returnedControls, false); + if (retcode != LDAP_SUCCESS) { + if (errstr) { + *errstr = i18n("LDAP search failure

Reason: [%3] %4").arg(retcode).arg(ldap_err2string(retcode)); + } + else { + KMessageBox::error(0, i18n("LDAP search failure

Reason: [%3] %4").arg(retcode).arg(ldap_err2string(retcode)), i18n("LDAP Error")); + } + if (mretcode) *mretcode = -1; + return LDAPMachineInfoList(); + } + if (cookie.bv_val != NULL) { + ber_memfree(cookie.bv_val); + cookie.bv_val = NULL; + cookie.bv_len = 0; + } + if (!!returnedControls) { + retcode = ldap_parse_pageresponse_control(m_ldap, returnedControls[0], NULL, &cookie); + morePages = (cookie.bv_val && (strlen(cookie.bv_val) > 0)); + } + else { + morePages = false; + } + + if (returnedControls != NULL) { + ldap_controls_free(returnedControls); + returnedControls = NULL; + } + serverControls[0] = NULL; + ldap_control_free(pageControl); + pageControl = NULL; + + // Iterate through the returned entries + LDAPMessage* entry; + for(entry = ldap_first_entry(m_ldap, msg); entry != NULL; entry = ldap_next_entry(m_ldap, entry)) { + machines.append(parseLDAPMachineRecord(entry)); + } + + // clean up + ldap_msgfree(msg); + } while (morePages); + + if (mretcode) *mretcode = 0; + return machines; } - - // clean up - ldap_msgfree(msg); - - if (mretcode) *mretcode = 0; - return machines; } return LDAPMachineInfoList(); } -LDAPServiceInfoList LDAPManager::services(int* mretcode) { +LDAPServiceInfoList LDAPManager::services(int* mretcode, TQString *errstr) { LDAPServiceInfoList services; if (bind() < 0) { @@ -2207,7 +2466,7 @@ LDAPServiceInfoList LDAPManager::services(int* mretcode) { } else { int machineSearchRet; - LDAPMachineInfoList machineList = machines(&machineSearchRet); + LDAPMachineInfoList machineList = machines(&machineSearchRet, errstr); if (machineSearchRet != 0) { if (mretcode) *mretcode = -1; return LDAPServiceInfoList(); @@ -3529,7 +3788,7 @@ KerberosTicketInfo::~KerberosTicketInfo() { LDAPPamConfig::LDAPPamConfig() { enable_cached_credentials = true; autocreate_user_directories_enable = true; - autocreate_user_directories_umask; + autocreate_user_directories_umask = 0; } LDAPPamConfig::~LDAPPamConfig() { diff --git a/src/libtdeldap.h b/src/libtdeldap.h index e67bca5..2c73967 100644 --- a/src/libtdeldap.h +++ b/src/libtdeldap.h @@ -417,11 +417,11 @@ class LDAPManager : public TQObject { TQString basedn(); int bind(TQString* errstr=0); int unbind(bool force, TQString* errstr=0); - LDAPUserInfoList users(int* retcode=0); - LDAPGroupInfoList groups(int* retcode=0); - LDAPMachineInfoList machines(int* retcode=0); + LDAPUserInfoList users(int* retcode=0, TQString *errstr=0); + LDAPGroupInfoList groups(int* retcode=0, TQString *errstr=0); + LDAPMachineInfoList machines(int* retcode=0, TQString *errstr=0); LDAPServiceInfoList machineServices(TQString machine_dn, int* retcode=0); - LDAPServiceInfoList services(int* retcode=0); + LDAPServiceInfoList services(int* retcode=0, TQString *errstr=0); LDAPUserInfo getUserByDistinguishedName(TQString dn); LDAPGroupInfo getGroupByDistinguishedName(TQString dn, TQString *errstr=0);