+/* $OpenLDAP$ */
/*
* Copyright (c) 1990-1996 Regents of the University of Michigan.
* All rights reserved.
#include "../../libraries/liblber/lber-int.h" /* get struct sockbuf */
#include "ldap.h"
#include "common.h"
+#include "lutil.h" /* Get lutil_detach() */
#ifdef HAVE_TCPD
#include <tcpd.h>
int deny_severity = LOG_NOTICE;
#endif /* TCP_WRAPPERS */
-void log_and_exit();
-static set_socket();
-static do_queries();
-static RETSIGTYPE wait4child();
+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 udp_init();
+static int udp_init( int port, int createsocket );
#endif
#ifdef LDAP_DEBUG
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 LDAP_CONNECTIONLESS
fprintf( stderr, "\n" );
}
-main (argc, argv)
-int argc;
-char **argv;
+int
+main( int argc, char **argv )
{
int tcps, ns;
#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;
- RETSIGTYPE wait4child();
#ifdef LDAP_PROCTITLE
char title[80];
#endif
- extern char *optarg;
- extern int optind;
#ifdef VMS
/* Pick up socket from inetd-type server on VMS */
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;
* that have exited
*/
if (!RunFromInetd) {
-#ifdef LDAP_SETPROCTITLE
+#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 LDAP_CONNECTIONLESS
Debug( LDAP_DEBUG_ARGS,
inet_ntoa( from.sin_addr ) );
}
-#ifdef LDAP_SETPROCTITLE
+#ifdef LDAP_PROCTITLE
sprintf( title, "%s %d\n", hp == NULL ?
inet_ntoa( from.sin_addr ) : hp->h_name, myport );
setproctitle( title );
* if we are doing CLDAP as well, handle those requests on the fly
*/
-#ifdef LDAP_SETPROCTITLE
+#ifdef LDAP_PROCTITLE
#ifdef LDAP_CONNECTIONLESS
sprintf( title, "listening %s/%s %d", do_tcp ? "tcp" : "",
do_udp ? "udp" : "", myport );
#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 );
-#ifdef LDAP_SETPROCTITLE
+ 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 );
-#ifdef LDAP_SETPROCTITLE
+ 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 LDAP_CONNECTIONLESS
conn_init();
}
- (void) memset( (void *) &sb, '\0', sizeof( sb ) );
- sb.sb_sd = clientsock;
- sb.sb_naddr = ( udp ) ? 1 : 0;
-#ifdef LDAP_CONNECTIONLESS
- 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 RETSIGTYPE wait4child()
+static RETSIGTYPE
+wait4child( int sig )
{
#ifndef HAVE_WAITPID
WAITSTATUSTYPE status;
Debug( LDAP_DEBUG_TRACE, "parent: catching child status\n", 0, 0, 0 );
#ifdef HAVE_WAITPID
- while( waitpid( (pid_t) -1, NULL, WAIT_FLAGS ) > 0 )
+ while( waitpid( (pid_t) -1, (int *) NULL, WAIT_FLAGS ) > 0 )
; /* NULL */
#else
- while ( wait3( &status, WAIT_FLAGS, 0 ) > 0 )
+ 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;
{
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 );