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