]> git.sur5r.net Git - openldap/blob - servers/slapd/back-ldbm/bind.c
f27872456e984b3131d370ed4a80ed43b210266b
[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, cred->bv_val, 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, cred->bv_val, strlen(cred->bv_val));
90                                 ldap_SHA1Final(SHA1digest, &SHA1context);
91
92                                 if (b64_ntop(SHA1digest, sizeof(SHA1digest),
93                                         base64digest, sizeof(base64digest)) < 0)
94                                 {
95                                         return ( 1 );
96                                 }
97
98                                 if (strcmp(userpassword, base64digest) == 0) {
99                                         return ( 0 );
100                                 }
101 #endif /* SLAPD_SHA1 */
102                 } else {
103                 if ( value_cmp( vals[i], v, syntax, normalize ) == 0 ) {
104                         return( 0 );
105                 }
106         }
107         }
108
109         return( 1 );
110 }
111 #endif /* SLAPD_CRYPT */
112
113 int
114 ldbm_back_bind(
115     Backend             *be,
116     Connection          *conn,
117     Operation           *op,
118     char                *dn,
119     int                 method,
120     struct berval       *cred
121 )
122 {
123         struct ldbminfo *li = (struct ldbminfo *) be->be_private;
124         Entry           *e;
125         Attribute       *a;
126         int             rc;
127         char            *matched = NULL;
128 #ifdef HAVE_KERBEROS
129         char            krbname[MAX_K_NAME_SZ + 1];
130         AUTH_DAT        ad;
131 #endif
132
133         Debug(LDAP_DEBUG_ARGS, "==> ldbm_back_bind: dn: %s\n", dn, 0, 0);
134
135         /* get entry with reader lock */
136         if ( (e = dn2entry_r( be, dn, &matched )) == NULL ) {
137                 /* allow noauth binds */
138                 if ( method == LDAP_AUTH_SIMPLE && cred->bv_len == 0 ) {
139                         /*
140                          * bind successful, but return 1 so we don't
141                          * authorize based on noauth credentials
142                          */
143                         send_ldap_result( conn, op, LDAP_SUCCESS, NULL, NULL );
144                         rc = 1;
145                 } else if ( be_isroot_pw( be, dn, cred ) ) {
146                         /* front end will send result */
147                         rc = 0;
148                 } else {
149                         send_ldap_result( conn, op, LDAP_NO_SUCH_OBJECT, matched, NULL );
150                         rc = 1;
151                 }
152                 if ( matched != NULL ) {
153                         free( matched );
154                 }
155                 return( rc );
156         }
157
158         /* check for deleted */
159
160         switch ( method ) {
161         case LDAP_AUTH_SIMPLE:
162                 if ( cred->bv_len == 0 ) {
163                         send_ldap_result( conn, op, LDAP_SUCCESS, NULL, NULL );
164
165                         /* stop front end from sending result */
166                         rc = 1;
167                         goto return_results;
168                 } else if ( be_isroot_pw( be, dn, cred ) ) {
169                         /* front end will send result */
170                         rc = 0;
171                         goto return_results;
172                 }
173
174                 if ( (a = attr_find( e->e_attrs, "userpassword" )) == NULL ) {
175                         if ( be_isroot_pw( be, dn, cred ) ) {
176                                 /* front end will send result */
177                                 rc = 0;
178                                 goto return_results;
179                         }
180                         send_ldap_result( conn, op, LDAP_INAPPROPRIATE_AUTH,
181                             NULL, NULL );
182                         rc = 1;
183                         goto return_results;
184                 }
185
186 #ifdef SLAPD_CRYPT
187                 if ( crypted_value_find( a->a_vals, cred, a->a_syntax, 0, cred ) != 0 )
188 #else
189                 if ( value_find( a->a_vals, cred, a->a_syntax, 0 ) != 0 )
190 #endif
191                 {
192                         if ( be_isroot_pw( be, dn, cred ) ) {
193                                 /* front end will send result */
194                                 rc = 0;
195                                 goto return_results;
196                         }
197                         send_ldap_result( conn, op, LDAP_INVALID_CREDENTIALS,
198                                 NULL, NULL );
199                         rc = 1;
200                         goto return_results;
201                 }
202                 rc = 0;
203                 break;
204
205 #ifdef HAVE_KERBEROS
206         case LDAP_AUTH_KRBV41:
207                 if ( krbv4_ldap_auth( be, cred, &ad ) != LDAP_SUCCESS ) {
208                         send_ldap_result( conn, op, LDAP_INVALID_CREDENTIALS,
209                             NULL, NULL );
210                         rc = 0;
211                         goto return_results;
212                 }
213                 sprintf( krbname, "%s%s%s@%s", ad.pname, *ad.pinst ? "."
214                     : "", ad.pinst, ad.prealm );
215                 if ( (a = attr_find( e->e_attrs, "krbname" )) == NULL ) {
216                         /*
217                          * no krbName values present:  check against DN
218                          */
219                         if ( strcasecmp( dn, krbname ) == 0 ) {
220                                 rc = 0; /* XXX wild ass guess */
221                                 break;
222                         }
223                         send_ldap_result( conn, op, LDAP_INAPPROPRIATE_AUTH,
224                             NULL, NULL );
225                         rc = 1;
226                         goto return_results;
227                 } else {        /* look for krbName match */
228                         struct berval   krbval;
229
230                         krbval.bv_val = krbname;
231                         krbval.bv_len = strlen( krbname );
232
233                         if ( value_find( a->a_vals, &krbval, a->a_syntax, 3 ) != 0 ) {
234                                 send_ldap_result( conn, op,
235                                     LDAP_INVALID_CREDENTIALS, NULL, NULL );
236                                 rc = 1;
237                                 goto return_results;
238                         }
239                 }
240                 break;
241
242         case LDAP_AUTH_KRBV42:
243                 send_ldap_result( conn, op, LDAP_SUCCESS, NULL, NULL );
244                 /* stop front end from sending result */
245                 rc = 1;
246                 goto return_results;
247 #endif
248
249         default:
250                 send_ldap_result( conn, op, LDAP_STRONG_AUTH_NOT_SUPPORTED,
251                     NULL, "auth method not supported" );
252                 rc = 1;
253                 goto return_results;
254         }
255
256 return_results:;
257         /* free entry and reader lock */
258         cache_return_entry_r( &li->li_cache, e );
259
260         /* front end with send result on success (rc==0) */
261         return( rc );
262 }
263