]> git.sur5r.net Git - openldap/blobdiff - servers/ldapd/main.c
Round 2 of connection management changes.
[openldap] / servers / ldapd / main.c
index 9edd4b532ea503d9886f9f7e84ed3577fb0111e4..5e91ec6ea31fea8159093d4234c6986ada064e71 100644 (file)
  * 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;
@@ -83,30 +82,27 @@ char        *kerberos_keyfile;
 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;
@@ -118,14 +114,9 @@ char       **argv;
        int                     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 */
@@ -146,7 +137,7 @@ char        **argv;
         dsapargv[2] = 0;
         dsapargv[3] = 0;
         dsapargc = 1;
-#ifdef KERBEROS
+#ifdef HAVE_KERBEROS
        kerberos_keyfile = "";
 #endif
 
@@ -163,7 +154,7 @@ char        **argv;
 #ifdef LDAP_DEBUG
                        ldap_debug = atoi( optarg );
                        if ( ldap_debug & LDAP_DEBUG_PACKETS )
-                               lber_debug = ldap_debug;
+                               lber_int_debug = ldap_debug;
 #else
                        fprintf( stderr, "Not compiled with -DLDAP_DEBUG!\n" );
 #endif
@@ -185,7 +176,7 @@ char        **argv;
                        idletime = atoi( optarg );
                        break;
 
-#ifdef KERBEROS
+#ifdef HAVE_KERBEROS
                case 'f':       /* kerberos key file */
                        kerberos_keyfile = strdup( optarg );
                        break;
@@ -201,7 +192,7 @@ char        **argv;
                        RunFromInetd = 1;
                        break;
 
-#ifdef CLDAP
+#ifdef LDAP_CONNECTIONLESS
                case 'U':       /* UDP only (no TCP) */
                        do_tcp = 0;
                        do_udp = 1;
@@ -213,7 +204,7 @@ char        **argv;
                        break;
 #endif /* NOTYET */
 
-#endif /* CLDAP */
+#endif /* LDAP_CONNECTIONLESS */
 
                default:
                        usage( argv[0] );
@@ -226,7 +217,7 @@ char        **argv;
                exit( 1 );
        }
 
-#ifdef CLDAP
+#ifdef LDAP_CONNECTIONLESS
        if ( do_udp && !do_tcp && idletime != DEFAULT_TIMEOUT ) {
                usage( argv[ 0 ] );
                exit( 1 );
@@ -235,13 +226,21 @@ char      **argv;
 
        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;
@@ -258,14 +257,18 @@ char      **argv;
         * that have exited
         */
        if (!RunFromInetd) {
-#ifndef NOSETPROCTITLE
+#ifdef LDAP_PROCTITLE
                setproctitle( "initializing" );
 #endif
 #ifndef VMS
-               (void) detach();
-#endif
-               (void) SIGNAL( SIGCHLD, (void *) wait4child );
-               (void) SIGNAL( SIGINT, (void *) log_and_exit );
+#  ifdef LDAP_DEBUG
+               lutil_detach( ldap_debug, 1 );
+#  else
+               lutil_detach( 0, 1 );
+#  endif
+#endif
+               (void) SIGNAL( SIGCHLD, wait4child );
+               (void) SIGNAL( SIGINT, log_and_exit );
        }
 
        /* 
@@ -297,19 +300,19 @@ char      **argv;
        (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 );
                }
 
@@ -328,7 +331,7 @@ char        **argv;
                                    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 );
@@ -343,7 +346,7 @@ char        **argv;
        if ( do_tcp )
            tcps = set_socket( myport, 0 );
 
-#ifdef CLDAP
+#ifdef LDAP_CONNECTIONLESS
        if ( do_udp )
                udps = udp_init( myport, 1 );
 #endif
@@ -353,8 +356,8 @@ char        **argv;
         * 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
@@ -367,7 +370,7 @@ char        **argv;
                FD_ZERO( &readfds );
                if ( do_tcp )
                        FD_SET( tcps, &readfds );
-#ifdef CLDAP
+#ifdef LDAP_CONNECTIONLESS
                if ( do_udp )
                        FD_SET( udps, &readfds );
 #endif
@@ -379,7 +382,7 @@ char        **argv;
                        continue;
                }
 
-#ifdef CLDAP
+#ifdef LDAP_CONNECTIONLESS
                if ( do_udp && FD_ISSET( udps, &readfds ) ) {
                        do_queries( udps, 1 );
                }
@@ -401,7 +404,7 @@ char        **argv;
                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 ) {
 
@@ -434,12 +437,12 @@ char      **argv;
 #ifdef VMS
                /* This is for debug on terminal on VMS */
                close( tcps );
-#ifndef NOSETPROCTITLE
+#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 */
@@ -448,14 +451,14 @@ char      **argv;
                switch( pid = fork() ) {
                case 0:         /* child */
                        close( tcps );
-#ifndef NOSETPROCTITLE
+#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;
@@ -480,20 +483,20 @@ char      **argv;
        /* 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 );
@@ -512,23 +515,14 @@ do_queries(
                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;
-
+       lber_pvt_sb_init( &sb );
+       lber_pvt_sb_set_desc( &sb, clientsock );
+       lber_pvt_sb_set_io( &sb, (udp) ? &lber_pvt_sb_io_udp :
+                                       &lber_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 );
@@ -536,6 +530,7 @@ do_queries(
 
 #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 ) ) {
@@ -552,7 +547,7 @@ do_queries(
                 * already waiting for us on the client sock.
                 */
 
-               if ( sb.sb_ber.ber_ptr >= sb.sb_ber.ber_end ) {
+               if ( ! lber_pvt_sb_data_ready( &sb ) ) {
                        if ( (rc = select( dtblsize, &readfds, 0, 0,
                            udp ? 0 : &timeout )) < 1 ) {
 #ifdef LDAP_DEBUG
@@ -578,7 +573,7 @@ do_queries(
                        }
                }
 
-               if ( sb.sb_ber.ber_ptr < sb.sb_ber.ber_end ||
+               if ( lber_pvt_sb_data_ready( &sb ) ||
                    FD_ISSET( clientsock, &readfds ) ) {
                        client_request( &sb, conns, udp );
                } else {
@@ -594,7 +589,8 @@ do_queries(
        /* NOT REACHED */
 }
 
-static set_socket(
+static int
+set_socket(
     int        port,
     int        udp     /* UDP port? */
 )
@@ -639,25 +635,28 @@ static set_socket(
        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;
@@ -676,7 +675,7 @@ log_and_exit( int exitcode )
 }
 
 
-#ifdef CLDAP
+#ifdef LDAP_CONNECTIONLESS
 static int
 udp_init(
     int        port,
@@ -685,9 +684,6 @@ udp_init(
 {
        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 );