]> git.sur5r.net Git - openldap/blob - servers/slapd/back-ldbm/bind.c
reduce slap_passwd_check to simple form
[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, cred ) != 0 ) {
201                         send_ldap_result( conn, op, LDAP_INVALID_CREDENTIALS,
202                                 NULL, NULL, NULL, NULL );
203                         /* stop front end from sending result */
204                         rc = 1;
205                         goto return_results;
206                 }
207
208                 rc = 0;
209                 break;
210
211 #ifdef HAVE_KERBEROS
212         case LDAP_AUTH_KRBV41:
213                 if ( ! access_allowed( be, conn, op, e,
214                         "krbname", NULL, ACL_AUTH ) )
215                 {
216                         send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
217                                 NULL, NULL, NULL, NULL );
218                         rc = 1;
219                         goto return_results;
220                 }
221
222                 if ( krbv4_ldap_auth( be, cred, &ad ) != LDAP_SUCCESS ) {
223                         send_ldap_result( conn, op, LDAP_INVALID_CREDENTIALS,
224                             NULL, NULL, NULL, NULL );
225                         rc = 1;
226                         goto return_results;
227                 }
228
229                 if ( ! access_allowed( be, conn, op, e,
230                         "krbname", NULL, ACL_AUTH ) )
231                 {
232                         send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
233                                 NULL, NULL, NULL, NULL );
234                         rc = 1;
235                         goto return_results;
236                 }
237
238                 sprintf( krbname, "%s%s%s@%s", ad.pname, *ad.pinst ? "."
239                     : "", ad.pinst, ad.prealm );
240
241
242                 if ( (a = attr_find( e->e_attrs, "krbname" )) == NULL ) {
243                         /*
244                          * no krbName values present:  check against DN
245                          */
246                         if ( strcasecmp( dn, krbname ) == 0 ) {
247                                 rc = 0;
248                                 break;
249                         }
250                         send_ldap_result( conn, op, LDAP_INAPPROPRIATE_AUTH,
251                             NULL, NULL, NULL, NULL );
252                         rc = 1;
253                         goto return_results;
254
255                 } else {        /* look for krbName match */
256                         struct berval   krbval;
257
258                         krbval.bv_val = krbname;
259                         krbval.bv_len = strlen( krbname );
260
261                         if ( value_find( a->a_vals, &krbval, a->a_syntax, 3 ) != 0 ) {
262                                 send_ldap_result( conn, op,
263                                     LDAP_INVALID_CREDENTIALS,
264                                         NULL, NULL, NULL, NULL );
265                                 rc = 1;
266                                 goto return_results;
267                         }
268                 }
269                 rc = 0;
270                 break;
271
272         case LDAP_AUTH_KRBV42:
273                 send_ldap_result( conn, op, LDAP_SUCCESS,
274                         NULL, NULL, NULL, NULL );
275                 /* stop front end from sending result */
276                 rc = 1;
277                 goto return_results;
278 #endif
279
280         case LDAP_AUTH_SASL:
281                 /* insert SASL code here */
282
283         default:
284                 send_ldap_result( conn, op, LDAP_STRONG_AUTH_NOT_SUPPORTED,
285                     NULL, "auth method not supported", NULL, NULL );
286                 rc = 1;
287                 goto return_results;
288         }
289
290 return_results:;
291         /* free entry and reader lock */
292         cache_return_entry_r( &li->li_cache, e );
293
294         /* front end with send result on success (rc==0) */
295         return( rc );
296 }
297