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.
24 #include <ac/string.h>
25 #include <ac/socket.h>
38 BerElement *ber = op->o_ber;
41 struct berval mech = { 0, NULL };
42 struct berval dn = { 0, NULL };
43 struct berval pdn = { 0, NULL };
44 struct berval ndn = { 0, NULL };
45 struct berval edn = { 0, NULL };
47 int rc = LDAP_SUCCESS;
49 struct berval cred = { 0, NULL };
53 Slapi_PBlock *pb = op->o_pb;
57 LDAP_LOG( OPERATION, ENTRY, "do_bind: conn %d\n", conn->c_connid, 0, 0 );
59 Debug( LDAP_DEBUG_TRACE, "do_bind\n", 0, 0, 0 );
63 * Force to connection to "anonymous" until bind succeeds.
65 ldap_pvt_thread_mutex_lock( &conn->c_mutex );
66 if ( conn->c_sasl_bind_in_progress ) be = conn->c_authz_backend;
68 /* log authorization identity demotion */
69 if ( conn->c_dn.bv_len ) {
70 Statslog( LDAP_DEBUG_STATS,
71 "conn=%lu op=%lu BIND anonymous mech=implicit ssf=0",
72 op->o_connid, op->o_opid, 0, 0, 0 );
75 connection2anonymous( conn );
76 if ( conn->c_sasl_bind_in_progress ) conn->c_authz_backend = be;
77 ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
79 if ( op->o_dn.bv_val != NULL ) {
80 free( op->o_dn.bv_val );
81 op->o_dn.bv_val = ch_strdup( "" );
85 if ( op->o_ndn.bv_val != NULL ) {
86 free( op->o_ndn.bv_val );
87 op->o_ndn.bv_val = ch_strdup( "" );
92 * Parse the bind request. It looks like this:
94 * BindRequest ::= SEQUENCE {
95 * version INTEGER, -- version
96 * name DistinguishedName, -- dn
97 * authentication CHOICE {
98 * simple [0] OCTET STRING -- passwd
99 * krbv42ldap [1] OCTET STRING
100 * krbv42dsa [2] OCTET STRING
101 * SASL [3] SaslCredentials
105 * SaslCredentials ::= SEQUENCE {
106 * mechanism LDAPString,
107 * credentials OCTET STRING OPTIONAL
111 tag = ber_scanf( ber, "{imt" /*}*/, &version, &dn, &method );
113 if ( tag == LBER_ERROR ) {
115 LDAP_LOG( OPERATION, ERR,
116 "do_bind: conn %d ber_scanf failed\n", conn->c_connid, 0, 0 );
118 Debug( LDAP_DEBUG_ANY, "bind: ber_scanf failed\n", 0, 0, 0 );
120 send_ldap_disconnect( conn, op,
121 LDAP_PROTOCOL_ERROR, "decoding error" );
126 op->o_protocol = version;
128 if( method != LDAP_AUTH_SASL ) {
129 tag = ber_scanf( ber, /*{*/ "m}", &cred );
132 tag = ber_scanf( ber, "{o" /*}*/, &mech );
134 if ( tag != LBER_ERROR ) {
136 tag = ber_peek_tag( ber, &len );
138 if ( tag == LDAP_TAG_LDAPCRED ) {
139 tag = ber_scanf( ber, "m", &cred );
141 tag = LDAP_TAG_LDAPCRED;
146 if ( tag != LBER_ERROR ) {
147 tag = ber_scanf( ber, /*{{*/ "}}" );
152 if ( tag == LBER_ERROR ) {
153 send_ldap_disconnect( conn, op,
156 rc = SLAPD_DISCONNECT;
160 if( (rc = get_ctrls( conn, op, 1 )) != LDAP_SUCCESS ) {
162 LDAP_LOG( OPERATION, INFO,
163 "do_bind: conn %d get_ctrls failed\n", conn->c_connid, 0, 0 );
165 Debug( LDAP_DEBUG_ANY, "do_bind: get_ctrls failed\n", 0, 0, 0 );
170 rc = dnPrettyNormal( NULL, &dn, &pdn, &ndn );
171 if ( rc != LDAP_SUCCESS ) {
173 LDAP_LOG( OPERATION, INFO,
174 "do_bind: conn %d invalid dn (%s)\n",
175 conn->c_connid, dn.bv_val, 0 );
177 Debug( LDAP_DEBUG_ANY, "bind: invalid dn (%s)\n",
180 send_ldap_result( conn, op, rc = LDAP_INVALID_DN_SYNTAX, NULL,
181 "invalid DN", NULL, NULL );
185 if( method == LDAP_AUTH_SASL ) {
187 LDAP_LOG( OPERATION, DETAIL1,
188 "do_sasl_bind: conn %d dn (%s) mech %s\n",
189 conn->c_connid, pdn.bv_val, mech.bv_val );
191 Debug( LDAP_DEBUG_TRACE, "do_sasl_bind: dn (%s) mech %s\n",
192 pdn.bv_val, mech.bv_val, NULL );
197 LDAP_LOG( OPERATION, DETAIL1,
198 "do_bind: version=%ld dn=\"%s\" method=%ld\n",
199 (unsigned long) version, pdn.bv_val, (unsigned long)method );
201 Debug( LDAP_DEBUG_TRACE,
202 "do_bind: version=%ld dn=\"%s\" method=%ld\n",
203 (unsigned long) version,
204 pdn.bv_val, (unsigned long) method );
208 Statslog( LDAP_DEBUG_STATS, "conn=%lu op=%lu BIND dn=\"%s\" method=%ld\n",
209 op->o_connid, op->o_opid, pdn.bv_val, (unsigned long) method, 0 );
211 if ( version < LDAP_VERSION_MIN || version > LDAP_VERSION_MAX ) {
213 LDAP_LOG( OPERATION, INFO,
214 "do_bind: conn %d unknown version = %ld\n",
215 conn->c_connid, (unsigned long)version, 0 );
217 Debug( LDAP_DEBUG_ANY, "do_bind: unknown version=%ld\n",
218 (unsigned long) version, 0, 0 );
220 send_ldap_result( conn, op, rc = LDAP_PROTOCOL_ERROR,
221 NULL, "requested protocol version not supported", NULL, NULL );
224 } else if (!( global_allows & SLAP_ALLOW_BIND_V2 ) &&
225 version < LDAP_VERSION3 )
227 send_ldap_result( conn, op, rc = LDAP_PROTOCOL_ERROR,
228 NULL, "requested protocol version not allowed", NULL, NULL );
232 /* we set connection version regardless of whether bind succeeds
235 ldap_pvt_thread_mutex_lock( &conn->c_mutex );
236 conn->c_protocol = version;
237 ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
239 /* check for inappropriate controls */
240 if( get_manageDSAit( op ) == SLAP_CRITICAL_CONTROL ) {
241 send_ldap_result( conn, op,
242 rc = LDAP_UNAVAILABLE_CRITICAL_EXTENSION,
243 NULL, "manageDSAit control inappropriate",
248 /* Set the bindop for the benefit of in-directory SASL lookups */
249 conn->c_sasl_bindop = op;
251 if ( method == LDAP_AUTH_SASL ) {
254 if ( version < LDAP_VERSION3 ) {
256 LDAP_LOG( OPERATION, INFO,
257 "do_bind: conn %d sasl with LDAPv%ld\n",
258 conn->c_connid, (unsigned long)version , 0 );
260 Debug( LDAP_DEBUG_ANY, "do_bind: sasl with LDAPv%ld\n",
261 (unsigned long) version, 0, 0 );
263 send_ldap_disconnect( conn, op,
264 LDAP_PROTOCOL_ERROR, "SASL bind requires LDAPv3" );
265 rc = SLAPD_DISCONNECT;
269 if( mech.bv_len == 0 ) {
271 LDAP_LOG( OPERATION, INFO,
272 "do_bind: conn %d no SASL mechanism provided\n",
273 conn->c_connid, 0, 0 );
275 Debug( LDAP_DEBUG_ANY,
276 "do_bind: no sasl mechanism provided\n",
279 send_ldap_result( conn, op, rc = LDAP_AUTH_METHOD_NOT_SUPPORTED,
280 NULL, "no SASL mechanism provided", NULL, NULL );
284 /* check restrictions */
285 rc = backend_check_restrictions( NULL, conn, op, &mech, &text );
286 if( rc != LDAP_SUCCESS ) {
287 send_ldap_result( conn, op, rc,
288 NULL, text, NULL, NULL );
292 ldap_pvt_thread_mutex_lock( &conn->c_mutex );
293 if ( conn->c_sasl_bind_in_progress ) {
294 if( !bvmatch( &conn->c_sasl_bind_mech, &mech ) ) {
295 /* mechanism changed between bind steps */
296 slap_sasl_reset(conn);
299 conn->c_sasl_bind_mech = mech;
303 ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
305 rc = slap_sasl_bind( conn, op,
309 ldap_pvt_thread_mutex_lock( &conn->c_mutex );
310 if( rc == LDAP_SUCCESS ) {
312 if( edn.bv_len != 0 ) {
313 /* edn is always normalized already */
314 ber_dupbv( &conn->c_ndn, &conn->c_dn );
316 conn->c_authmech = conn->c_sasl_bind_mech;
317 conn->c_sasl_bind_mech.bv_val = NULL;
318 conn->c_sasl_bind_mech.bv_len = 0;
319 conn->c_sasl_bind_in_progress = 0;
321 conn->c_sasl_ssf = ssf;
322 if( ssf > conn->c_ssf ) {
326 if( conn->c_dn.bv_len != 0 ) {
327 ber_len_t max = sockbuf_max_incoming_auth;
328 ber_sockbuf_ctrl( conn->c_sb,
329 LBER_SB_OPT_SET_MAX_INCOMING, &max );
332 /* log authorization identity */
333 Statslog( LDAP_DEBUG_STATS,
334 "conn=%lu op=%lu BIND dn=\"%s\" mech=%s ssf=%d\n",
335 op->o_connid, op->o_opid,
336 conn->c_dn.bv_val ? conn->c_dn.bv_val : "<empty>",
337 conn->c_authmech.bv_val, ssf );
340 LDAP_LOG( OPERATION, DETAIL1,
341 "do_bind: SASL/%s bind: dn=\"%s\" ssf=%d\n",
342 conn->c_authmech.bv_val,
343 conn->c_dn.bv_val ? conn->c_dn.bv_val : "<empty>",
346 Debug( LDAP_DEBUG_TRACE,
347 "do_bind: SASL/%s bind: dn=\"%s\" ssf=%d\n",
348 conn->c_authmech.bv_val,
349 conn->c_dn.bv_val ? conn->c_dn.bv_val : "<empty>",
353 } else if ( rc == LDAP_SASL_BIND_IN_PROGRESS ) {
354 conn->c_sasl_bind_in_progress = 1;
357 if ( conn->c_sasl_bind_mech.bv_val ) {
358 free( conn->c_sasl_bind_mech.bv_val );
359 conn->c_sasl_bind_mech.bv_val = NULL;
360 conn->c_sasl_bind_mech.bv_len = 0;
362 conn->c_sasl_bind_in_progress = 0;
364 ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
369 /* Not SASL, cancel any in-progress bind */
370 ldap_pvt_thread_mutex_lock( &conn->c_mutex );
372 if ( conn->c_sasl_bind_mech.bv_val != NULL ) {
373 free(conn->c_sasl_bind_mech.bv_val);
374 conn->c_sasl_bind_mech.bv_val = NULL;
375 conn->c_sasl_bind_mech.bv_len = 0;
377 conn->c_sasl_bind_in_progress = 0;
379 slap_sasl_reset( conn );
380 ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
383 if ( method == LDAP_AUTH_SIMPLE ) {
384 /* accept "anonymous" binds */
385 if ( cred.bv_len == 0 || ndn.bv_len == 0 ) {
390 !( global_allows & SLAP_ALLOW_BIND_ANON_CRED ))
392 /* cred is not empty, disallow */
393 rc = LDAP_INVALID_CREDENTIALS;
395 } else if ( ndn.bv_len &&
396 !( global_allows & SLAP_ALLOW_BIND_ANON_DN ))
398 /* DN is not empty, disallow */
399 rc = LDAP_UNWILLING_TO_PERFORM;
400 text = "unwilling to allow anonymous bind with non-empty DN";
402 } else if ( global_disallows & SLAP_DISALLOW_BIND_ANON ) {
404 rc = LDAP_INAPPROPRIATE_AUTH;
405 text = "anonymous bind disallowed";
408 rc = backend_check_restrictions( NULL, conn, op,
413 * we already forced connection to "anonymous",
414 * just need to send success
416 send_ldap_result( conn, op, rc,
417 NULL, text, NULL, NULL );
419 LDAP_LOG( OPERATION, DETAIL1,
420 "do_bind: conn %d v%d anonymous bind\n",
421 conn->c_connid, version , 0 );
423 Debug( LDAP_DEBUG_TRACE, "do_bind: v%d anonymous bind\n",
428 } else if ( global_disallows & SLAP_DISALLOW_BIND_SIMPLE ) {
429 /* disallow simple authentication */
430 rc = LDAP_UNWILLING_TO_PERFORM;
431 text = "unwilling to perform simple authentication";
433 send_ldap_result( conn, op, rc,
434 NULL, text, NULL, NULL );
436 LDAP_LOG( OPERATION, INFO,
437 "do_bind: conn %d v%d simple bind(%s) disallowed\n",
438 conn->c_connid, version, ndn.bv_val );
440 Debug( LDAP_DEBUG_TRACE,
441 "do_bind: v%d simple bind(%s) disallowed\n",
442 version, ndn.bv_val, 0 );
446 } else if (( global_disallows & SLAP_DISALLOW_BIND_SIMPLE_UNPROTECTED )
447 && ( op->o_ssf <= 1 ))
449 rc = LDAP_CONFIDENTIALITY_REQUIRED;
450 text = "unwilling to perform simple authentication "
451 "without confidentilty protection";
453 send_ldap_result( conn, op, rc,
454 NULL, text, NULL, NULL );
457 LDAP_LOG( OPERATION, INFO, "do_bind: conn %d "
458 "v%d unprotected simple bind(%s) disallowed\n",
459 conn->c_connid, version, ndn.bv_val );
461 Debug( LDAP_DEBUG_TRACE,
462 "do_bind: v%d unprotected simple bind(%s) disallowed\n",
463 version, ndn.bv_val, 0 );
468 #ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
469 } else if ( method == LDAP_AUTH_KRBV41 || method == LDAP_AUTH_KRBV42 ) {
470 if ( global_disallows & SLAP_DISALLOW_BIND_KRBV4 ) {
471 /* disallow simple authentication */
472 rc = LDAP_UNWILLING_TO_PERFORM;
473 text = "unwilling to perform Kerberos V4 bind";
475 send_ldap_result( conn, op, rc,
476 NULL, text, NULL, NULL );
478 LDAP_LOG( OPERATION, DETAIL1,
479 "do_bind: conn %d v%d Kerberos V4 bind\n",
480 conn->c_connid, version , 0 );
482 Debug( LDAP_DEBUG_TRACE, "do_bind: v%d Kerberos V4 bind\n",
490 rc = LDAP_AUTH_METHOD_NOT_SUPPORTED;
491 text = "unknown authentication method";
493 send_ldap_result( conn, op, rc,
494 NULL, text, NULL, NULL );
496 LDAP_LOG( OPERATION, INFO,
497 "do_bind: conn %ld v%d unknown authentication method (%ld)\n",
498 conn->c_connid, version, method );
500 Debug( LDAP_DEBUG_TRACE,
501 "do_bind: v%d unknown authentication method (%ld)\n",
502 version, method, 0 );
508 * We could be serving multiple database backends. Select the
509 * appropriate one, or send a referral to our "referral server"
510 * if we don't hold it.
513 if ( (be = select_backend( &ndn, 0, 0 )) == NULL ) {
514 if ( default_referral ) {
515 BerVarray ref = referral_rewrite( default_referral,
516 NULL, &pdn, LDAP_SCOPE_DEFAULT );
518 send_ldap_result( conn, op, rc = LDAP_REFERRAL,
519 NULL, NULL, ref ? ref : default_referral, NULL );
521 ber_bvarray_free( ref );
524 /* noSuchObject is not allowed to be returned by bind */
525 send_ldap_result( conn, op, rc = LDAP_INVALID_CREDENTIALS,
526 NULL, NULL, NULL, NULL );
532 /* check restrictions */
533 rc = backend_check_restrictions( be, conn, op, NULL, &text );
534 if( rc != LDAP_SUCCESS ) {
535 send_ldap_result( conn, op, rc,
536 NULL, text, NULL, NULL );
540 #if defined( LDAP_SLAPI )
541 slapi_x_backend_set_pb( pb, be );
542 slapi_x_connection_set_pb( pb, conn );
543 slapi_x_operation_set_pb( pb, op );
544 slapi_pblock_set( pb, SLAPI_BIND_TARGET, (void *)dn.bv_val );
545 slapi_pblock_set( pb, SLAPI_BIND_METHOD, (void *)method );
546 slapi_pblock_set( pb, SLAPI_BIND_CREDENTIALS, (void *)&cred );
547 slapi_pblock_set( pb, SLAPI_MANAGEDSAIT, (void *)(0) );
549 rc = doPluginFNs( be, SLAPI_PLUGIN_PRE_BIND_FN, pb );
550 if ( rc != SLAPI_BIND_SUCCESS ) {
552 * Binding is a special case for SLAPI plugins. It is
553 * possible for a bind plugin to be successful *and*
554 * abort further processing; this means it has handled
555 * a bind request authoritatively. If we have reached
556 * here, a result has been sent to the client (XXX
557 * need to check with Sun whether SLAPI_BIND_ANONYMOUS
558 * means a result has been sent).
562 if ( slapi_pblock_get( pb, SLAPI_RESULT_CODE, (void *)&ldapRc ) != 0 )
567 if ( rc != SLAPI_BIND_FAIL && ldapRc == LDAP_SUCCESS ) {
568 /* Set the new connection DN. */
569 if ( rc != SLAPI_BIND_ANONYMOUS ) {
570 slapi_pblock_get( pb, SLAPI_CONN_DN, (void *)&edn.bv_val );
572 rc = dnPrettyNormal( NULL, &edn, &pdn, &ndn );
573 ldap_pvt_thread_mutex_lock( &conn->c_mutex );
580 if ( conn->c_dn.bv_len != 0 ) {
581 ber_len_t max = sockbuf_max_incoming_auth;
582 ber_sockbuf_ctrl( conn->c_sb, LBER_SB_OPT_SET_MAX_INCOMING, &max );
584 /* log authorization identity */
585 Statslog( LDAP_DEBUG_STATS,
586 "conn=%lu op=%lu BIND dn=\"%s\" mech=simple (SLAPI) ssf=0\n",
587 op->o_connid, op->o_opid,
588 conn->c_dn.bv_val, 0, 0 );
589 ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
592 LDAP_LOG( OPERATION, INFO, "do_bind: Bind preoperation plugin returned %d\n",
595 Debug(LDAP_DEBUG_TRACE, "do_bind: Bind preoperation plugin returned %d.\n",
601 #endif /* defined( LDAP_SLAPI ) */
606 ret = (*be->be_bind)( be, conn, op,
607 &pdn, &ndn, method, &cred, &edn );
610 ldap_pvt_thread_mutex_lock( &conn->c_mutex );
612 if( conn->c_authz_backend == NULL ) {
613 conn->c_authz_backend = be;
628 if( conn->c_dn.bv_len != 0 ) {
629 ber_len_t max = sockbuf_max_incoming_auth;
630 ber_sockbuf_ctrl( conn->c_sb,
631 LBER_SB_OPT_SET_MAX_INCOMING, &max );
634 /* log authorization identity */
635 Statslog( LDAP_DEBUG_STATS,
636 "conn=%lu op=%lu BIND dn=\"%s\" mech=simple ssf=0\n",
637 op->o_connid, op->o_opid,
638 conn->c_dn.bv_val, conn->c_authmech.bv_val, 0 );
641 LDAP_LOG( OPERATION, DETAIL1,
642 "do_bind: v%d bind: \"%s\" to \"%s\" \n",
643 version, conn->c_dn.bv_val, conn->c_dn.bv_val );
645 Debug( LDAP_DEBUG_TRACE,
646 "do_bind: v%d bind: \"%s\" to \"%s\"\n",
647 version, dn.bv_val, conn->c_dn.bv_val );
650 ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
652 /* send this here to avoid a race condition */
653 send_ldap_result( conn, op, LDAP_SUCCESS,
654 NULL, NULL, NULL, NULL );
656 } else if (edn.bv_val != NULL) {
661 send_ldap_result( conn, op, rc = LDAP_UNWILLING_TO_PERFORM,
662 NULL, "operation not supported within namingContext",
666 #if defined( LDAP_SLAPI )
667 if ( doPluginFNs( be, SLAPI_PLUGIN_POST_BIND_FN, pb ) != 0 ) {
669 LDAP_LOG( OPERATION, INFO, "do_bind: Bind postoperation plugins failed\n",
672 Debug(LDAP_DEBUG_TRACE, "do_bind: Bind postoperation plugins failed.\n",
676 #endif /* defined( LDAP_SLAPI ) */
679 conn->c_sasl_bindop = NULL;
681 if( pdn.bv_val != NULL ) {
684 if( ndn.bv_val != NULL ) {
687 if ( mech.bv_val != NULL ) {