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