We encountered a back-ldap assertion failure with the back-ldap as a proxy to a 
remote Active Directory on Windows 2003 R2. The assertion failure occurred when 
the slapd  server was checking ACLs via the rwm overlay. Snippet of the stack 
trace:

Thread 1 (Thread 32267):
....
#2  0x0000003c354296e6 in __assert_fail () from /lib64/libc.so.6
#3  0x00002ac57daaf6c1 in ldap_back_dobind_int (lcp=0x42f70170, op=0x42f702f0, 
    rs=0x42f700a0, sendok=LDAP_BACK_GETCONN, retries=0, dolock=1)
    at 
/home/build/sol-2.4.23.101221/sol24x/ldap24/servers/slapd/back-ldap/bind.c:1389
#4  0x00002ac57daafda0 in ldap_back_dobind (lcp=0x42f70170, op=0x42f702f0, 
    rs=0x42f700a0, sendok=LDAP_BACK_DONTSEND)
    at 
/home/build/sol-2.4.23.101221/sol24x/ldap24/servers/slapd/back-ldap/bind.c:1572
#5  0x00002ac57daac7a7 in ldap_back_entry_get (op=0x42f702f0, ndn=0x42f701d0, 
    oc=0x0, at=0x135ad370, rw=0, ent=0x42f70a58)

Analysis of the assertion failure:

The ldap_back_entry_get() function, back-ldap/search.c, is called for ACL 
entries, via rwm overlay. The function sets op->o_do_not_cache to 1 before 
calling into ldap_back_dobind():

        /* Tell getconn this is a privileged op */
        do_not_cache = op->o_do_not_cache;
        tag = op->o_tag;
        /* do not cache */
        op->o_do_not_cache = 1;
        /* ldap_back_entry_get() is an entry lookup, so it does not need
         * to know what the entry is being looked up for */
        op->o_tag = LDAP_REQ_SEARCH;
        rc = ldap_back_dobind( &lc, op, &rs, LDAP_BACK_DONTSEND ); 


The ldap_back_dobind() function calls ldap_back_dobind_int() for bind, 
back-ldap/bind.c. The following ldap_back_dobind_int() code is destined for 
assertion failure, if op->o_do_not_cache flag is set and there is no valid 
binddn and bindcred returned by ldap_back_getconn(). Setting an invalid LDAP 
URI for the remote AD Windows box is such a case.

        ldap_back_dobind_int(…)
        {
                ...
                if (sendok & LDAP_BACK_GETCONN) {
                …
                        lc = ldap_back_getconn(op, rs, sendoff, &binddn, 
&bindcred);
                        ...
                }
                …

                if ( LDAP_BACK_CONN_ISIDASSERT( lc ) ) {
                        if ( BER_BVISEMPTY( &binddn ) && BER_BVISEMPTY( 
&bindcred ) ) {
                                /* if we got here, it shouldn't return result */
                                rc = ldap_back_is_proxy_authz( op, rs,
                                                LDAP_BACK_DONTSEND, &binddn, 
&bindcred );

                                /* ldap_back_is_proxy_authz always returns 0 
when op->o_do_not_cache is set, see below */
                                assert( rc == 1 );------> assertion failure
                        }
                        rc = ldap_back_proxy_authz_bind( lc, op, rs, sendok,
                                &binddn, &bindcred );
                        …
                }
        }
 

When the op->o_do_not_cache flag is set, the ldap_back_is_proxy_authz() 
function always returns 0.

        ldap_back_is_proxy_authz( ... )
        {
                ...
                int             dobind = 0;

                if ( op->o_conn == NULL || op->o_do_not_cache ) {
                        goto done;
                }
                ...
        done:;
                return dobind; <--- always returns 0
        }



Ted C. Cheng
Symas Corporation

Reply via email to