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