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