Back to index

openldap  2.4.31
bind.c
Go to the documentation of this file.
00001 /* bind.c - mdb backend bind routine */
00002 /* $OpenLDAP$ */
00003 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
00004  *
00005  * Copyright 2000-2012 The OpenLDAP Foundation.
00006  * All rights reserved.
00007  *
00008  * Redistribution and use in source and binary forms, with or without
00009  * modification, are permitted only as authorized by the OpenLDAP
00010  * Public License.
00011  *
00012  * A copy of this license is available in the file LICENSE in the
00013  * top-level directory of the distribution or, alternatively, at
00014  * <http://www.OpenLDAP.org/license.html>.
00015  */
00016 
00017 #include "portable.h"
00018 
00019 #include <stdio.h>
00020 #include <ac/string.h>
00021 #include <ac/unistd.h>
00022 
00023 #include "back-mdb.h"
00024 
00025 int
00026 mdb_bind( Operation *op, SlapReply *rs )
00027 {
00028        struct mdb_info *mdb = (struct mdb_info *) op->o_bd->be_private;
00029        Entry         *e;
00030        Attribute     *a;
00031 
00032        AttributeDescription *password = slap_schema.si_ad_userPassword;
00033 
00034        MDB_txn              *rtxn;
00035        mdb_op_info   opinfo = {{{0}}}, *moi = &opinfo;
00036 
00037        Debug( LDAP_DEBUG_ARGS,
00038               "==> " LDAP_XSTRING(mdb_bind) ": dn: %s\n",
00039               op->o_req_dn.bv_val, 0, 0);
00040 
00041        /* allow noauth binds */
00042        switch ( be_rootdn_bind( op, NULL ) ) {
00043        case LDAP_SUCCESS:
00044               /* frontend will send result */
00045               return rs->sr_err = LDAP_SUCCESS;
00046 
00047        default:
00048               /* give the database a chance */
00049               /* NOTE: this behavior departs from that of other backends,
00050                * since the others, in case of password checking failure
00051                * do not give the database a chance.  If an entry with
00052                * rootdn's name does not exist in the database the result
00053                * will be the same.  See ITS#4962 for discussion. */
00054               break;
00055        }
00056 
00057        rs->sr_err = mdb_opinfo_get(op, mdb, 1, &moi);
00058        switch(rs->sr_err) {
00059        case 0:
00060               break;
00061        default:
00062               rs->sr_text = "internal error";
00063               send_ldap_result( op, rs );
00064               return rs->sr_err;
00065        }
00066 
00067        rtxn = moi->moi_txn;
00068 
00069        /* get entry with reader lock */
00070        rs->sr_err = mdb_dn2entry( op, rtxn, NULL, &op->o_req_ndn, &e, 0 );
00071 
00072        switch(rs->sr_err) {
00073        case MDB_NOTFOUND:
00074               rs->sr_err = LDAP_INVALID_CREDENTIALS;
00075               goto done;
00076        case 0:
00077               break;
00078        case LDAP_BUSY:
00079               rs->sr_text = "ldap_server_busy";
00080               goto done;
00081        default:
00082               rs->sr_err = LDAP_OTHER;
00083               rs->sr_text = "internal error";
00084               goto done;
00085        }
00086 
00087        ber_dupbv( &op->oq_bind.rb_edn, &e->e_name );
00088 
00089        /* check for deleted */
00090        if ( is_entry_subentry( e ) ) {
00091               /* entry is an subentry, don't allow bind */
00092               Debug( LDAP_DEBUG_TRACE, "entry is subentry\n", 0,
00093                      0, 0 );
00094               rs->sr_err = LDAP_INVALID_CREDENTIALS;
00095               goto done;
00096        }
00097 
00098        if ( is_entry_alias( e ) ) {
00099               /* entry is an alias, don't allow bind */
00100               Debug( LDAP_DEBUG_TRACE, "entry is alias\n", 0, 0, 0 );
00101               rs->sr_err = LDAP_INVALID_CREDENTIALS;
00102               goto done;
00103        }
00104 
00105        if ( is_entry_referral( e ) ) {
00106               Debug( LDAP_DEBUG_TRACE, "entry is referral\n", 0,
00107                      0, 0 );
00108               rs->sr_err = LDAP_INVALID_CREDENTIALS;
00109               goto done;
00110        }
00111 
00112        switch ( op->oq_bind.rb_method ) {
00113        case LDAP_AUTH_SIMPLE:
00114               a = attr_find( e->e_attrs, password );
00115               if ( a == NULL ) {
00116                      rs->sr_err = LDAP_INVALID_CREDENTIALS;
00117                      goto done;
00118               }
00119 
00120               if ( slap_passwd_check( op, e, a, &op->oq_bind.rb_cred,
00121                                    &rs->sr_text ) != 0 )
00122               {
00123                      /* failure; stop front end from sending result */
00124                      rs->sr_err = LDAP_INVALID_CREDENTIALS;
00125                      goto done;
00126               }
00127                      
00128               rs->sr_err = 0;
00129               break;
00130 
00131        default:
00132               assert( 0 ); /* should not be reachable */
00133               rs->sr_err = LDAP_STRONG_AUTH_NOT_SUPPORTED;
00134               rs->sr_text = "authentication method not supported";
00135        }
00136 
00137 done:
00138        if ( moi == &opinfo ) {
00139               mdb_txn_reset( moi->moi_txn );
00140               LDAP_SLIST_REMOVE( &op->o_extra, &moi->moi_oe, OpExtra, oe_next );
00141        }
00142        /* free entry and reader lock */
00143        if( e != NULL ) {
00144               mdb_entry_return( op, e );
00145        }
00146 
00147        if ( rs->sr_err ) {
00148               send_ldap_result( op, rs );
00149               if ( rs->sr_ref ) {
00150                      ber_bvarray_free( rs->sr_ref );
00151                      rs->sr_ref = NULL;
00152               }
00153        }
00154        /* front end will send result on success (rs->sr_err==0) */
00155        return rs->sr_err;
00156 }