]> git.sur5r.net Git - openldap/blobdiff - libraries/libldap/open.c
ITS#6625,ITS#5421
[openldap] / libraries / libldap / open.c
index db5eacc69ffc5fbcd5b7dca6f9f4f726b2b8c58a..5cc653139f5442ac309670d9ab00ad048416f114 100644 (file)
 #include "ldap-int.h"
 #include "ldap_log.h"
 
-/* Caller should hold the req_mutex if simultaneous accesses are possible */
+/* Caller must hold the conn_mutex since simultaneous accesses are possible */
 int ldap_open_defconn( LDAP *ld )
 {
        ld->ld_defconn = ldap_new_connection( ld,
-               &ld->ld_options.ldo_defludp, 1, 1, NULL );
+               &ld->ld_options.ldo_defludp, 1, 1, NULL, 0, 0 );
 
        if( ld->ld_defconn == NULL ) {
                ld->ld_errno = LDAP_SERVER_DOWN;
@@ -74,7 +74,9 @@ ldap_open( LDAP_CONST char *host, int port )
                return( NULL );
        }
 
+       LDAP_MUTEX_LOCK( &ld->ld_conn_mutex );
        rc = ldap_open_defconn( ld );
+       LDAP_MUTEX_UNLOCK( &ld->ld_conn_mutex );
 
        if( rc < 0 ) {
                ldap_ld_free( ld, 0, NULL, NULL );
@@ -114,8 +116,19 @@ ldap_create( LDAP **ldp )
                return( LDAP_NO_MEMORY );
        }
    
+       if ( (ld->ldc = (struct ldap_common *) LDAP_CALLOC( 1,
+                       sizeof(struct ldap_common) )) == NULL ) {
+               LDAP_FREE( (char *)ld );
+               return( LDAP_NO_MEMORY );
+       }
        /* copy the global options */
+       LDAP_MUTEX_LOCK( &gopts->ldo_mutex );
        AC_MEMCPY(&ld->ld_options, gopts, sizeof(ld->ld_options));
+#ifdef LDAP_R_COMPILE
+       /* Properly initialize the structs mutex */
+       ldap_pvt_thread_mutex_init( &(ld->ld_ldopts_mutex) );
+#endif
+       LDAP_MUTEX_UNLOCK( &gopts->ldo_mutex );
 
        ld->ld_valid = LDAP_VALID_SESSION;
 
@@ -159,10 +172,14 @@ ldap_create( LDAP **ldp )
        if ( ld->ld_sb == NULL ) goto nomem;
 
 #ifdef LDAP_R_COMPILE
+       ldap_pvt_thread_mutex_init( &ld->ld_msgid_mutex );
+       ldap_pvt_thread_mutex_init( &ld->ld_conn_mutex );
        ldap_pvt_thread_mutex_init( &ld->ld_req_mutex );
        ldap_pvt_thread_mutex_init( &ld->ld_res_mutex );
-       ldap_pvt_thread_mutex_init( &ld->ld_conn_mutex );
+       ldap_pvt_thread_mutex_init( &ld->ld_abandon_mutex );
+       ldap_pvt_thread_mutex_init( &ld->ld_ldcmutex );
 #endif
+       ld->ld_ldcrefcnt = 1;
        *ldp = ld;
        return LDAP_SUCCESS;
 
@@ -265,8 +282,9 @@ ldap_init_fd(
                }
        }
 
+       LDAP_MUTEX_LOCK( &ld->ld_conn_mutex );
        /* Attach the passed socket as the LDAP's connection */
