+/* $OpenLDAP$ */
/*
* Copyright (c) 1990-1996 Regents of the University of Michigan.
* All rights reserved.
* University of Minnesota Microcomputer Workstation and Networks Center
*/
+#include "portable.h"
+
#include <stdio.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/time.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <sys/wait.h>
-#include <signal.h>
-#ifdef _AIX
-#include <sys/select.h>
-#endif
-#include <syslog.h>
+
+#include <ac/signal.h>
+#include <ac/socket.h>
+#include <ac/string.h>
+#include <ac/syslog.h>
+#include <ac/time.h>
+#include <ac/unistd.h>
+#include <ac/wait.h>
+
+#ifdef LDAP_PROCTITLE
+#include <ac/setproctitle.h>
+#endif
+
#include <quipu/commonarg.h>
#include <quipu/ds_error.h>
-#include "portable.h"
+
#include "lber.h"
+#include "../../libraries/liblber/lber-int.h" /* get struct sockbuf */
#include "ldap.h"
#include "common.h"
+#include "lutil.h" /* Get lutil_detach() */
-#ifdef USE_SYSCONF
-#include <unistd.h>
-#endif /* USE_SYSCONF */
-
-#ifdef TCP_WRAPPERS
+#ifdef HAVE_TCPD
#include <tcpd.h>
int allow_severity = LOG_INFO;
int deny_severity = LOG_NOTICE;
#endif /* TCP_WRAPPERS */
-void log_and_exit();
-static set_socket();
-static do_queries();
-static SIG_FN wait4child();
-#ifdef CLDAP
-static udp_init();
+static int set_socket( int port, int udp );
+static void do_queries( int clientsock, int udp );
+static RETSIGTYPE wait4child( int sig );
+#ifdef LDAP_CONNECTIONLESS
+static int udp_init( int port, int createsocket );
#endif
#ifdef LDAP_DEBUG
int ldap_debug;
#endif
int version;
-#ifdef COMPAT
+#ifdef LDAP_COMPAT
int ldap_compat;
#endif
int dosyslog;
int do_tcp = 1;
-#ifdef CLDAP
+#ifdef LDAP_CONNECTIONLESS
int do_udp = 0;
#endif
int idletime = DEFAULT_TIMEOUT;
int referral_connection_timeout = DEFAULT_REFERRAL_TIMEOUT;
struct timeval conn_start_tv;
-#ifdef KERBEROS
+#ifdef HAVE_KERBEROS
char *krb_ldap_service = "ldapserver";
char *krb_x500_service = "x500dsa";
char *krb_x500_instance;
int dtblsize;
int RunFromInetd = 0;
-extern char Versionstr[];
-
-static usage( name )
-char *name;
+static void
+usage( char *name )
{
fprintf( stderr, "usage: %s [-d debuglvl] [-p port] [-l] [-c dsa] [-r referraltimeout]", name );
-#ifdef CLDAP
+#ifdef LDAP_CONNECTIONLESS
fprintf( stderr, " [ -U | -t timeout ]" );
#else
fprintf( stderr, " [ -t timeout ]" );
#endif
fprintf( stderr, " [-I]" );
-#ifdef KERBEROS
+#ifdef HAVE_KERBEROS
fprintf( stderr, " [-i dsainstance]" );
#endif
fprintf( stderr, "\n" );
}
-main (argc, argv)
-int argc;
-char **argv;
+int
+main( int argc, char **argv )
{
int tcps, ns;
-#ifdef CLDAP
+#ifdef LDAP_CONNECTIONLESS
int udps;
#endif
int myport = LDAP_PORT;
+ int no_detach = 0;
int i, pid, socktype;
char *myname;
fd_set readfds;
struct hostent *hp;
struct sockaddr_in from;
- int len;
+ socklen_t len;
int dsapargc;
char **dsapargv;
- SIG_FN wait4child();
-#ifndef NOSETPROCTITLE
+#ifdef LDAP_PROCTITLE
char title[80];
- extern char **Argv;
- extern int Argc;
#endif
- extern char *optarg;
- extern int optind;
#ifdef VMS
/* Pick up socket from inetd-type server on VMS */
dsapargv[2] = 0;
dsapargv[3] = 0;
dsapargc = 1;
-#ifdef KERBEROS
+#ifdef HAVE_KERBEROS
kerberos_keyfile = "";
#endif
dsapargc = 3;
break;
- case 'd': /* turn on debugging */
+ case 'd': /* set debug level and 'do not detach' flag */
+ no_detach = 1;
#ifdef LDAP_DEBUG
ldap_debug = atoi( optarg );
if ( ldap_debug & LDAP_DEBUG_PACKETS )
- lber_debug = ldap_debug;
+ ber_set_option( NULL, LBER_OPT_DEBUG_LEVEL, &ldap_debug );
#else
- fprintf( stderr, "Not compiled with -DLDAP_DEBUG!\n" );
+ if ( atoi( optarg ) != 0 )
+ fputs( "Not compiled with -DLDAP_DEBUG!\n", stderr );
#endif
break;
idletime = atoi( optarg );
break;
-#ifdef KERBEROS
+#ifdef HAVE_KERBEROS
case 'f': /* kerberos key file */
kerberos_keyfile = strdup( optarg );
break;
RunFromInetd = 1;
break;
-#ifdef CLDAP
+#ifdef LDAP_CONNECTIONLESS
case 'U': /* UDP only (no TCP) */
do_tcp = 0;
do_udp = 1;
break;
#endif /* NOTYET */
-#endif /* CLDAP */
+#endif /* LDAP_CONNECTIONLESS */
default:
usage( argv[0] );
exit( 1 );
}
-#ifdef CLDAP
+#ifdef LDAP_CONNECTIONLESS
if ( do_udp && !do_tcp && idletime != DEFAULT_TIMEOUT ) {
usage( argv[ 0 ] );
exit( 1 );
Debug( LDAP_DEBUG_TRACE, "%s", Versionstr, 0, 0 );
-#ifdef USE_SYSCONF
+#ifdef HAVE_SYSCONF
dtblsize = sysconf( _SC_OPEN_MAX );
-#else /* USE_SYSCONF */
+#elif HAVE_GETDTABLESIZE
dtblsize = getdtablesize();
-#endif /* USE_SYSCONF */
+#else
+ dtblsize = FD_SETSIZE;
+#endif
-#ifndef NOSETPROCTITLE
+#ifdef FD_SETSIZE
+ if( dtblsize > FD_SETSIZE ) {
+ dtblsize = FD_SETSIZE;
+ }
+#endif /* FD_SETSIZE */
+
+#if defined(LDAP_PROCTITLE) && !defined( HAVE_SETPROCTITLE )
/* for setproctitle */
Argv = argv;
Argc = argc;
* that have exited
*/
if (!RunFromInetd) {
-#ifndef NOSETPROCTITLE
+#ifdef LDAP_PROCTITLE
setproctitle( "initializing" );
#endif
#ifndef VMS
- (void) detach();
+ lutil_detach( no_detach, 1 );
#endif
- (void) SIGNAL( SIGCHLD, (void *) wait4child );
- (void) SIGNAL( SIGINT, (void *) log_and_exit );
+ (void) SIGNAL( SIGCHLD, wait4child );
+ (void) SIGNAL( SIGINT, log_and_exit );
}
/*
(void) get_syntaxes();
if (RunFromInetd) {
len = sizeof( socktype );
- getsockopt( ns, SOL_SOCKET, SO_TYPE, &socktype, &len );
+ getsockopt( ns, SOL_SOCKET, SO_TYPE, (char *)&socktype, &len );
if ( socktype == SOCK_DGRAM ) {
-#ifdef CLDAP
+#ifdef LDAP_CONNECTIONLESS
Debug( LDAP_DEBUG_ARGS,
"CLDAP request from unknown (%s)\n",
inet_ntoa( from.sin_addr ), 0, 0 );
conn_start_tv.tv_sec = 0;
udp_init( 0, 0 );
do_queries( ns, 1 );
-#else /* CLDAP */
+#else /* LDAP_CONNECTIONLESS */
Debug( LDAP_DEBUG_ARGS,
- "Compile with -DCLDAP for UDP support\n",0,0,0 );
-#endif /* CLDAP */
+ "Compile with -DLDAP_CONNECTIONLESS for UDP support\n",0,0,0 );
+#endif /* LDAP_CONNECTIONLESS */
exit( 0 );
}
inet_ntoa( from.sin_addr ) );
}
-#ifndef NOSETPROCTITLE
+#ifdef LDAP_PROCTITLE
sprintf( title, "%s %d\n", hp == NULL ?
inet_ntoa( from.sin_addr ) : hp->h_name, myport );
setproctitle( title );
if ( do_tcp )
tcps = set_socket( myport, 0 );
-#ifdef CLDAP
+#ifdef LDAP_CONNECTIONLESS
if ( do_udp )
udps = udp_init( myport, 1 );
#endif
* if we are doing CLDAP as well, handle those requests on the fly
*/
-#ifndef NOSETPROCTITLE
-#ifdef CLDAP
+#ifdef LDAP_PROCTITLE
+#ifdef LDAP_CONNECTIONLESS
sprintf( title, "listening %s/%s %d", do_tcp ? "tcp" : "",
do_udp ? "udp" : "", myport );
#else
FD_ZERO( &readfds );
if ( do_tcp )
FD_SET( tcps, &readfds );
-#ifdef CLDAP
+#ifdef LDAP_CONNECTIONLESS
if ( do_udp )
FD_SET( udps, &readfds );
#endif
continue;
}
-#ifdef CLDAP
+#ifdef LDAP_CONNECTIONLESS
if ( do_udp && FD_ISSET( udps, &readfds ) ) {
do_queries( udps, 1 );
}
hp = gethostbyaddr( (char *) &(from.sin_addr.s_addr),
sizeof(from.sin_addr.s_addr), AF_INET );
-#ifdef TCP_WRAPPERS
+#ifdef HAVE_TCPD
if ( !hosts_ctl("ldapd", (hp == NULL) ? "unknown" : hp->h_name,
- inet_ntoa( from.sin_addr ), STRING_UNKNOWN ) {
+ inet_ntoa( from.sin_addr ), STRING_UNKNOWN) ) {
Debug( LDAP_DEBUG_ARGS, "connection from %s (%s) denied.\n",
(hp == NULL) ? "unknown" : hp->h_name,
inet_ntoa( from.sin_addr ) );
}
- close(ns);
+ tcp_close(ns);
continue;
}
#endif /* TCP_WRAPPERS */
#ifdef VMS
/* This is for debug on terminal on VMS */
- close( tcps );
-#ifndef NOSETPROCTITLE
+ tcp_close( tcps );
+#ifdef LDAP_PROCTITLE
setproctitle( hp == NULL ? inet_ntoa( from.sin_addr ) :
hp->h_name );
#endif
gettimeofday( &conn_start_tv, (struct timezone *) NULL );
- (void) SIGNAL( SIGPIPE, (void *) log_and_exit );
+ (void) SIGNAL( SIGPIPE, log_and_exit );
do_queries( ns, 0 );
/* NOT REACHED */
switch( pid = fork() ) {
case 0: /* child */
- close( tcps );
-#ifndef NOSETPROCTITLE
+ tcp_close( tcps );
+#ifdef LDAP_PROCTITLE
sprintf( title, "%s (%d)\n", hp == NULL ?
inet_ntoa( from.sin_addr ) : hp->h_name,
myport );
setproctitle( title );
#endif
gettimeofday( &conn_start_tv, (struct timezone *) NULL );
- (void) SIGNAL( SIGPIPE, (void *) log_and_exit );
+ (void) SIGNAL( SIGPIPE, log_and_exit );
do_queries( ns, 0 );
break;
#ifdef LDAP_DEBUG
if ( ldap_debug ) perror( "fork" );
#endif
- close( ns );
+ tcp_close( ns );
syslog( LOG_ERR, "fork failed %m" );
/* let things cool off */
sleep( 15 );
break;
default: /* parent */
- close( ns );
+ tcp_close( ns );
Debug( LDAP_DEBUG_TRACE, "forked child %d\n", pid, 0,
0 );
break;
/* NOT REACHED */
}
-static
+static void
do_queries(
int clientsock,
int udp /* is this a UDP (CLDAP) request? */
)
{
fd_set readfds;
- int rc, i;
+ int rc;
struct timeval timeout;
Sockbuf sb;
-#ifdef CLDAP
+#ifdef LDAP_CONNECTIONLESS
struct sockaddr saddr, faddr;
struct sockaddr *saddrlist[ 1 ];
-#endif /* CLDAP */
+#endif /* LDAP_CONNECTIONLESS */
Debug( LDAP_DEBUG_TRACE, "do_queries%s\n",
udp ? " udp" : "", 0, 0 );
conn_init();
}
- (void) memset( (void *) &sb, '\0', sizeof( sb ) );
- sb.sb_sd = clientsock;
- sb.sb_naddr = ( udp ) ? 1 : 0;
-#ifdef CLDAP
- sb.sb_addrs = (void **)saddrlist;
- sb.sb_fromaddr = &faddr;
- sb.sb_useaddr = saddrlist[ 0 ] = &saddr;
-#endif
- sb.sb_ber.ber_buf = NULL;
- sb.sb_ber.ber_ptr = NULL;
- sb.sb_ber.ber_end = NULL;
-
+ ber_pvt_sb_init( &sb );
+ ber_pvt_sb_set_desc( &sb, clientsock );
+ ber_pvt_sb_set_io( &sb, (udp) ? &ber_pvt_sb_io_udp :
+ &ber_pvt_sb_io_tcp, NULL );
timeout.tv_sec = idletime;
timeout.tv_usec = 0;
for ( ;; ) {
struct conn *dsaconn;
- extern struct conn *conns;
FD_ZERO( &readfds );
FD_SET( clientsock, &readfds );
#ifdef LDAP_DEBUG
if ( ldap_debug & LDAP_DEBUG_CONNS ) {
+ int i;
Debug( LDAP_DEBUG_CONNS, "FDLIST:", 0, 0, 0 );
for ( i = 0; i < dtblsize; i++ ) {
if ( FD_ISSET( i, &readfds ) ) {
* already waiting for us on the client sock.
*/
- if ( sb.sb_ber.ber_ptr >= sb.sb_ber.ber_end ) {
+ if ( ! ber_pvt_sb_data_ready( &sb ) ) {
if ( (rc = select( dtblsize, &readfds, 0, 0,
udp ? 0 : &timeout )) < 1 ) {
#ifdef LDAP_DEBUG
}
}
- if ( sb.sb_ber.ber_ptr < sb.sb_ber.ber_end ||
+ if ( ber_pvt_sb_data_ready( &sb ) ||
FD_ISSET( clientsock, &readfds ) ) {
client_request( &sb, conns, udp );
} else {
/* NOT REACHED */
}
-static set_socket(
+static int
+set_socket(
int port,
int udp /* UDP port? */
)
exit( 1 );
}
+#ifdef SO_REUSEADDR
/* set option so clients can't keep us from coming back up */
- i = 1;
+ i = 1;
if ( setsockopt( s, SOL_SOCKET, SO_REUSEADDR, (void *) &i, sizeof(i) )
- < 0 ) {
+ < 0 )
+ {
+ perror( "setsockopt" );
+ exit( 1 );
+ }
+#endif
+#ifdef SO_KEEPALIVE
+ /* enable keep alives */
+ i = 1;
+ if ( setsockopt( s, SOL_SOCKET, SO_KEEPALIVE, (void *) &i, sizeof(i) )
+ < 0 )
+ {
perror( "setsockopt" );
exit( 1 );
}
+#endif
/* bind to a name */
(void)memset( (void *)&addr, '\0', sizeof( addr ));
addr.sin_family = AF_INET;
- addr.sin_addr.s_addr = INADDR_ANY;
+ addr.sin_addr.s_addr = htonl(INADDR_ANY);
addr.sin_port = htons( port );
if ( bind( s, (struct sockaddr *) &addr, sizeof(addr) ) ) {
perror( "bind" );
return( s );
}
-static SIG_FN wait4child()
+static RETSIGTYPE
+wait4child( int sig )
{
- WAITSTATUSTYPE status;
+#ifndef HAVE_WAITPID
+ WAITSTATUSTYPE status;
+#endif
Debug( LDAP_DEBUG_TRACE, "parent: catching child status\n", 0, 0, 0 );
-#ifdef USE_WAITPID
- while( waitpid( (pid_t) -1, 0, WAIT_FLAGS ) > 0 )
+#ifdef HAVE_WAITPID
+ while( waitpid( (pid_t) -1, (int *) NULL, WAIT_FLAGS ) > 0 )
; /* NULL */
#else
- while ( wait3( &status, WAIT_FLAGS, 0 ) > 0 )
- ; /* NULL */
+ while ( wait4( (pid_t) -1, &status, WAIT_FLAGS, 0 ) > 0 )
+ ; /* NULL */
#endif
- (void) SIGNAL( SIGCHLD, (void *) wait4child );
+ (void) SIGNAL( SIGCHLD, wait4child );
}
-void
+RETSIGTYPE
log_and_exit( int exitcode )
{
struct timeval tv;
}
-#ifdef CLDAP
+#ifdef LDAP_CONNECTIONLESS
static int
udp_init(
int port,
{
int s, bound;
char *matched;
- extern char *dsa_address;
- extern struct PSAPaddr *psap_cpy();
- extern struct conn *conns;
if ( createsocket )
s = set_socket( port, 1 );