]> git.sur5r.net Git - openldap/blob - servers/slapd/bind.c
b264c46607883dc1710bd5de1de7d155b49a891e
[openldap] / servers / slapd / bind.c
1 /* bind.c - decode an ldap bind operation and pass it to a backend db */
2 /* $OpenLDAP$ */
3 /*
4  * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
5  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
6  */
7
8 /*
9  * Copyright (c) 1995 Regents of the University of Michigan.
10  * All rights reserved.
11  *
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.
18  */
19
20 #include "portable.h"
21 #include "slapi_common.h"
22
23 #include <stdio.h>
24
25 #include <ac/string.h>
26 #include <ac/socket.h>
27
28 #include "ldap_pvt.h"
29 #include "slap.h"
30 #include "slapi.h"
31
32
33 int
34 do_bind(
35     Connection  *conn,
36     Operation   *op
37 )
38 {
39         BerElement *ber = op->o_ber;
40         ber_int_t version;
41         ber_tag_t method;
42         struct berval mech = { 0, NULL };
43         struct berval dn = { 0, NULL };
44         struct berval pdn = { 0, NULL };
45         struct berval ndn = { 0, NULL };
46         struct berval edn = { 0, NULL };
47         ber_tag_t tag;
48         int     rc = LDAP_SUCCESS;
49         const char *text;
50         struct berval cred = { 0, NULL };
51         Backend *be = NULL;
52
53         Slapi_PBlock *pb = op->o_pb;
54
55 #ifdef NEW_LOGGING
56         LDAP_LOG( OPERATION, ENTRY, "do_bind: conn %d\n", conn->c_connid, 0, 0 );
57 #else
58         Debug( LDAP_DEBUG_TRACE, "do_bind\n", 0, 0, 0 );
59 #endif
60
61         /*
62          * Force to connection to "anonymous" until bind succeeds.
63          */
64         ldap_pvt_thread_mutex_lock( &conn->c_mutex );
65         if ( conn->c_sasl_bind_in_progress ) be = conn->c_authz_backend;
66
67         /* log authorization identity demotion */
68         if ( conn->c_dn.bv_len ) {
69                 Statslog( LDAP_DEBUG_STATS,
70                         "conn=%lu op=%lu AUTHZ anonymous mech=implicit ssf=0",
71                         op->o_connid, op->o_opid, 0, 0, 0 );
72         }
73
74         connection2anonymous( conn );
75         if ( conn->c_sasl_bind_in_progress ) conn->c_authz_backend = be;
76         ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
77
78         if ( op->o_dn.bv_val != NULL ) {
79                 free( op->o_dn.bv_val );
80                 op->o_dn.bv_val = ch_strdup( "" );
81                 op->o_dn.bv_len = 0;
82         }
83
84         if ( op->o_ndn.bv_val != NULL ) {
85                 free( op->o_ndn.bv_val );
86                 op->o_ndn.bv_val = ch_strdup( "" );
87                 op->o_ndn.bv_len = 0;
88         }
89
90         /*
91          * Parse the bind request.  It looks like this:
92          *
93          *      BindRequest ::= SEQUENCE {
94          *              version         INTEGER,                 -- version
95          *              name            DistinguishedName,       -- dn
96          *              authentication  CHOICE {
97          *                      simple          [0] OCTET STRING -- passwd
98          *                      krbv42ldap      [1] OCTET STRING
99          *                      krbv42dsa       [2] OCTET STRING
100          *                      SASL            [3] SaslCredentials
101          *              }
102          *      }
103          *
104          *      SaslCredentials ::= SEQUENCE {
105      *          mechanism           LDAPString,
106      *          credentials         OCTET STRING OPTIONAL
107          *      }
108          */
109
110         tag = ber_scanf( ber, "{imt" /*}*/, &version, &dn, &method );
111
112         if ( tag == LBER_ERROR ) {
113 #ifdef NEW_LOGGING
114                 LDAP_LOG( OPERATION, ERR, 
115                         "do_bind: conn %d  ber_scanf failed\n", conn->c_connid, 0, 0 );
116 #else
117                 Debug( LDAP_DEBUG_ANY, "bind: ber_scanf failed\n", 0, 0, 0 );
118 #endif
119                 send_ldap_disconnect( conn, op,
120                         LDAP_PROTOCOL_ERROR, "decoding error" );
121                 rc = -1;
122                 goto cleanup;
123         }
124
125         op->o_protocol = version;
126
127         if( method != LDAP_AUTH_SASL ) {
128                 tag = ber_scanf( ber, /*{*/ "m}", &cred );
129
130         } else {
131                 tag = ber_scanf( ber, "{o" /*}*/, &mech );
132
133                 if ( tag != LBER_ERROR ) {
134                         ber_len_t len;
135                         tag = ber_peek_tag( ber, &len );
136
137                         if ( tag == LDAP_TAG_LDAPCRED ) { 
138                                 tag = ber_scanf( ber, "m", &cred );
139                         } else {
140                                 tag = LDAP_TAG_LDAPCRED;
141                                 cred.bv_val = NULL;
142                                 cred.bv_len = 0;
143                         }
144
145                         if ( tag != LBER_ERROR ) {
146                                 tag = ber_scanf( ber, /*{{*/ "}}" );
147                         }
148                 }
149         }
150
151         if ( tag == LBER_ERROR ) {
152                 send_ldap_disconnect( conn, op,
153                         LDAP_PROTOCOL_ERROR,
154                 "decoding error" );
155                 rc = SLAPD_DISCONNECT;
156                 goto cleanup;
157         }
158
159         if( (rc = get_ctrls( conn, op, 1 )) != LDAP_SUCCESS ) {
160 #ifdef NEW_LOGGING
161                 LDAP_LOG( OPERATION, INFO, 
162                         "do_bind: conn %d  get_ctrls failed\n", conn->c_connid, 0, 0 );
163 #else
164                 Debug( LDAP_DEBUG_ANY, "do_bind: get_ctrls failed\n", 0, 0, 0 );
165 #endif
166                 goto cleanup;
167         } 
168
169         rc = dnPrettyNormal( NULL, &dn, &pdn, &ndn );
170         if ( rc != LDAP_SUCCESS ) {
171 #ifdef NEW_LOGGING
172                 LDAP_LOG( OPERATION, INFO, 
173                         "do_bind: conn %d  invalid dn (%s)\n", 
174                         conn->c_connid, dn.bv_val, 0 );
175 #else
176                 Debug( LDAP_DEBUG_ANY, "bind: invalid dn (%s)\n",
177                         dn.bv_val, 0, 0 );
178 #endif
179                 send_ldap_result( conn, op, rc = LDAP_INVALID_DN_SYNTAX, NULL,
180                     "invalid DN", NULL, NULL );
181                 goto cleanup;
182         }
183
184         if( method == LDAP_AUTH_SASL ) {
185 #ifdef NEW_LOGGING
186                 LDAP_LOG( OPERATION,     DETAIL1, 
187                         "do_sasl_bind: conn %d  dn (%s) mech %s\n", 
188                         conn->c_connid, pdn.bv_val, mech.bv_val );
189 #else
190                 Debug( LDAP_DEBUG_TRACE, "do_sasl_bind: dn (%s) mech %s\n",
191                         pdn.bv_val, mech.bv_val, NULL );
192 #endif
193
194         } else {
195 #ifdef NEW_LOGGING
196                 LDAP_LOG( OPERATION, DETAIL1, 
197                         "do_bind: version=%ld dn=\"%s\" method=%ld\n",
198                         (unsigned long) version, pdn.bv_val, (unsigned long)method );
199 #else
200                 Debug( LDAP_DEBUG_TRACE,
201                         "do_bind: version=%ld dn=\"%s\" method=%ld\n",
202                         (unsigned long) version,
203                         pdn.bv_val, (unsigned long) method );
204 #endif
205         }
206
207         Statslog( LDAP_DEBUG_STATS, "conn=%lu op=%lu BIND dn=\"%s\" method=%ld\n",
208             op->o_connid, op->o_opid, pdn.bv_val, (unsigned long) method, 0 );
209
210         if ( version < LDAP_VERSION_MIN || version > LDAP_VERSION_MAX ) {
211 #ifdef NEW_LOGGING
212                 LDAP_LOG( OPERATION, INFO, 
213                         "do_bind: conn %d  unknown version = %ld\n",
214                         conn->c_connid, (unsigned long)version, 0 );
215 #else
216                 Debug( LDAP_DEBUG_ANY, "do_bind: unknown version=%ld\n",
217                         (unsigned long) version, 0, 0 );
218 #endif
219                 send_ldap_result( conn, op, rc = LDAP_PROTOCOL_ERROR,
220                         NULL, "requested protocol version not supported", NULL, NULL );
221                 goto cleanup;
222
223         } else if (!( global_allows & SLAP_ALLOW_BIND_V2 ) &&
224                 version < LDAP_VERSION3 )
225         {
226                 send_ldap_result( conn, op, rc = LDAP_PROTOCOL_ERROR,
227                         NULL, "requested protocol version not allowed", NULL, NULL );
228                 goto cleanup;
229         }
230
231         /* we set connection version regardless of whether bind succeeds
232          * or not.
233          */
234         ldap_pvt_thread_mutex_lock( &conn->c_mutex );
235         conn->c_protocol = version;
236         ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
237
238         /* check for inappropriate controls */
239         if( get_manageDSAit( op ) == SLAP_CRITICAL_CONTROL ) {
240                 send_ldap_result( conn, op,
241                         rc = LDAP_UNAVAILABLE_CRITICAL_EXTENSION,
242                         NULL, "manageDSAit control inappropriate",
243                         NULL, NULL );
244                 goto cleanup;
245         }
246
247         /* Set the bindop for the benefit of in-directory SASL lookups */
248         conn->c_sasl_bindop = op;
249
250         if ( method == LDAP_AUTH_SASL ) {
251                 slap_ssf_t ssf = 0;
252
253                 if ( version < LDAP_VERSION3 ) {
254 #ifdef NEW_LOGGING
255                         LDAP_LOG( OPERATION, INFO, 
256                                 "do_bind: conn %d  sasl with LDAPv%ld\n",
257                                 conn->c_connid, (unsigned long)version , 0 );
258 #else
259                         Debug( LDAP_DEBUG_ANY, "do_bind: sasl with LDAPv%ld\n",
260                                 (unsigned long) version, 0, 0 );
261 #endif
262                         send_ldap_disconnect( conn, op,
263                                 LDAP_PROTOCOL_ERROR, "SASL bind requires LDAPv3" );
264                         rc = SLAPD_DISCONNECT;
265                         goto cleanup;
266                 }
267
268                 if( mech.bv_len == 0 ) {
269 #ifdef NEW_LOGGING
270                         LDAP_LOG( OPERATION, INFO, 
271                                    "do_bind: conn %d  no SASL mechanism provided\n",
272                                    conn->c_connid, 0, 0 );
273 #else
274                         Debug( LDAP_DEBUG_ANY,
275                                 "do_bind: no sasl mechanism provided\n",
276                                 0, 0, 0 );
277 #endif
278                         send_ldap_result( conn, op, rc = LDAP_AUTH_METHOD_NOT_SUPPORTED,
279                                 NULL, "no SASL mechanism provided", NULL, NULL );
280                         goto cleanup;
281                 }
282
283                 /* check restrictions */
284                 rc = backend_check_restrictions( NULL, conn, op, &mech, &text );
285                 if( rc != LDAP_SUCCESS ) {
286                         send_ldap_result( conn, op, rc,
287                                 NULL, text, NULL, NULL );
288                         goto cleanup;
289                 }
290
291                 ldap_pvt_thread_mutex_lock( &conn->c_mutex );
292                 if ( conn->c_sasl_bind_in_progress ) {
293                         if( !bvmatch( &conn->c_sasl_bind_mech, &mech ) ) {
294                                 /* mechanism changed between bind steps */
295                                 slap_sasl_reset(conn);
296                         }
297                 } else {
298                         conn->c_sasl_bind_mech = mech;
299                         mech.bv_val = NULL;
300                         mech.bv_len = 0;
301                 }
302                 ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
303
304                 rc = slap_sasl_bind( conn, op,
305                         &pdn, &ndn,
306                         &cred, &edn, &ssf );
307
308                 ldap_pvt_thread_mutex_lock( &conn->c_mutex );
309                 if( rc == LDAP_SUCCESS ) {
310                         conn->c_dn = edn;
311                         if( edn.bv_len != 0 ) {
312                                 /* edn is always normalized already */
313                                 ber_dupbv( &conn->c_ndn, &conn->c_dn );
314                         }
315                         conn->c_authmech = conn->c_sasl_bind_mech;
316                         conn->c_sasl_bind_mech.bv_val = NULL;
317                         conn->c_sasl_bind_mech.bv_len = 0;
318                         conn->c_sasl_bind_in_progress = 0;
319
320                         conn->c_sasl_ssf = ssf;
321                         if( ssf > conn->c_ssf ) {
322                                 conn->c_ssf = ssf;
323                         }
324
325                         if( conn->c_dn.bv_len != 0 ) {
326                                 ber_len_t max = sockbuf_max_incoming_auth;
327                                 ber_sockbuf_ctrl( conn->c_sb,
328                                         LBER_SB_OPT_SET_MAX_INCOMING, &max );
329                         }
330
331                         /* log authorization identity */
332                         Statslog( LDAP_DEBUG_STATS,
333                                 "conn=%lu op=%lu AUTHZ dn=\"%s\" mech=%s ssf=%d\n",
334                                 op->o_connid, op->o_opid,
335                                 conn->c_dn.bv_val ? conn->c_dn.bv_val : "<empty>",
336                                 conn->c_authmech.bv_val, ssf );
337
338 #ifdef NEW_LOGGING
339                         LDAP_LOG( OPERATION, DETAIL1, 
340                                 "do_bind: SASL/%s bind: dn=\"%s\" ssf=%d\n",
341                                 conn->c_authmech.bv_val,
342                                 conn->c_dn.bv_val ? conn->c_dn.bv_val : "<empty>",
343                                 ssf );
344 #else
345                         Debug( LDAP_DEBUG_TRACE,
346                                 "do_bind: SASL/%s bind: dn=\"%s\" ssf=%d\n",
347                                 conn->c_authmech.bv_val,
348                                 conn->c_dn.bv_val ? conn->c_dn.bv_val : "<empty>",
349                                 ssf );
350 #endif
351
352                 } else if ( rc == LDAP_SASL_BIND_IN_PROGRESS ) {
353                         conn->c_sasl_bind_in_progress = 1;
354
355                 } else {
356                         if ( conn->c_sasl_bind_mech.bv_val ) {
357                                 free( conn->c_sasl_bind_mech.bv_val );
358                                 conn->c_sasl_bind_mech.bv_val = NULL;
359                                 conn->c_sasl_bind_mech.bv_len = 0;
360                         }
361                         conn->c_sasl_bind_in_progress = 0;
362                 }
363                 ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
364
365                 goto cleanup;
366
367         } else {
368                 /* Not SASL, cancel any in-progress bind */
369                 ldap_pvt_thread_mutex_lock( &conn->c_mutex );
370
371                 if ( conn->c_sasl_bind_mech.bv_val != NULL ) {
372                         free(conn->c_sasl_bind_mech.bv_val);
373                         conn->c_sasl_bind_mech.bv_val = NULL;
374                         conn->c_sasl_bind_mech.bv_len = 0;
375                 }
376                 conn->c_sasl_bind_in_progress = 0;
377
378                 slap_sasl_reset( conn );
379                 ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
380         }
381
382         if ( method == LDAP_AUTH_SIMPLE ) {
383                 /* accept "anonymous" binds */
384                 if ( cred.bv_len == 0 || ndn.bv_len == 0 ) {
385                         rc = LDAP_SUCCESS;
386                         text = NULL;
387
388                         if( cred.bv_len &&
389                                 !( global_allows & SLAP_ALLOW_BIND_ANON_CRED ))
390                         {
391                                 /* cred is not empty, disallow */
392                                 rc = LDAP_INVALID_CREDENTIALS;
393
394                         } else if ( ndn.bv_len &&
395                                 !( global_allows & SLAP_ALLOW_BIND_ANON_DN ))
396                         {
397                                 /* DN is not empty, disallow */
398                                 rc = LDAP_UNWILLING_TO_PERFORM;
399                                 text = "unwilling to allow anonymous bind with non-empty DN";
400
401                         } else if ( global_disallows & SLAP_DISALLOW_BIND_ANON ) {
402                                 /* disallow */
403                                 rc = LDAP_INAPPROPRIATE_AUTH;
404                                 text = "anonymous bind disallowed";
405
406                         } else {
407                                 rc = backend_check_restrictions( NULL, conn, op,
408                                         &mech, &text );
409                         }
410
411                         /*
412                          * we already forced connection to "anonymous",
413                          * just need to send success
414                          */
415                         send_ldap_result( conn, op, rc,
416                                 NULL, text, NULL, NULL );
417 #ifdef NEW_LOGGING
418                         LDAP_LOG( OPERATION, DETAIL1, 
419                                    "do_bind: conn %d  v%d anonymous bind\n",
420                                    conn->c_connid, version , 0 );
421 #else
422                         Debug( LDAP_DEBUG_TRACE, "do_bind: v%d anonymous bind\n",
423                                 version, 0, 0 );
424 #endif
425                         goto cleanup;
426
427                 } else if ( global_disallows & SLAP_DISALLOW_BIND_SIMPLE ) {
428                         /* disallow simple authentication */
429                         rc = LDAP_UNWILLING_TO_PERFORM;
430                         text = "unwilling to perform simple authentication";
431
432                         send_ldap_result( conn, op, rc,
433                                 NULL, text, NULL, NULL );
434 #ifdef NEW_LOGGING
435                         LDAP_LOG( OPERATION, INFO, 
436                                    "do_bind: conn %d  v%d simple bind(%s) disallowed\n",
437                                    conn->c_connid, version, ndn.bv_val );
438 #else
439                         Debug( LDAP_DEBUG_TRACE,
440                                 "do_bind: v%d simple bind(%s) disallowed\n",
441                                 version, ndn.bv_val, 0 );
442 #endif
443                         goto cleanup;
444
445                 } else if (( global_disallows & SLAP_DISALLOW_BIND_SIMPLE_UNPROTECTED )
446                         && ( op->o_ssf <= 1 ))
447                 {
448                         rc = LDAP_CONFIDENTIALITY_REQUIRED;
449                         text = "unwilling to perform simple authentication "
450                                 "without confidentilty protection";
451
452                         send_ldap_result( conn, op, rc,
453                                 NULL, text, NULL, NULL );
454
455 #ifdef NEW_LOGGING
456                         LDAP_LOG( OPERATION, INFO, "do_bind: conn %d  "
457                                 "v%d unprotected simple bind(%s) disallowed\n",
458                                 conn->c_connid, version, ndn.bv_val );
459 #else
460                         Debug( LDAP_DEBUG_TRACE,
461                                 "do_bind: v%d unprotected simple bind(%s) disallowed\n",
462                                 version, ndn.bv_val, 0 );
463 #endif
464                         goto cleanup;
465                 }
466
467 #ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
468         } else if ( method == LDAP_AUTH_KRBV41 || method == LDAP_AUTH_KRBV42 ) {
469                 if ( global_disallows & SLAP_DISALLOW_BIND_KRBV4 ) {
470                         /* disallow simple authentication */
471                         rc = LDAP_UNWILLING_TO_PERFORM;
472                         text = "unwilling to perform Kerberos V4 bind";
473
474                         send_ldap_result( conn, op, rc,
475                                 NULL, text, NULL, NULL );
476 #ifdef NEW_LOGGING
477                         LDAP_LOG( OPERATION, DETAIL1, 
478                                    "do_bind: conn %d  v%d Kerberos V4 bind\n",
479                                    conn->c_connid, version , 0 );
480 #else
481                         Debug( LDAP_DEBUG_TRACE, "do_bind: v%d Kerberos V4 bind\n",
482                                 version, 0, 0 );
483 #endif
484                         goto cleanup;
485                 }
486 #endif
487
488         } else {
489                 rc = LDAP_AUTH_METHOD_NOT_SUPPORTED;
490                 text = "unknown authentication method";
491
492                 send_ldap_result( conn, op, rc,
493                         NULL, text, NULL, NULL );
494 #ifdef NEW_LOGGING
495                 LDAP_LOG( OPERATION, INFO, 
496                            "do_bind: conn %ld  v%d unknown authentication method (%ld)\n",
497                            conn->c_connid, version, method );
498 #else
499                 Debug( LDAP_DEBUG_TRACE,
500                         "do_bind: v%d unknown authentication method (%ld)\n",
501                         version, method, 0 );
502 #endif
503                 goto cleanup;
504         }
505
506         /*
507          * We could be serving multiple database backends.  Select the
508          * appropriate one, or send a referral to our "referral server"
509          * if we don't hold it.
510          */
511
512         if ( (be = select_backend( &ndn, 0, 0 )) == NULL ) {
513                 if ( default_referral ) {
514                         BerVarray ref = referral_rewrite( default_referral,
515                                 NULL, &pdn, LDAP_SCOPE_DEFAULT );
516
517                         send_ldap_result( conn, op, rc = LDAP_REFERRAL,
518                                 NULL, NULL, ref ? ref : default_referral, NULL );
519
520                         ber_bvarray_free( ref );
521
522                 } else {
523                         /* noSuchObject is not allowed to be returned by bind */
524                         send_ldap_result( conn, op, rc = LDAP_INVALID_CREDENTIALS,
525                                 NULL, NULL, NULL, NULL );
526                 }
527
528                 goto cleanup;
529         }
530
531         /* check restrictions */
532         rc = backend_check_restrictions( be, conn, op, NULL, &text );
533         if( rc != LDAP_SUCCESS ) {
534                 send_ldap_result( conn, op, rc,
535                         NULL, text, NULL, NULL );
536                 goto cleanup;
537         }
538
539 #if defined( LDAP_SLAPI )
540         slapi_backend_set_pb( pb, be );
541         slapi_connection_set_pb( pb, conn );
542         slapi_operation_set_pb( pb, op );
543         slapi_pblock_set( pb, SLAPI_BIND_TARGET, (void *)dn.bv_val );
544         slapi_pblock_set( pb, SLAPI_BIND_METHOD, (void *)method );
545         slapi_pblock_set( pb, SLAPI_MANAGEDSAIT, (void *)(1) );
546
547         rc = doPluginFNs( be, SLAPI_PLUGIN_PRE_BIND_FN, pb );
548         if ( rc != 0 && rc != LDAP_OTHER ) {
549                 /*
550                  * either there is no preOp (bind) plugins
551                  * or a plugin failed. Just log it
552                  *
553                  * FIXME: is this correct?
554                  */
555 #ifdef NEW_LOGGING
556                 LDAP_LOG( OPERATION, INFO, "do_bind: Bind preOps failed\n",
557                                 0, 0, 0);
558 #else
559                 Debug(LDAP_DEBUG_TRACE, "do_bind: Bind preOps failed.\n",
560                                 0, 0, 0);
561 #endif
562         }
563 #endif /* defined( LDAP_SLAPI ) */
564
565         if ( be->be_bind ) {
566                 int ret;
567
568                 /* deref suffix alias if appropriate */
569                 suffix_alias( be, &ndn );
570
571                 ret = (*be->be_bind)( be, conn, op,
572                         &pdn, &ndn, method, &cred, &edn );
573
574                 if ( ret == 0 ) {
575                         ldap_pvt_thread_mutex_lock( &conn->c_mutex );
576
577                         if( conn->c_authz_backend == NULL ) {
578                                 conn->c_authz_backend = be;
579                         }
580
581                         if(edn.bv_len) {
582                                 conn->c_dn = edn;
583                         } else {
584                                 conn->c_dn = pdn;
585                                 pdn.bv_val = NULL;
586                                 pdn.bv_len = 0;
587                         }
588
589                         conn->c_ndn = ndn;
590                         ndn.bv_val = NULL;
591                         ndn.bv_len = 0;
592
593                         if( conn->c_dn.bv_len != 0 ) {
594                                 ber_len_t max = sockbuf_max_incoming_auth;
595                                 ber_sockbuf_ctrl( conn->c_sb,
596                                         LBER_SB_OPT_SET_MAX_INCOMING, &max );
597                         }
598
599                         /* log authorization identity */
600                         Statslog( LDAP_DEBUG_STATS,
601                                 "conn=%lu op=%lu AUTHZ dn=\"%s\" mech=simple ssf=0\n",
602                                 op->o_connid, op->o_opid,
603                                 conn->c_dn.bv_val, conn->c_authmech.bv_val, 0 );
604
605 #ifdef NEW_LOGGING
606                         LDAP_LOG( OPERATION, DETAIL1, 
607                                 "do_bind: v%d bind: \"%s\" to \"%s\" \n",
608                                 version, conn->c_dn.bv_val, conn->c_dn.bv_val );
609 #else
610                         Debug( LDAP_DEBUG_TRACE,
611                                 "do_bind: v%d bind: \"%s\" to \"%s\"\n",
612                                 version, dn.bv_val, conn->c_dn.bv_val );
613 #endif
614
615                         ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
616
617                         /* send this here to avoid a race condition */
618                         send_ldap_result( conn, op, LDAP_SUCCESS,
619                                 NULL, NULL, NULL, NULL );
620
621                 } else if (edn.bv_val != NULL) {
622                         free( edn.bv_val );
623                 }
624
625         } else {
626                 send_ldap_result( conn, op, rc = LDAP_UNWILLING_TO_PERFORM,
627                         NULL, "operation not supported within namingContext",
628                         NULL, NULL );
629         }
630
631 #if defined( LDAP_SLAPI )
632         rc = doPluginFNs( be, SLAPI_PLUGIN_POST_BIND_FN, pb );
633         if ( rc != 0 && rc != LDAP_OTHER ) {
634                 /*
635                  * either there is no pretOp (bind) plugins
636                  * or a plugin failed. Just log it
637                  *
638                  * FIXME: is this correct?
639                  */
640 #ifdef NEW_LOGGING
641                 LDAP_LOG( OPERATION, INFO, "do_bind: Bind postOps failed\n",
642                                 0, 0, 0);
643 #else
644                 Debug(LDAP_DEBUG_TRACE, "do_bind: Bind postOps failed.\n",
645                                 0, 0, 0);
646 #endif
647         }
648 #endif /* defined( LDAP_SLAPI ) */
649
650 cleanup:
651         conn->c_sasl_bindop = NULL;
652
653         if( pdn.bv_val != NULL ) {
654                 free( pdn.bv_val );
655         }
656         if( ndn.bv_val != NULL ) {
657                 free( ndn.bv_val );
658         }
659         if ( mech.bv_val != NULL ) {
660                 free( mech.bv_val );
661         }
662
663         return rc;
664 }