1 /* 2 * Copyright 2002-2003 Sun Microsystems, Inc. All rights reserved. 3 * Use is subject to license terms. 4 */ 5 6 /* 7 * The contents of this file are subject to the Netscape Public 8 * License Version 1.1 (the "License"); you may not use this file 9 * except in compliance with the License. You may obtain a copy of 10 * the License at http://www.mozilla.org/NPL/ 11 * 12 * Software distributed under the License is distributed on an "AS 13 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or 14 * implied. See the License for the specific language governing 15 * rights and limitations under the License. 16 * 17 * The Original Code is Mozilla Communicator client code, released 18 * March 31, 1998. 19 * 20 * The Initial Developer of the Original Code is Netscape 21 * Communications Corporation. Portions created by Netscape are 22 * Copyright (C) 1998-1999 Netscape Communications Corporation. All 23 * Rights Reserved. 24 * 25 * Contributor(s): 26 */ 27 /* 28 * Copyright (c) 1990 Regents of the University of Michigan. 29 * All rights reserved. 30 */ 31 32 /* 33 * unbind.c 34 */ 35 36 #if 0 37 #ifndef lint 38 static char copyright[] = "@(#) Copyright (c) 1990 Regents of the University of Michigan.\nAll rights reserved.\n"; 39 #endif 40 #endif 41 42 #include "ldap-int.h" 43 44 int 45 LDAP_CALL 46 ldap_unbind( LDAP *ld ) 47 { 48 LDAPDebug( LDAP_DEBUG_TRACE, "ldap_unbind\n", 0, 0, 0 ); 49 50 return( ldap_ld_free( ld, NULL, NULL, 1 ) ); 51 } 52 53 54 int 55 LDAP_CALL 56 ldap_unbind_s( LDAP *ld ) 57 { 58 return( ldap_ld_free( ld, NULL, NULL, 1 )); 59 } 60 61 62 int 63 LDAP_CALL 64 ldap_unbind_ext( LDAP *ld, LDAPControl **serverctrls, 65 LDAPControl **clientctrls ) 66 { 67 return( ldap_ld_free( ld, serverctrls, clientctrls, 1 )); 68 } 69 70 71 /* 72 * Dispose of the LDAP session ld, including all associated connections 73 * and resources. If close is non-zero, an unbind() request is sent as well. 74 */ 75 int 76 ldap_ld_free( LDAP *ld, LDAPControl **serverctrls, 77 LDAPControl **clientctrls, int close ) 78 { 79 LDAPMessage *lm, *next; 80 int err = LDAP_SUCCESS; 81 LDAPRequest *lr, *nextlr; 82 83 if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) { 84 return( LDAP_PARAM_ERROR ); 85 } 86 87 if ( ld->ld_sbp->sb_naddr == 0 ) { 88 LDAP_MUTEX_LOCK( ld, LDAP_REQ_LOCK ); 89 /* free LDAP structure and outstanding requests/responses */ 90 for ( lr = ld->ld_requests; lr != NULL; lr = nextlr ) { 91 nextlr = lr->lr_next; 92 nsldapi_free_request( ld, lr, 0 ); 93 } 94 LDAP_MUTEX_UNLOCK( ld, LDAP_REQ_LOCK ); 95 96 /* free and unbind from all open connections */ 97 LDAP_MUTEX_LOCK( ld, LDAP_CONN_LOCK ); 98 while ( ld->ld_conns != NULL ) { 99 nsldapi_free_connection( ld, ld->ld_conns, serverctrls, 100 clientctrls, 1, close ); 101 } 102 LDAP_MUTEX_UNLOCK( ld, LDAP_CONN_LOCK ); 103 104 } else { 105 int i; 106 107 for ( i = 0; i < ld->ld_sbp->sb_naddr; ++i ) { 108 NSLDAPI_FREE( ld->ld_sbp->sb_addrs[ i ] ); 109 } 110 NSLDAPI_FREE( ld->ld_sbp->sb_addrs ); 111 NSLDAPI_FREE( ld->ld_sbp->sb_fromaddr ); 112 } 113 114 LDAP_MUTEX_LOCK( ld, LDAP_RESP_LOCK ); 115 for ( lm = ld->ld_responses; lm != NULL; lm = next ) { 116 next = lm->lm_next; 117 ldap_msgfree( lm ); 118 } 119 LDAP_MUTEX_UNLOCK( ld, LDAP_RESP_LOCK ); 120 121 /* call cache unbind function to allow it to clean up after itself */ 122 if ( ld->ld_cache_unbind != NULL ) { 123 LDAP_MUTEX_LOCK( ld, LDAP_CACHE_LOCK ); 124 (void)ld->ld_cache_unbind( ld, 0, 0 ); 125 LDAP_MUTEX_UNLOCK( ld, LDAP_CACHE_LOCK ); 126 } 127 128 /* call the dispose handle I/O callback if one is defined */ 129 if ( ld->ld_extdisposehandle_fn != NULL ) { 130 /* 131 * We always pass the session extended I/O argument to 132 * the dispose handle callback. 133 */ 134 ld->ld_extdisposehandle_fn( ld, ld->ld_ext_session_arg ); 135 } 136 137 if ( ld->ld_error != NULL ) 138 NSLDAPI_FREE( ld->ld_error ); 139 if ( ld->ld_matched != NULL ) 140 NSLDAPI_FREE( ld->ld_matched ); 141 if ( ld->ld_host != NULL ) 142 NSLDAPI_FREE( ld->ld_host ); 143 if ( ld->ld_ufnprefix != NULL ) 144 NSLDAPI_FREE( ld->ld_ufnprefix ); 145 if ( ld->ld_filtd != NULL ) 146 ldap_getfilter_free( ld->ld_filtd ); 147 if ( ld->ld_abandoned != NULL ) 148 NSLDAPI_FREE( ld->ld_abandoned ); 149 if ( ld->ld_sbp != NULL ) 150 ber_sockbuf_free( ld->ld_sbp ); 151 if ( ld->ld_defhost != NULL ) 152 NSLDAPI_FREE( ld->ld_defhost ); 153 if ( ld->ld_servercontrols != NULL ) 154 ldap_controls_free( ld->ld_servercontrols ); 155 if ( ld->ld_clientcontrols != NULL ) 156 ldap_controls_free( ld->ld_clientcontrols ); 157 if ( ld->ld_preferred_language != NULL ) 158 NSLDAPI_FREE( ld->ld_preferred_language ); 159 nsldapi_iostatus_free( ld ); 160 #ifdef LDAP_SASLIO_HOOKS 161 if ( ld->ld_def_sasl_mech != NULL ) 162 NSLDAPI_FREE( ld->ld_def_sasl_mech ); 163 if ( ld->ld_def_sasl_realm != NULL ) 164 NSLDAPI_FREE( ld->ld_def_sasl_realm ); 165 if ( ld->ld_def_sasl_authcid != NULL ) 166 NSLDAPI_FREE( ld->ld_def_sasl_authcid ); 167 if ( ld->ld_def_sasl_authzid != NULL ) 168 NSLDAPI_FREE( ld->ld_def_sasl_authzid ); 169 #endif 170 171 /* 172 * XXXmcs: should use cache function pointers to hook in memcache 173 */ 174 if ( ld->ld_memcache != NULL ) { 175 ldap_memcache_set( ld, NULL ); 176 } 177 178 /* free all mutexes we have allocated */ 179 nsldapi_mutex_free_all( ld ); 180 NSLDAPI_FREE( ld->ld_mutex ); 181 182 NSLDAPI_FREE( (char *) ld ); 183 184 return( err ); 185 } 186 187 188 189 int 190 nsldapi_send_unbind( LDAP *ld, Sockbuf *sb, LDAPControl **serverctrls, 191 LDAPControl **clientctrls ) 192 { 193 BerElement *ber; 194 int err, msgid; 195 196 LDAPDebug( LDAP_DEBUG_TRACE, "nsldapi_send_unbind\n", 0, 0, 0 ); 197 198 /* create a message to send */ 199 if (( err = nsldapi_alloc_ber_with_options( ld, &ber )) 200 != LDAP_SUCCESS ) { 201 return( err ); 202 } 203 204 /* fill it in */ 205 LDAP_MUTEX_LOCK( ld, LDAP_MSGID_LOCK ); 206 msgid = ++ld->ld_msgid; 207 LDAP_MUTEX_UNLOCK( ld, LDAP_MSGID_LOCK ); 208 209 if ( ber_printf( ber, "{itn", msgid, LDAP_REQ_UNBIND ) == -1 ) { 210 ber_free( ber, 1 ); 211 err = LDAP_ENCODING_ERROR; 212 LDAP_SET_LDERRNO( ld, err, NULL, NULL ); 213 return( err ); 214 } 215 216 if (( err = nsldapi_put_controls( ld, serverctrls, 1, ber )) 217 != LDAP_SUCCESS ) { 218 ber_free( ber, 1 ); 219 return( err ); 220 } 221 222 /* send the message */ 223 if ( nsldapi_ber_flush( ld, sb, ber, 1, 0 ) != 0 ) { 224 ber_free( ber, 1 ); 225 err = LDAP_SERVER_DOWN; 226 LDAP_SET_LDERRNO( ld, err, NULL, NULL ); 227 return( err ); 228 } 229 230 return( LDAP_SUCCESS ); 231 } 232