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>
40 BerElement *ber = op->o_ber;
43 struct berval mech = { 0, NULL };
44 struct berval dn = { 0, NULL };
45 struct berval pdn = { 0, NULL };
46 struct berval ndn = { 0, NULL };
47 struct berval edn = { 0, NULL };
49 int rc = LDAP_SUCCESS;
51 struct berval cred = { 0, NULL };
55 Slapi_PBlock *pb = op->o_pb;
59 LDAP_LOG( OPERATION, ENTRY, "do_bind: conn %d\n", conn->c_connid, 0, 0 );
61 Debug( LDAP_DEBUG_TRACE, "do_bind\n", 0, 0, 0 );
65 * Force to connection to "anonymous" until bind succeeds.
67 ldap_pvt_thread_mutex_lock( &conn->c_mutex );
68 if ( conn->c_sasl_bind_in_progress ) be = conn->c_authz_backend;
70 /* log authorization identity demotion */
71 if ( conn->c_dn.bv_len ) {
72 Statslog( LDAP_DEBUG_STATS,
73 "conn=%lu op=%lu BIND anonymous mech=implicit ssf=0",
74 op->o_connid, op->o_opid, 0, 0, 0 );
77 connection2anonymous( conn );
78 if ( conn->c_sasl_bind_in_progress ) conn->c_authz_backend = be;
79 ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
81 if ( op->o_dn.bv_val != NULL ) {
82 free( op->o_dn.bv_val );
83 op->o_dn.bv_val = ch_strdup( "" );
87 if ( op->o_ndn.bv_val != NULL ) {
88 free( op->o_ndn.bv_val );
89 op->o_ndn.bv_val = ch_strdup( "" );
94 * Parse the bind request. It looks like this:
96 * BindRequest ::= SEQUENCE {
97 * version INTEGER, -- version
98 * name DistinguishedName, -- dn
99 * authentication CHOICE {
100 * simple [0] OCTET STRING -- passwd
101 * krbv42ldap [1] OCTET STRING
102 * krbv42dsa [2] OCTET STRING
103 * SASL [3] SaslCredentials
107 * SaslCredentials ::= SEQUENCE {
108 * mechanism LDAPString,
109 * credentials OCTET STRING OPTIONAL
113 tag = ber_scanf( ber, "{imt" /*}*/, &version, &dn, &method );
115 if ( tag == LBER_ERROR ) {
117 LDAP_LOG( OPERATION, ERR,
118 "do_bind: conn %d ber_scanf failed\n", conn->c_connid, 0, 0 );
120 Debug( LDAP_DEBUG_ANY, "bind: ber_scanf failed\n", 0, 0, 0 );
122 send_ldap_disconnect( conn, op,
123 LDAP_PROTOCOL_ERROR, "decoding error" );
128 op->o_protocol = version;
130 if( method != LDAP_AUTH_SASL ) {
131 tag = ber_scanf( ber, /*{*/ "m}", &cred );
134 tag = ber_scanf( ber, "{o" /*}*/, &mech );
136 if ( tag != LBER_ERROR ) {
138 tag = ber_peek_tag( ber, &len );
140 if ( tag == LDAP_TAG_LDAPCRED ) {
141 tag = ber_scanf( ber, "m", &cred );
143 tag = LDAP_TAG_LDAPCRED;
148 if ( tag != LBER_ERROR ) {
149 tag = ber_scanf( ber, /*{{*/ "}}" );
154 if ( tag == LBER_ERROR ) {
155 send_ldap_disconnect( conn, op,
158 rc = SLAPD_DISCONNECT;
162 if( (rc = get_ctrls( conn, op, 1 )) != LDAP_SUCCESS ) {
164 LDAP_LOG( OPERATION, INFO,
165 "do_bind: conn %d get_ctrls failed\n", conn->c_connid, 0, 0 );
167 Debug( LDAP_DEBUG_ANY, "do_bind: get_ctrls failed\n", 0, 0, 0 );
172 rc = dnPrettyNormal( NULL, &dn, &pdn, &ndn );
173 if ( rc != LDAP_SUCCESS ) {
175 LDAP_LOG( OPERATION, INFO,
176 "do_bind: conn %d invalid dn (%s)\n",
177 conn->c_connid, dn.bv_val, 0 );
179 Debug( LDAP_DEBUG_ANY, "bind: invalid dn (%s)\n",
182 send_ldap_result( conn, op, rc = LDAP_INVALID_DN_SYNTAX, NULL,
183 "invalid DN", NULL, NULL );
187 if( method == LDAP_AUTH_SASL ) {
189 LDAP_LOG( OPERATION, DETAIL1,
190 "do_sasl_bind: conn %d dn (%s) mech %s\n",
191 conn->c_connid, pdn.bv_val, mech.bv_val );
193 Debug( LDAP_DEBUG_TRACE, "do_sasl_bind: dn (%s) mech %s\n",
194 pdn.bv_val, mech.bv_val, NULL );
199 LDAP_LOG( OPERATION, DETAIL1,
200 "do_bind: version=%ld dn=\"%s\" method=%ld\n",
201 (unsigned long) version, pdn.bv_val, (unsigned long)method );
203 Debug( LDAP_DEBUG_TRACE,
204 "do_bind: version=%ld dn=\"%s\" method=%ld\n",
205 (unsigned long) version,
206 pdn.bv_val, (unsigned long) method );
210 Statslog( LDAP_DEBUG_STATS, "conn=%lu op=%lu BIND dn=\"%s\" method=%ld\n",
211 op->o_connid, op->o_opid, pdn.bv_val, (unsigned long) method, 0 );
213 if ( version < LDAP_VERSION_MIN || version > LDAP_VERSION_MAX ) {
215 LDAP_LOG( OPERATION, INFO,
216 "do_bind: conn %d unknown version = %ld\n",
217 conn->c_connid, (unsigned long)version, 0 );
219 Debug( LDAP_DEBUG_ANY, "do_bind: unknown version=%ld\n",
220 (unsigned long) version, 0, 0 );
222 send_ldap_result( conn, op, rc = LDAP_PROTOCOL_ERROR,
223 NULL, "requested protocol version not supported", NULL, NULL );
226 } else if (!( global_allows & SLAP_ALLOW_BIND_V2 ) &&
227 version < LDAP_VERSION3 )
229 send_ldap_result( conn, op, rc = LDAP_PROTOCOL_ERROR,
230 NULL, "requested protocol version not allowed", NULL, NULL );
234 /* we set connection version regardless of whether bind succeeds
237 ldap_pvt_thread_mutex_lock( &conn->c_mutex );
238 conn->c_protocol = version;
239 ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
241 /* check for inappropriate controls */
242 if( get_manageDSAit( op ) == SLAP_CRITICAL_CONTROL ) {
243 send_ldap_result( conn, op,
244 rc = LDAP_UNAVAILABLE_CRITICAL_EXTENSION,
245 NULL, "manageDSAit control inappropriate",
250 /* Set the bindop for the benefit of in-directory SASL lookups */
251 conn->c_sasl_bindop = op;
253 if ( method == LDAP_AUTH_SASL ) {
256 if ( version < LDAP_VERSION3 ) {
258 LDAP_LOG( OPERATION, INFO,
259 "do_bind: conn %d sasl with LDAPv%ld\n",
260 conn->c_connid, (unsigned long)version , 0 );
262 Debug( LDAP_DEBUG_ANY, "do_bind: sasl with LDAPv%ld\n",
263 (unsigned long) version, 0, 0 );
265 send_ldap_disconnect( conn, op,
266 LDAP_PROTOCOL_ERROR, "SASL bind requires LDAPv3" );
267 rc = SLAPD_DISCONNECT;
271 if( mech.bv_len == 0 ) {
273 LDAP_LOG( OPERATION, INFO,
274 "do_bind: conn %d no SASL mechanism provided\n",
275 conn->c_connid, 0, 0 );
277 Debug( LDAP_DEBUG_ANY,
278 "do_bind: no sasl mechanism provided\n",
281 send_ldap_result( conn, op, rc = LDAP_AUTH_METHOD_NOT_SUPPORTED,
282 NULL, "no SASL mechanism provided", NULL, NULL );
286 /* check restrictions */
287 rc = backend_check_restrictions( NULL, conn, op, &mech, &text );
288 if( rc != LDAP_SUCCESS ) {
289 send_ldap_result( conn, op, rc,
290 NULL, text, NULL, NULL );
294 ldap_pvt_thread_mutex_lock( &conn->c_mutex );
295 if ( conn->c_sasl_bind_in_progress ) {
296 if( !bvmatch( &conn->c_sasl_bind_mech, &mech ) ) {
297 /* mechanism changed between bind steps */
298 slap_sasl_reset(conn);
301 conn->c_sasl_bind_mech = mech;
305 ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
307 rc = slap_sasl_bind( conn, op,
311 ldap_pvt_thread_mutex_lock( &conn->c_mutex );
312 if( rc == LDAP_SUCCESS ) {
314 if( edn.bv_len != 0 ) {
315 /* edn is always normalized already */
316 ber_dupbv( &conn->c_ndn, &conn->c_dn );
318 conn->c_authmech = conn->c_sasl_bind_mech;
319 conn->c_sasl_bind_mech.bv_val = NULL;
320 conn->c_sasl_bind_mech.bv_len = 0;
321 conn->c_sasl_bind_in_progress = 0;
323 conn->c_sasl_ssf = ssf;
324 if( ssf > conn->c_ssf ) {
328 if( conn->c_dn.bv_len != 0 ) {
329 ber_len_t max = sockbuf_max_incoming_auth;
330 ber_sockbuf_ctrl( conn->c_sb,
331 LBER_SB_OPT_SET_MAX_INCOMING, &max );
334 /* log authorization identity */
335 Statslog( LDAP_DEBUG_STATS,
336 "conn=%lu op=%lu BIND dn=\"%s\" mech=%s ssf=%d\n",
337 op->o_connid, op->o_opid,
338 conn->c_dn.bv_val ? conn->c_dn.bv_val : "<empty>",
339 conn->c_authmech.bv_val, ssf );
342 LDAP_LOG( OPERATION, DETAIL1,
343 "do_bind: SASL/%s bind: dn=\"%s\" ssf=%d\n",
344 conn->c_authmech.bv_val,
345 conn->c_dn.bv_val ? conn->c_dn.bv_val : "<empty>",
348 Debug( LDAP_DEBUG_TRACE,
349 "do_bind: SASL/%s bind: dn=\"%s\" ssf=%d\n",
350 conn->c_authmech.bv_val,
351 conn->c_dn.bv_val ? conn->c_dn.bv_val : "<empty>",
355 } else if ( rc == LDAP_SASL_BIND_IN_PROGRESS ) {
356 conn->c_sasl_bind_in_progress = 1;
359 if ( conn->c_sasl_bind_mech.bv_val ) {
360 free( conn->c_sasl_bind_mech.bv_val );
361 conn->c_sasl_bind_mech.bv_val = NULL;
362 conn->c_sasl_bind_mech.bv_len = 0;
364 conn->c_sasl_bind_in_progress = 0;
366 ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
371 /* Not SASL, cancel any in-progress bind */
372 ldap_pvt_thread_mutex_lock( &conn->c_mutex );
374 if ( conn->c_sasl_bind_mech.bv_val != NULL ) {
375 free(conn->c_sasl_bind_mech.bv_val);
376 conn->c_sasl_bind_mech.bv_val = NULL;
377 conn->c_sasl_bind_mech.bv_len = 0;
379 conn->c_sasl_bind_in_progress = 0;
381 slap_sasl_reset( conn );
382 ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
385 if ( method == LDAP_AUTH_SIMPLE ) {
386 /* accept "anonymous" binds */
387 if ( cred.bv_len == 0 || ndn.bv_len == 0 ) {
392 !( global_allows & SLAP_ALLOW_BIND_ANON_CRED ))
394 /* cred is not empty, disallow */
395 rc = LDAP_INVALID_CREDENTIALS;
397 } else if ( ndn.bv_len &&
398 !( global_allows & SLAP_ALLOW_BIND_ANON_DN ))
400 /* DN is not empty, disallow */
401 rc = LDAP_UNWILLING_TO_PERFORM;
402 text = "unauthenticated bind (DN with no password) disallowed";
404 } else if ( global_disallows & SLAP_DISALLOW_BIND_ANON ) {
406 rc = LDAP_INAPPROPRIATE_AUTH;
407 text = "anonymous bind disallowed";
410 rc = backend_check_restrictions( NULL, conn, op,
415 * we already forced connection to "anonymous",
416 * just need to send success
418 send_ldap_result( conn, op, rc,
419 NULL, text, NULL, NULL );
421 LDAP_LOG( OPERATION, DETAIL1,
422 "do_bind: conn %d v%d anonymous bind\n",
423 conn->c_connid, version , 0 );
425 Debug( LDAP_DEBUG_TRACE, "do_bind: v%d anonymous bind\n",
430 } else if ( global_disallows & SLAP_DISALLOW_BIND_SIMPLE ) {
431 /* disallow simple authentication */
432 rc = LDAP_UNWILLING_TO_PERFORM;
433 text = "unwilling to perform simple authentication";
435 send_ldap_result( conn, op, rc,
436 NULL, text, NULL, NULL );
438 LDAP_LOG( OPERATION, INFO,
439 "do_bind: conn %d v%d simple bind(%s) disallowed\n",
440 conn->c_connid, version, ndn.bv_val );
442 Debug( LDAP_DEBUG_TRACE,
443 "do_bind: v%d simple bind(%s) disallowed\n",
444 version, ndn.bv_val, 0 );
448 } else if (( global_disallows & SLAP_DISALLOW_BIND_SIMPLE_UNPROTECTED )
449 && ( op->o_ssf <= 1 ))
451 rc = LDAP_CONFIDENTIALITY_REQUIRED;
452 text = "unwilling to perform simple authentication "
453 "without confidentilty protection";
455 send_ldap_result( conn, op, rc,
456 NULL, text, NULL, NULL );
459 LDAP_LOG( OPERATION, INFO, "do_bind: conn %d "
460 "v%d unprotected simple bind(%s) disallowed\n",
461 conn->c_connid, version, ndn.bv_val );
463 Debug( LDAP_DEBUG_TRACE,
464 "do_bind: v%d unprotected simple bind(%s) disallowed\n",
465 version, ndn.bv_val, 0 );
470 #ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
471 } else if ( method == LDAP_AUTH_KRBV41 || method == LDAP_AUTH_KRBV42 ) {
472 if ( global_disallows & SLAP_DISALLOW_BIND_KRBV4 ) {
473 /* disallow simple authentication */
474 rc = LDAP_UNWILLING_TO_PERFORM;
475 text = "unwilling to perform Kerberos V4 bind";
477 send_ldap_result( conn, op, rc,
478 NULL, text, NULL, NULL );
480 LDAP_LOG( OPERATION, DETAIL1,
481 "do_bind: conn %d v%d Kerberos V4 bind\n",
482 conn->c_connid, version , 0 );
484 Debug( LDAP_DEBUG_TRACE, "do_bind: v%d Kerberos V4 bind\n",
492 rc = LDAP_AUTH_METHOD_NOT_SUPPORTED;
493 text = "unknown authentication method";
495 send_ldap_result( conn, op, rc,
496 NULL, text, NULL, NULL );
498 LDAP_LOG( OPERATION, INFO,
499 "do_bind: conn %ld v%d unknown authentication method (%ld)\n",
500 conn->c_connid, version, method );
502 Debug( LDAP_DEBUG_TRACE,
503 "do_bind: v%d unknown authentication method (%ld)\n",
504 version, method, 0 );
510 * We could be serving multiple database backends. Select the
511 * appropriate one, or send a referral to our "referral server"
512 * if we don't hold it.
515 if ( (be = select_backend( &ndn, 0, 0 )) == NULL ) {
516 if ( default_referral ) {
517 BerVarray ref = referral_rewrite( default_referral,
518 NULL, &pdn, LDAP_SCOPE_DEFAULT );
520 send_ldap_result( conn, op, rc = LDAP_REFERRAL,
521 NULL, NULL, ref ? ref : default_referral, NULL );
523 ber_bvarray_free( ref );
526 /* noSuchObject is not allowed to be returned by bind */
527 send_ldap_result( conn, op, rc = LDAP_INVALID_CREDENTIALS,
528 NULL, NULL, NULL, NULL );
534 /* check restrictions */
535 rc = backend_check_restrictions( be, conn, op, NULL, &text );
536 if( rc != LDAP_SUCCESS ) {
537 send_ldap_result( conn, op, rc,
538 NULL, text, NULL, NULL );
542 #if defined( LDAP_SLAPI )
543 slapi_x_backend_set_pb( pb, be );
544 slapi_x_connection_set_pb( pb, conn );
545 slapi_x_operation_set_pb( pb, op );
546 slapi_pblock_set( pb, SLAPI_BIND_TARGET, (void *)dn.bv_val );
547 slapi_pblock_set( pb, SLAPI_BIND_METHOD, (void *)method );
548 slapi_pblock_set( pb, SLAPI_BIND_CREDENTIALS, (void *)&cred );
549 slapi_pblock_set( pb, SLAPI_MANAGEDSAIT, (void *)(0) );
551 rc = doPluginFNs( be, SLAPI_PLUGIN_PRE_BIND_FN, pb );
552 if ( rc != SLAPI_BIND_SUCCESS ) {
554 * Binding is a special case for SLAPI plugins. It is
555 * possible for a bind plugin to be successful *and*
556 * abort further processing; this means it has handled
557 * a bind request authoritatively. If we have reached
558 * here, a result has been sent to the client (XXX
559 * need to check with Sun whether SLAPI_BIND_ANONYMOUS
560 * means a result has been sent).
564 if ( slapi_pblock_get( pb, SLAPI_RESULT_CODE, (void *)&ldapRc ) != 0 )
569 if ( rc != SLAPI_BIND_FAIL && ldapRc == LDAP_SUCCESS ) {
570 /* Set the new connection DN. */
571 if ( rc != SLAPI_BIND_ANONYMOUS ) {
572 slapi_pblock_get( pb, SLAPI_CONN_DN, (void *)&edn.bv_val );
574 rc = dnPrettyNormal( NULL, &edn, &pdn, &ndn );
575 ldap_pvt_thread_mutex_lock( &conn->c_mutex );
582 if ( conn->c_dn.bv_len != 0 ) {
583 ber_len_t max = sockbuf_max_incoming_auth;
584 ber_sockbuf_ctrl( conn->c_sb, LBER_SB_OPT_SET_MAX_INCOMING, &max );
586 /* log authorization identity */
587 Statslog( LDAP_DEBUG_STATS,
588 "conn=%lu op=%lu BIND dn=\"%s\" mech=simple (SLAPI) ssf=0\n",
589 op->o_connid, op->o_opid,
590 conn->c_dn.bv_val, 0, 0 );
591 ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
594 LDAP_LOG( OPERATION, INFO, "do_bind: Bind preoperation plugin returned %d\n",
597 Debug(LDAP_DEBUG_TRACE, "do_bind: Bind preoperation plugin returned %d.\n",
603 #endif /* defined( LDAP_SLAPI ) */
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 ) {