X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=libraries%2Flibldap%2Fopen.c;h=1bc86e39a718d160eee2a8f03180bb135328b5c7;hb=a5cad3f18a4b8fbbbb1bfc5db9d00022d9ebbfc4;hp=a3a4144e452a6bf336035991d060d4ce08a779d4;hpb=6939c531700652491f4be4688c6a1f35a1ab8a18;p=openldap diff --git a/libraries/libldap/open.c b/libraries/libldap/open.c index a3a4144e45..1bc86e39a7 100644 --- a/libraries/libldap/open.c +++ b/libraries/libldap/open.c @@ -1,19 +1,27 @@ /* $OpenLDAP$ */ -/* - * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved. - * COPYING RESTRICTIONS APPLY, see COPYRIGHT file - */ -/* Portions - * Copyright (c) 1995 Regents of the University of Michigan. - * All rights reserved. +/* This work is part of OpenLDAP Software . + * + * Copyright 1998-2010 The OpenLDAP Foundation. + * All rights reserved. * - * open.c + * Redistribution and use in source and binary forms, with or without + * modification, are permitted only as authorized by the OpenLDAP + * Public License. + * + * A copy of this license is available in the file LICENSE in the + * top-level directory of the distribution or, alternatively, at + * . + */ +/* Portions Copyright (c) 1995 Regents of the University of Michigan. + * All rights reserved. */ #include "portable.h" #include +#ifdef HAVE_LIMITS_H #include +#endif #include @@ -27,10 +35,11 @@ #include "ldap-int.h" #include "ldap_log.h" +/* Caller should hold the req_mutex if 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 ); if( ld->ld_defconn == NULL ) { ld->ld_errno = LDAP_SERVER_DOWN; @@ -57,12 +66,8 @@ ldap_open( LDAP_CONST char *host, int port ) int rc; LDAP *ld; -#ifdef NEW_LOGGING - LDAP_LOG ( CONNECTION, ARGS, "ldap_open(%s, %d)\n", host, port, 0 ); -#else Debug( LDAP_DEBUG_TRACE, "ldap_open(%s, %d)\n", host, port, 0 ); -#endif ld = ldap_init( host, port ); if ( ld == NULL ) { @@ -76,13 +81,8 @@ ldap_open( LDAP_CONST char *host, int port ) ld = NULL; } -#ifdef NEW_LOGGING - LDAP_LOG ( CONNECTION, RESULTS, "ldap_open: %s\n", - ld == NULL ? "succeeded" : "failed", 0, 0 ); -#else Debug( LDAP_DEBUG_TRACE, "ldap_open: %s\n", - ld == NULL ? "succeeded" : "failed", 0, 0 ); -#endif + ld != NULL ? "succeeded" : "failed", 0, 0 ); return ld; } @@ -108,11 +108,7 @@ ldap_create( LDAP **ldp ) return LDAP_LOCAL_ERROR; } -#ifdef NEW_LOGGING - LDAP_LOG ( CONNECTION, ENTRY, "ldap_create\n", 0, 0, 0 ); -#else Debug( LDAP_DEBUG_TRACE, "ldap_create\n", 0, 0, 0 ); -#endif if ( (ld = (LDAP *) LDAP_CALLOC( 1, sizeof(LDAP) )) == NULL ) { return( LDAP_NO_MEMORY ); @@ -126,6 +122,8 @@ ldap_create( LDAP **ldp ) /* but not pointers to malloc'ed items */ ld->ld_options.ldo_sctrls = NULL; ld->ld_options.ldo_cctrls = NULL; + ld->ld_options.ldo_defludp = NULL; + ld->ld_options.ldo_conn_cbs = NULL; #ifdef HAVE_CYRUS_SASL ld->ld_options.ldo_def_sasl_mech = gopts->ldo_def_sasl_mech @@ -138,30 +136,47 @@ ldap_create( LDAP **ldp ) ? LDAP_STRDUP( gopts->ldo_def_sasl_authzid ) : NULL; #endif - ld->ld_options.ldo_defludp = ldap_url_duplist(gopts->ldo_defludp); +#ifdef HAVE_TLS + /* We explicitly inherit the SSL_CTX, don't need the names/paths. Leave + * them empty to allow new SSL_CTX's to be created from scratch. + */ + memset( &ld->ld_options.ldo_tls_info, 0, + sizeof( ld->ld_options.ldo_tls_info )); + ld->ld_options.ldo_tls_ctx = NULL; +#endif - if ( ld->ld_options.ldo_defludp == NULL ) { - LDAP_FREE( (char*)ld ); - return LDAP_NO_MEMORY; - } + if ( gopts->ldo_defludp ) { + ld->ld_options.ldo_defludp = ldap_url_duplist(gopts->ldo_defludp); - if (( ld->ld_selectinfo = ldap_new_select_info()) == NULL ) { - ldap_free_urllist( ld->ld_options.ldo_defludp ); - LDAP_FREE( (char*) ld ); - return LDAP_NO_MEMORY; + if ( ld->ld_options.ldo_defludp == NULL ) goto nomem; } + if (( ld->ld_selectinfo = ldap_new_select_info()) == NULL ) goto nomem; + ld->ld_lberoptions = LBER_USE_DER; ld->ld_sb = ber_sockbuf_alloc( ); - if ( ld->ld_sb == NULL ) { - ldap_free_urllist( ld->ld_options.ldo_defludp ); - LDAP_FREE( (char*) ld ); - return LDAP_NO_MEMORY; - } + if ( ld->ld_sb == NULL ) goto nomem; +#ifdef LDAP_R_COMPILE + 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 ); +#endif *ldp = ld; return LDAP_SUCCESS; + +nomem: + ldap_free_select_info( ld->ld_selectinfo ); + ldap_free_urllist( ld->ld_options.ldo_defludp ); +#ifdef HAVE_CYRUS_SASL + LDAP_FREE( ld->ld_options.ldo_def_sasl_authzid ); + LDAP_FREE( ld->ld_options.ldo_def_sasl_authcid ); + LDAP_FREE( ld->ld_options.ldo_def_sasl_realm ); + LDAP_FREE( ld->ld_options.ldo_def_sasl_mech ); +#endif + LDAP_FREE( (char *)ld ); + return LDAP_NO_MEMORY; } /* @@ -225,6 +240,97 @@ ldap_initialize( LDAP **ldp, LDAP_CONST char *url ) return LDAP_SUCCESS; } +int +ldap_init_fd( + ber_socket_t fd, + int proto, + LDAP_CONST char *url, + LDAP **ldp +) +{ + int rc; + LDAP *ld; + LDAPConn *conn; + + *ldp = NULL; + rc = ldap_create( &ld ); + if( rc != LDAP_SUCCESS ) + return( rc ); + + if (url != NULL) { + rc = ldap_set_option(ld, LDAP_OPT_URI, url); + if ( rc != LDAP_SUCCESS ) { + ldap_ld_free(ld, 1, NULL, NULL); + return rc; + } + } + + /* Attach the passed socket as the LDAP's connection */ + conn = ldap_new_connection( ld, NULL, 1, 0, NULL); + if( conn == NULL ) { + ldap_unbind_ext( ld, NULL, NULL ); + return( LDAP_NO_MEMORY ); + } + if( url ) + conn->lconn_server = ldap_url_dup( ld->ld_options.ldo_defludp ); + 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 */ + + switch( proto ) { + case LDAP_PROTO_TCP: +#ifdef LDAP_DEBUG + ber_sockbuf_add_io( conn->lconn_sb, &ber_sockbuf_io_debug, + LBER_SBIOD_LEVEL_PROVIDER, (void *)"tcp_" ); +#endif + ber_sockbuf_add_io( conn->lconn_sb, &ber_sockbuf_io_tcp, + LBER_SBIOD_LEVEL_PROVIDER, NULL ); + break; + +#ifdef LDAP_CONNECTIONLESS + case LDAP_PROTO_UDP: +#ifdef LDAP_DEBUG + ber_sockbuf_add_io( conn->lconn_sb, &ber_sockbuf_io_debug, + LBER_SBIOD_LEVEL_PROVIDER, (void *)"udp_" ); +#endif + ber_sockbuf_add_io( conn->lconn_sb, &ber_sockbuf_io_udp, + LBER_SBIOD_LEVEL_PROVIDER, NULL ); + ber_sockbuf_add_io( conn->lconn_sb, &ber_sockbuf_io_readahead, + LBER_SBIOD_LEVEL_PROVIDER, NULL ); + break; +#endif /* LDAP_CONNECTIONLESS */ + + case LDAP_PROTO_IPC: +#ifdef LDAP_DEBUG + ber_sockbuf_add_io( conn->lconn_sb, &ber_sockbuf_io_debug, + LBER_SBIOD_LEVEL_PROVIDER, (void *)"ipc_" ); +#endif + ber_sockbuf_add_io( conn->lconn_sb, &ber_sockbuf_io_fd, + LBER_SBIOD_LEVEL_PROVIDER, NULL ); + break; + + case LDAP_PROTO_EXT: + /* caller must supply sockbuf handlers */ + break; + + default: + ldap_unbind_ext( ld, NULL, NULL ); + return LDAP_PARAM_ERROR; + } + +#ifdef LDAP_DEBUG + ber_sockbuf_add_io( conn->lconn_sb, &ber_sockbuf_io_debug, + INT_MAX, (void *)"ldap_" ); +#endif + + /* Add the connection to the *LDAP's select pool */ + ldap_mark_select_read( ld, conn->lconn_sb ); + ldap_mark_select_write( ld, conn->lconn_sb ); + + *ldp = ld; + return LDAP_SUCCESS; +} + int ldap_int_open_connection( LDAP *ld, @@ -233,44 +339,16 @@ ldap_int_open_connection( int async ) { int rc = -1; -#ifdef HAVE_CYRUS_SASL - char *sasl_host = NULL; -#endif - char *host; - int port, proto; - long addr; + int proto; -#ifdef NEW_LOGGING - LDAP_LOG ( CONNECTION, ENTRY, "ldap_int_open_connection\n", 0, 0, 0 ); -#else Debug( LDAP_DEBUG_TRACE, "ldap_int_open_connection\n", 0, 0, 0 ); -#endif switch ( proto = ldap_pvt_url_scheme2proto( srv->lud_scheme ) ) { case LDAP_PROTO_TCP: - port = srv->lud_port; - - addr = 0; - if ( srv->lud_host == NULL || *srv->lud_host == 0 ) { - host = NULL; - addr = htonl( INADDR_LOOPBACK ); - } else { - host = srv->lud_host; - } - - if( !port ) { - if( strcmp(srv->lud_scheme, "ldaps") == 0 ) { - port = LDAPS_PORT; - } else { - port = LDAP_PORT; - } - } - rc = ldap_connect_to_host( ld, conn->lconn_sb, - proto, host, addr, port, async ); + proto, srv, async ); if ( rc == -1 ) return rc; - #ifdef LDAP_DEBUG ber_sockbuf_add_io( conn->lconn_sb, &ber_sockbuf_io_debug, LBER_SBIOD_LEVEL_PROVIDER, (void *)"tcp_" ); @@ -278,28 +356,13 @@ ldap_int_open_connection( ber_sockbuf_add_io( conn->lconn_sb, &ber_sockbuf_io_tcp, LBER_SBIOD_LEVEL_PROVIDER, NULL ); -#ifdef HAVE_CYRUS_SASL - sasl_host = ldap_host_connected_to( conn->lconn_sb ); -#endif break; -#ifdef LDAP_CONNECTIONLESS +#ifdef LDAP_CONNECTIONLESS case LDAP_PROTO_UDP: - port = srv->lud_port; - - addr = 0; - if ( srv->lud_host == NULL || *srv->lud_host == 0 ) { - host = NULL; - addr = htonl( INADDR_LOOPBACK ); - } else { - host = srv->lud_host; - } - - if( !port ) port = LDAP_PORT; - LDAP_IS_UDP(ld) = 1; rc = ldap_connect_to_host( ld, conn->lconn_sb, - proto, host, addr, port, async ); + proto, srv, async ); if ( rc == -1 ) return rc; #ifdef LDAP_DEBUG @@ -308,13 +371,17 @@ ldap_int_open_connection( #endif ber_sockbuf_add_io( conn->lconn_sb, &ber_sockbuf_io_udp, LBER_SBIOD_LEVEL_PROVIDER, NULL ); + + ber_sockbuf_add_io( conn->lconn_sb, &ber_sockbuf_io_readahead, + LBER_SBIOD_LEVEL_PROVIDER, NULL ); + break; #endif case LDAP_PROTO_IPC: #ifdef LDAP_PF_LOCAL /* only IPC mechanism supported is PF_LOCAL (PF_UNIX) */ rc = ldap_connect_to_path( ld, conn->lconn_sb, - srv->lud_host, async ); + srv, async ); if ( rc == -1 ) return rc; #ifdef LDAP_DEBUG ber_sockbuf_add_io( conn->lconn_sb, &ber_sockbuf_io_debug, @@ -323,9 +390,6 @@ ldap_int_open_connection( ber_sockbuf_add_io( conn->lconn_sb, &ber_sockbuf_io_fd, LBER_SBIOD_LEVEL_PROVIDER, NULL ); -#ifdef HAVE_CYRUS_SASL - sasl_host = ldap_host_connected_to( conn->lconn_sb ); -#endif break; #endif /* LDAP_PF_LOCAL */ default: @@ -333,8 +397,7 @@ ldap_int_open_connection( break; } - ber_sockbuf_add_io( conn->lconn_sb, &ber_sockbuf_io_readahead, - LBER_SBIOD_LEVEL_PROVIDER, NULL ); + conn->lconn_created = time( NULL ); #ifdef LDAP_DEBUG ber_sockbuf_add_io( conn->lconn_sb, &ber_sockbuf_io_debug, @@ -342,25 +405,7 @@ ldap_int_open_connection( #endif #ifdef LDAP_CONNECTIONLESS - if( proto == LDAP_PROTO_UDP ) - return 0; -#endif - -#ifdef HAVE_CYRUS_SASL - /* establish Cyrus SASL context prior to starting TLS so - that SASL EXTERNAL might be used */ - if( sasl_host != NULL ) { - ldap_int_sasl_open( ld, conn, sasl_host ); - LDAP_FREE( sasl_host ); - } - if( proto == LDAP_PROTO_IPC ) { - char authid[sizeof("uidNumber=4294967295,gidNumber=4294967295," - "cn=peercred,cn=external,cn=auth")]; - sprintf( authid, "uidNumber=%d,gidNumber=%d," - "cn=peercred,cn=external,cn=auth", - geteuid(), getegid() ); - ldap_int_sasl_external( ld, conn, authid, LDAP_PVT_SASL_LOCAL_SSF); - } + if( proto == LDAP_PROTO_UDP ) return 0; #endif #ifdef HAVE_TLS @@ -379,23 +424,12 @@ ldap_int_open_connection( } #endif -#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND - if ( conn->lconn_krbinstance == NULL ) { - char *c; - conn->lconn_krbinstance = ldap_host_connected_to( conn->lconn_sb ); - - if( conn->lconn_krbinstance != NULL && - ( c = strchr( conn->lconn_krbinstance, '.' )) != NULL ) { - *c = '\0'; - } - } -#endif /* LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND */ - return( 0 ); } -int ldap_open_internal_connection( LDAP **ldp, ber_socket_t *fdp ) +int +ldap_open_internal_connection( LDAP **ldp, ber_socket_t *fdp ) { int rc; LDAPConn *c; @@ -410,7 +444,7 @@ int 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( *ldp ); + ldap_unbind_ext( *ldp, NULL, NULL ); *ldp = NULL; return( LDAP_NO_MEMORY ); } @@ -418,12 +452,13 @@ int ldap_open_internal_connection( LDAP **ldp, ber_socket_t *fdp ) lr->lr_msgid = 0; 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; /* Attach the passed socket as the *LDAP's connection */ c = ldap_new_connection( *ldp, NULL, 1, 0, NULL); if( c == NULL ) { - ldap_unbind( *ldp ); + ldap_unbind_ext( *ldp, NULL, NULL ); *ldp = NULL; return( LDAP_NO_MEMORY ); }