bind.c
来自「ldap服务器源码」· C语言 代码 · 共 1,440 行 · 第 1/3 页
C
1,440 行
rc = ldap_parse_result( msc->msc_ld, res, &rs->sr_err, &matched, &text, &refs, &ctrls, 1 ); res = NULL; rs->sr_text = text; if ( rc != LDAP_SUCCESS ) { rs->sr_err = rc; } if ( refs != NULL ) { 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 ] ); } if ( ctrls != NULL ) { rs->sr_ctrls = ctrls; } } assert( res == NULL ); } /* 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 && matched ) { /* record the (massaged) matched * DN into the reply structure */ rs->sr_matched = matched; } } if ( META_BACK_TGT_QUARANTINE( mt ) ) { meta_back_quarantine( op, rs, candidate ); } } else { int i, err = rs->sr_err; for ( i = 0; i < mi->mi_ntargets; i++ ) { metasingleconn_t *msc = &mc->mc_conns[ i ]; char *xtext = NULL; char *xmatched = NULL; rs->sr_err = LDAP_SUCCESS; ldap_get_option( msc->msc_ld, LDAP_OPT_ERROR_NUMBER, &rs->sr_err ); if ( rs->sr_err != LDAP_SUCCESS ) { /* * better check the type of error. In some cases * (search ?) it might be better to return a * success if at least one of the targets gave * positive result ... */ ldap_get_option( msc->msc_ld, LDAP_OPT_ERROR_STRING, &xtext ); if ( xtext != NULL && xtext [ 0 ] == '\0' ) { ldap_memfree( xtext ); xtext = NULL; } ldap_get_option( msc->msc_ld, LDAP_OPT_MATCHED_DN, &xmatched ); if ( xmatched != NULL && xmatched[ 0 ] == '\0' ) { ldap_memfree( xmatched ); xmatched = NULL; } rs->sr_err = slap_map_api2result( rs ); if ( StatslogTest( LDAP_DEBUG_ANY ) ) { char buf[ SLAP_TEXT_BUFLEN ]; snprintf( buf, sizeof( buf ), "meta_back_op_result[%d] " "err=%d text=\"%s\" matched=\"%s\"", i, rs->sr_err, ( xtext ? xtext : "" ), ( xmatched ? xmatched : "" ) ); Debug( LDAP_DEBUG_ANY, "%s %s.\n", op->o_log_prefix, buf, 0 ); } /* * FIXME: need to rewrite "match" (need rwinfo) */ switch ( rs->sr_err ) { default: err = rs->sr_err; if ( xtext != NULL ) { if ( text ) { ldap_memfree( text ); } text = xtext; xtext = NULL; } if ( xmatched != NULL ) { if ( matched ) { ldap_memfree( matched ); } matched = xmatched; xmatched = NULL; } break; } if ( xtext ) { ldap_memfree( xtext ); } if ( xmatched ) { ldap_memfree( xmatched ); } } if ( META_BACK_TGT_QUARANTINE( mi->mi_targets[ i ] ) ) { meta_back_quarantine( op, rs, i ); } } if ( err != LDAP_SUCCESS ) { rs->sr_err = err; } } if ( matched != NULL ) { struct berval dn, pdn; ber_str2bv( matched, 0, 0, &dn ); if ( dnPretty( NULL, &dn, &pdn, op->o_tmpmemctx ) == LDAP_SUCCESS ) { ldap_memfree( matched ); matched_ctx = op->o_tmpmemctx; matched = pdn.bv_val; } rs->sr_matched = matched; } if ( op->o_conn && ( ( sendok & LDAP_BACK_SENDOK ) || ( ( sendok & LDAP_BACK_SENDERR ) && rs->sr_err != LDAP_SUCCESS ) ) ) { send_ldap_result( op, rs ); } if ( matched ) { op->o_tmpfree( (char *)rs->sr_matched, matched_ctx ); } if ( text ) { ldap_memfree( text ); } if ( rs->sr_ref ) { assert( refs != NULL ); ber_memvfree( (void **)refs ); op->o_tmpfree( rs->sr_ref, op->o_tmpmemctx ); } if ( ctrls ) { assert( rs->sr_ctrls != NULL ); ldap_controls_free( ctrls ); } rs->sr_text = save_text; rs->sr_matched = save_matched; rs->sr_ref = save_ref; rs->sr_ctrls = save_ctrls; return( ERR_OK( rs->sr_err ) ? LDAP_SUCCESS : rs->sr_err );}/* * meta_back_proxy_authz_cred() * * prepares credentials & method for meta_back_proxy_authz_bind(); * or, if method is SASL, performs the SASL bind directly. */intmeta_back_proxy_authz_cred( metaconn_t *mc, int candidate, Operation *op, SlapReply *rs, ldap_back_send_t sendok, struct berval *binddn, struct berval *bindcred, int *method ){ metainfo_t *mi = (metainfo_t *)op->o_bd->be_private; metatarget_t *mt = mi->mi_targets[ candidate ]; metasingleconn_t *msc = &mc->mc_conns[ candidate ]; struct berval ndn; int dobind = 0; /* don't proxyAuthz if protocol is not LDAPv3 */ switch ( mt->mt_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 ); } LDAP_BACK_CONN_ISBOUND_CLEAR( msc ); goto done; } if ( op->o_tag == LDAP_REQ_BIND ) { ndn = op->o_req_ndn; } else if ( !BER_BVISNULL( &op->o_conn->c_ndn ) ) { ndn = op->o_conn->c_ndn; } else { ndn = op->o_ndn; } /* * 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 "proxyauthzdn" is set, then bind as * "proxyauthzdn" and explicitly add the proxyAuthz * control to every operation with the dn bound * to the connection as control value. */ /* bind as proxyauthzdn only if no idassert mode * is requested, or if the client's identity * is authorized */ switch ( mt->mt_idassert_mode ) { case LDAP_BACK_IDASSERT_LEGACY: if ( !BER_BVISNULL( &ndn ) && !BER_BVISEMPTY( &ndn ) ) { if ( !BER_BVISNULL( &mt->mt_idassert_authcDN ) && !BER_BVISEMPTY( &mt->mt_idassert_authcDN ) ) { *binddn = mt->mt_idassert_authcDN; *bindcred = mt->mt_idassert_passwd; dobind = 1; } } break; default: /* NOTE: rootdn can always idassert */ if ( BER_BVISNULL( &ndn ) && mt->mt_idassert_authz == NULL && !( mt->mt_idassert_flags & LDAP_BACK_AUTH_AUTHZ_ALL ) ) { if ( mt->mt_idassert_flags & LDAP_BACK_AUTH_PRESCRIPTIVE ) { rs->sr_err = LDAP_INAPPROPRIATE_AUTH; if ( sendok & LDAP_BACK_SENDERR ) { send_ldap_result( op, rs ); } LDAP_BACK_CONN_ISBOUND_CLEAR( msc ); goto done; } rs->sr_err = LDAP_SUCCESS; *binddn = slap_empty_bv; *bindcred = slap_empty_bv; break; } else if ( mt->mt_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, mt->mt_idassert_authz, &authcDN, &authcDN ); if ( rs->sr_err != LDAP_SUCCESS ) { if ( mt->mt_idassert_flags & LDAP_BACK_AUTH_PRESCRIPTIVE ) { if ( sendok & LDAP_BACK_SENDERR ) { send_ldap_result( op, rs ); } LDAP_BACK_CONN_ISBOUND_CLEAR( msc ); goto done; } rs->sr_err = LDAP_SUCCESS; *binddn = slap_empty_bv; *bindcred = slap_empty_bv; break; } } *binddn = mt->mt_idassert_authcDN; *bindcred = mt->mt_idassert_passwd; dobind = 1; break; } if ( dobind && mt->mt_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 ) && ( mt->mt_idassert_flags & LDAP_BACK_AUTH_NATIVE_AUTHZ ) ) { switch ( mt->mt_idassert_mode ) { case LDAP_BACK_IDASSERT_OTHERID: case LDAP_BACK_IDASSERT_OTHERDN: authzID = mt->mt_idassert_authzID; break; case LDAP_BACK_IDASSERT_ANONYMOUS: BER_BVSTR( &authzID, "dn:" ); break; case LDAP_BACK_IDASSERT_SELF: if ( BER_BVISNULL( &ndn ) ) { /* connection is not authc'd, so don't idassert */ BER_BVSTR( &authzID, "dn:" ); break; } authzID.bv_len = STRLENOF( "dn:" ) + ndn.bv_len; authzID.bv_val = slap_sl_malloc( authzID.bv_len + 1, op->o_tmpmemctx ); AC_MEMCPY( authzID.bv_val, "dn:", STRLENOF( "dn:" ) ); AC_MEMCPY( authzID.bv_val + STRLENOF( "dn:" ), ndn.bv_val, ndn.bv_len + 1 ); freeauthz = 1; break; default: break; } } if ( mt->mt_idassert_secprops != NULL ) { rs->sr_err = ldap_set_option( msc->msc_ld, LDAP_OPT_X_SASL_SECPROPS, (void *)mt->mt_idassert_secprops ); if ( rs->sr_err != LDAP_OPT_SUCCESS ) { rs->sr_err = LDAP_OTHER; if ( sendok & LDAP_BACK_SENDERR ) { send_ldap_result( op, rs ); } LDAP_BACK_CONN_ISBOUND_CLEAR( msc ); goto done; } } defaults = lutil_sasl_defaults( msc->msc_ld, mt->mt_idassert_sasl_mech.bv_val, mt->mt_idassert_sasl_realm.bv_val, mt->mt_idassert_authcID.bv_val, mt->mt_idassert_passwd.bv_val, authzID.bv_val ); rs->sr_err = ldap_sasl_interactive_bind_s( msc->msc_ld, binddn->bv_val, mt->mt_idassert_sasl_mech.bv_val, NULL, NULL, LDAP_SASL_QUIET, lutil_sasl_interact, defaults ); rs->sr_err = slap_map_api2result( rs ); if ( rs->sr_err != LDAP_SUCCESS ) { LDAP_BACK_CONN_ISBOUND_CLEAR( msc ); if ( sendok & LDAP_BACK_SENDERR ) { send_ldap_result( op, rs ); } } else { LDAP_BACK_CONN_ISBOUND_SET( msc ); } lutil_sasl_freedefs( defaults ); if ( freeauthz ) { slap_sl_free( authzID.bv_val, op->o_tmpmemctx ); } goto done;#endif /* HAVE_CYRUS_SASL */ } *method = mt->mt_idassert_authmethod; switch ( mt->mt_idassert_authmethod ) { case LDAP_AUTH_NONE: BER_BVSTR( binddn, "" ); BER_BVSTR( bindcred, "" ); /* fallthru */ case LDAP_AUTH_SIMPLE: break; default: /* unsupported! */ LDAP_BACK_CONN_ISBOUND_CLEAR( msc ); rs->sr_err = LDAP_AUTH_METHOD_NOT_SUPPORTED; if ( sendok & LDAP_BACK_SENDERR ) { send_ldap_result( op, rs ); } break; }done:; return rs->sr_err;}static intmeta_back_proxy_authz_bind( metaconn_t *mc, int candidate, Operation *op, SlapReply *rs, ldap_back_send_t sendok ){ metainfo_t *mi = (metainfo_t *)op->o_bd->be_private; metatarget_t *mt = mi->mi_targets[ candidate ]; metasingleconn_t *msc = &mc->mc_conns[ candidate ]; struct berval binddn = BER_BVC( "" ), cred = BER_BVC( "" ); int method = LDAP_AUTH_NONE, rc; rc = meta_back_proxy_authz_cred( mc, candidate, op, rs, sendok, &binddn, &cred, &method ); if ( rc == LDAP_SUCCESS && !LDAP_BACK_CONN_ISBOUND( msc ) ) { int msgid; switch ( method ) { case LDAP_AUTH_NONE: case LDAP_AUTH_SIMPLE: rs->sr_err = ldap_sasl_bind( msc->msc_ld, binddn.bv_val, LDAP_SASL_SIMPLE, &cred, NULL, NULL, &msgid ); rc = meta_back_bind_op_result( op, rs, mc, candidate, msgid, sendok ); if ( rc == LDAP_SUCCESS ) { /* set rebind stuff in case of successful proxyAuthz bind, * so that referral chasing is attempted using the right * identity */ LDAP_BACK_CONN_ISBOUND_SET( msc ); ber_bvreplace( &msc->msc_bound_ndn, &binddn ); if ( LDAP_BACK_SAVECRED( mi ) ) { if ( !BER_BVISNULL( &msc->msc_cred ) ) { memset( msc->msc_cred.bv_val, 0, msc->msc_cred.bv_len ); } ber_bvreplace( &msc->msc_cred, &cred ); ldap_set_rebind_proc( msc->msc_ld, mt->mt_rebind_f, msc ); } } break; default: assert( 0 ); break; } } return LDAP_BACK_CONN_ISBOUND( msc );}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?