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

Re: bind fallback



On Mon, 28 Aug 2006 07:35:03 +0200 (CEST)
"Pierangelo Masarati" <ando@sys-net.it> wrote:

> > If I call ldap_sasl_interactive_bind_s and it fails (e.g. because of a
> > bug [1]) and then call ldap_simple_bind_s as a fallback it hangs. If I
> > ldap_init again before calling ldap_simple_bind_s the fallback works. Is
> > this expected behavior
> 
> no
> 
> > or is the bind state not being reset properly?
> 
> could be.
> 
> > I'm
> > using 2.2.29 on Fedora Core 3.
> 
> You should upgrade to the latest 2.3 (2.3.27 currently) as the client
> library saw significant improvements, while 2.2 is historic.

Well I need to use what people have and near as I can tell Red Hat EL
4 shipped 2.2.

> > Also, should I deinitialize the LDAP object? I see nothing in the
> > documentation about an ldap_deinit or similar.
> 
> It's called ldap_unbind_ext(3) (used to be ldap_unbind(3), now
> deprecated), and it's intended to be the opposite of ldap_initialize(3)
> (formerly, ldap_init(3), now deprecated).  The name might sound
> misleading; it comes from draft-ietf-ldapext-ldap-c-api.

Funny the latest draft-ietf-ldapext-ldap-c-api-xxx.txt from webcvs has
no mention of ldap_initialize(3). Is this really portable? Are these
functions ok to use with 2.2?

> > If not, how is that not
> > a resource leak?
> 
> It is, unless you call ldap_unbind_ext(3).

Using ldap_initialize/ldap_unbind_ext I still see some leaks with
openldap-2.2 + cyrus-sasl-2.1.19.

With Fedora Core's 2.2.29-1.FC3 + ldap_sasl_interactive_bind_s failure +
successful ldap_simple_bind_s as a fallback it looks like there are 2
leaks [1]. Calling ldap_unbind_ext before trying the ldap_simple_bind_s
has no effect.

With CentOS 4's 2.2.13-4 + successful ldap_sasl_interactive_bind_s there
appears to be a few more.

One of the leaks is the strdup in my sasl_interact routine. I'll have to
look at cyrus sasl docs and determine what the proper method for freeing
that is. The others look like cyrus sasl could also be responsible
(man I get a bad vibe from that code).

The program otherwise retrieves the expect results and completes without
error.

The valgrind command I'm using is:

  valgrind --tool=memcheck --leak-check=yes --num-callers=10 ./theprogram

Note you may speculate that some of this is global data being reused
(e.g. krb5 ccache stuff) but if I add a loop, the number of bytes leaked
is multipled by the number of loops exactly.

I'll list the important part of my code below [3].

Mike

[1] valgrind report for Fedore Core 2.2.29-1.FC3 + fallback from
    ldap_sasl_interactive_bind_s to ldap_simple_bind_s:

==13014== 0 bytes in 1 blocks are definitely lost in loss record 1 of 45
==13014==    at 0x1B90640D: calloc (vg_replace_malloc.c:176)
==13014==    by 0xBAA419: (within /usr/lib/libkrb5.so.3.2)
==13014==    by 0xB5D700: kg_get_context (in /usr/lib/libgssapi_krb5.so.2.2)
==13014==    by 0xB5D955: krb5_gss_import_name (in /usr/lib/libgssapi_krb5.so.2.2)
==13014==    by 0xB62642: gss_import_name (in /usr/lib/libgssapi_krb5.so.2.2)
==13014==    by 0x1B9114CB: (within /usr/lib/sasl2/libgssapiv2.so.2.0.19)
==13014==    by 0x34BBCD: sasl_client_step (in /usr/lib/libsasl2.so.2.0.19)
==13014==    by 0x34C098: sasl_client_start (in /usr/lib/libsasl2.so.2.0.19)
==13014==    by 0x369C6E: ldap_int_sasl_bind (in /usr/lib/libldap-2.2.so.7.0.22)
==13014==    by 0x36C6B4: ldap_sasl_interactive_bind_s (in /usr/lib/libldap-2.2.so.7.0.22)
==13014== 
==13014== 
==13014== 1 bytes in 1 blocks are definitely lost in loss record 2 of 45
==13014==    at 0x1B905A90: malloc (vg_replace_malloc.c:131)
==13014==    by 0x255B9F: strdup (in /lib/tls/libc-2.3.6.so)
==13014==    by 0x80497E2: sasl_interact (pldapsearch.c:23)
==13014==    by 0x369C26: ldap_int_sasl_bind (in /usr/lib/libldap-2.2.so.7.0.22)
==13014==    by 0x36C6B4: ldap_sasl_interactive_bind_s (in /usr/lib/libldap-2.2.so.7.0.22)
==13014==    by 0x8049C28: run (pldapsearch.c:130)
==13014==    by 0x804A28A: main (pldapsearch.c:269)
==13014== 
==13014== 
==13014== 5 bytes in 1 blocks are definitely lost in loss record 3 of 45
==13014==    at 0x1B905A90: malloc (vg_replace_malloc.c:131)
==13014==    by 0xB990CA: krb5_cc_resolve (in /usr/lib/libkrb5.so.3.2)
==13014==    by 0xB993EC: krb5_cc_default (in /usr/lib/libkrb5.so.3.2)
==13014==    by 0xB9942E: krb5int_cc_default (in /usr/lib/libkrb5.so.3.2)
==13014==    by 0xB5BA5A: krb5_gss_acquire_cred (in /usr/lib/libgssapi_krb5.so.2.2)
==13014==    by 0xB5D6A4: kg_get_defcred (in /usr/lib/libgssapi_krb5.so.2.2)
==13014==    by 0xB5E39B: krb5_gss_init_sec_context (in /usr/lib/libgssapi_krb5.so.2.2)
==13014==    by 0xB62714: gss_init_sec_context (in /usr/lib/libgssapi_krb5.so.2.2)
==13014==    by 0x1B910F39: (within /usr/lib/sasl2/libgssapiv2.so.2.0.19)
==13014==    by 0x34BBCD: sasl_client_step (in /usr/lib/libsasl2.so.2.0.19)
==13014== 
==13014== LEAK SUMMARY:
==13014==    definitely lost: 6 bytes in 3 blocks.
==13014==    possibly lost:   0 bytes in 0 blocks.
==13014==    still reachable: 78745 bytes in 159 blocks.
==13014==         suppressed: 0 bytes in 0 blocks.

