From 2e5e4c3f20045ba6a3fea20f7b69e1dcd07bfcc8 Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Thu, 11 May 2000 20:50:20 +0000 Subject: [PATCH] More fixes for NT support: liblutil/ntservice.c change registry key path used for non-default service names. slapd/Makefile.in change to generate slapd.syms dynamically slapd/daemon.c fix to make NT service ignore SIGBREAK slapd/main.c fix to allow NT to retrieve listening url from registry slapd/nt_svc.c fix for exported symbols slapd/result.c change use of strerror to sock_errstr slapd/slapd.syms no longer needed --- libraries/liblutil/ntservice.c | 13 +- servers/slapd/Makefile.in | 127 +++++++++--- servers/slapd/daemon.c | 23 +++ servers/slapd/main.c | 30 ++- servers/slapd/nt_svc.c | 51 +++-- servers/slapd/result.c | 2 +- servers/slapd/slapd.syms | 339 --------------------------------- 7 files changed, 177 insertions(+), 408 deletions(-) delete mode 100644 servers/slapd/slapd.syms diff --git a/libraries/liblutil/ntservice.c b/libraries/liblutil/ntservice.c index 6540bf2079..d9be5df496 100644 --- a/libraries/liblutil/ntservice.c +++ b/libraries/liblutil/ntservice.c @@ -46,7 +46,8 @@ void (*stopfunc)(int); /* in nt_err.c */ char *GetLastErrorString( void ); -int srv_install(LPCTSTR lpszServiceName, LPCTSTR lpszBinaryPathName) +int srv_install(LPCTSTR lpszServiceName, LPCTSTR lpszDisplayName, + LPCTSTR lpszBinaryPathName, BOOL auto_start) { HKEY hKey; DWORD dwValue, dwDisposition; @@ -58,10 +59,10 @@ int srv_install(LPCTSTR lpszServiceName, LPCTSTR lpszBinaryPathName) if ((schService = CreateService( schSCManager, lpszServiceName, - TEXT("OpenLDAP Directory Service"), - SC_MANAGER_CREATE_SERVICE, + lpszDisplayName, + SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, - SERVICE_DEMAND_START, + auto_start ? SERVICE_AUTO_START : SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, lpszBinaryPathName, NULL, NULL, NULL, NULL, NULL)) != NULL) @@ -292,8 +293,8 @@ void *getRegParam( char *svc, char *value ) static char vValue[1024]; DWORD valLen = sizeof( vValue ); - if ( svc != NULL ) - sprintf ( path, "SOFTWARE\\OpenLDAP\\%s\\Parameters", svc ); + if ( svc && strcmp(svc, SERVICE_NAME) ) + sprintf ( path, "SOFTWARE\\%s", svc ); else strcpy (path, "SOFTWARE\\OpenLDAP\\Parameters" ); diff --git a/servers/slapd/Makefile.in b/servers/slapd/Makefile.in index 5d15867d0b..ebbde713ef 100644 --- a/servers/slapd/Makefile.in +++ b/servers/slapd/Makefile.in @@ -52,46 +52,113 @@ BUILD_SRV = @BUILD_SLAPD@ all-local-srv: all-cffiles -NT_GEN_DEFS = -DLIBLUTIL_DECL=dllexport -DLIBAVL_DECL=dllexport \ - -DLIBLDBM_DECL=dllexport -DLIBLDIF_DECL=dllexport - NT_DYN_DEFS = -DLIBLBER_DECL=dllimport -DLIBLDAP_DECL=dllimport DEFINES = $(@PLAT@_@LIB_LINKAGE@_DEFS) -slapd.def: slapd.syms - ( \ - echo EXPORTS > $@; \ - _hint=1; \ - for symbol in `cat $<`; do \ - echo " $$symbol @ $$_hint ; " >> $@; \ - _hint=`expr 1 + $$_hint`; \ - done \ - ) - -slapd.base: version.o - $(LTLINK) -o slapd $(OBJS) version.o $(LIBS) $(WRAP_LIBS) \ - -Wl,--base-file,$@ - rm -f slapd - -slapd.exp: slapd.def slapd.base - dlltool --dllname slapd.exe --def slapd.def --base-file slapd.base \ - --output-exp $@ - -libslapd.a: slapd.def - dlltool --dllname slapd.exe --def $< --output-lib $@ +# The tricky part about building slapd in NT is that it will export symbols +# like a DLL. The symbols that it exports should be representative of all +# of the static symbols that it knows about. NT_EXP = slapd.exp -NT_IMP_LIB = libslapd.a +NT_IMPLIB = libslapd.a +NT_DUMMY = symdummy.o -slapd: $(@PLAT@_IMP_LIB) libbackends.a version.o $(@PLAT@_EXP) - $(LTLINK) -o $@ $(OBJS) version.o $(LIBS) $(WRAP_LIBS) $(@PLAT@_EXP) +# Add extra def targets here +EXTRA_DEFS = + +# NT needs this if libltdl is built statically. You'll have to fix the path +# to point to where libltdl was built, then put ltdl.def in EXTRA_DEFS +ltdl.def: ../../../libtool/libltdl/*.o + dlltool --export-all-symbols --output-def $@ $^ + +DYNAMIC_DEFS = liblber.def libldap_r.def + +STATIC_DEFS = libavl.def libldbm.def libldif.def liblutil.def slapd.def \ + $(EXTRA_DEFS) + +libavl.def: $(LDAP_LIBDIR)/libavl/*.o + dlltool --export-all-symbols --output-def $@ `ls $^ | grep -v test` + +liblber.def: $(LDAP_LIBDIR)/liblber/*.o + dlltool --export-all-symbols --output-def $@ `ls $^ | grep -v test` + +libldap_r.def: $(LDAP_LIBDIR)/libldap_r/*.o + dlltool --export-all-symbols --output-def $@ `ls $^ | grep -v test` + +libldbm.def: $(LDAP_LIBDIR)/libldbm/*.o + dlltool --export-all-symbols --output-def $@ `ls $^ | grep -v test` + +libldif.def: $(LDAP_LIBDIR)/libldif/*.o + dlltool --export-all-symbols --output-def $@ `ls $^ | grep -v test` + +liblutil.def: $(LDAP_LIBDIR)/liblutil/*.o + dlltool --export-all-symbols --output-def $@ `ls $^ | grep -v test` + +slapd.def: $(OBJS) version.o + dlltool --export-all-symbols --exclude-symbols main,ServiceMain@8 --output-def $@ `ls $^ | grep -v test` + +# We don't want to include symbols from dynamic libraries. +all.def: $(STATIC_DEFS) $(DYNAMIC_DEFS) + cat $(STATIC_DEFS) | grep " @ " | sed -e 's/ @ [0-9]*//' > $@ + if [ "@LIB_LINKAGE@" != "DYN" ] ; \ + then \ + cat $(DYNAMIC_DEFS) | grep " @ " | sed -e 's/ @ [0-9]*//' >> $@; \ + fi + echo EXPORTS > tmp.def + sort $@ >> tmp.def + rm -f $@ + dlltool --input-def tmp.def --output-def $@ + rm -f tmp.def + +DUMMYTMP = symdummytmp.c + +symdummy.c: all.def $(ALL_DEFS) + rm -f $@ + echo "static void never_called() {" > $(DUMMYTMP) + cat $< | grep " @ " | while read line; \ + do \ + set dummy $$line; \ + case $$# in \ + 5) \ + echo "int $$2();" >> $@; \ + echo "$$2();" >> $(DUMMYTMP); \ + ;; \ + 6) \ + echo "extern int $$2;" >> $@; \ + echo "$$2 = 0;" >> $(DUMMYTMP); \ + ;; \ + esac; \ + done + echo "" >> $@ + echo "}" >> $(DUMMYTMP) + cat $(DUMMYTMP) >> $@ + rm -f $(DUMMYTMP) + +symdummy.o: symdummy.c + $(CC) $(CFLAGS) -c $< + +SLAPD_OBJS = $(OBJS) version.o symdummy.o + +slapd.exp: libbackends.a all.def $(SLAPD_OBJS) + $(LTLINK) -o slapd $(SLAPD_OBJS) $(LIBS) $(WRAP_LIBS) -Wl,--base-file,slapd.base + rm -f slapd.exe + dlltool --dllname slapd.exe --input-def all.def --base-file slapd.base --output-exp $@ + $(LTLINK) -o slapd $(SLAPD_OBJS) $(LIBS) $(WRAP_LIBS) $@ -Wl,--base-file,slapd.base + rm -f slapd.exe + dlltool --dllname slapd.exe --input-def all.def --base-file slapd.base --output-exp $@ + +libslapd.a: all.def + dlltool --dllname slapd.exe --input-def $< --output-lib $@ + +slapd: libbackends.a version.o $(@PLAT@_EXP) $(@PLAT@_DUMMY) + $(LTLINK) -o $@ $(@PLAT@_EXP) $(@PLAT@_DUMMY) $(OBJS) version.o $(LIBS) $(WRAP_LIBS) (cd tools; $(MAKE) $(MFLAGS) all) sslapd: version.o $(LTLINK) -static -o $@ $(OBJS) version.o $(LIBS) $(WRAP_LIBS) -.backend: FORCE +.backend: $(@PLAT@_IMPLIB) FORCE @for i in back-*; do \ if [ -d $$i ]; then \ echo " "; echo " cd $$i; $(MAKE) $(MFLAGS) all"; \ @@ -123,7 +190,7 @@ libbackends.a: .backend fi @ls -l libbackends.a -version.c: libbackends.a $(OBJS) $(SLAPD_LIBDEPEND) +version.c: $(OBJS) $(SLAPD_LIBDEPEND) @-$(RM) $@ $(MKVERSION) -s -n Versionstr slapd > $@ @@ -137,7 +204,7 @@ depend-local-srv: FORCE @echo "" clean-local: - rm -f *.exp *.def *.base *.a + rm -f *.exp *.def *.base *.a *.objs symdummy.c clean-local-srv: FORCE @for i in back-* shell-backends tools; do \ diff --git a/servers/slapd/daemon.c b/servers/slapd/daemon.c index 7bd2b45b90..c8092493de 100644 --- a/servers/slapd/daemon.c +++ b/servers/slapd/daemon.c @@ -74,6 +74,7 @@ do { if (w) tcp_write( wake_sds[1], "0", 1 ); } while(0) #ifdef HAVE_NT_SERVICE_MANAGER /* in nt_main.c */ extern ldap_pvt_thread_cond_t started_event; +extern int is_NT_Service; #endif #ifndef HAVE_WINSOCK @@ -999,6 +1000,13 @@ slapd_daemon_task( 0, 0, 0 ); } else if ( slapd_shutdown < 0 ) { +#ifdef HAVE_NT_SERVICE_MANAGER + if (slapd_shutdown == -1) + Debug( LDAP_DEBUG_TRACE, + "daemon: shutdown initiated by Service Manager.\n", + 0, 0, 0); + else +#endif Debug( LDAP_DEBUG_TRACE, "daemon: abnormal condition, shutdown initiated.\n", 0, 0, 0 ); @@ -1134,7 +1142,22 @@ static int sockdestroy(void) RETSIGTYPE slap_sig_shutdown( int sig ) { + Debug(LDAP_DEBUG_TRACE, "slap_sig_shutdown: signal %d\n", sig, 0, 0); + + /* + * If the NT Service Manager is controlling the server, we don't + * want SIGBREAK to kill the server. For some strange reason, + * SIGBREAK is generated when a user logs out. + */ + +#if HAVE_NT_SERVICE_MANAGER && SIGBREAK + if (is_NT_Service && sig == SIGBREAK) + Debug(LDAP_DEBUG_TRACE, "slap_sig_shutdown: SIGBREAK ignored.\n", + 0, 0, 0); + else +#endif slapd_shutdown = sig; + WAKE_LISTENER(1); /* reinstall self */ diff --git a/servers/slapd/main.c b/servers/slapd/main.c index 3f77d26edb..84e0d28deb 100644 --- a/servers/slapd/main.c +++ b/servers/slapd/main.c @@ -171,18 +171,32 @@ int main( int argc, char **argv ) { int *i; char *newConfigFile; + char *newUrls; if ( is_NT_Service ) { + NTservice = argv[0]; CommenceStartupProcessing( NTservice, slap_sig_shutdown ); } - i = (int*)getRegParam( NULL, "DebugLevel" ); + i = (int*)getRegParam( NTservice, "DebugLevel" ); if ( i != NULL ) { slap_debug = *i; Debug( LDAP_DEBUG_ANY, "new debug level from registry is: %d\n", slap_debug, 0, 0 ); } - newConfigFile = (char*)getRegParam( NULL, "ConfigFile" ); + + newUrls = (char *) getRegParam(NTservice, "Urls"); + if (newUrls) + { + if (urls) + ch_free(urls); + + urls = ch_strdup(newUrls); + Debug(LDAP_DEBUG_ANY, "new urls from registry: %s\n", + urls, 0, 0); + } + + newConfigFile = (char*)getRegParam( NTservice, "ConfigFile" ); if ( newConfigFile != NULL ) { configfile = newConfigFile; @@ -352,7 +366,13 @@ int main( int argc, char **argv ) #ifdef HAVE_TLS ldap_pvt_tls_init(); - ldap_pvt_tls_init_def_ctx(); + + if (ldap_pvt_tls_init_def_ctx() != 0) + { + rc = 1; + SERVICE_EXIT( ERROR_SERVICE_SPECIFIC_ERROR, 20 ); + goto destroy; + } #endif (void) SIGNAL( LDAP_SIGUSR1, slap_sig_wake ); @@ -384,7 +404,7 @@ int main( int argc, char **argv ) if ( slap_startup( NULL ) != 0 ) { rc = 1; - SERVICE_EXIT( ERROR_SERVICE_SPECIFIC_ERROR, 20 ); + SERVICE_EXIT( ERROR_SERVICE_SPECIFIC_ERROR, 21 ); goto shutdown; } @@ -412,6 +432,7 @@ int main( int argc, char **argv ) } #ifdef HAVE_NT_EVENT_LOG + if (is_NT_Service) LogSlapdStartedEvent( NTservice, slap_debug, configfile, urls ); #endif @@ -439,6 +460,7 @@ destroy: stop: #ifdef HAVE_NT_EVENT_LOG + if (is_NT_Service) LogSlapdStoppedEvent( NTservice ); #endif diff --git a/servers/slapd/nt_svc.c b/servers/slapd/nt_svc.c index 4349def634..1fd82abacb 100644 --- a/servers/slapd/nt_svc.c +++ b/servers/slapd/nt_svc.c @@ -9,38 +9,14 @@ #include #include "slap.h" -static void stubs() -{ - ldap_abandon(NULL, 0); - ldap_add_s(NULL, NULL, NULL); - ldap_bind_s(NULL, NULL, NULL, 0); - ldap_delete_s(NULL, NULL); - ldap_first_attribute(NULL, NULL, NULL); - ldap_first_entry(NULL, NULL); - ldap_get_dn(NULL, NULL); - ldap_get_option(NULL, 0, NULL); - ldap_get_values_len(NULL, NULL, NULL); - ldap_init(NULL, 0); - ldap_modify_s(NULL, NULL, NULL); - ldap_modrdn_s(NULL, NULL, NULL); - ldap_msgfree(NULL); - ldap_next_attribute(NULL, NULL, NULL); - ldap_result(NULL, 0, 0, NULL, NULL); - ldap_search(NULL, NULL, 0, NULL, NULL, 0); - ldap_unbind(NULL); -} - #ifdef HAVE_NT_SERVICE_MANAGER -ldap_pvt_thread_cond_t started_event, stopped_event; -ldap_pvt_thread_t start_status_tid, stop_status_tid; - - /* in main.c */ void WINAPI ServiceMain( DWORD argc, LPTSTR *argv ); /* in ntservice.c */ -int srv_install( char* service, char* filename ); +int srv_install( char* service, char * displayName, char* filename, + BOOL auto_start ); int srv_remove ( char* service, char* filename ); int main( int argc, LPTSTR *argv ) @@ -49,8 +25,17 @@ int main( int argc, LPTSTR *argv ) char filename[MAX_PATH], *fname_start; extern int is_NT_Service; + /* + * Because the service was registered as SERVICE_WIN32_OWN_PROCESS, + * the lpServiceName element of the SERVICE_TABLE_ENTRY will be + * ignored. Since we don't even know the name of the service at + * this point (since it could have been installed under a name + * different than SERVICE_NAME), we might as well just provide + * the parameter as "". + */ + SERVICE_TABLE_ENTRY DispatchTable[] = { - { SERVICE_NAME, (LPSERVICE_MAIN_FUNCTION) ServiceMain }, + { "", (LPSERVICE_MAIN_FUNCTION) ServiceMain }, { NULL, NULL } }; @@ -67,14 +52,24 @@ int main( int argc, LPTSTR *argv ) if ( _stricmp( "install", argv[1] ) == 0 ) { char *svcName = SERVICE_NAME; + char *displayName = "OpenLDAP Directory Service"; + BOOL auto_start = FALSE; + if ( (argc > 2) && (argv[2] != NULL) ) svcName = argv[2]; + + if ( argc > 3 && argv[3]) + displayName = argv[3]; + + if ( argc > 4 && stricmp(argv[4], "auto") == 0) + auto_start = TRUE; + if ( (length = GetModuleFileName(NULL, filename, sizeof( filename ))) == 0 ) { fputs( "unable to retrieve file name for the service.\n", stderr ); return EXIT_FAILURE; } - if ( !srv_install(svcName, filename) ) + if ( !srv_install(svcName, displayName, filename, auto_start) ) { fputs( "service failed installation ...\n", stderr ); return EXIT_FAILURE; diff --git a/servers/slapd/result.c b/servers/slapd/result.c index ad2f22afb9..3c71f04c1e 100644 --- a/servers/slapd/result.c +++ b/servers/slapd/result.c @@ -217,7 +217,7 @@ static long send_ldap_ber( */ Debug( LDAP_DEBUG_CONNS, "ber_flush failed errno=%d reason=\"%s\"\n", - err, STRERROR(err), 0 ); + err, sock_errstr(err), 0 ); if ( err != EWOULDBLOCK && err != EAGAIN ) { connection_closing( conn ); diff --git a/servers/slapd/slapd.syms b/servers/slapd/slapd.syms deleted file mode 100644 index b250b932c5..0000000000 --- a/servers/slapd/slapd.syms +++ /dev/null @@ -1,339 +0,0 @@ -access2str -access_allowed -acl_check_modlist -active_threads -active_threads_cond -active_threads_mutex -attrs_dup -attrs_free -attr_delete -attr_dup -attr_find -attr_free -attr_index_config -attr_index_destroy -attr_masks -attr_merge -attr_merge_fast -attr_normalize -attr_syntax -attr_syntax_config -at_add -at_append_to_list -at_canonical_name -at_delete_from_list -at_fake_if_needed -at_find -at_find_in_list -at_schema_info -ava_free -backendDB -backendInfo -backend_add -backend_connection_destroy -backend_connection_init -backend_db_init -backend_destroy -backend_group -backend_info -backend_init -backend_num -backend_shutdown -backend_startup -backend_subschemasubentry -backend_unbind -ber_bvfree -ber_free -be_db_close -be_entry_release_rw -be_isroot -be_isroot_pw -be_issuffix -be_root_dn -build_new_dn -cache_add_entry_rw -cache_delete_entry -cache_find_entry_dn2id -cache_find_entry_id -cache_release_all -cache_return_entry_rw -cache_update_entry -case_ignore_normalize -charray2str -charray_add -charray_dup -charray_free -charray_inlist -charray_merge -ch_calloc -ch_free -ch_malloc -ch_realloc -ch_strdup -config_info -connections_destroy -connections_init -connections_nextid -connections_shutdown -connections_timeout_idle -connection_closing -connection_done -connection_first -connection_init -connection_next -connection_read -connection_state2str -connection_state_closing -connection_write -default_referral -defsize -deftime -deref_internal_r -dn2entry_rw -dn2id -dn2idl -dn2id_add -dn2id_delete -dn_issuffix -dn_normalize -dn_parent -dn_rdn -dn_subtree -dn_validate -do_abandon -do_add -do_bind -do_compare -do_delete -do_extended -do_modify -do_modrdn -do_search -do_unbind -dscompare -dtblsize -entry2str -entry2str_mutex -entry_cmp -entry_destroy -entry_dn_cmp -entry_free -entry_id_cmp -filter_candidates -filter_free -filter_print -first_word -get_ava -get_ctrls -get_entry_referrals -get_filter -get_manageDSAit -global_acl -global_default_access -global_idletimeout -global_lastmod -global_readonly -global_realm -global_schemacheck -gmtime_mutex -g_argc -g_argv -has_children -id2entry_add -id2entry_delete -id2entry_rw -idl_allids -idl_alloc -idl_delete_key -idl_fetch -idl_firstid -idl_free -idl_insert -idl_insert_key -idl_intersection -idl_nextid -idl_notin -idl_union -index_add_entry -index_add_mods -index_change_values -index_read -is_entry_objectclass -ldap_abandon -ldap_add_s -ldap_bind_s -ldap_delete_s -ldap_first_attribute -ldap_first_entry -ldap_get_dn -ldap_get_option -ldap_get_values_len -ldap_init -ldap_modify_s -ldap_modrdn_s -ldap_msgfree -ldap_next_attribute -ldap_pvt_str2upper -ldap_pvt_thread_mutex_init -ldap_pvt_thread_mutex_lock -ldap_pvt_thread_mutex_trylock -ldap_pvt_thread_mutex_unlock -ldap_pvt_thread_yield -ldap_result -ldap_search -ldap_srvtab -ldap_syslog -ldap_unbind -ldbm_back_abandon -ldbm_back_add -ldbm_back_bind -ldbm_back_close -ldbm_back_compare -ldbm_back_db_close -ldbm_back_db_config -ldbm_back_db_destroy -ldbm_back_db_init -ldbm_back_db_open -ldbm_back_delete -ldbm_back_destroy -ldbm_back_entry_release_rw -ldbm_back_group -ldbm_back_initialize -ldbm_back_modify -ldbm_back_modrdn -ldbm_back_open -ldbm_back_search -ldbm_back_unbind -ldbm_cache_close -ldbm_cache_delete -ldbm_cache_fetch -ldbm_cache_flush_all -ldbm_cache_open -ldbm_cache_really_close -ldbm_cache_store -ldbm_close -ldbm_datum_free -ldbm_delete -ldbm_fetch -ldbm_firstkey -ldbm_initialize -ldbm_modify_internal -ldbm_nextkey -ldbm_open -ldbm_store -ldbm_sync -ldbm_tool_entry_close -ldbm_tool_entry_first -ldbm_tool_entry_get -ldbm_tool_entry_next -ldbm_tool_entry_open -ldbm_tool_entry_put -ldbm_tool_index_attr -ldbm_tool_index_change -ldbm_tool_sync -lock_fclose -lock_fopen -lutil_debug -main -module_load -module_path -monitor_info -mrule_defs -mr_add -mr_find -nBackendDB -nBackendInfo -next_id -next_id_get -next_id_write -next_word -num_bytes_sent -num_conns -num_entries_sent -num_ops_completed -num_ops_initiated -num_ops_mutex -num_pdu_sent -num_refs_sent -num_sent_mutex -oc_add -oc_check_no_usermod_attr -oc_check_operational_attr -oc_check_usermod_attr -oc_find -oc_schema_check -parse_acl -parse_at -parse_oc -parse_oc_old -parse_oidm -phonetic -rdn_attr_type -rdn_attr_value -rdn_validate -read_config -register_matching_rule -register_syntax -replog -replogfile -replog_mutex -root_dse_info -sasl_destroy -sasl_init -schema_info -schema_init -scherr2str -select_backend -send_ldap_disconnect -send_ldap_result -send_search_entry -send_search_reference -send_search_result -slapd_args_file -slapd_clr_read -slapd_clr_write -slapd_daemon -slapd_daemon_destroy -slapd_daemon_init -slapd_pid_file -slapd_remove -slapd_set_read -slapd_set_write -slapd_shutdown -slapMode -slap_debug -slap_destroy -slap_get_time -slap_init -slap_listeners -slap_op_add -slap_op_alloc -slap_op_free -slap_op_pop -slap_op_remove -slap_shutdown -slap_sig_shutdown -slap_sig_wake -slap_startup -starttime -str2access -str2charray -str2entry -str2filter -str2result -suffix_alias -supportedControls -supportedExtensions -supportedSASLMechanisms -syntax_defs -syn_add -syn_find -syn_find_desc -test_filter -value_add -value_add_fast -value_cmp -value_find -value_normalize -Versionstr -word_dup