]> git.sur5r.net Git - openldap/blobdiff - libraries/libldap/request.c
Silence warning in print_deref(): cast lutil_b64_ntop() arg to unsigned char*
[openldap] / libraries / libldap / request.c
index 8d92aa743d0835cd4baad656ce5623cf9e9f2c02..6098f0c904b14c48389c189c55252c6f0ff78dc2 100644 (file)
@@ -1,7 +1,7 @@
 /* $OpenLDAP$ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
- * Copyright 1998-2008 The OpenLDAP Foundation.
+ * Copyright 1998-2009 The OpenLDAP Foundation.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -352,6 +352,32 @@ ldap_send_server_request(
        return( msgid );
 }
 
+/* return 0 if no StartTLS ext, 1 if present, 2 if critical */
+static int
+find_tls_ext( LDAPURLDesc *srv )
+{
+       int i, crit;
+       char *ext;
+
+       if ( !srv->lud_exts )
+               return 0;
+
+       for (i=0; srv->lud_exts[i]; i++) {
+               crit = 0;
+               ext = srv->lud_exts[i];
+               if ( ext[0] == '!') {
+                       ext++;
+                       crit = 1;
+               }
+               if ( !strcasecmp( ext, "StartTLS" ) ||
+                       !strcasecmp( ext, "X-StartTLS" ) ||
+                       !strcmp( ext, LDAP_EXOP_START_TLS )) {
+                       return crit + 1;
+               }
+       }
+       return 0;
+}
+
 LDAPConn *
 ldap_new_connection( LDAP *ld, LDAPURLDesc **srvlist, int use_ldsb,
        int connect, LDAPreqinfo *bind )
@@ -426,6 +452,38 @@ ldap_new_connection( LDAP *ld, LDAPURLDesc **srvlist, int use_ldsb,
        ldap_pvt_thread_mutex_unlock( &ld->ld_conn_mutex );
 #endif
 
+       if ( connect ) {
+#ifdef HAVE_TLS
+               if ( lc->lconn_server->lud_exts ) {
+                       int rc, ext = find_tls_ext( lc->lconn_server );
+                       if ( ext ) {
+                               LDAPConn        *savedefconn;
+
+                               savedefconn = ld->ld_defconn;
+                               ++lc->lconn_refcnt;     /* avoid premature free */
+                               ld->ld_defconn = lc;
+
+#ifdef LDAP_R_COMPILE
+                               ldap_pvt_thread_mutex_unlock( &ld->ld_req_mutex );
+                               ldap_pvt_thread_mutex_unlock( &ld->ld_res_mutex );
+#endif
+                               rc = ldap_start_tls_s( ld, NULL, NULL );
+#ifdef LDAP_R_COMPILE
+                               ldap_pvt_thread_mutex_lock( &ld->ld_res_mutex );
+                               ldap_pvt_thread_mutex_lock( &ld->ld_req_mutex );
+#endif
+                               ld->ld_defconn = savedefconn;
+                               --lc->lconn_refcnt;
+
+                               if ( rc != LDAP_SUCCESS && ext == 2 ) {
+                                       ldap_free_connection( ld, lc, 1, 0 );
+                                       return NULL;
+                               }
+                       }
+               }
+#endif
+       }
+
        if ( bind != NULL ) {
                int             err = 0;
                LDAPConn        *savedefconn;
@@ -577,8 +635,7 @@ find_connection( LDAP *ld, LDAPURLDesc *srv, int any )
 
                        if ( lsu_port == lcu_port
                                && strcmp( lcu->lud_scheme, lsu->lud_scheme ) == 0
-                               && lcu->lud_host != NULL && *lcu->lud_host != '\0'
-                               && lsu->lud_host != NULL && *lsu->lud_host != '\0'
+                               && lcu->lud_host != NULL && lsu->lud_host != NULL
                                && strcasecmp( lsu->lud_host, lcu->lud_host ) == 0 )
                        {
                                found = 1;
@@ -677,6 +734,9 @@ ldap_free_connection( LDAP *ld, LDAPConn *lc, int force, int unbind )
                }
 
                ldap_int_sasl_close( ld, lc );
+#ifdef HAVE_GSSAPI
+               ldap_int_gssapi_close( ld, lc );
+#endif
 
                ldap_free_urllist( lc->lconn_server );
 
@@ -1018,10 +1078,18 @@ ldap_chase_v3referrals( LDAP *ld, LDAPRequest *lr, char **refs, int sref, char *
                }
 
                if( srv->lud_crit_exts ) {
-                       /* we do not support any extensions */
-                       ld->ld_errno = LDAP_NOT_SUPPORTED;
-                       rc = -1;
-                       goto done;
+                       int ok = 0;
+#ifdef HAVE_TLS
+                       /* If StartTLS is the only critical ext, OK. */
+                       if ( find_tls_ext( srv ) == 2 && srv->lud_crit_exts == 1 )
+                               ok = 1;
+#endif
+                       if ( !ok ) {
+                               /* we do not support any other extensions */
+                               ld->ld_errno = LDAP_NOT_SUPPORTED;
+                               rc = -1;
+                               goto done;
+                       }
                }
 
                /* check connection for re-bind in progress */
@@ -1029,7 +1097,7 @@ ldap_chase_v3referrals( LDAP *ld, LDAPRequest *lr, char **refs, int sref, char *
                        /* See if we've already requested this DN with this conn */
                        LDAPRequest *lp;
                        int looped = 0;
-                       int len = srv->lud_dn ? strlen( srv->lud_dn ) : 0;
+                       ber_len_t len = srv->lud_dn ? strlen( srv->lud_dn ) : 0;
                        for ( lp = origreq; lp; ) {
                                if ( lp->lr_conn == lc
                                        && len == lp->lr_dn.bv_len
@@ -1288,7 +1356,7 @@ ldap_chase_referrals( LDAP *ld,
                if (( lc = find_connection( ld, srv, 1 )) != NULL ) {
                        LDAPRequest *lp;
                        int looped = 0;
-                       int len = srv->lud_dn ? strlen( srv->lud_dn ) : 0;
+                       ber_len_t len = srv->lud_dn ? strlen( srv->lud_dn ) : 0;
                        for ( lp = lr; lp; lp = lp->lr_parent ) {
                                if ( lp->lr_conn == lc
                                        && len == lp->lr_dn.bv_len )