[2] valgrind report for CentOS 4's 2.2.13-4 with successfull
    ldap_sasl_interactive_bind_s:

==31317== 0 bytes in 1 blocks are definitely lost in loss record 1 of 44
==31317==    at 0x1B905301: calloc (vg_replace_malloc.c:176)
==31317==    by 0x642449: (within /usr/lib/libkrb5.so.3.2)
==31317==    by 0x50A700: kg_get_context (in /usr/lib/libgssapi_krb5.so.2.2)
==31317==    by 0x50A955: krb5_gss_import_name (in /usr/lib/libgssapi_krb5.so.2.2)
==31317==    by 0x50F642: gss_import_name (in /usr/lib/libgssapi_krb5.so.2.2)
==31317==    by 0x1BD304CB: (within /usr/lib/sasl2/libgssapiv2.so.2.0.19)
==31317==    by 0x3AEBED: sasl_client_step (in /usr/lib/libsasl2.so.2.0.19)
==31317==    by 0x3AF0B8: sasl_client_start (in /usr/lib/libsasl2.so.2.0.19)
==31317==    by 0x491B69: ldap_int_sasl_bind (in /usr/lib/libldap-2.2.so.7.0.6)
==31317==    by 0x494534: ldap_sasl_interactive_bind_s (in /usr/lib/libldap-2.2.so.7.0.6)
==31317== 
==31317== 
==31317== 1 bytes in 1 blocks are definitely lost in loss record 2 of 44
==31317==    at 0x1B904984: malloc (vg_replace_malloc.c:131)
==31317==    by 0x2DECCF: strdup (in /lib/tls/libc-2.3.4.so)
==31317==    by 0x80497E2: sasl_interact (pldapsearch.c:23)
==31317==    by 0x491B21: ldap_int_sasl_bind (in /usr/lib/libldap-2.2.so.7.0.6)
==31317==    by 0x494534: ldap_sasl_interactive_bind_s (in /usr/lib/libldap-2.2.so.7.0.6)
==31317==    by 0x8049C1E: run (pldapsearch.c:128)
==31317==    by 0x804A2C7: main (pldapsearch.c:267)
==31317== 
==31317== 
==31317== 8 bytes in 1 blocks are definitely lost in loss record 3 of 44
==31317==    at 0x1B904984: malloc (vg_replace_malloc.c:131)
==31317==    by 0x3C5569: ber_memalloc_x (in /usr/lib/liblber-2.2.so.7.0.6)
==31317==    by 0x3C150A: ber_get_stringal (in /usr/lib/liblber-2.2.so.7.0.6)
==31317==    by 0x3C1A21: ber_scanf (in /usr/lib/liblber-2.2.so.7.0.6)
==31317==    by 0x4940F2: ldap_parse_sasl_bind_result (in /usr/lib/libldap-2.2.so.7.0.6)
==31317==    by 0x494293: ldap_sasl_bind_s (in /usr/lib/libldap-2.2.so.7.0.6)
==31317==    by 0x491C5F: ldap_int_sasl_bind (in /usr/lib/libldap-2.2.so.7.0.6)
==31317==    by 0x494534: ldap_sasl_interactive_bind_s (in /usr/lib/libldap-2.2.so.7.0.6)
==31317==    by 0x8049C1E: run (pldapsearch.c:128)
==31317==    by 0x804A2C7: main (pldapsearch.c:267)
==31317== 
==31317== 
==31317== 10 bytes in 2 blocks are definitely lost in loss record 5 of 44
==31317==    at 0x1B904984: malloc (vg_replace_malloc.c:131)
==31317==    by 0x6310CA: krb5_cc_resolve (in /usr/lib/libkrb5.so.3.2)
==31317==    by 0x6313F4: krb5_cc_default (in /usr/lib/libkrb5.so.3.2)
==31317==    by 0x631468: krb5int_cc_default (in /usr/lib/libkrb5.so.3.2)
==31317==    by 0x508A5A: krb5_gss_acquire_cred (in /usr/lib/libgssapi_krb5.so.2.2)
==31317==    by 0x50A6A4: kg_get_defcred (in /usr/lib/libgssapi_krb5.so.2.2)
==31317==    by 0x50B39B: krb5_gss_init_sec_context (in /usr/lib/libgssapi_krb5.so.2.2)
==31317==    by 0x50F714: gss_init_sec_context (in /usr/lib/libgssapi_krb5.so.2.2)
==31317==    by 0x1BD2FF39: (within /usr/lib/sasl2/libgssapiv2.so.2.0.19)
==31317==    by 0x3AEBED: sasl_client_step (in /usr/lib/libsasl2.so.2.0.19)
==31317== 
==31317== 
==31317== 24 bytes in 1 blocks are definitely lost in loss record 9 of 44
==31317==    at 0x1B904984: malloc (vg_replace_malloc.c:131)
==31317==    by 0x50B0A2: (within /usr/lib/libgssapi_krb5.so.2.2)
==31317==    by 0x6453FB: krb5_mk_req_extended (in /usr/lib/libkrb5.so.3.2)
==31317==    by 0x50C168: krb5_gss_init_sec_context (in /usr/lib/libgssapi_krb5.so.2.2)
==31317==    by 0x50F714: gss_init_sec_context (in /usr/lib/libgssapi_krb5.so.2.2)
==31317==    by 0x1BD2FF39: (within /usr/lib/sasl2/libgssapiv2.so.2.0.19)
==31317==    by 0x3AEBED: sasl_client_step (in /usr/lib/libsasl2.so.2.0.19)
==31317==    by 0x3AF0B8: sasl_client_start (in /usr/lib/libsasl2.so.2.0.19)
==31317==    by 0x491B69: ldap_int_sasl_bind (in /usr/lib/libldap-2.2.so.7.0.6)
==31317==    by 0x494534: ldap_sasl_interactive_bind_s (in /usr/lib/libldap-2.2.so.7.0.6)
==31317== 
==31317== LEAK SUMMARY:
==31317==    definitely lost: 43 bytes in 6 blocks.
==31317==    possibly lost:   0 bytes in 0 blocks.
==31317==    still reachable: 78125 bytes in 128 blocks.
==31317==         suppressed: 0 bytes in 0 blocks.

