]> git.sur5r.net Git - openldap/blob - servers/slapd/back-ldbm/bind.c
66dfddbceb55fff38dc5908f1f2c953635238a09
[openldap] / servers / slapd / back-ldbm / bind.c
1 /* bind.c - ldbm backend bind and unbind routines */
2
3 #include <stdio.h>
4 #include <string.h>
5 #include <sys/types.h>
6 #include <sys/socket.h>
7 #include "slap.h"
8 #include "back-ldbm.h"
9 #include "proto-back-ldbm.h"
10 #ifdef KERBEROS
11 #ifdef KERBEROS_V
12 #include <kerberosIV/krb.h>
13 #else
14 #include <krb.h>
15 #endif /* KERBEROS_V */
16 #endif /* KERBEROS */
17
18 #ifdef LDAP_CRYPT
19 /* change for crypted passwords -- lukeh */
20 #ifdef __NeXT__
21 extern char *crypt (char *key, char *salt);
22 #else
23 #include <unistd.h>
24 #endif
25 #endif /* LDAP_CRYPT */
26
27 #ifdef LDAP_SHA1
28 #include <lutil_sha1.h>
29 #endif /* LDAP_SHA1 */
30 #ifdef LDAP_MD5
31 #include <lutil_md5.h>
32 #endif /* LDAP_MD5 */
33
34 #include <lutil.h>
35
36 extern Attribute        *attr_find();
37
38 #ifdef KERBEROS
39 extern int      krbv4_ldap_auth();
40 #endif
41
42 #ifdef LDAP_CRYPT
43 pthread_mutex_t crypt_mutex;
44
45 static int
46 crypted_value_find(
47         struct berval       **vals,
48         struct berval       *v,
49         int                 syntax,
50         int                 normalize,
51         struct berval           *cred
52 )
53 {
54         int     i;
55         for ( i = 0; vals[i] != NULL; i++ ) {
56                 if ( syntax != SYNTAX_BIN && strncasecmp( "{CRYPT}",
57                         vals[i]->bv_val, (sizeof("{CRYPT}") - 1 ) ) == 0 ) {
58                                 char *userpassword = vals[i]->bv_val + sizeof("{CRYPT}") - 1;
59                                 pthread_mutex_lock( &crypt_mutex );
60                                 if (strcmp(userpassword, crypt(cred->bv_val,
61                                                 userpassword)) == 0) {
62                                         pthread_mutex_unlock( &crypt_mutex );
63                                         return ( 0 );
64                                 }
65                                 pthread_mutex_unlock( &crypt_mutex );
66 #ifdef LDAP_MD5
67                 } else if ( syntax != SYNTAX_BIN && strncasecmp( "{MD5}",
68                         vals[i]->bv_val, (sizeof("{MD5}") - 1 ) ) == 0 ) {
69                                 ldap_MD5_CTX MD5context;
70                                 unsigned char MD5digest[20];
71                                 char base64digest[29];  /* ceiling(sizeof(input)/3) * 4 + 1 */
72
73                                 char *userpassword = vals[i]->bv_val + sizeof("{MD5}") - 1;
74
75                                 ldap_MD5Init(&MD5context);
76                                 ldap_MD5Update(&MD5context, cred->bv_val, strlen(cred->bv_val));
77                                 ldap_MD5Final(MD5digest, &MD5context);
78
79                                 if (b64_ntop(MD5digest, sizeof(MD5digest),
80                                         base64digest, sizeof(base64digest)) < 0)
81                                 {
82                                         return ( 1 );
83                                 }
84
85                                 if (strcmp(userpassword, base64digest) == 0) {
86                                         return ( 0 );
87                                 }
88 #endif /* LDAP_MD5 */
89 #ifdef LDAP_SHA1
90                 } else if ( syntax != SYNTAX_BIN && strncasecmp( "{SHA}",
91                         vals[i]->bv_val, (sizeof("{SHA}") - 1 ) ) == 0 ) {
92                                 ldap_SHA1_CTX SHA1context;
93                                 unsigned char SHA1digest[20];
94                                 char base64digest[29];  /* ceiling(sizeof(input)/3) * 4 + 1 */
95
96                                 char *userpassword = vals[i]->bv_val + sizeof("{SHA}") - 1;
97
98                                 ldap_SHA1Init(&SHA1context);
99                                 ldap_SHA1Update(&SHA1context, cred->bv_val, strlen(cred->bv_val));
100                                 ldap_SHA1Final(SHA1digest, &SHA1context);
101
102                                 if (b64_ntop(SHA1digest, sizeof(SHA1digest),
103                                         base64digest, sizeof(base64digest)) < 0)
104                                 {
105                                         return ( 1 );
106                                 }
107
108                                 if (strcmp(userpassword, base64digest) == 0) {
109                                         return ( 0 );
110                                 }
111 #endif /* LDAP_SHA1 */
112                 } else {
113                 if ( value_cmp( vals[i], v, syntax, normalize ) == 0 ) {
114                         return( 0 );
115                 }
116         }
117         }
118
119         return( 1 );
120 }
121 #endif /* LDAP_CRYPT */
122
123 int
124 ldbm_back_bind(
125     Backend             *be,
126     Connection          *conn,
127     Operation           *op,
128     char                *dn,
129     int                 method,
130     struct berval       *cred
131 )
132 {
133         struct ldbminfo *li = (struct ldbminfo *) be->be_private;
134         Entry           *e;
135         Attribute       *a;
136         int             rc;
137         char            *matched = NULL;
138 #ifdef KERBEROS
139         char            krbname[MAX_K_NAME_SZ + 1];
140         AUTH_DAT        ad;
141 #endif
142
143         Debug(LDAP_DEBUG_ARGS, "==> ldbm_back_bind: dn: %s\n", dn, 0, 0);
144
145         /* get entry with reader lock */
146         if ( (e = dn2entry_r( be, dn, &matched )) == NULL ) {
147                 /* allow noauth binds */
148                 if ( method == LDAP_AUTH_SIMPLE && cred->bv_len == 0 ) {
149                         /*
150                          * bind successful, but return 1 so we don't
151                          * authorize based on noauth credentials
152                          */
153                         send_ldap_result( conn, op, LDAP_SUCCESS, NULL, NULL );
154                         rc = 1;
155                 } else if ( be_isroot_pw( be, dn, cred ) ) {
156                         /* front end will send result */
157                         rc = 0;
158                 } else {
159                         send_ldap_result( conn, op, LDAP_NO_SUCH_OBJECT, matched, NULL );
160                         rc = 1;
161                 }
162                 if ( matched != NULL ) {
163                         free( matched );
164                 }
165                 return( rc );
166         }
167
168         /* check for deleted */
169
170         switch ( method ) {
171         case LDAP_AUTH_SIMPLE:
172                 if ( cred->bv_len == 0 ) {
173                         send_ldap_result( conn, op, LDAP_SUCCESS, NULL, NULL );
174
175                         /* stop front end from sending result */
176                         rc = 1;
177                         goto return_results;
178                 } else if ( be_isroot_pw( be, dn, cred ) ) {
179                         /* front end will send result */
180                         rc = 0;
181                         goto return_results;
182                 }
183
184                 if ( (a = attr_find( e->e_attrs, "userpassword" )) == NULL ) {
185                         if ( be_isroot_pw( be, dn, cred ) ) {
186                                 /* front end will send result */
187                                 rc = 0;
188                                 goto return_results;
189                         }
190                         send_ldap_result( conn, op, LDAP_INAPPROPRIATE_AUTH,
191                             NULL, NULL );
192                         rc = 1;
193                         goto return_results;
194                 }
195
196 #ifdef LDAP_CRYPT
197                 if ( crypted_value_find( a->a_vals, cred, a->a_syntax, 0, cred ) != 0 )
198 #else
199                 if ( value_find( a->a_vals, cred, a->a_syntax, 0 ) != 0 )
200 #endif
201                 {
202                         if ( be_isroot_pw( be, dn, cred ) ) {
203                                 /* front end will send result */
204                                 rc = 0;
205                                 goto return_results;
206                         }
207                         send_ldap_result( conn, op, LDAP_INVALID_CREDENTIALS,
208                                 NULL, NULL );
209                         rc = 1;
210                         goto return_results;
211                 }
212                 rc = 0;
213                 break;
214
215 #ifdef KERBEROS
216         case LDAP_AUTH_KRBV41:
217                 if ( krbv4_ldap_auth( be, cred, &ad ) != LDAP_SUCCESS ) {
218                         send_ldap_result( conn, op, LDAP_INVALID_CREDENTIALS,
219                             NULL, NULL );
220                         rc = 0;
221                         goto return_results;
222                 }
223                 sprintf( krbname, "%s%s%s@%s", ad.pname, *ad.pinst ? "."
224                     : "", ad.pinst, ad.prealm );
225                 if ( (a = attr_find( e->e_attrs, "krbname" )) == NULL ) {
226                         /*
227                          * no krbName values present:  check against DN
228                          */
229                         if ( strcasecmp( dn, krbname ) == 0 ) {
230                                 rc = 0; /* XXX wild ass guess */
231                                 break;
232                         }
233                         send_ldap_result( conn, op, LDAP_INAPPROPRIATE_AUTH,
234                             NULL, NULL );
235                         rc = 1;
236                         goto return_results;
237                 } else {        /* look for krbName match */
238                         struct berval   krbval;
239
240                         krbval.bv_val = krbname;
241                         krbval.bv_len = strlen( krbname );
242
243                         if ( value_find( a->a_vals, &krbval, a->a_syntax, 3 ) != 0 ) {
244                                 send_ldap_result( conn, op,
245                                     LDAP_INVALID_CREDENTIALS, NULL, NULL );
246                                 rc = 1;
247                                 goto return_results;
248                         }
249                 }
250                 break;
251
252         case LDAP_AUTH_KRBV42:
253                 send_ldap_result( conn, op, LDAP_SUCCESS, NULL, NULL );
254                 /* stop front end from sending result */
255                 rc = 1;
256                 goto return_results;
257 #endif
258
259         default:
260                 send_ldap_result( conn, op, LDAP_STRONG_AUTH_NOT_SUPPORTED,
261                     NULL, "auth method not supported" );
262                 rc = 1;
263                 goto return_results;
264         }
265
266 return_results:;
267         /* free entry and reader lock */
268         cache_return_entry_r( &li->li_cache, e );
269
270         /* front end with send result on success (rc==0) */
271         return( rc );
272 }
273