int ldap_open_internal_connection( LDAP **ldp, ber_socket_t *fdp ) { int rc; LDAPConn *c; LDAPRequest *lr; LDAP *ld; rc = ldap_create( &ld ); if( rc != LDAP_SUCCESS ) { *ldp = NULL; return( rc ); } /* Make it appear that a search request, msgid 0, was sent */ lr = (LDAPRequest *)LDAP_CALLOC( 1, sizeof( LDAPRequest )); if( lr == NULL ) { ldap_unbind_ext( ld, NULL, NULL ); *ldp = NULL; return( LDAP_NO_MEMORY ); } memset(lr, 0, sizeof( LDAPRequest )); 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 */ ld->ld_requests = lr; LDAP_MUTEX_LOCK( &ld->ld_conn_mutex ); /* Attach the passed socket as the *LDAP's connection */ c = ldap_new_connection( ld, NULL, 1, 0, NULL, 0, 0 ); if( c == 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 ); #ifdef LDAP_DEBUG ber_sockbuf_add_io( c->lconn_sb, &ber_sockbuf_io_debug, LBER_SBIOD_LEVEL_PROVIDER, (void *)"int_" ); #endif ber_sockbuf_add_io( c->lconn_sb, &ber_sockbuf_io_tcp, LBER_SBIOD_LEVEL_PROVIDER, NULL ); ld->ld_defconn = c; LDAP_MUTEX_UNLOCK( &ld->ld_conn_mutex ); /* Add the connection to the *LDAP's select pool */ 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( ld, LDAP_OPT_PROTOCOL_VERSION, &rc ); *ldp = ld; ++ld->ld_defconn->lconn_refcnt; /* so it never gets closed/freed */ return( LDAP_SUCCESS ); }
void nsldapi_dump_requests_and_responses( LDAP *ld ) { LDAPRequest *lr; LDAPMessage *lm, *l; char msg[256]; ber_err_print( "** Outstanding Requests:\n" ); LDAP_MUTEX_LOCK( ld, LDAP_REQ_LOCK ); if (( lr = ld->ld_requests ) == NULL ) { ber_err_print( " Empty\n" ); } for ( ; lr != NULL; lr = lr->lr_next ) { sprintf( msg, " * msgid %d, origid %d, status %s\n", lr->lr_msgid, lr->lr_origid, ( lr->lr_status == LDAP_REQST_INPROGRESS ) ? "InProgress" : ( lr->lr_status == LDAP_REQST_CHASINGREFS ) ? "ChasingRefs" : ( lr->lr_status == LDAP_REQST_NOTCONNECTED ) ? "NotConnected" : ( lr->lr_status == LDAP_REQST_CONNDEAD ) ? "Dead" : "Writing" ); ber_err_print( msg ); sprintf( msg, " outstanding referrals %d, parent count %d\n", lr->lr_outrefcnt, lr->lr_parentcnt ); ber_err_print( msg ); if ( lr->lr_binddn != NULL ) { sprintf( msg, " pending bind DN: <%s>\n", lr->lr_binddn ); ber_err_print( msg ); } } LDAP_MUTEX_UNLOCK( ld, LDAP_REQ_LOCK ); ber_err_print( "** Response Queue:\n" ); LDAP_MUTEX_LOCK( ld, LDAP_RESP_LOCK ); if (( lm = ld->ld_responses ) == NULLMSG ) { ber_err_print( " Empty\n" ); } for ( ; lm != NULLMSG; lm = lm->lm_next ) { sprintf( msg, " * msgid %d, type %d\n", lm->lm_msgid, lm->lm_msgtype ); ber_err_print( msg ); if (( l = lm->lm_chain ) != NULL ) { ber_err_print( " chained responses:\n" ); for ( ; l != NULLMSG; l = l->lm_chain ) { sprintf( msg, " * msgid %d, type %d\n", l->lm_msgid, l->lm_msgtype ); ber_err_print( msg ); } } } LDAP_MUTEX_UNLOCK( ld, LDAP_RESP_LOCK ); }
/* returns the message id of the request or -1 if an error occurs */ int nsldapi_send_initial_request( LDAP *ld, int msgid, unsigned long msgtype, char *dn, BerElement *ber ) { LDAPServer *servers; LDAPDebug( LDAP_DEBUG_TRACE, "nsldapi_send_initial_request\n", 0,0,0 ); #ifdef LDAP_DNS LDAP_MUTEX_LOCK( ld, LDAP_OPTION_LOCK ); if (( ld->ld_options & LDAP_BITOPT_DNS ) != 0 && ldap_is_dns_dn( dn )) { if (( servers = dn2servers( ld, dn )) == NULL ) { ber_free( ber, 1 ); LDAP_MUTEX_UNLOCK( ld, LDAP_OPTION_LOCK ); return( -1 ); } #ifdef LDAP_DEBUG if ( ldap_debug & LDAP_DEBUG_TRACE ) { LDAPServer *srv; char msg[256]; for ( srv = servers; srv != NULL; srv = srv->lsrv_next ) { sprintf( msg, "LDAP server %s: dn %s, port %d\n", srv->lsrv_host, ( srv->lsrv_dn == NULL ) ? "(default)" : srv->lsrv_dn, srv->lsrv_port ); ber_err_print( msg ); } } #endif /* LDAP_DEBUG */ } else { #endif /* LDAP_DNS */ /* * use of DNS is turned off or this is an LDAP DN... * use our default connection */ servers = NULL; #ifdef LDAP_DNS } LDAP_MUTEX_UNLOCK( ld, LDAP_OPTION_LOCK ); #endif /* LDAP_DNS */ return( nsldapi_send_server_request( ld, ber, msgid, NULL, servers, NULL, ( msgtype == LDAP_REQ_BIND ) ? dn : NULL, 0 )); }
LDAP * ldap_open( LDAP_CONST char *host, int port ) { int rc; LDAP *ld; Debug( LDAP_DEBUG_TRACE, "ldap_open(%s, %d)\n", host, port, 0 ); ld = ldap_init( host, port ); if ( ld == NULL ) { 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 ); ld = NULL; } Debug( LDAP_DEBUG_TRACE, "ldap_open: %s\n", ld != NULL ? "succeeded" : "failed", 0, 0 ); return ld; }
void nsldapi_handle_reconnect( LDAP *ld ) { LDAPDebug( LDAP_DEBUG_TRACE, "nsldapi_handle_reconnect\n", 0, 0, 0 ); /* * if the default connection has been lost and is now marked dead, * dispose of the default connection so it will get re-established. * * if not, clear the bind DN and status to ensure that we don't * report the wrong bind DN to a different thread while waiting * for our bind result to return from the server. */ LDAP_MUTEX_LOCK( ld, LDAP_CONN_LOCK ); if ( NULL != ld->ld_defconn ) { if ( LDAP_CONNST_DEAD == ld->ld_defconn->lconn_status ) { nsldapi_free_connection( ld, ld->ld_defconn, NULL, NULL, 1, 0 ); ld->ld_defconn = NULL; } else if ( ld->ld_defconn->lconn_binddn != NULL ) { NSLDAPI_FREE( ld->ld_defconn->lconn_binddn ); ld->ld_defconn->lconn_binddn = NULL; ld->ld_defconn->lconn_bound = 0; } } LDAP_MUTEX_UNLOCK( ld, LDAP_CONN_LOCK ); }
void ldap_pvt_gettime( struct lutil_tm *ltm ) { struct timeval tv; static struct timeval prevTv; static int subs; struct tm tm; time_t t; gettimeofday( &tv, NULL ); t = tv.tv_sec; LDAP_MUTEX_LOCK( &ldap_int_gettime_mutex ); if ( tv.tv_sec < prevTv.tv_sec || ( tv.tv_sec == prevTv.tv_sec && tv.tv_usec <= prevTv.tv_usec )) { subs++; } else { subs = 0; prevTv = tv; } LDAP_MUTEX_UNLOCK( &ldap_int_gettime_mutex ); ltm->tm_usub = subs; ldap_pvt_gmtime( &t, &tm ); ltm->tm_sec = tm.tm_sec; ltm->tm_min = tm.tm_min; ltm->tm_hour = tm.tm_hour; ltm->tm_mday = tm.tm_mday; ltm->tm_mon = tm.tm_mon; ltm->tm_year = tm.tm_year; ltm->tm_usec = tv.tv_usec; }
static void tlsg_ctx_ref( tls_ctx *ctx ) { tlsg_ctx *c = (tlsg_ctx *)ctx; LDAP_MUTEX_LOCK( &c->ref_mutex ); c->refcount++; LDAP_MUTEX_UNLOCK( &c->ref_mutex ); }
/* * ldap_mark_abandoned */ static int ldap_mark_abandoned( LDAP *ld, ber_int_t msgid ) { int ret, idx; assert( msgid >= 0 ); LDAP_MUTEX_LOCK( &ld->ld_abandon_mutex ); ret = ldap_int_bisect_find( ld->ld_abandoned, ld->ld_nabandoned, msgid, &idx ); if (ret <= 0) { /* error or already deleted by another thread */ LDAP_MUTEX_UNLOCK( &ld->ld_abandon_mutex ); return ret; } /* still in abandoned array, so delete */ ret = ldap_int_bisect_delete( &ld->ld_abandoned, &ld->ld_nabandoned, msgid, idx ); LDAP_MUTEX_UNLOCK( &ld->ld_abandon_mutex ); return ret; }
int ldap_x_sasl_digest_md5_bind_s( LDAP *ld, char *user_name, struct berval *cred, LDAPControl **serverctrls, LDAPControl **clientctrls) { struct berval *challenge = NULL; int errnum; char *digest = NULL; struct berval resp; LDAPDebug(LDAP_DEBUG_TRACE, "ldap_x_sasl_digest_md5_bind_s\n", 0, 0, 0); /* Add debug */ if (ld == NULL || user_name == NULL || cred == NULL || cred->bv_val == NULL) return (LDAP_PARAM_ERROR); if (ld->ld_version < LDAP_VERSION3) return (LDAP_PARAM_ERROR); errnum = ldap_sasl_bind_s(ld, NULL, LDAP_SASL_DIGEST_MD5, NULL, serverctrls, clientctrls, &challenge); if (errnum == LDAP_SASL_BIND_IN_PROGRESS) { if (challenge != NULL) { LDAPDebug(LDAP_DEBUG_TRACE, "SASL challenge: %s\n", challenge->bv_val, 0, 0); errnum = ldap_digest_md5_encode(challenge->bv_val, user_name, cred->bv_val, &digest); ber_bvfree(challenge); challenge = NULL; if (errnum == LDAP_SUCCESS) { resp.bv_val = digest; resp.bv_len = strlen(digest); LDAPDebug(LDAP_DEBUG_TRACE, "SASL reply: %s\n", digest, 0, 0); errnum = ldap_sasl_bind_s(ld, NULL, LDAP_SASL_DIGEST_MD5, &resp, serverctrls, clientctrls, &challenge); free(digest); } if (challenge != NULL) ber_bvfree(challenge); } else { errnum = LDAP_NO_MEMORY; /* TO DO: What val? */ } } LDAP_MUTEX_LOCK(ld, LDAP_ERR_LOCK); ld->ld_errno = errnum; LDAP_MUTEX_UNLOCK(ld, LDAP_ERR_LOCK); return (errnum); }
/* * ldap_sasl_interactive_bind_ext_s * * This function extends ldap_sasl_interactive_bind_s by allowing * controls received from the server to be returned as rctrl. The * caller must pass in a valid LDAPControl** pointer and free the * array of controls when finished with them e.g. * LDAPControl **retctrls = NULL; * ... * ldap_sasl_interactive_bind_ext_s(ld, ...., &retctrls); * ... * ldap_controls_free(retctrls); * Only the controls from the server during the last bind step are returned - * intermediate controls (if any, usually not) are discarded. */ int LDAP_CALL ldap_sasl_interactive_bind_ext_s( LDAP *ld, const char *dn, const char *saslMechanism, LDAPControl **sctrl, LDAPControl **cctrl, unsigned flags, LDAP_SASL_INTERACT_PROC *callback, void *defaults, LDAPControl ***rctrl ) { #ifdef LDAP_SASLIO_GET_MECHS_FROM_SERVER char *smechs; #endif int rc; LDAPDebug( LDAP_DEBUG_TRACE, "ldap_sasl_interactive_bind_s\n", 0, 0, 0 ); if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) { return( LDAP_PARAM_ERROR ); } if ((flags == LDAP_SASL_INTERACTIVE) && (callback == NULL)) { return( LDAP_PARAM_ERROR ); } LDAP_MUTEX_LOCK(ld, LDAP_SASL_LOCK ); if( saslMechanism == NULL || *saslMechanism == '\0' ) { #ifdef LDAP_SASLIO_GET_MECHS_FROM_SERVER rc = nsldapi_get_sasl_mechs( ld, &smechs ); if( rc != LDAP_SUCCESS ) { LDAP_MUTEX_UNLOCK(ld, LDAP_SASL_LOCK ); return( rc ); } saslMechanism = smechs; #else LDAP_MUTEX_UNLOCK(ld, LDAP_SASL_LOCK ); return( LDAP_PARAM_ERROR ); #endif /* LDAP_SASLIO_GET_MECHS_FROM_SERVER */ } rc = nsldapi_sasl_do_bind( ld, dn, saslMechanism, flags, callback, defaults, sctrl, cctrl, rctrl); LDAP_MUTEX_UNLOCK(ld, LDAP_SASL_LOCK ); return( rc ); }
/* * initialize the default context */ int ldap_pvt_tls_init_def_ctx( int is_server ) { struct ldapoptions *lo = LDAP_INT_GLOBAL_OPT(); int rc; LDAP_MUTEX_LOCK( &tls_def_ctx_mutex ); rc = ldap_int_tls_init_ctx( lo, is_server ); LDAP_MUTEX_UNLOCK( &tls_def_ctx_mutex ); return rc; }
/* * ldap_abandoned * * return the location of the message id in the array of abandoned * message ids, or -1 */ static int ldap_abandoned( LDAP *ld, ber_int_t msgid ) { int ret, idx; assert( msgid >= 0 ); LDAP_MUTEX_LOCK( &ld->ld_abandon_mutex ); ret = ldap_int_bisect_find( ld->ld_abandoned, ld->ld_nabandoned, msgid, &idx ); LDAP_MUTEX_UNLOCK( &ld->ld_abandon_mutex ); return ret; }
int ldap_pvt_discard( LDAP *ld, ber_int_t msgid ) { int rc; LDAP_MUTEX_LOCK( &ld->ld_req_mutex ); rc = do_abandon( ld, msgid, msgid, NULL, 0 ); LDAP_MUTEX_UNLOCK( &ld->ld_req_mutex ); return rc; }
LDAP *LDAP_CALL ldap_open(const char *host, int port) { LDAP *ld; LDAPDebug(LDAP_DEBUG_TRACE, "ldap_open\n", 0, 0, 0); if ((ld = ldap_init(host, port)) == NULL) { return (NULL); } LDAP_MUTEX_LOCK(ld, LDAP_CONN_LOCK); if (nsldapi_open_ldap_defconn(ld) < 0) { LDAP_MUTEX_UNLOCK(ld, LDAP_CONN_LOCK); ldap_ld_free(ld, NULL, NULL, 0); return (NULL); } LDAP_MUTEX_UNLOCK(ld, LDAP_CONN_LOCK); LDAPDebug(LDAP_DEBUG_TRACE, "ldap_open successful, ld_host is %s\n", (ld->ld_host == NULL) ? "(null)" : ld->ld_host, 0, 0); return (ld); }
/* sets needed mutexes - no mutexes set to this point */ ber_int_t ldap_send_initial_request( LDAP *ld, ber_tag_t msgtype, const char *dn, BerElement *ber, ber_int_t msgid) { int rc = 1; ber_socket_t sd = AC_SOCKET_INVALID; Debug( LDAP_DEBUG_TRACE, "ldap_send_initial_request\n", 0, 0, 0 ); LDAP_MUTEX_LOCK( &ld->ld_conn_mutex ); if ( ber_sockbuf_ctrl( ld->ld_sb, LBER_SB_OPT_GET_FD, &sd ) == -1 ) { /* not connected yet */ rc = ldap_open_defconn( ld ); } if ( ld->ld_defconn && ld->ld_defconn->lconn_status == LDAP_CONNST_CONNECTING ) rc = ldap_int_check_async_open( ld, sd ); if( rc < 0 ) { ber_free( ber, 1 ); LDAP_MUTEX_UNLOCK( &ld->ld_conn_mutex ); return( -1 ); } else if ( rc == 0 ) { Debug( LDAP_DEBUG_TRACE, "ldap_open_defconn: successful\n", 0, 0, 0 ); } #ifdef LDAP_CONNECTIONLESS if (LDAP_IS_UDP(ld)) { if (msgtype == LDAP_REQ_BIND) { LDAP_MUTEX_LOCK( &ld->ld_options.ldo_mutex ); if (ld->ld_options.ldo_cldapdn) ldap_memfree(ld->ld_options.ldo_cldapdn); ld->ld_options.ldo_cldapdn = ldap_strdup(dn); ber_free( ber, 1 ); LDAP_MUTEX_UNLOCK( &ld->ld_options.ldo_mutex ); LDAP_MUTEX_UNLOCK( &ld->ld_conn_mutex ); return 0; } if (msgtype != LDAP_REQ_ABANDON && msgtype != LDAP_REQ_SEARCH) { ber_free( ber, 1 ); LDAP_MUTEX_UNLOCK( &ld->ld_conn_mutex ); return LDAP_PARAM_ERROR; } } #endif LDAP_MUTEX_LOCK( &ld->ld_req_mutex ); rc = ldap_send_server_request( ld, ber, msgid, NULL, NULL, NULL, NULL, 0, 0 ); LDAP_MUTEX_UNLOCK( &ld->ld_req_mutex ); LDAP_MUTEX_UNLOCK( &ld->ld_conn_mutex ); return(rc); }
/* * 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; }
/* * LDAPv3 extended abandon. * Returns an LDAP error code. */ int LDAP_CALL ldap_abandon_ext(LDAP *ld, int msgid, LDAPControl **serverctrls, LDAPControl **clientctrls) { int rc; LDAPDebug(LDAP_DEBUG_TRACE, "ldap_abandon_ext %d\n", msgid, 0, 0); if (!NSLDAPI_VALID_LDAP_POINTER(ld)) { return (LDAP_PARAM_ERROR); } LDAP_MUTEX_LOCK(ld, LDAP_CONN_LOCK); LDAP_MUTEX_LOCK(ld, LDAP_REQ_LOCK); rc = do_abandon(ld, msgid, msgid, serverctrls, clientctrls); /* * XXXmcs should use cache function pointers to hook in memcache */ ldap_memcache_abandon(ld, msgid); LDAP_MUTEX_UNLOCK(ld, LDAP_REQ_LOCK); LDAP_MUTEX_UNLOCK(ld, LDAP_CONN_LOCK); return (rc); }
/* * ldap_msgdelete - delete a message. It returns: * 0 if the entire message was deleted * -1 if the message was not found, or only part of it was found */ int ldap_msgdelete( LDAP *ld, int msgid ) { LDAPMessage *lm, *prev; int rc = 0; assert( ld != NULL ); Debug( LDAP_DEBUG_TRACE, "ldap_msgdelete ld=%p msgid=%d\n", (void *)ld, msgid, 0 ); LDAP_MUTEX_LOCK( &ld->ld_res_mutex ); prev = NULL; for ( lm = ld->ld_responses; lm != NULL; lm = lm->lm_next ) { if ( lm->lm_msgid == msgid ) { break; } prev = lm; } if ( lm == NULL ) { rc = -1; } else { if ( prev == NULL ) { ld->ld_responses = lm->lm_next; } else { prev->lm_next = lm->lm_next; } } LDAP_MUTEX_UNLOCK( &ld->ld_res_mutex ); if ( lm ) { switch ( ldap_msgfree( lm ) ) { case LDAP_RES_SEARCH_ENTRY: case LDAP_RES_SEARCH_REFERENCE: case LDAP_RES_INTERMEDIATE: rc = -1; break; default: break; } } return rc; }
void ldap_dump_connection( LDAP *ld, LDAPConn *lconns, int all ) { LDAPConn *lc; char timebuf[32]; Debug( LDAP_DEBUG_TRACE, "** ld %p Connection%s:\n", (void *)ld, all ? "s" : "", 0 ); LDAP_MUTEX_LOCK( &ld->ld_conn_mutex ); for ( lc = lconns; lc != NULL; lc = lc->lconn_next ) { if ( lc->lconn_server != NULL ) { Debug( LDAP_DEBUG_TRACE, "* host: %s port: %d%s\n", ( lc->lconn_server->lud_host == NULL ) ? "(null)" : lc->lconn_server->lud_host, lc->lconn_server->lud_port, ( lc->lconn_sb == ld->ld_sb ) ? " (default)" : "" ); } Debug( LDAP_DEBUG_TRACE, " refcnt: %d status: %s\n", lc->lconn_refcnt, ( lc->lconn_status == LDAP_CONNST_NEEDSOCKET ) ? "NeedSocket" : ( lc->lconn_status == LDAP_CONNST_CONNECTING ) ? "Connecting" : "Connected", 0 ); Debug( LDAP_DEBUG_TRACE, " last used: %s%s\n", ldap_pvt_ctime( &lc->lconn_lastused, timebuf ), lc->lconn_rebind_inprogress ? " rebind in progress" : "", 0 ); if ( lc->lconn_rebind_inprogress ) { if ( lc->lconn_rebind_queue != NULL) { int i; for ( i = 0; lc->lconn_rebind_queue[i] != NULL; i++ ) { int j; for( j = 0; lc->lconn_rebind_queue[i][j] != 0; j++ ) { Debug( LDAP_DEBUG_TRACE, " queue %d entry %d - %s\n", i, j, lc->lconn_rebind_queue[i][j] ); } } } else { Debug( LDAP_DEBUG_TRACE, " queue is empty\n", 0, 0, 0 ); } } Debug( LDAP_DEBUG_TRACE, "\n", 0, 0, 0 ); if ( !all ) { break; } } LDAP_MUTEX_UNLOCK( &ld->ld_conn_mutex ); }
struct tm * ldap_pvt_localtime( const time_t *timep, struct tm *result ) { struct tm *tm_ptr; LDAP_MUTEX_LOCK( &ldap_int_gmtime_mutex ); tm_ptr = localtime( timep ); if ( tm_ptr == NULL ) { result = NULL; } else { *result = *tm_ptr; } LDAP_MUTEX_UNLOCK( &ldap_int_gmtime_mutex ); return result; }
/* * return a pointer to the bind DN for the default connection (a copy is * not made). If there is no bind DN available, NULL is returned. */ char * nsldapi_get_binddn( LDAP *ld ) { char *binddn; binddn = NULL; /* default -- assume they are not bound */ LDAP_MUTEX_LOCK( ld, LDAP_CONN_LOCK ); if ( NULL != ld->ld_defconn && LDAP_CONNST_CONNECTED == ld->ld_defconn->lconn_status && ld->ld_defconn->lconn_bound ) { if (( binddn = ld->ld_defconn->lconn_binddn ) == NULL ) { binddn = ""; } } LDAP_MUTEX_UNLOCK( ld, LDAP_CONN_LOCK ); return( binddn ); }
static void tlsg_ctx_free ( tls_ctx *ctx ) { tlsg_ctx *c = (tlsg_ctx *)ctx; int refcount; if ( !c ) return; LDAP_MUTEX_LOCK( &c->ref_mutex ); refcount = --c->refcount; LDAP_MUTEX_UNLOCK( &c->ref_mutex ); if ( refcount ) return; gnutls_priority_deinit( c->prios ); gnutls_certificate_free_credentials( c->cred ); if ( c->dh_params ) gnutls_dh_params_deinit( c->dh_params ); ber_memfree ( c ); }
void LDAP_CALL ldap_set_rebind_proc( LDAP *ld, LDAP_REBINDPROC_CALLBACK *rebindproc, void *arg ) { if ( ld == NULL ) { if ( !nsldapi_initialized ) { nsldapi_initialize_defaults(); } ld = &nsldapi_ld_defaults; } if ( NSLDAPI_VALID_LDAP_POINTER( ld )) { LDAP_MUTEX_LOCK( ld, LDAP_OPTION_LOCK ); ld->ld_rebind_fn = rebindproc; ld->ld_rebind_arg = arg; LDAP_MUTEX_UNLOCK( ld, LDAP_OPTION_LOCK ); } }
/* returns an LDAP error code and also sets error inside LDAP * */ int nsldapi_alloc_ber_with_options( LDAP *ld, BerElement **berp ) { int err; LDAP_MUTEX_LOCK( ld, LDAP_OPTION_LOCK ); if (( *berp = ber_alloc_t( ld->ld_lberoptions )) == NULLBER ) { err = LDAP_NO_MEMORY; LDAP_SET_LDERRNO( ld, err, NULL, NULL ); } else { err = LDAP_SUCCESS; #ifdef STR_TRANSLATION nsldapi_set_ber_options( ld, *berp ); #endif /* STR_TRANSLATION */ } LDAP_MUTEX_UNLOCK( ld, LDAP_OPTION_LOCK ); return( err ); }
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 ); }
static void tlsg_ctx_free ( tls_ctx *ctx ) { tlsg_ctx *c = (tlsg_ctx *)ctx; int refcount; if ( !c ) return; LDAP_MUTEX_LOCK( &c->ref_mutex ); refcount = --c->refcount; LDAP_MUTEX_UNLOCK( &c->ref_mutex ); if ( refcount ) return; #ifdef HAVE_CIPHERSUITES gnutls_priority_deinit( c->prios ); #else LDAP_FREE( c->kx_list ); #endif gnutls_certificate_free_credentials( c->cred ); ber_memfree ( c ); }
char *ldap_pvt_ctime( const time_t *tp, char *buf ) { #ifdef USE_CTIME_R # if (CTIME_R_NARGS > 3) || (CTIME_R_NARGS < 2) # error "CTIME_R_NARGS should be 2 or 3" # elif CTIME_R_NARGS > 2 && defined(CTIME_R_RETURNS_INT) return( ctime_r(tp,buf,26) < 0 ? 0 : buf ); # elif CTIME_R_NARGS > 2 return ctime_r(tp,buf,26); # else return ctime_r(tp,buf); # endif #else LDAP_MUTEX_LOCK( &ldap_int_ctime_mutex ); AC_MEMCPY( buf, ctime(tp), 26 ); LDAP_MUTEX_UNLOCK( &ldap_int_ctime_mutex ); return buf; #endif }
/* * ldap_abandon_ext - perform an ldap extended abandon operation. * * Parameters: * ld LDAP descriptor * msgid The message id of the operation to abandon * scntrls Server Controls * ccntrls Client Controls * * ldap_abandon_ext returns a LDAP error code. * (LDAP_SUCCESS if everything went ok) * * Example: * ldap_abandon_ext( ld, msgid, scntrls, ccntrls ); */ int ldap_abandon_ext( LDAP *ld, int msgid, LDAPControl **sctrls, LDAPControl **cctrls ) { int rc; Debug( LDAP_DEBUG_TRACE, "ldap_abandon_ext %d\n", msgid, 0, 0 ); /* check client controls */ LDAP_MUTEX_LOCK( &ld->ld_req_mutex ); rc = ldap_int_client_controls( ld, cctrls ); if ( rc == LDAP_SUCCESS ) { rc = do_abandon( ld, msgid, msgid, sctrls, 1 ); } LDAP_MUTEX_UNLOCK( &ld->ld_req_mutex ); return rc; }
/* * ldap_result - wait for an ldap result response to a message from the * ldap server. If msgid is LDAP_RES_ANY (-1), any message will be * accepted. If msgid is LDAP_RES_UNSOLICITED (0), any unsolicited * message is accepted. Otherwise ldap_result will wait for a response * with msgid. If all is LDAP_MSG_ONE (0) the first message with id * msgid will be accepted, otherwise, ldap_result will wait for all * responses with id msgid and then return a pointer to the entire list * of messages. In general, this is only useful for search responses, * which can be of three message types (zero or more entries, zero or * search references, followed by an ldap result). An extension to * LDAPv3 allows partial extended responses to be returned in response * to any request. The type of the first message received is returned. * When waiting, any messages that have been abandoned/discarded are * discarded. * * Example: * ldap_result( s, msgid, all, timeout, result ) */ int ldap_result( LDAP *ld, int msgid, int all, struct timeval *timeout, LDAPMessage **result ) { int rc; assert( ld != NULL ); assert( result != NULL ); Debug( LDAP_DEBUG_TRACE, "ldap_result ld %p msgid %d\n", (void *)ld, msgid, 0 ); if (ld->ld_errno == LDAP_LOCAL_ERROR || ld->ld_errno == LDAP_SERVER_DOWN) return -1; LDAP_MUTEX_LOCK( &ld->ld_res_mutex ); rc = wait4msg( ld, msgid, all, timeout, result ); LDAP_MUTEX_UNLOCK( &ld->ld_res_mutex ); return rc; }
int ldap_ld_free( LDAP *ld, int close, LDAPControl **sctrls, LDAPControl **cctrls ) { LDAPMessage *lm, *next; int err = LDAP_SUCCESS; LDAP_MUTEX_LOCK( &ld->ld_ldcmutex ); /* Someone else is still using this ld. */ if (ld->ld_ldcrefcnt > 1) { /* but not last thread */ /* clean up self only */ ld->ld_ldcrefcnt--; if ( ld->ld_error != NULL ) { LDAP_FREE( ld->ld_error ); ld->ld_error = NULL; } if ( ld->ld_matched != NULL ) { LDAP_FREE( ld->ld_matched ); ld->ld_matched = NULL; } if ( ld->ld_referrals != NULL) { LDAP_VFREE(ld->ld_referrals); ld->ld_referrals = NULL; } LDAP_MUTEX_UNLOCK( &ld->ld_ldcmutex ); LDAP_FREE( (char *) ld ); return( err ); } /* This ld is the last thread. */ /* free LDAP structure and outstanding requests/responses */ LDAP_MUTEX_LOCK( &ld->ld_req_mutex ); while ( ld->ld_requests != NULL ) { ldap_free_request( ld, ld->ld_requests ); } LDAP_MUTEX_UNLOCK( &ld->ld_req_mutex ); LDAP_MUTEX_LOCK( &ld->ld_conn_mutex ); /* free and unbind from all open connections */ while ( ld->ld_conns != NULL ) { ldap_free_connection( ld, ld->ld_conns, 1, close ); } LDAP_MUTEX_UNLOCK( &ld->ld_conn_mutex ); LDAP_MUTEX_LOCK( &ld->ld_res_mutex ); for ( lm = ld->ld_responses; lm != NULL; lm = next ) { next = lm->lm_next; ldap_msgfree( lm ); } if ( ld->ld_abandoned != NULL ) { LDAP_FREE( ld->ld_abandoned ); ld->ld_abandoned = NULL; } LDAP_MUTEX_UNLOCK( &ld->ld_res_mutex ); LDAP_MUTEX_LOCK( &ld->ld_ldopts_mutex ); /* final close callbacks */ { ldaplist *ll, *next; for ( ll = ld->ld_options.ldo_conn_cbs; ll; ll = next ) { ldap_conncb *cb = ll->ll_data; next = ll->ll_next; cb->lc_del( ld, NULL, cb ); LDAP_FREE( ll ); } } if ( ld->ld_error != NULL ) { LDAP_FREE( ld->ld_error ); ld->ld_error = NULL; } if ( ld->ld_matched != NULL ) { LDAP_FREE( ld->ld_matched ); ld->ld_matched = NULL; } if ( ld->ld_referrals != NULL) { LDAP_VFREE(ld->ld_referrals); ld->ld_referrals = NULL; } if ( ld->ld_selectinfo != NULL ) { ldap_free_select_info( ld->ld_selectinfo ); ld->ld_selectinfo = NULL; } if ( ld->ld_options.ldo_defludp != NULL ) { ldap_free_urllist( ld->ld_options.ldo_defludp ); ld->ld_options.ldo_defludp = NULL; } #ifdef LDAP_CONNECTIONLESS if ( ld->ld_options.ldo_peer != NULL ) { LDAP_FREE( ld->ld_options.ldo_peer ); ld->ld_options.ldo_peer = NULL; } if ( ld->ld_options.ldo_cldapdn != NULL ) { LDAP_FREE( ld->ld_options.ldo_cldapdn ); ld->ld_options.ldo_cldapdn = NULL; } #endif #ifdef HAVE_CYRUS_SASL if ( ld->ld_options.ldo_def_sasl_mech != NULL ) { LDAP_FREE( ld->ld_options.ldo_def_sasl_mech ); ld->ld_options.ldo_def_sasl_mech = NULL; } if ( ld->ld_options.ldo_def_sasl_realm != NULL ) { LDAP_FREE( ld->ld_options.ldo_def_sasl_realm ); ld->ld_options.ldo_def_sasl_realm = NULL; } if ( ld->ld_options.ldo_def_sasl_authcid != NULL ) { LDAP_FREE( ld->ld_options.ldo_def_sasl_authcid ); ld->ld_options.ldo_def_sasl_authcid = NULL; } if ( ld->ld_options.ldo_def_sasl_authzid != NULL ) { LDAP_FREE( ld->ld_options.ldo_def_sasl_authzid ); ld->ld_options.ldo_def_sasl_authzid = NULL; } #endif #ifdef HAVE_TLS ldap_int_tls_destroy( &ld->ld_options ); #endif if ( ld->ld_options.ldo_sctrls != NULL ) { ldap_controls_free( ld->ld_options.ldo_sctrls ); ld->ld_options.ldo_sctrls = NULL; } if ( ld->ld_options.ldo_cctrls != NULL ) { ldap_controls_free( ld->ld_options.ldo_cctrls ); ld->ld_options.ldo_cctrls = NULL; } LDAP_MUTEX_UNLOCK( &ld->ld_ldopts_mutex ); ber_sockbuf_free( ld->ld_sb ); #ifdef LDAP_R_COMPILE ldap_pvt_thread_mutex_destroy( &ld->ld_msgid_mutex ); ldap_pvt_thread_mutex_destroy( &ld->ld_conn_mutex ); ldap_pvt_thread_mutex_destroy( &ld->ld_req_mutex ); ldap_pvt_thread_mutex_destroy( &ld->ld_res_mutex ); ldap_pvt_thread_mutex_destroy( &ld->ld_abandon_mutex ); ldap_pvt_thread_mutex_destroy( &ld->ld_ldopts_mutex ); ldap_pvt_thread_mutex_unlock( &ld->ld_ldcmutex ); ldap_pvt_thread_mutex_destroy( &ld->ld_ldcmutex ); #endif #ifndef NDEBUG LDAP_TRASH(ld); #endif LDAP_FREE( (char *) ld->ldc ); LDAP_FREE( (char *) ld ); return( err ); }