1 /* $OpenLDAP: pkg/ldap/libraries/libldap/unbind.c,v 1.56.2.4 2008/02/11 23:26:41 kurt Exp $ */
2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4 * Copyright 1998-2008 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) 1990 Regents of the University of Michigan.
16 * All rights reserved.
22 #include <ac/stdlib.h>
24 #include <ac/socket.h>
25 #include <ac/string.h>
30 /* An Unbind Request looks like this:
32 * UnbindRequest ::= [APPLICATION 2] NULL
34 * and has no response. (Source: RFC 4511)
41 LDAPControl
**cctrls
)
46 assert( LDAP_VALID( ld
) );
48 /* check client controls */
49 rc
= ldap_int_client_controls( ld
, cctrls
);
50 if( rc
!= LDAP_SUCCESS
) return rc
;
52 return ldap_ld_free( ld
, 1, sctrls
, cctrls
);
59 LDAPControl
**cctrls
)
61 return ldap_unbind_ext( ld
, sctrls
, cctrls
);
65 ldap_unbind( LDAP
*ld
)
67 Debug( LDAP_DEBUG_TRACE
, "ldap_unbind\n", 0, 0, 0 );
69 return( ldap_unbind_ext( ld
, NULL
, NULL
) );
78 LDAPControl
**cctrls
)
80 LDAPMessage
*lm
, *next
;
81 int err
= LDAP_SUCCESS
;
83 /* free LDAP structure and outstanding requests/responses */
85 ldap_pvt_thread_mutex_lock( &ld
->ld_req_mutex
);
87 while ( ld
->ld_requests
!= NULL
) {
88 ldap_free_request( ld
, ld
->ld_requests
);
91 /* free and unbind from all open connections */
92 while ( ld
->ld_conns
!= NULL
) {
93 ldap_free_connection( ld
, ld
->ld_conns
, 1, close
);
96 ldap_pvt_thread_mutex_unlock( &ld
->ld_req_mutex
);
100 ldap_pvt_thread_mutex_lock( &ld
->ld_res_mutex
);
102 for ( lm
= ld
->ld_responses
; lm
!= NULL
; lm
= next
) {
107 if ( ld
->ld_abandoned
!= NULL
) {
108 LDAP_FREE( ld
->ld_abandoned
);
109 ld
->ld_abandoned
= NULL
;
111 #ifdef LDAP_R_COMPILE
112 ldap_pvt_thread_mutex_unlock( &ld
->ld_res_mutex
);
115 if ( ld
->ld_error
!= NULL
) {
116 LDAP_FREE( ld
->ld_error
);
120 if ( ld
->ld_matched
!= NULL
) {
121 LDAP_FREE( ld
->ld_matched
);
122 ld
->ld_matched
= NULL
;
125 if( ld
->ld_referrals
!= NULL
) {
126 LDAP_VFREE(ld
->ld_referrals
);
127 ld
->ld_referrals
= NULL
;
130 if ( ld
->ld_selectinfo
!= NULL
) {
131 ldap_free_select_info( ld
->ld_selectinfo
);
132 ld
->ld_selectinfo
= NULL
;
135 if ( ld
->ld_options
.ldo_defludp
!= NULL
) {
136 ldap_free_urllist( ld
->ld_options
.ldo_defludp
);
137 ld
->ld_options
.ldo_defludp
= NULL
;
140 #ifdef LDAP_CONNECTIONLESS
141 if ( ld
->ld_options
.ldo_peer
!= NULL
) {
142 LDAP_FREE( ld
->ld_options
.ldo_peer
);
143 ld
->ld_options
.ldo_peer
= NULL
;
147 #ifdef HAVE_CYRUS_SASL
148 if ( ld
->ld_options
.ldo_def_sasl_mech
!= NULL
) {
149 LDAP_FREE( ld
->ld_options
.ldo_def_sasl_mech
);
150 ld
->ld_options
.ldo_def_sasl_mech
= NULL
;
153 if ( ld
->ld_options
.ldo_def_sasl_realm
!= NULL
) {
154 LDAP_FREE( ld
->ld_options
.ldo_def_sasl_realm
);
155 ld
->ld_options
.ldo_def_sasl_realm
= NULL
;
158 if ( ld
->ld_options
.ldo_def_sasl_authcid
!= NULL
) {
159 LDAP_FREE( ld
->ld_options
.ldo_def_sasl_authcid
);
160 ld
->ld_options
.ldo_def_sasl_authcid
= NULL
;
163 if ( ld
->ld_options
.ldo_def_sasl_authzid
!= NULL
) {
164 LDAP_FREE( ld
->ld_options
.ldo_def_sasl_authzid
);
165 ld
->ld_options
.ldo_def_sasl_authzid
= NULL
;
170 ldap_int_tls_destroy( &ld
->ld_options
);
173 if ( ld
->ld_options
.ldo_sctrls
!= NULL
) {
174 ldap_controls_free( ld
->ld_options
.ldo_sctrls
);
175 ld
->ld_options
.ldo_sctrls
= NULL
;
178 if ( ld
->ld_options
.ldo_cctrls
!= NULL
) {
179 ldap_controls_free( ld
->ld_options
.ldo_cctrls
);
180 ld
->ld_options
.ldo_cctrls
= NULL
;
183 ber_sockbuf_free( ld
->ld_sb
);
185 #ifdef LDAP_R_COMPILE
186 ldap_pvt_thread_mutex_destroy( &ld
->ld_req_mutex
);
187 ldap_pvt_thread_mutex_destroy( &ld
->ld_res_mutex
);
188 ldap_pvt_thread_mutex_destroy( &ld
->ld_conn_mutex
);
193 LDAP_FREE( (char *) ld
);
199 ldap_unbind_s( LDAP
*ld
)
201 return( ldap_unbind_ext( ld
, NULL
, NULL
) );
204 /* FIXME: this function is called only by ldap_free_connection(),
205 * which, most of the times, is called with ld_req_mutex locked */
210 LDAPControl
**sctrls
,
211 LDAPControl
**cctrls
)
216 Debug( LDAP_DEBUG_TRACE
, "ldap_send_unbind\n", 0, 0, 0 );
218 #ifdef LDAP_CONNECTIONLESS
222 /* create a message to send */
223 if ( (ber
= ldap_alloc_ber_with_options( ld
)) == NULL
) {
224 return( ld
->ld_errno
);
227 id
= ++(ld
)->ld_msgid
;
230 if ( ber_printf( ber
, "{itn" /*}*/, id
,
231 LDAP_REQ_UNBIND
) == -1 ) {
232 ld
->ld_errno
= LDAP_ENCODING_ERROR
;
234 return( ld
->ld_errno
);
237 /* Put Server Controls */
238 if( ldap_int_put_controls( ld
, sctrls
, ber
) != LDAP_SUCCESS
) {
243 if ( ber_printf( ber
, /*{*/ "N}", LDAP_REQ_UNBIND
) == -1 ) {
244 ld
->ld_errno
= LDAP_ENCODING_ERROR
;
246 return( ld
->ld_errno
);
249 ld
->ld_errno
= LDAP_SUCCESS
;
250 /* send the message */
251 if ( ber_flush2( sb
, ber
, LBER_FLUSH_FREE_ALWAYS
) == -1 ) {
252 ld
->ld_errno
= LDAP_SERVER_DOWN
;
255 return( ld
->ld_errno
);