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