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