]> git.sur5r.net Git - openldap/blob - libraries/libldap/kbind.c
misc cleanup
[openldap] / libraries / libldap / kbind.c
1 /* $OpenLDAP$ */
2 /*
3  * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
4  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
5  */
6 /*  Portions
7  *  Copyright (c) 1993 Regents of the University of Michigan.
8  *  All rights reserved.
9  *
10  *  kbind.c
11  */
12
13 /*
14  *      BindRequest ::= SEQUENCE {
15  *              version         INTEGER,
16  *              name            DistinguishedName,       -- who
17  *              authentication  CHOICE {
18  *                      simple          [0] OCTET STRING -- passwd
19 #ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
20  *                      krbv42ldap      [1] OCTET STRING
21  *                      krbv42dsa       [2] OCTET STRING
22 #endif
23  *                      sasl            [3] SaslCredentials     -- LDAPv3
24  *              }
25  *      }
26  *
27  *      BindResponse ::= SEQUENCE {
28  *              COMPONENTS OF LDAPResult,
29  *              serverSaslCreds         OCTET STRING OPTIONAL -- LDAPv3
30  *      }
31  *
32  */
33
34 #include "portable.h"
35
36 #ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
37
38 #include <stdio.h>
39 #include <ac/stdlib.h>
40
41 #include <ac/krb.h>
42 #include <ac/socket.h>
43 #include <ac/string.h>
44 #include <ac/time.h>
45
46 #include "ldap-int.h"
47
48
49 /*
50  * ldap_kerberos_bind1 - initiate a bind to the ldap server using
51  * kerberos authentication.  The dn is supplied.  It is assumed the user
52  * already has a valid ticket granting ticket.  The msgid of the
53  * request is returned on success (suitable for passing to ldap_result()),
54  * -1 is returned if there's trouble.
55  *
56  * Example:
57  *      ldap_kerberos_bind1( ld, "cn=manager, o=university of michigan, c=us" )
58  */
59 int
60 ldap_kerberos_bind1( LDAP *ld, LDAP_CONST char *dn )
61 {
62         BerElement      *ber;
63         char            *cred;
64         int             rc;
65         ber_len_t credlen;
66
67         Debug( LDAP_DEBUG_TRACE, "ldap_kerberos_bind1\n", 0, 0, 0 );
68
69         if( ld->ld_version > LDAP_VERSION2 ) {
70                 ld->ld_errno = LDAP_NOT_SUPPORTED;
71                 return -1;
72         }
73
74         if ( dn == NULL )
75                 dn = "";
76
77         if ( (cred = ldap_get_kerberosv4_credentials( ld, dn, "ldapserver",
78             &credlen )) == NULL ) {
79                 return( -1 );   /* ld_errno should already be set */
80         }
81
82         /* create a message to send */
83         if ( (ber = ldap_alloc_ber_with_options( ld )) == NULL ) {
84                 LDAP_FREE( cred );
85                 return( -1 );
86         }
87
88         /* fill it in */
89         rc = ber_printf( ber, "{it{istoN}N}", ++ld->ld_msgid, LDAP_REQ_BIND,
90             ld->ld_version, dn, LDAP_AUTH_KRBV41, cred, credlen );
91
92         if ( rc == -1 ) {
93                 LDAP_FREE( cred );
94                 ber_free( ber, 1 );
95                 ld->ld_errno = LDAP_ENCODING_ERROR;
96                 return( -1 );
97         }
98
99         LDAP_FREE( cred );
100
101 #ifndef LDAP_NOCACHE
102         if ( ld->ld_cache != NULL ) {
103                 ldap_flush_cache( ld );
104         }
105 #endif /* !LDAP_NOCACHE */
106
107         /* send the message */
108         return ( ldap_send_initial_request( ld, LDAP_REQ_BIND, dn, ber ));
109 }
110
111 int
112 ldap_kerberos_bind1_s( LDAP *ld, LDAP_CONST char *dn )
113 {
114         int             msgid;
115         LDAPMessage     *res;
116
117         Debug( LDAP_DEBUG_TRACE, "ldap_kerberos_bind1_s\n", 0, 0, 0 );
118
119         /* initiate the bind */
120         if ( (msgid = ldap_kerberos_bind1( ld, dn )) == -1 )
121                 return( ld->ld_errno );
122
123         /* wait for a result */
124         if ( ldap_result( ld, ld->ld_msgid, 1, (struct timeval *) 0, &res )
125             == -1 ) {
126                 return( ld->ld_errno ); /* ldap_result sets ld_errno */
127         }
128
129         return( ldap_result2error( ld, res, 1 ) );
130 }
131
132 /*
133  * ldap_kerberos_bind2 - initiate a bind to the X.500 server using
134  * kerberos authentication.  The dn is supplied.  It is assumed the user
135  * already has a valid ticket granting ticket.  The msgid of the
136  * request is returned on success (suitable for passing to ldap_result()),
137  * -1 is returned if there's trouble.
138  *
139  * Example:
140  *      ldap_kerberos_bind2( ld, "cn=manager, o=university of michigan, c=us" )
141  */
142 int
143 ldap_kerberos_bind2( LDAP *ld, LDAP_CONST char *dn )
144 {
145         BerElement      *ber;
146         char            *cred;
147         int             rc;
148         ber_len_t credlen;
149
150         Debug( LDAP_DEBUG_TRACE, "ldap_kerberos_bind2\n", 0, 0, 0 );
151
152         if( ld->ld_version > LDAP_VERSION2 ) {
153                 ld->ld_errno = LDAP_NOT_SUPPORTED;
154                 return -1;
155         }
156
157         if ( dn == NULL )
158                 dn = "";
159
160         if ( (cred = ldap_get_kerberosv4_credentials( ld, dn, "x500dsa", &credlen ))
161             == NULL ) {
162                 return( -1 );   /* ld_errno should already be set */
163         }
164
165         /* create a message to send */
166         if ( (ber = ldap_alloc_ber_with_options( ld )) == NULL ) {
167                 LDAP_FREE( cred );
168                 return( -1 );
169         }
170
171         /* fill it in */
172         rc = ber_printf( ber, "{it{istoN}N}", ++ld->ld_msgid, LDAP_REQ_BIND,
173             ld->ld_version, dn, LDAP_AUTH_KRBV42, cred, credlen );
174
175
176         LDAP_FREE( cred );
177
178         if ( rc == -1 ) {
179                 ber_free( ber, 1 );
180                 ld->ld_errno = LDAP_ENCODING_ERROR;
181                 return( -1 );
182         }
183
184         /* send the message */
185         return ( ldap_send_initial_request( ld, LDAP_REQ_BIND, dn, ber ));
186 }
187
188 /* synchronous bind to DSA using kerberos */
189 int
190 ldap_kerberos_bind2_s( LDAP *ld, LDAP_CONST char *dn )
191 {
192         int             msgid;
193         LDAPMessage     *res;
194
195         Debug( LDAP_DEBUG_TRACE, "ldap_kerberos_bind2_s\n", 0, 0, 0 );
196
197         /* initiate the bind */
198         if ( (msgid = ldap_kerberos_bind2( ld, dn )) == -1 )
199                 return( ld->ld_errno );
200
201         /* wait for a result */
202         if ( ldap_result( ld, ld->ld_msgid, 1, (struct timeval *) 0, &res )
203             == -1 ) {
204                 return( ld->ld_errno ); /* ldap_result sets ld_errno */
205         }
206
207         return( ldap_result2error( ld, res, 1 ) );
208 }
209
210 /* synchronous bind to ldap and DSA using kerberos */
211 int
212 ldap_kerberos_bind_s( LDAP *ld, LDAP_CONST char *dn )
213 {
214         int     err;
215
216         Debug( LDAP_DEBUG_TRACE, "ldap_kerberos_bind_s\n", 0, 0, 0 );
217
218         if ( (err = ldap_kerberos_bind1_s( ld, dn )) != LDAP_SUCCESS )
219                 return( err );
220
221         return( ldap_kerberos_bind2_s( ld, dn ) );
222 }
223
224
225 #ifndef AUTHMAN
226 /*
227  * ldap_get_kerberosv4_credentials - obtain kerberos v4 credentials for ldap.
228  * The dn of the entry to which to bind is supplied.  It's assumed the
229  * user already has a tgt.
230  */
231
232 char *
233 ldap_get_kerberosv4_credentials(
234         LDAP *ld,
235         LDAP_CONST char *who,
236         LDAP_CONST char *service,
237         ber_len_t *len )
238 {
239         KTEXT_ST        ktxt;
240         int             err;
241         char            realm[REALM_SZ], *cred, *krbinstance;
242
243         Debug( LDAP_DEBUG_TRACE, "ldap_get_kerberosv4_credentials\n", 0, 0, 0 );
244
245         if ( (err = krb_get_tf_realm( tkt_string(), realm )) != KSUCCESS ) {
246                 Debug( LDAP_DEBUG_ANY, "ldap_get_kerberosv4_credentials: "
247                         "krb_get_tf_realm failed: %s\n", krb_err_txt[err], 0, 0 );
248                 ld->ld_errno = LDAP_AUTH_UNKNOWN;
249                 return( NULL );
250         }
251
252         if ( ber_sockbuf_ctrl( ld->ld_sb, LBER_SB_OPT_GET_FD, NULL ) == -1 ) {
253                 /* not connected yet */
254                 int rc = ldap_open_defconn( ld );
255
256                 if( rc < 0 ) return NULL;
257         }
258
259         krbinstance = ld->ld_defconn->lconn_krbinstance;
260
261         if ( (err = krb_mk_req( &ktxt, service, krbinstance, realm, 0 ))
262             != KSUCCESS )
263         {
264                 Debug( LDAP_DEBUG_ANY, "ldap_get_kerberosv4_credentials: "
265                         "krb_mk_req failed (%s)\n", krb_err_txt[err], 0, 0 );
266                 ld->ld_errno = LDAP_AUTH_UNKNOWN;
267                 return( NULL );
268         }
269
270         if ( ( cred = LDAP_MALLOC( ktxt.length )) == NULL ) {
271                 ld->ld_errno = LDAP_NO_MEMORY;
272                 return( NULL );
273         }
274
275         *len = ktxt.length;
276         AC_MEMCPY( cred, ktxt.dat, ktxt.length );
277
278         return( cred );
279 }
280
281 #endif /* !AUTHMAN */
282 #endif /* LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND */