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