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