2 * Copyright (c) 1990 Regents of the University of Michigan.
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.
14 #include <sys/types.h>
15 #include <sys/socket.h>
17 #include <netinet/in.h>
18 #include <quipu/commonarg.h>
19 #include <quipu/attrvalue.h>
20 #include <quipu/ds_error.h>
21 #include <quipu/bind.h>
22 #include <quipu/compare.h>
28 extern int ldap_compat;
29 #define BINDTAG (ldap_compat == 20 ? OLD_LDAP_RES_BIND : LDAP_RES_BIND)
31 #define BINDTAG LDAP_RES_BIND
35 * do_bind - perform an X.500 bind operation. Since we always respond
36 * to the request in here, always return 0 to signify the incoming message
53 struct PSAPaddr *addr, *psap_cpy();
54 extern char *dsa_address;
57 Debug( LDAP_DEBUG_TRACE, "do_bind\n", 0, 0, 0 );
60 * Parse the bind request. It looks like this:
61 * BindRequest ::= SEQUENCE {
62 * version INTEGER, -- version
63 * name DistinguishedName, -- dn
64 * authentication CHOICE {
65 * simple [0] OCTET STRING -- passwd
66 * krbv42ldap [1] OCTET STRING
67 * krbv42dsa [1] OCTET STRING
72 if ( ber_scanf( ber, "{ia", &version, &dn ) == LBER_ERROR ) {
73 Debug( LDAP_DEBUG_ANY, "ber_scanf failed\n", 0, 0, 0 );
74 send_ldap_msgresult( clientsb, BINDTAG, m,
75 LDAP_PROTOCOL_ERROR, NULL, "Decoding error" );
79 if ( ldap_compat == 30 )
80 method = ber_skip_tag( ber, &len );
83 method = ber_peek_tag( ber, &len );
85 if ( ber_scanf( ber, "la}", &len, &pw ) == LBER_ERROR ) {
86 Debug( LDAP_DEBUG_ANY, "ber_scanf2 failed\n", 0, 0, 0 );
87 send_ldap_msgresult( clientsb, BINDTAG, m,
88 LDAP_PROTOCOL_ERROR, NULL, "Decoding error" );
92 if ( version != LDAP_VERSION1 && version != LDAP_VERSION2 ) {
93 Debug( LDAP_DEBUG_ANY, "unknown version %d\n", version, 0, 0 );
94 send_ldap_msgresult( clientsb, BINDTAG, m,
95 LDAP_PROTOCOL_ERROR, NULL, "Version not supported" );
99 Debug( LDAP_DEBUG_ARGS, "do_bind: version %d dn (%s) method %d\n",
100 version, dn, method );
102 if ( m->m_conn->c_paddr == NULLPA ) {
105 sprintf( buf, "Bad DSA address (%s)", dsa_address ?
106 dsa_address : "NULL" );
107 send_ldap_msgresult( clientsb, BINDTAG, m,
108 LDAP_OPERATIONS_ERROR, NULL, buf );
112 if ( m->m_conn->c_dn )
113 free( m->m_conn->c_dn );
114 if ( m->m_conn->c_cred )
115 free( m->m_conn->c_cred );
116 m->m_conn->c_dn = dn;
117 m->m_conn->c_cred = pw;
118 m->m_conn->c_credlen = len;
119 m->m_conn->c_method = method;
121 err = do_bind_real( m->m_conn, bound, &matched );
123 send_ldap_msgresult( clientsb, BINDTAG, m, err, matched, "" );
125 if ( matched != NULL )
133 struct conn *dsaconn,
138 struct ds_bind_arg ba;
139 struct ds_bind_arg br;
140 struct ds_bind_error be;
142 char *dn = dsaconn->c_dn;
147 extern DN ldap_str2dn();
149 Debug( LDAP_DEBUG_TRACE, "do_bind_real\n", 0, 0, 0 );
152 if ( (ba.dba_dn = ldap_str2dn( dn )) == NULLDN && *dn != '\0' ) {
153 Debug( LDAP_DEBUG_ANY, "ldap_str2dn (%s) failed\n", dn, 0, 0 );
154 return( LDAP_INVALID_DN_SYNTAX );
157 switch ( dsaconn->c_method ) {
159 case OLD_LDAP_AUTH_SIMPLE:
162 case LDAP_AUTH_SIMPLE_30:
164 case LDAP_AUTH_SIMPLE: /* x.500 simple authentication */
165 if ( dsaconn->c_credlen > DBA_MAX_PASSWD_LEN ) {
166 Debug( LDAP_DEBUG_ANY, "Password too long\n", 0, 0, 0 );
167 return( LDAP_INAPPROPRIATE_AUTH );
169 if (( ba.dba_passwd_len = dsaconn->c_credlen ) > 0 ) {
170 SAFEMEMCPY( ba.dba_passwd, dsaconn->c_cred,
172 ba.dba_auth_type = DBA_AUTH_SIMPLE;
174 ba.dba_auth_type = DBA_AUTH_NONE;
176 ba.dba_version = DBA_VERSION_V1988;
181 case OLD_LDAP_AUTH_KRBV4:
184 case LDAP_AUTH_KRBV41_30:
186 case LDAP_AUTH_KRBV41: /* kerberos authentication to ldap server */
187 return( kerberosv4_ldap_auth( dsaconn->c_cred,
188 dsaconn->c_credlen ) );
192 case OLD_LDAP_AUTH_KRBV42:
195 case LDAP_AUTH_KRBV42_30:
197 case LDAP_AUTH_KRBV42: /* kerberos authentication to x500 dsa */
198 if ( (err = kerberosv4_bindarg( &ba, ba.dba_dn, dsaconn->c_cred,
199 dsaconn->c_credlen, &nonce )) != 0 )
205 return( LDAP_PROTOCOL_ERROR );
209 if ( dsaconn->c_ad != -1 )
210 dap_unbind( dsaconn->c_ad );
212 Debug( LDAP_DEBUG_TRACE, "dap_bind to dsa (%s)...\n", paddr2str(
213 dsaconn->c_paddr, NULLNA ), 0, 0 );
215 err = dap_bind( &dsaconn->c_ad, &ba, &be, &br, dsaconn->c_paddr );
217 if ( err != DS_OK && ba.dba_dn != NULLDN && ba.dba_auth_type
218 == DBA_AUTH_NONE && be.dbe_type == DBE_TYPE_SECURITY ) {
219 /* if doing a NULL bind, retry with a NULL dn */
220 Debug( LDAP_DEBUG_TRACE, "retring NULL dap_bind\n", 0, 0, 0 );
221 dn_free( ba.dba_dn );
223 err = dap_bind( &dsaconn->c_ad, &ba, &be, &br,
227 if ( err != DS_OK ) {
228 if ( ba.dba_dn != NULLDN )
229 dn_free( ba.dba_dn );
231 if ( be.dbe_type == DBE_TYPE_SERVICE ) {
232 dse.dse_type = DSE_SERVICEERROR;
233 dse.ERR_SERVICE.DSE_sv_problem = be.dbe_value;
234 } else if ( be.dbe_type == DBE_TYPE_SECURITY ) {
235 dse.dse_type = DSE_SECURITYERROR;
236 dse.ERR_SECURITY.DSE_sc_problem = be.dbe_value;
238 dse.dse_type = DSE_REMOTEERROR;
240 err = x500err2ldaperr( &dse, matched );
244 print_error( &dse ); /* prints and then frees */
247 ds_error_free( &dse );
253 bind_arg_free( &br );
255 Debug( LDAP_DEBUG_TRACE, "dap_bind successful\n", 0, 0, 0 );
258 /* XXX why doesn't this work??
259 if ( dsaconn->c_method == LDAP_AUTH_KRBV42 &&
260 kerberos_check_mutual( &br, nonce ) != 0 ) {
261 Debug( LDAP_DEBUG_ANY, "Mutual authentication failed\n", 0, 0,
263 return( LDAP_INVALID_CREDENTIALS );
270 return( LDAP_SUCCESS );