2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4 * Copyright 1998-2005 The OpenLDAP Foundation.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted only as authorized by the OpenLDAP
11 * A copy of this license is available in the file LICENSE in the
12 * top-level directory of the distribution or, alternatively, at
13 * <http://www.OpenLDAP.org/license.html>.
15 /* Portions Copyright (c) 1993 Regents of the University of Michigan.
16 * All rights reserved.
18 /* Portions Copyright (C) The Internet Society (1997)
19 * ASN.1 fragments are from RFC 2251; see RFC for full legal notices.
23 * BindRequest ::= SEQUENCE {
25 * name DistinguishedName, -- who
26 * authentication CHOICE {
27 * simple [0] OCTET STRING -- passwd
28 #ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
29 * krbv42ldap [1] OCTET STRING
30 * krbv42dsa [2] OCTET STRING
32 * sasl [3] SaslCredentials -- LDAPv3
36 * BindResponse ::= SEQUENCE {
37 * COMPONENTS OF LDAPResult,
38 * serverSaslCreds OCTET STRING OPTIONAL -- LDAPv3
45 #ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
48 #include <ac/stdlib.h>
51 #include <ac/socket.h>
52 #include <ac/string.h>
58 * ldap_kerberos_bind1 - initiate a bind to the ldap server using
59 * kerberos authentication. The dn is supplied. It is assumed the user
60 * already has a valid ticket granting ticket. The msgid of the
61 * request is returned on success (suitable for passing to ldap_result()),
62 * -1 is returned if there's trouble.
65 * ldap_kerberos_bind1( ld, "cn=manager, o=university of michigan, c=us" )
68 ldap_kerberos_bind1( LDAP *ld, LDAP_CONST char *dn )
76 Debug( LDAP_DEBUG_TRACE, "ldap_kerberos_bind1\n", 0, 0, 0 );
78 if( ld->ld_version > LDAP_VERSION2 ) {
79 ld->ld_errno = LDAP_NOT_SUPPORTED;
86 if ( (cred = ldap_get_kerberosv4_credentials( ld, dn, "ldapserver",
87 &credlen )) == NULL ) {
88 return( -1 ); /* ld_errno should already be set */
91 /* create a message to send */
92 if ( (ber = ldap_alloc_ber_with_options( ld )) == NULL ) {
97 LDAP_NEXT_MSGID( ld, id );
99 rc = ber_printf( ber, "{it{istoN}N}", id, LDAP_REQ_BIND,
100 ld->ld_version, dn, LDAP_AUTH_KRBV41, cred, credlen );
105 ld->ld_errno = LDAP_ENCODING_ERROR;
112 /* send the message */
113 return ( ldap_send_initial_request( ld, LDAP_REQ_BIND, dn, ber, id ));
117 ldap_kerberos_bind1_s( LDAP *ld, LDAP_CONST char *dn )
122 Debug( LDAP_DEBUG_TRACE, "ldap_kerberos_bind1_s\n", 0, 0, 0 );
124 /* initiate the bind */
125 if ( (msgid = ldap_kerberos_bind1( ld, dn )) == -1 )
126 return( ld->ld_errno );
128 /* wait for a result */
129 if ( ldap_result( ld, msgid, LDAP_MSG_ALL, (struct timeval *) 0, &res )
131 return( ld->ld_errno ); /* ldap_result sets ld_errno */
134 return( ldap_result2error( ld, res, 1 ) );
138 * ldap_kerberos_bind2 - initiate a bind to the X.500 server using
139 * kerberos authentication. The dn is supplied. It is assumed the user
140 * already has a valid ticket granting ticket. The msgid of the
141 * request is returned on success (suitable for passing to ldap_result()),
142 * -1 is returned if there's trouble.
145 * ldap_kerberos_bind2( ld, "cn=manager, o=university of michigan, c=us" )
148 ldap_kerberos_bind2( LDAP *ld, LDAP_CONST char *dn )
156 Debug( LDAP_DEBUG_TRACE, "ldap_kerberos_bind2\n", 0, 0, 0 );
158 if( ld->ld_version > LDAP_VERSION2 ) {
159 ld->ld_errno = LDAP_NOT_SUPPORTED;
166 if ( (cred = ldap_get_kerberosv4_credentials( ld, dn, "x500dsa", &credlen ))
168 return( -1 ); /* ld_errno should already be set */
171 /* create a message to send */
172 if ( (ber = ldap_alloc_ber_with_options( ld )) == NULL ) {
177 LDAP_NEXT_MSGID( ld, id );
179 rc = ber_printf( ber, "{it{istoN}N}", id, LDAP_REQ_BIND,
180 ld->ld_version, dn, LDAP_AUTH_KRBV42, cred, credlen );
186 ld->ld_errno = LDAP_ENCODING_ERROR;
190 /* send the message */
191 return ( ldap_send_initial_request( ld, LDAP_REQ_BIND, dn, ber, id ));
194 /* synchronous bind to DSA using kerberos */
196 ldap_kerberos_bind2_s( LDAP *ld, LDAP_CONST char *dn )
201 Debug( LDAP_DEBUG_TRACE, "ldap_kerberos_bind2_s\n", 0, 0, 0 );
203 /* initiate the bind */
204 if ( (msgid = ldap_kerberos_bind2( ld, dn )) == -1 )
205 return( ld->ld_errno );
207 /* wait for a result */
208 if ( ldap_result( ld, msgid, LDAP_MSG_ALL, (struct timeval *) 0, &res )
210 return( ld->ld_errno ); /* ldap_result sets ld_errno */
213 return( ldap_result2error( ld, res, 1 ) );
216 /* synchronous bind to ldap and DSA using kerberos */
218 ldap_kerberos_bind_s( LDAP *ld, LDAP_CONST char *dn )
222 Debug( LDAP_DEBUG_TRACE, "ldap_kerberos_bind_s\n", 0, 0, 0 );
224 if ( (err = ldap_kerberos_bind1_s( ld, dn )) != LDAP_SUCCESS )
227 return( ldap_kerberos_bind2_s( ld, dn ) );
233 * ldap_get_kerberosv4_credentials - obtain kerberos v4 credentials for ldap.
234 * The dn of the entry to which to bind is supplied. It's assumed the
235 * user already has a tgt.
239 ldap_get_kerberosv4_credentials(
241 LDAP_CONST char *who,
242 LDAP_CONST char *service,
247 char realm[REALM_SZ], *cred, *krbinstance;
249 Debug( LDAP_DEBUG_TRACE, "ldap_get_kerberosv4_credentials\n", 0, 0, 0 );
251 if ( (err = krb_get_tf_realm( tkt_string(), realm )) != KSUCCESS ) {
252 Debug( LDAP_DEBUG_ANY, "ldap_get_kerberosv4_credentials: "
253 "krb_get_tf_realm failed: %s\n", krb_err_txt[err], 0, 0 );
254 ld->ld_errno = LDAP_AUTH_UNKNOWN;
258 if ( ber_sockbuf_ctrl( ld->ld_sb, LBER_SB_OPT_GET_FD, NULL ) == -1 ) {
259 /* not connected yet */
260 int rc = ldap_open_defconn( ld );
262 if( rc < 0 ) return NULL;
265 krbinstance = ld->ld_defconn->lconn_krbinstance;
267 if ( (err = krb_mk_req( &ktxt, service, krbinstance, realm, 0 ))
270 Debug( LDAP_DEBUG_ANY, "ldap_get_kerberosv4_credentials: "
271 "krb_mk_req failed (%s)\n", krb_err_txt[err], 0, 0 );
272 ld->ld_errno = LDAP_AUTH_UNKNOWN;
276 if ( ( cred = LDAP_MALLOC( ktxt.length )) == NULL ) {
277 ld->ld_errno = LDAP_NO_MEMORY;
282 AC_MEMCPY( cred, ktxt.dat, ktxt.length );
287 #endif /* !AUTHMAN */
288 #endif /* LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND */