⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bind.c

📁 OpenLdap是LDAP的开源项目
💻 C
📖 第 1 页 / 共 5 页
字号:
		} else {			rs->sr_err = avl_insert( &li->li_conninfo.lai_tree, (caddr_t)lc,				ldap_back_conndn_cmp, ldap_back_conndn_dup );			LDAP_BACK_CONN_CACHED_SET( lc );		}#if LDAP_BACK_PRINT_CONNTREE > 0		ldap_back_print_conntree( li, "<<< ldap_back_getconn(insert)" );#endif /* LDAP_BACK_PRINT_CONNTREE */			ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex );		if ( StatslogTest( LDAP_DEBUG_TRACE ) ) {			char	buf[ SLAP_TEXT_BUFLEN ];			snprintf( buf, sizeof( buf ),				"lc=%p inserted refcnt=%u rc=%d",				(void *)lc, refcnt, rs->sr_err );							Debug( LDAP_DEBUG_TRACE,				"=>ldap_back_getconn: %s: %s\n",				op->o_log_prefix, buf, 0 );		}			if ( !LDAP_BACK_PCONN_ISPRIV( lc ) ) {			/* Err could be -1 in case a duplicate ldapconn is inserted */			switch ( rs->sr_err ) {			case 0:				break;			case -1:				LDAP_BACK_CONN_CACHED_CLEAR( lc );				if ( !( sendok & LDAP_BACK_BINDING ) && !LDAP_BACK_USE_TEMPORARIES( li ) ) {					/* duplicate: free and try to get the newly created one */					ldap_back_conn_free( lc );					lc = NULL;					goto retry_lock;				}				/* taint connection, so that it'll be freed when released */				LDAP_BACK_CONN_TAINTED_SET( lc );				break;			default:				LDAP_BACK_CONN_CACHED_CLEAR( lc );				ldap_back_conn_free( lc );				rs->sr_err = LDAP_OTHER;				rs->sr_text = "Proxy bind collision";				if ( op->o_conn && ( sendok & LDAP_BACK_SENDERR ) ) {					send_ldap_result( op, rs );				}				return NULL;			}		}	} else {		int	expiring = 0;		if ( ( li->li_idle_timeout != 0 && op->o_time > lc->lc_time + li->li_idle_timeout )			|| ( li->li_conn_ttl != 0 && op->o_time > lc->lc_create_time + li->li_conn_ttl ) )		{			expiring = 1;			/* let it be used, but taint/delete it so that 			 * no-one else can look it up any further */			ldap_pvt_thread_mutex_lock( &li->li_conninfo.lai_mutex );#if LDAP_BACK_PRINT_CONNTREE > 0			ldap_back_print_conntree( li, ">>> ldap_back_getconn(timeout)" );#endif /* LDAP_BACK_PRINT_CONNTREE */			(void)ldap_back_conn_delete( li, lc );			LDAP_BACK_CONN_TAINTED_SET( lc );#if LDAP_BACK_PRINT_CONNTREE > 0			ldap_back_print_conntree( li, "<<< ldap_back_getconn(timeout)" );#endif /* LDAP_BACK_PRINT_CONNTREE */			ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex );		}		if ( StatslogTest( LDAP_DEBUG_TRACE ) ) {			char	buf[ SLAP_TEXT_BUFLEN ];			snprintf( buf, sizeof( buf ),				"conn %p fetched refcnt=%u%s",				(void *)lc, refcnt,				expiring ? " expiring" : "" );			Debug( LDAP_DEBUG_TRACE,				"=>ldap_back_getconn: %s.\n", buf, 0, 0 );		}	}#ifdef HAVE_TLSdone:;#endif /* HAVE_TLS */	return lc;}voidldap_back_release_conn_lock(	ldapinfo_t		*li,	ldapconn_t		**lcp,	int			dolock ){	ldapconn_t	*lc = *lcp;	if ( dolock ) {		ldap_pvt_thread_mutex_lock( &li->li_conninfo.lai_mutex );	}	assert( lc->lc_refcnt > 0 );	LDAP_BACK_CONN_BINDING_CLEAR( lc );	lc->lc_refcnt--;	if ( LDAP_BACK_CONN_TAINTED( lc ) ) {		ldap_back_freeconn( li, lc, 0 );		*lcp = NULL;	}	if ( dolock ) {		ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex );	}}voidldap_back_quarantine(	Operation	*op,	SlapReply	*rs ){	ldapinfo_t		*li = (ldapinfo_t *)op->o_bd->be_private;	slap_retry_info_t	*ri = &li->li_quarantine;	ldap_pvt_thread_mutex_lock( &li->li_quarantine_mutex );	if ( rs->sr_err == LDAP_UNAVAILABLE ) {		time_t		new_last = slap_get_time();		switch ( li->li_isquarantined ) {		case LDAP_BACK_FQ_NO:			if ( ri->ri_last == new_last ) {				goto done;			}			Debug( LDAP_DEBUG_ANY,				"%s: ldap_back_quarantine enter.\n",				op->o_log_prefix, 0, 0 );			ri->ri_idx = 0;			ri->ri_count = 0;			break;		case LDAP_BACK_FQ_RETRYING:			Debug( LDAP_DEBUG_ANY,				"%s: ldap_back_quarantine block #%d try #%d failed.\n",				op->o_log_prefix, ri->ri_idx, ri->ri_count );			++ri->ri_count;			if ( ri->ri_num[ ri->ri_idx ] != SLAP_RETRYNUM_FOREVER				&& ri->ri_count == ri->ri_num[ ri->ri_idx ] )			{				ri->ri_count = 0;				++ri->ri_idx;			}			break;		default:			break;		}		li->li_isquarantined = LDAP_BACK_FQ_YES;		ri->ri_last = new_last;	} else if ( li->li_isquarantined != LDAP_BACK_FQ_NO ) {		if ( ri->ri_last == slap_get_time() ) {			goto done;		}		Debug( LDAP_DEBUG_ANY,			"%s: ldap_back_quarantine exit (%d) err=%d.\n",			op->o_log_prefix, li->li_isquarantined, rs->sr_err );		if ( li->li_quarantine_f ) {			(void)li->li_quarantine_f( li, li->li_quarantine_p );		}		ri->ri_count = 0;		ri->ri_idx = 0;		li->li_isquarantined = LDAP_BACK_FQ_NO;	}done:;	ldap_pvt_thread_mutex_unlock( &li->li_quarantine_mutex );}/* * ldap_back_dobind_int * * Note: dolock indicates whether li->li_conninfo.lai_mutex must be locked or not */static intldap_back_dobind_int(	ldapconn_t		**lcp,	Operation		*op,	SlapReply		*rs,	ldap_back_send_t	sendok,	int			retries,	int			dolock ){		ldapinfo_t	*li = (ldapinfo_t *)op->o_bd->be_private;	ldapconn_t	*lc;	struct berval	binddn = slap_empty_bv,			bindcred = slap_empty_bv;	int		rc = 0,			isbound,			binding = 0;	ber_int_t	msgid;	assert( lcp != NULL );	assert( retries >= 0 );	if ( sendok & LDAP_BACK_GETCONN ) {		assert( *lcp == NULL );		lc = ldap_back_getconn( op, rs, sendok, &binddn, &bindcred );		if ( lc == NULL ) {			return 0;		}		*lcp = lc;	} else {		lc = *lcp;	}	assert( lc != NULL );retry_lock:; 	if ( dolock ) { 		ldap_pvt_thread_mutex_lock( &li->li_conninfo.lai_mutex ); 	} 	if ( binding == 0 ) {		/* check if already bound */		rc = isbound = LDAP_BACK_CONN_ISBOUND( lc );		if ( isbound ) { 			if ( dolock ) { 				ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex ); 			}			return rc;		}		if ( LDAP_BACK_CONN_BINDING( lc ) ) {			/* if someone else is about to bind it, give up and retry */ 			if ( dolock ) { 				ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex ); 			}			ldap_pvt_thread_yield();			goto retry_lock;		} else {			/* otherwise this thread will bind it */ 			LDAP_BACK_CONN_BINDING_SET( lc );			binding = 1;		}	} 	if ( dolock ) { 		ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex ); 	}	/*	 * FIXME: we need to let clients use proxyAuthz	 * otherwise we cannot do symmetric pools of servers;	 * we have to live with the fact that a user can	 * authorize itself as any ID that is allowed	 * by the authzTo directive of the "proxyauthzdn".	 */	/*	 * NOTE: current Proxy Authorization specification	 * and implementation do not allow proxy authorization	 * control to be provided with Bind requests	 */	/*	 * if no bind took place yet, but the connection is bound	 * and the "idassert-authcDN" (or other ID) is set, 	 * then bind as the asserting identity and explicitly 	 * add the proxyAuthz control to every operation with the	 * dn bound to the connection as control value.	 * This is done also if this is the authrizing backend,	 * but the "override" flag is given to idassert.	 * It allows to use SASL bind and yet proxyAuthz users	 */	if ( LDAP_BACK_CONN_ISIDASSERT( lc ) ) {		if ( BER_BVISEMPTY( &binddn ) && BER_BVISEMPTY( &bindcred ) ) {			/* if we got here, it shouldn't return result */			rc = ldap_back_is_proxy_authz( op, rs,				LDAP_BACK_DONTSEND, &binddn, &bindcred );			assert( rc == 1 );		}		rc = ldap_back_proxy_authz_bind( lc, op, rs, sendok, &binddn, &bindcred );		goto done;	}#ifdef HAVE_CYRUS_SASL	if ( LDAP_BACK_CONN_ISPRIV( lc )		&& li->li_acl_authmethod == LDAP_AUTH_SASL )	{		void		*defaults = NULL;		if ( li->li_acl_secprops != NULL ) {			rc = ldap_set_option( lc->lc_ld,				LDAP_OPT_X_SASL_SECPROPS, li->li_acl_secprops );			if ( rc != LDAP_OPT_SUCCESS ) {				Debug( LDAP_DEBUG_ANY, "Error: ldap_set_option "					"(SECPROPS,\"%s\") failed!\n",					li->li_acl_secprops, 0, 0 );				goto done;			}		}		defaults = lutil_sasl_defaults( lc->lc_ld,				li->li_acl_sasl_mech.bv_val,				li->li_acl_sasl_realm.bv_val,				li->li_acl_authcID.bv_val,				li->li_acl_passwd.bv_val,				NULL );		rs->sr_err = ldap_sasl_interactive_bind_s( lc->lc_ld,				li->li_acl_authcDN.bv_val,				li->li_acl_sasl_mech.bv_val, NULL, NULL,				LDAP_SASL_QUIET, lutil_sasl_interact,				defaults );		lutil_sasl_freedefs( defaults );		rs->sr_err = slap_map_api2result( rs );		if ( rs->sr_err != LDAP_SUCCESS ) {			LDAP_BACK_CONN_ISBOUND_CLEAR( lc );			if ( sendok & LDAP_BACK_SENDERR ) {				send_ldap_result( op, rs );			}		} else {			LDAP_BACK_CONN_ISBOUND_SET( lc );		}		if ( LDAP_BACK_QUARANTINE( li ) ) {			ldap_back_quarantine( op, rs );		}		goto done;	}#endif /* HAVE_CYRUS_SASL */retry:;	rs->sr_err = ldap_sasl_bind( lc->lc_ld,			BER_BVISNULL( &lc->lc_cred ) ? "" : lc->lc_bound_ndn.bv_val,			LDAP_SASL_SIMPLE, &lc->lc_cred,			NULL, NULL, &msgid );	if ( rs->sr_err == LDAP_SERVER_DOWN ) {		if ( retries != LDAP_BACK_RETRY_NEVER ) {			if ( dolock ) {				ldap_pvt_thread_mutex_lock( &li->li_conninfo.lai_mutex );			}			assert( lc->lc_refcnt > 0 );			if ( lc->lc_refcnt == 1 ) {				ldap_unbind_ext( lc->lc_ld, NULL, NULL );				lc->lc_ld = NULL;				/* lc here must be the regular lc, reset and ready for init */				rs->sr_err = ldap_back_prepare_conn( lc, op, rs, sendok );				if ( rs->sr_err != LDAP_SUCCESS ) {					sendok &= ~LDAP_BACK_SENDERR;					lc->lc_refcnt = 0;				}			}			if ( dolock ) {				ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex );			}			if ( rs->sr_err == LDAP_SUCCESS ) {				if ( retries > 0 ) {					retries--;				}				goto retry;			}		}		assert( lc->lc_refcnt == 1 );		lc->lc_refcnt = 0;		ldap_back_freeconn( li, lc, dolock );		*lcp = NULL;		rs->sr_err = slap_map_api2result( rs );		if ( LDAP_BACK_QUARANTINE( li ) ) {			ldap_back_quarantine( op, rs );		}		if ( rs->sr_err != LDAP_SUCCESS &&			( sendok & LDAP_BACK_SENDERR ) )		{			rs->sr_text = "Internal proxy bind failure";			send_ldap_result( op, rs );		}		return 0;	}	rc = ldap_back_op_result( lc, op, rs, msgid,		-1, ( sendok | LDAP_BACK_BINDING ) );	if ( rc == LDAP_SUCCESS ) {		LDAP_BACK_CONN_ISBOUND_SET( lc );	}done:;	LDAP_BACK_CONN_BINDING_CLEAR( lc );	rc = LDAP_BACK_CONN_ISBOUND( lc );	if ( !rc ) {		ldap_back_release_conn_lock( li, lcp, dolock );	} else if ( LDAP_BACK_SAVECRED( li ) ) {		ldap_set_rebind_proc( lc->lc_ld, li->li_rebind_f, lc );	}	return rc;}/* * ldap_back_dobind * * Note: dolock indicates whether li->li_conninfo.lai_mutex must be locked or not */intldap_back_dobind( ldapconn_t **lcp, Operation *op, SlapReply *rs, ldap_back_send_t sendok ){	ldapinfo_t	*li = (ldapinfo_t *)op->o_bd->be_private;	return ldap_back_dobind_int( lcp, op, rs,		( sendok | LDAP_BACK_GETCONN ), li->li_nretries, 1 );}/* * ldap_back_default_rebind * * This is a callback used for chasing referrals using the same * credentials as the original user on this session. */int ldap_back_default_rebind( LDAP *ld, LDAP_CONST char *url, ber_tag_t request,	ber_int_t msgid, void *params ){	ldapconn_t	*lc = (ldapconn_t *)params;#ifdef HAVE_TLS	/* ... otherwise we couldn't get here */	assert( lc != NULL );	if ( !ldap_tls_inplace( ld ) ) {		int		is_tls = LDAP_BACK_CONN_ISTLS( lc ),				rc;		const char	*text = NULL;		rc = ldap_back_start_tls( ld, 0, &is_tls, url, lc->lc_flags,			LDAP_BACK_RETRY_DEFAULT, &text );		if ( rc != LDAP_SUCCESS ) {			return rc;		}	}#endif /* HAVE_TLS */	/* FIXME: add checks on the URL/identity? */	return ldap_sasl_bind_s( ld,			BER_BVISNULL( &lc->lc_cred ) ? "" : lc->lc_bound_ndn.bv_val,			LDAP_SASL_SIMPLE, &lc->lc_cred, NULL, NULL, NULL );}intldap_back_cancel(		ldapconn_t		*lc,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -