]> git.sur5r.net Git - openldap/blobdiff - libraries/libldap/request.c
ITS#889: quick fix
[openldap] / libraries / libldap / request.c
index 033914e899e86bc9e5069a2c1fe3daf4da1e4130..d174308191c5416df3ff65a15d0faab9d6d6d342 100644 (file)
@@ -236,7 +236,7 @@ ldap_new_connection( LDAP *ld, LDAPURLDesc *srvlist, int use_ldsb,
 {
        LDAPConn        *lc;
        LDAPURLDesc     *srv;
-       Sockbuf         *sb;
+       Sockbuf         *sb = NULL;
 
        Debug( LDAP_DEBUG_TRACE, "ldap_new_connection\n", 0, 0, 0 );
        /*
@@ -256,9 +256,7 @@ ldap_new_connection( LDAP *ld, LDAPURLDesc *srvlist, int use_ldsb,
 
        if ( connect ) {
                for ( srv = srvlist; srv != NULL; srv = srv->lud_next ) {
-                       if ( open_ldap_connection( ld, lc->lconn_sb,
-                                       srv, &lc->lconn_krbinstance, 0 ) != -1 )
-                       {
+                       if ( ldap_int_open_connection( ld, lc, srv, 0 ) != -1 ) {
                                break;
                        }
                }
@@ -353,10 +351,11 @@ find_connection( LDAP *ld, LDAPURLDesc *srv, int any )
        for ( lc = ld->ld_conns; lc != NULL; lc = lc->lconn_next ) {
                for ( ls = srv; ls != NULL; ls = ls->lud_next ) {
                        if ( lc->lconn_server->lud_host != NULL &&
-                           ls->lud_host != NULL && strcasecmp(
-                           ls->lud_host, lc->lconn_server->lud_host ) == 0
+                               *lc->lconn_server->lud_host != '\0' &&
+                           ls->lud_host != NULL && *ls->lud_host != '\0' &&
+                               strcasecmp( ls->lud_host, lc->lconn_server->lud_host ) == 0
                            && ls->lud_port == lc->lconn_server->lud_port ) {
-                               return( lc );
+                               return lc;
                        }
                        if ( !any ) {
                                break;
@@ -364,7 +363,7 @@ find_connection( LDAP *ld, LDAPURLDesc *srv, int any )
                }
        }
 
-       return( NULL );
+       return NULL;
 }
 
 
@@ -396,6 +395,8 @@ ldap_free_connection( LDAP *ld, LDAPConn *lc, int force, int unbind )
                        ber_free( lc->lconn_ber, 1 );
                }
 
+               ldap_int_sasl_close( ld, lc );
+
                prevlc = NULL;
                for ( tmplc = ld->ld_conns; tmplc != NULL;
                    tmplc = tmplc->lconn_next ) {
@@ -410,9 +411,11 @@ ldap_free_connection( LDAP *ld, LDAPConn *lc, int force, int unbind )
                        prevlc = tmplc;
                }
                ldap_free_urllist( lc->lconn_server );
+#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
                if ( lc->lconn_krbinstance != NULL ) {
                        LDAP_FREE( lc->lconn_krbinstance );
                }
+#endif
                if ( lc->lconn_sb != ld->ld_sb ) {
                        ber_sockbuf_free( lc->lconn_sb );
                }
@@ -573,13 +576,14 @@ ldap_free_request( LDAP *ld, LDAPRequest *lr )
  *  (IN) lr = LDAP Request structure
  *  (IN) refs = array of pointers to referral strings that we will chase
  *              The array will be free'd by this function when no longer needed
+ *  (IN) sref != 0 if following search reference
  *  (OUT) errstrp = Place to return a string of referrals which could not be followed
  *  (OUT) hadrefp = 1 if sucessfully followed referral
  *
  * Return value - number of referrals followed
  */
-LIBLDAP_F(int)
-ldap_chase_v3referrals( LDAP *ld, LDAPRequest *lr, char **refs, char **errstrp, int *hadrefp )
+int
+ldap_chase_v3referrals( LDAP *ld, LDAPRequest *lr, char **refs, int sref, char **errstrp, int *hadrefp )
 {
        char            *unfollowed;
        int                      unfollowedcnt = 0;
@@ -630,6 +634,13 @@ ldap_chase_v3referrals( LDAP *ld, LDAPRequest *lr, char **refs, char **errstrp,
                        goto done;
                }
 
+               if( srv->lud_crit_exts ) {
+                       /* we do not support any extensions */
+                       ld->ld_errno = LDAP_NOT_SUPPORTED;
+                       rc = -1;
+                       goto done;
+               }
+
                /* treat ldap://hostpart and ldap://hostpart/ the same */
                if ( srv->lud_dn && srv->lud_dn[0] == '\0' ) {
                        LDAP_FREE( srv->lud_dn );
@@ -685,6 +696,11 @@ ldap_chase_v3referrals( LDAP *ld, LDAPRequest *lr, char **refs, char **errstrp,
                 * Note: In the future we also need to replace the filter if one
                 * was provided with the search reference
                 */
+
+               /* For references we don't want old dn if new dn empty */
+               if ( sref && srv->lud_dn == NULL )
+                       srv->lud_dn = LDAP_STRDUP( "" );
+
                if (( ber = re_encode_request( ld, origreq->lr_ber,
                            ++ld->ld_msgid, &srv->lud_dn, &rinfo.ri_request )) == NULL ) {
                        ld->ld_errno = LDAP_ENCODING_ERROR;
@@ -786,8 +802,7 @@ ldap_chase_referrals( LDAP *ld, LDAPRequest *lr, char **errstrp, int *hadrefp )
 
        len = strlen( *errstrp );
        for ( p = *errstrp; len >= LDAP_REF_STR_LEN; ++p, --len ) {
-               if (( *p == 'R' || *p == 'r' ) && strncasecmp( p,
-                   LDAP_REF_STR, LDAP_REF_STR_LEN ) == 0 ) {
+               if ( strncasecmp( p, LDAP_REF_STR, LDAP_REF_STR_LEN ) == 0 ) {
                        *p = '\0';
                        p += LDAP_REF_STR_LEN;
                        break;
@@ -824,6 +839,9 @@ ldap_chase_referrals( LDAP *ld, LDAPRequest *lr, char **errstrp, int *hadrefp )
                        p = NULL;
                }
 
+               /* copy the complete referral for rebind process */
+               rinfo.ri_url = LDAP_STRDUP( ref );
+
                ldap_pvt_hex_unescape( ref );
                len = strlen( ref );
 
@@ -839,12 +857,11 @@ ldap_chase_referrals( LDAP *ld, LDAPRequest *lr, char **errstrp, int *hadrefp )
                            "ignoring unknown referral <%s>\n", ref, 0, 0 );
                        rc = ldap_append_referral( ld, &unfollowed, ref );
                        *hadrefp = 1;
+                       LDAP_FREE( rinfo.ri_url );
+                       rinfo.ri_url = NULL;
                        continue;
                }
 
-               /* copy the complete referral for rebind process */
-               rinfo.ri_url = LDAP_STRDUP( ref );
-
                *hadrefp = 1;
 
                if (( refdn = strchr( tmpref, '/' )) != NULL ) {
@@ -885,7 +902,7 @@ ldap_chase_referrals( LDAP *ld, LDAPRequest *lr, char **errstrp, int *hadrefp )
                                *ports++ = '\0';
                                srv->lud_port = atoi( ports );
                        } else {
-                               srv->lud_port = ldap_int_global_options.ldo_defport;
+                               srv->lud_port = (LDAP_INT_GLOBAL_OPT())->ldo_defport;
                        }
 
                rinfo.ri_msgid = origreq->lr_origid;
@@ -950,9 +967,9 @@ ldap_append_referral( LDAP *ld, char **referralsp, char *s )
 static BerElement *
 re_encode_request( LDAP *ld, BerElement *origber, ber_int_t msgid, char **dnp, int *type )
 {
-/*
- * XXX this routine knows way too much about how the lber library works!
- */
+       /*
       * XXX this routine knows way too much about how the lber library works!
       */
        ber_int_t       along;
        ber_tag_t       tag;
        ber_int_t       ver;
@@ -1010,7 +1027,7 @@ re_encode_request( LDAP *ld, BerElement *origber, ber_int_t msgid, char **dnp, i
        if ( tag == LDAP_REQ_BIND ) {
                rc = ber_printf( ber, "{it{is" /*}}*/, msgid, tag, ver, *dnp );
        } else if ( tag == LDAP_REQ_DELETE ) {
-               rc = ber_printf( ber, "{its}", msgid, tag, *dnp );
+               rc = ber_printf( ber, "{itsN}", msgid, tag, *dnp );
        } else {
                rc = ber_printf( ber, "{it{s" /*}}*/, msgid, tag, *dnp );
        }
@@ -1024,7 +1041,7 @@ re_encode_request( LDAP *ld, BerElement *origber, ber_int_t msgid, char **dnp, i
        if ( tag != LDAP_REQ_DELETE && (
                ber_write(ber, tmpber.ber_ptr, ( tmpber.ber_end - tmpber.ber_ptr ), 0)
                != ( tmpber.ber_end - tmpber.ber_ptr ) ||
-           ber_printf( ber, /*{{*/ "}}" ) == -1 ) )
+           ber_printf( ber, /*{{*/ "N}N}" ) == -1 ) )
        {
                ld->ld_errno = LDAP_ENCODING_ERROR;
                ber_free( ber, 1 );
@@ -1047,7 +1064,7 @@ re_encode_request( LDAP *ld, BerElement *origber, ber_int_t msgid, char **dnp, i
 LDAPRequest *
 ldap_find_request_by_msgid( LDAP *ld, ber_int_t msgid )
 {
-       LDAPRequest     *lr;
+       LDAPRequest     *lr;
 
        for ( lr = ld->ld_requests; lr != NULL; lr = lr->lr_next ) {
                if( lr->lr_status == LDAP_REQST_COMPLETED ) {