]> git.sur5r.net Git - openldap/blobdiff - libraries/libldap/open.c
Happy New Year
[openldap] / libraries / libldap / open.c
index a92095334e91fab25d884dda576352699d528f9d..6ee1dd13e3e93e7652e8f322317fbd8e34323ab0 100644 (file)
@@ -1,7 +1,7 @@
 /* $OpenLDAP$ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
- * Copyright 1998-2012 The OpenLDAP Foundation.
+ * Copyright 1998-2018 The OpenLDAP Foundation.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -50,6 +50,29 @@ int ldap_open_defconn( LDAP *ld )
        return 0;
 }
 
+/*
+ * ldap_connect - Connect to an ldap server.
+ *
+ * Example:
+ *     LDAP    *ld;
+ *     ldap_initialize( &ld, url );
+ *     ldap_connect( ld );
+ */
+int
+ldap_connect( LDAP *ld )
+{
+       ber_socket_t sd = AC_SOCKET_INVALID;
+       int rc = LDAP_SUCCESS;
+
+       LDAP_MUTEX_LOCK( &ld->ld_conn_mutex );
+       if ( ber_sockbuf_ctrl( ld->ld_sb, LBER_SB_OPT_GET_FD, &sd ) == -1 ) {
+               rc = ldap_open_defconn( ld );
+       }
+       LDAP_MUTEX_UNLOCK( &ld->ld_conn_mutex );
+
+       return rc;
+}
+
 /*
  * ldap_open - initialize and connect to an ldap server.  A magic cookie to
  * be used for future communication is returned on success, NULL on failure.
@@ -128,6 +151,23 @@ ldap_create( LDAP **ldp )
        /* Properly initialize the structs mutex */
        ldap_pvt_thread_mutex_init( &(ld->ld_ldopts_mutex) );
 #endif
+
+#ifdef HAVE_TLS
+       if ( ld->ld_options.ldo_tls_pin_hashalg ) {
+               int len = strlen( gopts->ldo_tls_pin_hashalg );
+
+               ld->ld_options.ldo_tls_pin_hashalg =
+                       LDAP_MALLOC( len + 1 + gopts->ldo_tls_pin.bv_len );
+               if ( !ld->ld_options.ldo_tls_pin_hashalg ) goto nomem;
+
+               ld->ld_options.ldo_tls_pin.bv_val = ld->ld_options.ldo_tls_pin_hashalg
+                       + len + 1;
+               AC_MEMCPY( ld->ld_options.ldo_tls_pin_hashalg, gopts->ldo_tls_pin_hashalg,
+                               len + 1 + gopts->ldo_tls_pin.bv_len );
+       } else if ( !BER_BVISEMPTY(&ld->ld_options.ldo_tls_pin) ) {
+               ber_dupbv( &ld->ld_options.ldo_tls_pin, &gopts->ldo_tls_pin );
+       }
+#endif
        LDAP_MUTEX_UNLOCK( &gopts->ldo_mutex );
 
        ld->ld_valid = LDAP_VALID_SESSION;
@@ -192,6 +232,15 @@ nomem:
        LDAP_FREE( ld->ld_options.ldo_def_sasl_realm );
        LDAP_FREE( ld->ld_options.ldo_def_sasl_mech );
 #endif
+
+#ifdef HAVE_TLS
+       /* tls_pin_hashalg and tls_pin share the same buffer */
+       if ( ld->ld_options.ldo_tls_pin_hashalg ) {
+               LDAP_FREE( ld->ld_options.ldo_tls_pin_hashalg );
+       } else {
+               LDAP_FREE( ld->ld_options.ldo_tls_pin.bv_val );
+       }
+#endif
        LDAP_FREE( (char *)ld );
        return LDAP_NO_MEMORY;
 }
@@ -268,6 +317,9 @@ ldap_init_fd(
        int rc;
        LDAP *ld;
        LDAPConn *conn;
+#ifdef LDAP_CONNECTIONLESS
+       ber_socklen_t   len;
+#endif
 
        *ldp = NULL;
        rc = ldap_create( &ld );
@@ -308,6 +360,15 @@ ldap_init_fd(
 
 #ifdef LDAP_CONNECTIONLESS
        case LDAP_PROTO_UDP:
+               LDAP_IS_UDP(ld) = 1;
+               if( ld->ld_options.ldo_peer )
+                       ldap_memfree( ld->ld_options.ldo_peer );
+               ld->ld_options.ldo_peer = ldap_memcalloc( 1, sizeof( struct sockaddr_storage ) );
+               len = sizeof( struct sockaddr_storage );
+               if( getpeername ( fd, ld->ld_options.ldo_peer, &len ) < 0) {
+                       ldap_unbind_ext( ld, NULL, NULL );
+                       return( AC_SOCKET_ERROR );
+               }
 #ifdef LDAP_DEBUG
                ber_sockbuf_add_io( conn->lconn_sb, &ber_sockbuf_io_debug,
                        LBER_SBIOD_LEVEL_PROVIDER, (void *)"udp_" );
@@ -438,6 +499,31 @@ ldap_int_open_connection(
                --conn->lconn_refcnt;
 
                if (rc != LDAP_SUCCESS) {
+                       /* process connection callbacks */
+                       {
+                               struct ldapoptions *lo;
+                               ldaplist *ll;
+                               ldap_conncb *cb;
+
+                               lo = &ld->ld_options;
+                               LDAP_MUTEX_LOCK( &lo->ldo_mutex );
+                               if ( lo->ldo_conn_cbs ) {
+                                       for ( ll=lo->ldo_conn_cbs; ll; ll=ll->ll_next ) {
+                                               cb = ll->ll_data;
+                                               cb->lc_del( ld, conn->lconn_sb, cb );
+                                       }
+                               }
+                               LDAP_MUTEX_UNLOCK( &lo->ldo_mutex );
+                               lo = LDAP_INT_GLOBAL_OPT();
+                               LDAP_MUTEX_LOCK( &lo->ldo_mutex );
+                               if ( lo->ldo_conn_cbs ) {
+                                       for ( ll=lo->ldo_conn_cbs; ll; ll=ll->ll_next ) {
+                                               cb = ll->ll_data;
+                                               cb->lc_del( ld, conn->lconn_sb, cb );
+                                       }
+                               }
+                               LDAP_MUTEX_UNLOCK( &lo->ldo_mutex );
+                       }
                        return -1;
                }
        }
@@ -540,7 +626,7 @@ ldap_int_check_async_open( LDAP *ld, ber_socket_t sd )
        struct timeval tv = { 0 };
        int rc;
 
-       rc = ldap_int_poll( ld, sd, &tv );
+       rc = ldap_int_poll( ld, sd, &tv, 1 );
        switch ( rc ) {
        case 0:
                /* now ready to start tls */