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