Jean-Marc Choulet wrote:
Hello,
I have a little with this very simple program :
#include <iostream> #include <stdlib.h> #define LDAP_DEPRECATED 1 #include <ldap.h>
using namespace std;
const char* server = "ldap://ldap.xxxx.fr"; const char* cacert_file = "cacert.pem"; const char* root_dn = "cn=replicator,ou=DSA,dc=xxxx,dc=fr"; const char* root_pw = "xxxx"; const char* aliased_people_dn ="ou=AliasedPeople,dc=xxxx,dc=fr";
int main(int argc, char *argv[]) { if (argc != 3) { cerr << "Usage: " << argv[0] << " username password" << endl; return 1; }
LDAP *ld; int version = LDAP_VERSION3; int rc; if ((rc = ldap_initialize(&ld, server)) != LDAP_SUCCESS) { cerr << "ldap_initialize: " << server << endl; return EXIT_FAILURE; } if ((rc = ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &version))
!= LDAP_OPT_SUCCESS) { cerr << "ldap_set_option error: " << ldap_err2string(rc) << endl; return EXIT_FAILURE; }
if ((rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_CACERTFILE,
cacert_file)) != LDAP_OPT_SUCCESS ) { cerr << "ldap_set_option error: " << ldap_err2string(rc) << endl; return EXIT_FAILURE; }
if ((rc = ldap_start_tls_s(ld, NULL, NULL)) != LDAP_SUCCESS) { cerr << "ldap_start_tls_s error: " << ldap_err2string(rc) << endl; return EXIT_FAILURE; } if ((rc = ldap_bind_s(ld, root_dn, root_pw, LDAP_AUTH_SIMPLE)) !=
LDAP_SUCCESS) { cerr << "ldap_bind_s: " << ldap_err2string(rc) << endl; return EXIT_FAILURE; }
cout << "user replicator authenticated :)." << endl; LDAPMessage *pResult; struct berval cred; char *pDN; std::string filter("uid=" + string(argv[1])); rc = ldap_search_ext_s(ld, aliased_people_dn, LDAP_SCOPE_SUBTREE, filter.c_str(), NULL, 0, NULL, NULL, NULL, LDAP_NO_LIMIT, &pResult); if (rc != LDAP_SUCCESS) { cerr << "ldap_search_ext_s error: " << ldap_err2string(rc) <<
endl; ldap_unbind_s(ld); return EXIT_FAILURE; }
struct berval **vals; LDAPMessage *pEntry; string user_dn; if (ldap_count_entries(ld, pResult) == 1) { pEntry = ldap_first_entry(ld, pResult); pDN = ldap_get_dn(ld, pEntry); vals = ldap_get_values_len(ld, pEntry, "aliasedObjectName"); if (vals) { user_dn = vals[0]->bv_val; ldap_value_free_len(vals); } ldap_memfree(pDN); } else { cout << "aliasedObjectName attribute not found" << endl; ldap_unbind_s(ld); return EXIT_FAILURE; } ldap_memfree(pResult); if ((rc = ldap_bind_s(ld, user_dn.c_str(), argv[2],
LDAP_AUTH_SIMPLE)) != LDAP_SUCCESS) { cerr << "user " << argv[1] << " not authenticated" << endl; ldap_unbind_s(ld); return EXIT_FAILURE; }
cout << "user " << argv[1] << " (" << user_dn << ") authenticated"
<< endl;
ldap_unbind_s(ld); return EXIT_SUCCESS;
}
My program works fine but, if I use valgrind, I have memory leaks :
Read the ldap_result(3) manpage again. You're supposed to use ldap_msgfree() on the result, not ldap_memfree().
==13616== LEAK SUMMARY: ==13616== definitely lost: 136 bytes in 2 blocks ==13616== indirectly lost: 284 bytes in 3 blocks ==13616== possibly lost: 0 bytes in 0 blocks ==13616== still reachable: 260,033 bytes in 1,152 blocks ==13616== suppressed: 0 bytes in 0 blocks ==13616== Reachable blocks (those to which a pointer was found) are not shown. ==13616== To see them, rerun with: --leak-check=full --show-leak-kinds=all ==13616== ==13616== For counts of detected and suppressed errors, rerun with: -v ==13616== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
I don't understand why. Do you have a idea ?
I work on Ubuntu 14.04. The OpenLDAP version is 2.4.31.
Thanks,
Jean-Marc.