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