mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-12-21 15:19:34 -05:00
-lldap reentrantancy improvements from Bart Hartgers <A.Hartgers@phys.tue.nl>
including use of ctime_r, gethostby*_r, etc.. Also reworked ldap_sort_entries to be reentrant. Need to add code to properly set LDAP_API_FEATURE_THREAD_SAFE.
This commit is contained in:
parent
b5e50eff5e
commit
0024cf2f4b
15 changed files with 462 additions and 323 deletions
|
|
@ -22,7 +22,8 @@ lint5: lint5-local FORCE
|
||||||
$(5LINT) $(DEFS) $(DEFINES) $(SRCS)
|
$(5LINT) $(DEFS) $(DEFINES) $(SRCS)
|
||||||
|
|
||||||
clean-common: FORCE
|
clean-common: FORCE
|
||||||
$(RM) $(LIBRARY) ../$(LIBRARY) $(PROGRAMS) $(XPROGRAMS) $(XSRCS) \
|
$(RM) $(LIBRARY) ../$(LIBRARY) $(XLIBRARY) \
|
||||||
|
$(PROGRAMS) $(XPROGRAMS) $(XSRCS) \
|
||||||
*.o *.lo a.out core version.c .libs/*
|
*.o *.lo a.out core version.c .libs/*
|
||||||
|
|
||||||
depend-common: FORCE
|
depend-common: FORCE
|
||||||
|
|
|
||||||
52
configure.in
52
configure.in
|
|
@ -803,24 +803,37 @@ int x = errno;
|
||||||
LTHREAD_LIBS=""
|
LTHREAD_LIBS=""
|
||||||
fi
|
fi
|
||||||
|
|
||||||
dnl check for reentrant/threadsafe functions
|
dnl When in thread environment, use
|
||||||
dnl
|
dnl #if defined( HAVE_REENTRANT_FUNCTIONS ) \
|
||||||
dnl note: these should only be used when linking
|
dnl || defined( HAVE_FUNC_R )
|
||||||
dnl with $LTHREAD_LIBS
|
dnl func_r(...);
|
||||||
dnl
|
dnl #else
|
||||||
save_CPPFLAGS="$CPPFLAGS"
|
dnl func(...);
|
||||||
save_LIBS="$LIBS"
|
dnl #endif
|
||||||
LIBS="$LTHREAD_LIBS $LIBS"
|
dnl
|
||||||
AC_CHECK_FUNCS( \
|
dnl HAVE_REENTRANT_FUNCTIONS is derived from:
|
||||||
strtok_r \
|
dnl _POSIX_REENTRANT_FUNCTIONS
|
||||||
gmtime_r \
|
dnl _POSIX_THREAD_SAFE_FUNCTIONS
|
||||||
gethostbyaddr_r gethostbyname_r \
|
dnl _POSIX_THREADSAFE_FUNCTIONS
|
||||||
feof_unlocked unlocked_feof \
|
dnl
|
||||||
putc_unlocked unlocked_putc \
|
dnl dnl check for reentrant/threadsafe functions
|
||||||
flockfile ftrylockfile \
|
dnl dnl
|
||||||
)
|
dnl dnl note: these should only be used when linking
|
||||||
CPPFLAGS="$save_CPPFLAGS"
|
dnl dnl with $LTHREAD_LIBS
|
||||||
LIBS="$save_LIBS"
|
dnl dnl
|
||||||
|
dnl save_CPPFLAGS="$CPPFLAGS"
|
||||||
|
dnl save_LIBS="$LIBS"
|
||||||
|
dnl LIBS="$LTHREAD_LIBS $LIBS"
|
||||||
|
dnl AC_CHECK_FUNCS( \
|
||||||
|
dnl strtok_r \
|
||||||
|
dnl gmtime_r \
|
||||||
|
dnl gethostbyaddr_r gethostbyname_r \
|
||||||
|
dnl feof_unlocked unlocked_feof \
|
||||||
|
dnl putc_unlocked unlocked_putc \
|
||||||
|
dnl flockfile ftrylockfile \
|
||||||
|
dnl )
|
||||||
|
dnl CPPFLAGS="$save_CPPFLAGS"
|
||||||
|
dnl LIBS="$save_LIBS"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
dnl ----------------------------------------------------------------
|
dnl ----------------------------------------------------------------
|
||||||
|
|
@ -1103,9 +1116,11 @@ AC_FUNC_WAIT3
|
||||||
|
|
||||||
AC_CHECK_FUNCS( \
|
AC_CHECK_FUNCS( \
|
||||||
bcopy \
|
bcopy \
|
||||||
|
ctime_r \
|
||||||
flock \
|
flock \
|
||||||
getdtablesize \
|
getdtablesize \
|
||||||
gethostname \
|
gethostname \
|
||||||
|
gethostbyaddr_r gethostbyname_r \
|
||||||
getpwuid \
|
getpwuid \
|
||||||
gettimeofday \
|
gettimeofday \
|
||||||
lockf \
|
lockf \
|
||||||
|
|
@ -1126,6 +1141,7 @@ AC_CHECK_FUNCS( \
|
||||||
strsep \
|
strsep \
|
||||||
strstr \
|
strstr \
|
||||||
strtok \
|
strtok \
|
||||||
|
strtok_r \
|
||||||
strtol \
|
strtol \
|
||||||
strtoul \
|
strtoul \
|
||||||
sysconf \
|
sysconf \
|
||||||
|
|
|
||||||
|
|
@ -279,18 +279,12 @@ is provided ``as is'' without express or implied warranty.
|
||||||
/* Define if you have the bcopy function. */
|
/* Define if you have the bcopy function. */
|
||||||
#undef HAVE_BCOPY
|
#undef HAVE_BCOPY
|
||||||
|
|
||||||
/* Define if you have the feof_unlocked function. */
|
/* Define if you have the ctime_r function. */
|
||||||
#undef HAVE_FEOF_UNLOCKED
|
#undef HAVE_CTIME_R
|
||||||
|
|
||||||
/* Define if you have the flock function. */
|
/* Define if you have the flock function. */
|
||||||
#undef HAVE_FLOCK
|
#undef HAVE_FLOCK
|
||||||
|
|
||||||
/* Define if you have the flockfile function. */
|
|
||||||
#undef HAVE_FLOCKFILE
|
|
||||||
|
|
||||||
/* Define if you have the ftrylockfile function. */
|
|
||||||
#undef HAVE_FTRYLOCKFILE
|
|
||||||
|
|
||||||
/* Define if you have the getdtablesize function. */
|
/* Define if you have the getdtablesize function. */
|
||||||
#undef HAVE_GETDTABLESIZE
|
#undef HAVE_GETDTABLESIZE
|
||||||
|
|
||||||
|
|
@ -312,9 +306,6 @@ is provided ``as is'' without express or implied warranty.
|
||||||
/* Define if you have the gettimeofday function. */
|
/* Define if you have the gettimeofday function. */
|
||||||
#undef HAVE_GETTIMEOFDAY
|
#undef HAVE_GETTIMEOFDAY
|
||||||
|
|
||||||
/* Define if you have the gmtime_r function. */
|
|
||||||
#undef HAVE_GMTIME_R
|
|
||||||
|
|
||||||
/* Define if you have the lockf function. */
|
/* Define if you have the lockf function. */
|
||||||
#undef HAVE_LOCKF
|
#undef HAVE_LOCKF
|
||||||
|
|
||||||
|
|
@ -354,9 +345,6 @@ is provided ``as is'' without express or implied warranty.
|
||||||
/* Define if you have the pthread_yield function. */
|
/* Define if you have the pthread_yield function. */
|
||||||
#undef HAVE_PTHREAD_YIELD
|
#undef HAVE_PTHREAD_YIELD
|
||||||
|
|
||||||
/* Define if you have the putc_unlocked function. */
|
|
||||||
#undef HAVE_PUTC_UNLOCKED
|
|
||||||
|
|
||||||
/* Define if you have the res_search function. */
|
/* Define if you have the res_search function. */
|
||||||
#undef HAVE_RES_SEARCH
|
#undef HAVE_RES_SEARCH
|
||||||
|
|
||||||
|
|
@ -423,12 +411,6 @@ is provided ``as is'' without express or implied warranty.
|
||||||
/* Define if you have the thr_setconcurrency function. */
|
/* Define if you have the thr_setconcurrency function. */
|
||||||
#undef HAVE_THR_SETCONCURRENCY
|
#undef HAVE_THR_SETCONCURRENCY
|
||||||
|
|
||||||
/* Define if you have the unlocked_feof function. */
|
|
||||||
#undef HAVE_UNLOCKED_FEOF
|
|
||||||
|
|
||||||
/* Define if you have the unlocked_putc function. */
|
|
||||||
#undef HAVE_UNLOCKED_PUTC
|
|
||||||
|
|
||||||
/* Define if you have the vsnprintf function. */
|
/* Define if you have the vsnprintf function. */
|
||||||
#undef HAVE_VSNPRINTF
|
#undef HAVE_VSNPRINTF
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
##
|
##
|
||||||
|
|
||||||
LIBRARY = liblber.la
|
LIBRARY = liblber.la
|
||||||
|
XLIBRARY = ../liblber.a
|
||||||
|
|
||||||
SRCS= decode.c encode.c io.c bprint.c
|
SRCS= decode.c encode.c io.c bprint.c
|
||||||
OBJS= decode.lo encode.lo io.lo bprint.lo
|
OBJS= decode.lo encode.lo io.lo bprint.lo
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,8 @@
|
||||||
## Makefile.in for LDAP -lldap
|
## Makefile.in for LDAP -lldap
|
||||||
##
|
##
|
||||||
LIBRARY = libldap.la
|
LIBRARY = libldap.la
|
||||||
|
XLIBRARY = ../libldap.a
|
||||||
|
|
||||||
PROGRAMS = apitest ltest ttest
|
PROGRAMS = apitest ltest ttest
|
||||||
|
|
||||||
SRCS = bind.c open.c result.c error.c compare.c search.c \
|
SRCS = bind.c open.c result.c error.c compare.c search.c \
|
||||||
|
|
@ -10,14 +12,14 @@ SRCS = bind.c open.c result.c error.c compare.c search.c \
|
||||||
free.c disptmpl.c srchpref.c dsparse.c tmplout.c sort.c \
|
free.c disptmpl.c srchpref.c dsparse.c tmplout.c sort.c \
|
||||||
getdn.c getentry.c getattr.c getvalues.c addentry.c \
|
getdn.c getentry.c getattr.c getvalues.c addentry.c \
|
||||||
request.c getdxbyname.c os-ip.c url.c charset.c \
|
request.c getdxbyname.c os-ip.c url.c charset.c \
|
||||||
init.c options.c strdup.c
|
init.c options.c strdup.c util-int.c
|
||||||
OBJS = bind.lo open.lo result.lo error.lo compare.lo search.lo \
|
OBJS = bind.lo open.lo result.lo error.lo compare.lo search.lo \
|
||||||
modify.lo add.lo modrdn.lo delete.lo abandon.lo ufn.lo cache.lo \
|
modify.lo add.lo modrdn.lo delete.lo abandon.lo ufn.lo cache.lo \
|
||||||
getfilter.lo sbind.lo kbind.lo unbind.lo friendly.lo cldap.lo \
|
getfilter.lo sbind.lo kbind.lo unbind.lo friendly.lo cldap.lo \
|
||||||
free.lo disptmpl.lo srchpref.lo dsparse.lo tmplout.lo sort.lo \
|
free.lo disptmpl.lo srchpref.lo dsparse.lo tmplout.lo sort.lo \
|
||||||
getdn.lo getentry.lo getattr.lo getvalues.lo addentry.lo \
|
getdn.lo getentry.lo getattr.lo getvalues.lo addentry.lo \
|
||||||
request.lo getdxbyname.lo os-ip.lo url.lo charset.lo \
|
request.lo getdxbyname.lo os-ip.lo url.lo charset.lo \
|
||||||
init.lo options.lo strdup.lo
|
init.lo options.lo strdup.lo util-int.lo
|
||||||
|
|
||||||
LDAP_INCDIR= ../../include
|
LDAP_INCDIR= ../../include
|
||||||
LDAP_LIBDIR= ../../libraries
|
LDAP_LIBDIR= ../../libraries
|
||||||
|
|
|
||||||
|
|
@ -64,6 +64,13 @@ cldap_open( char *host, int port )
|
||||||
char *p;
|
char *p;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
/* buffers for ldap_int_gethostbyname_a ... */
|
||||||
|
struct hostent he_buf;
|
||||||
|
int local_h_errno;
|
||||||
|
char *ha_buf=NULL;
|
||||||
|
|
||||||
|
#define DO_RETURN(x) if (ha_buf) free(ha_buf); return (x);
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "ldap_open\n", 0, 0, 0 );
|
Debug( LDAP_DEBUG_TRACE, "ldap_open\n", 0, 0, 0 );
|
||||||
|
|
||||||
if ( (s = socket( AF_INET, SOCK_DGRAM, 0 )) < 0 ) {
|
if ( (s = socket( AF_INET, SOCK_DGRAM, 0 )) < 0 ) {
|
||||||
|
|
@ -110,7 +117,9 @@ cldap_open( char *host, int port )
|
||||||
/* This was just a test for -1 until OSF1 let inet_addr return
|
/* This was just a test for -1 until OSF1 let inet_addr return
|
||||||
unsigned int, which is narrower than 'unsigned long address' */
|
unsigned int, which is narrower than 'unsigned long address' */
|
||||||
if ( address == 0xffffffff || address == (unsigned long) -1 ) {
|
if ( address == 0xffffffff || address == (unsigned long) -1 ) {
|
||||||
if ( (hp = gethostbyname( host )) == NULL ) {
|
if ((ldap_int_gethostbyname_a( host, &he_buf, &ha_buf,
|
||||||
|
&hp,&local_h_errno)<0) ||
|
||||||
|
(hp==NULL)) {
|
||||||
errno = EHOSTUNREACH;
|
errno = EHOSTUNREACH;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
@ -121,7 +130,7 @@ cldap_open( char *host, int port )
|
||||||
sizeof(sock.sin_addr.s_addr));
|
sizeof(sock.sin_addr.s_addr));
|
||||||
if ( add_addr( ld, (struct sockaddr *)&sock ) < 0 ) {
|
if ( add_addr( ld, (struct sockaddr *)&sock ) < 0 ) {
|
||||||
ldap_ld_free( ld, 1 );
|
ldap_ld_free( ld, 1 );
|
||||||
return( NULL );
|
DO_RETURN( NULL );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -129,7 +138,7 @@ cldap_open( char *host, int port )
|
||||||
sock.sin_addr.s_addr = address;
|
sock.sin_addr.s_addr = address;
|
||||||
if ( add_addr( ld, (struct sockaddr *)&sock ) < 0 ) {
|
if ( add_addr( ld, (struct sockaddr *)&sock ) < 0 ) {
|
||||||
ldap_ld_free( ld, 1 );
|
ldap_ld_free( ld, 1 );
|
||||||
return( NULL );
|
DO_RETURN( NULL );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -137,13 +146,12 @@ cldap_open( char *host, int port )
|
||||||
ld->ld_host = ldap_strdup( host );
|
ld->ld_host = ldap_strdup( host );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
address = INADDR_LOOPBACK;
|
address = INADDR_LOOPBACK;
|
||||||
sock.sin_addr.s_addr = htonl( address );
|
sock.sin_addr.s_addr = htonl( address );
|
||||||
if ( add_addr( ld, (struct sockaddr *)&sock ) < 0 ) {
|
if ( add_addr( ld, (struct sockaddr *)&sock ) < 0 ) {
|
||||||
ldap_ld_free( ld, 1 );
|
ldap_ld_free( ld, 1 );
|
||||||
return( NULL );
|
DO_RETURN( NULL );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -153,7 +161,7 @@ cldap_open( char *host, int port )
|
||||||
#endif /* LDAP_API_FEATURE_X_OPENLDAP_V2_REFERRALS */
|
#endif /* LDAP_API_FEATURE_X_OPENLDAP_V2_REFERRALS */
|
||||||
) {
|
) {
|
||||||
ldap_ld_free( ld, 0 );
|
ldap_ld_free( ld, 0 );
|
||||||
return( NULL );
|
DO_RETURN( NULL );
|
||||||
}
|
}
|
||||||
|
|
||||||
ld->ld_sb.sb_useaddr = ld->ld_sb.sb_addrs[ 0 ];
|
ld->ld_sb.sb_useaddr = ld->ld_sb.sb_addrs[ 0 ];
|
||||||
|
|
@ -168,10 +176,10 @@ cldap_open( char *host, int port )
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return( ld );
|
DO_RETURN( ld );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#undef DO_RETURN
|
||||||
|
|
||||||
void
|
void
|
||||||
cldap_close( LDAP *ld )
|
cldap_close( LDAP *ld )
|
||||||
|
|
|
||||||
|
|
@ -124,6 +124,7 @@ ldap_explode_dns( char *dn )
|
||||||
int ncomps, maxcomps;
|
int ncomps, maxcomps;
|
||||||
char *s;
|
char *s;
|
||||||
char **rdns;
|
char **rdns;
|
||||||
|
char *tok_r;
|
||||||
|
|
||||||
if ( (rdns = (char **) malloc( 8 * sizeof(char *) )) == NULL ) {
|
if ( (rdns = (char **) malloc( 8 * sizeof(char *) )) == NULL ) {
|
||||||
return( NULL );
|
return( NULL );
|
||||||
|
|
@ -131,7 +132,8 @@ ldap_explode_dns( char *dn )
|
||||||
|
|
||||||
maxcomps = 8;
|
maxcomps = 8;
|
||||||
ncomps = 0;
|
ncomps = 0;
|
||||||
for ( s = strtok( dn, "@." ); s != NULL; s = strtok( NULL, "@." ) ) {
|
for ( s = ldap_int_strtok( dn, "@.", &tok_r ); s != NULL;
|
||||||
|
s = ldap_int_strtok( NULL, "@.", &tok_r ) ) {
|
||||||
if ( ncomps == maxcomps ) {
|
if ( ncomps == maxcomps ) {
|
||||||
maxcomps *= 2;
|
maxcomps *= 2;
|
||||||
if ( (rdns = (char **) realloc( rdns, maxcomps *
|
if ( (rdns = (char **) realloc( rdns, maxcomps *
|
||||||
|
|
|
||||||
|
|
@ -405,6 +405,7 @@ break_into_words( char *str, char *delims, char ***wordsp )
|
||||||
{
|
{
|
||||||
char *word, **words;
|
char *word, **words;
|
||||||
int count;
|
int count;
|
||||||
|
char *tok_r;
|
||||||
|
|
||||||
if (( words = (char **)calloc( 1, sizeof( char * ))) == NULL ) {
|
if (( words = (char **)calloc( 1, sizeof( char * ))) == NULL ) {
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
@ -412,7 +413,7 @@ break_into_words( char *str, char *delims, char ***wordsp )
|
||||||
count = 0;
|
count = 0;
|
||||||
words[ count ] = NULL;
|
words[ count ] = NULL;
|
||||||
|
|
||||||
word = strtok( str, delims );
|
word = ldap_int_strtok( str, delims, &tok_r );
|
||||||
while ( word != NULL ) {
|
while ( word != NULL ) {
|
||||||
if (( words = (char **)realloc( words,
|
if (( words = (char **)realloc( words,
|
||||||
( count + 2 ) * sizeof( char * ))) == NULL ) {
|
( count + 2 ) * sizeof( char * ))) == NULL ) {
|
||||||
|
|
@ -421,7 +422,7 @@ break_into_words( char *str, char *delims, char ***wordsp )
|
||||||
|
|
||||||
words[ count ] = word;
|
words[ count ] = word;
|
||||||
words[ ++count ] = NULL;
|
words[ ++count ] = NULL;
|
||||||
word = strtok( NULL, delims );
|
word = ldap_int_strtok( NULL, delims, &tok_r );
|
||||||
}
|
}
|
||||||
|
|
||||||
*wordsp = words;
|
*wordsp = words;
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,8 @@
|
||||||
#include "../liblber/lber-int.h"
|
#include "../liblber/lber-int.h"
|
||||||
#include "ldap_log.h"
|
#include "ldap_log.h"
|
||||||
#include "ldap.h"
|
#include "ldap.h"
|
||||||
|
#include <time.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
|
||||||
LDAP_BEGIN_DECL
|
LDAP_BEGIN_DECL
|
||||||
|
|
||||||
|
|
@ -273,6 +275,28 @@ int ldap_8859_to_t61( char **bufp, unsigned long *buflenp, int free_input );
|
||||||
#endif /* LDAP_CHARSET_8859 == LDAP_DEFAULT_CHARSET */
|
#endif /* LDAP_CHARSET_8859 == LDAP_DEFAULT_CHARSET */
|
||||||
#endif /* STR_TRANSLATION && LDAP_DEFAULT_CHARSET */
|
#endif /* STR_TRANSLATION && LDAP_DEFAULT_CHARSET */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* in util_r.c
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern char *ldap_int_strtok( char *str, const char *delim, char **pos );
|
||||||
|
extern char *ldap_int_ctime( const time_t *tp, char *buf );
|
||||||
|
extern int ldap_int_gethostbyname_a(
|
||||||
|
const char *name,
|
||||||
|
struct hostent *resbuf,
|
||||||
|
char **buf,
|
||||||
|
struct hostent **result,
|
||||||
|
int *herrno_ptr );
|
||||||
|
extern int ldap_int_gethostbyaddr_a(
|
||||||
|
const char *addr,
|
||||||
|
int len,
|
||||||
|
int type,
|
||||||
|
struct hostent *resbuf,
|
||||||
|
char **buf,
|
||||||
|
struct hostent **result,
|
||||||
|
int *herrno_ptr );
|
||||||
|
|
||||||
LDAP_END_DECL
|
LDAP_END_DECL
|
||||||
|
|
||||||
#endif /* _LDAP_INT_H */
|
#endif /* _LDAP_INT_H */
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,12 @@ ldap_connect_to_host( Sockbuf *sb, char *host, unsigned long address,
|
||||||
#endif /* LDAP_API_FEATURE_X_OPENLDAP_V2_REFERRALS */
|
#endif /* LDAP_API_FEATURE_X_OPENLDAP_V2_REFERRALS */
|
||||||
#endif /* notyet */
|
#endif /* notyet */
|
||||||
|
|
||||||
|
/* buffers for ldap_int_gethostbyname_a */
|
||||||
|
struct hostent he_buf;
|
||||||
|
int local_h_errno;
|
||||||
|
char *ha_buf=NULL;
|
||||||
|
#define DO_RETURN(x) if (ha_buf) free(ha_buf); return (x);
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "ldap_connect_to_host: %s:%d\n",
|
Debug( LDAP_DEBUG_TRACE, "ldap_connect_to_host: %s:%d\n",
|
||||||
( host == NULL ) ? "(by address)" : host, (int) ntohs( (short) port ), 0 );
|
( host == NULL ) ? "(by address)" : host, (int) ntohs( (short) port ), 0 );
|
||||||
|
|
||||||
|
|
@ -59,13 +65,15 @@ ldap_connect_to_host( Sockbuf *sb, char *host, unsigned long address,
|
||||||
/* This was just a test for -1 until OSF1 let inet_addr return
|
/* This was just a test for -1 until OSF1 let inet_addr return
|
||||||
unsigned int, which is narrower than 'unsigned long address' */
|
unsigned int, which is narrower than 'unsigned long address' */
|
||||||
if ( address == 0xffffffff || address == (unsigned long) -1 ) {
|
if ( address == 0xffffffff || address == (unsigned long) -1 ) {
|
||||||
if ( (hp = gethostbyname( host )) == NULL ) {
|
if ( ( ldap_int_gethostbyname_a( host, &he_buf, &ha_buf,
|
||||||
|
&hp, &local_h_errno) < 0) || (hp==NULL))
|
||||||
|
{
|
||||||
#ifdef HAVE_WINSOCK
|
#ifdef HAVE_WINSOCK
|
||||||
errno = WSAGetLastError();
|
errno = WSAGetLastError();
|
||||||
#else
|
#else
|
||||||
errno = EHOSTUNREACH; /* not exactly right, but... */
|
errno = EHOSTUNREACH; /* not exactly right, but... */
|
||||||
#endif
|
#endif
|
||||||
return( -1 );
|
DO_RETURN( -1 );
|
||||||
}
|
}
|
||||||
use_hp = 1;
|
use_hp = 1;
|
||||||
}
|
}
|
||||||
|
|
@ -74,7 +82,7 @@ ldap_connect_to_host( Sockbuf *sb, char *host, unsigned long address,
|
||||||
rc = -1;
|
rc = -1;
|
||||||
for ( i = 0; !use_hp || ( hp->h_addr_list[ i ] != 0 ); i++ ) {
|
for ( i = 0; !use_hp || ( hp->h_addr_list[ i ] != 0 ); i++ ) {
|
||||||
if (( s = socket( AF_INET, SOCK_STREAM, 0 )) < 0 ) {
|
if (( s = socket( AF_INET, SOCK_STREAM, 0 )) < 0 ) {
|
||||||
return( -1 );
|
DO_RETURN( -1 );
|
||||||
}
|
}
|
||||||
#ifdef notyet
|
#ifdef notyet
|
||||||
#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_REFERRALS
|
#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_REFERRALS
|
||||||
|
|
@ -145,9 +153,13 @@ ldap_connect_to_host( Sockbuf *sb, char *host, unsigned long address,
|
||||||
s, (char *) inet_ntoa( sin.sin_addr ), 0 );
|
s, (char *) inet_ntoa( sin.sin_addr ), 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
return( rc );
|
DO_RETURN( rc );
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#undef DO_RETURN
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ldap_close_connection( Sockbuf *sb )
|
ldap_close_connection( Sockbuf *sb )
|
||||||
|
|
@ -165,6 +177,12 @@ ldap_host_connected_to( Sockbuf *sb )
|
||||||
int len;
|
int len;
|
||||||
struct sockaddr_in sin;
|
struct sockaddr_in sin;
|
||||||
|
|
||||||
|
/* buffers for gethostbyaddr_r */
|
||||||
|
struct hostent he_buf;
|
||||||
|
int local_h_errno;
|
||||||
|
char *ha_buf=NULL;
|
||||||
|
#define DO_RETURN(x) if (ha_buf) free(ha_buf); return (x);
|
||||||
|
|
||||||
(void)memset( (char *)&sin, 0, sizeof( struct sockaddr_in ));
|
(void)memset( (char *)&sin, 0, sizeof( struct sockaddr_in ));
|
||||||
len = sizeof( sin );
|
len = sizeof( sin );
|
||||||
if ( getpeername( sb->sb_sd, (struct sockaddr *)&sin, &len ) == -1 ) {
|
if ( getpeername( sb->sb_sd, (struct sockaddr *)&sin, &len ) == -1 ) {
|
||||||
|
|
@ -176,15 +194,20 @@ ldap_host_connected_to( Sockbuf *sb )
|
||||||
* this is necessary for kerberos to work right, since the official
|
* this is necessary for kerberos to work right, since the official
|
||||||
* hostname is used as the kerberos instance.
|
* hostname is used as the kerberos instance.
|
||||||
*/
|
*/
|
||||||
if (( hp = gethostbyaddr( (char *) &sin.sin_addr,
|
if ((ldap_int_gethostbyaddr_a( (char *) &sin.sin_addr,
|
||||||
sizeof( sin.sin_addr ), AF_INET )) != NULL ) {
|
sizeof( sin.sin_addr ),
|
||||||
|
AF_INET, &he_buf, &ha_buf,
|
||||||
|
&hp,&local_h_errno ) ==0 ) && (hp != NULL) )
|
||||||
|
{
|
||||||
if ( hp->h_name != NULL ) {
|
if ( hp->h_name != NULL ) {
|
||||||
return( ldap_strdup( hp->h_name ));
|
DO_RETURN( ldap_strdup( hp->h_name ));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return( NULL );
|
DO_RETURN( NULL );
|
||||||
}
|
}
|
||||||
|
#undef DO_RETURN
|
||||||
|
|
||||||
#endif /* HAVE_KERBEROS */
|
#endif /* HAVE_KERBEROS */
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -442,6 +442,7 @@ void
|
||||||
ldap_dump_connection( LDAP *ld, LDAPConn *lconns, int all )
|
ldap_dump_connection( LDAP *ld, LDAPConn *lconns, int all )
|
||||||
{
|
{
|
||||||
LDAPConn *lc;
|
LDAPConn *lc;
|
||||||
|
char timebuf[32];
|
||||||
|
|
||||||
fprintf( stderr, "** Connection%s:\n", all ? "s" : "" );
|
fprintf( stderr, "** Connection%s:\n", all ? "s" : "" );
|
||||||
for ( lc = lconns; lc != NULL; lc = lc->lconn_next ) {
|
for ( lc = lconns; lc != NULL; lc = lc->lconn_next ) {
|
||||||
|
|
@ -457,7 +458,7 @@ ldap_dump_connection( LDAP *ld, LDAPConn *lconns, int all )
|
||||||
"NeedSocket" : ( lc->lconn_status ==
|
"NeedSocket" : ( lc->lconn_status ==
|
||||||
LDAP_CONNST_CONNECTING ) ? "Connecting" : "Connected" );
|
LDAP_CONNST_CONNECTING ) ? "Connecting" : "Connected" );
|
||||||
fprintf( stderr, " last used: %s\n",
|
fprintf( stderr, " last used: %s\n",
|
||||||
ctime( &lc->lconn_lastused ));
|
ldap_int_ctime( &lc->lconn_lastused, timebuf ));
|
||||||
if ( !all ) {
|
if ( !all ) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,9 +27,9 @@
|
||||||
struct entrything {
|
struct entrything {
|
||||||
char **et_vals;
|
char **et_vals;
|
||||||
LDAPMessage *et_msg;
|
LDAPMessage *et_msg;
|
||||||
|
int (*et_cmp_fn) LDAP_P((const char *a, const char *b));
|
||||||
};
|
};
|
||||||
|
|
||||||
static int (*et_cmp_fn) LDAP_P(( const char *a, const char *b ));
|
|
||||||
static int et_cmp LDAP_P(( const void *aa, const void *bb));
|
static int et_cmp LDAP_P(( const void *aa, const void *bb));
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -60,8 +60,7 @@ et_cmp(
|
||||||
return( 1 );
|
return( 1 );
|
||||||
|
|
||||||
for ( i = 0; a->et_vals[i] && b->et_vals[i]; i++ ) {
|
for ( i = 0; a->et_vals[i] && b->et_vals[i]; i++ ) {
|
||||||
if ( (rc = (*et_cmp_fn)( a->et_vals[i], b->et_vals[i] ))
|
if ( (rc = a->et_cmp_fn( a->et_vals[i], b->et_vals[i] )) != 0 ) {
|
||||||
!= 0 ) {
|
|
||||||
return( rc );
|
return( rc );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -96,6 +95,7 @@ ldap_sort_entries(
|
||||||
|
|
||||||
e = *chain;
|
e = *chain;
|
||||||
for ( i = 0; i < count; i++ ) {
|
for ( i = 0; i < count; i++ ) {
|
||||||
|
et[i].et_cmp_fn = cmp;
|
||||||
et[i].et_msg = e;
|
et[i].et_msg = e;
|
||||||
if ( attr == NULL ) {
|
if ( attr == NULL ) {
|
||||||
char *dn;
|
char *dn;
|
||||||
|
|
@ -111,7 +111,6 @@ ldap_sort_entries(
|
||||||
}
|
}
|
||||||
last = e;
|
last = e;
|
||||||
|
|
||||||
et_cmp_fn = cmp;
|
|
||||||
qsort( et, count, sizeof(struct entrything), et_cmp );
|
qsort( et, count, sizeof(struct entrything), et_cmp );
|
||||||
|
|
||||||
ep = chain;
|
ep = chain;
|
||||||
|
|
|
||||||
|
|
@ -874,6 +874,7 @@ time2text( char *ldtimestr, int dateonly )
|
||||||
struct tm t;
|
struct tm t;
|
||||||
char *p, *timestr, zone, *fmterr = "badly formatted time";
|
char *p, *timestr, zone, *fmterr = "badly formatted time";
|
||||||
time_t gmttime;
|
time_t gmttime;
|
||||||
|
char timebuf[32];
|
||||||
|
|
||||||
memset( (char *)&t, 0, sizeof( struct tm ));
|
memset( (char *)&t, 0, sizeof( struct tm ));
|
||||||
if ( (int) strlen( ldtimestr ) < 13 ) {
|
if ( (int) strlen( ldtimestr ) < 13 ) {
|
||||||
|
|
@ -899,7 +900,8 @@ time2text( char *ldtimestr, int dateonly )
|
||||||
}
|
}
|
||||||
|
|
||||||
gmttime = gtime( &t );
|
gmttime = gtime( &t );
|
||||||
timestr = ctime( &gmttime );
|
|
||||||
|
timestr = ldap_int_ctime( &gmttime, timebuf );
|
||||||
|
|
||||||
timestr[ strlen( timestr ) - 1 ] = zone; /* replace trailing newline */
|
timestr[ strlen( timestr ) - 1 ] = zone; /* replace trailing newline */
|
||||||
if ( dateonly ) {
|
if ( dateonly ) {
|
||||||
|
|
|
||||||
141
libraries/libldap/util-int.c
Normal file
141
libraries/libldap/util-int.c
Normal file
|
|
@ -0,0 +1,141 @@
|
||||||
|
/*
|
||||||
|
* util-int.c Various functions to replace missing threadsafe ones.
|
||||||
|
* Without the real *_r funcs, things will work, but won't be
|
||||||
|
* threadsafe.
|
||||||
|
*
|
||||||
|
* Written by Bart Hartgers.
|
||||||
|
*
|
||||||
|
* Copyright 1998, A. Hartgers, All rights reserved.
|
||||||
|
* This software is not subject to any license of Eindhoven University of
|
||||||
|
* Technology, since it was written in my spare time.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms are permitted only
|
||||||
|
* as authorized by the OpenLDAP Public License. A copy of this
|
||||||
|
* license is available at http://www.OpenLDAP.org/license.html or
|
||||||
|
* in file LICENSE in the top-level directory of the distribution.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "portable.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include <ac/errno.h>
|
||||||
|
#include <ac/socket.h>
|
||||||
|
#include <ac/string.h>
|
||||||
|
#include <ac/time.h>
|
||||||
|
|
||||||
|
#include "ldap-int.h"
|
||||||
|
|
||||||
|
char *ldap_int_strtok( char *str, const char *delim, char **pos )
|
||||||
|
{
|
||||||
|
#ifdef HAVE_STRTOK_R
|
||||||
|
return strtok_r(str, delim, pos);
|
||||||
|
#else
|
||||||
|
return strtok(str, delim);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
char *ldap_int_ctime( const time_t *tp, char *buf )
|
||||||
|
{
|
||||||
|
#ifdef HAVE_CTIME_R
|
||||||
|
return ctime_r(tp,buf);
|
||||||
|
#else
|
||||||
|
return ctime(tp);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#define BUFSTART 1024
|
||||||
|
#define BUFMAX (32*1024)
|
||||||
|
|
||||||
|
static char *safe_realloc( char **buf, int len )
|
||||||
|
{
|
||||||
|
char *tmpbuf;
|
||||||
|
tmpbuf = realloc( *buf, len );
|
||||||
|
if (tmpbuf) {
|
||||||
|
*buf=tmpbuf;
|
||||||
|
}
|
||||||
|
return tmpbuf;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ldap_int_gethostbyname_a(
|
||||||
|
const char *name,
|
||||||
|
struct hostent *resbuf,
|
||||||
|
char **buf,
|
||||||
|
struct hostent **result,
|
||||||
|
int *herrno_ptr )
|
||||||
|
{
|
||||||
|
#ifdef HAVE_GETHOSTBYNAME_R
|
||||||
|
int r;
|
||||||
|
int buflen=BUFSTART;
|
||||||
|
|
||||||
|
if (safe_realloc( buf, buflen)) {
|
||||||
|
for(;buflen<BUFMAX;) {
|
||||||
|
r = gethostbyname_r( name, resbuf, *buf,
|
||||||
|
buflen, result, herrno_ptr );
|
||||||
|
#ifdef NETDB_INTERNAL
|
||||||
|
if ((r<0) &&
|
||||||
|
(*herrno_ptr==NETDB_INTERNAL) &&
|
||||||
|
(errno==ERANGE))
|
||||||
|
{
|
||||||
|
if (safe_realloc( buf, buflen*=2 )) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* gethostbyname() */
|
||||||
|
*result = gethostbyname( name );
|
||||||
|
|
||||||
|
if (*result!=NULL) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
*herrno_ptr = h_errno;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ldap_int_gethostbyaddr_a(
|
||||||
|
const char *addr,
|
||||||
|
int len,
|
||||||
|
int type,
|
||||||
|
struct hostent *resbuf,
|
||||||
|
char **buf,
|
||||||
|
struct hostent **result,
|
||||||
|
int *herrno_ptr )
|
||||||
|
{
|
||||||
|
#ifdef HAVE_GETHOSTBYADDR_R
|
||||||
|
int r;
|
||||||
|
int buflen=BUFSTART;
|
||||||
|
if (safe_realloc( buf, buflen)) {
|
||||||
|
for(;buflen<BUFMAX;) {
|
||||||
|
r = gethostbyaddr_r( addr, len, type,
|
||||||
|
resbuf, *buf, buflen,
|
||||||
|
result, herrno_ptr );
|
||||||
|
#ifdef NETDB_INTERNAL
|
||||||
|
if ((r<0) &&
|
||||||
|
(*herrno_ptr==NETDB_INTERNAL) &&
|
||||||
|
(errno==ERANGE))
|
||||||
|
{
|
||||||
|
if (safe_realloc( buf, buflen*=2))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* gethostbyaddr() */
|
||||||
|
*result = gethostbyaddr( addr, len, type );
|
||||||
|
|
||||||
|
if (*result!=NULL) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue