1 /* $NetBSD: bind.c,v 1.3 2021/08/14 16:15:00 christos Exp $ */
2
3 /* bind.c - mdb backend bind routine */
4 /* $OpenLDAP$ */
5 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
6 *
7 * Copyright 2000-2021 The OpenLDAP Foundation.
8 * All rights reserved.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted only as authorized by the OpenLDAP
12 * Public License.
13 *
14 * A copy of this license is available in the file LICENSE in the
15 * top-level directory of the distribution or, alternatively, at
16 * <http://www.OpenLDAP.org/license.html>.
17 */
18
19 #include <sys/cdefs.h>
20 __RCSID("$NetBSD: bind.c,v 1.3 2021/08/14 16:15:00 christos Exp $");
21
22 #include "portable.h"
23
24 #include <stdio.h>
25 #include <ac/string.h>
26 #include <ac/unistd.h>
27
28 #include "back-mdb.h"
29
30 int
mdb_bind(Operation * op,SlapReply * rs)31 mdb_bind( Operation *op, SlapReply *rs )
32 {
33 struct mdb_info *mdb = (struct mdb_info *) op->o_bd->be_private;
34 Entry *e;
35 Attribute *a;
36
37 AttributeDescription *password = slap_schema.si_ad_userPassword;
38
39 MDB_txn *rtxn;
40 mdb_op_info opinfo = {{{0}}}, *moi = &opinfo;
41
42 Debug( LDAP_DEBUG_ARGS,
43 "==> " LDAP_XSTRING(mdb_bind) ": dn: %s\n",
44 op->o_req_dn.bv_val );
45
46 /* allow noauth binds */
47 switch ( be_rootdn_bind( op, NULL ) ) {
48 case LDAP_SUCCESS:
49 /* frontend will send result */
50 return rs->sr_err = LDAP_SUCCESS;
51
52 default:
53 /* give the database a chance */
54 /* NOTE: this behavior departs from that of other backends,
55 * since the others, in case of password checking failure
56 * do not give the database a chance. If an entry with
57 * rootdn's name does not exist in the database the result
58 * will be the same. See ITS#4962 for discussion. */
59 break;
60 }
61
62 rs->sr_err = mdb_opinfo_get(op, mdb, 1, &moi);
63 switch(rs->sr_err) {
64 case 0:
65 break;
66 default:
67 rs->sr_text = "internal error";
68 send_ldap_result( op, rs );
69 return rs->sr_err;
70 }
71
72 rtxn = moi->moi_txn;
73
74 /* get entry with reader lock */
75 rs->sr_err = mdb_dn2entry( op, rtxn, NULL, &op->o_req_ndn, &e, NULL, 0 );
76
77 switch(rs->sr_err) {
78 case MDB_NOTFOUND:
79 rs->sr_err = LDAP_INVALID_CREDENTIALS;
80 goto done;
81 case 0:
82 break;
83 case LDAP_BUSY:
84 rs->sr_text = "ldap_server_busy";
85 goto done;
86 default:
87 rs->sr_err = LDAP_OTHER;
88 rs->sr_text = "internal error";
89 goto done;
90 }
91
92 ber_dupbv( &op->oq_bind.rb_edn, &e->e_name );
93
94 /* check for deleted */
95 if ( is_entry_subentry( e ) ) {
96 /* entry is an subentry, don't allow bind */
97 Debug( LDAP_DEBUG_TRACE, "entry is subentry\n" );
98 rs->sr_err = LDAP_INVALID_CREDENTIALS;
99 goto done;
100 }
101
102 if ( is_entry_alias( e ) ) {
103 /* entry is an alias, don't allow bind */
104 Debug( LDAP_DEBUG_TRACE, "entry is alias\n" );
105 rs->sr_err = LDAP_INVALID_CREDENTIALS;
106 goto done;
107 }
108
109 if ( is_entry_referral( e ) ) {
110 Debug( LDAP_DEBUG_TRACE, "entry is referral\n" );
111 rs->sr_err = LDAP_INVALID_CREDENTIALS;
112 goto done;
113 }
114
115 switch ( op->oq_bind.rb_method ) {
116 case LDAP_AUTH_SIMPLE:
117 a = attr_find( e->e_attrs, password );
118 if ( a == NULL ) {
119 rs->sr_err = LDAP_INVALID_CREDENTIALS;
120 goto done;
121 }
122
123 if ( slap_passwd_check( op, e, a, &op->oq_bind.rb_cred,
124 &rs->sr_text ) != 0 )
125 {
126 /* failure; stop front end from sending result */
127 rs->sr_err = LDAP_INVALID_CREDENTIALS;
128 goto done;
129 }
130
131 rs->sr_err = 0;
132 break;
133
134 default:
135 assert( 0 ); /* should not be reachable */
136 rs->sr_err = LDAP_STRONG_AUTH_NOT_SUPPORTED;
137 rs->sr_text = "authentication method not supported";
138 }
139
140 done:
141 if ( moi == &opinfo ) {
142 mdb_txn_reset( moi->moi_txn );
143 LDAP_SLIST_REMOVE( &op->o_extra, &moi->moi_oe, OpExtra, oe_next );
144 } else {
145 moi->moi_ref--;
146 }
147 /* free entry and reader lock */
148 if( e != NULL ) {
149 mdb_entry_return( op, e );
150 }
151
152 if ( rs->sr_err ) {
153 send_ldap_result( op, rs );
154 if ( rs->sr_ref ) {
155 ber_bvarray_free( rs->sr_ref );
156 rs->sr_ref = NULL;
157 }
158 }
159 /* front end will send result on success (rs->sr_err==0) */
160 return rs->sr_err;
161 }
162