]> git.sur5r.net Git - openldap/blob - servers/slapd/back-ldbm/bind.c
Fixed md5/sha files.
[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 #ifdef KERBEROS
10 #ifdef KERBEROS_V
11 #include <kerberosIV/krb.h>
12 #else
13 #include <krb.h>
14 #endif /* KERBEROS_V */
15 #endif /* KERBEROS */
16
17 #ifdef LDAP_CRYPT
18 /* change for crypted passwords -- lukeh */
19 #ifdef __NeXT__
20 extern char *crypt (char *key, char *salt);
21 #else
22 #include <unistd.h>
23 #endif
24 #endif /* LDAP_CRYPT */
25
26 #ifdef LDAP_SHA1
27 #include <lutil_sha1.h>
28 #endif /* LDAP_SHA1 */
29 #ifdef LDAP_MD5
30 #include <lutil_md5.h>
31 #endif /* LDAP_MD5 */
32
33 #include <lutil.h>
34
35 extern Entry            *dn2entry();
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         if ( (e = dn2entry( be, dn, &matched )) == NULL ) {
144                 /* allow noauth binds */
145                 if ( method == LDAP_AUTH_SIMPLE && cred->bv_len == 0 ) {
146                         /*
147                          * bind successful, but return 1 so we don't
148                          * authorize based on noauth credentials
149                          */
150                         send_ldap_result( conn, op, LDAP_SUCCESS, NULL, NULL );
151                         rc = 1;
152                 } else if ( be_isroot_pw( be, dn, cred ) ) {
153                         /* front end will send result */
154                         rc = 0;
155                 } else {
156                         send_ldap_result( conn, op, LDAP_NO_SUCH_OBJECT,
157                             matched, NULL );
158                         rc = 1;
159                 }
160                 if ( matched != NULL ) {
161                         free( matched );
162                 }
163                 return( rc );
164         }
165
166         switch ( method ) {
167         case LDAP_AUTH_SIMPLE:
168                 if ( cred->bv_len == 0 ) {
169                         send_ldap_result( conn, op, LDAP_SUCCESS, NULL, NULL );
170                         return( 1 );
171                 } else if ( be_isroot_pw( be, dn, cred ) ) {
172                         /* front end will send result */
173                         return( 0 );
174                 }
175
176                 if ( (a = attr_find( e->e_attrs, "userpassword" )) == NULL ) {
177                         if ( be_isroot_pw( be, dn, cred ) ) {
178                                 /* front end will send result */
179                                 return( 0 );
180                         }
181                         send_ldap_result( conn, op, LDAP_INAPPROPRIATE_AUTH,
182                             NULL, NULL );
183                         cache_return_entry( &li->li_cache, e );
184                         return( 1 );
185                 }
186
187 #ifdef LDAP_CRYPT
188                 if ( crypted_value_find( a->a_vals, cred, a->a_syntax, 0, cred ) != 0 )
189 #else
190                 if ( value_find( a->a_vals, cred, a->a_syntax, 0 ) != 0 )
191 #endif
192 {
193                         if ( be_isroot_pw( be, dn, cred ) ) {
194                                 /* front end will send result */
195                                 return( 0 );
196                         }
197                         send_ldap_result( conn, op, LDAP_INVALID_CREDENTIALS,
198                                 NULL, NULL );
199                         cache_return_entry( &li->li_cache, e );
200                         return( 1 );
201                 }
202                 break;
203
204 #ifdef KERBEROS
205         case LDAP_AUTH_KRBV41:
206                 if ( krbv4_ldap_auth( be, cred, &ad ) != LDAP_SUCCESS ) {
207                         send_ldap_result( conn, op, LDAP_INVALID_CREDENTIALS,
208                             NULL, NULL );
209                         cache_return_entry( &li->li_cache, e );
210                         return( 1 );
211                 }
212                 sprintf( krbname, "%s%s%s@%s", ad.pname, *ad.pinst ? "."
213                     : "", ad.pinst, ad.prealm );
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                                 break;
220                         }
221                         send_ldap_result( conn, op, LDAP_INAPPROPRIATE_AUTH,
222                             NULL, NULL );
223                         cache_return_entry( &li->li_cache, e );
224                         return( 1 );
225                 } else {        /* look for krbName match */
226                         struct berval   krbval;
227
228                         krbval.bv_val = krbname;
229                         krbval.bv_len = strlen( krbname );
230
231                         if ( value_find( a->a_vals, &krbval, a->a_syntax, 3 )
232                             != 0 ) {
233                                 send_ldap_result( conn, op,
234                                     LDAP_INVALID_CREDENTIALS, NULL, NULL );
235                                 cache_return_entry( &li->li_cache, e );
236                                 return( 1 );
237                         }
238                 }
239                 break;
240
241         case LDAP_AUTH_KRBV42:
242                 send_ldap_result( conn, op, LDAP_SUCCESS, NULL, NULL );
243                 cache_return_entry( &li->li_cache, e );
244                 return( 1 );
245 #endif
246
247         default:
248                 send_ldap_result( conn, op, LDAP_STRONG_AUTH_NOT_SUPPORTED,
249                     NULL, "auth method not supported" );
250                 cache_return_entry( &li->li_cache, e );
251                 return( 1 );
252         }
253
254         cache_return_entry( &li->li_cache, e );
255
256         /* success:  front end will send result */
257         return( 0 );
258 }