Skip to content
Snippets Groups Projects
Commit b0aea66d authored by Kurt Zeilenga's avatar Kurt Zeilenga
Browse files

Recommit NT service changes (untested) with changes to resolve

compiling errors on other platforms.  Will need to update NT projects.
parent af06bba2
No related branches found
No related tags found
No related merge requests found
#include "portable.h"
//#include "portable_err.h"
#include <stdio.h>
......@@ -22,18 +23,22 @@ int deny_severity = LOG_NOTICE;
/* globals */
int dtblsize;
static int tcps;
#ifdef HAVE_WINSOCK2
// in nt_main.c
extern ldap_pvt_thread_cond_t started_event;
/* forward reference */
void hit_socket();
/* In wsa_err.c */
char *WSAGetLastErrorString();
static ldap_pvt_thread_t hit_tid;
#define WAKE_LISTENER(w) \
do {\
if( w ) {\
ldap_pvt_thread_kill( listener_tid, LDAP_SIGUSR1 );\
hit_socket();\
hit_socket(); \
}\
} while(0)
#else
......@@ -45,9 +50,13 @@ do {\
} while(0)
#endif
#ifndef HAVE_WINSOCK
static
#endif
volatile sig_atomic_t slapd_shutdown = 0;
static int daemon_initialized = 0;
static ldap_pvt_thread_t listener_tid;
static volatile sig_atomic_t slapd_shutdown = 0;
static volatile sig_atomic_t slapd_listener = 0;
void sockinit();
......@@ -119,17 +128,24 @@ void slapd_clr_write(int s, int wake) {
FD_CLR( (unsigned) s, &slap_daemon.sd_writers );
ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
if( wake ) {
ldap_pvt_thread_kill( listener_tid, LDAP_SIGUSR1 );
}
}
void slapd_set_write(int s, int wake) {
ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );
WAKE_LISTENER(wake);
assert( FD_ISSET( s, &slap_daemon.sd_actives) );
FD_SET( (unsigned) s, &slap_daemon.sd_writers );
ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
if( wake ) {
ldap_pvt_thread_kill( listener_tid, LDAP_SIGUSR1 );
}
}
void slapd_clr_read(int s, int wake) {
......@@ -141,6 +157,9 @@ void slapd_clr_read(int s, int wake) {
ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
if( wake ) {
ldap_pvt_thread_kill( listener_tid, LDAP_SIGUSR1 );
}
}
void slapd_set_read(int s, int wake) {
......@@ -151,6 +170,10 @@ void slapd_set_read(int s, int wake) {
FD_SET( (unsigned) s, &slap_daemon.sd_readers );
ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
if( wake ) {
ldap_pvt_thread_kill( listener_tid, LDAP_SIGUSR1 );
}
}
static void slapd_close(int s) {
......@@ -158,6 +181,8 @@ static void slapd_close(int s) {
tcp_close(s);
}
int
set_socket( struct sockaddr_in *addr )
{
......@@ -252,10 +277,14 @@ slapd_daemon_task(
void *ptr
)
{
int inetd = ((int *)ptr) [0];
int tcps = ((int *)ptr) [1];
int inetd;
struct slapd_args *args = (struct slapd_args *) ptr;
struct sockaddr_in *slapd_addr = args->addr;
tcps = args->tcps;
free( ptr );
inetd = ( slapd_addr == NULL);
if ( !daemon_initialized ) sockinit();
slapd_listener=1;
......@@ -289,6 +318,11 @@ slapd_daemon_task(
slapd_add( 0 );
}
#ifdef HAVE_WINSOCK
if ( started_event != NULL )
ldap_pvt_thread_cond_signal( &started_event );
#endif
// initialization complete. Here comes the loop.
while ( !slapd_shutdown ) {
unsigned int i;
int ns, nfds;
......@@ -302,7 +336,7 @@ slapd_daemon_task(
#if defined(SLAPD_RLOOKUPS) || defined(HAVE_TCPD)
struct hostent *hp;
#endif
struct timeval zero;
struct timeval zero;
struct timeval *tvp;
char *client_name;
......@@ -357,7 +391,11 @@ slapd_daemon_task(
switch(ns = select( nfds, &readfds, &writefds, 0, tvp )) {
case -1: { /* failure - try again */
#ifdef HAVE_WINSOCK
int err = WSAGetLastError();
#else
int err = errno;
#endif
if( err == EBADF && ++ebadf < SLAPD_EBADF_LIMIT) {
continue;
......@@ -371,7 +409,8 @@ slapd_daemon_task(
? sys_errlist[err] : "unknown",
0 );
slapd_shutdown = -1;
slapd_shutdown = -1;
}
}
continue;
......@@ -481,7 +520,6 @@ slapd_daemon_task(
}
#endif /* HAVE_TCPD */
if( (id = connection_init(s, client_name, client_addr)) < 0 ) {
Debug( LDAP_DEBUG_ANY,
"daemon: connection_init(%d, %s, %s) failed.\n",
......@@ -548,7 +586,6 @@ slapd_daemon_task(
if ( wd == tcps ) {
continue;
}
Debug( LDAP_DEBUG_CONNS,
"daemon: write active on %d\n",
wd, 0, 0 );
......@@ -590,7 +627,6 @@ slapd_daemon_task(
Debug ( LDAP_DEBUG_CONNS,
"daemon: read activity on %d\n", rd, 0, 0 );
/*
* NOTE: it is possible that the connection was closed
* and that the stream is now inactive.
......@@ -607,13 +643,13 @@ slapd_daemon_task(
if( slapd_shutdown > 0 ) {
Debug( LDAP_DEBUG_TRACE,
"daemon: shutdown requested (%d) and initiated.\n",
(int) slapd_shutdown, 0, 0 );
"daemon: shutdown requested and initiated.\n",
0, 0, 0 );
} else if ( slapd_shutdown < 0 ) {
Debug( LDAP_DEBUG_TRACE,
"daemon: abnormal condition (%d), shutdown initiated.\n",
(int) slapd_shutdown, 0, 0 );
"daemon: abnormal condition, shutdown initiated.\n",
0, 0, 0 );
} else {
Debug( LDAP_DEBUG_TRACE,
"daemon: no active streams, shutdown initiated.\n",
......@@ -624,9 +660,6 @@ slapd_daemon_task(
slapd_close( tcps );
}
/* we only implement "quick" shutdown */
connections_shutdown();
ldap_pvt_thread_mutex_lock( &active_threads_mutex );
Debug( LDAP_DEBUG_ANY,
"slapd shutdown: waiting for %d threads to terminate\n",
......@@ -636,16 +669,13 @@ slapd_daemon_task(
}
ldap_pvt_thread_mutex_unlock( &active_threads_mutex );
slapd_listener = 0;
return NULL;
}
int slapd_daemon( int inetd, int tcps )
int slapd_daemon( struct slapd_args *args )
{
int rc;
int *args = ch_malloc( sizeof( int[2] ) );
args[0] = inetd;
args[1] = tcps;
if ( !daemon_initialized ) sockinit();
......@@ -717,25 +747,27 @@ void sockinit()
daemon_initialized = 1;
} /* The WinSock DLL is acceptable. Proceed. */
void hit_socket( void )
void hit_socket()
{
int s, on = 1;
extern struct sockaddr_in bind_addr;
/* throw something at the socket to terminate the select() in the daemon thread. */
if (( s = socket( AF_INET, SOCK_STREAM, 0 )) == INVALID_SOCKET )
Debug( LDAP_DEBUG_TRACE,
Debug( LDAP_DEBUG_ANY,
"slap_set_shutdown: socket failed\n\tWSAGetLastError=%d (%s)\n",
WSAGetLastError(), WSAGetLastErrorString(), 0 );
if ( ioctlsocket( s, FIONBIO, &on ) == -1 )
Debug( LDAP_DEBUG_TRACE,
Debug( LDAP_DEBUG_ANY,
"slap_set_shutdown:FIONBIO ioctl on %d faled\n\tWSAGetLastError=%d (%s)\n",
s, WSAGetLastError(), WSAGetLastError() );
bind_addr.sin_addr.s_addr = htonl( INADDR_LOOPBACK );
if ( connect( s, (struct sockaddr *)&bind_addr, sizeof( struct sockaddr_in )) == SOCKET_ERROR ) {
Debug( LDAP_DEBUG_ANY,
"hit_socket: error on connect: %d\n", WSAGetLastError(), 0 );
/* we can probably expect some error to occur here, mostly WSAEWOULDBLOCK */
}
......@@ -767,7 +799,11 @@ slap_set_shutdown( int sig )
ldap_pvt_thread_kill( listener_tid, LDAP_SIGUSR1 );
}
#else
hit_socket();
Debug( LDAP_DEBUG_TRACE, "Shutdown %d ordered", sig, 0 );
// trying to "hit" the socket seems to always get a
// EWOULDBLOCK error, so just close the listen socket to
// break out of the select since we're shutting down anyway
tcp_close( tcps );
#endif
/* reinstall self */
(void) SIGNAL( sig, slap_set_shutdown );
......
......@@ -13,12 +13,44 @@
#include "ldap_defaults.h"
#include "slap.h"
#ifndef HAVE_WINSOCK
#include "lutil.h" /* Get lutil_detach() */
#endif
#ifdef LDAP_SIGCHLD
static RETSIGTYPE wait4child( int sig );
#endif
#ifdef HAVE_WINSOCK
#define SERVICE_NAME "OpenLDAP"
struct sockaddr_in bind_addr;
// in nt_main.c
extern SERVICE_STATUS SLAPDServiceStatus;
extern SERVICE_STATUS_HANDLE hSLAPDServiceStatus;
extern ldap_pvt_thread_cond_t started_event, stopped_event;
extern int is_NT_Service;
void LogSlapdStartedEvent( char *svc, int slap_debug, char *configfile, short port, int udp );
void LogSlapdStoppedEvent( char *svc );
void CommenceStartupProcessing( LPCTSTR serviceName,
void(*stopper)(int));
void ReportSlapdShutdownComplete( void );
void *getRegParam( char *svc, char *value );
#define SERVICE_EXIT( e, n ) \
if ( is_NT_Service ) \
{ \
SLAPDServiceStatus.dwWin32ExitCode = e; \
SLAPDServiceStatus.dwServiceSpecificExitCode = n; \
}
#else
#define SERVICE_EXIT( e, n )
#endif
short port = LDAP_PORT;
/*
* when more than one slapd is running on one machine, each one might have
* it's own LOCAL for syslogging and must have its own pid/args files
......@@ -62,7 +94,7 @@ static void
usage( char *name )
{
fprintf( stderr, "usage: %s [-d ?|debuglevel] [-f configfile] [-p portnumber] [-s sysloglevel]", name );
fprintf( stderr, "\n [-a bind-address] [-i]" );
fprintf( stderr, "\n [-a bind-address] [-i] [-u]" );
#if LDAP_CONNECTIONLESS
fprintf( stderr, " [-c]" );
#endif
......@@ -80,39 +112,77 @@ usage( char *name )
time_t starttime;
struct sockaddr_in bind_addr;
int tcps;
int
main( int argc, char **argv )
#ifdef HAVE_WINSOCK
void WINAPI ServiceMain( DWORD argc, LPTSTR *argv )
{
#else
int main( int argc, char **argv )
{
#endif
int i;
int inetd = 0;
int rc;
int tcps;
#ifdef LDAP_CONNECTIONLESS
struct slapd_args args;
int udp;
#if defined(HAVE_SETUID) && defined(HAVE_SETGID)
char *username = NULL;
char *groupname = NULL;
#endif
#ifdef LOG_LOCAL4
int syslogUser = DEFAULT_SYSLOG_USER;
#endif
#if defined(HAVE_SETUID) && defined(HAVE_SETGID)
char *username = NULL, *groupname = NULL;
#ifdef HAVE_WINSOCK
char *configfile = ".\\slapd.conf";
#else
char *configfile = SLAPD_DEFAULT_CONFIGFILE;
#endif
char *configfile;
char *serverName;
int serverMode = SLAP_SERVER_MODE;
configfile = SLAPD_DEFAULT_CONFIGFILE;
(void) memset( (void*) &bind_addr, '\0', sizeof(bind_addr));
bind_addr.sin_family = AF_INET;
bind_addr.sin_addr.s_addr = htonl(INADDR_ANY);
bind_addr.sin_port = htons(LDAP_PORT);
bind_addr.sin_port = htons(port);
g_argc = argc;
g_argv = argv;
#ifdef HAVE_WINSOCK
//if ( is_NT_Service )
{
int *newPort;
int *newDebugLevel;
char *newConfigFile;
ldap_debug = 0xffff;
if ( is_NT_Service ) CommenceStartupProcessing( SERVICE_NAME, slap_set_shutdown );
newPort = (int*)getRegParam( NULL, "Port" );
if ( newPort != NULL )
{
port = *newPort;
bind_addr.sin_port = htons(port);
Debug ( LDAP_DEBUG_ANY, "new port from registry is: %d\n", port, 0, 0 );
}
newDebugLevel = (int*)getRegParam( NULL, "DebugLevel" );
if ( newDebugLevel != NULL )
{
slap_debug = *newDebugLevel;
Debug( LDAP_DEBUG_ANY, "new debug level from registry is: %d\n", slap_debug, 0, 0 );
}
newConfigFile = (char*)getRegParam( NULL, "ConfigFile" );
if ( newConfigFile != NULL )
{
configfile = newConfigFile;
Debug ( LDAP_DEBUG_ANY, "new config file from registry is: %s\n", configfile, 0, 0 );
}
}
#endif
while ( (i = getopt( argc, argv,
"d:f:ia:p:s:"
"d:f:ia:p:s:u"
#ifdef LOG_LOCAL4
"l:"
#endif
......@@ -189,7 +259,7 @@ main( int argc, char **argv )
break;
case 'p': { /* port on which to listen */
short port = (short)atoi( optarg );
port = (short)atoi( optarg );
if(! port ) {
fprintf(stderr, "-p %s must be numeric\n", optarg);
} else {
......@@ -234,7 +304,9 @@ main( int argc, char **argv )
default:
usage( argv[0] );
exit( 1 );
rc = 1;
SERVICE_EXIT( ERROR_SERVICE_SPECIFIC_ERROR, 15 );
goto stop;
}
}
......@@ -256,8 +328,6 @@ main( int argc, char **argv )
openlog( serverName, OPENLOG_OPTIONS );
#endif
tcps = set_socket( inetd ? NULL : &bind_addr );
#if defined(HAVE_SETUID) && defined(HAVE_SETGID)
if ( username != NULL || groupname != NULL )
slap_init_user( username, groupname );
......@@ -265,14 +335,19 @@ main( int argc, char **argv )
if ( slap_init( serverMode, serverName ) != 0 ) {
rc = 1;
SERVICE_EXIT( ERROR_SERVICE_SPECIFIC_ERROR, 18 );
goto destroy;
}
if ( read_config( configfile ) != 0 ) {
rc = 1;
SERVICE_EXIT( ERROR_SERVICE_SPECIFIC_ERROR, 19 );
goto destroy;
}
tcps = set_socket( inetd ? NULL : &bind_addr );
(void) SIGNAL( LDAP_SIGUSR1, slap_do_nothing );
(void) SIGNAL( LDAP_SIGUSR2, slap_set_shutdown );
#ifdef SIGPIPE
......@@ -286,8 +361,12 @@ main( int argc, char **argv )
#ifdef LDAP_SIGCHLD
(void) SIGNAL( LDAP_SIGCHLD, wait4child );
#endif
#ifdef HAVE_WINSOCK
// SIGBREAK is generated when Ctrl-Break is pressed.
(void) SIGNAL( SIGBREAK, slap_set_shutdown );
#endif
#ifndef WIN32
#ifndef HAVE_WINSOCK
if(!inetd) {
#ifdef LDAP_DEBUG
lutil_detach( ldap_debug, 0 );
......@@ -295,16 +374,19 @@ main( int argc, char **argv )
lutil_detach( 0, 0 );
#endif
}
#endif /* WIN32 */
#endif /* HAVE_WINSOC */
if ( slap_startup(-1) != 0 ) {
rc = 1;
SERVICE_EXIT( ERROR_SERVICE_SPECIFIC_ERROR, 20 );
goto shutdown;
}
if(!inetd) {
FILE *fp;
args.addr = &bind_addr;
Debug( LDAP_DEBUG_ANY, "slapd starting\n", 0, 0, 0 );
if (( slapd_pid_file != NULL ) &&
......@@ -323,11 +405,25 @@ main( int argc, char **argv )
fprintf( fp, "\n" );
fclose( fp );
}
} else {
args.addr = NULL;
}
args.tcps = tcps;
time( &starttime );
#ifdef HAVE_WINSOCK
LogSlapdStartedEvent( SERVICE_NAME, slap_debug, configfile, port, udp );
#endif
rc = slapd_daemon( &args );
#ifdef HAVE_WINSOCK
// Throw away the event that we used during the startup process.
if ( is_NT_Service )
ldap_pvt_thread_cond_destroy( &started_event );
#endif
rc = slapd_daemon( inetd, tcps );
shutdown:
/* remember an error during shutdown */
......@@ -336,9 +432,16 @@ destroy:
/* remember an error during destroy */
rc |= slap_destroy();
stop:
#ifdef HAVE_WINSOCK
LogSlapdStoppedEvent( SERVICE_NAME );
#endif
Debug( LDAP_DEBUG_ANY, "slapd stopped.\n", 0, 0, 0 );
#ifdef HAVE_WINSOCK
ReportSlapdShutdownComplete();
#endif
closelog();
closelog();
return rc;
}
......
......@@ -338,8 +338,12 @@ extern int slap_shutdown LDAP_P((int dbnum));
extern int slap_destroy LDAP_P((void));
struct sockaddr_in;
extern int set_socket LDAP_P((struct sockaddr_in *addr));
extern int slapd_daemon LDAP_P((int inetd, int tcps));
struct slapd_args {
struct sockaddr_in *addr;
int tcps;
};
extern int slapd_daemon LDAP_P((struct slapd_args *args));
extern void slapd_set_write LDAP_P((int s, int wake));
extern void slapd_clr_write LDAP_P((int s, int wake));
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment