mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-12-24 00:29:35 -05:00
This could cause problems on odd systems. The generic headers should be extended as needed to include necessary system headers or, if necessary, make explicit declarations. Extended ac/string.h header to look for string.h/strings.h if STDC_HEADERS is not defined. Also provide basic declarations for str*() functions. This could cause problems on odd systems. Extended ac/unistd.h header to define basic declaration for misc functions that might be missing from headers. This includes externs for getenv(), getopt(), mktemp(), tempname(). Protect fax500.h from multiple inclusion. Moved includes of system/generic headers back to source files. Made mail500 helper functions static. Fixed includes of ctype.h, signal.h, etc. to use generics. lutil/tempname.c: was including stdlib.h twice, one should stdio.h. Wrapped <sys/resource.h> with HAVE_SYS_RESOURCE_H. lber/io.c/ber_get_next(): Changed noctets back to signed. Used with BerRead which expects signed int as second arg and returns signed int.
285 lines
6.7 KiB
C
285 lines
6.7 KiB
C
#include "portable.h"
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <ac/socket.h>
|
|
#include <ac/string.h>
|
|
#include <ac/time.h>
|
|
#include <ac/unistd.h>
|
|
|
|
#include "ldapconfig.h"
|
|
#include "slap.h"
|
|
#include "lutil.h" /* Get lutil_detach() */
|
|
|
|
|
|
/*
|
|
* read-only global variables or variables only written by the listener
|
|
* thread (after they are initialized) - no need to protect them with a mutex.
|
|
*/
|
|
int ldap_debug = 0;
|
|
#ifdef LDAP_DEBUG
|
|
int ldap_syslog = LDAP_DEBUG_STATS;
|
|
#else
|
|
int ldap_syslog;
|
|
#endif
|
|
int ldap_syslog_level = LOG_DEBUG;
|
|
int udp;
|
|
int slapd_shutdown;
|
|
char *default_referral;
|
|
char *configfile;
|
|
time_t starttime;
|
|
pthread_t listener_tid;
|
|
int g_argc;
|
|
char **g_argv;
|
|
/*
|
|
* global variables that need mutex protection
|
|
*/
|
|
time_t currenttime;
|
|
pthread_mutex_t currenttime_mutex;
|
|
int active_threads;
|
|
pthread_mutex_t active_threads_mutex;
|
|
pthread_mutex_t new_conn_mutex;
|
|
long ops_initiated;
|
|
long ops_completed;
|
|
int num_conns;
|
|
pthread_mutex_t ops_mutex;
|
|
long num_entries_sent;
|
|
long num_bytes_sent;
|
|
pthread_mutex_t num_sent_mutex;
|
|
/*
|
|
* these mutexes must be used when calling the entry2str()
|
|
* routine since it returns a pointer to static data.
|
|
*/
|
|
pthread_mutex_t entry2str_mutex;
|
|
pthread_mutex_t replog_mutex;
|
|
|
|
static void
|
|
usage( char *name )
|
|
{
|
|
fprintf( stderr, "usage: %s [-d ?|debuglevel] [-f configfile] [-p portnumber] [-s sysloglevel]\n", name );
|
|
}
|
|
|
|
int
|
|
main( int argc, char **argv )
|
|
{
|
|
int i;
|
|
int inetd = 0;
|
|
int port;
|
|
char *myname;
|
|
Backend *be = NULL;
|
|
FILE *fp = NULL;
|
|
|
|
configfile = SLAPD_DEFAULT_CONFIGFILE;
|
|
port = LDAP_PORT;
|
|
g_argc = argc;
|
|
g_argv = argv;
|
|
|
|
while ( (i = getopt( argc, argv, "d:f:ip:s:u" )) != EOF ) {
|
|
switch ( i ) {
|
|
#ifdef LDAP_DEBUG
|
|
case 'd': /* turn on debugging */
|
|
if ( optarg[0] == '?' ) {
|
|
printf( "Debug levels:\n" );
|
|
printf( "\tLDAP_DEBUG_TRACE\t%d\n",
|
|
LDAP_DEBUG_TRACE );
|
|
printf( "\tLDAP_DEBUG_PACKETS\t%d\n",
|
|
LDAP_DEBUG_PACKETS );
|
|
printf( "\tLDAP_DEBUG_ARGS\t\t%d\n",
|
|
LDAP_DEBUG_ARGS );
|
|
printf( "\tLDAP_DEBUG_CONNS\t%d\n",
|
|
LDAP_DEBUG_CONNS );
|
|
printf( "\tLDAP_DEBUG_BER\t\t%d\n",
|
|
LDAP_DEBUG_BER );
|
|
printf( "\tLDAP_DEBUG_FILTER\t%d\n",
|
|
LDAP_DEBUG_FILTER );
|
|
printf( "\tLDAP_DEBUG_CONFIG\t%d\n",
|
|
LDAP_DEBUG_CONFIG );
|
|
printf( "\tLDAP_DEBUG_ACL\t\t%d\n",
|
|
LDAP_DEBUG_ACL );
|
|
printf( "\tLDAP_DEBUG_STATS\t%d\n",
|
|
LDAP_DEBUG_STATS );
|
|
printf( "\tLDAP_DEBUG_STATS2\t%d\n",
|
|
LDAP_DEBUG_STATS2 );
|
|
printf( "\tLDAP_DEBUG_SHELL\t%d\n",
|
|
LDAP_DEBUG_SHELL );
|
|
printf( "\tLDAP_DEBUG_PARSE\t%d\n",
|
|
LDAP_DEBUG_PARSE );
|
|
printf( "\tLDAP_DEBUG_ANY\t\t%d\n",
|
|
LDAP_DEBUG_ANY );
|
|
exit( 0 );
|
|
} else {
|
|
ldap_debug |= atoi( optarg );
|
|
lber_debug = (ldap_debug & LDAP_DEBUG_BER);
|
|
}
|
|
break;
|
|
#else
|
|
case 'd': /* turn on debugging */
|
|
fprintf( stderr,
|
|
"must compile with LDAP_DEBUG for debugging\n" );
|
|
break;
|
|
#endif
|
|
|
|
case 'f': /* read config file */
|
|
configfile = strdup( optarg );
|
|
break;
|
|
|
|
case 'i': /* run from inetd */
|
|
inetd = 1;
|
|
break;
|
|
|
|
case 'p': /* port on which to listen */
|
|
port = atoi( optarg );
|
|
break;
|
|
|
|
case 's': /* set syslog level */
|
|
ldap_syslog = atoi( optarg );
|
|
break;
|
|
|
|
case 'u': /* do udp */
|
|
udp = 1;
|
|
break;
|
|
|
|
default:
|
|
usage( argv[0] );
|
|
exit( 1 );
|
|
}
|
|
}
|
|
|
|
Debug( LDAP_DEBUG_TRACE, "%s", Versionstr, 0, 0 );
|
|
|
|
if ( (myname = strrchr( argv[0], '/' )) == NULL ) {
|
|
myname = strdup( argv[0] );
|
|
} else {
|
|
myname = strdup( myname + 1 );
|
|
}
|
|
|
|
if ( ! inetd ) {
|
|
/* pre-open config file before detach in case it is a relative path */
|
|
fp = fopen( configfile, "r" );
|
|
#ifdef LDAP_DEBUG
|
|
lutil_detach( ldap_debug, 0 );
|
|
#else
|
|
lutil_detach( 0, 0 );
|
|
#endif
|
|
}
|
|
#ifdef LOG_LOCAL4
|
|
openlog( myname, OPENLOG_OPTIONS, LOG_LOCAL4 );
|
|
#else
|
|
openlog( myname, OPENLOG_OPTIONS );
|
|
#endif
|
|
|
|
init();
|
|
read_config( configfile, &be, fp );
|
|
|
|
if ( ! inetd ) {
|
|
pthread_attr_t attr;
|
|
int status;
|
|
|
|
time( &starttime );
|
|
pthread_attr_init( &attr );
|
|
pthread_attr_setdetachstate( &attr, PTHREAD_CREATE_DETACHED );
|
|
|
|
#if !defined(HAVE_PTHREADS_D4)
|
|
/* POSIX_THREADS or compatible
|
|
* This is a draft 10 or standard pthreads implementation
|
|
*/
|
|
if ( pthread_create( &listener_tid, &attr, slapd_daemon,
|
|
(void *) port ) != 0 ) {
|
|
Debug( LDAP_DEBUG_ANY,
|
|
"listener pthread_create failed\n", 0, 0, 0 );
|
|
exit( 1 );
|
|
}
|
|
#else /* draft4 */
|
|
/*
|
|
* This is a draft 4 or earlier pthreads implementation
|
|
*/
|
|
if ( pthread_create( &listener_tid, attr, slapd_daemon,
|
|
(void *) port ) != 0 ) {
|
|
Debug( LDAP_DEBUG_ANY,
|
|
"listener pthread_create failed\n", 0, 0, 0 );
|
|
exit( 1 );
|
|
}
|
|
#endif /* !draft4 */
|
|
pthread_attr_destroy( &attr );
|
|
pthread_join( listener_tid, (void *) &status );
|
|
pthread_exit( 0 );
|
|
} else {
|
|
Connection c;
|
|
Operation *o;
|
|
BerElement ber;
|
|
unsigned long len, tag;
|
|
long msgid;
|
|
int flen;
|
|
struct sockaddr_in from;
|
|
struct hostent *hp;
|
|
|
|
c.c_dn = NULL;
|
|
c.c_ops = NULL;
|
|
c.c_sb.sb_sd = 0;
|
|
c.c_sb.sb_options = 0;
|
|
c.c_sb.sb_naddr = udp ? 1 : 0;
|
|
c.c_sb.sb_ber.ber_buf = NULL;
|
|
c.c_sb.sb_ber.ber_ptr = NULL;
|
|
c.c_sb.sb_ber.ber_end = NULL;
|
|
pthread_mutex_init( &c.c_dnmutex, pthread_mutexattr_default );
|
|
pthread_mutex_init( &c.c_opsmutex, pthread_mutexattr_default );
|
|
pthread_mutex_init( &c.c_pdumutex, pthread_mutexattr_default );
|
|
#ifdef notdefcldap
|
|
c.c_sb.sb_addrs = (void **) saddrlist;
|
|
c.c_sb.sb_fromaddr = &faddr;
|
|
c.c_sb.sb_useaddr = saddrlist[ 0 ] = &saddr;
|
|
#endif
|
|
flen = sizeof(from);
|
|
if ( getpeername( 0, (struct sockaddr *) &from, &flen ) == 0 ) {
|
|
#ifdef SLAPD_RLOOKUPS
|
|
hp = gethostbyaddr( (char *) &(from.sin_addr.s_addr),
|
|
sizeof(from.sin_addr.s_addr), AF_INET );
|
|
#else
|
|
hp = NULL;
|
|
#endif
|
|
|
|
Debug( LDAP_DEBUG_ARGS, "connection from %s (%s)\n",
|
|
hp == NULL ? "unknown" : hp->h_name,
|
|
inet_ntoa( from.sin_addr ), 0 );
|
|
|
|
c.c_addr = inet_ntoa( from.sin_addr );
|
|
c.c_domain = strdup( hp == NULL ? "" : hp->h_name );
|
|
} else {
|
|
Debug( LDAP_DEBUG_ARGS, "connection from unknown\n",
|
|
0, 0, 0 );
|
|
}
|
|
|
|
ber_init_w_nullc( &ber, 0 );
|
|
|
|
while ( (tag = ber_get_next( &c.c_sb, &len, &ber ))
|
|
== LDAP_TAG_MESSAGE ) {
|
|
pthread_mutex_lock( ¤ttime_mutex );
|
|
time( ¤ttime );
|
|
pthread_mutex_unlock( ¤ttime_mutex );
|
|
|
|
if ( (tag = ber_get_int( &ber, &msgid ))
|
|
!= LDAP_TAG_MSGID ) {
|
|
/* log and send error */
|
|
Debug( LDAP_DEBUG_ANY,
|
|
"ber_get_int returns 0x%lx\n", tag, 0, 0 );
|
|
return 1;
|
|
}
|
|
|
|
if ( (tag = ber_peek_tag( &ber, &len ))
|
|
== LBER_ERROR ) {
|
|
/* log, close and send error */
|
|
Debug( LDAP_DEBUG_ANY,
|
|
"ber_peek_tag returns 0x%lx\n", tag, 0, 0 );
|
|
ber_free( &ber, 1 );
|
|
close( c.c_sb.sb_sd );
|
|
c.c_sb.sb_sd = -1;
|
|
return 1;
|
|
}
|
|
|
|
connection_activity( &c );
|
|
|
|
ber_free( &ber, 1 );
|
|
}
|
|
}
|
|
return 1;
|
|
}
|