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 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 58 ldap_unbind_s( LDAP *ld ) 59 { 60 return( ldap_ld_free( ld, NULL, NULL, 1 )); 61 } 62 63 64 int 65 LDAP_CALL 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 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 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