]> git.sur5r.net Git - openldap/blob - servers/slapd/back-ldbm/bind.c
Add a default case with assert() just in case.
[openldap] / servers / slapd / back-ldbm / bind.c
1 /* bind.c - ldbm backend bind and unbind routines */
2 /* $OpenLDAP$ */
3 /*
4  * Copyright 1998-2002 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     struct berval       *dn,
27     struct berval       *ndn,
28     int                 method,
29     struct berval       *cred,
30     struct berval       *edn
31 )
32 {
33         struct ldbminfo *li = (struct ldbminfo *) be->be_private;
34         Entry           *e;
35         Attribute       *a;
36         int             rc;
37         Entry           *matched;
38 #ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
39         char            krbname[MAX_K_NAME_SZ + 1];
40         AttributeDescription *krbattr = slap_schema.si_ad_krbName;
41         AUTH_DAT        ad;
42 #endif
43
44         AttributeDescription *password = slap_schema.si_ad_userPassword;
45
46 #ifdef NEW_LOGGING
47         LDAP_LOG(( "backend", LDAP_LEVEL_ENTRY,
48                 "ldbm_back_bind: dn: %s.\n", dn->bv_val ));
49 #else
50         Debug(LDAP_DEBUG_ARGS, "==> ldbm_back_bind: dn: %s\n", dn->bv_val, 0, 0);
51 #endif
52
53
54         dn = ndn;
55
56         /* get entry with reader lock */
57         if ( (e = dn2entry_r( be, dn, &matched )) == NULL ) {
58                 char *matched_dn = NULL;
59                 BerVarray refs = NULL;
60
61                 if( matched != NULL ) {
62                         matched_dn = ch_strdup( matched->e_dn );
63
64                         refs = is_entry_referral( matched )
65                                 ? get_entry_referrals( be, conn, op, matched )
66                                 : NULL;
67
68                         cache_return_entry_r( &li->li_cache, matched );
69
70                 } else {
71                         refs = referral_rewrite( default_referral,
72                                 NULL, dn, LDAP_SCOPE_DEFAULT );
73                 }
74
75                 /* allow noauth binds */
76                 rc = 1;
77                 if ( method == LDAP_AUTH_SIMPLE ) {
78                         if ( be_isroot_pw( be, conn, dn, cred ) ) {
79                                 ber_dupbv( edn, be_root_dn( be ) );
80                                 rc = 0; /* front end will send result */
81
82                         } else if ( refs != NULL ) {
83                                 send_ldap_result( conn, op, LDAP_REFERRAL,
84                                         matched_dn, NULL, refs, NULL );
85
86                         } else {
87                                 send_ldap_result( conn, op, LDAP_INVALID_CREDENTIALS,
88                                         NULL, NULL, NULL, NULL );
89                         }
90
91                 } else if ( refs != NULL ) {
92                         send_ldap_result( conn, op, LDAP_REFERRAL,
93                                 matched_dn, NULL, refs, NULL );
94
95                 } else {
96                         send_ldap_result( conn, op, LDAP_INVALID_CREDENTIALS,
97                                 NULL, NULL, NULL, NULL );
98                 }
99
100                 if ( refs ) ber_bvarray_free( refs );
101                 if ( matched_dn ) free( matched_dn );
102                 return( rc );
103         }
104
105         ber_dupbv( edn, &e->e_name );
106
107         /* check for deleted */
108
109         if ( is_entry_alias( e ) ) {
110                 /* entry is an alias, don't allow bind */
111 #ifdef NEW_LOGGING
112                 LDAP_LOG(( "backend", LDAP_LEVEL_INFO,
113                            "ldbm_back_bind: entry (%s) is an alias.\n", e->e_dn ));
114 #else
115                 Debug( LDAP_DEBUG_TRACE, "entry is alias\n", 0,
116                     0, 0 );
117 #endif
118
119
120                 send_ldap_result( conn, op, LDAP_ALIAS_PROBLEM,
121                     NULL, "entry is alias", NULL, NULL );
122
123                 rc = 1;
124                 goto return_results;
125         }
126
127         if ( is_entry_referral( e ) ) {
128                 /* entry is a referral, don't allow bind */
129                 BerVarray refs = get_entry_referrals( be,
130                         conn, op, e );
131
132 #ifdef NEW_LOGGING
133                 LDAP_LOG(( "backend", LDAP_LEVEL_INFO,
134                            "ldbm_back_bind: entry(%s) is a referral.\n", e->e_dn ));
135 #else
136                 Debug( LDAP_DEBUG_TRACE, "entry is referral\n", 0,
137                     0, 0 );
138 #endif
139
140
141                 if( refs != NULL ) {
142                         send_ldap_result( conn, op, LDAP_REFERRAL,
143                                 e->e_dn, NULL, refs, NULL );
144
145                 } else {
146                         send_ldap_result( conn, op, LDAP_INVALID_CREDENTIALS,
147                                 NULL, NULL, NULL, NULL );
148                 }
149
150                 ber_bvarray_free( refs );
151
152                 rc = 1;
153                 goto return_results;
154         }
155
156         switch ( method ) {
157         case LDAP_AUTH_SIMPLE:
158                 /* check for root dn/passwd */
159                 if ( be_isroot_pw( be, conn, dn, cred ) ) {
160                         /* front end will send result */
161                         if(edn->bv_val != NULL) free( edn->bv_val );
162                         ber_dupbv( edn, be_root_dn( be ) );
163                         rc = 0;
164                         goto return_results;
165                 }
166
167                 if ( ! access_allowed( be, conn, op, e,
168                         password, NULL, ACL_AUTH ) )
169                 {
170                         send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
171                                 NULL, NULL, NULL, NULL );
172                         rc = 1;
173                         goto return_results;
174                 }
175
176                 if ( (a = attr_find( e->e_attrs, password )) == NULL ) {
177                         send_ldap_result( conn, op, LDAP_INAPPROPRIATE_AUTH,
178                             NULL, NULL, NULL, NULL );
179
180                         /* stop front end from sending result */
181                         rc = 1;
182                         goto return_results;
183                 }
184
185                 if ( slap_passwd_check( conn, a, cred ) != 0 ) {
186                         send_ldap_result( conn, op, LDAP_INVALID_CREDENTIALS,
187                                 NULL, NULL, NULL, NULL );
188                         /* stop front end from sending result */
189                         rc = 1;
190                         goto return_results;
191                 }
192
193                 rc = 0;
194                 break;
195
196 #ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
197         case LDAP_AUTH_KRBV41:
198                 if ( krbv4_ldap_auth( be, cred, &ad ) != LDAP_SUCCESS ) {
199                         send_ldap_result( conn, op, LDAP_INVALID_CREDENTIALS,
200                             NULL, NULL, NULL, NULL );
201                         rc = 1;
202                         goto return_results;
203                 }
204
205                 if ( ! access_allowed( be, conn, op, e,
206                         krbattr, NULL, ACL_AUTH ) )
207                 {
208                         send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
209                                 NULL, NULL, NULL, NULL );
210                         rc = 1;
211                         goto return_results;
212                 }
213
214                 sprintf( krbname, "%s%s%s@%s", ad.pname, *ad.pinst ? "."
215                     : "", ad.pinst, ad.prealm );
216
217                 if ( (a = attr_find( e->e_attrs, krbattr )) == NULL ) {
218                         /*
219                          * no krbname values present:  check against DN
220                          */
221                         if ( strcasecmp( dn->bv_val, krbname ) == 0 ) {
222                                 rc = 0;
223                                 break;
224                         }
225                         send_ldap_result( conn, op, LDAP_INAPPROPRIATE_AUTH,
226                             NULL, NULL, NULL, NULL );
227                         rc = 1;
228                         goto return_results;
229
230                 } else {        /* look for krbname match */
231                         struct berval   krbval;
232
233                         krbval.bv_val = krbname;
234                         krbval.bv_len = strlen( krbname );
235
236                         if ( value_find( a->a_desc, a->a_vals, &krbval ) != 0 ) {
237                                 send_ldap_result( conn, op,
238                                     LDAP_INVALID_CREDENTIALS,
239                                         NULL, NULL, NULL, NULL );
240                                 rc = 1;
241                                 goto return_results;
242                         }
243                 }
244                 rc = 0;
245                 break;
246
247         case LDAP_AUTH_KRBV42:
248                 send_ldap_result( conn, op, LDAP_UNWILLING_TO_PERFORM,
249                         NULL, "Kerberos bind step 2 not supported",
250                         NULL, NULL );
251                 /* stop front end from sending result */
252                 rc = LDAP_UNWILLING_TO_PERFORM;
253                 goto return_results;
254 #endif
255
256         default:
257                 send_ldap_result( conn, op, LDAP_STRONG_AUTH_NOT_SUPPORTED,
258                     NULL, "authentication method not supported", NULL, NULL );
259                 rc = 1;
260                 goto return_results;
261         }
262
263 return_results:;
264         /* free entry and reader lock */
265         cache_return_entry_r( &li->li_cache, e );
266
267         /* front end with send result on success (rc==0) */
268         return( rc );
269 }
270