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