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, "historical protocol version requested, use LDAPv3 instead",
235 /* we set connection version regardless of whether bind succeeds
238 ldap_pvt_thread_mutex_lock( &conn->c_mutex );
239 conn->c_protocol = version;
240 ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
242 /* check for inappropriate controls */
243 if( get_manageDSAit( op ) == SLAP_CRITICAL_CONTROL ) {
244 send_ldap_result( conn, op,
245 rc = LDAP_UNAVAILABLE_CRITICAL_EXTENSION,
246 NULL, "manageDSAit control inappropriate",
251 /* Set the bindop for the benefit of in-directory SASL lookups */
252 conn->c_sasl_bindop = op;
254 if ( method == LDAP_AUTH_SASL ) {
257 if ( version < LDAP_VERSION3 ) {
259 LDAP_LOG( OPERATION, INFO,
260 "do_bind: conn %d sasl with LDAPv%ld\n",
261 conn->c_connid, (unsigned long)version , 0 );
263 Debug( LDAP_DEBUG_ANY, "do_bind: sasl with LDAPv%ld\n",
264 (unsigned long) version, 0, 0 );
266 send_ldap_disconnect( conn, op,
267 LDAP_PROTOCOL_ERROR, "SASL bind requires LDAPv3" );
268 rc = SLAPD_DISCONNECT;
272 if( mech.bv_len == 0 ) {
274 LDAP_LOG( OPERATION, INFO,
275 "do_bind: conn %d no SASL mechanism provided\n",
276 conn->c_connid, 0, 0 );
278 Debug( LDAP_DEBUG_ANY,
279 "do_bind: no sasl mechanism provided\n",
282 send_ldap_result( conn, op, rc = LDAP_AUTH_METHOD_NOT_SUPPORTED,
283 NULL, "no SASL mechanism provided", NULL, NULL );
287 /* check restrictions */
288 rc = backend_check_restrictions( NULL, conn, op, &mech, &text );
289 if( rc != LDAP_SUCCESS ) {
290 send_ldap_result( conn, op, rc,
291 NULL, text, NULL, NULL );
295 ldap_pvt_thread_mutex_lock( &conn->c_mutex );
296 if ( conn->c_sasl_bind_in_progress ) {
297 if( !bvmatch( &conn->c_sasl_bind_mech, &mech ) ) {
298 /* mechanism changed between bind steps */
299 slap_sasl_reset(conn);
302 conn->c_sasl_bind_mech = mech;
306 ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
308 rc = slap_sasl_bind( conn, op,
312 ldap_pvt_thread_mutex_lock( &conn->c_mutex );
313 if( rc == LDAP_SUCCESS ) {
315 if( edn.bv_len != 0 ) {
316 /* edn is always normalized already */
317 ber_dupbv( &conn->c_ndn, &conn->c_dn );
319 conn->c_authmech = conn->c_sasl_bind_mech;
320 conn->c_sasl_bind_mech.bv_val = NULL;
321 conn->c_sasl_bind_mech.bv_len = 0;
322 conn->c_sasl_bind_in_progress = 0;
324 conn->c_sasl_ssf = ssf;
325 if( ssf > conn->c_ssf ) {
329 if( conn->c_dn.bv_len != 0 ) {
330 ber_len_t max = sockbuf_max_incoming_auth;
331 ber_sockbuf_ctrl( conn->c_sb,
332 LBER_SB_OPT_SET_MAX_INCOMING, &max );
335 /* log authorization identity */
336 Statslog( LDAP_DEBUG_STATS,
337 "conn=%lu op=%lu BIND dn=\"%s\" mech=%s ssf=%d\n",
338 op->o_connid, op->o_opid,
339 conn->c_dn.bv_val ? conn->c_dn.bv_val : "<empty>",
340 conn->c_authmech.bv_val, ssf );
343 LDAP_LOG( OPERATION, DETAIL1,
344 "do_bind: SASL/%s bind: dn=\"%s\" ssf=%d\n",
345 conn->c_authmech.bv_val,
346 conn->c_dn.bv_val ? conn->c_dn.bv_val : "<empty>",
349 Debug( LDAP_DEBUG_TRACE,
350 "do_bind: SASL/%s bind: dn=\"%s\" ssf=%d\n",
351 conn->c_authmech.bv_val,
352 conn->c_dn.bv_val ? conn->c_dn.bv_val : "<empty>",
356 } else if ( rc == LDAP_SASL_BIND_IN_PROGRESS ) {
357 conn->c_sasl_bind_in_progress = 1;
360 if ( conn->c_sasl_bind_mech.bv_val ) {
361 free( conn->c_sasl_bind_mech.bv_val );
362 conn->c_sasl_bind_mech.bv_val = NULL;
363 conn->c_sasl_bind_mech.bv_len = 0;
365 conn->c_sasl_bind_in_progress = 0;
367 ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
372 /* Not SASL, cancel any in-progress bind */
373 ldap_pvt_thread_mutex_lock( &conn->c_mutex );
375 if ( conn->c_sasl_bind_mech.bv_val != NULL ) {
376 free(conn->c_sasl_bind_mech.bv_val);
377 conn->c_sasl_bind_mech.bv_val = NULL;
378 conn->c_sasl_bind_mech.bv_len = 0;
380 conn->c_sasl_bind_in_progress = 0;
382 slap_sasl_reset( conn );
383 ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
386 if ( method == LDAP_AUTH_SIMPLE ) {
387 /* accept "anonymous" binds */
388 if ( cred.bv_len == 0 || ndn.bv_len == 0 ) {
393 !( global_allows & SLAP_ALLOW_BIND_ANON_CRED ))
395 /* cred is not empty, disallow */
396 rc = LDAP_INVALID_CREDENTIALS;
398 } else if ( ndn.bv_len &&
399 !( global_allows & SLAP_ALLOW_BIND_ANON_DN ))
401 /* DN is not empty, disallow */
402 rc = LDAP_UNWILLING_TO_PERFORM;
403 text = "unauthenticated bind (DN with no password) disallowed";
405 } else if ( global_disallows & SLAP_DISALLOW_BIND_ANON ) {
407 rc = LDAP_INAPPROPRIATE_AUTH;
408 text = "anonymous bind disallowed";
411 rc = backend_check_restrictions( NULL, conn, op,
416 * we already forced connection to "anonymous",
417 * just need to send success
419 send_ldap_result( conn, op, rc,
420 NULL, text, NULL, NULL );
422 LDAP_LOG( OPERATION, DETAIL1,
423 "do_bind: conn %d v%d anonymous bind\n",
424 conn->c_connid, version , 0 );
426 Debug( LDAP_DEBUG_TRACE, "do_bind: v%d anonymous bind\n",
431 } else if ( global_disallows & SLAP_DISALLOW_BIND_SIMPLE ) {
432 /* disallow simple authentication */
433 rc = LDAP_UNWILLING_TO_PERFORM;
434 text = "unwilling to perform simple authentication";
436 send_ldap_result( conn, op, rc,
437 NULL, text, NULL, NULL );
439 LDAP_LOG( OPERATION, INFO,
440 "do_bind: conn %d v%d simple bind(%s) disallowed\n",
441 conn->c_connid, version, ndn.bv_val );
443 Debug( LDAP_DEBUG_TRACE,
444 "do_bind: v%d simple bind(%s) disallowed\n",
445 version, ndn.bv_val, 0 );
449 } else if (( global_disallows & SLAP_DISALLOW_BIND_SIMPLE_UNPROTECTED )
450 && ( op->o_ssf <= 1 ))
452 rc = LDAP_CONFIDENTIALITY_REQUIRED;
453 text = "unwilling to perform simple authentication "
454 "without confidentilty protection";
456 send_ldap_result( conn, op, rc,
457 NULL, text, NULL, NULL );
460 LDAP_LOG( OPERATION, INFO, "do_bind: conn %d "
461 "v%d unprotected simple bind(%s) disallowed\n",
462 conn->c_connid, version, ndn.bv_val );
464 Debug( LDAP_DEBUG_TRACE,
465 "do_bind: v%d unprotected simple bind(%s) disallowed\n",
466 version, ndn.bv_val, 0 );
471 #ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
472 } else if ( method == LDAP_AUTH_KRBV41 || method == LDAP_AUTH_KRBV42 ) {
473 if ( global_disallows & SLAP_DISALLOW_BIND_KRBV4 ) {
474 /* disallow simple authentication */
475 rc = LDAP_UNWILLING_TO_PERFORM;
476 text = "unwilling to perform Kerberos V4 bind";
478 send_ldap_result( conn, op, rc,
479 NULL, text, NULL, NULL );
481 LDAP_LOG( OPERATION, DETAIL1,
482 "do_bind: conn %d v%d Kerberos V4 bind\n",
483 conn->c_connid, version , 0 );
485 Debug( LDAP_DEBUG_TRACE, "do_bind: v%d Kerberos V4 bind\n",
493 rc = LDAP_AUTH_METHOD_NOT_SUPPORTED;
494 text = "unknown authentication method";
496 send_ldap_result( conn, op, rc,
497 NULL, text, NULL, NULL );
499 LDAP_LOG( OPERATION, INFO,
500 "do_bind: conn %ld v%d unknown authentication method (%ld)\n",
501 conn->c_connid, version, method );
503 Debug( LDAP_DEBUG_TRACE,
504 "do_bind: v%d unknown authentication method (%ld)\n",
505 version, method, 0 );
511 * We could be serving multiple database backends. Select the
512 * appropriate one, or send a referral to our "referral server"
513 * if we don't hold it.
516 if ( (be = select_backend( &ndn, 0, 0 )) == NULL ) {
517 if ( default_referral ) {
518 BerVarray ref = referral_rewrite( default_referral,
519 NULL, &pdn, LDAP_SCOPE_DEFAULT );
521 send_ldap_result( conn, op, rc = LDAP_REFERRAL,
522 NULL, NULL, ref ? ref : default_referral, NULL );
524 ber_bvarray_free( ref );
527 /* noSuchObject is not allowed to be returned by bind */
528 send_ldap_result( conn, op, rc = LDAP_INVALID_CREDENTIALS,
529 NULL, NULL, NULL, NULL );
535 /* check restrictions */
536 rc = backend_check_restrictions( be, conn, op, NULL, &text );
537 if( rc != LDAP_SUCCESS ) {
538 send_ldap_result( conn, op, rc,
539 NULL, text, NULL, NULL );
543 #if defined( LDAP_SLAPI )
544 slapi_x_backend_set_pb( pb, be );
545 slapi_x_connection_set_pb( pb, conn );
546 slapi_x_operation_set_pb( pb, op );
547 slapi_pblock_set( pb, SLAPI_BIND_TARGET, (void *)dn.bv_val );
548 slapi_pblock_set( pb, SLAPI_BIND_METHOD, (void *)method );
549 slapi_pblock_set( pb, SLAPI_BIND_CREDENTIALS, (void *)&cred );
550 slapi_pblock_set( pb, SLAPI_MANAGEDSAIT, (void *)(0) );
552 rc = doPluginFNs( be, SLAPI_PLUGIN_PRE_BIND_FN, pb );
553 if ( rc != SLAPI_BIND_SUCCESS ) {
555 * Binding is a special case for SLAPI plugins. It is
556 * possible for a bind plugin to be successful *and*
557 * abort further processing; this means it has handled
558 * a bind request authoritatively. If we have reached
559 * here, a result has been sent to the client (XXX
560 * need to check with Sun whether SLAPI_BIND_ANONYMOUS
561 * means a result has been sent).
565 if ( slapi_pblock_get( pb, SLAPI_RESULT_CODE, (void *)&ldapRc ) != 0 )
570 if ( rc != SLAPI_BIND_FAIL && ldapRc == LDAP_SUCCESS ) {
571 /* Set the new connection DN. */
572 if ( rc != SLAPI_BIND_ANONYMOUS ) {
573 slapi_pblock_get( pb, SLAPI_CONN_DN, (void *)&edn.bv_val );
575 rc = dnPrettyNormal( NULL, &edn, &pdn, &ndn );
576 ldap_pvt_thread_mutex_lock( &conn->c_mutex );
583 if ( conn->c_dn.bv_len != 0 ) {
584 ber_len_t max = sockbuf_max_incoming_auth;
585 ber_sockbuf_ctrl( conn->c_sb, LBER_SB_OPT_SET_MAX_INCOMING, &max );
587 /* log authorization identity */
588 Statslog( LDAP_DEBUG_STATS,
589 "conn=%lu op=%lu BIND dn=\"%s\" mech=simple (SLAPI) ssf=0\n",
590 op->o_connid, op->o_opid,
591 conn->c_dn.bv_val, 0, 0 );
592 ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
595 LDAP_LOG( OPERATION, INFO, "do_bind: Bind preoperation plugin returned %d\n",
598 Debug(LDAP_DEBUG_TRACE, "do_bind: Bind preoperation plugin returned %d.\n",
604 #endif /* defined( LDAP_SLAPI ) */
609 ret = (*be->be_bind)( be, conn, op,
610 &pdn, &ndn, method, &cred, &edn );
613 ldap_pvt_thread_mutex_lock( &conn->c_mutex );
615 if( conn->c_authz_backend == NULL ) {
616 conn->c_authz_backend = be;
631 if( conn->c_dn.bv_len != 0 ) {
632 ber_len_t max = sockbuf_max_incoming_auth;
633 ber_sockbuf_ctrl( conn->c_sb,
634 LBER_SB_OPT_SET_MAX_INCOMING, &max );
637 /* log authorization identity */
638 Statslog( LDAP_DEBUG_STATS,
639 "conn=%lu op=%lu BIND dn=\"%s\" mech=simple ssf=0\n",
640 op->o_connid, op->o_opid,
641 conn->c_dn.bv_val, conn->c_authmech.bv_val, 0 );
644 LDAP_LOG( OPERATION, DETAIL1,
645 "do_bind: v%d bind: \"%s\" to \"%s\" \n",
646 version, conn->c_dn.bv_val, conn->c_dn.bv_val );
648 Debug( LDAP_DEBUG_TRACE,
649 "do_bind: v%d bind: \"%s\" to \"%s\"\n",
650 version, dn.bv_val, conn->c_dn.bv_val );
653 ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
655 /* send this here to avoid a race condition */
656 send_ldap_result( conn, op, LDAP_SUCCESS,
657 NULL, NULL, NULL, NULL );
659 } else if (edn.bv_val != NULL) {
664 send_ldap_result( conn, op, rc = LDAP_UNWILLING_TO_PERFORM,
665 NULL, "operation not supported within namingContext",
669 #if defined( LDAP_SLAPI )
670 if ( doPluginFNs( be, SLAPI_PLUGIN_POST_BIND_FN, pb ) != 0 ) {
672 LDAP_LOG( OPERATION, INFO, "do_bind: Bind postoperation plugins failed\n",
675 Debug(LDAP_DEBUG_TRACE, "do_bind: Bind postoperation plugins failed.\n",
679 #endif /* defined( LDAP_SLAPI ) */
682 conn->c_sasl_bindop = NULL;
684 if( pdn.bv_val != NULL ) {
687 if( ndn.bv_val != NULL ) {
690 if ( mech.bv_val != NULL ) {