1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * Copyright 2001-2002 Sun Microsystems, Inc. All rights reserved. 3*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 4*7c478bd9Sstevel@tonic-gate */ 5*7c478bd9Sstevel@tonic-gate 6*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 7*7c478bd9Sstevel@tonic-gate 8*7c478bd9Sstevel@tonic-gate 9*7c478bd9Sstevel@tonic-gate /* 10*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the Netscape Public 11*7c478bd9Sstevel@tonic-gate * License Version 1.1 (the "License"); you may not use this file 12*7c478bd9Sstevel@tonic-gate * except in compliance with the License. You may obtain a copy of 13*7c478bd9Sstevel@tonic-gate * the License at http://www.mozilla.org/NPL/ 14*7c478bd9Sstevel@tonic-gate * 15*7c478bd9Sstevel@tonic-gate * Software distributed under the License is distributed on an "AS 16*7c478bd9Sstevel@tonic-gate * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or 17*7c478bd9Sstevel@tonic-gate * implied. See the License for the specific language governing 18*7c478bd9Sstevel@tonic-gate * rights and limitations under the License. 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * The Original Code is Mozilla Communicator client code, released 21*7c478bd9Sstevel@tonic-gate * March 31, 1998. 22*7c478bd9Sstevel@tonic-gate * 23*7c478bd9Sstevel@tonic-gate * The Initial Developer of the Original Code is Netscape 24*7c478bd9Sstevel@tonic-gate * Communications Corporation. Portions created by Netscape are 25*7c478bd9Sstevel@tonic-gate * Copyright (C) 1998-1999 Netscape Communications Corporation. All 26*7c478bd9Sstevel@tonic-gate * Rights Reserved. 27*7c478bd9Sstevel@tonic-gate * 28*7c478bd9Sstevel@tonic-gate * Contributor(s): 29*7c478bd9Sstevel@tonic-gate */ 30*7c478bd9Sstevel@tonic-gate 31*7c478bd9Sstevel@tonic-gate /* 32*7c478bd9Sstevel@tonic-gate * Extended I/O callback functions for libldap that use 33*7c478bd9Sstevel@tonic-gate * NSPR (Netscape Portable Runtime) I/O. 34*7c478bd9Sstevel@tonic-gate * 35*7c478bd9Sstevel@tonic-gate * High level strategy: we use the socket-specific arg to hold our own data 36*7c478bd9Sstevel@tonic-gate * structure that includes the NSPR file handle (PRFileDesc *), among other 37*7c478bd9Sstevel@tonic-gate * useful information. We use the default argument to hold an LDAP session 38*7c478bd9Sstevel@tonic-gate * handle specific data structure. 39*7c478bd9Sstevel@tonic-gate */ 40*7c478bd9Sstevel@tonic-gate 41*7c478bd9Sstevel@tonic-gate #include "ldappr-int.h" 42*7c478bd9Sstevel@tonic-gate #include <string.h> 43*7c478bd9Sstevel@tonic-gate 44*7c478bd9Sstevel@tonic-gate #define PRLDAP_POLL_ARRAY_GROWTH 5 /* grow arrays 5 elements at a time */ 45*7c478bd9Sstevel@tonic-gate 46*7c478bd9Sstevel@tonic-gate /* 47*7c478bd9Sstevel@tonic-gate * Local function prototypes: 48*7c478bd9Sstevel@tonic-gate */ 49*7c478bd9Sstevel@tonic-gate static PRIntervalTime prldap_timeout2it( int ms_timeout, int ms_maxtimeout ); 50*7c478bd9Sstevel@tonic-gate static int LDAP_CALLBACK prldap_read( int s, void *buf, int bufsize, 51*7c478bd9Sstevel@tonic-gate struct lextiof_socket_private *socketarg ); 52*7c478bd9Sstevel@tonic-gate static int LDAP_CALLBACK prldap_write( int s, const void *buf, int len, 53*7c478bd9Sstevel@tonic-gate struct lextiof_socket_private *socketarg ); 54*7c478bd9Sstevel@tonic-gate static int LDAP_CALLBACK prldap_poll( LDAP_X_PollFD fds[], int nfds, 55*7c478bd9Sstevel@tonic-gate int timeout, struct lextiof_session_private *sessionarg ); 56*7c478bd9Sstevel@tonic-gate static int LDAP_CALLBACK prldap_connect( const char *hostlist, int defport, 57*7c478bd9Sstevel@tonic-gate int timeout, unsigned long options, 58*7c478bd9Sstevel@tonic-gate struct lextiof_session_private *sessionarg, 59*7c478bd9Sstevel@tonic-gate struct lextiof_socket_private **socketargp 60*7c478bd9Sstevel@tonic-gate #ifdef _SOLARIS_SDK 61*7c478bd9Sstevel@tonic-gate , void **dhost ); 62*7c478bd9Sstevel@tonic-gate #else 63*7c478bd9Sstevel@tonic-gate ); 64*7c478bd9Sstevel@tonic-gate #endif /* _SOLARIS_SDK */ 65*7c478bd9Sstevel@tonic-gate static int LDAP_CALLBACK prldap_close( int s, 66*7c478bd9Sstevel@tonic-gate struct lextiof_socket_private *socketarg ); 67*7c478bd9Sstevel@tonic-gate static int LDAP_CALLBACK prldap_newhandle( LDAP *ld, 68*7c478bd9Sstevel@tonic-gate struct lextiof_session_private *sessionarg ); 69*7c478bd9Sstevel@tonic-gate static void LDAP_CALLBACK prldap_disposehandle( LDAP *ld, 70*7c478bd9Sstevel@tonic-gate struct lextiof_session_private *sessionarg ); 71*7c478bd9Sstevel@tonic-gate static int LDAP_CALLBACK prldap_shared_newhandle( LDAP *ld, 72*7c478bd9Sstevel@tonic-gate struct lextiof_session_private *sessionarg ); 73*7c478bd9Sstevel@tonic-gate static void LDAP_CALLBACK prldap_shared_disposehandle( LDAP *ld, 74*7c478bd9Sstevel@tonic-gate struct lextiof_session_private *sessionarg ); 75*7c478bd9Sstevel@tonic-gate static PRLDAPIOSessionArg *prldap_session_arg_alloc( void ); 76*7c478bd9Sstevel@tonic-gate static void prldap_session_arg_free( PRLDAPIOSessionArg **prsesspp ); 77*7c478bd9Sstevel@tonic-gate static PRLDAPIOSocketArg *prldap_socket_arg_alloc( PRLDAPIOSessionArg *sessionarg ); 78*7c478bd9Sstevel@tonic-gate static void prldap_socket_arg_free( PRLDAPIOSocketArg **prsockpp ); 79*7c478bd9Sstevel@tonic-gate static void *prldap_safe_realloc( void *ptr, PRUint32 size ); 80*7c478bd9Sstevel@tonic-gate 81*7c478bd9Sstevel@tonic-gate 82*7c478bd9Sstevel@tonic-gate 83*7c478bd9Sstevel@tonic-gate /* 84*7c478bd9Sstevel@tonic-gate * Local macros: 85*7c478bd9Sstevel@tonic-gate */ 86*7c478bd9Sstevel@tonic-gate /* given a socket-specific arg, return the corresponding PRFileDesc * */ 87*7c478bd9Sstevel@tonic-gate #define PRLDAP_GET_PRFD( socketarg ) \ 88*7c478bd9Sstevel@tonic-gate (((PRLDAPIOSocketArg *)(socketarg))->prsock_prfd) 89*7c478bd9Sstevel@tonic-gate 90*7c478bd9Sstevel@tonic-gate /* 91*7c478bd9Sstevel@tonic-gate * Static variables. 92*7c478bd9Sstevel@tonic-gate */ 93*7c478bd9Sstevel@tonic-gate static int prldap_default_io_max_timeout = LDAP_X_IO_TIMEOUT_NO_TIMEOUT; 94*7c478bd9Sstevel@tonic-gate 95*7c478bd9Sstevel@tonic-gate /* 96*7c478bd9Sstevel@tonic-gate * Install NSPR I/O functions into ld (if ld is NULL, they are installed 97*7c478bd9Sstevel@tonic-gate * as the default functions for new LDAP * handles). 98*7c478bd9Sstevel@tonic-gate * 99*7c478bd9Sstevel@tonic-gate * Returns 0 if all goes well and -1 if not. 100*7c478bd9Sstevel@tonic-gate */ 101*7c478bd9Sstevel@tonic-gate int 102*7c478bd9Sstevel@tonic-gate prldap_install_io_functions( LDAP *ld, int shared ) 103*7c478bd9Sstevel@tonic-gate { 104*7c478bd9Sstevel@tonic-gate struct ldap_x_ext_io_fns iofns; 105*7c478bd9Sstevel@tonic-gate 106*7c478bd9Sstevel@tonic-gate memset( &iofns, 0, sizeof(iofns)); 107*7c478bd9Sstevel@tonic-gate iofns.lextiof_size = LDAP_X_EXTIO_FNS_SIZE; 108*7c478bd9Sstevel@tonic-gate iofns.lextiof_read = prldap_read; 109*7c478bd9Sstevel@tonic-gate iofns.lextiof_write = prldap_write; 110*7c478bd9Sstevel@tonic-gate iofns.lextiof_poll = prldap_poll; 111*7c478bd9Sstevel@tonic-gate iofns.lextiof_connect = prldap_connect; 112*7c478bd9Sstevel@tonic-gate iofns.lextiof_close = prldap_close; 113*7c478bd9Sstevel@tonic-gate if ( shared ) { 114*7c478bd9Sstevel@tonic-gate iofns.lextiof_newhandle = prldap_shared_newhandle; 115*7c478bd9Sstevel@tonic-gate iofns.lextiof_disposehandle = prldap_shared_disposehandle; 116*7c478bd9Sstevel@tonic-gate } else { 117*7c478bd9Sstevel@tonic-gate iofns.lextiof_newhandle = prldap_newhandle; 118*7c478bd9Sstevel@tonic-gate iofns.lextiof_disposehandle = prldap_disposehandle; 119*7c478bd9Sstevel@tonic-gate } 120*7c478bd9Sstevel@tonic-gate if ( NULL != ld ) { 121*7c478bd9Sstevel@tonic-gate /* 122*7c478bd9Sstevel@tonic-gate * If we are dealing with a real ld, we allocate the session specific 123*7c478bd9Sstevel@tonic-gate * data structure now. If not allocated here, it will be allocated 124*7c478bd9Sstevel@tonic-gate * inside prldap_newhandle() or prldap_shared_newhandle(). 125*7c478bd9Sstevel@tonic-gate */ 126*7c478bd9Sstevel@tonic-gate if ( NULL == 127*7c478bd9Sstevel@tonic-gate ( iofns.lextiof_session_arg = prldap_session_arg_alloc())) { 128*7c478bd9Sstevel@tonic-gate ldap_set_lderrno( ld, LDAP_NO_MEMORY, NULL, NULL ); 129*7c478bd9Sstevel@tonic-gate return( -1 ); 130*7c478bd9Sstevel@tonic-gate } 131*7c478bd9Sstevel@tonic-gate } else { 132*7c478bd9Sstevel@tonic-gate iofns.lextiof_session_arg = NULL; 133*7c478bd9Sstevel@tonic-gate } 134*7c478bd9Sstevel@tonic-gate 135*7c478bd9Sstevel@tonic-gate if ( ldap_set_option( ld, LDAP_X_OPT_EXTIO_FN_PTRS, &iofns ) != 0 ) { 136*7c478bd9Sstevel@tonic-gate prldap_session_arg_free( 137*7c478bd9Sstevel@tonic-gate (PRLDAPIOSessionArg **) &iofns.lextiof_session_arg ); 138*7c478bd9Sstevel@tonic-gate return( -1 ); 139*7c478bd9Sstevel@tonic-gate } 140*7c478bd9Sstevel@tonic-gate 141*7c478bd9Sstevel@tonic-gate return( 0 ); 142*7c478bd9Sstevel@tonic-gate } 143*7c478bd9Sstevel@tonic-gate 144*7c478bd9Sstevel@tonic-gate 145*7c478bd9Sstevel@tonic-gate static PRIntervalTime 146*7c478bd9Sstevel@tonic-gate prldap_timeout2it( int ms_timeout, int ms_maxtimeout ) 147*7c478bd9Sstevel@tonic-gate { 148*7c478bd9Sstevel@tonic-gate PRIntervalTime prit; 149*7c478bd9Sstevel@tonic-gate 150*7c478bd9Sstevel@tonic-gate if ( LDAP_X_IO_TIMEOUT_NO_WAIT == ms_timeout ) { 151*7c478bd9Sstevel@tonic-gate prit = PR_INTERVAL_NO_WAIT; 152*7c478bd9Sstevel@tonic-gate } else if ( LDAP_X_IO_TIMEOUT_NO_TIMEOUT == ms_timeout ) { 153*7c478bd9Sstevel@tonic-gate prit = PR_INTERVAL_NO_TIMEOUT; 154*7c478bd9Sstevel@tonic-gate } else { 155*7c478bd9Sstevel@tonic-gate prit = PR_MillisecondsToInterval( ms_timeout ); 156*7c478bd9Sstevel@tonic-gate } 157*7c478bd9Sstevel@tonic-gate 158*7c478bd9Sstevel@tonic-gate /* cap at maximum I/O timeout */ 159*7c478bd9Sstevel@tonic-gate if ( LDAP_X_IO_TIMEOUT_NO_WAIT == ms_maxtimeout ) { 160*7c478bd9Sstevel@tonic-gate prit = LDAP_X_IO_TIMEOUT_NO_WAIT; 161*7c478bd9Sstevel@tonic-gate } else if ( LDAP_X_IO_TIMEOUT_NO_TIMEOUT != ms_maxtimeout ) { 162*7c478bd9Sstevel@tonic-gate if ( LDAP_X_IO_TIMEOUT_NO_TIMEOUT == ms_timeout || 163*7c478bd9Sstevel@tonic-gate ms_timeout > ms_maxtimeout ) { 164*7c478bd9Sstevel@tonic-gate prit = PR_MillisecondsToInterval( ms_maxtimeout ); 165*7c478bd9Sstevel@tonic-gate } 166*7c478bd9Sstevel@tonic-gate } 167*7c478bd9Sstevel@tonic-gate 168*7c478bd9Sstevel@tonic-gate #ifdef PRLDAP_DEBUG 169*7c478bd9Sstevel@tonic-gate if ( PR_INTERVAL_NO_WAIT == prit ) { 170*7c478bd9Sstevel@tonic-gate fprintf( stderr, "prldap_timeout2it: NO_WAIT\n" ); 171*7c478bd9Sstevel@tonic-gate } else if ( PR_INTERVAL_NO_TIMEOUT == prit ) { 172*7c478bd9Sstevel@tonic-gate fprintf( stderr, "prldap_timeout2it: NO_TIMEOUT\n" ); 173*7c478bd9Sstevel@tonic-gate } else { 174*7c478bd9Sstevel@tonic-gate fprintf( stderr, "prldap_timeout2it: %dms\n", 175*7c478bd9Sstevel@tonic-gate PR_IntervalToMilliseconds(prit)); 176*7c478bd9Sstevel@tonic-gate } 177*7c478bd9Sstevel@tonic-gate #endif /* PRLDAP_DEBUG */ 178*7c478bd9Sstevel@tonic-gate 179*7c478bd9Sstevel@tonic-gate return( prit ); 180*7c478bd9Sstevel@tonic-gate } 181*7c478bd9Sstevel@tonic-gate 182*7c478bd9Sstevel@tonic-gate 183*7c478bd9Sstevel@tonic-gate static int LDAP_CALLBACK 184*7c478bd9Sstevel@tonic-gate prldap_read( int s, void *buf, int bufsize, 185*7c478bd9Sstevel@tonic-gate struct lextiof_socket_private *socketarg ) 186*7c478bd9Sstevel@tonic-gate { 187*7c478bd9Sstevel@tonic-gate PRIntervalTime prit; 188*7c478bd9Sstevel@tonic-gate 189*7c478bd9Sstevel@tonic-gate prit = prldap_timeout2it( LDAP_X_IO_TIMEOUT_NO_TIMEOUT, 190*7c478bd9Sstevel@tonic-gate socketarg->prsock_io_max_timeout ); 191*7c478bd9Sstevel@tonic-gate return( PR_Recv( PRLDAP_GET_PRFD(socketarg), buf, bufsize, 0, prit )); 192*7c478bd9Sstevel@tonic-gate } 193*7c478bd9Sstevel@tonic-gate 194*7c478bd9Sstevel@tonic-gate 195*7c478bd9Sstevel@tonic-gate static int LDAP_CALLBACK 196*7c478bd9Sstevel@tonic-gate prldap_write( int s, const void *buf, int len, 197*7c478bd9Sstevel@tonic-gate struct lextiof_socket_private *socketarg ) 198*7c478bd9Sstevel@tonic-gate { 199*7c478bd9Sstevel@tonic-gate PRIntervalTime prit; 200*7c478bd9Sstevel@tonic-gate 201*7c478bd9Sstevel@tonic-gate prit = prldap_timeout2it( LDAP_X_IO_TIMEOUT_NO_TIMEOUT, 202*7c478bd9Sstevel@tonic-gate socketarg->prsock_io_max_timeout ); 203*7c478bd9Sstevel@tonic-gate 204*7c478bd9Sstevel@tonic-gate /* 205*7c478bd9Sstevel@tonic-gate * Note the 4th parameter (flags) to PR_Send() has been obsoleted and 206*7c478bd9Sstevel@tonic-gate * must always be 0 207*7c478bd9Sstevel@tonic-gate */ 208*7c478bd9Sstevel@tonic-gate return( PR_Send( PRLDAP_GET_PRFD(socketarg), buf, len, 0, prit )); 209*7c478bd9Sstevel@tonic-gate } 210*7c478bd9Sstevel@tonic-gate 211*7c478bd9Sstevel@tonic-gate 212*7c478bd9Sstevel@tonic-gate struct prldap_eventmap_entry { 213*7c478bd9Sstevel@tonic-gate PRInt16 evm_nspr; /* corresponding NSPR PR_Poll() event */ 214*7c478bd9Sstevel@tonic-gate int evm_ldap; /* LDAP poll event */ 215*7c478bd9Sstevel@tonic-gate }; 216*7c478bd9Sstevel@tonic-gate 217*7c478bd9Sstevel@tonic-gate static struct prldap_eventmap_entry prldap_eventmap[] = { 218*7c478bd9Sstevel@tonic-gate { PR_POLL_READ, LDAP_X_POLLIN }, 219*7c478bd9Sstevel@tonic-gate { PR_POLL_EXCEPT, LDAP_X_POLLPRI }, 220*7c478bd9Sstevel@tonic-gate { PR_POLL_WRITE, LDAP_X_POLLOUT }, 221*7c478bd9Sstevel@tonic-gate { PR_POLL_ERR, LDAP_X_POLLERR }, 222*7c478bd9Sstevel@tonic-gate { PR_POLL_HUP, LDAP_X_POLLHUP }, 223*7c478bd9Sstevel@tonic-gate { PR_POLL_NVAL, LDAP_X_POLLNVAL }, 224*7c478bd9Sstevel@tonic-gate }; 225*7c478bd9Sstevel@tonic-gate 226*7c478bd9Sstevel@tonic-gate #define PRLDAP_EVENTMAP_ENTRIES \ 227*7c478bd9Sstevel@tonic-gate sizeof(prldap_eventmap)/sizeof(struct prldap_eventmap_entry ) 228*7c478bd9Sstevel@tonic-gate 229*7c478bd9Sstevel@tonic-gate static int LDAP_CALLBACK 230*7c478bd9Sstevel@tonic-gate prldap_poll( LDAP_X_PollFD fds[], int nfds, int timeout, 231*7c478bd9Sstevel@tonic-gate struct lextiof_session_private *sessionarg ) 232*7c478bd9Sstevel@tonic-gate { 233*7c478bd9Sstevel@tonic-gate PRLDAPIOSessionArg *prsessp = sessionarg; 234*7c478bd9Sstevel@tonic-gate PRPollDesc *pds; 235*7c478bd9Sstevel@tonic-gate int i, j, rc; 236*7c478bd9Sstevel@tonic-gate 237*7c478bd9Sstevel@tonic-gate if ( NULL == prsessp ) { 238*7c478bd9Sstevel@tonic-gate prldap_set_system_errno( EINVAL ); 239*7c478bd9Sstevel@tonic-gate return( -1 ); 240*7c478bd9Sstevel@tonic-gate } 241*7c478bd9Sstevel@tonic-gate 242*7c478bd9Sstevel@tonic-gate /* allocate or resize NSPR poll descriptor array */ 243*7c478bd9Sstevel@tonic-gate if ( prsessp->prsess_pollds_count < nfds ) { 244*7c478bd9Sstevel@tonic-gate pds = prldap_safe_realloc( prsessp->prsess_pollds, 245*7c478bd9Sstevel@tonic-gate ( nfds + PRLDAP_POLL_ARRAY_GROWTH ) 246*7c478bd9Sstevel@tonic-gate * sizeof( PRPollDesc )); 247*7c478bd9Sstevel@tonic-gate if ( NULL == pds ) { 248*7c478bd9Sstevel@tonic-gate prldap_set_system_errno( prldap_prerr2errno()); 249*7c478bd9Sstevel@tonic-gate return( -1 ); 250*7c478bd9Sstevel@tonic-gate } 251*7c478bd9Sstevel@tonic-gate prsessp->prsess_pollds = pds; 252*7c478bd9Sstevel@tonic-gate prsessp->prsess_pollds_count = nfds + PRLDAP_POLL_ARRAY_GROWTH; 253*7c478bd9Sstevel@tonic-gate } else { 254*7c478bd9Sstevel@tonic-gate pds = prsessp->prsess_pollds; 255*7c478bd9Sstevel@tonic-gate } 256*7c478bd9Sstevel@tonic-gate 257*7c478bd9Sstevel@tonic-gate /* populate NSPR poll info. based on LDAP info. */ 258*7c478bd9Sstevel@tonic-gate for ( i = 0; i < nfds; ++i ) { 259*7c478bd9Sstevel@tonic-gate if ( NULL == fds[i].lpoll_socketarg ) { 260*7c478bd9Sstevel@tonic-gate pds[i].fd = NULL; 261*7c478bd9Sstevel@tonic-gate } else { 262*7c478bd9Sstevel@tonic-gate pds[i].fd = PRLDAP_GET_PRFD( fds[i].lpoll_socketarg ); 263*7c478bd9Sstevel@tonic-gate } 264*7c478bd9Sstevel@tonic-gate pds[i].in_flags = pds[i].out_flags = 0; 265*7c478bd9Sstevel@tonic-gate if ( fds[i].lpoll_fd >= 0 ) { 266*7c478bd9Sstevel@tonic-gate for ( j = 0; j < PRLDAP_EVENTMAP_ENTRIES; ++j ) { 267*7c478bd9Sstevel@tonic-gate if (( fds[i].lpoll_events & prldap_eventmap[j].evm_ldap ) 268*7c478bd9Sstevel@tonic-gate != 0 ) { 269*7c478bd9Sstevel@tonic-gate pds[i].in_flags |= prldap_eventmap[j].evm_nspr; 270*7c478bd9Sstevel@tonic-gate } 271*7c478bd9Sstevel@tonic-gate } 272*7c478bd9Sstevel@tonic-gate } 273*7c478bd9Sstevel@tonic-gate fds[i].lpoll_revents = 0; /* clear revents */ 274*7c478bd9Sstevel@tonic-gate } 275*7c478bd9Sstevel@tonic-gate 276*7c478bd9Sstevel@tonic-gate /* call PR_Poll() to do the real work */ 277*7c478bd9Sstevel@tonic-gate rc = PR_Poll( pds, nfds, 278*7c478bd9Sstevel@tonic-gate prldap_timeout2it( timeout, prsessp->prsess_io_max_timeout )); 279*7c478bd9Sstevel@tonic-gate 280*7c478bd9Sstevel@tonic-gate /* populate LDAP info. based on NSPR results */ 281*7c478bd9Sstevel@tonic-gate for ( i = 0; i < nfds; ++i ) { 282*7c478bd9Sstevel@tonic-gate if ( pds[i].fd != NULL ) { 283*7c478bd9Sstevel@tonic-gate for ( j = 0; j < PRLDAP_EVENTMAP_ENTRIES; ++j ) { 284*7c478bd9Sstevel@tonic-gate if (( pds[i].out_flags & prldap_eventmap[j].evm_nspr ) 285*7c478bd9Sstevel@tonic-gate != 0 ) { 286*7c478bd9Sstevel@tonic-gate fds[i].lpoll_revents |= prldap_eventmap[j].evm_ldap; 287*7c478bd9Sstevel@tonic-gate } 288*7c478bd9Sstevel@tonic-gate } 289*7c478bd9Sstevel@tonic-gate } 290*7c478bd9Sstevel@tonic-gate } 291*7c478bd9Sstevel@tonic-gate 292*7c478bd9Sstevel@tonic-gate return( rc ); 293*7c478bd9Sstevel@tonic-gate } 294*7c478bd9Sstevel@tonic-gate 295*7c478bd9Sstevel@tonic-gate 296*7c478bd9Sstevel@tonic-gate /* 297*7c478bd9Sstevel@tonic-gate * Utility function to try one TCP connect() 298*7c478bd9Sstevel@tonic-gate * Returns 1 if successful and -1 if not. Sets the NSPR fd inside prsockp. 299*7c478bd9Sstevel@tonic-gate */ 300*7c478bd9Sstevel@tonic-gate static int 301*7c478bd9Sstevel@tonic-gate prldap_try_one_address( struct lextiof_socket_private *prsockp, 302*7c478bd9Sstevel@tonic-gate PRNetAddr *addrp, int port, int timeout, unsigned long options ) 303*7c478bd9Sstevel@tonic-gate { 304*7c478bd9Sstevel@tonic-gate /* 305*7c478bd9Sstevel@tonic-gate * Set up address and open a TCP socket: 306*7c478bd9Sstevel@tonic-gate */ 307*7c478bd9Sstevel@tonic-gate if ( PR_SUCCESS != PR_SetNetAddr( PR_IpAddrNull, /* don't touch IP addr. */ 308*7c478bd9Sstevel@tonic-gate PRLDAP_DEFAULT_ADDRESS_FAMILY, (PRUint16)port, addrp )) { 309*7c478bd9Sstevel@tonic-gate return( -1 ); 310*7c478bd9Sstevel@tonic-gate } 311*7c478bd9Sstevel@tonic-gate 312*7c478bd9Sstevel@tonic-gate if (( prsockp->prsock_prfd = PR_OpenTCPSocket( 313*7c478bd9Sstevel@tonic-gate PRLDAP_DEFAULT_ADDRESS_FAMILY )) == NULL ) { 314*7c478bd9Sstevel@tonic-gate return( -1 ); 315*7c478bd9Sstevel@tonic-gate } 316*7c478bd9Sstevel@tonic-gate 317*7c478bd9Sstevel@tonic-gate /* 318*7c478bd9Sstevel@tonic-gate * Set nonblocking option if requested: 319*7c478bd9Sstevel@tonic-gate */ 320*7c478bd9Sstevel@tonic-gate if ( 0 != ( options & LDAP_X_EXTIOF_OPT_NONBLOCKING )) { 321*7c478bd9Sstevel@tonic-gate PRSocketOptionData optdata; 322*7c478bd9Sstevel@tonic-gate 323*7c478bd9Sstevel@tonic-gate optdata.option = PR_SockOpt_Nonblocking; 324*7c478bd9Sstevel@tonic-gate optdata.value.non_blocking = PR_TRUE; 325*7c478bd9Sstevel@tonic-gate if ( PR_SetSocketOption( prsockp->prsock_prfd, &optdata ) 326*7c478bd9Sstevel@tonic-gate != PR_SUCCESS ) { 327*7c478bd9Sstevel@tonic-gate prldap_set_system_errno( prldap_prerr2errno()); 328*7c478bd9Sstevel@tonic-gate PR_Close( prsockp->prsock_prfd ); 329*7c478bd9Sstevel@tonic-gate return( -1 ); 330*7c478bd9Sstevel@tonic-gate } 331*7c478bd9Sstevel@tonic-gate } 332*7c478bd9Sstevel@tonic-gate 333*7c478bd9Sstevel@tonic-gate #ifdef PRLDAP_DEBUG 334*7c478bd9Sstevel@tonic-gate { 335*7c478bd9Sstevel@tonic-gate char buf[ 256 ], *p, *fmtstr; 336*7c478bd9Sstevel@tonic-gate 337*7c478bd9Sstevel@tonic-gate if ( PR_SUCCESS != PR_NetAddrToString( addrp, buf, sizeof(buf ))) { 338*7c478bd9Sstevel@tonic-gate strcpy( buf, "conversion failed!" ); 339*7c478bd9Sstevel@tonic-gate } 340*7c478bd9Sstevel@tonic-gate if ( strncmp( buf, "::ffff:", 7 ) == 0 ) { 341*7c478bd9Sstevel@tonic-gate /* IPv4 address mapped into IPv6 address space */ 342*7c478bd9Sstevel@tonic-gate p = buf + 7; 343*7c478bd9Sstevel@tonic-gate fmtstr = "prldap_try_one_address(): Trying %s:%d...\n"; 344*7c478bd9Sstevel@tonic-gate } else { 345*7c478bd9Sstevel@tonic-gate p = buf; 346*7c478bd9Sstevel@tonic-gate fmtstr = "prldap_try_one_address(): Trying [%s]:%d...\n"; 347*7c478bd9Sstevel@tonic-gate } 348*7c478bd9Sstevel@tonic-gate fprintf( stderr, fmtstr, p, PR_ntohs( addrp->ipv6.port )); 349*7c478bd9Sstevel@tonic-gate } 350*7c478bd9Sstevel@tonic-gate #endif /* PRLDAP_DEBUG */ 351*7c478bd9Sstevel@tonic-gate 352*7c478bd9Sstevel@tonic-gate /* 353*7c478bd9Sstevel@tonic-gate * Try to open the TCP connection itself: 354*7c478bd9Sstevel@tonic-gate */ 355*7c478bd9Sstevel@tonic-gate if ( PR_SUCCESS != PR_Connect( prsockp->prsock_prfd, addrp, 356*7c478bd9Sstevel@tonic-gate prldap_timeout2it( timeout, prsockp->prsock_io_max_timeout ))) { 357*7c478bd9Sstevel@tonic-gate PR_Close( prsockp->prsock_prfd ); 358*7c478bd9Sstevel@tonic-gate prsockp->prsock_prfd = NULL; 359*7c478bd9Sstevel@tonic-gate return( -1 ); 360*7c478bd9Sstevel@tonic-gate } 361*7c478bd9Sstevel@tonic-gate 362*7c478bd9Sstevel@tonic-gate #ifdef PRLDAP_DEBUG 363*7c478bd9Sstevel@tonic-gate fputs( "prldap_try_one_address(): Connected.\n", stderr ); 364*7c478bd9Sstevel@tonic-gate #endif /* PRLDAP_DEBUG */ 365*7c478bd9Sstevel@tonic-gate 366*7c478bd9Sstevel@tonic-gate /* 367*7c478bd9Sstevel@tonic-gate * Success. Return a valid file descriptor (1 is always valid) 368*7c478bd9Sstevel@tonic-gate */ 369*7c478bd9Sstevel@tonic-gate return( 1 ); 370*7c478bd9Sstevel@tonic-gate } 371*7c478bd9Sstevel@tonic-gate 372*7c478bd9Sstevel@tonic-gate 373*7c478bd9Sstevel@tonic-gate /* 374*7c478bd9Sstevel@tonic-gate * XXXmcs: At present, this code ignores the timeout when doing DNS lookups. 375*7c478bd9Sstevel@tonic-gate */ 376*7c478bd9Sstevel@tonic-gate static int LDAP_CALLBACK 377*7c478bd9Sstevel@tonic-gate prldap_connect( const char *hostlist, int defport, int timeout, 378*7c478bd9Sstevel@tonic-gate unsigned long options, struct lextiof_session_private *sessionarg, 379*7c478bd9Sstevel@tonic-gate struct lextiof_socket_private **socketargp 380*7c478bd9Sstevel@tonic-gate #ifdef _SOLARIS_SDK 381*7c478bd9Sstevel@tonic-gate , void **dhost ) 382*7c478bd9Sstevel@tonic-gate #else 383*7c478bd9Sstevel@tonic-gate ) 384*7c478bd9Sstevel@tonic-gate #endif /* _SOLARIS_SDK */ 385*7c478bd9Sstevel@tonic-gate { 386*7c478bd9Sstevel@tonic-gate int rc, parse_err, port; 387*7c478bd9Sstevel@tonic-gate char *host, hbuf[ PR_NETDB_BUF_SIZE ]; 388*7c478bd9Sstevel@tonic-gate struct ldap_x_hostlist_status *status; 389*7c478bd9Sstevel@tonic-gate struct lextiof_socket_private *prsockp; 390*7c478bd9Sstevel@tonic-gate PRNetAddr addr; 391*7c478bd9Sstevel@tonic-gate PRHostEnt hent; 392*7c478bd9Sstevel@tonic-gate #ifdef _SOLARIS_SDK 393*7c478bd9Sstevel@tonic-gate char *hostname = NULL; 394*7c478bd9Sstevel@tonic-gate char *nsldapi_strdup(char *); 395*7c478bd9Sstevel@tonic-gate #endif /* _SOLARIS_SDK */ 396*7c478bd9Sstevel@tonic-gate 397*7c478bd9Sstevel@tonic-gate if ( 0 != ( options & LDAP_X_EXTIOF_OPT_SECURE )) { 398*7c478bd9Sstevel@tonic-gate prldap_set_system_errno( EINVAL ); 399*7c478bd9Sstevel@tonic-gate return( -1 ); 400*7c478bd9Sstevel@tonic-gate } 401*7c478bd9Sstevel@tonic-gate 402*7c478bd9Sstevel@tonic-gate if ( NULL == ( prsockp = prldap_socket_arg_alloc( sessionarg ))) { 403*7c478bd9Sstevel@tonic-gate prldap_set_system_errno( prldap_prerr2errno()); 404*7c478bd9Sstevel@tonic-gate return( -1 ); 405*7c478bd9Sstevel@tonic-gate } 406*7c478bd9Sstevel@tonic-gate 407*7c478bd9Sstevel@tonic-gate rc = -1; /* pessimistic */ 408*7c478bd9Sstevel@tonic-gate for ( parse_err = ldap_x_hostlist_first( hostlist, defport, &host, &port, 409*7c478bd9Sstevel@tonic-gate &status ); 410*7c478bd9Sstevel@tonic-gate rc < 0 && LDAP_SUCCESS == parse_err && NULL != host; 411*7c478bd9Sstevel@tonic-gate parse_err = ldap_x_hostlist_next( &host, &port, status )) { 412*7c478bd9Sstevel@tonic-gate 413*7c478bd9Sstevel@tonic-gate if ( PR_SUCCESS == PR_StringToNetAddr( host, &addr )) { 414*7c478bd9Sstevel@tonic-gate 415*7c478bd9Sstevel@tonic-gate if ( PRLDAP_DEFAULT_ADDRESS_FAMILY == PR_AF_INET6 && 416*7c478bd9Sstevel@tonic-gate PR_AF_INET == PR_NetAddrFamily( &addr )) { 417*7c478bd9Sstevel@tonic-gate PRUint32 ipv4ip = addr.inet.ip; 418*7c478bd9Sstevel@tonic-gate memset( &addr, 0, sizeof(addr)); 419*7c478bd9Sstevel@tonic-gate PR_ConvertIPv4AddrToIPv6( ipv4ip, &addr.ipv6.ip ); 420*7c478bd9Sstevel@tonic-gate addr.ipv6.family = PR_AF_INET6; 421*7c478bd9Sstevel@tonic-gate 422*7c478bd9Sstevel@tonic-gate } 423*7c478bd9Sstevel@tonic-gate rc = prldap_try_one_address( prsockp, &addr, port, 424*7c478bd9Sstevel@tonic-gate timeout, options ); 425*7c478bd9Sstevel@tonic-gate } else { 426*7c478bd9Sstevel@tonic-gate if ( PR_SUCCESS == PR_GetIPNodeByName( host, 427*7c478bd9Sstevel@tonic-gate PRLDAP_DEFAULT_ADDRESS_FAMILY, PR_AI_DEFAULT | PR_AI_ALL, hbuf, 428*7c478bd9Sstevel@tonic-gate sizeof( hbuf ), &hent )) { 429*7c478bd9Sstevel@tonic-gate PRIntn enumIndex = 0; 430*7c478bd9Sstevel@tonic-gate 431*7c478bd9Sstevel@tonic-gate while ( rc < 0 && ( enumIndex = PR_EnumerateHostEnt( 432*7c478bd9Sstevel@tonic-gate enumIndex, &hent, (PRUint16)port, &addr )) > 0 ) { 433*7c478bd9Sstevel@tonic-gate rc = prldap_try_one_address( prsockp, &addr, port, 434*7c478bd9Sstevel@tonic-gate timeout, options ); 435*7c478bd9Sstevel@tonic-gate } 436*7c478bd9Sstevel@tonic-gate } 437*7c478bd9Sstevel@tonic-gate } 438*7c478bd9Sstevel@tonic-gate 439*7c478bd9Sstevel@tonic-gate #ifdef _SOLARIS_SDK 440*7c478bd9Sstevel@tonic-gate if ( NULL != hostname ) ldap_memfree(hostname); 441*7c478bd9Sstevel@tonic-gate hostname = nsldapi_strdup(host); 442*7c478bd9Sstevel@tonic-gate #endif /* _SOLARIS_SDK */ 443*7c478bd9Sstevel@tonic-gate ldap_memfree( host ); 444*7c478bd9Sstevel@tonic-gate } 445*7c478bd9Sstevel@tonic-gate 446*7c478bd9Sstevel@tonic-gate ldap_x_hostlist_statusfree( status ); 447*7c478bd9Sstevel@tonic-gate 448*7c478bd9Sstevel@tonic-gate if ( rc < 0 ) { 449*7c478bd9Sstevel@tonic-gate prldap_set_system_errno( prldap_prerr2errno()); 450*7c478bd9Sstevel@tonic-gate prldap_socket_arg_free( &prsockp ); 451*7c478bd9Sstevel@tonic-gate } else { 452*7c478bd9Sstevel@tonic-gate *socketargp = prsockp; 453*7c478bd9Sstevel@tonic-gate } 454*7c478bd9Sstevel@tonic-gate 455*7c478bd9Sstevel@tonic-gate #ifdef _SOLARIS_SDK 456*7c478bd9Sstevel@tonic-gate if ( NULL != hostname && NULL != dhost ) *dhost = hostname; 457*7c478bd9Sstevel@tonic-gate else if ( NULL != hostname ) ldap_memfree(hostname); 458*7c478bd9Sstevel@tonic-gate #endif /* _SOLARIS_SDK */ 459*7c478bd9Sstevel@tonic-gate 460*7c478bd9Sstevel@tonic-gate return( rc ); 461*7c478bd9Sstevel@tonic-gate } 462*7c478bd9Sstevel@tonic-gate 463*7c478bd9Sstevel@tonic-gate 464*7c478bd9Sstevel@tonic-gate static int LDAP_CALLBACK 465*7c478bd9Sstevel@tonic-gate prldap_close( int s, struct lextiof_socket_private *socketarg ) 466*7c478bd9Sstevel@tonic-gate { 467*7c478bd9Sstevel@tonic-gate int rc; 468*7c478bd9Sstevel@tonic-gate 469*7c478bd9Sstevel@tonic-gate rc = 0; 470*7c478bd9Sstevel@tonic-gate if ( PR_Close( PRLDAP_GET_PRFD(socketarg)) != PR_SUCCESS ) { 471*7c478bd9Sstevel@tonic-gate rc = -1; 472*7c478bd9Sstevel@tonic-gate prldap_set_system_errno( prldap_prerr2errno()); 473*7c478bd9Sstevel@tonic-gate } 474*7c478bd9Sstevel@tonic-gate prldap_socket_arg_free( &socketarg ); 475*7c478bd9Sstevel@tonic-gate 476*7c478bd9Sstevel@tonic-gate return( rc ); 477*7c478bd9Sstevel@tonic-gate } 478*7c478bd9Sstevel@tonic-gate 479*7c478bd9Sstevel@tonic-gate 480*7c478bd9Sstevel@tonic-gate /* 481*7c478bd9Sstevel@tonic-gate * LDAP session handle creation callback. 482*7c478bd9Sstevel@tonic-gate * 483*7c478bd9Sstevel@tonic-gate * Allocate a session argument if not already done, and then call the 484*7c478bd9Sstevel@tonic-gate * thread's new handle function. 485*7c478bd9Sstevel@tonic-gate */ 486*7c478bd9Sstevel@tonic-gate static int LDAP_CALLBACK 487*7c478bd9Sstevel@tonic-gate prldap_newhandle( LDAP *ld, struct lextiof_session_private *sessionarg ) 488*7c478bd9Sstevel@tonic-gate { 489*7c478bd9Sstevel@tonic-gate 490*7c478bd9Sstevel@tonic-gate if ( NULL == sessionarg ) { 491*7c478bd9Sstevel@tonic-gate struct ldap_x_ext_io_fns iofns; 492*7c478bd9Sstevel@tonic-gate 493*7c478bd9Sstevel@tonic-gate memset( &iofns, 0, sizeof(iofns)); 494*7c478bd9Sstevel@tonic-gate iofns.lextiof_size = LDAP_X_EXTIO_FNS_SIZE; 495*7c478bd9Sstevel@tonic-gate if ( ldap_get_option( ld, LDAP_X_OPT_EXTIO_FN_PTRS, 496*7c478bd9Sstevel@tonic-gate (void *)&iofns ) < 0 ) { 497*7c478bd9Sstevel@tonic-gate return( ldap_get_lderrno( ld, NULL, NULL )); 498*7c478bd9Sstevel@tonic-gate } 499*7c478bd9Sstevel@tonic-gate if ( NULL == 500*7c478bd9Sstevel@tonic-gate ( iofns.lextiof_session_arg = prldap_session_arg_alloc())) { 501*7c478bd9Sstevel@tonic-gate return( LDAP_NO_MEMORY ); 502*7c478bd9Sstevel@tonic-gate } 503*7c478bd9Sstevel@tonic-gate if ( ldap_set_option( ld, LDAP_X_OPT_EXTIO_FN_PTRS, 504*7c478bd9Sstevel@tonic-gate (void *)&iofns ) < 0 ) { 505*7c478bd9Sstevel@tonic-gate return( ldap_get_lderrno( ld, NULL, NULL )); 506*7c478bd9Sstevel@tonic-gate } 507*7c478bd9Sstevel@tonic-gate } 508*7c478bd9Sstevel@tonic-gate 509*7c478bd9Sstevel@tonic-gate return( LDAP_SUCCESS ); 510*7c478bd9Sstevel@tonic-gate } 511*7c478bd9Sstevel@tonic-gate 512*7c478bd9Sstevel@tonic-gate 513*7c478bd9Sstevel@tonic-gate /* only called/installed if shared is non-zero. */ 514*7c478bd9Sstevel@tonic-gate static int LDAP_CALLBACK 515*7c478bd9Sstevel@tonic-gate prldap_shared_newhandle( LDAP *ld, struct lextiof_session_private *sessionarg ) 516*7c478bd9Sstevel@tonic-gate { 517*7c478bd9Sstevel@tonic-gate int rc; 518*7c478bd9Sstevel@tonic-gate 519*7c478bd9Sstevel@tonic-gate if (( rc = prldap_newhandle( ld, sessionarg )) == LDAP_SUCCESS ) { 520*7c478bd9Sstevel@tonic-gate rc = prldap_thread_new_handle( ld, sessionarg ); 521*7c478bd9Sstevel@tonic-gate } 522*7c478bd9Sstevel@tonic-gate 523*7c478bd9Sstevel@tonic-gate return( rc ); 524*7c478bd9Sstevel@tonic-gate } 525*7c478bd9Sstevel@tonic-gate 526*7c478bd9Sstevel@tonic-gate 527*7c478bd9Sstevel@tonic-gate static void LDAP_CALLBACK 528*7c478bd9Sstevel@tonic-gate prldap_disposehandle( LDAP *ld, struct lextiof_session_private *sessionarg ) 529*7c478bd9Sstevel@tonic-gate { 530*7c478bd9Sstevel@tonic-gate prldap_session_arg_free( &sessionarg ); 531*7c478bd9Sstevel@tonic-gate } 532*7c478bd9Sstevel@tonic-gate 533*7c478bd9Sstevel@tonic-gate 534*7c478bd9Sstevel@tonic-gate /* only called/installed if shared is non-zero */ 535*7c478bd9Sstevel@tonic-gate static void LDAP_CALLBACK 536*7c478bd9Sstevel@tonic-gate prldap_shared_disposehandle( LDAP *ld, 537*7c478bd9Sstevel@tonic-gate struct lextiof_session_private *sessionarg ) 538*7c478bd9Sstevel@tonic-gate { 539*7c478bd9Sstevel@tonic-gate prldap_thread_dispose_handle( ld, sessionarg ); 540*7c478bd9Sstevel@tonic-gate prldap_disposehandle( ld, sessionarg ); 541*7c478bd9Sstevel@tonic-gate } 542*7c478bd9Sstevel@tonic-gate 543*7c478bd9Sstevel@tonic-gate 544*7c478bd9Sstevel@tonic-gate /* 545*7c478bd9Sstevel@tonic-gate * Allocate a session argument. 546*7c478bd9Sstevel@tonic-gate */ 547*7c478bd9Sstevel@tonic-gate static PRLDAPIOSessionArg * 548*7c478bd9Sstevel@tonic-gate prldap_session_arg_alloc( void ) 549*7c478bd9Sstevel@tonic-gate { 550*7c478bd9Sstevel@tonic-gate PRLDAPIOSessionArg *prsessp; 551*7c478bd9Sstevel@tonic-gate 552*7c478bd9Sstevel@tonic-gate prsessp = PR_Calloc( 1, sizeof( PRLDAPIOSessionArg )); 553*7c478bd9Sstevel@tonic-gate 554*7c478bd9Sstevel@tonic-gate if ( NULL != prsessp ) { 555*7c478bd9Sstevel@tonic-gate /* copy global defaults to the new session handle */ 556*7c478bd9Sstevel@tonic-gate prsessp->prsess_io_max_timeout = prldap_default_io_max_timeout; 557*7c478bd9Sstevel@tonic-gate } 558*7c478bd9Sstevel@tonic-gate 559*7c478bd9Sstevel@tonic-gate return( prsessp ); 560*7c478bd9Sstevel@tonic-gate } 561*7c478bd9Sstevel@tonic-gate 562*7c478bd9Sstevel@tonic-gate 563*7c478bd9Sstevel@tonic-gate static void 564*7c478bd9Sstevel@tonic-gate prldap_session_arg_free( PRLDAPIOSessionArg **prsesspp ) 565*7c478bd9Sstevel@tonic-gate { 566*7c478bd9Sstevel@tonic-gate if ( NULL != prsesspp && NULL != *prsesspp ) { 567*7c478bd9Sstevel@tonic-gate if ( NULL != (*prsesspp)->prsess_pollds ) { 568*7c478bd9Sstevel@tonic-gate PR_Free( (*prsesspp)->prsess_pollds ); 569*7c478bd9Sstevel@tonic-gate (*prsesspp)->prsess_pollds = NULL; 570*7c478bd9Sstevel@tonic-gate } 571*7c478bd9Sstevel@tonic-gate PR_Free( *prsesspp ); 572*7c478bd9Sstevel@tonic-gate *prsesspp = NULL; 573*7c478bd9Sstevel@tonic-gate } 574*7c478bd9Sstevel@tonic-gate } 575*7c478bd9Sstevel@tonic-gate 576*7c478bd9Sstevel@tonic-gate 577*7c478bd9Sstevel@tonic-gate /* 578*7c478bd9Sstevel@tonic-gate * Given an LDAP session handle, retrieve a session argument. 579*7c478bd9Sstevel@tonic-gate * Returns an LDAP error code. 580*7c478bd9Sstevel@tonic-gate */ 581*7c478bd9Sstevel@tonic-gate int 582*7c478bd9Sstevel@tonic-gate prldap_session_arg_from_ld( LDAP *ld, PRLDAPIOSessionArg **sessargpp ) 583*7c478bd9Sstevel@tonic-gate { 584*7c478bd9Sstevel@tonic-gate struct ldap_x_ext_io_fns iofns; 585*7c478bd9Sstevel@tonic-gate 586*7c478bd9Sstevel@tonic-gate if ( NULL == ld || NULL == sessargpp ) { 587*7c478bd9Sstevel@tonic-gate /* XXXmcs: NULL ld's are not supported */ 588*7c478bd9Sstevel@tonic-gate ldap_set_lderrno( ld, LDAP_PARAM_ERROR, NULL, NULL ); 589*7c478bd9Sstevel@tonic-gate return( LDAP_PARAM_ERROR ); 590*7c478bd9Sstevel@tonic-gate } 591*7c478bd9Sstevel@tonic-gate 592*7c478bd9Sstevel@tonic-gate memset( &iofns, 0, sizeof(iofns)); 593*7c478bd9Sstevel@tonic-gate iofns.lextiof_size = LDAP_X_EXTIO_FNS_SIZE; 594*7c478bd9Sstevel@tonic-gate if ( ldap_get_option( ld, LDAP_X_OPT_EXTIO_FN_PTRS, (void *)&iofns ) < 0 ) { 595*7c478bd9Sstevel@tonic-gate return( ldap_get_lderrno( ld, NULL, NULL )); 596*7c478bd9Sstevel@tonic-gate } 597*7c478bd9Sstevel@tonic-gate 598*7c478bd9Sstevel@tonic-gate if ( NULL == iofns.lextiof_session_arg ) { 599*7c478bd9Sstevel@tonic-gate ldap_set_lderrno( ld, LDAP_LOCAL_ERROR, NULL, NULL ); 600*7c478bd9Sstevel@tonic-gate return( LDAP_LOCAL_ERROR ); 601*7c478bd9Sstevel@tonic-gate } 602*7c478bd9Sstevel@tonic-gate 603*7c478bd9Sstevel@tonic-gate *sessargpp = iofns.lextiof_session_arg; 604*7c478bd9Sstevel@tonic-gate return( LDAP_SUCCESS ); 605*7c478bd9Sstevel@tonic-gate } 606*7c478bd9Sstevel@tonic-gate 607*7c478bd9Sstevel@tonic-gate 608*7c478bd9Sstevel@tonic-gate /* 609*7c478bd9Sstevel@tonic-gate * Given an LDAP session handle, retrieve a socket argument. 610*7c478bd9Sstevel@tonic-gate * Returns an LDAP error code. 611*7c478bd9Sstevel@tonic-gate */ 612*7c478bd9Sstevel@tonic-gate int 613*7c478bd9Sstevel@tonic-gate prldap_socket_arg_from_ld( LDAP *ld, PRLDAPIOSocketArg **sockargpp ) 614*7c478bd9Sstevel@tonic-gate { 615*7c478bd9Sstevel@tonic-gate Sockbuf *sbp; 616*7c478bd9Sstevel@tonic-gate struct lber_x_ext_io_fns extiofns; 617*7c478bd9Sstevel@tonic-gate 618*7c478bd9Sstevel@tonic-gate if ( NULL == ld || NULL == sockargpp ) { 619*7c478bd9Sstevel@tonic-gate /* XXXmcs: NULL ld's are not supported */ 620*7c478bd9Sstevel@tonic-gate ldap_set_lderrno( ld, LDAP_PARAM_ERROR, NULL, NULL ); 621*7c478bd9Sstevel@tonic-gate return( LDAP_PARAM_ERROR ); 622*7c478bd9Sstevel@tonic-gate } 623*7c478bd9Sstevel@tonic-gate 624*7c478bd9Sstevel@tonic-gate if ( ldap_get_option( ld, LDAP_X_OPT_SOCKBUF, (void *)&sbp ) < 0 ) { 625*7c478bd9Sstevel@tonic-gate return( ldap_get_lderrno( ld, NULL, NULL )); 626*7c478bd9Sstevel@tonic-gate } 627*7c478bd9Sstevel@tonic-gate 628*7c478bd9Sstevel@tonic-gate memset( &extiofns, 0, sizeof(extiofns)); 629*7c478bd9Sstevel@tonic-gate extiofns.lbextiofn_size = LBER_X_EXTIO_FNS_SIZE; 630*7c478bd9Sstevel@tonic-gate if ( ber_sockbuf_get_option( sbp, LBER_SOCKBUF_OPT_EXT_IO_FNS, 631*7c478bd9Sstevel@tonic-gate (void *)&extiofns ) < 0 ) { 632*7c478bd9Sstevel@tonic-gate return( ldap_get_lderrno( ld, NULL, NULL )); 633*7c478bd9Sstevel@tonic-gate } 634*7c478bd9Sstevel@tonic-gate 635*7c478bd9Sstevel@tonic-gate if ( NULL == extiofns.lbextiofn_socket_arg ) { 636*7c478bd9Sstevel@tonic-gate ldap_set_lderrno( ld, LDAP_LOCAL_ERROR, NULL, NULL ); 637*7c478bd9Sstevel@tonic-gate return( LDAP_LOCAL_ERROR ); 638*7c478bd9Sstevel@tonic-gate } 639*7c478bd9Sstevel@tonic-gate 640*7c478bd9Sstevel@tonic-gate *sockargpp = extiofns.lbextiofn_socket_arg; 641*7c478bd9Sstevel@tonic-gate return( LDAP_SUCCESS ); 642*7c478bd9Sstevel@tonic-gate } 643*7c478bd9Sstevel@tonic-gate 644*7c478bd9Sstevel@tonic-gate 645*7c478bd9Sstevel@tonic-gate /* 646*7c478bd9Sstevel@tonic-gate * Allocate a socket argument. 647*7c478bd9Sstevel@tonic-gate */ 648*7c478bd9Sstevel@tonic-gate static PRLDAPIOSocketArg * 649*7c478bd9Sstevel@tonic-gate prldap_socket_arg_alloc( PRLDAPIOSessionArg *sessionarg ) 650*7c478bd9Sstevel@tonic-gate { 651*7c478bd9Sstevel@tonic-gate PRLDAPIOSocketArg *prsockp; 652*7c478bd9Sstevel@tonic-gate 653*7c478bd9Sstevel@tonic-gate prsockp = PR_Calloc( 1, sizeof( PRLDAPIOSocketArg )); 654*7c478bd9Sstevel@tonic-gate 655*7c478bd9Sstevel@tonic-gate if ( NULL != prsockp && NULL != sessionarg ) { 656*7c478bd9Sstevel@tonic-gate /* copy socket defaults from the session */ 657*7c478bd9Sstevel@tonic-gate prsockp->prsock_io_max_timeout = sessionarg->prsess_io_max_timeout; 658*7c478bd9Sstevel@tonic-gate } 659*7c478bd9Sstevel@tonic-gate 660*7c478bd9Sstevel@tonic-gate return( prsockp ); 661*7c478bd9Sstevel@tonic-gate } 662*7c478bd9Sstevel@tonic-gate 663*7c478bd9Sstevel@tonic-gate 664*7c478bd9Sstevel@tonic-gate static void 665*7c478bd9Sstevel@tonic-gate prldap_socket_arg_free( PRLDAPIOSocketArg **prsockpp ) 666*7c478bd9Sstevel@tonic-gate { 667*7c478bd9Sstevel@tonic-gate if ( NULL != prsockpp && NULL != *prsockpp ) { 668*7c478bd9Sstevel@tonic-gate PR_Free( *prsockpp ); 669*7c478bd9Sstevel@tonic-gate *prsockpp = NULL; 670*7c478bd9Sstevel@tonic-gate } 671*7c478bd9Sstevel@tonic-gate } 672*7c478bd9Sstevel@tonic-gate 673*7c478bd9Sstevel@tonic-gate 674*7c478bd9Sstevel@tonic-gate static void * 675*7c478bd9Sstevel@tonic-gate prldap_safe_realloc( void *ptr, PRUint32 size ) 676*7c478bd9Sstevel@tonic-gate { 677*7c478bd9Sstevel@tonic-gate void *p; 678*7c478bd9Sstevel@tonic-gate 679*7c478bd9Sstevel@tonic-gate if ( NULL == ptr ) { 680*7c478bd9Sstevel@tonic-gate p = PR_Malloc( size ); 681*7c478bd9Sstevel@tonic-gate } else { 682*7c478bd9Sstevel@tonic-gate p = PR_Realloc( ptr, size ); 683*7c478bd9Sstevel@tonic-gate } 684*7c478bd9Sstevel@tonic-gate 685*7c478bd9Sstevel@tonic-gate return( p ); 686*7c478bd9Sstevel@tonic-gate } 687*7c478bd9Sstevel@tonic-gate 688*7c478bd9Sstevel@tonic-gate 689*7c478bd9Sstevel@tonic-gate 690*7c478bd9Sstevel@tonic-gate /* returns an LDAP result code */ 691*7c478bd9Sstevel@tonic-gate int 692*7c478bd9Sstevel@tonic-gate prldap_set_io_max_timeout( PRLDAPIOSessionArg *prsessp, int io_max_timeout ) 693*7c478bd9Sstevel@tonic-gate { 694*7c478bd9Sstevel@tonic-gate int rc = LDAP_SUCCESS; /* optimistic */ 695*7c478bd9Sstevel@tonic-gate 696*7c478bd9Sstevel@tonic-gate if ( NULL == prsessp ) { 697*7c478bd9Sstevel@tonic-gate prldap_default_io_max_timeout = io_max_timeout; 698*7c478bd9Sstevel@tonic-gate } else { 699*7c478bd9Sstevel@tonic-gate prsessp->prsess_io_max_timeout = io_max_timeout; 700*7c478bd9Sstevel@tonic-gate } 701*7c478bd9Sstevel@tonic-gate 702*7c478bd9Sstevel@tonic-gate return( rc ); 703*7c478bd9Sstevel@tonic-gate } 704*7c478bd9Sstevel@tonic-gate 705*7c478bd9Sstevel@tonic-gate 706*7c478bd9Sstevel@tonic-gate /* returns an LDAP result code */ 707*7c478bd9Sstevel@tonic-gate int 708*7c478bd9Sstevel@tonic-gate prldap_get_io_max_timeout( PRLDAPIOSessionArg *prsessp, int *io_max_timeoutp ) 709*7c478bd9Sstevel@tonic-gate { 710*7c478bd9Sstevel@tonic-gate int rc = LDAP_SUCCESS; /* optimistic */ 711*7c478bd9Sstevel@tonic-gate 712*7c478bd9Sstevel@tonic-gate if ( NULL == io_max_timeoutp ) { 713*7c478bd9Sstevel@tonic-gate rc = LDAP_PARAM_ERROR; 714*7c478bd9Sstevel@tonic-gate } else if ( NULL == prsessp ) { 715*7c478bd9Sstevel@tonic-gate *io_max_timeoutp = prldap_default_io_max_timeout; 716*7c478bd9Sstevel@tonic-gate } else { 717*7c478bd9Sstevel@tonic-gate *io_max_timeoutp = prsessp->prsess_io_max_timeout; 718*7c478bd9Sstevel@tonic-gate } 719*7c478bd9Sstevel@tonic-gate 720*7c478bd9Sstevel@tonic-gate return( rc ); 721*7c478bd9Sstevel@tonic-gate } 722