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