]> git.sur5r.net Git - openldap/blob - servers/slapd/back-ldbm/bind.c
Added mixed-case as well as up-cased DN argument. The behavior of back-bdb2
[openldap] / servers / slapd / back-ldbm / bind.c
1 /* bind.c - ldbm backend bind and unbind routines */
2 /* $OpenLDAP$ */
3 /*
4  * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
5  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
6  */
7
8 #include "portable.h"
9
10 #include <stdio.h>
11
12 #include <ac/krb.h>
13 #include <ac/socket.h>
14 #include <ac/string.h>
15 #include <ac/unistd.h>
16
17 #include "slap.h"
18 #include "back-ldbm.h"
19 #include "proto-back-ldbm.h"
20
21 #include <lutil.h>
22
23 #ifdef HAVE_KERBEROS
24 extern int      krbv4_ldap_auth();
25 #endif
26
27 static int
28 crypted_value_find(
29         struct berval       **vals,
30         struct berval       *v,
31         int                 syntax,
32         int                 normalize,
33         struct berval           *cred
34 )
35 {
36         int     i;
37         for ( i = 0; vals[i] != NULL; i++ ) {
38                 if ( syntax != SYNTAX_BIN ) {
39                         int result;
40
41 #ifdef SLAPD_CRYPT
42                         ldap_pvt_thread_mutex_lock( &crypt_mutex );
43 #endif
44
45                         result = lutil_passwd(
46                                 (char*) cred->bv_val,
47                                 (char*) vals[i]->bv_val,
48                                 NULL );
49
50 #ifdef SLAPD_CRYPT
51                         ldap_pvt_thread_mutex_unlock( &crypt_mutex );
52 #endif
53
54                         return result;
55
56                 } else {
57                 if ( value_cmp( vals[i], v, syntax, normalize ) == 0 ) {
58                         return( 0 );
59                 }
60         }
61         }
62
63         return( 1 );
64 }
65
66 int
67 ldbm_back_bind(
68     Backend             *be,
69     Connection          *conn,
70     Operation           *op,
71     char                *dn,
72     char                *ndn,
73     int                 method,
74         char            *mech,
75     struct berval       *cred,
76         char**  edn
77 )
78 {
79         struct ldbminfo *li = (struct ldbminfo *) be->be_private;
80         Entry           *e;
81         Attribute       *a;
82         int             rc;
83         Entry           *matched;
84 #ifdef HAVE_KERBEROS
85         char            krbname[MAX_K_NAME_SZ + 1];
86         AUTH_DAT        ad;
87 #endif
88
89         Debug(LDAP_DEBUG_ARGS, "==> ldbm_back_bind: dn: %s\n", dn, 0, 0);
90
91         *edn = NULL;
92         dn = ndn;
93
94         /* get entry with reader lock */
95         if ( (e = dn2entry_r( be, dn, &matched )) == NULL ) {
96                 char *matched_dn = NULL;
97                 struct berval **refs = NULL;
98
99                 if( matched != NULL ) {
100                         matched_dn = ch_strdup( matched->e_dn );
101
102                         refs = is_entry_referral( matched )
103                                 ? get_entry_referrals( be, conn, op, matched )
104                                 : NULL;
105
106                         cache_return_entry_r( &li->li_cache, matched );
107                 } else {
108                         refs = default_referral;
109                 }
110
111                 /* allow noauth binds */
112                 rc = 1;
113                 if ( method == LDAP_AUTH_SIMPLE ) {
114                         if( cred->bv_len == 0 ) {
115                                 /* SUCCESS */
116                                 send_ldap_result( conn, op, LDAP_SUCCESS,
117                                         NULL, NULL, NULL, NULL );
118
119                         } else if ( be_isroot_pw( be, dn, cred ) ) {
120                                 *edn = ch_strdup( be_root_dn( be ) );
121                                 rc = 0; /* front end will send result */
122
123                         } else {
124                                 send_ldap_result( conn, op, LDAP_REFERRAL,
125                                         matched_dn, NULL, refs, NULL );
126                         }
127
128                 } else if ( method == LDAP_AUTH_SASL ) {
129                         if( mech != NULL && strcasecmp(mech,"DIGEST-MD5") == 0 ) {
130                                 /* insert DIGEST calls here */
131                                 send_ldap_result( conn, op, LDAP_AUTH_METHOD_NOT_SUPPORTED,
132                                         NULL, NULL, NULL, NULL );
133                                 
134                         } else {
135                                 send_ldap_result( conn, op, LDAP_AUTH_METHOD_NOT_SUPPORTED,
136                                         NULL, NULL, NULL, NULL );
137                         }
138
139                 } else {
140                         send_ldap_result( conn, op, LDAP_REFERRAL,
141                                 matched_dn, NULL, refs, NULL );
142                 }
143
144                 if ( matched != NULL ) {
145                         ber_bvecfree( refs );
146                         free( matched_dn );
147                 }
148                 return( rc );
149         }
150
151         *edn = ch_strdup( e->e_dn );
152
153         /* check for deleted */
154
155         if ( ! access_allowed( be, conn, op, e,
156                 "entry", NULL, ACL_AUTH ) )
157         {
158                 send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
159                         NULL, NULL, NULL, NULL );
160                 rc = 1;
161                 goto return_results;
162         }
163
164         if ( is_entry_alias( e ) ) {
165                 /* entry is an alias, don't allow bind */
166                 Debug( LDAP_DEBUG_TRACE, "entry is alias\n", 0,
167                     0, 0 );
168
169                 send_ldap_result( conn, op, LDAP_ALIAS_PROBLEM,
170                     NULL, NULL, NULL, NULL );
171
172                 rc = 1;
173                 goto return_results;
174         }
175
176         if ( is_entry_referral( e ) ) {
177                 /* entry is a referral, don't allow bind */
178                 struct berval **refs = get_entry_referrals( be,
179                         conn, op, e );
180
181                 Debug( LDAP_DEBUG_TRACE, "entry is referral\n", 0,
182                     0, 0 );
183
184                 send_ldap_result( conn, op, LDAP_REFERRAL,
185                     e->e_dn, NULL, refs, NULL );
186
187                 ber_bvecfree( refs );
188
189                 rc = 1;
190                 goto return_results;
191         }
192
193         switch ( method ) {
194         case LDAP_AUTH_SIMPLE:
195                 if ( cred->bv_len == 0 ) {
196                         send_ldap_result( conn, op, LDAP_SUCCESS,
197                                 NULL, NULL, NULL, NULL );
198
199                         /* stop front end from sending result */
200                         rc = 1;
201                         goto return_results;
202                 } 
203
204                 /* check for root dn/passwd */
205                 if ( be_isroot_pw( be, dn, cred ) ) {
206                         /* front end will send result */
207                         if(*edn != NULL) free( *edn );
208                         *edn = ch_strdup( be_root_dn( be ) );
209                         rc = 0;
210                         goto return_results;
211                 }
212
213                 if ( ! access_allowed( be, conn, op, e,
214                         "userpassword", NULL, ACL_AUTH ) )
215                 {
216                         send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
217                                 NULL, NULL, NULL, NULL );
218                         rc = 1;
219                         goto return_results;
220                 }
221
222                 if ( (a = attr_find( e->e_attrs, "userpassword" )) == NULL ) {
223                         send_ldap_result( conn, op, LDAP_INAPPROPRIATE_AUTH,
224                             NULL, NULL, NULL, NULL );
225
226                         /* stop front end from sending result */
227                         rc = 1;
228                         goto return_results;
229                 }
230
231                 if ( crypted_value_find( a->a_vals, cred, a->a_syntax, 0, cred ) != 0 )
232                 {
233                         send_ldap_result( conn, op, LDAP_INVALID_CREDENTIALS,
234                                 NULL, NULL, NULL, NULL );
235                         /* stop front end from sending result */
236                         rc = 1;
237                         goto return_results;
238                 }
239
240                 rc = 0;
241                 break;
242
243 #ifdef HAVE_KERBEROS
244         case LDAP_AUTH_KRBV41:
245                 if ( ! access_allowed( be, conn, op, e,
246                         "krbname", NULL, ACL_AUTH ) )
247                 {
248                         send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
249                                 NULL, NULL, NULL, NULL );
250                         rc = 1;
251                         goto return_results;
252                 }
253
254                 if ( krbv4_ldap_auth( be, cred, &ad ) != LDAP_SUCCESS ) {
255                         send_ldap_result( conn, op, LDAP_INVALID_CREDENTIALS,
256                             NULL, NULL, NULL, NULL );
257                         rc = 1;
258                         goto return_results;
259                 }
260
261                 if ( ! access_allowed( be, conn, op, e,
262                         "krbname", NULL, ACL_AUTH ) )
263                 {
264                         send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
265                                 NULL, NULL, NULL, NULL );
266                         rc = 1;
267                         goto return_results;
268                 }
269
270                 sprintf( krbname, "%s%s%s@%s", ad.pname, *ad.pinst ? "."
271                     : "", ad.pinst, ad.prealm );
272
273
274                 if ( (a = attr_find( e->e_attrs, "krbname" )) == NULL ) {
275                         /*
276                          * no krbName values present:  check against DN
277                          */
278                         if ( strcasecmp( dn, krbname ) == 0 ) {
279                                 rc = 0;
280                                 break;
281                         }
282                         send_ldap_result( conn, op, LDAP_INAPPROPRIATE_AUTH,
283                             NULL, NULL, NULL, NULL );
284                         rc = 1;
285                         goto return_results;
286
287                 } else {        /* look for krbName match */
288                         struct berval   krbval;
289
290                         krbval.bv_val = krbname;
291                         krbval.bv_len = strlen( krbname );
292
293                         if ( value_find( a->a_vals, &krbval, a->a_syntax, 3 ) != 0 ) {
294                                 send_ldap_result( conn, op,
295                                     LDAP_INVALID_CREDENTIALS,
296                                         NULL, NULL, NULL, NULL );
297                                 rc = 1;
298                                 goto return_results;
299                         }
300                 }
301                 rc = 0;
302                 break;
303
304         case LDAP_AUTH_KRBV42:
305                 send_ldap_result( conn, op, LDAP_SUCCESS,
306                         NULL, NULL, NULL, NULL );
307                 /* stop front end from sending result */
308                 rc = 1;
309                 goto return_results;
310 #endif
311
312         case LDAP_AUTH_SASL:
313                 /* insert SASL code here */
314
315         default:
316                 send_ldap_result( conn, op, LDAP_STRONG_AUTH_NOT_SUPPORTED,
317                     NULL, "auth method not supported", NULL, NULL );
318                 rc = 1;
319                 goto return_results;
320         }
321
322 return_results:;
323         /* free entry and reader lock */
324         cache_return_entry_r( &li->li_cache, e );
325
326         /* front end with send result on success (rc==0) */
327         return( rc );
328 }
329