-       conn = ldap_new_connection( ld, NULL, 1, 0, NULL);
+       conn = ldap_new_connection( ld, NULL, 1, 0, NULL, 0, 0 );
        if( conn == NULL ) {
                ldap_unbind_ext( ld, NULL, NULL );
                return( LDAP_NO_MEMORY );
@@ -276,6 +294,7 @@ ldap_init_fd(
        ber_sockbuf_ctrl( conn->lconn_sb, LBER_SB_OPT_SET_FD, &fd );
        ld->ld_defconn = conn;
        ++ld->ld_defconn->lconn_refcnt; /* so it never gets closed/freed */
+       LDAP_MUTEX_UNLOCK( &ld->ld_conn_mutex );
 
        switch( proto ) {
        case LDAP_PROTO_TCP:
@@ -331,6 +350,7 @@ ldap_init_fd(
        return LDAP_SUCCESS;
 }
 
+/* Protected by ld_conn_mutex */
 int
 ldap_int_open_connection(
        LDAP *ld,
@@ -434,8 +454,9 @@ ldap_open_internal_connection( LDAP **ldp, ber_socket_t *fdp )
        int rc;
        LDAPConn *c;
        LDAPRequest *lr;
+       LDAP    *ld;
 
-       rc = ldap_create( ldp );
+       rc = ldap_create( &ld );
        if( rc != LDAP_SUCCESS ) {
                *ldp = NULL;
                return( rc );
@@ -444,7 +465,7 @@ ldap_open_internal_connection( LDAP **ldp, ber_socket_t *fdp )
        /* Make it appear that a search request, msgid 0, was sent */
        lr = (LDAPRequest *)LDAP_CALLOC( 1, sizeof( LDAPRequest ));
        if( lr == NULL ) {
-               ldap_unbind_ext( *ldp, NULL, NULL );
+               ldap_unbind_ext( ld, NULL, NULL );
                *ldp = NULL;
                return( LDAP_NO_MEMORY );
        }
@@ -453,13 +474,15 @@ ldap_open_internal_connection( LDAP **ldp, ber_socket_t *fdp )
        lr->lr_status = LDAP_REQST_INPROGRESS;
        lr->lr_res_errno = LDAP_SUCCESS;
        /* no mutex lock needed, we just created this ld here */
-       (*ldp)->ld_requests = lr;
+       ld->ld_requests = lr;
 
+       LDAP_MUTEX_LOCK( &ld->ld_conn_mutex );
        /* Attach the passed socket as the *LDAP's connection */
-       c = ldap_new_connection( *ldp, NULL, 1, 0, NULL);
+       c = ldap_new_connection( ld, NULL, 1, 0, NULL, 0, 0 );
        if( c == NULL ) {
-               ldap_unbind_ext( *ldp, NULL, NULL );
+               ldap_unbind_ext( ld, NULL, NULL );
                *ldp = NULL;
+               LDAP_MUTEX_UNLOCK( &ld->ld_conn_mutex );
                return( LDAP_NO_MEMORY );
        }
        ber_sockbuf_ctrl( c->lconn_sb, LBER_SB_OPT_SET_FD, fdp );
@@ -469,15 +492,39 @@ ldap_open_internal_connection( LDAP **ldp, ber_socket_t *fdp )
 #endif
        ber_sockbuf_add_io( c->lconn_sb, &ber_sockbuf_io_tcp,
          LBER_SBIOD_LEVEL_PROVIDER, NULL );
-       (*ldp)->ld_defconn = c;
+       ld->ld_defconn = c;
+       LDAP_MUTEX_UNLOCK( &ld->ld_conn_mutex );
 
        /* Add the connection to the *LDAP's select pool */
-       ldap_mark_select_read( *ldp, c->lconn_sb );
-       ldap_mark_select_write( *ldp, c->lconn_sb );
+       ldap_mark_select_read( ld, c->lconn_sb );
+       ldap_mark_select_write( ld, c->lconn_sb );
 
        /* Make this connection an LDAP V3 protocol connection */
        rc = LDAP_VERSION3;
-       ldap_set_option( *ldp, LDAP_OPT_PROTOCOL_VERSION, &rc );
+       ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &rc );
+       *ldp = ld;
 
        return( LDAP_SUCCESS );
 }
+
+LDAP *
+ldap_dup( LDAP *old )
+{
+       LDAP                    *ld;
+
+       if ( old == NULL ) {
+               return( NULL );
+       }
+
+       Debug( LDAP_DEBUG_TRACE, "ldap_dup\n", 0, 0, 0 );
+
+       if ( (ld = (LDAP *) LDAP_CALLOC( 1, sizeof(LDAP) )) == NULL ) {
+               return( NULL );
+       }
+   
+       LDAP_MUTEX_LOCK( &old->ld_ldcmutex );
+       ld->ldc = old->ldc;
+       old->ld_ldcrefcnt++;
+       LDAP_MUTEX_UNLOCK( &old->ld_ldcmutex );
+       return ( ld );
+}