]> git.sur5r.net Git - openldap/blob - servers/slapd/back-ldbm/bind.c
8183b75525563194c030ea6b84c131afa19f7ad1
[openldap] / servers / slapd / back-ldbm / bind.c
1 /* bind.c - ldbm backend bind and unbind routines */
2 /* $OpenLDAP$ */
3 /*
4  * Copyright 1998-1999 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     char                *dn,
27     char                *ndn,
28     int                 method,
29         char            *mech,
30     struct berval       *cred,
31         char**  edn
32 )
33 {
34         struct ldbminfo *li = (struct ldbminfo *) be->be_private;
35         Entry           *e;
36         Attribute       *a;
37         int             rc;
38         Entry           *matched;
39 #ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
40         char            krbname[MAX_K_NAME_SZ + 1];
41         AUTH_DAT        ad;
42 #endif
43
44 #ifdef SLAPD_SCHEMA_NOT_COMPAT
45         static AttributeDescription *password = NULL;
46         static AttributeDescription *entry = NULL;
47 #else
48         static const char *password = "userpassword";
49         static const char *entry = "entry";
50 #endif
51
52         Debug(LDAP_DEBUG_ARGS, "==> ldbm_back_bind: dn: %s\n", dn, 0, 0);
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, 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 ( ! 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 an 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, "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                 struct berval **refs = get_entry_referrals( be,
134                         conn, op, e );
135
136                 Debug( LDAP_DEBUG_TRACE, "entry is referral\n", 0,
137                     0, 0 );
138
139                 if( refs != NULL ) {
140                         send_ldap_result( conn, op, LDAP_REFERRAL,
141                                 e->e_dn, NULL, refs, NULL );
142
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                 /* check for root dn/passwd */
157                 if ( be_isroot_pw( be, dn, cred ) ) {
158                         /* front end will send result */
159                         if(*edn != NULL) free( *edn );
160                         *edn = ch_strdup( be_root_dn( be ) );
161                         rc = 0;
162                         goto return_results;
163                 }
164
165                 if ( ! access_allowed( be, conn, op, e,
166                         password, NULL, ACL_AUTH ) )
167                 {
168                         send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
169                                 NULL, NULL, NULL, NULL );
170                         rc = 1;
171                         goto return_results;
172                 }
173
174                 if ( (a = attr_find( e->e_attrs, password )) == NULL ) {
175                         send_ldap_result( conn, op, LDAP_INAPPROPRIATE_AUTH,
176                             NULL, NULL, NULL, NULL );
177
178                         /* stop front end from sending result */
179                         rc = 1;
180                         goto return_results;
181                 }
182
183                 if ( slap_passwd_check( a, cred ) != 0 ) {
184                         send_ldap_result( conn, op, LDAP_INVALID_CREDENTIALS,
185                                 NULL, NULL, NULL, NULL );
186                         /* stop front end from sending result */
187                         rc = 1;
188                         goto return_results;
189                 }
190
191                 rc = 0;
192                 break;
193
194 #ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
195         case LDAP_AUTH_KRBV41:
196                 if ( krbv4_ldap_auth( be, cred, &ad ) != LDAP_SUCCESS ) {
197                         send_ldap_result( conn, op, LDAP_INVALID_CREDENTIALS,
198                             NULL, NULL, NULL, NULL );
199                         rc = 1;
200                         goto return_results;
201                 }
202
203                 if ( ! access_allowed( be, conn, op, e,
204                         "krbname", NULL, ACL_AUTH ) )
205                 {
206                         send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
207                                 NULL, NULL, NULL, NULL );
208                         rc = 1;
209                         goto return_results;
210                 }
211
212                 sprintf( krbname, "%s%s%s@%s", ad.pname, *ad.pinst ? "."
213                     : "", ad.pinst, ad.prealm );
214
215                 if ( (a = attr_find( e->e_attrs, "krbname" )) == NULL ) {
216                         /*
217                          * no krbname values present:  check against DN
218                          */
219                         if ( strcasecmp( dn, krbname ) == 0 ) {
220                                 rc = 0;
221                                 break;
222                         }
223                         send_ldap_result( conn, op, LDAP_INAPPROPRIATE_AUTH,
224                             NULL, NULL, NULL, NULL );
225                         rc = 1;
226                         goto return_results;
227
228                 } else {        /* look for krbname match */
229                         struct berval   krbval;
230
231                         krbval.bv_val = krbname;
232                         krbval.bv_len = strlen( krbname );
233
234                         if ( value_find( a->a_vals, &krbval, a->a_syntax, 3 ) != 0 ) {
235                                 send_ldap_result( conn, op,
236                                     LDAP_INVALID_CREDENTIALS,
237                                         NULL, NULL, NULL, NULL );
238                                 rc = 1;
239                                 goto return_results;
240                         }
241                 }
242                 rc = 0;
243                 break;
244
245         case LDAP_AUTH_KRBV42:
246                 send_ldap_result( conn, op, LDAP_SUCCESS,
247                         NULL, NULL, NULL, NULL );
248                 /* stop front end from sending result */
249                 rc = 1;
250                 goto return_results;
251 #endif
252
253         default:
254                 send_ldap_result( conn, op, LDAP_STRONG_AUTH_NOT_SUPPORTED,
255                     NULL, "authentication method not supported", NULL, NULL );
256                 rc = 1;
257                 goto return_results;
258         }
259
260 return_results:;
261         /* free entry and reader lock */
262         cache_return_entry_r( &li->li_cache, e );
263
264         /* front end with send result on success (rc==0) */
265         return( rc );
266 }
267