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