1 /* bind.c - decode an ldap bind operation and pass it to a backend db */
4 * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
5 * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
9 * Copyright (c) 1995 Regents of the University of Michigan.
10 * All rights reserved.
12 * Redistribution and use in source and binary forms are permitted
13 * provided that this notice is preserved and that due credit is given
14 * to the University of Michigan at Ann Arbor. The name of the University
15 * may not be used to endorse or promote products derived from this
16 * software without specific prior written permission. This software
17 * is provided ``as is'' without express or implied warranty.
21 #include "slapi_common.h"
25 #include <ac/string.h>
26 #include <ac/socket.h>
39 BerElement *ber = op->o_ber;
42 struct berval mech = { 0, NULL };
43 struct berval dn = { 0, NULL };
44 struct berval pdn = { 0, NULL };
45 struct berval ndn = { 0, NULL };
46 struct berval edn = { 0, NULL };
48 int rc = LDAP_SUCCESS;
50 struct berval cred = { 0, NULL };
53 Slapi_PBlock *pb = op->o_pb;
56 LDAP_LOG( OPERATION, ENTRY, "do_bind: conn %d\n", conn->c_connid, 0, 0 );
58 Debug( LDAP_DEBUG_TRACE, "do_bind\n", 0, 0, 0 );
62 * Force to connection to "anonymous" until bind succeeds.
64 ldap_pvt_thread_mutex_lock( &conn->c_mutex );
65 if ( conn->c_sasl_bind_in_progress ) be = conn->c_authz_backend;
67 /* log authorization identity demotion */
68 if ( conn->c_dn.bv_len ) {
69 Statslog( LDAP_DEBUG_STATS,
70 "conn=%lu op=%lu BIND anonymous mech=implicit ssf=0",
71 op->o_connid, op->o_opid, 0, 0, 0 );
74 connection2anonymous( conn );
75 if ( conn->c_sasl_bind_in_progress ) conn->c_authz_backend = be;
76 ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
78 if ( op->o_dn.bv_val != NULL ) {
79 free( op->o_dn.bv_val );
80 op->o_dn.bv_val = ch_strdup( "" );
84 if ( op->o_ndn.bv_val != NULL ) {
85 free( op->o_ndn.bv_val );
86 op->o_ndn.bv_val = ch_strdup( "" );
91 * Parse the bind request. It looks like this:
93 * BindRequest ::= SEQUENCE {
94 * version INTEGER, -- version
95 * name DistinguishedName, -- dn
96 * authentication CHOICE {
97 * simple [0] OCTET STRING -- passwd
98 * krbv42ldap [1] OCTET STRING
99 * krbv42dsa [2] OCTET STRING
100 * SASL [3] SaslCredentials
104 * SaslCredentials ::= SEQUENCE {
105 * mechanism LDAPString,
106 * credentials OCTET STRING OPTIONAL
110 tag = ber_scanf( ber, "{imt" /*}*/, &version, &dn, &method );
112 if ( tag == LBER_ERROR ) {
114 LDAP_LOG( OPERATION, ERR,
115 "do_bind: conn %d ber_scanf failed\n", conn->c_connid, 0, 0 );
117 Debug( LDAP_DEBUG_ANY, "bind: ber_scanf failed\n", 0, 0, 0 );
119 send_ldap_disconnect( conn, op,
120 LDAP_PROTOCOL_ERROR, "decoding error" );
125 op->o_protocol = version;
127 if( method != LDAP_AUTH_SASL ) {
128 tag = ber_scanf( ber, /*{*/ "m}", &cred );
131 tag = ber_scanf( ber, "{o" /*}*/, &mech );
133 if ( tag != LBER_ERROR ) {
135 tag = ber_peek_tag( ber, &len );
137 if ( tag == LDAP_TAG_LDAPCRED ) {
138 tag = ber_scanf( ber, "m", &cred );
140 tag = LDAP_TAG_LDAPCRED;
145 if ( tag != LBER_ERROR ) {
146 tag = ber_scanf( ber, /*{{*/ "}}" );
151 if ( tag == LBER_ERROR ) {
152 send_ldap_disconnect( conn, op,
155 rc = SLAPD_DISCONNECT;
159 if( (rc = get_ctrls( conn, op, 1 )) != LDAP_SUCCESS ) {
161 LDAP_LOG( OPERATION, INFO,
162 "do_bind: conn %d get_ctrls failed\n", conn->c_connid, 0, 0 );
164 Debug( LDAP_DEBUG_ANY, "do_bind: get_ctrls failed\n", 0, 0, 0 );
169 rc = dnPrettyNormal( NULL, &dn, &pdn, &ndn );
170 if ( rc != LDAP_SUCCESS ) {
172 LDAP_LOG( OPERATION, INFO,
173 "do_bind: conn %d invalid dn (%s)\n",
174 conn->c_connid, dn.bv_val, 0 );
176 Debug( LDAP_DEBUG_ANY, "bind: invalid dn (%s)\n",
179 send_ldap_result( conn, op, rc = LDAP_INVALID_DN_SYNTAX, NULL,
180 "invalid DN", NULL, NULL );
184 if( method == LDAP_AUTH_SASL ) {
186 LDAP_LOG( OPERATION, DETAIL1,
187 "do_sasl_bind: conn %d dn (%s) mech %s\n",
188 conn->c_connid, pdn.bv_val, mech.bv_val );
190 Debug( LDAP_DEBUG_TRACE, "do_sasl_bind: dn (%s) mech %s\n",
191 pdn.bv_val, mech.bv_val, NULL );
196 LDAP_LOG( OPERATION, DETAIL1,
197 "do_bind: version=%ld dn=\"%s\" method=%ld\n",
198 (unsigned long) version, pdn.bv_val, (unsigned long)method );
200 Debug( LDAP_DEBUG_TRACE,
201 "do_bind: version=%ld dn=\"%s\" method=%ld\n",
202 (unsigned long) version,
203 pdn.bv_val, (unsigned long) method );
207 Statslog( LDAP_DEBUG_STATS, "conn=%lu op=%lu BIND dn=\"%s\" method=%ld\n",
208 op->o_connid, op->o_opid, pdn.bv_val, (unsigned long) method, 0 );
210 if ( version < LDAP_VERSION_MIN || version > LDAP_VERSION_MAX ) {
212 LDAP_LOG( OPERATION, INFO,
213 "do_bind: conn %d unknown version = %ld\n",
214 conn->c_connid, (unsigned long)version, 0 );
216 Debug( LDAP_DEBUG_ANY, "do_bind: unknown version=%ld\n",
217 (unsigned long) version, 0, 0 );
219 send_ldap_result( conn, op, rc = LDAP_PROTOCOL_ERROR,
220 NULL, "requested protocol version not supported", NULL, NULL );
223 } else if (!( global_allows & SLAP_ALLOW_BIND_V2 ) &&
224 version < LDAP_VERSION3 )
226 send_ldap_result( conn, op, rc = LDAP_PROTOCOL_ERROR,
227 NULL, "requested protocol version not allowed", NULL, NULL );
231 /* we set connection version regardless of whether bind succeeds
234 ldap_pvt_thread_mutex_lock( &conn->c_mutex );
235 conn->c_protocol = version;
236 ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
238 /* check for inappropriate controls */
239 if( get_manageDSAit( op ) == SLAP_CRITICAL_CONTROL ) {
240 send_ldap_result( conn, op,
241 rc = LDAP_UNAVAILABLE_CRITICAL_EXTENSION,
242 NULL, "manageDSAit control inappropriate",
247 /* Set the bindop for the benefit of in-directory SASL lookups */
248 conn->c_sasl_bindop = op;
250 if ( method == LDAP_AUTH_SASL ) {
253 if ( version < LDAP_VERSION3 ) {
255 LDAP_LOG( OPERATION, INFO,
256 "do_bind: conn %d sasl with LDAPv%ld\n",
257 conn->c_connid, (unsigned long)version , 0 );
259 Debug( LDAP_DEBUG_ANY, "do_bind: sasl with LDAPv%ld\n",
260 (unsigned long) version, 0, 0 );
262 send_ldap_disconnect( conn, op,
263 LDAP_PROTOCOL_ERROR, "SASL bind requires LDAPv3" );
264 rc = SLAPD_DISCONNECT;
268 if( mech.bv_len == 0 ) {
270 LDAP_LOG( OPERATION, INFO,
271 "do_bind: conn %d no SASL mechanism provided\n",
272 conn->c_connid, 0, 0 );
274 Debug( LDAP_DEBUG_ANY,
275 "do_bind: no sasl mechanism provided\n",
278 send_ldap_result( conn, op, rc = LDAP_AUTH_METHOD_NOT_SUPPORTED,
279 NULL, "no SASL mechanism provided", NULL, NULL );
283 /* check restrictions */
284 rc = backend_check_restrictions( NULL, conn, op, &mech, &text );
285 if( rc != LDAP_SUCCESS ) {
286 send_ldap_result( conn, op, rc,
287 NULL, text, NULL, NULL );
291 ldap_pvt_thread_mutex_lock( &conn->c_mutex );
292 if ( conn->c_sasl_bind_in_progress ) {
293 if( !bvmatch( &conn->c_sasl_bind_mech, &mech ) ) {
294 /* mechanism changed between bind steps */
295 slap_sasl_reset(conn);
298 conn->c_sasl_bind_mech = mech;
302 ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
304 rc = slap_sasl_bind( conn, op,
308 ldap_pvt_thread_mutex_lock( &conn->c_mutex );
309 if( rc == LDAP_SUCCESS ) {
311 if( edn.bv_len != 0 ) {
312 /* edn is always normalized already */
313 ber_dupbv( &conn->c_ndn, &conn->c_dn );
315 conn->c_authmech = conn->c_sasl_bind_mech;
316 conn->c_sasl_bind_mech.bv_val = NULL;
317 conn->c_sasl_bind_mech.bv_len = 0;
318 conn->c_sasl_bind_in_progress = 0;
320 conn->c_sasl_ssf = ssf;
321 if( ssf > conn->c_ssf ) {
325 if( conn->c_dn.bv_len != 0 ) {
326 ber_len_t max = sockbuf_max_incoming_auth;
327 ber_sockbuf_ctrl( conn->c_sb,
328 LBER_SB_OPT_SET_MAX_INCOMING, &max );
331 /* log authorization identity */
332 Statslog( LDAP_DEBUG_STATS,
333 "conn=%lu op=%lu BIND dn=\"%s\" mech=%s ssf=%d\n",
334 op->o_connid, op->o_opid,
335 conn->c_dn.bv_val ? conn->c_dn.bv_val : "<empty>",
336 conn->c_authmech.bv_val, ssf );
339 LDAP_LOG( OPERATION, DETAIL1,
340 "do_bind: SASL/%s bind: dn=\"%s\" ssf=%d\n",
341 conn->c_authmech.bv_val,
342 conn->c_dn.bv_val ? conn->c_dn.bv_val : "<empty>",
345 Debug( LDAP_DEBUG_TRACE,
346 "do_bind: SASL/%s bind: dn=\"%s\" ssf=%d\n",
347 conn->c_authmech.bv_val,
348 conn->c_dn.bv_val ? conn->c_dn.bv_val : "<empty>",
352 } else if ( rc == LDAP_SASL_BIND_IN_PROGRESS ) {
353 conn->c_sasl_bind_in_progress = 1;
356 if ( conn->c_sasl_bind_mech.bv_val ) {
357 free( conn->c_sasl_bind_mech.bv_val );
358 conn->c_sasl_bind_mech.bv_val = NULL;
359 conn->c_sasl_bind_mech.bv_len = 0;
361 conn->c_sasl_bind_in_progress = 0;
363 ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
368 /* Not SASL, cancel any in-progress bind */
369 ldap_pvt_thread_mutex_lock( &conn->c_mutex );
371 if ( conn->c_sasl_bind_mech.bv_val != NULL ) {
372 free(conn->c_sasl_bind_mech.bv_val);
373 conn->c_sasl_bind_mech.bv_val = NULL;
374 conn->c_sasl_bind_mech.bv_len = 0;
376 conn->c_sasl_bind_in_progress = 0;
378 slap_sasl_reset( conn );
379 ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
382 if ( method == LDAP_AUTH_SIMPLE ) {
383 /* accept "anonymous" binds */
384 if ( cred.bv_len == 0 || ndn.bv_len == 0 ) {
389 !( global_allows & SLAP_ALLOW_BIND_ANON_CRED ))
391 /* cred is not empty, disallow */
392 rc = LDAP_INVALID_CREDENTIALS;
394 } else if ( ndn.bv_len &&
395 !( global_allows & SLAP_ALLOW_BIND_ANON_DN ))
397 /* DN is not empty, disallow */
398 rc = LDAP_UNWILLING_TO_PERFORM;
399 text = "unwilling to allow anonymous bind with non-empty DN";
401 } else if ( global_disallows & SLAP_DISALLOW_BIND_ANON ) {
403 rc = LDAP_INAPPROPRIATE_AUTH;
404 text = "anonymous bind disallowed";
407 rc = backend_check_restrictions( NULL, conn, op,
412 * we already forced connection to "anonymous",
413 * just need to send success
415 send_ldap_result( conn, op, rc,
416 NULL, text, NULL, NULL );
418 LDAP_LOG( OPERATION, DETAIL1,
419 "do_bind: conn %d v%d anonymous bind\n",
420 conn->c_connid, version , 0 );
422 Debug( LDAP_DEBUG_TRACE, "do_bind: v%d anonymous bind\n",
427 } else if ( global_disallows & SLAP_DISALLOW_BIND_SIMPLE ) {
428 /* disallow simple authentication */
429 rc = LDAP_UNWILLING_TO_PERFORM;
430 text = "unwilling to perform simple authentication";
432 send_ldap_result( conn, op, rc,
433 NULL, text, NULL, NULL );
435 LDAP_LOG( OPERATION, INFO,
436 "do_bind: conn %d v%d simple bind(%s) disallowed\n",
437 conn->c_connid, version, ndn.bv_val );
439 Debug( LDAP_DEBUG_TRACE,
440 "do_bind: v%d simple bind(%s) disallowed\n",
441 version, ndn.bv_val, 0 );
445 } else if (( global_disallows & SLAP_DISALLOW_BIND_SIMPLE_UNPROTECTED )
446 && ( op->o_ssf <= 1 ))
448 rc = LDAP_CONFIDENTIALITY_REQUIRED;
449 text = "unwilling to perform simple authentication "
450 "without confidentilty protection";
452 send_ldap_result( conn, op, rc,
453 NULL, text, NULL, NULL );
456 LDAP_LOG( OPERATION, INFO, "do_bind: conn %d "
457 "v%d unprotected simple bind(%s) disallowed\n",
458 conn->c_connid, version, ndn.bv_val );
460 Debug( LDAP_DEBUG_TRACE,
461 "do_bind: v%d unprotected simple bind(%s) disallowed\n",
462 version, ndn.bv_val, 0 );
467 #ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
468 } else if ( method == LDAP_AUTH_KRBV41 || method == LDAP_AUTH_KRBV42 ) {
469 if ( global_disallows & SLAP_DISALLOW_BIND_KRBV4 ) {
470 /* disallow simple authentication */
471 rc = LDAP_UNWILLING_TO_PERFORM;
472 text = "unwilling to perform Kerberos V4 bind";
474 send_ldap_result( conn, op, rc,
475 NULL, text, NULL, NULL );
477 LDAP_LOG( OPERATION, DETAIL1,
478 "do_bind: conn %d v%d Kerberos V4 bind\n",
479 conn->c_connid, version , 0 );
481 Debug( LDAP_DEBUG_TRACE, "do_bind: v%d Kerberos V4 bind\n",
489 rc = LDAP_AUTH_METHOD_NOT_SUPPORTED;
490 text = "unknown authentication method";
492 send_ldap_result( conn, op, rc,
493 NULL, text, NULL, NULL );
495 LDAP_LOG( OPERATION, INFO,
496 "do_bind: conn %ld v%d unknown authentication method (%ld)\n",
497 conn->c_connid, version, method );
499 Debug( LDAP_DEBUG_TRACE,
500 "do_bind: v%d unknown authentication method (%ld)\n",
501 version, method, 0 );
507 * We could be serving multiple database backends. Select the
508 * appropriate one, or send a referral to our "referral server"
509 * if we don't hold it.
512 if ( (be = select_backend( &ndn, 0, 0 )) == NULL ) {
513 if ( default_referral ) {
514 BerVarray ref = referral_rewrite( default_referral,
515 NULL, &pdn, LDAP_SCOPE_DEFAULT );
517 send_ldap_result( conn, op, rc = LDAP_REFERRAL,
518 NULL, NULL, ref ? ref : default_referral, NULL );
520 ber_bvarray_free( ref );
523 /* noSuchObject is not allowed to be returned by bind */
524 send_ldap_result( conn, op, rc = LDAP_INVALID_CREDENTIALS,
525 NULL, NULL, NULL, NULL );
531 /* check restrictions */
532 rc = backend_check_restrictions( be, conn, op, NULL, &text );
533 if( rc != LDAP_SUCCESS ) {
534 send_ldap_result( conn, op, rc,
535 NULL, text, NULL, NULL );
539 #if defined( LDAP_SLAPI )
540 slapi_x_backend_set_pb( pb, be );
541 slapi_x_connection_set_pb( pb, conn );
542 slapi_x_operation_set_pb( pb, op );
543 slapi_pblock_set( pb, SLAPI_BIND_TARGET, (void *)dn.bv_val );
544 slapi_pblock_set( pb, SLAPI_BIND_METHOD, (void *)method );
545 slapi_pblock_set( pb, SLAPI_BIND_CREDENTIALS, (void *)&cred );
546 slapi_pblock_set( pb, SLAPI_MANAGEDSAIT, (void *)(1) );
548 rc = doPluginFNs( be, SLAPI_PLUGIN_PRE_BIND_FN, pb );
549 if ( rc != SLAPI_BIND_SUCCESS ) {
551 * Binding is a special case for SLAPI plugins. It is
552 * possible for a bind plugin to be successful *and*
553 * abort further processing; this means it has handled
554 * a bind request authoritatively. If we have reached
555 * here, a result has been sent to the client (XXX
556 * need to check with Sun whether SLAPI_BIND_ANONYMOUS
557 * means a result has been sent).
561 if ( slapi_pblock_get( pb, SLAPI_RESULT_CODE, (void *)&ldapRc ) != 0 )
566 if ( rc != SLAPI_BIND_FAIL && ldapRc == LDAP_SUCCESS ) {
567 /* Set the new connection DN. */
568 if ( rc != SLAPI_BIND_ANONYMOUS ) {
569 slapi_pblock_get( pb, SLAPI_CONN_DN, (void *)&edn.bv_val );
571 rc = dnPrettyNormal( NULL, &edn, &pdn, &ndn );
572 ldap_pvt_thread_mutex_lock( &conn->c_mutex );
579 if ( conn->c_dn.bv_len != 0 ) {
580 ber_len_t max = sockbuf_max_incoming_auth;
581 ber_sockbuf_ctrl( conn->c_sb, LBER_SB_OPT_SET_MAX_INCOMING, &max );
583 /* log authorization identity */
584 Statslog( LDAP_DEBUG_STATS,
585 "conn=%lu op=%lu BIND dn=\"%s\" mech=simple (SLAPI) ssf=0\n",
586 op->o_connid, op->o_opid,
587 conn->c_dn.bv_val, 0, 0 );
588 ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
591 LDAP_LOG( OPERATION, INFO, "do_bind: Bind preoperation plugin returned %d\n",
594 Debug(LDAP_DEBUG_TRACE, "do_bind: Bind preoperation plugin returned %d.\n",
600 #endif /* defined( LDAP_SLAPI ) */
605 /* deref suffix alias if appropriate */
606 suffix_alias( be, &ndn );
608 ret = (*be->be_bind)( be, conn, op,
609 &pdn, &ndn, method, &cred, &edn );
612 ldap_pvt_thread_mutex_lock( &conn->c_mutex );
614 if( conn->c_authz_backend == NULL ) {
615 conn->c_authz_backend = be;
630 if( conn->c_dn.bv_len != 0 ) {
631 ber_len_t max = sockbuf_max_incoming_auth;
632 ber_sockbuf_ctrl( conn->c_sb,
633 LBER_SB_OPT_SET_MAX_INCOMING, &max );
636 /* log authorization identity */
637 Statslog( LDAP_DEBUG_STATS,
638 "conn=%lu op=%lu BIND dn=\"%s\" mech=simple ssf=0\n",
639 op->o_connid, op->o_opid,
640 conn->c_dn.bv_val, conn->c_authmech.bv_val, 0 );
643 LDAP_LOG( OPERATION, DETAIL1,
644 "do_bind: v%d bind: \"%s\" to \"%s\" \n",
645 version, conn->c_dn.bv_val, conn->c_dn.bv_val );
647 Debug( LDAP_DEBUG_TRACE,
648 "do_bind: v%d bind: \"%s\" to \"%s\"\n",
649 version, dn.bv_val, conn->c_dn.bv_val );
652 ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
654 /* send this here to avoid a race condition */
655 send_ldap_result( conn, op, LDAP_SUCCESS,
656 NULL, NULL, NULL, NULL );
658 } else if (edn.bv_val != NULL) {
663 send_ldap_result( conn, op, rc = LDAP_UNWILLING_TO_PERFORM,
664 NULL, "operation not supported within namingContext",
668 #if defined( LDAP_SLAPI )
669 if ( doPluginFNs( be, SLAPI_PLUGIN_POST_BIND_FN, pb ) != 0 ) {
671 LDAP_LOG( OPERATION, INFO, "do_bind: Bind postoperation plugins failed\n",
674 Debug(LDAP_DEBUG_TRACE, "do_bind: Bind postoperation plugins failed.\n",
678 #endif /* defined( LDAP_SLAPI ) */
681 conn->c_sasl_bindop = NULL;
683 if( pdn.bv_val != NULL ) {
686 if( ndn.bv_val != NULL ) {
689 if ( mech.bv_val != NULL ) {