mirror of
https://git.openldap.org/openldap/openldap.git
synced 2026-05-28 04:35:57 -04:00
Resolve authzid after a successful auth
This commit is contained in:
parent
c957bb9199
commit
7a69017f6f
3 changed files with 190 additions and 4 deletions
|
|
@ -476,6 +476,86 @@ fail:
|
|||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Remember the response, but first ask the server what
|
||||
* authorization identity has been negotiated.
|
||||
*
|
||||
* Also, this request will fail if the server thinks a SASL
|
||||
* confidentiality/integrity layer has been negotiated so we catch
|
||||
* it early and no other clients are affected.
|
||||
*/
|
||||
int
|
||||
finish_sasl_bind(
|
||||
LloadConnection *upstream,
|
||||
LloadOperation *op,
|
||||
BerElement *ber )
|
||||
{
|
||||
LloadConnection *client = op->o_client;
|
||||
BerElement *output;
|
||||
LloadOperation *removed;
|
||||
ber_int_t msgid;
|
||||
int rc;
|
||||
|
||||
if ( !(lload_features & LLOAD_FEATURE_PROXYAUTHZ) ) {
|
||||
Debug( LDAP_DEBUG_TRACE, "finish_sasl_bind: "
|
||||
"connid=%lu not configured to do proxyauthz, making no "
|
||||
"attempt to resolve final authzid name\n",
|
||||
op->o_client_connid );
|
||||
CONNECTION_UNLOCK(upstream);
|
||||
return forward_final_response( client, op, ber );
|
||||
}
|
||||
|
||||
removed = tavl_delete( &upstream->c_ops, op, operation_upstream_cmp );
|
||||
if ( !removed ) {
|
||||
assert( upstream->c_state != LLOAD_C_BINDING );
|
||||
/* FIXME: has client replaced this bind since? */
|
||||
assert(0);
|
||||
|
||||
operation_destroy_from_upstream( op );
|
||||
}
|
||||
assert( removed == op && upstream->c_state == LLOAD_C_BINDING );
|
||||
|
||||
CONNECTION_UNLOCK(upstream);
|
||||
|
||||
Debug( LDAP_DEBUG_TRACE, "finish_sasl_bind: "
|
||||
"SASL exchange in lieu of client connid=%lu to upstream "
|
||||
"connid=%lu finished, resolving final authzid name\n",
|
||||
op->o_client_connid, op->o_upstream_connid );
|
||||
|
||||
ldap_pvt_thread_mutex_lock( &upstream->c_io_mutex );
|
||||
output = upstream->c_pendingber;
|
||||
if ( output == NULL && (output = ber_alloc()) == NULL ) {
|
||||
ldap_pvt_thread_mutex_unlock( &upstream->c_io_mutex );
|
||||
return -1;
|
||||
}
|
||||
upstream->c_pendingber = output;
|
||||
|
||||
msgid = upstream->c_next_msgid++;
|
||||
ber_printf( output, "t{tit{ts}}", LDAP_TAG_MESSAGE,
|
||||
LDAP_TAG_MSGID, msgid,
|
||||
LDAP_REQ_EXTENDED,
|
||||
LDAP_TAG_EXOP_REQ_OID, LDAP_EXOP_WHO_AM_I );
|
||||
|
||||
/* Make sure noone flushes the buffer before we re-insert the operation */
|
||||
CONNECTION_LOCK(upstream);
|
||||
ldap_pvt_thread_mutex_unlock( &upstream->c_io_mutex );
|
||||
|
||||
op->o_upstream_msgid = msgid;
|
||||
|
||||
/* remember the response for later */
|
||||
ber_free( op->o_ber, 1 );
|
||||
op->o_ber = ber;
|
||||
|
||||
rc = tavl_insert(
|
||||
&upstream->c_ops, op, operation_upstream_cmp, avl_dup_error );
|
||||
assert( rc == LDAP_SUCCESS );
|
||||
|
||||
CONNECTION_UNLOCK(upstream);
|
||||
|
||||
connection_write_cb( -1, 0, upstream );
|
||||
return LDAP_SUCCESS;
|
||||
}
|
||||
|
||||
int
|
||||
handle_bind_response(
|
||||
LloadConnection *client,
|
||||
|
|
@ -515,13 +595,20 @@ handle_bind_response(
|
|||
|
||||
CONNECTION_LOCK(upstream);
|
||||
if ( result != LDAP_SASL_BIND_IN_PROGRESS ) {
|
||||
int sasl_finished = 0;
|
||||
if ( !BER_BVISNULL( &upstream->c_sasl_bind_mech ) ) {
|
||||
sasl_finished = 1;
|
||||
ber_memfree( upstream->c_sasl_bind_mech.bv_val );
|
||||
BER_BVZERO( &upstream->c_sasl_bind_mech );
|
||||
}
|
||||
|
||||
upstream->c_state = LLOAD_C_READY;
|
||||
assert( op->o_client_msgid && op->o_upstream_msgid );
|
||||
op->o_pin_id = 0;
|
||||
|
||||
if ( sasl_finished && result == LDAP_SUCCESS ) {
|
||||
return finish_sasl_bind( upstream, op, ber );
|
||||
}
|
||||
upstream->c_state = LLOAD_C_READY;
|
||||
} else {
|
||||
if ( tavl_delete( &upstream->c_ops, op, operation_upstream_cmp ) ) {
|
||||
op->o_upstream_msgid = 0;
|
||||
|
|
@ -584,6 +671,99 @@ done:
|
|||
return forward_final_response( client, op, ber );
|
||||
}
|
||||
|
||||
int
|
||||
handle_whoami_response(
|
||||
LloadConnection *client,
|
||||
LloadOperation *op,
|
||||
BerElement *ber )
|
||||
{
|
||||
LloadConnection *upstream = op->o_upstream;
|
||||
BerValue matched, diagmsg;
|
||||
BerElement *saved_response = op->o_ber;
|
||||
LloadOperation *removed;
|
||||
ber_int_t result;
|
||||
ber_tag_t tag;
|
||||
ber_len_t len;
|
||||
|
||||
Debug( LDAP_DEBUG_TRACE, "handle_whoami_response: "
|
||||
"connid=%ld received whoami response in lieu of connid=%ld\n",
|
||||
upstream->c_connid, client->c_connid );
|
||||
|
||||
tag = ber_scanf( ber, "{emm" /* "}" */,
|
||||
&result, &matched, &diagmsg );
|
||||
if ( tag == LBER_ERROR ) {
|
||||
operation_send_reject( op, LDAP_OTHER, "upstream protocol error", 0 );
|
||||
return -1;
|
||||
}
|
||||
|
||||
CONNECTION_LOCK_DECREF(upstream);
|
||||
if ( result == LDAP_PROTOCOL_ERROR ) {
|
||||
LloadBackend *b;
|
||||
|
||||
b = (LloadBackend *)upstream->c_private;
|
||||
Debug( LDAP_DEBUG_ANY, "handle_whoami_response: "
|
||||
"Who Am I? extended operation not supported on backend %s, "
|
||||
"proxyauthz with clients that do SASL binds will not work "
|
||||
"msg=%s!\n",
|
||||
b->b_uri.bv_val, diagmsg.bv_val );
|
||||
CONNECTION_UNLOCK_INCREF(upstream);
|
||||
operation_send_reject( op, LDAP_OTHER, "upstream protocol error", 0 );
|
||||
return -1;
|
||||
}
|
||||
upstream->c_state = LLOAD_C_READY;
|
||||
|
||||
CONNECTION_UNLOCK_INCREF(upstream);
|
||||
|
||||
tag = ber_peek_tag( ber, &len );
|
||||
|
||||
CONNECTION_LOCK_DECREF(client);
|
||||
|
||||
assert( client->c_state == LLOAD_C_BINDING &&
|
||||
BER_BVISNULL( &client->c_auth ) );
|
||||
if ( !BER_BVISNULL( &client->c_auth ) ) {
|
||||
ber_memfree( client->c_auth.bv_val );
|
||||
BER_BVZERO( &client->c_auth );
|
||||
}
|
||||
|
||||
if ( tag == LDAP_TAG_EXOP_RES_VALUE ) {
|
||||
tag = ber_scanf( ber, "o", &client->c_auth );
|
||||
if ( tag == LBER_ERROR ) {
|
||||
operation_send_reject_locked(
|
||||
op, LDAP_OTHER, "upstream protocol error", 0 );
|
||||
CONNECTION_DESTROY(client);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
removed = tavl_delete( &client->c_ops, op, operation_client_cmp );
|
||||
assert( !removed || op == removed );
|
||||
|
||||
Debug( LDAP_DEBUG_TRACE, "handle_whoami_response: "
|
||||
"connid=%ld new authid=%s\n",
|
||||
client->c_connid, client->c_auth.bv_val );
|
||||
|
||||
if ( client->c_state == LLOAD_C_BINDING ) {
|
||||
op->o_client = NULL;
|
||||
client->c_state = LLOAD_C_READY;
|
||||
client->c_type = LLOAD_C_OPEN;
|
||||
client->c_pin_id = 0;
|
||||
if ( !BER_BVISNULL( &client->c_auth ) &&
|
||||
!ber_bvstrcasecmp( &client->c_auth, &lloadd_identity ) ) {
|
||||
client->c_type = LLOAD_C_PRIVILEGED;
|
||||
}
|
||||
if ( !BER_BVISNULL( &client->c_sasl_bind_mech ) ) {
|
||||
ber_memfree( client->c_sasl_bind_mech.bv_val );
|
||||
BER_BVZERO( &client->c_sasl_bind_mech );
|
||||
}
|
||||
}
|
||||
|
||||
CONNECTION_UNLOCK_INCREF(client);
|
||||
|
||||
/* defer the disposal of ber to operation_destroy_* */
|
||||
op->o_ber = ber;
|
||||
return forward_final_response( client, op, saved_response );
|
||||
}
|
||||
|
||||
#ifdef LDAP_API_FEATURE_VERIFY_CREDENTIALS
|
||||
int
|
||||
handle_vc_bind_response(
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@ LDAP_SLAPD_F (void) backends_destroy( void );
|
|||
*/
|
||||
LDAP_SLAPD_F (int) request_bind( LloadConnection *c, LloadOperation *op );
|
||||
LDAP_SLAPD_F (int) handle_bind_response( LloadConnection *client, LloadOperation *op, BerElement *ber );
|
||||
LDAP_SLAPD_F (int) handle_whoami_response( LloadConnection *client, LloadOperation *op, BerElement *ber );
|
||||
LDAP_SLAPD_F (int) handle_vc_bind_response( LloadConnection *client, LloadOperation *op, BerElement *ber );
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -190,11 +190,16 @@ handle_one_response( LloadConnection *c )
|
|||
handler = handle_bind_response;
|
||||
break;
|
||||
case LDAP_RES_EXTENDED:
|
||||
#ifdef LDAP_API_FEATURE_VERIFY_CREDENTIALS
|
||||
if ( op->o_tag == LDAP_REQ_BIND ) {
|
||||
handler = handle_vc_bind_response;
|
||||
}
|
||||
#ifdef LDAP_API_FEATURE_VERIFY_CREDENTIALS
|
||||
if ( lload_features & LLOAD_FEATURE_VC ) {
|
||||
handler = handle_vc_bind_response;
|
||||
} else
|
||||
#endif /* LDAP_API_FEATURE_VERIFY_CREDENTIALS */
|
||||
{
|
||||
handler = handle_whoami_response;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
if ( !handler ) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue