Hi All,
I am using ldap_search_ext_s C API and having strange results, not sure if I am missing something or its an API bug:
My Directory Tree looks like this:
| -- dc=example,dc=com | ------ ou=users,dc=example,dc=com | ---------- uid=1,ou=users,dc=example,dc=com | --------------- cn=john | ------ ou=departments,dc=example,dc=com | ---------- uid=11,ou=departments,dc=example,dc=com | --------------- cn=hr | --------------- member=uid=1 | ---------- uid=12,ou=departments,dc=example,dc=com | --------------- cn=sales | --------------- member=uid=1 | ---------- uid=13,ou=departments,dc=example,dc=com | --------------- cn=marketing | --------------- member=uid=1
First I get all the departments for "john" by using *memberof* in sarch attribute. for this query my search filter contains only one criteria ("uid=1") Then I construct another search filter for getting names of all the departments john belongs to : (|(uid=11)(uid=12)(uid=13)) I pass this filter to ldap_search_ext_s, where base is "ou=departments,dc=example,dc=com", scope is one level down, and I want "cn" in the attribute
LDAPMessage* output; int retCode = ldap_search_ext_s(ld,base.c_str(), scope,filter.c_str(),attrs,false,NULL,NULL,NULL,0,&output); if(retCode == LDAP_SUCCESS){ //log success //send result to a static method for parsing LDAPUtil::parseResult(ld,output,result); ldap_msgfree(output); }else{ //log error & throw exception }
LDAPUtil parse result implementation
void LDAPUtil::parseResult(LDAP* ld, LDAPMessage* ldapResponse, LDAPSearchResult* parsedResult){
int numEntries = ldap_count_entries(ld,ldapResponse); cout << "number of entries" << numEntries << endl;* // I get 3 here* if(numEntries > 0){ //parse result LDAPMessage * entry; BerElement * ber; char * attr; BerVarray* vals ; map<string,LDAPAttribute*> attributeValueMap ; int count = 0; * //If I don't use count < numEntries this loop becomes an infinite loop, this loop runs 3 times, however the dn value output is:* *// run 1 :: dn: uid=11,ou=departments,dc=examples,dc=com //run 2 :: dn: uid=12,ou=departments,dc=examples,dc=com // run 3 :: dn: uid=12,ou=departments,dc=examples,dc=com*
for ( entry = ldap_first_entry(ld,ldapResponse);entry != NULL && count < numEntries; entry = ldap_next_entry(ld,ldapResponse)){ count++;
//create LDAP Attributes LDAPAttribute* attribute = new LDAPAttribute(); //set DN attribute->setDn(ldap_get_dn(ld,entry)); cout << "dn is " << ldap_get_dn(ld,entry) <<endl;
for(attr = ldap_first_attribute(ld,entry,&ber); attr != NULL; attr=ldap_next_attribute(ld,entry,ber)) { string temp = attr; cout << "attribute :: " << attr << endl; vals = ldap_get_values_len(ld,entry,attr); if((ldap_count_values_len(vals))> 0 ){ LDAPUtil::processAttribute(attribute,temp,vals); } ldap_value_free_len(vals); }
attributeValueMap.insert(pair<string,LDAPAttribute*>(attribute->getDn(),attribute)); } parsedResult->setAttributeValueMap(attributeValueMap); } }
Basically above code is working only if I have one entry returned in the output. I would really appreciate if someone can help me with this. As I have hard time beliving its an API bug since I am just doing basic operation.
Thanks, - Simon
On Thu, Apr 21, 2011 at 10:36 AM, sim123 Sim3159@gmail.com wrote:
Hi All,
I am using ldap_search_ext_s C API and having strange results, not sure if I am missing something or its an API bug:
My Directory Tree looks like this:
| -- dc=example,dc=com | ------ ou=users,dc=example,dc=com | ---------- uid=1,ou=users,dc=example,dc=com | --------------- cn=john | ------ ou=departments,dc=example,dc=com | ---------- uid=11,ou=departments,dc=example,dc=com | --------------- cn=hr | --------------- member=uid=1 | ---------- uid=12,ou=departments,dc=example,dc=com | --------------- cn=sales | --------------- member=uid=1 | ---------- uid=13,ou=departments,dc=example,dc=com | --------------- cn=marketing | --------------- member=uid=1
First I get all the departments for "john" by using *memberof* in sarch attribute. for this query my search filter contains only one criteria ("uid=1") Then I construct another search filter for getting names of all the departments john belongs to : (|(uid=11)(uid=12)(uid=13)) I pass this filter to ldap_search_ext_s, where base is "ou=departments,dc=example,dc=com", scope is one level down, and I want "cn" in the attribute
LDAPMessage* output; int retCode = ldap_search_ext_s(ld,base.c_str(), scope,filter.c_str(),attrs,false,NULL,NULL,NULL,0,&output); if(retCode == LDAP_SUCCESS){ //log success //send result to a static method for parsing LDAPUtil::parseResult(ld,output,result); ldap_msgfree(output); }else{ //log error & throw exception }
LDAPUtil parse result implementation
void LDAPUtil::parseResult(LDAP* ld, LDAPMessage* ldapResponse, LDAPSearchResult* parsedResult){
int numEntries = ldap_count_entries(ld,ldapResponse); cout << "number of entries" << numEntries << endl;* // I get 3 here* if(numEntries > 0){ //parse result LDAPMessage * entry; BerElement * ber; char * attr; BerVarray* vals ; map<string,LDAPAttribute*> attributeValueMap ; int count = 0; * //If I don't use count < numEntries this loop becomes an infinite
loop, this loop runs 3 times, however the dn value output is:* *// run 1 :: dn: uid=11,ou=departments,dc=examples,dc=com //run 2 :: dn: uid=12,ou=departments,dc=examples,dc=com // run 3 :: dn: uid=12,ou=departments,dc=examples,dc=com*
for ( entry = ldap_first_entry(ld,ldapResponse);entry != NULL &&
count < numEntries; entry = ldap_next_entry(ld,ldapResponse)){ count++;
//create LDAP Attributes LDAPAttribute* attribute = new LDAPAttribute(); //set DN attribute->setDn(ldap_get_dn(ld,entry)); cout << "dn is " << ldap_get_dn(ld,entry) <<endl; for(attr = ldap_first_attribute(ld,entry,&ber); attr != NULL;
attr=ldap_next_attribute(ld,entry,ber)) { string temp = attr; cout << "attribute :: " << attr << endl; vals = ldap_get_values_len(ld,entry,attr); if((ldap_count_values_len(vals))> 0 ){ LDAPUtil::processAttribute(attribute,temp,vals); } ldap_value_free_len(vals); }
attributeValueMap.insert(pair<string,LDAPAttribute*>(attribute->getDn(),attribute)); } parsedResult->setAttributeValueMap(attributeValueMap); } }
Basically above code is working only if I have one entry returned in the output. I would really appreciate if someone can help me with this. As I have hard time beliving its an API bug since I am just doing basic operation.
Thanks,
- Simon
I guess I was right, it my code who had bug not the API :) I need to do this :
for ( entry = ldap_first_entry(ld,ldapResponse);entry != NULL && count < numEntries; * entry = ldap_next_entry(ld,entry)*)
instead of
for ( entry = ldap_first_entry(ld,ldapResponse);entry != NULL && count < numEntries; * entry = ldap_next_entry(ld,ldapResponse))
*thanks for the help. * *
openldap-technical@openldap.org