2 * Copyright 2002-2003 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
6 #pragma ident "%Z%%M% %I% %E% SMI"
9 * The contents of this file are subject to the Netscape Public
10 * License Version 1.1 (the "License"); you may not use this file
11 * except in compliance with the License. You may obtain a copy of
12 * the License at http://www.mozilla.org/NPL/
14 * Software distributed under the License is distributed on an "AS
15 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
16 * implied. See the License for the specific language governing
17 * rights and limitations under the License.
19 * The Original Code is Mozilla Communicator client code, released
22 * The Initial Developer of the Original Code is Netscape
23 * Communications Corporation. Portions created by Netscape are
24 * Copyright (C) 1998-1999 Netscape Communications Corporation. All
30 * Copyright (c) 1990 Regents of the University of Michigan.
31 * All rights reserved.
40 static char copyright
[] = "@(#) Copyright (c) 1990 Regents of the University of Michigan.\nAll rights reserved.\n";
48 ldap_unbind( LDAP
*ld
)
50 LDAPDebug( LDAP_DEBUG_TRACE
, "ldap_unbind\n", 0, 0, 0 );
52 return( ldap_ld_free( ld
, NULL
, NULL
, 1 ) );
58 ldap_unbind_s( LDAP
*ld
)
60 return( ldap_ld_free( ld
, NULL
, NULL
, 1 ));
66 ldap_unbind_ext( LDAP
*ld
, LDAPControl
**serverctrls
,
67 LDAPControl
**clientctrls
)
69 return( ldap_ld_free( ld
, serverctrls
, clientctrls
, 1 ));
74 * Dispose of the LDAP session ld, including all associated connections
75 * and resources. If close is non-zero, an unbind() request is sent as well.
78 ldap_ld_free( LDAP
*ld
, LDAPControl
**serverctrls
,
79 LDAPControl
**clientctrls
, int close
)
81 LDAPMessage
*lm
, *next
;
82 int err
= LDAP_SUCCESS
;
83 LDAPRequest
*lr
, *nextlr
;
85 if ( !NSLDAPI_VALID_LDAP_POINTER( ld
)) {
86 return( LDAP_PARAM_ERROR
);
89 if ( ld
->ld_sbp
->sb_naddr
== 0 ) {
90 LDAP_MUTEX_LOCK( ld
, LDAP_REQ_LOCK
);
91 /* free LDAP structure and outstanding requests/responses */
92 for ( lr
= ld
->ld_requests
; lr
!= NULL
; lr
= nextlr
) {
94 nsldapi_free_request( ld
, lr
, 0 );
96 LDAP_MUTEX_UNLOCK( ld
, LDAP_REQ_LOCK
);
98 /* free and unbind from all open connections */
99 LDAP_MUTEX_LOCK( ld
, LDAP_CONN_LOCK
);
100 while ( ld
->ld_conns
!= NULL
) {
101 nsldapi_free_connection( ld
, ld
->ld_conns
, serverctrls
,
102 clientctrls
, 1, close
);
104 LDAP_MUTEX_UNLOCK( ld
, LDAP_CONN_LOCK
);
109 for ( i
= 0; i
< ld
->ld_sbp
->sb_naddr
; ++i
) {
110 NSLDAPI_FREE( ld
->ld_sbp
->sb_addrs
[ i
] );
112 NSLDAPI_FREE( ld
->ld_sbp
->sb_addrs
);
113 NSLDAPI_FREE( ld
->ld_sbp
->sb_fromaddr
);
116 LDAP_MUTEX_LOCK( ld
, LDAP_RESP_LOCK
);
117 for ( lm
= ld
->ld_responses
; lm
!= NULL
; lm
= next
) {
121 LDAP_MUTEX_UNLOCK( ld
, LDAP_RESP_LOCK
);
123 /* call cache unbind function to allow it to clean up after itself */
124 if ( ld
->ld_cache_unbind
!= NULL
) {
125 LDAP_MUTEX_LOCK( ld
, LDAP_CACHE_LOCK
);
126 (void)ld
->ld_cache_unbind( ld
, 0, 0 );
127 LDAP_MUTEX_UNLOCK( ld
, LDAP_CACHE_LOCK
);
130 /* call the dispose handle I/O callback if one is defined */
131 if ( ld
->ld_extdisposehandle_fn
!= NULL
) {
133 * We always pass the session extended I/O argument to
134 * the dispose handle callback.
136 ld
->ld_extdisposehandle_fn( ld
, ld
->ld_ext_session_arg
);
139 if ( ld
->ld_error
!= NULL
)
140 NSLDAPI_FREE( ld
->ld_error
);
141 if ( ld
->ld_matched
!= NULL
)
142 NSLDAPI_FREE( ld
->ld_matched
);
143 if ( ld
->ld_host
!= NULL
)
144 NSLDAPI_FREE( ld
->ld_host
);
145 if ( ld
->ld_ufnprefix
!= NULL
)
146 NSLDAPI_FREE( ld
->ld_ufnprefix
);
147 if ( ld
->ld_filtd
!= NULL
)
148 ldap_getfilter_free( ld
->ld_filtd
);
149 if ( ld
->ld_abandoned
!= NULL
)
150 NSLDAPI_FREE( ld
->ld_abandoned
);
151 if ( ld
->ld_sbp
!= NULL
)
152 ber_sockbuf_free( ld
->ld_sbp
);
153 if ( ld
->ld_defhost
!= NULL
)
154 NSLDAPI_FREE( ld
->ld_defhost
);
155 if ( ld
->ld_servercontrols
!= NULL
)
156 ldap_controls_free( ld
->ld_servercontrols
);
157 if ( ld
->ld_clientcontrols
!= NULL
)
158 ldap_controls_free( ld
->ld_clientcontrols
);
159 if ( ld
->ld_preferred_language
!= NULL
)
160 NSLDAPI_FREE( ld
->ld_preferred_language
);
161 nsldapi_iostatus_free( ld
);
162 #ifdef LDAP_SASLIO_HOOKS
163 if ( ld
->ld_def_sasl_mech
!= NULL
)
164 NSLDAPI_FREE( ld
->ld_def_sasl_mech
);
165 if ( ld
->ld_def_sasl_realm
!= NULL
)
166 NSLDAPI_FREE( ld
->ld_def_sasl_realm
);
167 if ( ld
->ld_def_sasl_authcid
!= NULL
)
168 NSLDAPI_FREE( ld
->ld_def_sasl_authcid
);
169 if ( ld
->ld_def_sasl_authzid
!= NULL
)
170 NSLDAPI_FREE( ld
->ld_def_sasl_authzid
);
174 * XXXmcs: should use cache function pointers to hook in memcache
176 if ( ld
->ld_memcache
!= NULL
) {
177 ldap_memcache_set( ld
, NULL
);
180 /* free all mutexes we have allocated */
181 nsldapi_mutex_free_all( ld
);
182 NSLDAPI_FREE( ld
->ld_mutex
);
184 NSLDAPI_FREE( (char *) ld
);
192 nsldapi_send_unbind( LDAP
*ld
, Sockbuf
*sb
, LDAPControl
**serverctrls
,
193 LDAPControl
**clientctrls
)
198 LDAPDebug( LDAP_DEBUG_TRACE
, "nsldapi_send_unbind\n", 0, 0, 0 );
200 /* create a message to send */
201 if (( err
= nsldapi_alloc_ber_with_options( ld
, &ber
))
207 LDAP_MUTEX_LOCK( ld
, LDAP_MSGID_LOCK
);
208 msgid
= ++ld
->ld_msgid
;
209 LDAP_MUTEX_UNLOCK( ld
, LDAP_MSGID_LOCK
);
211 if ( ber_printf( ber
, "{itn", msgid
, LDAP_REQ_UNBIND
) == -1 ) {
213 err
= LDAP_ENCODING_ERROR
;
214 LDAP_SET_LDERRNO( ld
, err
, NULL
, NULL
);
218 if (( err
= nsldapi_put_controls( ld
, serverctrls
, 1, ber
))
224 /* send the message */
225 if ( nsldapi_ber_flush( ld
, sb
, ber
, 1, 0 ) != 0 ) {
227 err
= LDAP_SERVER_DOWN
;
228 LDAP_SET_LDERRNO( ld
, err
, NULL
, NULL
);
232 return( LDAP_SUCCESS
);