Back to index

openldap  2.4.31
bind.cpp
Go to the documentation of this file.
00001 /* bind.cpp - ndb backend bind routine */
00002 /* $OpenLDAP$ */
00003 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
00004  *
00005  * Copyright 2008-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 /* ACKNOWLEDGEMENTS:
00017  * This work was initially developed by Howard Chu for inclusion
00018  * in OpenLDAP Software. This work was sponsored by MySQL.
00019  */
00020 
00021 #include "portable.h"
00022 
00023 #include <stdio.h>
00024 #include <ac/string.h>
00025 #include <ac/unistd.h>
00026 
00027 #include "back-ndb.h"
00028 
00029 extern "C" int
00030 ndb_back_bind( Operation *op, SlapReply *rs )
00031 {
00032        struct ndb_info *ni = (struct ndb_info *) op->o_bd->be_private;
00033        Entry         e = {0};
00034        Attribute     *a;
00035 
00036        AttributeDescription *password = slap_schema.si_ad_userPassword;
00037 
00038        NdbArgs NA;
00039 
00040        Debug( LDAP_DEBUG_ARGS,
00041               "==> " LDAP_XSTRING(ndb_back_bind) ": dn: %s\n",
00042               op->o_req_dn.bv_val, 0, 0);
00043 
00044        /* allow noauth binds */
00045        switch ( be_rootdn_bind( op, NULL ) ) {
00046        case LDAP_SUCCESS:
00047               /* frontend will send result */
00048               return rs->sr_err = LDAP_SUCCESS;
00049 
00050        default:
00051               /* give the database a chance */
00052               break;
00053        }
00054 
00055        /* Get our NDB handle */
00056        rs->sr_err = ndb_thread_handle( op, &NA.ndb );
00057 
00058        e.e_name = op->o_req_dn;
00059        e.e_nname = op->o_req_ndn;
00060        NA.e = &e;
00061 
00062 dn2entry_retry:
00063        NA.txn = NA.ndb->startTransaction();
00064        rs->sr_text = NULL;
00065        if( !NA.txn ) {
00066               Debug( LDAP_DEBUG_TRACE,
00067                      LDAP_XSTRING(ndb_back_bind) ": startTransaction failed: %s (%d)\n",
00068                      NA.ndb->getNdbError().message, NA.ndb->getNdbError().code, 0 );
00069               rs->sr_err = LDAP_OTHER;
00070               rs->sr_text = "internal error";
00071               goto done;
00072        }
00073 
00074        /* get entry */
00075        {
00076               NdbRdns rdns;
00077               rdns.nr_num = 0;
00078               NA.rdns = &rdns;
00079               NA.ocs = NULL;
00080               rs->sr_err = ndb_entry_get_info( op, &NA, 0, NULL );
00081        }
00082        switch(rs->sr_err) {
00083        case 0:
00084               break;
00085        case LDAP_NO_SUCH_OBJECT:
00086               rs->sr_err = LDAP_INVALID_CREDENTIALS;
00087               goto done;
00088        case LDAP_BUSY:
00089               rs->sr_text = "ldap_server_busy";
00090               goto done;
00091 #if 0
00092        case DB_LOCK_DEADLOCK:
00093        case DB_LOCK_NOTGRANTED:
00094               goto dn2entry_retry;
00095 #endif
00096        default:
00097               rs->sr_err = LDAP_OTHER;
00098               rs->sr_text = "internal error";
00099               goto done;
00100        }
00101 
00102        rs->sr_err = ndb_entry_get_data( op, &NA, 0 );
00103        ber_bvarray_free_x( NA.ocs, op->o_tmpmemctx );
00104        ber_dupbv( &op->oq_bind.rb_edn, &e.e_name );
00105 
00106        /* check for deleted */
00107        if ( is_entry_subentry( &e ) ) {
00108               /* entry is an subentry, don't allow bind */
00109               Debug( LDAP_DEBUG_TRACE, "entry is subentry\n", 0,
00110                      0, 0 );
00111               rs->sr_err = LDAP_INVALID_CREDENTIALS;
00112               goto done;
00113        }
00114 
00115        if ( is_entry_alias( &e ) ) {
00116               /* entry is an alias, don't allow bind */
00117               Debug( LDAP_DEBUG_TRACE, "entry is alias\n", 0, 0, 0 );
00118               rs->sr_err = LDAP_INVALID_CREDENTIALS;
00119               goto done;
00120        }
00121 
00122        if ( is_entry_referral( &e ) ) {
00123               Debug( LDAP_DEBUG_TRACE, "entry is referral\n", 0,
00124                      0, 0 );
00125               rs->sr_err = LDAP_INVALID_CREDENTIALS;
00126               goto done;
00127        }
00128 
00129        switch ( op->oq_bind.rb_method ) {
00130        case LDAP_AUTH_SIMPLE:
00131               a = attr_find( e.e_attrs, password );
00132               if ( a == NULL ) {
00133                      rs->sr_err = LDAP_INVALID_CREDENTIALS;
00134                      goto done;
00135               }
00136 
00137               if ( slap_passwd_check( op, &e, a, &op->oq_bind.rb_cred,
00138                                    &rs->sr_text ) != 0 )
00139               {
00140                      /* failure; stop front end from sending result */
00141                      rs->sr_err = LDAP_INVALID_CREDENTIALS;
00142                      goto done;
00143               }
00144                      
00145               rs->sr_err = 0;
00146               break;
00147 
00148        default:
00149               assert( 0 ); /* should not be reachable */
00150               rs->sr_err = LDAP_STRONG_AUTH_NOT_SUPPORTED;
00151               rs->sr_text = "authentication method not supported";
00152        }
00153 
00154 done:
00155        NA.txn->close();
00156        if ( e.e_attrs ) {
00157               attrs_free( e.e_attrs );
00158               e.e_attrs = NULL;
00159        }
00160        if ( rs->sr_err ) {
00161               send_ldap_result( op, rs );
00162        }
00163        /* front end will send result on success (rs->sr_err==0) */
00164        return rs->sr_err;
00165 }