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