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

📄 bind.c

📁 OpenLdap是LDAP的开源项目
💻 C
📖 第 1 页 / 共 5 页
字号:
		Operation		*op,		SlapReply		*rs,		ber_int_t		msgid,		ldap_back_send_t	sendok ){	ldapinfo_t	*li = (ldapinfo_t *)op->o_bd->be_private;	/* default behavior */	if ( LDAP_BACK_ABANDON( li ) ) {		return ldap_abandon_ext( lc->lc_ld, msgid, NULL, NULL );	}	if ( LDAP_BACK_CANCEL( li ) ) {		/* FIXME: asynchronous? */		return ldap_cancel_s( lc->lc_ld, msgid, NULL, NULL );	}	assert( 0 );	return LDAP_OTHER;}intldap_back_op_result(		ldapconn_t		*lc,		Operation		*op,		SlapReply		*rs,		ber_int_t		msgid,		time_t			timeout,		ldap_back_send_t	sendok ){	ldapinfo_t	*li = (ldapinfo_t *)op->o_bd->be_private;	char		*match = NULL;	char		*text = NULL;	char		**refs = NULL;	LDAPControl	**ctrls = NULL;#define	ERR_OK(err) ((err) == LDAP_SUCCESS || (err) == LDAP_COMPARE_FALSE || (err) == LDAP_COMPARE_TRUE)	rs->sr_text = NULL;	rs->sr_matched = NULL;	rs->sr_ref = NULL;	rs->sr_ctrls = NULL;	/* if the error recorded in the reply corresponds	 * to a successful state, get the error from the	 * remote server response */	if ( ERR_OK( rs->sr_err ) ) {		int		rc;		struct timeval	tv;		LDAPMessage	*res = NULL;		time_t		stoptime = (time_t)(-1);		int		timeout_err = op->o_protocol >= LDAP_VERSION3 ?					LDAP_ADMINLIMIT_EXCEEDED : LDAP_OTHER;		const char	*timeout_text = "Operation timed out";		/* if timeout is not specified, compute and use		 * the one specific to the ongoing operation */		if ( timeout == (time_t)(-1) ) {			slap_op_t	opidx = slap_req2op( op->o_tag );			if ( opidx == SLAP_OP_SEARCH ) {				if ( op->ors_tlimit <= 0 ) {					timeout = 0;				} else {					timeout = op->ors_tlimit;					timeout_err = LDAP_TIMELIMIT_EXCEEDED;					timeout_text = NULL;				}			} else {				timeout = li->li_timeout[ opidx ];			}		}		/* better than nothing :) */		if ( timeout == 0 ) {			if ( li->li_idle_timeout ) {				timeout = li->li_idle_timeout;			} else if ( li->li_conn_ttl ) {				timeout = li->li_conn_ttl;			}		}		if ( timeout ) {			stoptime = op->o_time + timeout;		}		LDAP_BACK_TV_SET( &tv );retry:;		/* if result parsing fails, note the failure reason */		rc = ldap_result( lc->lc_ld, msgid, LDAP_MSG_ALL, &tv, &res );		switch ( rc ) {		case 0:			if ( timeout && slap_get_time() > stoptime ) {				if ( sendok & LDAP_BACK_BINDING ) {					ldap_unbind_ext( lc->lc_ld, NULL, NULL );					lc->lc_ld = NULL;					/* 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 );				} else {					(void)ldap_back_cancel( lc, op, rs, msgid, sendok );				}				rs->sr_err = timeout_err;				rs->sr_text = timeout_text;				break;			}			/* timeout == 0 */			LDAP_BACK_TV_SET( &tv );			ldap_pvt_thread_yield();			goto retry;		case -1:			ldap_get_option( lc->lc_ld, LDAP_OPT_ERROR_NUMBER,					&rs->sr_err );			break;		/* otherwise get the result; if it is not		 * LDAP_SUCCESS, record it in the reply		 * structure (this includes 		 * LDAP_COMPARE_{TRUE|FALSE}) */		default:			/* only touch when activity actually took place... */			if ( li->li_idle_timeout && lc ) {				lc->lc_time = op->o_time;			}			rc = ldap_parse_result( lc->lc_ld, res, &rs->sr_err,					&match, &text, &refs, &ctrls, 1 );			rs->sr_text = text;			if ( rc != LDAP_SUCCESS ) {				rs->sr_err = rc;			}			/* RFC 4511: referrals can only appear			 * if result code is LDAP_REFERRAL */			if ( refs != NULL				&& refs[ 0 ] != NULL				&& refs[ 0 ][ 0 ] != '\0' )			{				if ( rs->sr_err != LDAP_REFERRAL ) {					Debug( LDAP_DEBUG_ANY,						"%s ldap_back_op_result: "						"got referrals with err=%d\n",						op->o_log_prefix,						rs->sr_err, 0 );				} else {					int	i;					for ( i = 0; refs[ i ] != NULL; i++ )						/* count */ ;					rs->sr_ref = op->o_tmpalloc( sizeof( struct berval ) * ( i + 1 ),						op->o_tmpmemctx );					for ( i = 0; refs[ i ] != NULL; i++ ) {						ber_str2bv( refs[ i ], 0, 0, &rs->sr_ref[ i ] );					}					BER_BVZERO( &rs->sr_ref[ i ] );				}			} else if ( rs->sr_err == LDAP_REFERRAL ) {				Debug( LDAP_DEBUG_ANY,					"%s ldap_back_op_result: "					"got err=%d with null "					"or empty referrals\n",					op->o_log_prefix,					rs->sr_err, 0 );				rs->sr_err = LDAP_NO_SUCH_OBJECT;			}			if ( ctrls != NULL ) {				rs->sr_ctrls = ctrls;			}		}	}	/* if the error in the reply structure is not	 * LDAP_SUCCESS, try to map it from client 	 * to server error */	if ( !ERR_OK( rs->sr_err ) ) {		rs->sr_err = slap_map_api2result( rs );		/* internal ops ( op->o_conn == NULL ) 		 * must not reply to client */		if ( op->o_conn && !op->o_do_not_cache && match ) {			/* record the (massaged) matched			 * DN into the reply structure */			rs->sr_matched = match;		}	}	if ( rs->sr_err == LDAP_UNAVAILABLE ) {		if ( !( sendok & LDAP_BACK_RETRYING ) ) {			if ( LDAP_BACK_QUARANTINE( li ) ) {				ldap_back_quarantine( op, rs );			}			if ( op->o_conn && ( sendok & LDAP_BACK_SENDERR ) ) {				if ( rs->sr_text == NULL ) rs->sr_text = "Proxy operation retry failed";				send_ldap_result( op, rs );			}		}	} else if ( op->o_conn &&		( ( ( sendok & LDAP_BACK_SENDOK ) && ERR_OK( rs->sr_err ) )			|| ( ( sendok & LDAP_BACK_SENDERR ) && rs->sr_err != LDAP_SUCCESS ) ) )	{		send_ldap_result( op, rs );	}	if ( match ) {		if ( rs->sr_matched != match ) {			free( (char *)rs->sr_matched );		}		rs->sr_matched = NULL;		ldap_memfree( match );	}	if ( text ) {		ldap_memfree( text );	}	rs->sr_text = NULL;	if ( rs->sr_ref ) {		op->o_tmpfree( rs->sr_ref, op->o_tmpmemctx );		rs->sr_ref = NULL;	}	if ( refs ) {		ber_memvfree( (void **)refs );	}	if ( ctrls ) {		assert( rs->sr_ctrls != NULL );		ldap_controls_free( ctrls );		rs->sr_ctrls = NULL;	}	return( ERR_OK( rs->sr_err ) ? LDAP_SUCCESS : rs->sr_err );}/* return true if bound, false if failed */intldap_back_retry( ldapconn_t **lcp, Operation *op, SlapReply *rs, ldap_back_send_t sendok ){	ldapinfo_t	*li = (ldapinfo_t *)op->o_bd->be_private;	int		rc = 0;	assert( lcp != NULL );	assert( *lcp != NULL );	ldap_pvt_thread_mutex_lock( &li->li_conninfo.lai_mutex );	if ( (*lcp)->lc_refcnt == 1 ) {		int binding = LDAP_BACK_CONN_BINDING( *lcp );		ldap_pvt_thread_mutex_lock( &li->li_uri_mutex );		Debug( LDAP_DEBUG_ANY,			"%s ldap_back_retry: retrying URI=\"%s\" DN=\"%s\"\n",			op->o_log_prefix, li->li_uri,			BER_BVISNULL( &(*lcp)->lc_bound_ndn ) ?				"" : (*lcp)->lc_bound_ndn.bv_val );		ldap_pvt_thread_mutex_unlock( &li->li_uri_mutex );		ldap_unbind_ext( (*lcp)->lc_ld, NULL, NULL );		(*lcp)->lc_ld = NULL;		LDAP_BACK_CONN_ISBOUND_CLEAR( (*lcp) );		/* lc here must be the regular lc, reset and ready for init */		rc = ldap_back_prepare_conn( *lcp, op, rs, sendok );		if ( rc != LDAP_SUCCESS ) {			/* freeit, because lc_refcnt == 1 */			(*lcp)->lc_refcnt = 0;			(void)ldap_back_freeconn( li, *lcp, 0 );			*lcp = NULL;			rc = 0;		} else if ( ( sendok & LDAP_BACK_BINDING ) ) {			if ( binding ) {				LDAP_BACK_CONN_BINDING_SET( *lcp );			}			rc = 1;		} else {			rc = ldap_back_dobind_int( lcp, op, rs, sendok, 0, 0 );			if ( rc == 0 && *lcp != NULL ) {				/* freeit, because lc_refcnt == 1 */				(*lcp)->lc_refcnt = 0;				LDAP_BACK_CONN_TAINTED_SET( *lcp );				(void)ldap_back_freeconn( li, *lcp, 0 );				*lcp = NULL;			}		}	} else {		Debug( LDAP_DEBUG_TRACE,			"ldap_back_retry: conn %p refcnt=%u unable to retry.\n",			(void *)(*lcp), (*lcp)->lc_refcnt, 0 );		LDAP_BACK_CONN_TAINTED_SET( *lcp );		ldap_back_release_conn_lock( li, lcp, 0 );		assert( *lcp == NULL );		if ( sendok & LDAP_BACK_SENDERR ) {			rs->sr_err = LDAP_UNAVAILABLE;			rs->sr_text = "Unable to retry";			send_ldap_result( op, rs );		}	}	ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex );	return rc;}static intldap_back_is_proxy_authz( Operation *op, SlapReply *rs, ldap_back_send_t sendok,	struct berval *binddn, struct berval *bindcred ){	ldapinfo_t	*li = (ldapinfo_t *)op->o_bd->be_private;	struct berval	ndn;	int		dobind = 0;	if ( op->o_conn == NULL || op->o_do_not_cache ) {		goto done;	}	/* don't proxyAuthz if protocol is not LDAPv3 */	switch ( li->li_version ) {	case LDAP_VERSION3:		break;	case 0:		if ( op->o_protocol == 0 || op->o_protocol == LDAP_VERSION3 ) {			break;		}		/* fall thru */	default:		rs->sr_err = LDAP_UNWILLING_TO_PERFORM;		if ( sendok & LDAP_BACK_SENDERR ) {			send_ldap_result( op, rs );			dobind = -1;		}		goto done;	}	/* safe default */	*binddn = slap_empty_bv;	*bindcred = slap_empty_bv;	if ( !BER_BVISNULL( &op->o_conn->c_ndn ) ) {		ndn = op->o_conn->c_ndn;	} else {		ndn = op->o_ndn;	}	switch ( li->li_idassert_mode ) {	case LDAP_BACK_IDASSERT_LEGACY:		if ( !BER_BVISNULL( &ndn ) && !BER_BVISEMPTY( &ndn ) ) {			if ( !BER_BVISNULL( &li->li_idassert_authcDN ) && !BER_BVISEMPTY( &li->li_idassert_authcDN ) )			{				*binddn = li->li_idassert_authcDN;				*bindcred = li->li_idassert_passwd;				dobind = 1;			}		}		break;	default:		/* NOTE: rootdn can always idassert */		if ( BER_BVISNULL( &ndn )			&& li->li_idassert_authz == NULL			&& !( li->li_idassert_flags & LDAP_BACK_AUTH_AUTHZ_ALL ) )		{			if ( li->li_idassert_flags & LDAP_BACK_AUTH_PRESCRIPTIVE ) {				rs->sr_err = LDAP_INAPPROPRIATE_AUTH;				if ( sendok & LDAP_BACK_SENDERR ) {					send_ldap_result( op, rs );					dobind = -1;				}			} else {				rs->sr_err = LDAP_SUCCESS;				*binddn = slap_empty_bv;				*bindcred = slap_empty_bv;				break;			}			goto done;		} else if ( li->li_idassert_authz && !be_isroot( op ) ) {			struct berval authcDN;			if ( BER_BVISNULL( &ndn ) ) {				authcDN = slap_empty_bv;			} else {				authcDN = ndn;			}				rs->sr_err = slap_sasl_matches( op, li->li_idassert_authz,					&authcDN, &authcDN );			if ( rs->sr_err != LDAP_SUCCESS ) {				if ( li->li_idassert_flags & LDAP_BACK_AUTH_PRESCRIPTIVE ) {					if ( sendok & LDAP_BACK_SENDERR ) {						send_ldap_result( op, rs );						dobind = -1;					}				} else {					rs->sr_err = LDAP_SUCCESS;					*binddn = slap_empty_bv;					*bindcred = slap_empty_bv;					break;				}				goto done;			}		}		*binddn = li->li_idassert_authcDN;		*bindcred = li->li_idassert_passwd;		dobind = 1;		break;	}done:;	return dobind;}static intldap_back_proxy_authz_bind(	ldapconn_t		*lc,	Operation		*op,	SlapReply		*rs,	ldap_back_send_t	sendok,	struct berval		*binddn,	struct berval		*bindcred ){	ldapinfo_t	*li = (ldapinfo_t *)op->o_bd->be_private;	struct berval	ndn;	int		msgid;	int		rc;	if ( !BER_BVISNULL( &op->o_conn->c_ndn ) ) {		ndn = op->o_conn->c_ndn;	} else {		ndn = op->o_ndn;	}	if ( li->li_idassert_authmethod == LDAP_AUTH_SASL ) {#ifdef HAVE_CYRUS_SASL		void		*defaults = NULL;		struct berval	authzID = BER_BVNULL;		int		freeauthz = 0;		/* if SASL supports native authz, prepare for it */		if ( ( !op->o_do_not_cache || !op->o_is_auth_check ) &&				( li->li_idassert_flags & LDAP_BACK_AUTH_NATIVE_AUTHZ ) )		{			switch ( li->li_idassert_mode ) {			case LDAP_BACK_IDASSERT_OTHERID:			case LDAP_BACK_IDASSERT_OTHERDN:

⌨️ 快捷键说明

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