]> git.sur5r.net Git - openldap/blob - servers/ldapd/bind.c
ldapd did not compile
[openldap] / servers / ldapd / bind.c
1 /*
2  * Copyright (c) 1990 Regents of the University of Michigan.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms are permitted
6  * provided that this notice is preserved and that due credit is given
7  * to the University of Michigan at Ann Arbor. The name of the University
8  * may not be used to endorse or promote products derived from this
9  * software without specific prior written permission. This software
10  * is provided ``as is'' without express or implied warranty.
11  */
12
13 #include "portable.h"
14
15 #include <stdio.h>
16
17 #include <ac/socket.h>
18 #include <ac/string.h>          /* get SAFEMEMCPY */
19
20 #include <quipu/commonarg.h>
21 #include <quipu/attrvalue.h>
22 #include <quipu/ds_error.h>
23 #include <quipu/bind.h>
24 #include <quipu/compare.h>
25
26 #include "lber.h"
27 #include "ldap.h"
28 #include "common.h"
29
30 #ifdef LDAP_COMPAT20
31 extern int      ldap_compat;
32 #define BINDTAG (ldap_compat == 20 ? OLD_LDAP_RES_BIND : LDAP_RES_BIND)
33 #else
34 #define BINDTAG LDAP_RES_BIND
35 #endif
36
37 /*
38  * do_bind - perform an X.500 bind operation.  Since we always respond
39  * to the request in here, always return 0 to signify the incoming message
40  * can be discarded.
41  */
42
43 int
44 do_bind( 
45     Sockbuf     *clientsb,
46     struct msg  *m,
47     BerElement  *ber,
48     int         *bound
49 )
50 {
51         int             err;
52         unsigned long   method;
53         unsigned long   len;
54         char            *dn, *pw;
55         char            *matched;
56         struct PSAPaddr *addr, *psap_cpy();
57         extern char     *dsa_address;
58         extern int      version;
59
60         Debug( LDAP_DEBUG_TRACE, "do_bind\n", 0, 0, 0 );
61
62         /*
63          * Parse the bind request.  It looks like this:
64          *      BindRequest ::= SEQUENCE {
65          *              version         INTEGER,                 -- version
66          *              name            DistinguishedName,       -- dn
67          *              authentication  CHOICE {
68          *                      simple          [0] OCTET STRING -- passwd
69          *                      krbv42ldap      [1] OCTET STRING
70          *                      krbv42dsa       [1] OCTET STRING
71          *              }
72          *      }
73          */
74
75         if ( ber_scanf( ber, "{ia", &version, &dn ) == LBER_ERROR ) {
76                 Debug( LDAP_DEBUG_ANY, "ber_scanf failed\n", 0, 0, 0 );
77                 send_ldap_msgresult( clientsb, BINDTAG, m,
78                     LDAP_PROTOCOL_ERROR, NULL, "Decoding error" );
79                 return( 0 );
80         }
81 #ifdef LDAP_COMPAT30
82         if ( ldap_compat == 30 )
83                 method = ber_skip_tag( ber, &len );
84         else
85 #endif
86                 method = ber_peek_tag( ber, &len );
87
88         if ( ber_scanf( ber, "la}", &len, &pw ) == LBER_ERROR ) {
89                 Debug( LDAP_DEBUG_ANY, "ber_scanf2 failed\n", 0, 0, 0 );
90                 send_ldap_msgresult( clientsb, BINDTAG, m,
91                     LDAP_PROTOCOL_ERROR, NULL, "Decoding error" );
92                 return( 0 );
93         }
94
95         if ( version != LDAP_VERSION1 && version != LDAP_VERSION2 ) {
96                 Debug( LDAP_DEBUG_ANY, "unknown version %d\n", version, 0, 0 );
97                 send_ldap_msgresult( clientsb, BINDTAG, m,
98                     LDAP_PROTOCOL_ERROR, NULL, "Version not supported" );
99                 return( 0 );
100         }
101
102         Debug( LDAP_DEBUG_ARGS, "do_bind: version %d dn (%s) method %d\n",
103             version, dn, method );
104
105         if ( m->m_conn->c_paddr == NULLPA ) {
106                 char    buf[256];
107
108                 sprintf( buf, "Bad DSA address (%s)", dsa_address ?
109                     dsa_address : "NULL" );
110                 send_ldap_msgresult( clientsb, BINDTAG, m,
111                     LDAP_OPERATIONS_ERROR, NULL, buf );
112                 return( 0 );
113         }
114
115         if ( m->m_conn->c_dn )
116                 free( m->m_conn->c_dn );
117         if ( m->m_conn->c_cred )
118                 free( m->m_conn->c_cred );
119         m->m_conn->c_dn = dn;
120         m->m_conn->c_cred = pw;
121         m->m_conn->c_credlen = len;
122         m->m_conn->c_method = method;
123
124         err = do_bind_real( m->m_conn, bound, &matched );
125
126         send_ldap_msgresult( clientsb, BINDTAG, m, err, matched, "" );
127
128         if ( matched != NULL )
129                 free( matched );
130
131         return( 0 );
132 }
133
134 int
135 do_bind_real(
136     struct conn *dsaconn,
137     int         *bound,
138     char        **matched
139 )
140 {
141         struct ds_bind_arg      ba;
142         struct ds_bind_arg      br;
143         struct ds_bind_error    be;
144         struct DSError          dse;
145         char                    *dn = dsaconn->c_dn;
146         int                     err;
147 #ifdef HAVE_KERBEROS
148         u_long                  nonce;
149 #endif
150         extern DN               ldap_str2dn();
151
152         Debug( LDAP_DEBUG_TRACE, "do_bind_real\n", 0, 0, 0 );
153
154         *matched = NULL;
155         if ( (ba.dba_dn = ldap_str2dn( dn )) == NULLDN && *dn != '\0' ) {
156                 Debug( LDAP_DEBUG_ANY, "ldap_str2dn (%s) failed\n", dn, 0, 0 );
157                 return( LDAP_INVALID_DN_SYNTAX );
158         }
159
160         switch ( dsaconn->c_method ) {
161 #ifdef LDAP_COMPAT20
162         case OLD_LDAP_AUTH_SIMPLE:
163 #endif
164 #ifdef LDAP_COMPAT30
165         case LDAP_AUTH_SIMPLE_30:
166 #endif
167         case LDAP_AUTH_SIMPLE:  /* x.500 simple authentication */
168                 if ( dsaconn->c_credlen > DBA_MAX_PASSWD_LEN ) {
169                         Debug( LDAP_DEBUG_ANY, "Password too long\n", 0, 0, 0 );
170                         return( LDAP_INAPPROPRIATE_AUTH );
171                 }
172                 if (( ba.dba_passwd_len = dsaconn->c_credlen ) > 0 ) {
173                         SAFEMEMCPY( ba.dba_passwd, dsaconn->c_cred,
174                             ba.dba_passwd_len );
175                         ba.dba_auth_type = DBA_AUTH_SIMPLE;
176                 } else {
177                         ba.dba_auth_type = DBA_AUTH_NONE;
178                 }
179                 ba.dba_version = DBA_VERSION_V1988;
180                 break;
181
182 #ifdef HAVE_KERBEROS
183 #ifdef LDAP_COMPAT20
184         case OLD_LDAP_AUTH_KRBV4:
185 #endif
186 #ifdef LDAP_COMPAT30
187         case LDAP_AUTH_KRBV41_30:
188 #endif
189         case LDAP_AUTH_KRBV41:  /* kerberos authentication to ldap server */
190                 return( kerberosv4_ldap_auth( dsaconn->c_cred,
191                     dsaconn->c_credlen ) );
192                 break;
193
194 #ifdef LDAP_COMPAT20
195         case OLD_LDAP_AUTH_KRBV42:
196 #endif
197 #ifdef LDAP_COMPAT30
198         case LDAP_AUTH_KRBV42_30:
199 #endif
200         case LDAP_AUTH_KRBV42:  /* kerberos authentication to x500 dsa */
201                 if ( (err = kerberosv4_bindarg( &ba, ba.dba_dn, dsaconn->c_cred,
202                     dsaconn->c_credlen, &nonce )) != 0 )
203                         return( err );
204                 break;
205 #endif
206
207         default:
208                 return( LDAP_PROTOCOL_ERROR );
209                 break;
210         }
211
212         if ( dsaconn->c_ad != -1 )
213                 dap_unbind( dsaconn->c_ad );
214
215         Debug( LDAP_DEBUG_TRACE, "dap_bind to dsa (%s)...\n", paddr2str(
216             dsaconn->c_paddr, NULLNA ), 0, 0 );
217
218         err = dap_bind( &dsaconn->c_ad, &ba, &be, &br, dsaconn->c_paddr );
219
220         if ( err != DS_OK && ba.dba_dn != NULLDN && ba.dba_auth_type
221             == DBA_AUTH_NONE && be.dbe_type == DBE_TYPE_SECURITY ) {
222                 /* if doing a NULL bind, retry with a NULL dn */
223                 Debug( LDAP_DEBUG_TRACE, "retring NULL dap_bind\n", 0, 0, 0 );
224                 dn_free( ba.dba_dn );
225                 ba.dba_dn = NULLDN;
226                 err = dap_bind( &dsaconn->c_ad, &ba, &be, &br,
227                     dsaconn->c_paddr );
228         }
229
230         if ( err != DS_OK ) {
231                 if ( ba.dba_dn != NULLDN )
232                         dn_free( ba.dba_dn );
233
234                 if ( be.dbe_type == DBE_TYPE_SERVICE ) {
235                         dse.dse_type = DSE_SERVICEERROR;
236                         dse.ERR_SERVICE.DSE_sv_problem = be.dbe_value;
237                 } else if ( be.dbe_type == DBE_TYPE_SECURITY ) {
238                         dse.dse_type = DSE_SECURITYERROR;
239                         dse.ERR_SECURITY.DSE_sc_problem = be.dbe_value;
240                 } else {
241                         dse.dse_type = DSE_REMOTEERROR;
242                 }
243                 err = x500err2ldaperr( &dse, matched );
244
245 #ifdef LDAP_DEBUG
246                 if ( ldap_debug )
247                         print_error( &dse );    /* prints and then frees */
248                 else
249 #endif
250                         ds_error_free( &dse );
251
252                 dsaconn->c_ad = -1;
253
254                 return( err );
255         }
256         bind_arg_free( &br );
257
258         Debug( LDAP_DEBUG_TRACE, "dap_bind successful\n", 0, 0, 0 );
259
260 #ifdef HAVE_KERBEROS
261 /* XXX why doesn't this work??
262         if ( dsaconn->c_method == LDAP_AUTH_KRBV42 &&
263             kerberos_check_mutual( &br, nonce ) != 0 ) {
264                 Debug( LDAP_DEBUG_ANY, "Mutual authentication failed\n", 0, 0,
265                     0 );
266                 return( LDAP_INVALID_CREDENTIALS );
267         }
268 */
269 #endif
270
271         *bound = 1;
272
273         return( LDAP_SUCCESS );
274 }