1 /*
2 * Copyright 2002-2003 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
4 */
5
6 #pragma ident "%Z%%M% %I% %E% SMI"
7
8 /*
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/
13 *
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.
18 *
19 * The Original Code is Mozilla Communicator client code, released
20 * March 31, 1998.
21 *
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
25 * Rights Reserved.
26 *
27 * Contributor(s):
28 */
29 /*
30 * Copyright (c) 1990 Regents of the University of Michigan.
31 * All rights reserved.
32 */
33
34 /*
35 * unbind.c
36 */
37
38 #if 0
39 #ifndef lint
40 static char copyright[] = "@(#) Copyright (c) 1990 Regents of the University of Michigan.\nAll rights reserved.\n";
41 #endif
42 #endif
43
44 #include "ldap-int.h"
45
46 int
47 LDAP_CALL
ldap_unbind(LDAP * ld)48 ldap_unbind( LDAP *ld )
49 {
50 LDAPDebug( LDAP_DEBUG_TRACE, "ldap_unbind\n", 0, 0, 0 );
51
52 return( ldap_ld_free( ld, NULL, NULL, 1 ) );
53 }
54
55
56 int
57 LDAP_CALL
ldap_unbind_s(LDAP * ld)58 ldap_unbind_s( LDAP *ld )
59 {
60 return( ldap_ld_free( ld, NULL, NULL, 1 ));
61 }
62
63
64 int
65 LDAP_CALL
ldap_unbind_ext(LDAP * ld,LDAPControl ** serverctrls,LDAPControl ** clientctrls)66 ldap_unbind_ext( LDAP *ld, LDAPControl **serverctrls,
67 LDAPControl **clientctrls )
68 {
69 return( ldap_ld_free( ld, serverctrls, clientctrls, 1 ));
70 }
71
72
73 /*
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.
76 */
77 int
ldap_ld_free(LDAP * ld,LDAPControl ** serverctrls,LDAPControl ** clientctrls,int close)78 ldap_ld_free( LDAP *ld, LDAPControl **serverctrls,
79 LDAPControl **clientctrls, int close )
80 {
81 LDAPMessage *lm, *next;
82 int err = LDAP_SUCCESS;
83 LDAPRequest *lr, *nextlr;
84
85 if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
86 return( LDAP_PARAM_ERROR );
87 }
88
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 ) {
93 nextlr = lr->lr_next;
94 nsldapi_free_request( ld, lr, 0 );
95 }
96 LDAP_MUTEX_UNLOCK( ld, LDAP_REQ_LOCK );
97
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 );
103 }
104 LDAP_MUTEX_UNLOCK( ld, LDAP_CONN_LOCK );
105
106 } else {
107 int i;
108
109 for ( i = 0; i < ld->ld_sbp->sb_naddr; ++i ) {
110 NSLDAPI_FREE( ld->ld_sbp->sb_addrs[ i ] );
111 }
112 NSLDAPI_FREE( ld->ld_sbp->sb_addrs );
113 NSLDAPI_FREE( ld->ld_sbp->sb_fromaddr );
114 }
115
116 LDAP_MUTEX_LOCK( ld, LDAP_RESP_LOCK );
117 for ( lm = ld->ld_responses; lm != NULL; lm = next ) {
118 next = lm->lm_next;
119 ldap_msgfree( lm );
120 }
121 LDAP_MUTEX_UNLOCK( ld, LDAP_RESP_LOCK );
122
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 );
128 }
129
130 /* call the dispose handle I/O callback if one is defined */
131 if ( ld->ld_extdisposehandle_fn != NULL ) {
132 /*
133 * We always pass the session extended I/O argument to
134 * the dispose handle callback.
135 */
136 ld->ld_extdisposehandle_fn( ld, ld->ld_ext_session_arg );
137 }
138
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 );
171 #endif
172
173 /*
174 * XXXmcs: should use cache function pointers to hook in memcache
175 */
176 if ( ld->ld_memcache != NULL ) {
177 ldap_memcache_set( ld, NULL );
178 }
179
180 /* free all mutexes we have allocated */
181 nsldapi_mutex_free_all( ld );
182 NSLDAPI_FREE( ld->ld_mutex );
183
184 NSLDAPI_FREE( (char *) ld );
185
186 return( err );
187 }
188
189
190
191 int
nsldapi_send_unbind(LDAP * ld,Sockbuf * sb,LDAPControl ** serverctrls,LDAPControl ** clientctrls)192 nsldapi_send_unbind( LDAP *ld, Sockbuf *sb, LDAPControl **serverctrls,
193 LDAPControl **clientctrls )
194 {
195 BerElement *ber;
196 int err, msgid;
197
198 LDAPDebug( LDAP_DEBUG_TRACE, "nsldapi_send_unbind\n", 0, 0, 0 );
199
200 /* create a message to send */
201 if (( err = nsldapi_alloc_ber_with_options( ld, &ber ))
202 != LDAP_SUCCESS ) {
203 return( err );
204 }
205
206 /* fill it in */
207 LDAP_MUTEX_LOCK( ld, LDAP_MSGID_LOCK );
208 msgid = ++ld->ld_msgid;
209 LDAP_MUTEX_UNLOCK( ld, LDAP_MSGID_LOCK );
210
211 if ( ber_printf( ber, "{itn", msgid, LDAP_REQ_UNBIND ) == -1 ) {
212 ber_free( ber, 1 );
213 err = LDAP_ENCODING_ERROR;
214 LDAP_SET_LDERRNO( ld, err, NULL, NULL );
215 return( err );
216 }
217
218 if (( err = nsldapi_put_controls( ld, serverctrls, 1, ber ))
219 != LDAP_SUCCESS ) {
220 ber_free( ber, 1 );
221 return( err );
222 }
223
224 /* send the message */
225 if ( nsldapi_ber_flush( ld, sb, ber, 1, 0 ) != 0 ) {
226 ber_free( ber, 1 );
227 err = LDAP_SERVER_DOWN;
228 LDAP_SET_LDERRNO( ld, err, NULL, NULL );
229 return( err );
230 }
231
232 return( LDAP_SUCCESS );
233 }
234