1/* bind.cpp - ndb backend bind routine */ 2/* OpenLDAP: pkg/ldap/servers/slapd/back-ndb/bind.cpp,v 1.3.2.3 2010/04/13 20:23:34 kurt Exp */ 3/* This work is part of OpenLDAP Software <http://www.openldap.org/>. 4 * 5 * Copyright 2008-2010 The OpenLDAP Foundation. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted only as authorized by the OpenLDAP 10 * Public License. 11 * 12 * A copy of this license is available in the file LICENSE in the 13 * top-level directory of the distribution or, alternatively, at 14 * <http://www.OpenLDAP.org/license.html>. 15 */ 16/* ACKNOWLEDGEMENTS: 17 * This work was initially developed by Howard Chu for inclusion 18 * in OpenLDAP Software. This work was sponsored by MySQL. 19 */ 20 21#include "portable.h" 22 23#include <stdio.h> 24#include <ac/string.h> 25#include <ac/unistd.h> 26 27#include "back-ndb.h" 28 29extern "C" int 30ndb_back_bind( Operation *op, SlapReply *rs ) 31{ 32 struct ndb_info *ni = (struct ndb_info *) op->o_bd->be_private; 33 Entry e = {0}; 34 Attribute *a; 35 36 AttributeDescription *password = slap_schema.si_ad_userPassword; 37 38 NdbArgs NA; 39 40 Debug( LDAP_DEBUG_ARGS, 41 "==> " LDAP_XSTRING(ndb_back_bind) ": dn: %s\n", 42 op->o_req_dn.bv_val, 0, 0); 43 44 /* allow noauth binds */ 45 switch ( be_rootdn_bind( op, NULL ) ) { 46 case SLAP_CB_CONTINUE: 47 break; 48 49 default: 50 return rs->sr_err; 51 } 52 53 /* Get our NDB handle */ 54 rs->sr_err = ndb_thread_handle( op, &NA.ndb ); 55 56 e.e_name = op->o_req_dn; 57 e.e_nname = op->o_req_ndn; 58 NA.e = &e; 59 60dn2entry_retry: 61 NA.txn = NA.ndb->startTransaction(); 62 rs->sr_text = NULL; 63 if( !NA.txn ) { 64 Debug( LDAP_DEBUG_TRACE, 65 LDAP_XSTRING(ndb_back_bind) ": startTransaction failed: %s (%d)\n", 66 NA.ndb->getNdbError().message, NA.ndb->getNdbError().code, 0 ); 67 rs->sr_err = LDAP_OTHER; 68 rs->sr_text = "internal error"; 69 goto done; 70 } 71 72 /* get entry */ 73 { 74 NdbRdns rdns; 75 rdns.nr_num = 0; 76 NA.rdns = &rdns; 77 NA.ocs = NULL; 78 rs->sr_err = ndb_entry_get_info( op, &NA, 0, NULL ); 79 } 80 switch(rs->sr_err) { 81 case 0: 82 break; 83 case LDAP_NO_SUCH_OBJECT: 84 rs->sr_err = LDAP_INVALID_CREDENTIALS; 85 goto done; 86 case LDAP_BUSY: 87 rs->sr_text = "ldap_server_busy"; 88 goto done; 89#if 0 90 case DB_LOCK_DEADLOCK: 91 case DB_LOCK_NOTGRANTED: 92 goto dn2entry_retry; 93#endif 94 default: 95 rs->sr_err = LDAP_OTHER; 96 rs->sr_text = "internal error"; 97 goto done; 98 } 99 100 rs->sr_err = ndb_entry_get_data( op, &NA, 0 ); 101 ber_bvarray_free_x( NA.ocs, op->o_tmpmemctx ); 102 ber_dupbv( &op->oq_bind.rb_edn, &e.e_name ); 103 104 /* check for deleted */ 105 if ( is_entry_subentry( &e ) ) { 106 /* entry is an subentry, don't allow bind */ 107 Debug( LDAP_DEBUG_TRACE, "entry is subentry\n", 0, 108 0, 0 ); 109 rs->sr_err = LDAP_INVALID_CREDENTIALS; 110 goto done; 111 } 112 113 if ( is_entry_alias( &e ) ) { 114 /* entry is an alias, don't allow bind */ 115 Debug( LDAP_DEBUG_TRACE, "entry is alias\n", 0, 0, 0 ); 116 rs->sr_err = LDAP_INVALID_CREDENTIALS; 117 goto done; 118 } 119 120 if ( is_entry_referral( &e ) ) { 121 Debug( LDAP_DEBUG_TRACE, "entry is referral\n", 0, 122 0, 0 ); 123 rs->sr_err = LDAP_INVALID_CREDENTIALS; 124 goto done; 125 } 126 127 switch ( op->oq_bind.rb_method ) { 128 case LDAP_AUTH_SIMPLE: 129 a = attr_find( e.e_attrs, password ); 130 if ( a == NULL ) { 131 rs->sr_err = LDAP_INVALID_CREDENTIALS; 132 goto done; 133 } 134 135 if ( slap_passwd_check( op, &e, a, &op->oq_bind.rb_cred, 136 &rs->sr_text ) != 0 ) 137 { 138 /* failure; stop front end from sending result */ 139 rs->sr_err = LDAP_INVALID_CREDENTIALS; 140 goto done; 141 } 142 143 rs->sr_err = 0; 144 break; 145 146 default: 147 assert( 0 ); /* should not be reachable */ 148 rs->sr_err = LDAP_STRONG_AUTH_NOT_SUPPORTED; 149 rs->sr_text = "authentication method not supported"; 150 } 151 152done: 153 NA.txn->close(); 154 if ( e.e_attrs ) { 155 attrs_free( e.e_attrs ); 156 e.e_attrs = NULL; 157 } 158 if ( rs->sr_err ) { 159 send_ldap_result( op, rs ); 160 } 161 /* front end will send result on success (rs->sr_err==0) */ 162 return rs->sr_err; 163} 164