]> git.sur5r.net Git - openldap/blob - servers/slapd/back-ldbm/bind.c
52234e336a97c7b926842b9bfc797c2158b5c90b
[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 if ( refs != NULL ) {
124                                 send_ldap_result( conn, op, LDAP_REFERRAL,
125                                         matched_dn, NULL, refs, NULL );
126
127                         } else {
128                                 send_ldap_result( conn, op, LDAP_INVALID_CREDENTIALS,
129                                         NULL, NULL, NULL, NULL );
130                         }
131
132                 } else if ( method == LDAP_AUTH_SASL ) {
133                         if( mech != NULL && strcasecmp(mech,"DIGEST-MD5") == 0 ) {
134                                 /* insert DIGEST calls here */
135                                 send_ldap_result( conn, op, LDAP_AUTH_METHOD_NOT_SUPPORTED,
136                                         NULL, NULL, NULL, NULL );
137                                 
138                         } else {
139                                 send_ldap_result( conn, op, LDAP_AUTH_METHOD_NOT_SUPPORTED,
140                                         NULL, NULL, NULL, NULL );
141                         }
142
143                 } else if ( refs != NULL ) {
144                         send_ldap_result( conn, op, LDAP_REFERRAL,
145                                 matched_dn, NULL, refs, NULL );
146
147                 } else {
148                         send_ldap_result( conn, op, LDAP_INVALID_CREDENTIALS,
149                                 NULL, NULL, NULL, NULL );
150                 }
151
152                 if ( matched != NULL ) {
153                         ber_bvecfree( refs );
154                         free( matched_dn );
155                 }
156                 return( rc );
157         }
158
159         *edn = ch_strdup( e->e_dn );
160
161         /* check for deleted */
162
163         if ( ! access_allowed( be, conn, op, e,
164                 "entry", NULL, ACL_AUTH ) )
165         {
166                 send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
167                         NULL, NULL, NULL, NULL );
168                 rc = 1;
169                 goto return_results;
170         }
171
172         if ( is_entry_alias( e ) ) {
173                 /* entry is an alias, don't allow bind */
174                 Debug( LDAP_DEBUG_TRACE, "entry is alias\n", 0,
175                     0, 0 );
176
177                 send_ldap_result( conn, op, LDAP_ALIAS_PROBLEM,
178                     NULL, NULL, NULL, NULL );
179
180                 rc = 1;
181                 goto return_results;
182         }
183
184         if ( is_entry_referral( e ) ) {
185                 /* entry is a referral, don't allow bind */
186                 struct berval **refs = get_entry_referrals( be,
187                         conn, op, e );
188
189                 Debug( LDAP_DEBUG_TRACE, "entry is referral\n", 0,
190                     0, 0 );
191
192                 if( refs != NULL ) {
193                         send_ldap_result( conn, op, LDAP_REFERRAL,
194                                 e->e_dn, NULL, refs, NULL );
195
196                 } else {
197                         send_ldap_result( conn, op, LDAP_INVALID_CREDENTIALS,
198                                 NULL, NULL, NULL, NULL );
199                 }
200
201                 ber_bvecfree( refs );
202
203                 rc = 1;
204                 goto return_results;
205         }
206
207         switch ( method ) {
208         case LDAP_AUTH_SIMPLE:
209                 if ( cred->bv_len == 0 ) {
210                         send_ldap_result( conn, op, LDAP_SUCCESS,
211                                 NULL, NULL, NULL, NULL );
212
213                         /* stop front end from sending result */
214                         rc = 1;
215                         goto return_results;
216                 } 
217
218                 /* check for root dn/passwd */
219                 if ( be_isroot_pw( be, dn, cred ) ) {
220                         /* front end will send result */
221                         if(*edn != NULL) free( *edn );
222                         *edn = ch_strdup( be_root_dn( be ) );
223                         rc = 0;
224                         goto return_results;
225                 }
226
227                 if ( ! access_allowed( be, conn, op, e,
228                         "userpassword", NULL, ACL_AUTH ) )
229                 {
230                         send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
231                                 NULL, NULL, NULL, NULL );
232                         rc = 1;
233                         goto return_results;
234                 }
235
236                 if ( (a = attr_find( e->e_attrs, "userpassword" )) == NULL ) {
237                         send_ldap_result( conn, op, LDAP_INAPPROPRIATE_AUTH,
238                             NULL, NULL, NULL, NULL );
239
240                         /* stop front end from sending result */
241                         rc = 1;
242                         goto return_results;
243                 }
244
245                 if ( crypted_value_find( a->a_vals, cred, a->a_syntax, 0, cred ) != 0 )
246                 {
247                         send_ldap_result( conn, op, LDAP_INVALID_CREDENTIALS,
248                                 NULL, NULL, NULL, NULL );
249                         /* stop front end from sending result */
250                         rc = 1;
251                         goto return_results;
252                 }
253
254                 rc = 0;
255                 break;
256
257 #ifdef HAVE_KERBEROS
258         case LDAP_AUTH_KRBV41:
259                 if ( ! access_allowed( be, conn, op, e,
260                         "krbname", NULL, ACL_AUTH ) )
261                 {
262                         send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
263                                 NULL, NULL, NULL, NULL );
264                         rc = 1;
265                         goto return_results;
266                 }
267
268                 if ( krbv4_ldap_auth( be, cred, &ad ) != LDAP_SUCCESS ) {
269                         send_ldap_result( conn, op, LDAP_INVALID_CREDENTIALS,
270                             NULL, NULL, NULL, NULL );
271                         rc = 1;
272                         goto return_results;
273                 }
274
275                 if ( ! access_allowed( be, conn, op, e,
276                         "krbname", NULL, ACL_AUTH ) )
277                 {
278                         send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
279                                 NULL, NULL, NULL, NULL );
280                         rc = 1;
281                         goto return_results;
282                 }
283
284                 sprintf( krbname, "%s%s%s@%s", ad.pname, *ad.pinst ? "."
285                     : "", ad.pinst, ad.prealm );
286
287
288                 if ( (a = attr_find( e->e_attrs, "krbname" )) == NULL ) {
289                         /*
290                          * no krbName values present:  check against DN
291                          */
292                         if ( strcasecmp( dn, krbname ) == 0 ) {
293                                 rc = 0;
294                                 break;
295                         }
296                         send_ldap_result( conn, op, LDAP_INAPPROPRIATE_AUTH,
297                             NULL, NULL, NULL, NULL );
298                         rc = 1;
299                         goto return_results;
300
301                 } else {        /* look for krbName match */
302                         struct berval   krbval;
303
304                         krbval.bv_val = krbname;
305                         krbval.bv_len = strlen( krbname );
306
307                         if ( value_find( a->a_vals, &krbval, a->a_syntax, 3 ) != 0 ) {
308                                 send_ldap_result( conn, op,
309                                     LDAP_INVALID_CREDENTIALS,
310                                         NULL, NULL, NULL, NULL );
311                                 rc = 1;
312                                 goto return_results;
313                         }
314                 }
315                 rc = 0;
316                 break;
317
318         case LDAP_AUTH_KRBV42:
319                 send_ldap_result( conn, op, LDAP_SUCCESS,
320                         NULL, NULL, NULL, NULL );
321                 /* stop front end from sending result */
322                 rc = 1;
323                 goto return_results;
324 #endif
325
326         case LDAP_AUTH_SASL:
327                 /* insert SASL code here */
328
329         default:
330                 send_ldap_result( conn, op, LDAP_STRONG_AUTH_NOT_SUPPORTED,
331                     NULL, "auth method not supported", NULL, NULL );
332                 rc = 1;
333                 goto return_results;
334         }
335
336 return_results:;
337         /* free entry and reader lock */
338         cache_return_entry_r( &li->li_cache, e );
339
340         /* front end with send result on success (rc==0) */
341         return( rc );
342 }
343