]> git.sur5r.net Git - openldap/blob - servers/slapd/back-bdb2/bind.c
Use #ifdef, not #if
[openldap] / servers / slapd / back-bdb2 / bind.c
1 /* bind.c - bdb2 backend bind and unbind routines */
2 /* $OpenLDAP$ */
3
4 #include "portable.h"
5
6 #include <stdio.h>
7
8 #include <ac/krb.h>
9 #include <ac/socket.h>
10 #include <ac/string.h>
11 #include <ac/unistd.h>
12
13 #include "slap.h"
14 #include "back-bdb2.h"
15 #include "proto-back-bdb2.h"
16
17 static int
18 bdb2i_back_bind_internal(
19     BackendDB           *be,
20     Connection          *conn,
21     Operation           *op,
22     char                *dn,
23     int                 method,
24     struct berval       *cred,
25         char**  edn
26 )
27 {
28         struct ldbminfo *li = (struct ldbminfo *) be->be_private;
29         Entry           *e;
30         Attribute       *a;
31         int             rc;
32         Entry           *matched;
33 #ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
34         char            krbname[MAX_K_NAME_SZ + 1];
35         AUTH_DAT        ad;
36 #endif
37
38         Debug(LDAP_DEBUG_ARGS, "==> bdb2_back_bind: dn: %s\n", dn, 0, 0);
39
40         *edn = NULL;
41
42         /* get entry with reader lock */
43         if ( (e = bdb2i_dn2entry_r( be, dn, &matched )) == NULL ) {
44                 char *matched_dn = NULL;
45                 struct berval **refs = NULL;
46
47                 if ( matched != NULL ) {
48                         matched_dn = ch_strdup( matched->e_dn );
49                         refs = is_entry_referral( matched )
50                                 ? get_entry_referrals( be, conn, op, matched )
51                                 : NULL;
52                         bdb2i_cache_return_entry_r( &li->li_cache, matched );
53                 } else {
54                         refs = default_referral;
55                 }
56
57                 /* allow noauth binds */
58                 rc = 1;
59                 if ( method == LDAP_AUTH_SIMPLE ) {
60                         if( cred->bv_len == 0 ) {
61                                 /* SUCCESS */
62                                 send_ldap_result( conn, op, LDAP_SUCCESS,
63                                         NULL, NULL, NULL, NULL );
64
65                         } else if ( be_isroot_pw( be, dn, cred ) ) {
66                                 /* front end will send result */
67                                 *edn = ch_strdup( be_root_dn( be ) );
68                                 rc = 0;
69
70                         } else if ( refs != NULL ) {
71                                 send_ldap_result( conn, op, LDAP_REFERRAL,
72                                         matched_dn, NULL, refs, NULL );
73
74                         } else {
75                                 send_ldap_result( conn, op, LDAP_INVALID_CREDENTIALS,
76                                         NULL, NULL, NULL, NULL );
77                         }
78
79                 } else if ( method == LDAP_AUTH_SASL ) {
80                         if( mech != NULL && strcasecmp(mech,"DIGEST-MD5") == 0 ) {
81                                 /* insert DIGEST calls here */
82                                 send_ldap_result( conn, op, LDAP_AUTH_METHOD_NOT_SUPPORTED,
83                                         NULL, NULL, NULL, NULL );
84
85                         } else {
86                                 send_ldap_result( conn, op, LDAP_AUTH_METHOD_NOT_SUPPORTED,
87                                         NULL, NULL, NULL, NULL );
88                         }
89
90                 } else if ( refs != NULL ) {
91                         send_ldap_result( conn, op, LDAP_REFERRAL,
92                                 matched_dn, NULL, refs, NULL );
93
94                 } else {
95                         send_ldap_result( conn, op, LDAP_INVALID_CREDENTIALS,
96                                 NULL, NULL, NULL, NULL );
97                 }
98
99                 if ( matched != NULL ) {
100                         ber_bvecfree( refs );
101                         free( matched_dn );
102                 }
103                 return( rc );
104         }
105
106         *edn = ch_strdup( e->e_dn );
107
108         /* check for deleted */
109
110         if ( ! access_allowed( be, conn, op, e,
111                 "entry", NULL, ACL_AUTH ) )
112         {
113                 send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
114                         NULL, NULL, NULL, NULL );
115                 rc = 1;
116                 goto return_results;
117         }
118
119         if ( is_entry_alias( e ) ) {
120                 /* entry is a alias, don't allow bind */
121                 Debug( LDAP_DEBUG_TRACE, "entry is alias\n", 0,
122                         0, 0 );
123
124                 send_ldap_result( conn, op, LDAP_ALIAS_PROBLEM,
125                         NULL, NULL, NULL, NULL );
126
127                 rc = 1;
128                 goto return_results;
129         }
130
131
132         if ( is_entry_referral( e ) ) {
133                 /* entry is a referral, don't allow bind */
134                 struct berval **refs = get_entry_referrals( be,
135                         conn, op, e );
136
137                 Debug( LDAP_DEBUG_TRACE, "entry is referral\n", 0,
138                         0, 0 );
139
140                 if( refs != NULL ) {
141                         send_ldap_result( conn, op, LDAP_REFERRAL,
142                                 e->e_dn, NULL, refs, NULL );
143                 } else {
144                         send_ldap_result( conn, op, LDAP_INVALID_CREDENTIALS,
145                                 NULL, NULL, NULL, NULL );
146                 }
147
148                 ber_bvecfree( refs );
149
150                 rc = 1;
151                 goto return_results;
152         }
153
154         switch ( method ) {
155         case LDAP_AUTH_SIMPLE:
156                 if ( cred->bv_len == 0 ) {
157                         send_ldap_result( conn, op, LDAP_SUCCESS,
158                                 NULL, NULL, NULL, NULL );
159
160                         /* stop front end from sending result */
161                         rc = 1;
162                         goto return_results;
163                 }
164
165                 /* check for root dn/passwd */
166                 if ( be_isroot_pw( be, dn, cred ) ) {
167                         /* front end will send result */
168                         if( *edn != NULL ) free( *edn );
169                         *edn = ch_strdup( be_root_dn( be ) );
170                         rc = 0;
171                         goto return_results;
172                 }
173
174                 if ( ! access_allowed( be, conn, op, e,
175                         "userpassword", NULL, ACL_AUTH ) )
176                 {
177                         send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
178                                 NULL, NULL, NULL, NULL);
179                         rc = 1;
180                         goto return_results;
181                 }
182
183                 if ( (a = attr_find( e->e_attrs, "userpassword" )) == NULL ) {
184                         send_ldap_result( conn, op, LDAP_INAPPROPRIATE_AUTH,
185                                 NULL, NULL, NULL, NULL);
186
187                         /* stop front end from sending result */
188                         rc = 1;
189                         goto return_results;
190                 }
191
192                 if ( slap_passwd_check( a, cred ) != 0 ) {
193                         send_ldap_result( conn, op, LDAP_INVALID_CREDENTIALS,
194                                 NULL, NULL, NULL, NULL);
195                         /* stop front end from sending result */
196                         rc = 1;
197                         goto return_results;
198                 }
199                 rc = 0;
200                 break;
201
202 #ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
203         case LDAP_AUTH_KRBV41:
204                 if ( bdb2i_krbv4_ldap_auth( be, cred, &ad ) != LDAP_SUCCESS ) {
205                         send_ldap_result( conn, op, LDAP_INVALID_CREDENTIALS,
206                                 NULL, NULL, NULL, NULL);
207                         rc = 1;
208                         goto return_results;
209                 }
210
211                 if ( ! access_allowed( be, conn, op, e,
212                         "krbname", NULL, ACL_AUTH ) )
213                 {
214                         send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
215                                 NULL, NULL, NULL, NULL);
216                         rc = 1;
217                         goto return_results;
218                 }
219
220                 sprintf( krbname, "%s%s%s@%s", ad.pname, *ad.pinst ? "."
221                     : "", ad.pinst, ad.prealm );
222
223                 if ( (a = attr_find( e->e_attrs, "krbname" )) == NULL ) {
224                         /*
225                          * no krbName values present:  check against DN
226                          */
227                         if ( strcasecmp( dn, krbname ) == 0 ) {
228                                 rc = 0; /* XXX wild ass guess */
229                                 break;
230                         }
231                         send_ldap_result( conn, op, LDAP_INAPPROPRIATE_AUTH,
232                                 NULL, NULL, NULL, NULL);
233                         rc = 1;
234                         goto return_results;
235                 } else {        /* look for krbName match */
236                         struct berval   krbval;
237
238                         krbval.bv_val = krbname;
239                         krbval.bv_len = strlen( krbname );
240
241                         if ( value_find( a->a_vals, &krbval, a->a_syntax, 3 ) != 0 ) {
242                                 send_ldap_result( conn, op, 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_SUCCESS,
253                         NULL, NULL, NULL, NULL );
254                 /* stop front end from sending result */
255                 rc = 1;
256                 goto return_results;
257 #endif
258
259         case LDAP_AUTH_SASL:
260                 /* insert sasl code here */
261
262         default:
263                 send_ldap_result( conn, op, LDAP_STRONG_AUTH_NOT_SUPPORTED,
264                     NULL, "auth method not supported", NULL, NULL );
265                 rc = 1;
266                 goto return_results;
267         }
268
269 return_results:;
270         /* free entry and reader lock */
271         bdb2i_cache_return_entry_r( &li->li_cache, e );
272
273         /* front end with send result on success (rc==0) */
274         return( rc );
275 }
276
277
278 int
279 bdb2_back_bind(
280     BackendDB           *be,
281     Connection          *conn,
282     Operation           *op,
283     char                *dn,
284     char                *ndn,
285     int                 method,
286         char            *mech,
287     struct berval       *cred,
288         char**  edn
289 )
290 {
291         DB_LOCK         lock;
292         struct ldbminfo *li = (struct ldbminfo *) be->be_private;
293         struct timeval  time1;
294         int             ret;
295
296         bdb2i_start_timing( be->bd_info, &time1 );
297
298         if ( bdb2i_enter_backend_r( &lock ) != 0 ) {
299                 send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
300                         NULL, NULL, NULL, NULL );
301                 return( 1 );
302         }
303
304         ret = bdb2i_back_bind_internal( be, conn, op, ndn, method, mech, cred, edn );
305
306         (void) bdb2i_leave_backend_r( lock );
307
308         bdb2i_stop_timing( be->bd_info, time1, "BIND", conn, op );
309
310         return( ret );
311 }
312
313