[Date Prev][Date Next] [Chronological] [Thread] [Top]

Re: Question about ldap_search_ext_s and memory leak



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.




--
  -- Howard Chu
  CTO, Symas Corp.           http://www.symas.com
  Director, Highland Sun     http://highlandsun.com/hyc/
  Chief Architect, OpenLDAP  http://www.openldap.org/project/