1 /* bind.c - decode an ldap bind operation and pass it to a backend db */
4 * Copyright 1998-2000 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>
36 BerElement *ber = op->o_ber;
40 struct berval dn = { 0, NULL };
41 struct berval *pdn = NULL;
42 struct berval *ndn = NULL;
44 int rc = LDAP_SUCCESS;
46 struct berval cred = { 0, NULL };
50 LDAP_LOG(( "operation", LDAP_LEVEL_ENTRY,
51 "do_bind: conn %d\n", conn->c_connid ));
53 Debug( LDAP_DEBUG_TRACE, "do_bind\n", 0, 0, 0 );
57 * Force to connection to "anonymous" until bind succeeds.
59 ldap_pvt_thread_mutex_lock( &conn->c_mutex );
60 connection2anonymous( conn );
61 ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
63 if ( op->o_dn != NULL ) {
65 op->o_dn = ch_strdup( "" );
68 if ( op->o_ndn != NULL ) {
70 op->o_ndn = ch_strdup( "" );
74 * Parse the bind request. It looks like this:
76 * BindRequest ::= SEQUENCE {
77 * version INTEGER, -- version
78 * name DistinguishedName, -- dn
79 * authentication CHOICE {
80 * simple [0] OCTET STRING -- passwd
81 * krbv42ldap [1] OCTET STRING
82 * krbv42dsa [2] OCTET STRING
83 * SASL [3] SaslCredentials
87 * SaslCredentials ::= SEQUENCE {
88 * mechanism LDAPString,
89 * credentials OCTET STRING OPTIONAL
93 tag = ber_scanf( ber, "{iot" /*}*/, &version, &dn, &method );
95 if ( tag == LBER_ERROR ) {
97 LDAP_LOG(( "operation", LDAP_LEVEL_ERR,
98 "do_bind: conn %d ber_scanf failed\n", conn->c_connid ));
100 Debug( LDAP_DEBUG_ANY, "bind: ber_scanf failed\n", 0, 0, 0 );
102 send_ldap_disconnect( conn, op,
103 LDAP_PROTOCOL_ERROR, "decoding error" );
108 op->o_protocol = version;
110 if( method != LDAP_AUTH_SASL ) {
111 tag = ber_scanf( ber, /*{*/ "o}", &cred );
114 tag = ber_scanf( ber, "{a" /*}*/, &mech );
116 if ( tag != LBER_ERROR ) {
118 tag = ber_peek_tag( ber, &len );
120 if ( tag == LDAP_TAG_LDAPCRED ) {
121 tag = ber_scanf( ber, "o", &cred );
123 tag = LDAP_TAG_LDAPCRED;
128 if ( tag != LBER_ERROR ) {
129 tag = ber_scanf( ber, /*{{*/ "}}" );
134 if ( tag == LBER_ERROR ) {
135 send_ldap_disconnect( conn, op,
138 rc = SLAPD_DISCONNECT;
142 if( (rc = get_ctrls( conn, op, 1 )) != LDAP_SUCCESS ) {
144 LDAP_LOG(( "operation", LDAP_LEVEL_INFO,
145 "do_bind: conn %d get_ctrls failed\n", conn->c_connid ));
147 Debug( LDAP_DEBUG_ANY, "do_bind: get_ctrls failed\n", 0, 0, 0 );
152 rc = dnPretty( NULL, &dn, &pdn );
153 if ( rc != LDAP_SUCCESS ) {
155 LDAP_LOG(( "operation", LDAP_LEVEL_INFO,
156 "do_bind: conn %d invalid dn (%s)\n",
157 conn->c_connid, dn.bv_val ));
159 Debug( LDAP_DEBUG_ANY, "bind: invalid dn (%s)\n",
162 send_ldap_result( conn, op, rc = LDAP_INVALID_DN_SYNTAX, NULL,
163 "invalid DN", NULL, NULL );
167 rc = dnNormalize( NULL, &dn, &ndn );
168 if ( rc != LDAP_SUCCESS ) {
170 LDAP_LOG(( "operation", LDAP_LEVEL_INFO,
171 "do_bind: conn %d invalid dn (%s)\n",
172 conn->c_connid, dn.bv_val ));
174 Debug( LDAP_DEBUG_ANY, "bind: invalid dn (%s)\n",
177 send_ldap_result( conn, op, rc = LDAP_INVALID_DN_SYNTAX, NULL,
178 "invalid DN", NULL, NULL );
182 if( method == LDAP_AUTH_SASL ) {
184 LDAP_LOG(( "operation", LDAP_LEVEL_DETAIL1,
185 "do_sasl_bind: conn %d dn (%s) mech %s\n", conn->c_connid,
186 pdn->bv_val, mech ));
188 Debug( LDAP_DEBUG_TRACE, "do_sasl_bind: dn (%s) mech %s\n",
189 pdn->bv_val, mech, NULL );
194 LDAP_LOG(( "operation", LDAP_LEVEL_DETAIL1,
195 "do_bind: conn %d version=%ld dn=\"%s\" method=%ld\n",
196 conn->c_connid, (unsigned long) version,
197 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=%ld op=%d 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", LDAP_LEVEL_INFO,
212 "do_bind: conn %d unknown version = %ld\n",
213 conn->c_connid, (unsigned long)version ));
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 if ( method == LDAP_AUTH_SASL ) {
241 if ( version < LDAP_VERSION3 ) {
243 LDAP_LOG(( "operation", LDAP_LEVEL_INFO,
244 "do_bind: conn %d sasl with LDAPv%ld\n",
245 conn->c_connid, (unsigned long)version ));
247 Debug( LDAP_DEBUG_ANY, "do_bind: sasl with LDAPv%ld\n",
248 (unsigned long) version, 0, 0 );
250 send_ldap_disconnect( conn, op,
251 LDAP_PROTOCOL_ERROR, "SASL bind requires LDAPv3" );
252 rc = SLAPD_DISCONNECT;
256 if( mech == NULL || *mech == '\0' ) {
258 LDAP_LOG(( "operation", LDAP_LEVEL_INFO,
259 "do_bind: conn %d no SASL mechanism provided\n",
262 Debug( LDAP_DEBUG_ANY,
263 "do_bind: no sasl mechanism provided\n",
266 send_ldap_result( conn, op, rc = LDAP_AUTH_METHOD_NOT_SUPPORTED,
267 NULL, "no SASL mechanism provided", NULL, NULL );
271 /* check restrictions */
272 rc = backend_check_restrictions( NULL, conn, op, mech, &text );
273 if( rc != LDAP_SUCCESS ) {
274 send_ldap_result( conn, op, rc,
275 NULL, text, NULL, NULL );
279 ldap_pvt_thread_mutex_lock( &conn->c_mutex );
280 if ( conn->c_sasl_bind_in_progress ) {
281 if((strcmp(conn->c_sasl_bind_mech, mech) != 0)) {
282 /* mechanism changed between bind steps */
283 slap_sasl_reset(conn);
286 conn->c_sasl_bind_mech = mech;
289 ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
292 rc = slap_sasl_bind( conn, op,
293 pdn->bv_val, ndn->bv_val,
296 ldap_pvt_thread_mutex_lock( &conn->c_mutex );
297 if( rc == LDAP_SUCCESS ) {
300 conn->c_ndn = ch_strdup( edn );
301 dn_normalize( conn->c_ndn );
303 conn->c_authmech = conn->c_sasl_bind_mech;
304 conn->c_sasl_bind_mech = NULL;
305 conn->c_sasl_bind_in_progress = 0;
307 conn->c_sasl_ssf = ssf;
308 if( ssf > conn->c_ssf ) {
312 if( conn->c_dn != NULL ) {
313 ber_len_t max = sockbuf_max_incoming;
314 ber_sockbuf_ctrl( conn->c_sb,
315 LBER_SB_OPT_SET_MAX_INCOMING, &max );
318 } else if ( rc == LDAP_SASL_BIND_IN_PROGRESS ) {
319 conn->c_sasl_bind_in_progress = 1;
322 if ( conn->c_sasl_bind_mech ) {
323 free( conn->c_sasl_bind_mech );
324 conn->c_sasl_bind_mech = NULL;
326 conn->c_sasl_bind_in_progress = 0;
328 ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
333 /* Not SASL, cancel any in-progress bind */
334 ldap_pvt_thread_mutex_lock( &conn->c_mutex );
336 if ( conn->c_sasl_bind_mech != NULL ) {
337 free(conn->c_sasl_bind_mech);
338 conn->c_sasl_bind_mech = NULL;
340 conn->c_sasl_bind_in_progress = 0;
342 slap_sasl_reset( conn );
343 ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
346 if ( method == LDAP_AUTH_SIMPLE ) {
347 /* accept "anonymous" binds */
348 if ( cred.bv_len == 0 || ndn->bv_len == 0 ) {
353 !( global_allows & SLAP_ALLOW_BIND_ANON_CRED ))
355 /* cred is not empty, disallow */
356 rc = LDAP_INVALID_CREDENTIALS;
358 } else if ( ndn->bv_len &&
359 !( global_allows & SLAP_ALLOW_BIND_ANON_DN ))
361 /* DN is not empty, disallow */
362 rc = LDAP_UNWILLING_TO_PERFORM;
363 text = "unwilling to allow anonymous bind with non-empty DN";
365 } else if ( global_disallows & SLAP_DISALLOW_BIND_ANON ) {
367 rc = LDAP_INAPPROPRIATE_AUTH;
368 text = "anonymous bind disallowed";
371 rc = backend_check_restrictions( NULL, conn, op, mech, &text );
375 * we already forced connection to "anonymous",
376 * just need to send success
378 send_ldap_result( conn, op, rc,
379 NULL, text, NULL, NULL );
381 LDAP_LOG(( "operation", LDAP_LEVEL_DETAIL1,
382 "do_bind: conn %d v%d anonymous bind\n",
383 conn->c_connid, version ));
385 Debug( LDAP_DEBUG_TRACE, "do_bind: v%d anonymous bind\n",
390 } else if ( global_disallows & SLAP_DISALLOW_BIND_SIMPLE ) {
391 /* disallow simple authentication */
392 rc = LDAP_UNWILLING_TO_PERFORM;
393 text = "unwilling to perform simple authentication";
395 send_ldap_result( conn, op, rc,
396 NULL, text, NULL, NULL );
398 LDAP_LOG(( "operation", LDAP_LEVEL_INFO,
399 "do_bind: conn %d v%d simple bind(%s) disallowed\n",
400 conn->c_connid, version, ndn ));
402 Debug( LDAP_DEBUG_TRACE,
403 "do_bind: v%d simple bind(%s) disallowed\n",
409 #ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
410 } else if ( method == LDAP_AUTH_KRBV41 || method == LDAP_AUTH_KRBV42 ) {
411 if ( global_disallows & SLAP_DISALLOW_BIND_KRBV4 ) {
412 /* disallow simple authentication */
413 rc = LDAP_UNWILLING_TO_PERFORM;
414 text = "unwilling to perform Kerberos V4 bind";
416 send_ldap_result( conn, op, rc,
417 NULL, text, NULL, NULL );
419 LDAP_LOG(( "operation", LDAP_LEVEL_DETAIL1,
420 "do_bind: conn %d v%d Kerberos V4 bind\n",
421 conn->c_connid, version ));
423 Debug( LDAP_DEBUG_TRACE, "do_bind: v%d Kerberos V4 bind\n",
431 rc = LDAP_AUTH_METHOD_NOT_SUPPORTED;
432 text = "unknown authentication method";
434 send_ldap_result( conn, op, rc,
435 NULL, text, NULL, NULL );
437 LDAP_LOG(( "operation", LDAP_LEVEL_INFO,
438 "do_bind: conn %ld v%d unknown authentication method (%ld)\n",
439 conn->c_connid, version, method ));
441 Debug( LDAP_DEBUG_TRACE,
442 "do_bind: v%d unknown authentication method (%ld)\n",
443 version, method, 0 );
449 * We could be serving multiple database backends. Select the
450 * appropriate one, or send a referral to our "referral server"
451 * if we don't hold it.
454 if ( (be = select_backend( ndn->bv_val, 0, 0 )) == NULL ) {
455 if ( default_referral ) {
456 struct berval **ref = referral_rewrite( default_referral,
457 NULL, pdn->bv_val, LDAP_SCOPE_DEFAULT );
459 send_ldap_result( conn, op, rc = LDAP_REFERRAL,
460 NULL, NULL, ref ? ref : default_referral, NULL );
465 /* noSuchObject is not allowed to be returned by bind */
466 send_ldap_result( conn, op, rc = LDAP_INVALID_CREDENTIALS,
467 NULL, NULL, NULL, NULL );
473 /* check restrictions */
474 rc = backend_check_restrictions( be, conn, op, NULL, &text );
475 if( rc != LDAP_SUCCESS ) {
476 send_ldap_result( conn, op, rc,
477 NULL, text, NULL, NULL );
481 conn->c_authz_backend = be;
488 /* deref suffix alias if appropriate */
489 ndn->bv_val = suffix_alias( be, ndn->bv_val );
490 ndn->bv_len = strlen( ndn->bv_val );
492 ret = (*be->be_bind)( be, conn, op,
493 pdn->bv_val, ndn->bv_val,
494 method, &cred, &edn );
497 ldap_pvt_thread_mutex_lock( &conn->c_mutex );
499 conn->c_cdn = pdn->bv_val;
506 conn->c_dn = ch_strdup( conn->c_cdn );
508 conn->c_ndn = ndn->bv_val;
512 if( conn->c_dn != NULL ) {
513 ber_len_t max = sockbuf_max_incoming;
514 ber_sockbuf_ctrl( conn->c_sb,
515 LBER_SB_OPT_SET_MAX_INCOMING, &max );
519 LDAP_LOG(( "operation", LDAP_LEVEL_DETAIL1,
520 "do_bind: conn %d v%d bind: \"%s\" to \"%s\" \n",
521 conn->c_connid, version, conn->c_cdn, conn->c_dn ));
523 Debug( LDAP_DEBUG_TRACE,
524 "do_bind: v%d bind: \"%s\" to \"%s\"\n",
525 version, conn->c_cdn, conn->c_dn );
528 ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
530 /* send this here to avoid a race condition */
531 send_ldap_result( conn, op, LDAP_SUCCESS,
532 NULL, NULL, NULL, NULL );
534 } else if (edn != NULL) {
539 send_ldap_result( conn, op, rc = LDAP_UNWILLING_TO_PERFORM,
540 NULL, "operation not supported within namingContext",
552 if ( mech != NULL ) {
555 if ( cred.bv_val != NULL ) {