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