]> git.sur5r.net Git - openldap/blob - servers/slapd/back-ldbm/bind.c
1c72e0eda18c8208ff062db0e796d2ecc3ab3af5
[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         AUTH_DAT        ad;
41 #endif
42
43         AttributeDescription *password = slap_schema.si_ad_userPassword;
44         AttributeDescription *entry = slap_schema.si_ad_entry;
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 ( ! access_allowed( be, conn, op, e,
105                 entry, NULL, ACL_AUTH ) )
106         {
107                 send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
108                         NULL, NULL, NULL, NULL );
109                 rc = 1;
110                 goto return_results;
111         }
112
113         if ( is_entry_alias( e ) ) {
114                 /* entry is an alias, don't allow bind */
115                 Debug( LDAP_DEBUG_TRACE, "entry is alias\n", 0,
116                     0, 0 );
117
118                 send_ldap_result( conn, op, LDAP_ALIAS_PROBLEM,
119                     NULL, "entry is alias", NULL, NULL );
120
121                 rc = 1;
122                 goto return_results;
123         }
124
125         if ( is_entry_referral( e ) ) {
126                 /* entry is a referral, don't allow bind */
127                 struct berval **refs = get_entry_referrals( be,
128                         conn, op, e );
129
130                 Debug( LDAP_DEBUG_TRACE, "entry is referral\n", 0,
131                     0, 0 );
132
133                 if( refs != NULL ) {
134                         send_ldap_result( conn, op, LDAP_REFERRAL,
135                                 e->e_dn, NULL, refs, NULL );
136
137                 } else {
138                         send_ldap_result( conn, op, LDAP_INVALID_CREDENTIALS,
139                                 NULL, NULL, NULL, NULL );
140                 }
141
142                 ber_bvecfree( refs );
143
144                 rc = 1;
145                 goto return_results;
146         }
147
148         switch ( method ) {
149         case LDAP_AUTH_SIMPLE:
150                 /* check for root dn/passwd */
151                 if ( be_isroot_pw( be, dn, cred ) ) {
152                         /* front end will send result */
153                         if(*edn != NULL) free( *edn );
154                         *edn = ch_strdup( be_root_dn( be ) );
155                         rc = 0;
156                         goto return_results;
157                 }
158
159                 if ( ! access_allowed( be, conn, op, e,
160                         password, NULL, ACL_AUTH ) )
161                 {
162                         send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
163                                 NULL, NULL, NULL, NULL );
164                         rc = 1;
165                         goto return_results;
166                 }
167
168                 if ( (a = attr_find( e->e_attrs, password )) == NULL ) {
169                         send_ldap_result( conn, op, LDAP_INAPPROPRIATE_AUTH,
170                             NULL, NULL, NULL, NULL );
171
172                         /* stop front end from sending result */
173                         rc = 1;
174                         goto return_results;
175                 }
176
177                 if ( slap_passwd_check( a, cred ) != 0 ) {
178                         send_ldap_result( conn, op, LDAP_INVALID_CREDENTIALS,
179                                 NULL, NULL, NULL, NULL );
180                         /* stop front end from sending result */
181                         rc = 1;
182                         goto return_results;
183                 }
184
185                 rc = 0;
186                 break;
187
188 #ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
189         case LDAP_AUTH_KRBV41:
190                 if ( krbv4_ldap_auth( be, cred, &ad ) != LDAP_SUCCESS ) {
191                         send_ldap_result( conn, op, LDAP_INVALID_CREDENTIALS,
192                             NULL, NULL, NULL, NULL );
193                         rc = 1;
194                         goto return_results;
195                 }
196
197                 if ( ! access_allowed( be, conn, op, e,
198                         "krbname", NULL, ACL_AUTH ) )
199                 {
200                         send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
201                                 NULL, NULL, NULL, NULL );
202                         rc = 1;
203                         goto return_results;
204                 }
205
206                 sprintf( krbname, "%s%s%s@%s", ad.pname, *ad.pinst ? "."
207                     : "", ad.pinst, ad.prealm );
208
209                 if ( (a = attr_find( e->e_attrs, "krbname" )) == NULL ) {
210                         /*
211                          * no krbname values present:  check against DN
212                          */
213                         if ( strcasecmp( dn, krbname ) == 0 ) {
214                                 rc = 0;
215                                 break;
216                         }
217                         send_ldap_result( conn, op, LDAP_INAPPROPRIATE_AUTH,
218                             NULL, NULL, NULL, NULL );
219                         rc = 1;
220                         goto return_results;
221
222                 } else {        /* look for krbname match */
223                         struct berval   krbval;
224
225                         krbval.bv_val = krbname;
226                         krbval.bv_len = strlen( krbname );
227
228                         if ( value_find( a->a_vals, &krbval, a->a_syntax, 3 ) != 0 ) {
229                                 send_ldap_result( conn, op,
230                                     LDAP_INVALID_CREDENTIALS,
231                                         NULL, NULL, NULL, NULL );
232                                 rc = 1;
233                                 goto return_results;
234                         }
235                 }
236                 rc = 0;
237                 break;
238
239         case LDAP_AUTH_KRBV42:
240                 send_ldap_result( conn, op, LDAP_SUCCESS,
241                         NULL, NULL, NULL, NULL );
242                 /* stop front end from sending result */
243                 rc = 1;
244                 goto return_results;
245 #endif
246
247         default:
248                 send_ldap_result( conn, op, LDAP_STRONG_AUTH_NOT_SUPPORTED,
249                     NULL, "authentication method not supported", NULL, NULL );
250                 rc = 1;
251                 goto return_results;
252         }
253
254 return_results:;
255         /* free entry and reader lock */
256         cache_return_entry_r( &li->li_cache, e );
257
258         /* front end with send result on success (rc==0) */
259         return( rc );
260 }
261