[3] Code used:

static int
sasl_interact(LDAP *ldap, unsigned flags, void *defaults, void *in)
{
    sasl_interact_t *interact = in;

    while (interact->id != SASL_CB_LIST_END) {
        const char *dflt = interact->defresult;

        interact->result = strdup((dflt && *dflt) ? dflt : "");
        interact->len = interact->result ? strlen(interact->result) : 0;
        interact++;
    };

    (void)ldap;
    (void)flags;
    (void)defaults;
    return LDAP_SUCCESS;
}
int
run(const unsigned char *url)
{
    unsigned char buf[1024], *bp = buf, *blim = buf + sizeof(buf);
    LDAPURLDesc *lud;
    LDAP *ldap;
    int ret;

    ret = ldap_url_parse(url, &lud);
    if (ret) { 
        PMSG("ldap_url_parse: %s", ldap_err2string(ret));
        return -1;
    }

    str_sprintf(&bp, blim, "%s://%s", lud->lud_scheme, lud->lud_host);
    if (lud->lud_port != LDAP_PORT) {
        str_sprintf(&bp, blim, ":%d", lud->lud_port);
    }

    ret = ldap_initialize(&ldap, buf);
    if (ret != 0) { 
        PMSG("ldap_initialize: %s", ldap_err2string(ret));
        ldap_free_urldesc(lud);
        return -1;
    }
    if (ret == 0) { 
        int v3 = LDAP_VERSION3;

        if (ldap_set_option(ldap, LDAP_OPT_REFERRALS, LDAP_OPT_OFF) != LDAP_SUCCESS ||
                    ldap_set_option(ldap, LDAP_OPT_PROTOCOL_VERSION, &v3) != LDAP_SUCCESS){
            PMSG("");
            ldap_unbind_ext(ldap, NULL, NULL);
            ldap_free_urldesc(lud);
            return -1;
        }

        ret = ldap_sasl_interactive_bind_s(ldap,
                    NULL,
                    NULL,
                    NULL,
                    NULL,
                    LDAP_SASL_QUIET,
                    sasl_interact,
                    NULL);
        if (ret) { 
            MMSG(2, "ldap_sasl_interactive_bind: %s", ldap_err2string(ret));
            ldap_unbind_ext(ldap, NULL, NULL);
            ret = ldap_simple_bind_s(ldap, "administrator@WIN.NET", "bogus");
            if (ret) { 
                PMSG("ldap_simple_bind_s: %s", ldap_err2string(ret));
                ldap_free_urldesc(lud);
            	ldap_unbind_ext(ldap, NULL, NULL);
                return -1;
            }       
        }

        if (ret == 0) { 
            LDAPMessage *entries ...