Back to index

openldap  2.4.31
open.c
Go to the documentation of this file.
00001 /* $OpenLDAP$ */
00002 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
00003  *
00004  * Copyright 1998-2012 The OpenLDAP Foundation.
00005  * All rights reserved.
00006  *
00007  * Redistribution and use in source and binary forms, with or without
00008  * modification, are permitted only as authorized by the OpenLDAP
00009  * Public License.
00010  *
00011  * A copy of this license is available in the file LICENSE in the
00012  * top-level directory of the distribution or, alternatively, at
00013  * <http://www.OpenLDAP.org/license.html>.
00014  */
00015 /* Portions Copyright (c) 1995 Regents of the University of Michigan.
00016  * All rights reserved.
00017  */
00018 
00019 #include "portable.h"
00020 
00021 #include <stdio.h>
00022 #ifdef HAVE_LIMITS_H
00023 #include <limits.h>
00024 #endif
00025 
00026 #include <ac/stdlib.h>
00027 
00028 #include <ac/param.h>
00029 #include <ac/socket.h>
00030 #include <ac/string.h>
00031 #include <ac/time.h>
00032 
00033 #include <ac/unistd.h>
00034 
00035 #include "ldap-int.h"
00036 #include "ldap_log.h"
00037 
00038 /* Caller must hold the conn_mutex since simultaneous accesses are possible */
00039 int ldap_open_defconn( LDAP *ld )
00040 {
00041        ld->ld_defconn = ldap_new_connection( ld,
00042               &ld->ld_options.ldo_defludp, 1, 1, NULL, 0, 0 );
00043 
00044        if( ld->ld_defconn == NULL ) {
00045               ld->ld_errno = LDAP_SERVER_DOWN;
00046               return -1;
00047        }
00048 
00049        ++ld->ld_defconn->lconn_refcnt;    /* so it never gets closed/freed */
00050        return 0;
00051 }
00052 
00053 /*
00054  * ldap_open - initialize and connect to an ldap server.  A magic cookie to
00055  * be used for future communication is returned on success, NULL on failure.
00056  * "host" may be a space-separated list of hosts or IP addresses
00057  *
00058  * Example:
00059  *     LDAP   *ld;
00060  *     ld = ldap_open( hostname, port );
00061  */
00062 
00063 LDAP *
00064 ldap_open( LDAP_CONST char *host, int port )
00065 {
00066        int rc;
00067        LDAP          *ld;
00068 
00069        Debug( LDAP_DEBUG_TRACE, "ldap_open(%s, %d)\n",
00070               host, port, 0 );
00071 
00072        ld = ldap_init( host, port );
00073        if ( ld == NULL ) {
00074               return( NULL );
00075        }
00076 
00077        LDAP_MUTEX_LOCK( &ld->ld_conn_mutex );
00078        rc = ldap_open_defconn( ld );
00079        LDAP_MUTEX_UNLOCK( &ld->ld_conn_mutex );
00080 
00081        if( rc < 0 ) {
00082               ldap_ld_free( ld, 0, NULL, NULL );
00083               ld = NULL;
00084        }
00085 
00086        Debug( LDAP_DEBUG_TRACE, "ldap_open: %s\n",
00087               ld != NULL ? "succeeded" : "failed", 0, 0 );
00088 
00089        return ld;
00090 }
00091 
00092 
00093 
00094 int
00095 ldap_create( LDAP **ldp )
00096 {
00097        LDAP                 *ld;
00098        struct ldapoptions   *gopts;
00099 
00100        *ldp = NULL;
00101        /* Get pointer to global option structure */
00102        if ( (gopts = LDAP_INT_GLOBAL_OPT()) == NULL) {
00103               return LDAP_NO_MEMORY;
00104        }
00105 
00106        /* Initialize the global options, if not already done. */
00107        if( gopts->ldo_valid != LDAP_INITIALIZED ) {
00108               ldap_int_initialize(gopts, NULL);
00109               if ( gopts->ldo_valid != LDAP_INITIALIZED )
00110                      return LDAP_LOCAL_ERROR;
00111        }
00112 
00113        Debug( LDAP_DEBUG_TRACE, "ldap_create\n", 0, 0, 0 );
00114 
00115        if ( (ld = (LDAP *) LDAP_CALLOC( 1, sizeof(LDAP) )) == NULL ) {
00116               return( LDAP_NO_MEMORY );
00117        }
00118    
00119        if ( (ld->ldc = (struct ldap_common *) LDAP_CALLOC( 1,
00120                      sizeof(struct ldap_common) )) == NULL ) {
00121               LDAP_FREE( (char *)ld );
00122               return( LDAP_NO_MEMORY );
00123        }
00124        /* copy the global options */
00125        LDAP_MUTEX_LOCK( &gopts->ldo_mutex );
00126        AC_MEMCPY(&ld->ld_options, gopts, sizeof(ld->ld_options));
00127 #ifdef LDAP_R_COMPILE
00128        /* Properly initialize the structs mutex */
00129        ldap_pvt_thread_mutex_init( &(ld->ld_ldopts_mutex) );
00130 #endif
00131        LDAP_MUTEX_UNLOCK( &gopts->ldo_mutex );
00132 
00133        ld->ld_valid = LDAP_VALID_SESSION;
00134 
00135        /* but not pointers to malloc'ed items */
00136        ld->ld_options.ldo_sctrls = NULL;
00137        ld->ld_options.ldo_cctrls = NULL;
00138        ld->ld_options.ldo_defludp = NULL;
00139        ld->ld_options.ldo_conn_cbs = NULL;
00140 
00141 #ifdef HAVE_CYRUS_SASL
00142        ld->ld_options.ldo_def_sasl_mech = gopts->ldo_def_sasl_mech
00143               ? LDAP_STRDUP( gopts->ldo_def_sasl_mech ) : NULL;
00144        ld->ld_options.ldo_def_sasl_realm = gopts->ldo_def_sasl_realm
00145               ? LDAP_STRDUP( gopts->ldo_def_sasl_realm ) : NULL;
00146        ld->ld_options.ldo_def_sasl_authcid = gopts->ldo_def_sasl_authcid
00147               ? LDAP_STRDUP( gopts->ldo_def_sasl_authcid ) : NULL;
00148        ld->ld_options.ldo_def_sasl_authzid = gopts->ldo_def_sasl_authzid
00149               ? LDAP_STRDUP( gopts->ldo_def_sasl_authzid ) : NULL;
00150 #endif
00151 
00152 #ifdef HAVE_TLS
00153        /* We explicitly inherit the SSL_CTX, don't need the names/paths. Leave
00154         * them empty to allow new SSL_CTX's to be created from scratch.
00155         */
00156        memset( &ld->ld_options.ldo_tls_info, 0,
00157               sizeof( ld->ld_options.ldo_tls_info ));
00158        ld->ld_options.ldo_tls_ctx = NULL;
00159 #endif
00160 
00161        if ( gopts->ldo_defludp ) {
00162               ld->ld_options.ldo_defludp = ldap_url_duplist(gopts->ldo_defludp);
00163 
00164               if ( ld->ld_options.ldo_defludp == NULL ) goto nomem;
00165        }
00166 
00167        if (( ld->ld_selectinfo = ldap_new_select_info()) == NULL ) goto nomem;
00168 
00169        ld->ld_lberoptions = LBER_USE_DER;
00170 
00171        ld->ld_sb = ber_sockbuf_alloc( );
00172        if ( ld->ld_sb == NULL ) goto nomem;
00173 
00174 #ifdef LDAP_R_COMPILE
00175        ldap_pvt_thread_mutex_init( &ld->ld_msgid_mutex );
00176        ldap_pvt_thread_mutex_init( &ld->ld_conn_mutex );
00177        ldap_pvt_thread_mutex_init( &ld->ld_req_mutex );
00178        ldap_pvt_thread_mutex_init( &ld->ld_res_mutex );
00179        ldap_pvt_thread_mutex_init( &ld->ld_abandon_mutex );
00180        ldap_pvt_thread_mutex_init( &ld->ld_ldcmutex );
00181 #endif
00182        ld->ld_ldcrefcnt = 1;
00183        *ldp = ld;
00184        return LDAP_SUCCESS;
00185 
00186 nomem:
00187        ldap_free_select_info( ld->ld_selectinfo );
00188        ldap_free_urllist( ld->ld_options.ldo_defludp );
00189 #ifdef HAVE_CYRUS_SASL
00190        LDAP_FREE( ld->ld_options.ldo_def_sasl_authzid );
00191        LDAP_FREE( ld->ld_options.ldo_def_sasl_authcid );
00192        LDAP_FREE( ld->ld_options.ldo_def_sasl_realm );
00193        LDAP_FREE( ld->ld_options.ldo_def_sasl_mech );
00194 #endif
00195        LDAP_FREE( (char *)ld );
00196        return LDAP_NO_MEMORY;
00197 }
00198 
00199 /*
00200  * ldap_init - initialize the LDAP library.  A magic cookie to be used for
00201  * future communication is returned on success, NULL on failure.
00202  * "host" may be a space-separated list of hosts or IP addresses
00203  *
00204  * Example:
00205  *     LDAP   *ld;
00206  *     ld = ldap_init( host, port );
00207  */
00208 LDAP *
00209 ldap_init( LDAP_CONST char *defhost, int defport )
00210 {
00211        LDAP *ld;
00212        int rc;
00213 
00214        rc = ldap_create(&ld);
00215        if ( rc != LDAP_SUCCESS )
00216               return NULL;
00217 
00218        if (defport != 0)
00219               ld->ld_options.ldo_defport = defport;
00220 
00221        if (defhost != NULL) {
00222               rc = ldap_set_option(ld, LDAP_OPT_HOST_NAME, defhost);
00223               if ( rc != LDAP_SUCCESS ) {
00224                      ldap_ld_free(ld, 1, NULL, NULL);
00225                      return NULL;
00226               }
00227        }
00228 
00229        return( ld );
00230 }
00231 
00232 
00233 int
00234 ldap_initialize( LDAP **ldp, LDAP_CONST char *url )
00235 {
00236        int rc;
00237        LDAP *ld;
00238 
00239        *ldp = NULL;
00240        rc = ldap_create(&ld);
00241        if ( rc != LDAP_SUCCESS )
00242               return rc;
00243 
00244        if (url != NULL) {
00245               rc = ldap_set_option(ld, LDAP_OPT_URI, url);
00246               if ( rc != LDAP_SUCCESS ) {
00247                      ldap_ld_free(ld, 1, NULL, NULL);
00248                      return rc;
00249               }
00250 #ifdef LDAP_CONNECTIONLESS
00251               if (ldap_is_ldapc_url(url))
00252                      LDAP_IS_UDP(ld) = 1;
00253 #endif
00254        }
00255 
00256        *ldp = ld;
00257        return LDAP_SUCCESS;
00258 }
00259 
00260 int
00261 ldap_init_fd(
00262        ber_socket_t fd,
00263        int proto,
00264        LDAP_CONST char *url,
00265        LDAP **ldp
00266 )
00267 {
00268        int rc;
00269        LDAP *ld;
00270        LDAPConn *conn;
00271 
00272        *ldp = NULL;
00273        rc = ldap_create( &ld );
00274        if( rc != LDAP_SUCCESS )
00275               return( rc );
00276 
00277        if (url != NULL) {
00278               rc = ldap_set_option(ld, LDAP_OPT_URI, url);
00279               if ( rc != LDAP_SUCCESS ) {
00280                      ldap_ld_free(ld, 1, NULL, NULL);
00281                      return rc;
00282               }
00283        }
00284 
00285        LDAP_MUTEX_LOCK( &ld->ld_conn_mutex );
00286        /* Attach the passed socket as the LDAP's connection */
00287        conn = ldap_new_connection( ld, NULL, 1, 0, NULL, 0, 0 );
00288        if( conn == NULL ) {
00289               ldap_unbind_ext( ld, NULL, NULL );
00290               return( LDAP_NO_MEMORY );
00291        }
00292        if( url )
00293               conn->lconn_server = ldap_url_dup( ld->ld_options.ldo_defludp );
00294        ber_sockbuf_ctrl( conn->lconn_sb, LBER_SB_OPT_SET_FD, &fd );
00295        ld->ld_defconn = conn;
00296        ++ld->ld_defconn->lconn_refcnt;    /* so it never gets closed/freed */
00297        LDAP_MUTEX_UNLOCK( &ld->ld_conn_mutex );
00298 
00299        switch( proto ) {
00300        case LDAP_PROTO_TCP:
00301 #ifdef LDAP_DEBUG
00302               ber_sockbuf_add_io( conn->lconn_sb, &ber_sockbuf_io_debug,
00303                      LBER_SBIOD_LEVEL_PROVIDER, (void *)"tcp_" );
00304 #endif
00305               ber_sockbuf_add_io( conn->lconn_sb, &ber_sockbuf_io_tcp,
00306                      LBER_SBIOD_LEVEL_PROVIDER, NULL );
00307               break;
00308 
00309 #ifdef LDAP_CONNECTIONLESS
00310        case LDAP_PROTO_UDP:
00311 #ifdef LDAP_DEBUG
00312               ber_sockbuf_add_io( conn->lconn_sb, &ber_sockbuf_io_debug,
00313                      LBER_SBIOD_LEVEL_PROVIDER, (void *)"udp_" );
00314 #endif
00315               ber_sockbuf_add_io( conn->lconn_sb, &ber_sockbuf_io_udp,
00316                      LBER_SBIOD_LEVEL_PROVIDER, NULL );
00317               ber_sockbuf_add_io( conn->lconn_sb, &ber_sockbuf_io_readahead,
00318                      LBER_SBIOD_LEVEL_PROVIDER, NULL );
00319               break;
00320 #endif /* LDAP_CONNECTIONLESS */
00321 
00322        case LDAP_PROTO_IPC:
00323 #ifdef LDAP_DEBUG
00324               ber_sockbuf_add_io( conn->lconn_sb, &ber_sockbuf_io_debug,
00325                      LBER_SBIOD_LEVEL_PROVIDER, (void *)"ipc_" );
00326 #endif
00327               ber_sockbuf_add_io( conn->lconn_sb, &ber_sockbuf_io_fd,
00328                      LBER_SBIOD_LEVEL_PROVIDER, NULL );
00329               break;
00330 
00331        case LDAP_PROTO_EXT:
00332               /* caller must supply sockbuf handlers */
00333               break;
00334 
00335        default:
00336               ldap_unbind_ext( ld, NULL, NULL );
00337               return LDAP_PARAM_ERROR;
00338        }
00339 
00340 #ifdef LDAP_DEBUG
00341        ber_sockbuf_add_io( conn->lconn_sb, &ber_sockbuf_io_debug,
00342               INT_MAX, (void *)"ldap_" );
00343 #endif
00344 
00345        /* Add the connection to the *LDAP's select pool */
00346        ldap_mark_select_read( ld, conn->lconn_sb );
00347        
00348        *ldp = ld;
00349        return LDAP_SUCCESS;
00350 }
00351 
00352 /* Protected by ld_conn_mutex */
00353 int
00354 ldap_int_open_connection(
00355        LDAP *ld,
00356        LDAPConn *conn,
00357        LDAPURLDesc *srv,
00358        int async )
00359 {
00360        int rc = -1;
00361        int proto;
00362 
00363        Debug( LDAP_DEBUG_TRACE, "ldap_int_open_connection\n", 0, 0, 0 );
00364 
00365        switch ( proto = ldap_pvt_url_scheme2proto( srv->lud_scheme ) ) {
00366               case LDAP_PROTO_TCP:
00367                      rc = ldap_connect_to_host( ld, conn->lconn_sb,
00368                             proto, srv, async );
00369 
00370                      if ( rc == -1 ) return rc;
00371 #ifdef LDAP_DEBUG
00372                      ber_sockbuf_add_io( conn->lconn_sb, &ber_sockbuf_io_debug,
00373                             LBER_SBIOD_LEVEL_PROVIDER, (void *)"tcp_" );
00374 #endif
00375                      ber_sockbuf_add_io( conn->lconn_sb, &ber_sockbuf_io_tcp,
00376                             LBER_SBIOD_LEVEL_PROVIDER, NULL );
00377 
00378                      break;
00379 
00380 #ifdef LDAP_CONNECTIONLESS
00381               case LDAP_PROTO_UDP:
00382                      LDAP_IS_UDP(ld) = 1;
00383                      rc = ldap_connect_to_host( ld, conn->lconn_sb,
00384                             proto, srv, async );
00385 
00386                      if ( rc == -1 ) return rc;
00387 #ifdef LDAP_DEBUG
00388                      ber_sockbuf_add_io( conn->lconn_sb, &ber_sockbuf_io_debug,
00389                             LBER_SBIOD_LEVEL_PROVIDER, (void *)"udp_" );
00390 #endif
00391                      ber_sockbuf_add_io( conn->lconn_sb, &ber_sockbuf_io_udp,
00392                             LBER_SBIOD_LEVEL_PROVIDER, NULL );
00393 
00394                      ber_sockbuf_add_io( conn->lconn_sb, &ber_sockbuf_io_readahead,
00395                             LBER_SBIOD_LEVEL_PROVIDER, NULL );
00396 
00397                      break;
00398 #endif
00399               case LDAP_PROTO_IPC:
00400 #ifdef LDAP_PF_LOCAL
00401                      /* only IPC mechanism supported is PF_LOCAL (PF_UNIX) */
00402                      rc = ldap_connect_to_path( ld, conn->lconn_sb,
00403                             srv, async );
00404                      if ( rc == -1 ) return rc;
00405 #ifdef LDAP_DEBUG
00406                      ber_sockbuf_add_io( conn->lconn_sb, &ber_sockbuf_io_debug,
00407                             LBER_SBIOD_LEVEL_PROVIDER, (void *)"ipc_" );
00408 #endif
00409                      ber_sockbuf_add_io( conn->lconn_sb, &ber_sockbuf_io_fd,
00410                             LBER_SBIOD_LEVEL_PROVIDER, NULL );
00411 
00412                      break;
00413 #endif /* LDAP_PF_LOCAL */
00414               default:
00415                      return -1;
00416                      break;
00417        }
00418 
00419        conn->lconn_created = time( NULL );
00420 
00421 #ifdef LDAP_DEBUG
00422        ber_sockbuf_add_io( conn->lconn_sb, &ber_sockbuf_io_debug,
00423               INT_MAX, (void *)"ldap_" );
00424 #endif
00425 
00426 #ifdef LDAP_CONNECTIONLESS
00427        if( proto == LDAP_PROTO_UDP ) return 0;
00428 #endif
00429 
00430 #ifdef HAVE_TLS
00431        if (rc == 0 && ( ld->ld_options.ldo_tls_mode == LDAP_OPT_X_TLS_HARD ||
00432               strcmp( srv->lud_scheme, "ldaps" ) == 0 ))
00433        {
00434               ++conn->lconn_refcnt;       /* avoid premature free */
00435 
00436               rc = ldap_int_tls_start( ld, conn, srv );
00437 
00438               --conn->lconn_refcnt;
00439 
00440               if (rc != LDAP_SUCCESS) {
00441                      return -1;
00442               }
00443        }
00444 #endif
00445 
00446        return( 0 );
00447 }
00448 
00449 /*
00450  * ldap_open_internal_connection - open connection and set file descriptor
00451  *
00452  * note: ldap_init_fd() may be preferable
00453  */
00454 
00455 int
00456 ldap_open_internal_connection( LDAP **ldp, ber_socket_t *fdp )
00457 {
00458        int rc;
00459        LDAPConn *c;
00460        LDAPRequest *lr;
00461        LDAP   *ld;
00462 
00463        rc = ldap_create( &ld );
00464        if( rc != LDAP_SUCCESS ) {
00465               *ldp = NULL;
00466               return( rc );
00467        }
00468 
00469        /* Make it appear that a search request, msgid 0, was sent */
00470        lr = (LDAPRequest *)LDAP_CALLOC( 1, sizeof( LDAPRequest ));
00471        if( lr == NULL ) {
00472               ldap_unbind_ext( ld, NULL, NULL );
00473               *ldp = NULL;
00474               return( LDAP_NO_MEMORY );
00475        }
00476        memset(lr, 0, sizeof( LDAPRequest ));
00477        lr->lr_msgid = 0;
00478        lr->lr_status = LDAP_REQST_INPROGRESS;
00479        lr->lr_res_errno = LDAP_SUCCESS;
00480        /* no mutex lock needed, we just created this ld here */
00481        ld->ld_requests = lr;
00482 
00483        LDAP_MUTEX_LOCK( &ld->ld_conn_mutex );
00484        /* Attach the passed socket as the *LDAP's connection */
00485        c = ldap_new_connection( ld, NULL, 1, 0, NULL, 0, 0 );
00486        if( c == NULL ) {
00487               ldap_unbind_ext( ld, NULL, NULL );
00488               *ldp = NULL;
00489               LDAP_MUTEX_UNLOCK( &ld->ld_conn_mutex );
00490               return( LDAP_NO_MEMORY );
00491        }
00492        ber_sockbuf_ctrl( c->lconn_sb, LBER_SB_OPT_SET_FD, fdp );
00493 #ifdef LDAP_DEBUG
00494        ber_sockbuf_add_io( c->lconn_sb, &ber_sockbuf_io_debug,
00495               LBER_SBIOD_LEVEL_PROVIDER, (void *)"int_" );
00496 #endif
00497        ber_sockbuf_add_io( c->lconn_sb, &ber_sockbuf_io_tcp,
00498          LBER_SBIOD_LEVEL_PROVIDER, NULL );
00499        ld->ld_defconn = c;
00500        LDAP_MUTEX_UNLOCK( &ld->ld_conn_mutex );
00501 
00502        /* Add the connection to the *LDAP's select pool */
00503        ldap_mark_select_read( ld, c->lconn_sb );
00504 
00505        /* Make this connection an LDAP V3 protocol connection */
00506        rc = LDAP_VERSION3;
00507        ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &rc );
00508        *ldp = ld;
00509 
00510        ++ld->ld_defconn->lconn_refcnt;    /* so it never gets closed/freed */
00511 
00512        return( LDAP_SUCCESS );
00513 }
00514 
00515 LDAP *
00516 ldap_dup( LDAP *old )
00517 {
00518        LDAP                 *ld;
00519 
00520        if ( old == NULL ) {
00521               return( NULL );
00522        }
00523 
00524        Debug( LDAP_DEBUG_TRACE, "ldap_dup\n", 0, 0, 0 );
00525 
00526        if ( (ld = (LDAP *) LDAP_CALLOC( 1, sizeof(LDAP) )) == NULL ) {
00527               return( NULL );
00528        }
00529    
00530        LDAP_MUTEX_LOCK( &old->ld_ldcmutex );
00531        ld->ldc = old->ldc;
00532        old->ld_ldcrefcnt++;
00533        LDAP_MUTEX_UNLOCK( &old->ld_ldcmutex );
00534        return ( ld );
00535 }
00536 
00537 int
00538 ldap_int_check_async_open( LDAP *ld, ber_socket_t sd )
00539 {
00540        struct timeval tv = { 0 };
00541        int rc;
00542 
00543        rc = ldap_int_poll( ld, sd, &tv );
00544        switch ( rc ) {
00545        case 0:
00546               /* now ready to start tls */
00547               ld->ld_defconn->lconn_status = LDAP_CONNST_CONNECTED;
00548               break;
00549 
00550        default:
00551               ld->ld_errno = LDAP_CONNECT_ERROR;
00552               return -1;
00553 
00554        case -2:
00555               /* connect not completed yet */
00556               ld->ld_errno = LDAP_X_CONNECTING;
00557               return rc;
00558        }
00559 
00560 #ifdef HAVE_TLS
00561        if ( ld->ld_options.ldo_tls_mode == LDAP_OPT_X_TLS_HARD ||
00562               !strcmp( ld->ld_defconn->lconn_server->lud_scheme, "ldaps" )) {
00563 
00564               ++ld->ld_defconn->lconn_refcnt;    /* avoid premature free */
00565 
00566               rc = ldap_int_tls_start( ld, ld->ld_defconn, ld->ld_defconn->lconn_server );
00567 
00568               --ld->ld_defconn->lconn_refcnt;
00569        }
00570 #endif
00571        return rc;
00572 }