Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/libs/ldap/libldap/unbind.c
4394 views
1
/* $OpenLDAP$ */
2
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
3
*
4
* Copyright 1998-2024 The OpenLDAP Foundation.
5
* All rights reserved.
6
*
7
* Redistribution and use in source and binary forms, with or without
8
* modification, are permitted only as authorized by the OpenLDAP
9
* Public License.
10
*
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>.
14
*/
15
/* Portions Copyright (c) 1990 Regents of the University of Michigan.
16
* All rights reserved.
17
*/
18
19
#include "portable.h"
20
21
#include <stdio.h>
22
#include <ac/stdlib.h>
23
24
#include <ac/socket.h>
25
#include <ac/string.h>
26
#include <ac/time.h>
27
28
#include "ldap-int.h"
29
30
/* An Unbind Request looks like this:
31
*
32
* UnbindRequest ::= [APPLICATION 2] NULL
33
*
34
* and has no response. (Source: RFC 4511)
35
*/
36
37
int
38
ldap_unbind_ext(
39
LDAP *ld,
40
LDAPControl **sctrls,
41
LDAPControl **cctrls )
42
{
43
int rc;
44
45
assert( ld != NULL );
46
assert( LDAP_VALID( ld ) );
47
48
/* check client controls */
49
rc = ldap_int_client_controls( ld, cctrls );
50
if( rc != LDAP_SUCCESS ) return rc;
51
52
return ldap_ld_free( ld, 1, sctrls, cctrls );
53
}
54
55
int
56
ldap_unbind_ext_s(
57
LDAP *ld,
58
LDAPControl **sctrls,
59
LDAPControl **cctrls )
60
{
61
return ldap_unbind_ext( ld, sctrls, cctrls );
62
}
63
64
int
65
ldap_unbind( LDAP *ld )
66
{
67
Debug0( LDAP_DEBUG_TRACE, "ldap_unbind\n" );
68
69
return( ldap_unbind_ext( ld, NULL, NULL ) );
70
}
71
72
73
int
74
ldap_ld_free(
75
LDAP *ld,
76
int close,
77
LDAPControl **sctrls,
78
LDAPControl **cctrls )
79
{
80
LDAPMessage *lm, *next;
81
int err = LDAP_SUCCESS;
82
83
LDAP_MUTEX_LOCK( &ld->ld_ldcmutex );
84
/* Someone else is still using this ld. */
85
if (ld->ld_ldcrefcnt > 1) { /* but not last thread */
86
/* clean up self only */
87
ld->ld_ldcrefcnt--;
88
if ( ld->ld_error != NULL ) {
89
LDAP_FREE( ld->ld_error );
90
ld->ld_error = NULL;
91
}
92
93
if ( ld->ld_matched != NULL ) {
94
LDAP_FREE( ld->ld_matched );
95
ld->ld_matched = NULL;
96
}
97
if ( ld->ld_referrals != NULL) {
98
LDAP_VFREE(ld->ld_referrals);
99
ld->ld_referrals = NULL;
100
}
101
LDAP_MUTEX_UNLOCK( &ld->ld_ldcmutex );
102
LDAP_FREE( (char *) ld );
103
return( err );
104
}
105
106
/* This ld is the last thread. */
107
LDAP_MUTEX_UNLOCK( &ld->ld_ldcmutex );
108
109
/* free LDAP structure and outstanding requests/responses */
110
LDAP_MUTEX_LOCK( &ld->ld_req_mutex );
111
ldap_tavl_free( ld->ld_requests, ldap_do_free_request );
112
ld->ld_requests = NULL;
113
LDAP_MUTEX_UNLOCK( &ld->ld_req_mutex );
114
LDAP_MUTEX_LOCK( &ld->ld_conn_mutex );
115
116
/* free and unbind from all open connections */
117
while ( ld->ld_conns != NULL ) {
118
ldap_free_connection( ld, ld->ld_conns, 1, close );
119
}
120
LDAP_MUTEX_UNLOCK( &ld->ld_conn_mutex );
121
LDAP_MUTEX_LOCK( &ld->ld_res_mutex );
122
for ( lm = ld->ld_responses; lm != NULL; lm = next ) {
123
next = lm->lm_next;
124
ldap_msgfree( lm );
125
}
126
127
if ( ld->ld_abandoned != NULL ) {
128
LDAP_FREE( ld->ld_abandoned );
129
ld->ld_abandoned = NULL;
130
}
131
LDAP_MUTEX_UNLOCK( &ld->ld_res_mutex );
132
133
/* Should already be closed by ldap_free_connection which knows not to free
134
* this one */
135
ber_int_sb_destroy( ld->ld_sb );
136
LBER_FREE( ld->ld_sb );
137
138
LDAP_MUTEX_LOCK( &ld->ld_ldopts_mutex );
139
140
/* final close callbacks */
141
{
142
ldaplist *ll, *next;
143
144
for ( ll = ld->ld_options.ldo_conn_cbs; ll; ll = next ) {
145
ldap_conncb *cb = ll->ll_data;
146
next = ll->ll_next;
147
cb->lc_del( ld, NULL, cb );
148
LDAP_FREE( ll );
149
}
150
}
151
152
if ( ld->ld_error != NULL ) {
153
LDAP_FREE( ld->ld_error );
154
ld->ld_error = NULL;
155
}
156
157
if ( ld->ld_matched != NULL ) {
158
LDAP_FREE( ld->ld_matched );
159
ld->ld_matched = NULL;
160
}
161
162
if ( ld->ld_referrals != NULL) {
163
LDAP_VFREE(ld->ld_referrals);
164
ld->ld_referrals = NULL;
165
}
166
167
if ( ld->ld_selectinfo != NULL ) {
168
ldap_free_select_info( ld->ld_selectinfo );
169
ld->ld_selectinfo = NULL;
170
}
171
172
if ( ld->ld_options.ldo_defludp != NULL ) {
173
ldap_free_urllist( ld->ld_options.ldo_defludp );
174
ld->ld_options.ldo_defludp = NULL;
175
}
176
177
if ( ld->ld_options.ldo_local_ip_addrs.local_ip_addrs ) {
178
LDAP_FREE( ld->ld_options.ldo_local_ip_addrs.local_ip_addrs );
179
memset( & ld->ld_options.ldo_local_ip_addrs, 0,
180
sizeof( ldapsourceip ) );
181
}
182
183
#ifdef LDAP_CONNECTIONLESS
184
if ( ld->ld_options.ldo_peer != NULL ) {
185
LDAP_FREE( ld->ld_options.ldo_peer );
186
ld->ld_options.ldo_peer = NULL;
187
}
188
189
if ( ld->ld_options.ldo_cldapdn != NULL ) {
190
LDAP_FREE( ld->ld_options.ldo_cldapdn );
191
ld->ld_options.ldo_cldapdn = NULL;
192
}
193
#endif
194
195
if ( ld->ld_options.ldo_defbase != NULL ) {
196
LDAP_FREE( ld->ld_options.ldo_defbase );
197
ld->ld_options.ldo_defbase = NULL;
198
}
199
200
#ifdef HAVE_CYRUS_SASL
201
if ( ld->ld_options.ldo_def_sasl_mech != NULL ) {
202
LDAP_FREE( ld->ld_options.ldo_def_sasl_mech );
203
ld->ld_options.ldo_def_sasl_mech = NULL;
204
}
205
206
if ( ld->ld_options.ldo_def_sasl_realm != NULL ) {
207
LDAP_FREE( ld->ld_options.ldo_def_sasl_realm );
208
ld->ld_options.ldo_def_sasl_realm = NULL;
209
}
210
211
if ( ld->ld_options.ldo_def_sasl_authcid != NULL ) {
212
LDAP_FREE( ld->ld_options.ldo_def_sasl_authcid );
213
ld->ld_options.ldo_def_sasl_authcid = NULL;
214
}
215
216
if ( ld->ld_options.ldo_def_sasl_authzid != NULL ) {
217
LDAP_FREE( ld->ld_options.ldo_def_sasl_authzid );
218
ld->ld_options.ldo_def_sasl_authzid = NULL;
219
}
220
#endif
221
222
#ifdef HAVE_TLS
223
ldap_int_tls_destroy( &ld->ld_options );
224
#endif
225
226
if ( ld->ld_options.ldo_sctrls != NULL ) {
227
ldap_controls_free( ld->ld_options.ldo_sctrls );
228
ld->ld_options.ldo_sctrls = NULL;
229
}
230
231
if ( ld->ld_options.ldo_cctrls != NULL ) {
232
ldap_controls_free( ld->ld_options.ldo_cctrls );
233
ld->ld_options.ldo_cctrls = NULL;
234
}
235
LDAP_MUTEX_UNLOCK( &ld->ld_ldopts_mutex );
236
237
#ifdef LDAP_R_COMPILE
238
ldap_pvt_thread_mutex_destroy( &ld->ld_msgid_mutex );
239
ldap_pvt_thread_mutex_destroy( &ld->ld_conn_mutex );
240
ldap_pvt_thread_mutex_destroy( &ld->ld_req_mutex );
241
ldap_pvt_thread_mutex_destroy( &ld->ld_res_mutex );
242
ldap_pvt_thread_mutex_destroy( &ld->ld_abandon_mutex );
243
ldap_pvt_thread_mutex_destroy( &ld->ld_ldopts_mutex );
244
ldap_pvt_thread_mutex_destroy( &ld->ld_ldcmutex );
245
#endif
246
#ifndef NDEBUG
247
LDAP_TRASH(ld);
248
#endif
249
LDAP_FREE( (char *) ld->ldc );
250
LDAP_FREE( (char *) ld );
251
252
return( err );
253
}
254
255
int
256
ldap_destroy( LDAP *ld )
257
{
258
return ( ldap_ld_free( ld, 1, NULL, NULL ) );
259
}
260
261
int
262
ldap_unbind_s( LDAP *ld )
263
{
264
return( ldap_unbind_ext( ld, NULL, NULL ) );
265
}
266
267
/* FIXME: this function is called only by ldap_free_connection(),
268
* which, most of the times, is called with ld_req_mutex locked */
269
int
270
ldap_send_unbind(
271
LDAP *ld,
272
Sockbuf *sb,
273
LDAPControl **sctrls,
274
LDAPControl **cctrls )
275
{
276
BerElement *ber;
277
ber_int_t id;
278
279
Debug0( LDAP_DEBUG_TRACE, "ldap_send_unbind\n" );
280
281
#ifdef LDAP_CONNECTIONLESS
282
if (LDAP_IS_UDP(ld))
283
return LDAP_SUCCESS;
284
#endif
285
/* create a message to send */
286
if ( (ber = ldap_alloc_ber_with_options( ld )) == NULL ) {
287
return( ld->ld_errno );
288
}
289
290
LDAP_NEXT_MSGID(ld, id);
291
292
/* fill it in */
293
if ( ber_printf( ber, "{itn" /*}*/, id,
294
LDAP_REQ_UNBIND ) == -1 ) {
295
ld->ld_errno = LDAP_ENCODING_ERROR;
296
ber_free( ber, 1 );
297
return( ld->ld_errno );
298
}
299
300
/* Put Server Controls */
301
if( ldap_int_put_controls( ld, sctrls, ber ) != LDAP_SUCCESS ) {
302
ber_free( ber, 1 );
303
return ld->ld_errno;
304
}
305
306
if ( ber_printf( ber, /*{*/ "N}", LDAP_REQ_UNBIND ) == -1 ) {
307
ld->ld_errno = LDAP_ENCODING_ERROR;
308
ber_free( ber, 1 );
309
return( ld->ld_errno );
310
}
311
312
ld->ld_errno = LDAP_SUCCESS;
313
/* send the message */
314
if ( ber_flush2( sb, ber, LBER_FLUSH_FREE_ALWAYS ) == -1 ) {
315
ld->ld_errno = LDAP_SERVER_DOWN;
316
}
317
318
return( ld->ld_errno );
319
}
320
321