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 };
52 Slapi_PBlock *pb = op->o_pb;
55 LDAP_LOG( OPERATION, ENTRY, "do_bind: conn %d\n", conn->c_connid, 0, 0 );
57 Debug( LDAP_DEBUG_TRACE, "do_bind\n", 0, 0, 0 );
61 * Force to connection to "anonymous" until bind succeeds.
63 ldap_pvt_thread_mutex_lock( &conn->c_mutex );
64 if ( conn->c_sasl_bind_in_progress ) be = conn->c_authz_backend;
66 /* log authorization identity demotion */
67 if ( conn->c_dn.bv_len ) {
68 Statslog( LDAP_DEBUG_STATS,
69 "conn=%lu op=%lu BIND anonymous mech=implicit ssf=0",
70 op->o_connid, op->o_opid, 0, 0, 0 );
73 connection2anonymous( conn );
74 if ( conn->c_sasl_bind_in_progress ) conn->c_authz_backend = be;
75 ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
77 if ( op->o_dn.bv_val != NULL ) {
78 free( op->o_dn.bv_val );
79 op->o_dn.bv_val = ch_strdup( "" );
83 if ( op->o_ndn.bv_val != NULL ) {
84 free( op->o_ndn.bv_val );
85 op->o_ndn.bv_val = ch_strdup( "" );
90 * Parse the bind request. It looks like this:
92 * BindRequest ::= SEQUENCE {
93 * version INTEGER, -- version
94 * name DistinguishedName, -- dn
95 * authentication CHOICE {
96 * simple [0] OCTET STRING -- passwd
97 * krbv42ldap [1] OCTET STRING
98 * krbv42dsa [2] OCTET STRING
99 * SASL [3] SaslCredentials
103 * SaslCredentials ::= SEQUENCE {
104 * mechanism LDAPString,
105 * credentials OCTET STRING OPTIONAL
109 tag = ber_scanf( ber, "{imt" /*}*/, &version, &dn, &method );
111 if ( tag == LBER_ERROR ) {
113 LDAP_LOG( OPERATION, ERR,
114 "do_bind: conn %d ber_scanf failed\n", conn->c_connid, 0, 0 );
116 Debug( LDAP_DEBUG_ANY, "bind: ber_scanf failed\n", 0, 0, 0 );
118 send_ldap_disconnect( conn, op,
119 LDAP_PROTOCOL_ERROR, "decoding error" );
124 op->o_protocol = version;
126 if( method != LDAP_AUTH_SASL ) {
127 tag = ber_scanf( ber, /*{*/ "m}", &cred );
130 tag = ber_scanf( ber, "{o" /*}*/, &mech );
132 if ( tag != LBER_ERROR ) {
134 tag = ber_peek_tag( ber, &len );
136 if ( tag == LDAP_TAG_LDAPCRED ) {
137 tag = ber_scanf( ber, "m", &cred );
139 tag = LDAP_TAG_LDAPCRED;
144 if ( tag != LBER_ERROR ) {
145 tag = ber_scanf( ber, /*{{*/ "}}" );
150 if ( tag == LBER_ERROR ) {
151 send_ldap_disconnect( conn, op,
154 rc = SLAPD_DISCONNECT;
158 if( (rc = get_ctrls( conn, op, 1 )) != LDAP_SUCCESS ) {
160 LDAP_LOG( OPERATION, INFO,
161 "do_bind: conn %d get_ctrls failed\n", conn->c_connid, 0, 0 );
163 Debug( LDAP_DEBUG_ANY, "do_bind: get_ctrls failed\n", 0, 0, 0 );
168 rc = dnPrettyNormal( NULL, &dn, &pdn, &ndn );
169 if ( rc != LDAP_SUCCESS ) {
171 LDAP_LOG( OPERATION, INFO,
172 "do_bind: conn %d invalid dn (%s)\n",
173 conn->c_connid, dn.bv_val, 0 );
175 Debug( LDAP_DEBUG_ANY, "bind: invalid dn (%s)\n",
178 send_ldap_result( conn, op, rc = LDAP_INVALID_DN_SYNTAX, NULL,
179 "invalid DN", NULL, NULL );
183 if( method == LDAP_AUTH_SASL ) {
185 LDAP_LOG( OPERATION, DETAIL1,
186 "do_sasl_bind: conn %d dn (%s) mech %s\n",
187 conn->c_connid, pdn.bv_val, mech.bv_val );
189 Debug( LDAP_DEBUG_TRACE, "do_sasl_bind: dn (%s) mech %s\n",
190 pdn.bv_val, mech.bv_val, NULL );
195 LDAP_LOG( OPERATION, DETAIL1,
196 "do_bind: version=%ld dn=\"%s\" method=%ld\n",
197 (unsigned long) version, pdn.bv_val, (unsigned long)method );
199 Debug( LDAP_DEBUG_TRACE,
200 "do_bind: version=%ld dn=\"%s\" method=%ld\n",
201 (unsigned long) version,
202 pdn.bv_val, (unsigned long) method );
206 Statslog( LDAP_DEBUG_STATS, "conn=%lu op=%lu BIND dn=\"%s\" method=%ld\n",
207 op->o_connid, op->o_opid, pdn.bv_val, (unsigned long) method, 0 );
209 if ( version < LDAP_VERSION_MIN || version > LDAP_VERSION_MAX ) {
211 LDAP_LOG( OPERATION, INFO,
212 "do_bind: conn %d unknown version = %ld\n",
213 conn->c_connid, (unsigned long)version, 0 );
215 Debug( LDAP_DEBUG_ANY, "do_bind: unknown version=%ld\n",
216 (unsigned long) version, 0, 0 );
218 send_ldap_result( conn, op, rc = LDAP_PROTOCOL_ERROR,
219 NULL, "requested protocol version not supported", NULL, NULL );
222 } else if (!( global_allows & SLAP_ALLOW_BIND_V2 ) &&
223 version < LDAP_VERSION3 )
225 send_ldap_result( conn, op, rc = LDAP_PROTOCOL_ERROR,
226 NULL, "requested protocol version not allowed", NULL, NULL );
230 /* we set connection version regardless of whether bind succeeds
233 ldap_pvt_thread_mutex_lock( &conn->c_mutex );
234 conn->c_protocol = version;
235 ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
237 /* check for inappropriate controls */
238 if( get_manageDSAit( op ) == SLAP_CRITICAL_CONTROL ) {
239 send_ldap_result( conn, op,
240 rc = LDAP_UNAVAILABLE_CRITICAL_EXTENSION,
241 NULL, "manageDSAit control inappropriate",
246 /* Set the bindop for the benefit of in-directory SASL lookups */
247 conn->c_sasl_bindop = op;
249 if ( method == LDAP_AUTH_SASL ) {
252 if ( version < LDAP_VERSION3 ) {
254 LDAP_LOG( OPERATION, INFO,
255 "do_bind: conn %d sasl with LDAPv%ld\n",
256 conn->c_connid, (unsigned long)version , 0 );
258 Debug( LDAP_DEBUG_ANY, "do_bind: sasl with LDAPv%ld\n",
259 (unsigned long) version, 0, 0 );
261 send_ldap_disconnect( conn, op,
262 LDAP_PROTOCOL_ERROR, "SASL bind requires LDAPv3" );
263 rc = SLAPD_DISCONNECT;
267 if( mech.bv_len == 0 ) {
269 LDAP_LOG( OPERATION, INFO,
270 "do_bind: conn %d no SASL mechanism provided\n",
271 conn->c_connid, 0, 0 );
273 Debug( LDAP_DEBUG_ANY,
274 "do_bind: no sasl mechanism provided\n",
277 send_ldap_result( conn, op, rc = LDAP_AUTH_METHOD_NOT_SUPPORTED,
278 NULL, "no SASL mechanism provided", NULL, NULL );
282 /* check restrictions */
283 rc = backend_check_restrictions( NULL, conn, op, &mech, &text );
284 if( rc != LDAP_SUCCESS ) {
285 send_ldap_result( conn, op, rc,
286 NULL, text, NULL, NULL );
290 ldap_pvt_thread_mutex_lock( &conn->c_mutex );
291 if ( conn->c_sasl_bind_in_progress ) {
292 if( !bvmatch( &conn->c_sasl_bind_mech, &mech ) ) {
293 /* mechanism changed between bind steps */
294 slap_sasl_reset(conn);
297 conn->c_sasl_bind_mech = mech;
301 ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
303 rc = slap_sasl_bind( conn, op,
307 ldap_pvt_thread_mutex_lock( &conn->c_mutex );
308 if( rc == LDAP_SUCCESS ) {
310 if( edn.bv_len != 0 ) {
311 /* edn is always normalized already */
312 ber_dupbv( &conn->c_ndn, &conn->c_dn );
314 conn->c_authmech = conn->c_sasl_bind_mech;
315 conn->c_sasl_bind_mech.bv_val = NULL;
316 conn->c_sasl_bind_mech.bv_len = 0;
317 conn->c_sasl_bind_in_progress = 0;
319 conn->c_sasl_ssf = ssf;
320 if( ssf > conn->c_ssf ) {
324 if( conn->c_dn.bv_len != 0 ) {
325 ber_len_t max = sockbuf_max_incoming_auth;
326 ber_sockbuf_ctrl( conn->c_sb,
327 LBER_SB_OPT_SET_MAX_INCOMING, &max );
330 /* log authorization identity */
331 Statslog( LDAP_DEBUG_STATS,
332 "conn=%lu op=%lu BIND dn=\"%s\" mech=%s ssf=%d\n",
333 op->o_connid, op->o_opid,
334 conn->c_dn.bv_val ? conn->c_dn.bv_val : "<empty>",
335 conn->c_authmech.bv_val, ssf );
338 LDAP_LOG( OPERATION, DETAIL1,
339 "do_bind: SASL/%s bind: dn=\"%s\" ssf=%d\n",
340 conn->c_authmech.bv_val,
341 conn->c_dn.bv_val ? conn->c_dn.bv_val : "<empty>",
344 Debug( LDAP_DEBUG_TRACE,
345 "do_bind: SASL/%s bind: dn=\"%s\" ssf=%d\n",
346 conn->c_authmech.bv_val,
347 conn->c_dn.bv_val ? conn->c_dn.bv_val : "<empty>",
351 } else if ( rc == LDAP_SASL_BIND_IN_PROGRESS ) {
352 conn->c_sasl_bind_in_progress = 1;
355 if ( conn->c_sasl_bind_mech.bv_val ) {
356 free( conn->c_sasl_bind_mech.bv_val );
357 conn->c_sasl_bind_mech.bv_val = NULL;
358 conn->c_sasl_bind_mech.bv_len = 0;
360 conn->c_sasl_bind_in_progress = 0;
362 ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
367 /* Not SASL, cancel any in-progress bind */
368 ldap_pvt_thread_mutex_lock( &conn->c_mutex );
370 if ( conn->c_sasl_bind_mech.bv_val != NULL ) {
371 free(conn->c_sasl_bind_mech.bv_val);
372 conn->c_sasl_bind_mech.bv_val = NULL;
373 conn->c_sasl_bind_mech.bv_len = 0;
375 conn->c_sasl_bind_in_progress = 0;
377 slap_sasl_reset( conn );
378 ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
381 if ( method == LDAP_AUTH_SIMPLE ) {
382 /* accept "anonymous" binds */
383 if ( cred.bv_len == 0 || ndn.bv_len == 0 ) {
388 !( global_allows & SLAP_ALLOW_BIND_ANON_CRED ))
390 /* cred is not empty, disallow */
391 rc = LDAP_INVALID_CREDENTIALS;
393 } else if ( ndn.bv_len &&
394 !( global_allows & SLAP_ALLOW_BIND_ANON_DN ))
396 /* DN is not empty, disallow */
397 rc = LDAP_UNWILLING_TO_PERFORM;
398 text = "unwilling to allow anonymous bind with non-empty DN";
400 } else if ( global_disallows & SLAP_DISALLOW_BIND_ANON ) {
402 rc = LDAP_INAPPROPRIATE_AUTH;
403 text = "anonymous bind disallowed";
406 rc = backend_check_restrictions( NULL, conn, op,
411 * we already forced connection to "anonymous",
412 * just need to send success
414 send_ldap_result( conn, op, rc,
415 NULL, text, NULL, NULL );
417 LDAP_LOG( OPERATION, DETAIL1,
418 "do_bind: conn %d v%d anonymous bind\n",
419 conn->c_connid, version , 0 );
421 Debug( LDAP_DEBUG_TRACE, "do_bind: v%d anonymous bind\n",
426 } else if ( global_disallows & SLAP_DISALLOW_BIND_SIMPLE ) {
427 /* disallow simple authentication */
428 rc = LDAP_UNWILLING_TO_PERFORM;
429 text = "unwilling to perform simple authentication";
431 send_ldap_result( conn, op, rc,
432 NULL, text, NULL, NULL );
434 LDAP_LOG( OPERATION, INFO,
435 "do_bind: conn %d v%d simple bind(%s) disallowed\n",
436 conn->c_connid, version, ndn.bv_val );
438 Debug( LDAP_DEBUG_TRACE,
439 "do_bind: v%d simple bind(%s) disallowed\n",
440 version, ndn.bv_val, 0 );
444 } else if (( global_disallows & SLAP_DISALLOW_BIND_SIMPLE_UNPROTECTED )
445 && ( op->o_ssf <= 1 ))
447 rc = LDAP_CONFIDENTIALITY_REQUIRED;
448 text = "unwilling to perform simple authentication "
449 "without confidentilty protection";
451 send_ldap_result( conn, op, rc,
452 NULL, text, NULL, NULL );
455 LDAP_LOG( OPERATION, INFO, "do_bind: conn %d "
456 "v%d unprotected simple bind(%s) disallowed\n",
457 conn->c_connid, version, ndn.bv_val );
459 Debug( LDAP_DEBUG_TRACE,
460 "do_bind: v%d unprotected simple bind(%s) disallowed\n",
461 version, ndn.bv_val, 0 );
466 #ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
467 } else if ( method == LDAP_AUTH_KRBV41 || method == LDAP_AUTH_KRBV42 ) {
468 if ( global_disallows & SLAP_DISALLOW_BIND_KRBV4 ) {
469 /* disallow simple authentication */
470 rc = LDAP_UNWILLING_TO_PERFORM;
471 text = "unwilling to perform Kerberos V4 bind";
473 send_ldap_result( conn, op, rc,
474 NULL, text, NULL, NULL );
476 LDAP_LOG( OPERATION, DETAIL1,
477 "do_bind: conn %d v%d Kerberos V4 bind\n",
478 conn->c_connid, version , 0 );
480 Debug( LDAP_DEBUG_TRACE, "do_bind: v%d Kerberos V4 bind\n",
488 rc = LDAP_AUTH_METHOD_NOT_SUPPORTED;
489 text = "unknown authentication method";
491 send_ldap_result( conn, op, rc,
492 NULL, text, NULL, NULL );
494 LDAP_LOG( OPERATION, INFO,
495 "do_bind: conn %ld v%d unknown authentication method (%ld)\n",
496 conn->c_connid, version, method );
498 Debug( LDAP_DEBUG_TRACE,
499 "do_bind: v%d unknown authentication method (%ld)\n",
500 version, method, 0 );
506 * We could be serving multiple database backends. Select the
507 * appropriate one, or send a referral to our "referral server"
508 * if we don't hold it.
511 if ( (be = select_backend( &ndn, 0, 0 )) == NULL ) {
512 if ( default_referral ) {
513 BerVarray ref = referral_rewrite( default_referral,
514 NULL, &pdn, LDAP_SCOPE_DEFAULT );
516 send_ldap_result( conn, op, rc = LDAP_REFERRAL,
517 NULL, NULL, ref ? ref : default_referral, NULL );
519 ber_bvarray_free( ref );
522 /* noSuchObject is not allowed to be returned by bind */
523 send_ldap_result( conn, op, rc = LDAP_INVALID_CREDENTIALS,
524 NULL, NULL, NULL, NULL );
530 /* check restrictions */
531 rc = backend_check_restrictions( be, conn, op, NULL, &text );
532 if( rc != LDAP_SUCCESS ) {
533 send_ldap_result( conn, op, rc,
534 NULL, text, NULL, NULL );
538 #if defined( LDAP_SLAPI )
539 slapi_x_backend_set_pb( pb, be );
540 slapi_x_connection_set_pb( pb, conn );
541 slapi_x_operation_set_pb( pb, op );
542 slapi_pblock_set( pb, SLAPI_BIND_TARGET, (void *)dn.bv_val );
543 slapi_pblock_set( pb, SLAPI_BIND_METHOD, (void *)method );
544 slapi_pblock_set( pb, SLAPI_BIND_CREDENTIALS, (void *)&cred );
545 slapi_pblock_set( pb, SLAPI_MANAGEDSAIT, (void *)(0) );
547 rc = doPluginFNs( be, SLAPI_PLUGIN_PRE_BIND_FN, pb );
548 if ( rc != SLAPI_BIND_SUCCESS ) {
550 * Binding is a special case for SLAPI plugins. It is
551 * possible for a bind plugin to be successful *and*
552 * abort further processing; this means it has handled
553 * a bind request authoritatively. If we have reached
554 * here, a result has been sent to the client (XXX
555 * need to check with Sun whether SLAPI_BIND_ANONYMOUS
556 * means a result has been sent).
560 if ( slapi_pblock_get( pb, SLAPI_RESULT_CODE, (void *)&ldapRc ) != 0 )
565 if ( rc != SLAPI_BIND_FAIL && ldapRc == LDAP_SUCCESS ) {
566 /* Set the new connection DN. */
567 if ( rc != SLAPI_BIND_ANONYMOUS ) {
568 slapi_pblock_get( pb, SLAPI_CONN_DN, (void *)&edn.bv_val );
570 rc = dnPrettyNormal( NULL, &edn, &pdn, &ndn );
571 ldap_pvt_thread_mutex_lock( &conn->c_mutex );
578 if ( conn->c_dn.bv_len != 0 ) {
579 ber_len_t max = sockbuf_max_incoming_auth;
580 ber_sockbuf_ctrl( conn->c_sb, LBER_SB_OPT_SET_MAX_INCOMING, &max );
582 /* log authorization identity */
583 Statslog( LDAP_DEBUG_STATS,
584 "conn=%lu op=%lu BIND dn=\"%s\" mech=simple (SLAPI) ssf=0\n",
585 op->o_connid, op->o_opid,
586 conn->c_dn.bv_val, 0, 0 );
587 ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
590 LDAP_LOG( OPERATION, INFO, "do_bind: Bind preoperation plugin returned %d\n",
593 Debug(LDAP_DEBUG_TRACE, "do_bind: Bind preoperation plugin returned %d.\n",
599 #endif /* defined( LDAP_SLAPI ) */
604 /* deref suffix alias if appropriate */
605 suffix_alias( be, &ndn );
607 ret = (*be->be_bind)( be, conn, op,
608 &pdn, &ndn, method, &cred, &edn );
611 ldap_pvt_thread_mutex_lock( &conn->c_mutex );
613 if( conn->c_authz_backend == NULL ) {
614 conn->c_authz_backend = be;
629 if( conn->c_dn.bv_len != 0 ) {
630 ber_len_t max = sockbuf_max_incoming_auth;
631 ber_sockbuf_ctrl( conn->c_sb,
632 LBER_SB_OPT_SET_MAX_INCOMING, &max );
635 /* log authorization identity */
636 Statslog( LDAP_DEBUG_STATS,
637 "conn=%lu op=%lu BIND dn=\"%s\" mech=simple ssf=0\n",
638 op->o_connid, op->o_opid,
639 conn->c_dn.bv_val, conn->c_authmech.bv_val, 0 );
642 LDAP_LOG( OPERATION, DETAIL1,
643 "do_bind: v%d bind: \"%s\" to \"%s\" \n",
644 version, conn->c_dn.bv_val, conn->c_dn.bv_val );
646 Debug( LDAP_DEBUG_TRACE,
647 "do_bind: v%d bind: \"%s\" to \"%s\"\n",
648 version, dn.bv_val, conn->c_dn.bv_val );
651 ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
653 /* send this here to avoid a race condition */
654 send_ldap_result( conn, op, LDAP_SUCCESS,
655 NULL, NULL, NULL, NULL );
657 } else if (edn.bv_val != NULL) {
662 send_ldap_result( conn, op, rc = LDAP_UNWILLING_TO_PERFORM,
663 NULL, "operation not supported within namingContext",
667 #if defined( LDAP_SLAPI )
668 if ( doPluginFNs( be, SLAPI_PLUGIN_POST_BIND_FN, pb ) != 0 ) {
670 LDAP_LOG( OPERATION, INFO, "do_bind: Bind postoperation plugins failed\n",
673 Debug(LDAP_DEBUG_TRACE, "do_bind: Bind postoperation plugins failed.\n",
677 #endif /* defined( LDAP_SLAPI ) */
680 conn->c_sasl_bindop = NULL;
682 if( pdn.bv_val != NULL ) {
685 if( ndn.bv_val != NULL ) {
688 if ( mech.bv_val != NULL ) {