]> git.sur5r.net Git - openldap/blob - servers/slapd/back-ldbm/bind.c
Add OpenLDAP RCSid to *.[ch] in clients, libraries, and servers.
[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     int                 method,
73         char            *mech,
74     struct berval       *cred,
75         char**  edn
76 )
77 {
78         struct ldbminfo *li = (struct ldbminfo *) be->be_private;
79         Entry           *e;
80         Attribute       *a;
81         int             rc;
82         Entry           *matched;
83 #ifdef HAVE_KERBEROS
84         char            krbname[MAX_K_NAME_SZ + 1];
85         AUTH_DAT        ad;
86 #endif
87
88         Debug(LDAP_DEBUG_ARGS, "==> ldbm_back_bind: dn: %s\n", dn, 0, 0);
89
90         *edn = NULL;
91
92         /* get entry with reader lock */
93         if ( (e = dn2entry_r( be, dn, &matched )) == NULL ) {
94                 char *matched_dn = NULL;
95                 struct berval **refs = NULL;
96
97                 if( matched != NULL ) {
98                         matched_dn = ch_strdup( matched->e_dn );
99
100                         refs = is_entry_referral( matched )
101                                 ? get_entry_referrals( be, conn, op, matched )
102                                 : NULL;
103
104                         cache_return_entry_r( &li->li_cache, matched );
105                 } else {
106                         refs = default_referral;
107                 }
108
109                 /* allow noauth binds */
110                 rc = 1;
111                 if ( method == LDAP_AUTH_SIMPLE ) {
112                         if( cred->bv_len == 0 ) {
113                                 /* SUCCESS */
114                                 send_ldap_result( conn, op, LDAP_SUCCESS,
115                                         NULL, NULL, NULL, NULL );
116
117                         } else if ( be_isroot_pw( be, dn, cred ) ) {
118                                 *edn = ch_strdup( be_root_dn( be ) );
119                                 rc = 0; /* front end will send result */
120
121                         } else {
122                                 send_ldap_result( conn, op, LDAP_REFERRAL,
123                                         matched_dn, NULL, refs, NULL );
124                         }
125
126                 } else if ( method == LDAP_AUTH_SASL ) {
127                         if( mech != NULL && strcasecmp(mech,"DIGEST-MD5") == 0 ) {
128                                 /* insert DIGEST calls here */
129                                 send_ldap_result( conn, op, LDAP_AUTH_METHOD_NOT_SUPPORTED,
130                                         NULL, NULL, NULL, NULL );
131                                 
132                         } else {
133                                 send_ldap_result( conn, op, LDAP_AUTH_METHOD_NOT_SUPPORTED,
134                                         NULL, NULL, NULL, NULL );
135                         }
136
137                 } else {
138                         send_ldap_result( conn, op, LDAP_REFERRAL,
139                                 matched_dn, NULL, refs, NULL );
140                 }
141
142                 if ( matched != NULL ) {
143                         ber_bvecfree( refs );
144                         free( matched_dn );
145                 }
146                 return( rc );
147         }
148
149         *edn = ch_strdup( e->e_dn );
150
151         /* check for deleted */
152
153         if ( ! access_allowed( be, conn, op, e,
154                 "entry", NULL, ACL_AUTH ) )
155         {
156                 send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
157                         NULL, NULL, NULL, NULL );
158                 rc = 1;
159                 goto return_results;
160         }
161
162         if ( is_entry_alias( e ) ) {
163                 /* entry is an alias, don't allow bind */
164                 Debug( LDAP_DEBUG_TRACE, "entry is alias\n", 0,
165                     0, 0 );
166
167                 send_ldap_result( conn, op, LDAP_ALIAS_PROBLEM,
168                     NULL, NULL, NULL, NULL );
169
170                 rc = 1;
171                 goto return_results;
172         }
173
174         if ( is_entry_referral( e ) ) {
175                 /* entry is a referral, don't allow bind */
176                 struct berval **refs = get_entry_referrals( be,
177                         conn, op, e );
178
179                 Debug( LDAP_DEBUG_TRACE, "entry is referral\n", 0,
180                     0, 0 );
181
182                 send_ldap_result( conn, op, LDAP_REFERRAL,
183                     e->e_dn, NULL, refs, NULL );
184
185                 ber_bvecfree( refs );
186
187                 rc = 1;
188                 goto return_results;
189         }
190
191         switch ( method ) {
192         case LDAP_AUTH_SIMPLE:
193                 if ( cred->bv_len == 0 ) {
194                         send_ldap_result( conn, op, LDAP_SUCCESS,
195                                 NULL, NULL, NULL, NULL );
196
197                         /* stop front end from sending result */
198                         rc = 1;
199                         goto return_results;
200                 } 
201
202                 /* check for root dn/passwd */
203                 if ( be_isroot_pw( be, dn, cred ) ) {
204                         /* front end will send result */
205                         if(*edn != NULL) free( *edn );
206                         *edn = ch_strdup( be_root_dn( be ) );
207                         rc = 0;
208                         goto return_results;
209                 }
210
211                 if ( ! access_allowed( be, conn, op, e,
212                         "userpassword", NULL, ACL_AUTH ) )
213                 {
214                         send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
215                                 NULL, NULL, NULL, NULL );
216                         rc = 1;
217                         goto return_results;
218                 }
219
220                 if ( (a = attr_find( e->e_attrs, "userpassword" )) == NULL ) {
221                         send_ldap_result( conn, op, LDAP_INAPPROPRIATE_AUTH,
222                             NULL, NULL, NULL, NULL );
223
224                         /* stop front end from sending result */
225                         rc = 1;
226                         goto return_results;
227                 }
228
229                 if ( crypted_value_find( a->a_vals, cred, a->a_syntax, 0, cred ) != 0 )
230                 {
231                         send_ldap_result( conn, op, LDAP_INVALID_CREDENTIALS,
232                                 NULL, NULL, NULL, NULL );
233                         /* stop front end from sending result */
234                         rc = 1;
235                         goto return_results;
236                 }
237
238                 rc = 0;
239                 break;
240
241 #ifdef HAVE_KERBEROS
242         case LDAP_AUTH_KRBV41:
243                 if ( ! access_allowed( be, conn, op, e,
244                         "krbname", NULL, ACL_AUTH ) )
245                 {
246                         send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
247                                 NULL, NULL, NULL, NULL );
248                         rc = 1;
249                         goto return_results;
250                 }
251
252                 if ( krbv4_ldap_auth( be, cred, &ad ) != LDAP_SUCCESS ) {
253                         send_ldap_result( conn, op, LDAP_INVALID_CREDENTIALS,
254                             NULL, NULL, NULL, NULL );
255                         rc = 1;
256                         goto return_results;
257                 }
258
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                 sprintf( krbname, "%s%s%s@%s", ad.pname, *ad.pinst ? "."
269                     : "", ad.pinst, ad.prealm );
270
271
272                 if ( (a = attr_find( e->e_attrs, "krbname" )) == NULL ) {
273                         /*
274                          * no krbName values present:  check against DN
275                          */
276                         if ( strcasecmp( dn, krbname ) == 0 ) {
277                                 rc = 0;
278                                 break;
279                         }
280                         send_ldap_result( conn, op, LDAP_INAPPROPRIATE_AUTH,
281                             NULL, NULL, NULL, NULL );
282                         rc = 1;
283                         goto return_results;
284
285                 } else {        /* look for krbName match */
286                         struct berval   krbval;
287
288                         krbval.bv_val = krbname;
289                         krbval.bv_len = strlen( krbname );
290
291                         if ( value_find( a->a_vals, &krbval, a->a_syntax, 3 ) != 0 ) {
292                                 send_ldap_result( conn, op,
293                                     LDAP_INVALID_CREDENTIALS,
294                                         NULL, NULL, NULL, NULL );
295                                 rc = 1;
296                                 goto return_results;
297                         }
298                 }
299                 rc = 0;
300                 break;
301
302         case LDAP_AUTH_KRBV42:
303                 send_ldap_result( conn, op, LDAP_SUCCESS,
304                         NULL, NULL, NULL, NULL );
305                 /* stop front end from sending result */
306                 rc = 1;
307                 goto return_results;
308 #endif
309
310         case LDAP_AUTH_SASL:
311                 /* insert SASL code here */
312
313         default:
314                 send_ldap_result( conn, op, LDAP_STRONG_AUTH_NOT_SUPPORTED,
315                     NULL, "auth method not supported", NULL, NULL );
316                 rc = 1;
317                 goto return_results;
318         }
319
320 return_results:;
321         /* free entry and reader lock */
322         cache_return_entry_r( &li->li_cache, e );
323
324         /* front end with send result on success (rc==0) */
325         return( rc );
326 }
327