summaryrefslogtreecommitdiffstats
path: root/src/ccapi
diff options
context:
space:
mode:
Diffstat (limited to 'src/ccapi')
-rw-r--r--src/ccapi/lib/ccapi_context.c1
-rw-r--r--src/ccapi/lib/ccapi_ipc.c7
-rw-r--r--src/ccapi/lib/ccapi_ipc.h1
-rw-r--r--src/ccapi/lib/ccapi_os_ipc.h1
-rw-r--r--src/ccapi/lib/mac/ccapi_os_ipc.c8
-rw-r--r--src/ccapi/lib/win/Makefile.in2
-rw-r--r--src/ccapi/lib/win/ccapi_os_ipc.cxx7
-rw-r--r--src/ccapi/server/win/Makefile.in218
-rw-r--r--src/ccapi/server/win/Server.sln40
-rw-r--r--src/ccapi/server/win/Server.vcproj454
-rw-r--r--src/ccapi/server/win/WorkItem.cpp252
-rw-r--r--src/ccapi/server/win/WorkQueue.cpp122
-rw-r--r--src/ccapi/server/win/ccs_os_server.cpp1926
-rw-r--r--src/ccapi/test/Makefile.in38
-rw-r--r--src/ccapi/test/pingtest.c14
15 files changed, 1531 insertions, 1560 deletions
diff --git a/src/ccapi/lib/ccapi_context.c b/src/ccapi/lib/ccapi_context.c
index da8aa59f08..7715139ff4 100644
--- a/src/ccapi/lib/ccapi_context.c
+++ b/src/ccapi/lib/ccapi_context.c
@@ -114,7 +114,6 @@ static void cci_thread_fini (void)
remove_error_table(&et_CAPI_error_table);
cci_context_change_time_thread_fini ();
- cci_ipc_thread_fini ();
}
diff --git a/src/ccapi/lib/ccapi_ipc.c b/src/ccapi/lib/ccapi_ipc.c
index 54b5faa867..0f14df80af 100644
--- a/src/ccapi/lib/ccapi_ipc.c
+++ b/src/ccapi/lib/ccapi_ipc.c
@@ -36,13 +36,6 @@ cc_int32 cci_ipc_thread_init (void)
/* ------------------------------------------------------------------------ */
-void cci_ipc_thread_fini (void)
-{
- cci_os_ipc_thread_fini ();
-}
-
-/* ------------------------------------------------------------------------ */
-
static cc_int32 _cci_ipc_send (enum cci_msg_id_t in_request_name,
cc_int32 in_launch_server,
cci_identifier_t in_identifier,
diff --git a/src/ccapi/lib/ccapi_ipc.h b/src/ccapi/lib/ccapi_ipc.h
index 5b7d5d3745..03b890b1fc 100644
--- a/src/ccapi/lib/ccapi_ipc.h
+++ b/src/ccapi/lib/ccapi_ipc.h
@@ -30,7 +30,6 @@
#include "cci_common.h"
cc_int32 cci_ipc_thread_init (void);
-void cci_ipc_thread_fini (void);
cc_int32 cci_ipc_send (enum cci_msg_id_t in_request_name,
cci_identifier_t in_identifier,
diff --git a/src/ccapi/lib/ccapi_os_ipc.h b/src/ccapi/lib/ccapi_os_ipc.h
index b5e0405997..eabea254e2 100644
--- a/src/ccapi/lib/ccapi_os_ipc.h
+++ b/src/ccapi/lib/ccapi_os_ipc.h
@@ -30,7 +30,6 @@
#include "cci_common.h"
cc_int32 cci_os_ipc_thread_init (void);
-void cci_os_ipc_thread_fini (void);
cc_int32 cci_os_ipc (cc_int32 in_launch_server,
k5_ipc_stream in_request_stream,
diff --git a/src/ccapi/lib/mac/ccapi_os_ipc.c b/src/ccapi/lib/mac/ccapi_os_ipc.c
index e0a81d8786..a25297e311 100644
--- a/src/ccapi/lib/mac/ccapi_os_ipc.c
+++ b/src/ccapi/lib/mac/ccapi_os_ipc.c
@@ -40,14 +40,6 @@ cc_int32 cci_os_ipc_thread_init (void)
/* ------------------------------------------------------------------------ */
-void cci_os_ipc_thread_fini (void)
-{
- /* k5_ipc_send_request handles all thread data for us */
- return;
-}
-
-/* ------------------------------------------------------------------------ */
-
cc_int32 cci_os_ipc (cc_int32 in_launch_server,
k5_ipc_stream in_request_stream,
k5_ipc_stream *out_reply_stream)
diff --git a/src/ccapi/lib/win/Makefile.in b/src/ccapi/lib/win/Makefile.in
index d5ca7a55be..7ca749a189 100644
--- a/src/ccapi/lib/win/Makefile.in
+++ b/src/ccapi/lib/win/Makefile.in
@@ -116,4 +116,4 @@ clean::
if exist $(OUTPRE)*.map del $(OUTPRE)*.map
if exist $(OUTPRE)*.pdb del $(OUTPRE)*.pdb
if exist *.err del *.err
- if exist $(SRCTMP) rm -rf $(SRCTMP)
+ if exist $(SRCTMP) rmdir /s /q $(SRCTMP)
diff --git a/src/ccapi/lib/win/ccapi_os_ipc.cxx b/src/ccapi/lib/win/ccapi_os_ipc.cxx
index b6fc70155c..062558cb1f 100644
--- a/src/ccapi/lib/win/ccapi_os_ipc.cxx
+++ b/src/ccapi/lib/win/ccapi_os_ipc.cxx
@@ -120,13 +120,6 @@ extern "C" cc_int32 cci_os_ipc_thread_init (void) {
/* ------------------------------------------------------------------------ */
-void cci_os_ipc_thread_fini (void)
-{
-}
-
-
-/* ------------------------------------------------------------------------ */
-
cc_int32 cci_os_ipc (cc_int32 in_launch_server,
k5_ipc_stream in_request_stream,
k5_ipc_stream* out_reply_stream) {
diff --git a/src/ccapi/server/win/Makefile.in b/src/ccapi/server/win/Makefile.in
index 3d8da6d223..36909b85eb 100644
--- a/src/ccapi/server/win/Makefile.in
+++ b/src/ccapi/server/win/Makefile.in
@@ -1,109 +1,109 @@
-# makefile: Constructs the Kerberos for Windows CCAPI server.
-
-#BUILDTOP is krb5/src and is relative to krb5/src/ccapi/server/win, for making Makefile.
-BUILDTOP=..\..\..\
-CCAPI = $(BUILDTOP)\CCAPI
-CO = $(CCAPI)\common
-COWIN = $(CCAPI)\common\win
-CCUTIL = $(CCAPI)\common\win\OldCC
-SRVDIR = $(CCAPI)\server
-SRVWIN = $(SRVDIR)\win
-POSIX = $(BUILDTOP)\lib\krb5\posix
-SRCTMP = $(SRVWIN)\srctmp
-
-!if defined(KRB5_KFW_COMPILE)
-KFWINC= /I$(BUILDTOP)\..\..\krbcc\include
-!endif
-
-OBJS = $(OUTPRE)cci_array_internal.$(OBJEXT) \
- $(OUTPRE)cci_cred_union.$(OBJEXT) \
- $(OUTPRE)cci_debugging.$(OBJEXT) \
- $(OUTPRE)cci_identifier.$(OBJEXT) \
- $(OUTPRE)cci_message.$(OBJEXT) \
- $(OUTPRE)cci_os_debugging.$(OBJEXT) \
- $(OUTPRE)cci_os_identifier.$(OBJEXT) \
- $(OUTPRE)ccs_array.$(OBJEXT) \
- $(OUTPRE)ccs_cache_collection.$(OBJEXT) \
- $(OUTPRE)ccs_callback.$(OBJEXT) \
- $(OUTPRE)ccs_ccache.$(OBJEXT) \
- $(OUTPRE)ccs_ccache_iterator.$(OBJEXT) \
- $(OUTPRE)ccs_client.$(OBJEXT) \
- $(OUTPRE)ccs_credentials.$(OBJEXT) \
- $(OUTPRE)ccs_credentials_iterator.$(OBJEXT) \
- $(OUTPRE)ccs_list.$(OBJEXT) \
- $(OUTPRE)ccs_list_internal.$(OBJEXT) \
- $(OUTPRE)ccs_lock.$(OBJEXT) \
- $(OUTPRE)ccs_lock_state.$(OBJEXT) \
- $(OUTPRE)ccs_os_pipe.$(OBJEXT) \
- $(OUTPRE)ccs_os_server.$(OBJEXT) \
- $(OUTPRE)ccs_pipe.$(OBJEXT) \
- $(OUTPRE)ccs_reply_c.$(OBJEXT) \
- $(OUTPRE)ccs_request_proc.$(OBJEXT) \
- $(OUTPRE)ccs_server.$(OBJEXT) \
- $(OUTPRE)ccs_win_pipe.$(OBJEXT) \
- $(OUTPRE)ccs_request_s.$(OBJEXT) \
- $(OUTPRE)ccutils.$(OBJEXT) \
- $(OUTPRE)init.$(OBJEXT) \
- $(OUTPRE)opts.$(OBJEXT) \
- $(OUTPRE)secure.$(OBJEXT) \
- $(OUTPRE)tls.$(OBJEXT) \
- $(OUTPRE)util.$(OBJEXT) \
- $(OUTPRE)win-utils.$(OBJEXT) \
- $(OUTPRE)WorkItem.$(OBJEXT) \
- $(OUTPRE)WorkQueue.$(OBJEXT)
-
-##### Options
-
-# Because all the sources are pulled together into the temp directory SRCTMP,
-# the only includes we need are to directories outside of ccapi.
-LOCALINCLUDES = /I..\$(BUILDTOP) /I..\$(BUILDTOP)\include /I..\$(BUILDTOP)\include\krb5 $(KFWINC) \
- -I..\$(BUILDTOP)\util\et /I.
-MIDLI = /I..\$(BUILDTOP)\include
-
-CPPFLAGS = $(CPPFLAGS) /EHsc -D_CRTAPI1=_cdecl -D_CRTAPI2=_cdecl -DWINVER=0x0501 \
--D_WIN32_WINNT=0x0501 -D_CRT_SECURE_NO_WARNINGS
-
-##### Linker
-LINK = link
-LIBS = ..\$(SLIB) rpcrt4.lib advapi32.lib ws2_32.lib user32.lib
-LFLAGS = /nologo $(LOPTS)
-
-
-all:: Makefile copysrc midl $(OUTPRE)ccapiserver.exe finish
-
-ccs_request.h ccs_request_c.c ccs_request_s.c : ccs_request.idl ccs_request.acf
- midl $(MIDL_OPTIMIZATION) $(MIDLI) -oldnames -cpp_cmd $(CC) -cpp_opt "-E" \
- ccs_request.idl
-
-ccs_reply.h ccs_reply_c.c ccs_reply_s.c : ccs_reply.idl ccs_reply.acf
- midl $(MIDL_OPTIMIZATION) $(MIDLI) -oldnames -cpp_cmd $(CC) -cpp_opt "-E" \
- ccs_reply.idl
-
-copysrc :
- echo "Copying all sources needed to build ccapiserver.exe to $(SRCTMP)"
- if NOT exist $(SRCTMP)\nul mkdir $(SRCTMP)
- xcopy /D/Y $(CO)\*.* $(SRCTMP)
- xcopy /D/Y $(COWIN)\*.* $(SRCTMP)
- xcopy /D/Y $(CCUTIL)\*.* $(SRCTMP)
- xcopy /D/Y $(SRVDIR)\*.* $(SRCTMP)
- xcopy /D/Y $(SRVWIN)\*.* $(SRCTMP)
- cd $(SRCTMP)
- if NOT exist $(OUTPRE)\nul mkdir $(OUTPRE)
-
-midl : ccs_request.h ccs_reply.h
-
-$(OUTPRE)ccapiserver.exe: $(OBJS)
- $(LINK) $(LFLAGS) /map:$*.map /out:$@ $(OBJS) $(LIBS) $(conlibsdll) $(conflags)
-
-finish :
- @echo "Finished building ccapiserver.exe"
- cd
-
-clean::
- if exist $(OUTPRE)*.exe del $(OUTPRE)*.exe
- if exist $(OUTPRE)*.obj del $(OUTPRE)*.obj
- if exist $(OUTPRE)*.res del $(OUTPRE)*.res
- if exist $(OUTPRE)*.map del $(OUTPRE)*.map
- if exist $(OUTPRE)*.pdb del $(OUTPRE)*.pdb
- if exist *.err del *.err
- if exist $(SRCTMP) rm -rf $(SRCTMP)
+# makefile: Constructs the Kerberos for Windows CCAPI server.
+
+#BUILDTOP is krb5/src and is relative to krb5/src/ccapi/server/win, for making Makefile.
+BUILDTOP=..\..\..
+CCAPI = $(BUILDTOP)\CCAPI
+CO = $(CCAPI)\common
+COWIN = $(CCAPI)\common\win
+CCUTIL = $(CCAPI)\common\win\OldCC
+SRVDIR = $(CCAPI)\server
+SRVWIN = $(SRVDIR)\win
+POSIX = $(BUILDTOP)\lib\krb5\posix
+SRCTMP = $(SRVWIN)\srctmp
+
+!if defined(KRB5_KFW_COMPILE)
+KFWINC= /I$(BUILDTOP)\..\..\krbcc\include
+!endif
+
+OBJS = $(OUTPRE)cci_array_internal.$(OBJEXT) \
+ $(OUTPRE)cci_cred_union.$(OBJEXT) \
+ $(OUTPRE)cci_debugging.$(OBJEXT) \
+ $(OUTPRE)cci_identifier.$(OBJEXT) \
+ $(OUTPRE)cci_message.$(OBJEXT) \
+ $(OUTPRE)cci_os_debugging.$(OBJEXT) \
+ $(OUTPRE)cci_os_identifier.$(OBJEXT) \
+ $(OUTPRE)ccs_array.$(OBJEXT) \
+ $(OUTPRE)ccs_cache_collection.$(OBJEXT) \
+ $(OUTPRE)ccs_callback.$(OBJEXT) \
+ $(OUTPRE)ccs_ccache.$(OBJEXT) \
+ $(OUTPRE)ccs_ccache_iterator.$(OBJEXT) \
+ $(OUTPRE)ccs_client.$(OBJEXT) \
+ $(OUTPRE)ccs_credentials.$(OBJEXT) \
+ $(OUTPRE)ccs_credentials_iterator.$(OBJEXT) \
+ $(OUTPRE)ccs_list.$(OBJEXT) \
+ $(OUTPRE)ccs_list_internal.$(OBJEXT) \
+ $(OUTPRE)ccs_lock.$(OBJEXT) \
+ $(OUTPRE)ccs_lock_state.$(OBJEXT) \
+ $(OUTPRE)ccs_os_pipe.$(OBJEXT) \
+ $(OUTPRE)ccs_os_server.$(OBJEXT) \
+ $(OUTPRE)ccs_pipe.$(OBJEXT) \
+ $(OUTPRE)ccs_reply_c.$(OBJEXT) \
+ $(OUTPRE)ccs_request_proc.$(OBJEXT) \
+ $(OUTPRE)ccs_server.$(OBJEXT) \
+ $(OUTPRE)ccs_win_pipe.$(OBJEXT) \
+ $(OUTPRE)ccs_request_s.$(OBJEXT) \
+ $(OUTPRE)ccutils.$(OBJEXT) \
+ $(OUTPRE)init.$(OBJEXT) \
+ $(OUTPRE)opts.$(OBJEXT) \
+ $(OUTPRE)secure.$(OBJEXT) \
+ $(OUTPRE)tls.$(OBJEXT) \
+ $(OUTPRE)util.$(OBJEXT) \
+ $(OUTPRE)win-utils.$(OBJEXT) \
+ $(OUTPRE)WorkItem.$(OBJEXT) \
+ $(OUTPRE)WorkQueue.$(OBJEXT)
+
+##### Options
+
+# Because all the sources are pulled together into the temp directory SRCTMP,
+# the only includes we need are to directories outside of ccapi.
+LOCALINCLUDES = /I..\$(BUILDTOP) /I..\$(BUILDTOP)\include /I..\$(BUILDTOP)\include\krb5 $(KFWINC) \
+ -I..\$(BUILDTOP)\util\et /I.
+MIDLI = /I..\$(BUILDTOP)\include
+
+CPPFLAGS = $(CPPFLAGS) /EHsc -D_CRTAPI1=_cdecl -D_CRTAPI2=_cdecl -DWINVER=0x0501 \
+-D_WIN32_WINNT=0x0501 -D_CRT_SECURE_NO_WARNINGS
+
+##### Linker
+LINK = link
+LIBS = ..\$(SLIB) rpcrt4.lib advapi32.lib ws2_32.lib user32.lib
+LFLAGS = /nologo $(LOPTS)
+
+
+all:: Makefile copysrc midl $(OUTPRE)ccapiserver.exe finish
+
+ccs_request.h ccs_request_c.c ccs_request_s.c : ccs_request.idl ccs_request.acf
+ midl $(MIDL_OPTIMIZATION) $(MIDLI) -oldnames -cpp_cmd $(CC) -cpp_opt "-E" \
+ ccs_request.idl
+
+ccs_reply.h ccs_reply_c.c ccs_reply_s.c : ccs_reply.idl ccs_reply.acf
+ midl $(MIDL_OPTIMIZATION) $(MIDLI) -oldnames -cpp_cmd $(CC) -cpp_opt "-E" \
+ ccs_reply.idl
+
+copysrc :
+ echo "Copying all sources needed to build ccapiserver.exe to $(SRCTMP)"
+ if NOT exist $(SRCTMP)\nul mkdir $(SRCTMP)
+ xcopy /D/Y $(CO)\*.* $(SRCTMP)
+ xcopy /D/Y $(COWIN)\*.* $(SRCTMP)
+ xcopy /D/Y $(CCUTIL)\*.* $(SRCTMP)
+ xcopy /D/Y $(SRVDIR)\*.* $(SRCTMP)
+ xcopy /D/Y $(SRVWIN)\*.* $(SRCTMP)
+ cd $(SRCTMP)
+ if NOT exist $(OUTPRE)\nul mkdir $(OUTPRE)
+
+midl : ccs_request.h ccs_reply.h
+
+$(OUTPRE)ccapiserver.exe: $(OBJS)
+ $(LINK) $(LFLAGS) /map:$*.map /out:$@ $(OBJS) $(LIBS) $(conlibsdll) $(conflags)
+
+finish :
+ @echo "Finished building ccapiserver.exe"
+ cd
+
+clean::
+ if exist $(OUTPRE)*.exe del $(OUTPRE)*.exe
+ if exist $(OUTPRE)*.obj del $(OUTPRE)*.obj
+ if exist $(OUTPRE)*.res del $(OUTPRE)*.res
+ if exist $(OUTPRE)*.map del $(OUTPRE)*.map
+ if exist $(OUTPRE)*.pdb del $(OUTPRE)*.pdb
+ if exist *.err del *.err
+ if exist $(SRCTMP) rm -rf $(SRCTMP)
diff --git a/src/ccapi/server/win/Server.sln b/src/ccapi/server/win/Server.sln
index 64cc7f08c9..ea1bd455f6 100644
--- a/src/ccapi/server/win/Server.sln
+++ b/src/ccapi/server/win/Server.sln
@@ -1,20 +1,20 @@
-
-Microsoft Visual Studio Solution File, Format Version 9.00
-# Visual Studio 2005
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Server", "Server.vcproj", "{114DCD80-6D13-4AAA-9510-B51CE6D94C1C}"
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Win32 = Debug|Win32
- Release|Win32 = Release|Win32
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {114DCD80-6D13-4AAA-9510-B51CE6D94C1C}.Debug|Win32.ActiveCfg = Debug|Win32
- {114DCD80-6D13-4AAA-9510-B51CE6D94C1C}.Debug|Win32.Build.0 = Debug|Win32
- {114DCD80-6D13-4AAA-9510-B51CE6D94C1C}.Release|Win32.ActiveCfg = Release|Win32
- {114DCD80-6D13-4AAA-9510-B51CE6D94C1C}.Release|Win32.Build.0 = Release|Win32
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
-EndGlobal
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Server", "Server.vcproj", "{114DCD80-6D13-4AAA-9510-B51CE6D94C1C}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Release|Win32 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {114DCD80-6D13-4AAA-9510-B51CE6D94C1C}.Debug|Win32.ActiveCfg = Debug|Win32
+ {114DCD80-6D13-4AAA-9510-B51CE6D94C1C}.Debug|Win32.Build.0 = Debug|Win32
+ {114DCD80-6D13-4AAA-9510-B51CE6D94C1C}.Release|Win32.ActiveCfg = Release|Win32
+ {114DCD80-6D13-4AAA-9510-B51CE6D94C1C}.Release|Win32.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/src/ccapi/server/win/Server.vcproj b/src/ccapi/server/win/Server.vcproj
index 39db361d8e..626c7a3c78 100644
--- a/src/ccapi/server/win/Server.vcproj
+++ b/src/ccapi/server/win/Server.vcproj
@@ -1,227 +1,227 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="8.00"
- Name="Server"
- ProjectGUID="{114DCD80-6D13-4AAA-9510-B51CE6D94C1C}"
- RootNamespace="Server"
- Keyword="MakeFileProj"
- >
- <Platforms>
- <Platform
- Name="Win32"
- />
- </Platforms>
- <ToolFiles>
- </ToolFiles>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="Debug"
- IntermediateDirectory="Debug"
- ConfigurationType="0"
- >
- <Tool
- Name="VCNMakeTool"
- BuildCommandLine="nmake"
- ReBuildCommandLine="nmake"
- CleanCommandLine="nmake clean"
- Output=""
- PreprocessorDefinitions="WIN32;_DEBUG;"
- IncludeSearchPath=""
- ForcedIncludes=""
- AssemblySearchPath=""
- ForcedUsingAssemblies=""
- CompileAsManaged=""
- />
- </Configuration>
- <Configuration
- Name="Release|Win32"
- OutputDirectory="Release"
- IntermediateDirectory="Release"
- ConfigurationType="0"
- >
- <Tool
- Name="VCNMakeTool"
- BuildCommandLine="nmake"
- ReBuildCommandLine="nmake"
- CleanCommandLine="nmake clean"
- Output=""
- PreprocessorDefinitions="WIN32;NDEBUG;"
- IncludeSearchPath=""
- ForcedIncludes=""
- AssemblySearchPath=""
- ForcedUsingAssemblies=""
- CompileAsManaged=""
- />
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
- >
- <File
- RelativePath="..\..\common\cci_debugging.h"
- >
- </File>
- <File
- RelativePath="..\..\common\cci_os_debugging.h"
- >
- </File>
- <File
- RelativePath="..\..\common\cci_stream.h"
- >
- </File>
- <File
- RelativePath=".\ccs_reply.h"
- >
- </File>
- <File
- RelativePath=".\ccs_request.h"
- >
- </File>
- <File
- RelativePath="..\ccs_server.h"
- >
- </File>
- <File
- RelativePath="..\..\common\win\ccutil\ccutils.h"
- >
- </File>
- <File
- RelativePath="..\..\common\win\ccutil\init.hxx"
- >
- </File>
- <File
- RelativePath="..\..\..\include\k5-platform.h"
- >
- </File>
- <File
- RelativePath="..\..\common\win\ccutil\secure.hxx"
- >
- </File>
- <File
- RelativePath="..\..\common\win\ccutil\util.h"
- >
- </File>
- <File
- RelativePath="..\..\common\win\win-utils.h"
- >
- </File>
- <File
- RelativePath=".\workitem.h"
- >
- </File>
- <File
- RelativePath=".\WorkQueue.h"
- >
- </File>
- </Filter>
- <Filter
- Name="Resource Files"
- Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
- UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
- >
- </Filter>
- <Filter
- Name="Source Files"
- Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
- UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
- >
- <File
- RelativePath="..\..\common\cci_debugging.c"
- >
- </File>
- <File
- RelativePath="..\..\common\win\cci_os_debugging.c"
- >
- </File>
- <File
- RelativePath="..\..\common\cci_stream.c"
- >
- </File>
- <File
- RelativePath="..\ccs_lock.c"
- >
- </File>
- <File
- RelativePath=".\ccs_os_pipe.c"
- >
- </File>
- <File
- RelativePath=".\ccs_os_server.cpp"
- >
- </File>
- <File
- RelativePath="..\..\common\win\ccs_reply.Idl"
- >
- </File>
- <File
- RelativePath=".\ccs_reply_c.c"
- >
- </File>
- <File
- RelativePath=".\ccs_reply_s.c"
- >
- </File>
- <File
- RelativePath="..\..\common\win\ccs_request.idl"
- >
- </File>
- <File
- RelativePath=".\ccs_request_c.c"
- >
- </File>
- <File
- RelativePath=".\ccs_request_proc.c"
- >
- </File>
- <File
- RelativePath=".\ccs_request_s.cpp"
- >
- </File>
- <File
- RelativePath="..\ccs_server.c"
- >
- </File>
- <File
- RelativePath="..\..\common\win\ccutil\ccutils.c"
- >
- </File>
- <File
- RelativePath="..\..\common\win\ccutil\init.cxx"
- >
- </File>
- <File
- RelativePath="..\..\common\win\ccutil\secure.cxx"
- >
- </File>
- <File
- RelativePath="..\..\common\win\ccutil\util.cxx"
- >
- </File>
- <File
- RelativePath="..\..\common\win\win-utils.c"
- >
- </File>
- <File
- RelativePath=".\WorkItem.cpp"
- >
- </File>
- <File
- RelativePath=".\WorkQueue.cpp"
- >
- </File>
- </Filter>
- <File
- RelativePath="..\..\common\win\ccs_reply.Acf"
- >
- </File>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
+<?xml version="1.0" encoding="UTF-8"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="Server"
+ ProjectGUID="{114DCD80-6D13-4AAA-9510-B51CE6D94C1C}"
+ RootNamespace="Server"
+ Keyword="MakeFileProj"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Debug"
+ IntermediateDirectory="Debug"
+ ConfigurationType="0"
+ >
+ <Tool
+ Name="VCNMakeTool"
+ BuildCommandLine="nmake"
+ ReBuildCommandLine="nmake"
+ CleanCommandLine="nmake clean"
+ Output=""
+ PreprocessorDefinitions="WIN32;_DEBUG;"
+ IncludeSearchPath=""
+ ForcedIncludes=""
+ AssemblySearchPath=""
+ ForcedUsingAssemblies=""
+ CompileAsManaged=""
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release"
+ ConfigurationType="0"
+ >
+ <Tool
+ Name="VCNMakeTool"
+ BuildCommandLine="nmake"
+ ReBuildCommandLine="nmake"
+ CleanCommandLine="nmake clean"
+ Output=""
+ PreprocessorDefinitions="WIN32;NDEBUG;"
+ IncludeSearchPath=""
+ ForcedIncludes=""
+ AssemblySearchPath=""
+ ForcedUsingAssemblies=""
+ CompileAsManaged=""
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath="..\..\common\cci_debugging.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\common\cci_os_debugging.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\common\cci_stream.h"
+ >
+ </File>
+ <File
+ RelativePath=".\ccs_reply.h"
+ >
+ </File>
+ <File
+ RelativePath=".\ccs_request.h"
+ >
+ </File>
+ <File
+ RelativePath="..\ccs_server.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\common\win\ccutil\ccutils.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\common\win\ccutil\init.hxx"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\include\k5-platform.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\common\win\ccutil\secure.hxx"
+ >
+ </File>
+ <File
+ RelativePath="..\..\common\win\ccutil\util.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\common\win\win-utils.h"
+ >
+ </File>
+ <File
+ RelativePath=".\workitem.h"
+ >
+ </File>
+ <File
+ RelativePath=".\WorkQueue.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ </Filter>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath="..\..\common\cci_debugging.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\common\win\cci_os_debugging.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\common\cci_stream.c"
+ >
+ </File>
+ <File
+ RelativePath="..\ccs_lock.c"
+ >
+ </File>
+ <File
+ RelativePath=".\ccs_os_pipe.c"
+ >
+ </File>
+ <File
+ RelativePath=".\ccs_os_server.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\common\win\ccs_reply.Idl"
+ >
+ </File>
+ <File
+ RelativePath=".\ccs_reply_c.c"
+ >
+ </File>
+ <File
+ RelativePath=".\ccs_reply_s.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\common\win\ccs_request.idl"
+ >
+ </File>
+ <File
+ RelativePath=".\ccs_request_c.c"
+ >
+ </File>
+ <File
+ RelativePath=".\ccs_request_proc.c"
+ >
+ </File>
+ <File
+ RelativePath=".\ccs_request_s.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\ccs_server.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\common\win\ccutil\ccutils.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\common\win\ccutil\init.cxx"
+ >
+ </File>
+ <File
+ RelativePath="..\..\common\win\ccutil\secure.cxx"
+ >
+ </File>
+ <File
+ RelativePath="..\..\common\win\ccutil\util.cxx"
+ >
+ </File>
+ <File
+ RelativePath="..\..\common\win\win-utils.c"
+ >
+ </File>
+ <File
+ RelativePath=".\WorkItem.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\WorkQueue.cpp"
+ >
+ </File>
+ </Filter>
+ <File
+ RelativePath="..\..\common\win\ccs_reply.Acf"
+ >
+ </File>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/src/ccapi/server/win/WorkItem.cpp b/src/ccapi/server/win/WorkItem.cpp
index 1b1725a8aa..22e209de9f 100644
--- a/src/ccapi/server/win/WorkItem.cpp
+++ b/src/ccapi/server/win/WorkItem.cpp
@@ -1,126 +1,126 @@
-/*
- * $Header$
- *
- * Copyright 2008 Massachusetts Institute of Technology.
- * All Rights Reserved.
- *
- * Export of this software from the United States of America may
- * require a specific license from the United States Government.
- * It is the responsibility of any person or organization contemplating
- * export to obtain such a license before exporting.
- *
- * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
- * distribute this software and its documentation for any purpose and
- * without fee is hereby granted, provided that the above copyright
- * notice appear in all copies and that both that copyright notice and
- * this permission notice appear in supporting documentation, and that
- * the name of M.I.T. not be used in advertising or publicity pertaining
- * to distribution of the software without specific, written prior
- * permission. Furthermore if you modify this software you must label
- * your software as modified software and not distribute it in such a
- * fashion that it might be confused with the original M.I.T. software.
- * M.I.T. makes no representations about the suitability of
- * this software for any purpose. It is provided "as is" without express
- * or implied warranty.
- */
-
-#include <string.h>
-#include "assert.h"
-
-#pragma warning (disable : 4996)
-
-#include "win-utils.h"
-#include "WorkItem.h"
-
-extern "C" {
-#include "cci_debugging.h"
- }
-
-// CountedBuffer makes a copy of the data. Each CountedBuffer must be deleted.
-
-void deleteBuffer(char** buf) {
- if (*buf) {
- delete [](*buf);
- *buf = NULL;
- }
- }
-
-// WorkItem contains a CountedBuffer which must be deleted,
-// so each WorkItem must be deleted.
-WorkItem::WorkItem(k5_ipc_stream buf, WIN_PIPE* pipe, const long type, const long sst)
-: _buf(buf), _rpcmsg(type), _pipe(pipe), _sst(sst) { }
-
-WorkItem::WorkItem(const WorkItem& item) : _buf(NULL), _rpcmsg(0), _pipe(NULL), _sst(0) {
-
- k5_ipc_stream _buf = NULL;
- krb5int_ipc_stream_new(&_buf);
- krb5int_ipc_stream_write(_buf,
- krb5int_ipc_stream_data(item.payload()),
- krb5int_ipc_stream_size(item.payload()) );
- WorkItem(_buf, item._pipe, item._rpcmsg, item._sst);
- }
-
-WorkItem::WorkItem() : _buf(NULL), _rpcmsg(CCMSG_INVALID), _pipe(NULL), _sst(0) { }
-
-WorkItem::~WorkItem() {
- if (_buf) krb5int_ipc_stream_release(_buf);
- if (_pipe) ccs_win_pipe_release(_pipe);
- }
-
-const k5_ipc_stream WorkItem::take_payload() {
- k5_ipc_stream temp = payload();
- _buf = NULL;
- return temp;
- }
-
-WIN_PIPE* WorkItem::take_pipe() {
- WIN_PIPE* temp = pipe();
- _pipe = NULL;
- return temp;
- }
-
-WorkList::WorkList() {
- assert(InitializeCriticalSectionAndSpinCount(&cs, 0x80000400));
- }
-
-WorkList::~WorkList() {
- // Delete any WorkItems in the queue:
- WorkItem* item;
- cci_debug_printf("%s", __FUNCTION__);
- char buf[2048];
- char* pbuf = (char*)buf;
- while (remove(&item)) {
- cci_debug_printf("WorkList::~WorkList() deleting %s", item->print(pbuf));
- delete item;
- }
-
- DeleteCriticalSection(&cs);
- }
-
-char* WorkItem::print(char* buf) {
- sprintf(buf, "WorkItem msg#:%d sst:%ld pipe:<%s>/0x%X", _rpcmsg, _sst,
- ccs_win_pipe_getUuid(_pipe), ccs_win_pipe_getHandle(_pipe));
- return buf;
- }
-
-int WorkList::add(WorkItem* item) {
- EnterCriticalSection(&cs);
- wl.push_front(item);
- LeaveCriticalSection(&cs);
- return 1;
- }
-
-int WorkList::remove(WorkItem** item) {
- bool bEmpty;
-
- bEmpty = wl.empty() & 1;
-
- if (!bEmpty) {
- EnterCriticalSection(&cs);
- *item = wl.back();
- wl.pop_back();
- LeaveCriticalSection(&cs);
- }
-
- return !bEmpty;
- }
+/*
+ * $Header$
+ *
+ * Copyright 2008 Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ */
+
+#include <string.h>
+#include "assert.h"
+
+#pragma warning (disable : 4996)
+
+#include "win-utils.h"
+#include "WorkItem.h"
+
+extern "C" {
+#include "cci_debugging.h"
+ }
+
+// CountedBuffer makes a copy of the data. Each CountedBuffer must be deleted.
+
+void deleteBuffer(char** buf) {
+ if (*buf) {
+ delete [](*buf);
+ *buf = NULL;
+ }
+ }
+
+// WorkItem contains a CountedBuffer which must be deleted,
+// so each WorkItem must be deleted.
+WorkItem::WorkItem(k5_ipc_stream buf, WIN_PIPE* pipe, const long type, const long sst)
+: _buf(buf), _rpcmsg(type), _pipe(pipe), _sst(sst) { }
+
+WorkItem::WorkItem(const WorkItem& item) : _buf(NULL), _rpcmsg(0), _pipe(NULL), _sst(0) {
+
+ k5_ipc_stream _buf = NULL;
+ krb5int_ipc_stream_new(&_buf);
+ krb5int_ipc_stream_write(_buf,
+ krb5int_ipc_stream_data(item.payload()),
+ krb5int_ipc_stream_size(item.payload()) );
+ WorkItem(_buf, item._pipe, item._rpcmsg, item._sst);
+ }
+
+WorkItem::WorkItem() : _buf(NULL), _rpcmsg(CCMSG_INVALID), _pipe(NULL), _sst(0) { }
+
+WorkItem::~WorkItem() {
+ if (_buf) krb5int_ipc_stream_release(_buf);
+ if (_pipe) ccs_win_pipe_release(_pipe);
+ }
+
+const k5_ipc_stream WorkItem::take_payload() {
+ k5_ipc_stream temp = payload();
+ _buf = NULL;
+ return temp;
+ }
+
+WIN_PIPE* WorkItem::take_pipe() {
+ WIN_PIPE* temp = pipe();
+ _pipe = NULL;
+ return temp;
+ }
+
+WorkList::WorkList() {
+ assert(InitializeCriticalSectionAndSpinCount(&cs, 0x80000400));
+ }
+
+WorkList::~WorkList() {
+ // Delete any WorkItems in the queue:
+ WorkItem* item;
+ cci_debug_printf("%s", __FUNCTION__);
+ char buf[2048];
+ char* pbuf = (char*)buf;
+ while (remove(&item)) {
+ cci_debug_printf("WorkList::~WorkList() deleting %s", item->print(pbuf));
+ delete item;
+ }
+
+ DeleteCriticalSection(&cs);
+ }
+
+char* WorkItem::print(char* buf) {
+ sprintf(buf, "WorkItem msg#:%d sst:%ld pipe:<%s>/0x%X", _rpcmsg, _sst,
+ ccs_win_pipe_getUuid(_pipe), ccs_win_pipe_getHandle(_pipe));
+ return buf;
+ }
+
+int WorkList::add(WorkItem* item) {
+ EnterCriticalSection(&cs);
+ wl.push_front(item);
+ LeaveCriticalSection(&cs);
+ return 1;
+ }
+
+int WorkList::remove(WorkItem** item) {
+ bool bEmpty;
+
+ bEmpty = wl.empty() & 1;
+
+ if (!bEmpty) {
+ EnterCriticalSection(&cs);
+ *item = wl.back();
+ wl.pop_back();
+ LeaveCriticalSection(&cs);
+ }
+
+ return !bEmpty;
+ }
diff --git a/src/ccapi/server/win/WorkQueue.cpp b/src/ccapi/server/win/WorkQueue.cpp
index f16ad117e4..cc12054a10 100644
--- a/src/ccapi/server/win/WorkQueue.cpp
+++ b/src/ccapi/server/win/WorkQueue.cpp
@@ -1,61 +1,61 @@
-/*
- * $Header$
- *
- * Copyright 2008 Massachusetts Institute of Technology.
- * All Rights Reserved.
- *
- * Export of this software from the United States of America may
- * require a specific license from the United States Government.
- * It is the responsibility of any person or organization contemplating
- * export to obtain such a license before exporting.
- *
- * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
- * distribute this software and its documentation for any purpose and
- * without fee is hereby granted, provided that the above copyright
- * notice appear in all copies and that both that copyright notice and
- * this permission notice appear in supporting documentation, and that
- * the name of M.I.T. not be used in advertising or publicity pertaining
- * to distribution of the software without specific, written prior
- * permission. Furthermore if you modify this software you must label
- * your software as modified software and not distribute it in such a
- * fashion that it might be confused with the original M.I.T. software.
- * M.I.T. makes no representations about the suitability of
- * this software for any purpose. It is provided "as is" without express
- * or implied warranty.
- */
-
-extern "C" {
- #include "cci_debugging.h"
- }
-
-#include "WorkItem.h"
-
-WorkList worklist;
-
-/* C interfaces: */
-EXTERN_C bool worklist_isEmpty() {
- return worklist.isEmpty();
- }
-
-EXTERN_C int worklist_add( const long rpcmsg,
- const ccs_pipe_t pipe,
- const k5_ipc_stream stream,
- const time_t serverStartTime) {
- return worklist.add(new WorkItem(stream, pipe, rpcmsg, serverStartTime) );
- }
-
-EXTERN_C int worklist_remove(long* rpcmsg,
- ccs_pipe_t* pipe,
- k5_ipc_stream* stream,
- time_t* sst) {
- WorkItem* item = NULL;
- cc_int32 err = worklist.remove(&item);
-
- *rpcmsg = item->type();
- *pipe = item->take_pipe();
- *stream = item->take_payload();
- *sst = item->sst();
- delete item;
- return err;
- }
-
+/*
+ * $Header$
+ *
+ * Copyright 2008 Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ */
+
+extern "C" {
+ #include "cci_debugging.h"
+ }
+
+#include "WorkItem.h"
+
+WorkList worklist;
+
+/* C interfaces: */
+EXTERN_C bool worklist_isEmpty() {
+ return worklist.isEmpty();
+ }
+
+EXTERN_C int worklist_add( const long rpcmsg,
+ const ccs_pipe_t pipe,
+ const k5_ipc_stream stream,
+ const time_t serverStartTime) {
+ return worklist.add(new WorkItem(stream, pipe, rpcmsg, serverStartTime) );
+ }
+
+EXTERN_C int worklist_remove(long* rpcmsg,
+ ccs_pipe_t* pipe,
+ k5_ipc_stream* stream,
+ time_t* sst) {
+ WorkItem* item = NULL;
+ cc_int32 err = worklist.remove(&item);
+
+ *rpcmsg = item->type();
+ *pipe = item->take_pipe();
+ *stream = item->take_payload();
+ *sst = item->sst();
+ delete item;
+ return err;
+ }
+
diff --git a/src/ccapi/server/win/ccs_os_server.cpp b/src/ccapi/server/win/ccs_os_server.cpp
index b22fdfa9b9..e0695876d6 100644
--- a/src/ccapi/server/win/ccs_os_server.cpp
+++ b/src/ccapi/server/win/ccs_os_server.cpp
@@ -1,963 +1,963 @@
-/*
- * $Header$
- *
- * Copyright 2008 Massachusetts Institute of Technology.
- * All Rights Reserved.
- *
- * Export of this software from the United States of America may
- * require a specific license from the United States Government.
- * It is the responsibility of any person or organization contemplating
- * export to obtain such a license before exporting.
- *
- * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
- * distribute this software and its documentation for any purpose and
- * without fee is hereby granted, provided that the above copyright
- * notice appear in all copies and that both that copyright notice and
- * this permission notice appear in supporting documentation, and that
- * the name of M.I.T. not be used in advertising or publicity pertaining
- * to distribution of the software without specific, written prior
- * permission. Furthermore if you modify this software you must label
- * your software as modified software and not distribute it in such a
- * fashion that it might be confused with the original M.I.T. software.
- * M.I.T. makes no representations about the suitability of
- * this software for any purpose. It is provided "as is" without express
- * or implied warranty.
- */
-
-#include "process.h"
-#include "windows.h"
-
-extern "C" {
-#include "ccs_common.h"
-#include "ccs_os_notify.h"
-#include "ccs_os_server.h"
-#include "ccs_reply.h"
-#include "ccs_request.h"
-#include "win-utils.h"
-#include "ccutils.h"
- }
-
-#include "WorkQueue.h"
-#include "util.h"
-#include "opts.hxx"
-#include "init.hxx"
-
-#pragma warning (disable : 4996)
-
-BOOL bListen = TRUE; /* Why aren't bool and true defined? */
-const char* sessID = NULL; /* The logon session we are running on behalf of. */
-time_t _sst = 0;
-unsigned char* pszNetworkAddress = NULL;
-unsigned char* pszStringBinding = NULL;
-BOOL bRpcHandleInited = FALSE;
-_RPC_ASYNC_STATE* rpcState = NULL;
-
-/* Thread procedures can take only one void* argument. We put all the args we want
- to pass into this struct and then pass a pointer to the struct: */
-struct RpcRcvArgs {
- char* networkAddress;
- unsigned char* protocolSequence;
- unsigned char* sessID; /* Used for this server's endpoint */
- unsigned char* uuid; /* Used for client's UUID */
- ParseOpts::Opts* opts;
- RPC_STATUS status;
- } rpcargs = { NULL, /* pszNetworkAddress */
- (unsigned char*)"ncalrpc", /* pszProtocolSequence */
- NULL, /* sessID placeholder */
- NULL, /* uuid placeholder */
- NULL }; /* Opts placeholder */
-
-/* Command line format:
- argv[0] Program name
- argv[1] session ID to use
- argv[2] "D" Debug: go into infinite loop in ccs_os_server_initialize so process
- can be attached in debugger.
- Any other value: continue
- */
-#define N_FIXED_ARGS 3
-#define SERVER_REPLY_RPC_HANDLE ccs_reply_IfHandle
-
-/* Forward declarations: */
-void receiveLoop(void* rpcargs);
-void connectionListener(void* rpcargs);
-void Usage(const char* argv0);
-void printError(TCHAR* msg);
-void setMySST() {_sst = time(&_sst);}
-time_t getMySST() {return _sst;}
-RPC_STATUS send_connection_reply(ccs_pipe_t in_pipe);
-void RPC_ENTRY clientListener( _RPC_ASYNC_STATE*,
- void* Context,
- RPC_ASYNC_EVENT Event);
-RPC_STATUS RPC_ENTRY sec_callback( IN RPC_IF_ID *Interface,
- IN void *Context);
-RPC_STATUS send_init(char* clientUUID);
-//DWORD alloc_name(LPSTR* pname, LPSTR postfix);
-
-
-/* The layout of the rest of this module:
-
- The four entrypoints defined in ccs_os_server.h:
- ccs_os_server_initialize
- cc_int32 ccs_os_server_cleanup
- cc_int32 ccs_os_server_listen_loop
- cc_int32 ccs_os_server_send_reply
-
- Other routines needed by those four.
- */
-
-/* ------------------------------------------------------------------------ */
-
-cc_int32 ccs_os_server_initialize (int argc, const char *argv[]) {
- cc_int32 err = 0;
- ParseOpts::Opts opts = { 0 };
- ParseOpts PO;
- BOOL bAdjustedShutdown = FALSE;
- HMODULE hKernel32 = GetModuleHandle("kernel32");
-
- if (!err) {
- sessID = argv[1];
- setMySST();
-
- opts.cMinCalls = 1;
- opts.cMaxCalls = 20;
- opts.fDontWait = TRUE;
-
-#ifdef CCAPI_TEST_OPTIONS
- PO.SetValidOpts("kemnfubc");
-#else
- PO.SetValidOpts("kc");
-#endif
-
- PO.Parse(opts, argc, (char**)argv);
-
-// while(*argv[2] == 'D') {} /* Hang here to attach process with debugger. */
-
- if (hKernel32) {
- typedef BOOL (WINAPI *FP_SetProcessShutdownParameters)(DWORD, DWORD);
- FP_SetProcessShutdownParameters pSetProcessShutdownParameters =
- (FP_SetProcessShutdownParameters)
- GetProcAddress(hKernel32, "SetProcessShutdownParameters");
- if (pSetProcessShutdownParameters) {
- bAdjustedShutdown = pSetProcessShutdownParameters(100, 0);
- }
- }
- cci_debug_printf("%s Shutdown Parameters",
- bAdjustedShutdown ? "Adjusted" : "Did not adjust");
-
- err = Init::Initialize();
- }
-
-// if (!err) {
-// if (opts.bShutdown) {
-// status = shutdown_server(opts.pszEndpoint);
-// }
-// }
-// else {
-// status = startup_server(opts);
-// }
-
- if (err) {
- Init::Cleanup();
- fprintf( stderr, "An error occured while %s the server (%u)\n",
- opts.bShutdown ? "shutting down" : "starting/running",
- err);
- exit(cci_check_error (err));
- }
-
- return cci_check_error (err);
- }
-
-/* ------------------------------------------------------------------------ */
-
-cc_int32 ccs_os_server_cleanup (int argc, const char *argv[]) {
- cc_int32 err = 0;
-
- cci_debug_printf("%s for user <%s> shutting down.", argv[0], argv[1]);
-
- return cci_check_error (err);
- }
-
-/* ------------------------------------------------------------------------ */
-
-/* This function takes work items off the work queue and executes them.
- * This is the one and only place where the multi-threaded Windows code
- * calls into the single-threaded common code.
- *
- * The actual 'listening' for requests from clients happens after receiveloop
- * establishes the RPC endpoint the clients will connect to and the RPC procedures
- * put the work items into the work queue.
- */
-cc_int32 ccs_os_server_listen_loop (int argc, const char *argv[]) {
- cc_int32 err = 0;
- uintptr_t threadStatus;
- unsigned int loopCounter = 0;
-
- ParseOpts::Opts opts = { 0 };
- ParseOpts PO;
-
- opts.cMinCalls = 1;
- opts.cMaxCalls = 20;
- opts.fDontWait = TRUE;
-
-#ifdef CCAPI_TEST_OPTIONS
- PO.SetValidOpts("kemnfubc");
-#else
- PO.SetValidOpts("kc");
-#endif
- PO.Parse(opts, argc, (char**)argv);
-
-
- //++ debug stuff
- #define INFO_BUFFER_SIZE 32767
- TCHAR infoBuf[INFO_BUFFER_SIZE];
- DWORD bufCharCount = INFO_BUFFER_SIZE;
- // Get and display the user name.
- bufCharCount = INFO_BUFFER_SIZE;
- if( !GetUserName( infoBuf, &bufCharCount ) ) printError( TEXT("GetUserName") );
- //--
-
- /* Sending the reply from within the request RPC handler doesn't seem to work.
- So we listen for requests in a separate thread and put the requests in a
- queue. */
- rpcargs.sessID = (unsigned char*)sessID;
- rpcargs.opts = &opts;
- threadStatus = _beginthread(receiveLoop, 0, (void*)&rpcargs);
-
- /* We handle the queue entries here. Work loop: */
- while (TRUE) {
- loopCounter++;
- if (worklist_isEmpty() & 1) {
- SleepEx(1000, TRUE);
- }
- else if (TRUE) { // Take next WorkItem from the queue:
- k5_ipc_stream buf = NULL;
- long rpcmsg = CCMSG_INVALID;
- time_t serverStartTime = 0xDEADDEAD;
- RPC_STATUS status = 0;
- char* uuid = NULL;
- k5_ipc_stream stream = NULL;
- ccs_pipe_t pipe = NULL;
- ccs_pipe_t pipe2 = NULL;
-
- if (worklist_remove(&rpcmsg, &pipe, &buf, &serverStartTime)) {
- uuid = ccs_win_pipe_getUuid(pipe);
-#if 0
- cci_debug_printf("%s: processing WorkItem msg:%ld pipeUUID:<%s> pipeHandle:0x%X SST:%ld",
- __FUNCTION__, rpcmsg, uuid, ccs_win_pipe_getHandle(pipe), serverStartTime);
-#endif
- if (serverStartTime <= getMySST()) {
- switch (rpcmsg) {
- case CCMSG_CONNECT: {
- cci_debug_printf(" Processing CONNECT");
- rpcargs.uuid = (unsigned char*)uuid;
-
- // Even if a disconnect message is received before this code finishes,
- // it won't be dequeued and processed until after this code finishes.
- // So we can add the client after starting the connection listener.
- connectionListener((void*)&rpcargs);
- status = rpcargs.status;
-
- if (!status) {
- status = ccs_server_add_client(pipe);
- }
- if (!status) {status = send_connection_reply(pipe);}
- break;
- }
- case CCMSG_DISCONNECT: {
- cci_debug_printf(" Processing DISCONNECT");
- if (!status) {
- status = ccs_server_remove_client(pipe);
- }
- break;
- }
- case CCMSG_REQUEST:
- cci_debug_printf(" Processing REQUEST");
- ccs_pipe_copy(&pipe2, pipe);
- // Dispatch message here, setting both pipes to the client UUID:
- err = ccs_server_handle_request (pipe, pipe2, buf);
- break;
- case CCMSG_PING:
- cci_debug_printf(" Processing PING");
- err = krb5int_ipc_stream_new (&stream);
- err = krb5int_ipc_stream_write(stream, "This is a test of the emergency broadcasting system", 52);
- err = ccs_os_server_send_reply(pipe, stream);
- break;
- default:
- cci_debug_printf("Huh? Received invalid message type %ld from UUID:<%s>",
- rpcmsg, uuid);
- break;
- }
- if (buf) krb5int_ipc_stream_release(buf);
- /* Don't free uuid, which was allocated here. A pointer to it is in the
- rpcargs struct which was passed to connectionListener which will be
- received by ccapi_listen when the client exits. ccapi_listen needs
- the uuid to know which client to disconnect.
- */
- }
- // Server's start time is different from what the client thinks.
- // That means the server has rebooted since the client connected.
- else {
- cci_debug_printf("Whoops! Server has rebooted since client established connection.");
- }
- }
- else {cci_debug_printf("Huh? Queue not empty but no item to remove.");}
- }
- }
-
- return cci_check_error (err);
- }
-
-/* ------------------------------------------------------------------------ */
-
-cc_int32 ccs_os_server_send_reply (ccs_pipe_t in_pipe,
- k5_ipc_stream in_reply_stream) {
-
- /* ccs_pipe_t in_reply_pipe is a char* reply endpoint.
- k5_ipc_stream in_reply_stream is the data to be sent.
- */
-
- cc_int32 err = 0;
- char* uuid = ccs_win_pipe_getUuid(in_pipe);
- HANDLE h = ccs_win_pipe_getHandle(in_pipe);
-
- if (!err) {
- err = send_init(uuid); // Sets RPC handle to be used.
- }
-
- if (!err) {
- RpcTryExcept {
- long status;
- ccs_rpc_request_reply( // make call with user message
- CCMSG_REQUEST_REPLY, /* Message type */
- (unsigned char*)&h, /* client's tspdata* */
- (unsigned char*)uuid,
- getMySST(),
- krb5int_ipc_stream_size(in_reply_stream), /* Length of buffer */
- (const unsigned char*)krb5int_ipc_stream_data(in_reply_stream), /* Data buffer */
- &status ); /* Return code */
- }
- RpcExcept(1) {
- cci_check_error(RpcExceptionCode());
- }
- RpcEndExcept
- }
-
- /* The calls to the remote procedures are complete. */
- /* Free whatever we allocated: */
- err = RpcBindingFree(&SERVER_REPLY_RPC_HANDLE);
-
- return cci_check_error (err);
- }
-
-
-/* Windows-specific routines: */
-
-void Usage(const char* argv0) {
- printf("Usage:\n");
- printf("%s [m maxcalls] [n mincalls] [f dontwait] [h|?]]\n", argv0);
- printf(" CCAPI server process.\n");
- printf(" h|? whow usage message. <\n");
- }
-
-/* ------------------------------------------------------------------------ */
-/* The receive thread repeatedly issues RpcServerListen.
- When a message arrives, it is handled in the RPC procedure.
- */
-void receiveLoop(void* rpcargs) {
-
- struct RpcRcvArgs* rcvargs = (struct RpcRcvArgs*)rpcargs;
- RPC_STATUS status = FALSE;
- unsigned char* pszSecurity = NULL;
- LPSTR endpoint = NULL;
- LPSTR event_name = NULL;
- PSECURITY_DESCRIPTOR psd = NULL;
- HANDLE hEvent = 0;
- Init::InitInfo info;
-
- cci_debug_printf("THREAD BEGIN: %s", __FUNCTION__);
-
- status = Init::Info(info);
-
- /* Build complete RPC endpoint using previous CCAPI implementation: */
- if (!status) {
- if (!rcvargs->opts->pszEndpoint) {
- if (!status) {
- status = alloc_name(&endpoint, "ep", isNT());
- }
-
- if (!status) {
- status = alloc_name(&event_name, "startup", isNT());
- }
-
- if (!status) {
- hEvent = OpenEvent(EVENT_MODIFY_STATE, FALSE, event_name);
- // We ignore any error opening the event because we do not know who started us.
- // [Comment paraphrased from previous implementation, whence it was copied.]
- }
- }
- else {
- endpoint = rcvargs->opts->pszEndpoint;
- }
- }
-
- cci_debug_printf("%s Registering endpoint %s", __FUNCTION__, endpoint);
-
- if (!status && isNT()) {
- status = alloc_own_security_descriptor_NT(&psd);
- }
-
- if (!status) {
- status = RpcServerUseProtseqEp(rcvargs->protocolSequence,
- rcvargs->opts->cMaxCalls,
- (RPC_CSTR)endpoint,
- rcvargs->opts->bDontProtect ? 0 : psd); // SD
- }
-
- if (!status) {
- status = RpcServerRegisterAuthInfo(0, // server principal
- RPC_C_AUTHN_WINNT,
- 0,
- 0);
- }
-
- while (bListen && !status) {
- cci_debug_printf("%s is listening ...", __FUNCTION__);
-
- if (!info.isNT) {
- status = RpcServerRegisterIf(ccs_request_ServerIfHandle, // interface
- NULL, // MgrTypeUuid
- NULL); // MgrEpv; null means use default
- }
- else {
- status = info.fRpcServerRegisterIfEx(ccs_request_ServerIfHandle, // interface
- NULL, // MgrTypeUuid
- NULL, // MgrEpv; 0 means default
- RPC_IF_ALLOW_SECURE_ONLY,
- rcvargs->opts->cMaxCalls,
- rcvargs->opts->bSecCallback ?
- (RPC_IF_CALLBACK_FN*)sec_callback : 0 );
- }
-
- if (!status) {
- status = RpcServerListen(rcvargs->opts->cMinCalls,
- rcvargs->opts->cMaxCalls,
- rcvargs->opts->fDontWait);
- }
-
- if (!status) {
- if (rcvargs->opts->fDontWait) {
- if (hEvent) SetEvent(hEvent); // Ignore any error -- SetEvent is an optimization.
- status = RpcMgmtWaitServerListen();
- }
- }
- }
-
- if (status) { // Cleanup in case of errors:
- if (hEvent) CloseHandle(hEvent);
- free_alloc_p(&event_name);
- free_alloc_p(&psd);
- if (endpoint && (endpoint != rcvargs->opts->pszEndpoint))
- free_alloc_p(&endpoint);
- }
-
- _endthread();
- } // End receiveLoop
-
-
-#if 0
-
- return status;
-}
-#endif
-
-
-
-/* ------------------------------------------------------------------------ */
-/* The connection listener thread waits forever for a call to the CCAPI_CLIENT_<UUID>
- endpoint, ccapi_listen function to complete. If the call completes or gets an
- RPC exception, it means the client has disappeared.
-
- A separate connectionListener is started for each client that has connected to the server.
- */
-
-void connectionListener(void* rpcargs) {
-
- struct RpcRcvArgs* rcvargs = (struct RpcRcvArgs*)rpcargs;
- RPC_STATUS status = FALSE;
- char* endpoint;
- unsigned char* pszOptions = NULL;
- unsigned char * pszUuid = NULL;
-
- endpoint = clientEndpoint((char*)rcvargs->uuid);
- rpcState = (RPC_ASYNC_STATE*)malloc(sizeof(RPC_ASYNC_STATE));
- status = RpcAsyncInitializeHandle(rpcState, sizeof(RPC_ASYNC_STATE));
- cci_debug_printf("");
- cci_debug_printf("%s About to LISTEN to <%s>", __FUNCTION__, endpoint);
-
- rpcState->UserInfo = rcvargs->uuid;
- rpcState->NotificationType = RpcNotificationTypeApc;
- rpcState->u.APC.NotificationRoutine = clientListener;
- rpcState->u.APC.hThread = 0;
-
- /* [If in use] Free previous binding: */
- if (bRpcHandleInited) {
- // Free previous binding (could have been used to call ccapi_listen
- // in a different client thread).
- // Don't check result or update status.
- RpcStringFree(&pszStringBinding);
- RpcBindingFree(&SERVER_REPLY_RPC_HANDLE);
- bRpcHandleInited = FALSE;
- }
-
- /* Set up binding to the client's endpoint: */
- if (!status) {
- status = RpcStringBindingCompose(
- pszUuid,
- pszProtocolSequence,
- pszNetworkAddress,
- (RPC_CSTR)endpoint,
- pszOptions,
- &pszStringBinding);
- }
-
- /* Set the binding handle that will be used to bind to the server. */
- if (!status) {
- status = RpcBindingFromStringBinding(pszStringBinding, &SERVER_REPLY_RPC_HANDLE);
- }
- if (!status) {bRpcHandleInited = TRUE;}
-
- RpcTryExcept {
- cci_debug_printf(" Calling remote procedure ccapi_listen");
- ccapi_listen(rpcState, SERVER_REPLY_RPC_HANDLE, CCMSG_LISTEN, &status);
- /* Asynchronous call will return immediately. */
- }
- RpcExcept(1) {
- status = cci_check_error(RpcExceptionCode());
- }
- RpcEndExcept
-
- rcvargs->status = status;
- } // End connectionListener
-
-
-void RPC_ENTRY clientListener(
- _RPC_ASYNC_STATE* pAsync,
- void* Context,
- RPC_ASYNC_EVENT Event
- ) {
-
- ccs_pipe_t pipe = ccs_win_pipe_new((char*)pAsync->UserInfo, NULL);
-
- cci_debug_printf("%s(0x%X, ...) async routine for <0x%X:%s>!",
- __FUNCTION__, pAsync, pAsync->UserInfo, pAsync->UserInfo);
-
- worklist_add( CCMSG_DISCONNECT,
- pipe,
- NULL, /* No payload with connect request */
- (const time_t)0 ); /* No server session number with connect request */
- }
-
-
-void printError( TCHAR* msg ) {
- DWORD eNum;
- TCHAR sysMsg[256];
- TCHAR* p;
-
- eNum = GetLastError( );
- FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM |
- FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL, eNum,
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
- sysMsg, 256, NULL );
-
- // Trim the end of the line and terminate it with a null
- p = sysMsg;
- while( ( *p > 31 ) || ( *p == 9 ) )
- ++p;
- do { *p-- = 0; } while( ( p >= sysMsg ) &&
- ( ( *p == '.' ) || ( *p < 33 ) ) );
-
- // Display the message
- cci_debug_printf("%s failed with error %d (%s)", msg, eNum, sysMsg);
- }
-
-
-RPC_STATUS send_init(char* clientUUID) {
- RPC_STATUS status;
- unsigned char * pszUuid = NULL;
- unsigned char * pszOptions = NULL;
-
- /* Use a convenience function to concatenate the elements of */
- /* the string binding into the proper sequence. */
- status = RpcStringBindingCompose(pszUuid,
- pszProtocolSequence,
- pszNetworkAddress,
- (unsigned char*)clientEndpoint(clientUUID),
- pszOptions,
- &pszStringBinding);
- if (status) {return (status);}
-
- /* Set the binding handle that will be used to bind to the RPC server [the 'client']. */
- status = RpcBindingFromStringBinding(pszStringBinding, &SERVER_REPLY_RPC_HANDLE);
- return (status);
- }
-
-RPC_STATUS send_finish() {
- RPC_STATUS status;
- /* Can't shut down client -- it runs listen function which */
- /* server uses to detect the client going away. */
-
- /* The calls to the remote procedures are complete. */
- /* Free the string and the binding handle */
- status = RpcStringFree(&pszStringBinding); // remote calls done; unbind
- if (status) {return (status);}
-
- status = RpcBindingFree(&SERVER_REPLY_RPC_HANDLE); // remote calls done; unbind
-
- return (status);
- }
-
-RPC_STATUS send_connection_reply(ccs_pipe_t in_pipe) {
- char* uuid = ccs_win_pipe_getUuid (in_pipe);
- HANDLE h = ccs_win_pipe_getHandle(in_pipe);
- RPC_STATUS status = send_init(uuid);
-
- RpcTryExcept {
- ccs_rpc_connect_reply( // make call with user message
- CCMSG_CONNECT_REPLY, /* Message type */
- (unsigned char*)&h, /* client's tspdata* */
- (unsigned char*)uuid,
- getMySST(), /* Server's session number = it's start time */
- &status ); /* Return code */
- }
- RpcExcept(1) {
- cci_check_error(RpcExceptionCode());
- }
- RpcEndExcept
-
- status = send_finish();
- return (status);
- }
-
-#if 0
-DWORD alloc_name(LPSTR* pname, LPSTR postfix) {
- DWORD len = strlen(sessID) + 1 + strlen(postfix) + 1;
-
- *pname = (LPSTR)malloc(len);
- if (!*pname) return GetLastError();
- _snprintf(*pname, len, "%s.%s", sessID, postfix);
- return 0;
- }
-#endif
-
-RPC_STATUS GetPeerName( RPC_BINDING_HANDLE hClient,
- LPTSTR pszClientName,
- int iMaxLen) {
- RPC_STATUS Status = RPC_S_OK;
- RPC_BINDING_HANDLE hServer = NULL;
- PTBYTE pszStringBinding = NULL;
- PTBYTE pszClientNetAddr = NULL;
- PTBYTE pszProtSequence = NULL;
-
- memset(pszClientName, 0, iMaxLen * sizeof(TCHAR));
-
- __try {
- // Create a partially bound server handle from the client handle.
- Status = RpcBindingServerFromClient (hClient, &hServer);
- if (Status != RPC_S_OK) __leave;
-
- // Get the partially bound server string binding and parse it.
- Status = RpcBindingToStringBinding (hServer,
- &pszStringBinding);
- if (Status != RPC_S_OK) __leave;
-
- // String binding only contains protocol sequence and client
- // address, and is not currently implemented for named pipes.
- Status = RpcStringBindingParse (pszStringBinding, NULL,
- &pszProtSequence, &pszClientNetAddr,
- NULL, NULL);
- if (Status != RPC_S_OK)
- __leave;
- int iLen = lstrlen(pszClientName) + 1;
- if (iMaxLen < iLen)
- Status = RPC_S_BUFFER_TOO_SMALL;
- lstrcpyn(pszClientName, (LPCTSTR)pszClientNetAddr, iMaxLen);
- }
- __finally {
- if (pszProtSequence)
- RpcStringFree (&pszProtSequence);
-
- if (pszClientNetAddr)
- RpcStringFree (&pszClientNetAddr);
-
- if (pszStringBinding)
- RpcStringFree (&pszStringBinding);
-
- if (hServer)
- RpcBindingFree (&hServer);
- }
- return Status;
-}
-
-struct client_auth_info {
- RPC_AUTHZ_HANDLE authz_handle;
- unsigned char* server_principal; // need to RpcFreeString this
- ULONG authn_level;
- ULONG authn_svc;
- ULONG authz_svc;
-};
-
-RPC_STATUS
-GetClientId(
- RPC_BINDING_HANDLE hClient,
- char* client_id,
- int max_len,
- client_auth_info* info
- )
-{
- RPC_AUTHZ_HANDLE authz_handle = 0;
- unsigned char* server_principal = 0;
- ULONG authn_level = 0;
- ULONG authn_svc = 0;
- ULONG authz_svc = 0;
- RPC_STATUS status = 0;
-
- memset(client_id, 0, max_len);
-
- if (info) {
- memset(info, 0, sizeof(client_auth_info));
- }
-
- status = RpcBindingInqAuthClient(hClient, &authz_handle,
- info ? &server_principal : 0,
- &authn_level, &authn_svc, &authz_svc);
- if (status == RPC_S_OK)
- {
- if (info) {
- info->server_principal = server_principal;
- info->authz_handle = authz_handle;
- info->authn_level = authn_level;
- info->authn_svc = authn_svc;
- info->authz_svc = authz_svc;
- }
-
- if (authn_svc == RPC_C_AUTHN_WINNT) {
- WCHAR* username = (WCHAR*)authz_handle;
- int len = lstrlenW(username) + 1;
- if (max_len < len)
- status = RPC_S_BUFFER_TOO_SMALL;
- _snprintf(client_id, max_len, "%S", username);
- } else {
- status = RPC_S_UNKNOWN_AUTHN_SERVICE;
- }
- }
- return status;
-}
-
-char*
-rpc_error_to_string(
- RPC_STATUS status
- )
-{
- switch(status) {
- case RPC_S_OK:
- return "OK";
- case RPC_S_INVALID_BINDING:
- return "Invalid binding";
- case RPC_S_WRONG_KIND_OF_BINDING:
- return "Wrong binding";
- case RPC_S_BINDING_HAS_NO_AUTH:
- RpcRaiseException(RPC_S_BINDING_HAS_NO_AUTH);
- return "Binding has no auth";
- default:
- return "BUG: I am confused";
- }
-}
-
-void
-print_client_info(
- RPC_STATUS peer_status,
- const char* peer_name,
- RPC_STATUS client_status,
- const char* client_id,
- client_auth_info* info
- )
-{
- if (peer_status == RPC_S_OK || peer_status == RPC_S_BUFFER_TOO_SMALL) {
- cci_debug_printf("%s Peer Name is \"%s\"", __FUNCTION__, peer_name);
- } else {
- cci_debug_printf("%s Error %u getting Peer Name (%s)",
- __FUNCTION__, peer_status, rpc_error_to_string(peer_status));
- }
-
- if (client_status == RPC_S_OK || client_status == RPC_S_BUFFER_TOO_SMALL) {
- if (info) {
- cci_debug_printf("%s Client Auth Info"
- "\tServer Principal: %s\n"
- "\tAuthentication Level: %d\n"
- "\tAuthentication Service: %d\n"
- "\tAuthorization Service: %d\n",
- __FUNCTION__,
- info->server_principal,
- info->authn_level,
- info->authn_svc,
- info->authz_svc);
- }
- cci_debug_printf("%s Client ID is \"%s\"", __FUNCTION__, client_id);
- } else {
- cci_debug_printf("%s Error getting Client Info (%u = %s)",
- __FUNCTION__, client_status, rpc_error_to_string(client_status));
- }
-}
-
-DWORD sid_check() {
- DWORD status = 0;
- HANDLE hToken_c = 0;
- HANDLE hToken_s = 0;
- PTOKEN_USER ptu_c = 0;
- PTOKEN_USER ptu_s = 0;
- DWORD len = 0;
- BOOL bImpersonate = FALSE;
-
- // Note GetUserName will fail while impersonating at identify
- // level. The workaround is to impersonate, OpenThreadToken,
- // revert, call GetTokenInformation, and finally, call
- // LookupAccountSid.
-
- // XXX - Note: This workaround does not appear to work.
- // OpenThreadToken fails with error 1346: "Either a requid
- // impersonation level was not provided or the provided
- // impersonation level is invalid".
-
- status = RpcImpersonateClient(0);
-
- if (!status) {
- bImpersonate = TRUE;
- if (!OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, FALSE, &hToken_c))
- status = GetLastError();
- }
-
- if (!status) {
- status = RpcRevertToSelf();
- }
-
- if (!status) {
- bImpersonate = FALSE;
-
- len = 0;
- GetTokenInformation(hToken_c, TokenUser, ptu_c, 0, &len);
- if (len == 0) status = 1;
- }
-
- if (!status) {
- if (!(ptu_c = (PTOKEN_USER)LocalAlloc(0, len)))
- status = GetLastError();
- }
-
- if (!status) {
- if (!GetTokenInformation(hToken_c, TokenUser, ptu_c, len, &len))
- status = GetLastError();
- }
-
- if (!status) {
- if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken_s))
- status = GetLastError();
- }
-
- if (!status) {
- len = 0;
- GetTokenInformation(hToken_s, TokenUser, ptu_s, 0, &len);
- if (len == 0) status = GetLastError();
- }
-
- if (!status) {
- if (!(ptu_s = (PTOKEN_USER)LocalAlloc(0, len)))
- status = GetLastError();
- }
-
- if (!status) {
- if (!GetTokenInformation(hToken_s, TokenUser, ptu_s, len, &len))
- status = GetLastError();
- }
-
- if (!EqualSid(ptu_s->User.Sid, ptu_c->User.Sid))
- status = RPC_S_ACCESS_DENIED;
-
-/* Cleanup: */
- if (!hToken_c && !bImpersonate)
- cci_debug_printf("%s Cannot impersonate (%u)", __FUNCTION__, status);
- else if (!hToken_c)
- cci_debug_printf("%s Failed to open client token (%u)", __FUNCTION__, status);
- else if (bImpersonate)
- cci_debug_printf("%s Failed to revert (%u)", __FUNCTION__, status);
- else if (!ptu_c)
- cci_debug_printf("%s Failed to get client token user info (%u)",
- __FUNCTION__, status);
- else if (!hToken_s)
- cci_debug_printf("%s Failed to open server token (%u)", __FUNCTION__, status);
- else if (!ptu_s)
- cci_debug_printf("%s Failed to get server token user info (%u)",
- __FUNCTION__, status);
- else if (status == RPC_S_ACCESS_DENIED)
- cci_debug_printf("%s SID **does not** match!", __FUNCTION__);
- else if (status == RPC_S_OK)
- cci_debug_printf("%s SID matches!", __FUNCTION__);
- else
- if (status) {
- cci_debug_printf("%s unrecognized error %u", __FUNCTION__, status);
- abort();
- }
-
- if (bImpersonate) RpcRevertToSelf();
- if (hToken_c && hToken_c != INVALID_HANDLE_VALUE)
- CloseHandle(hToken_c);
- if (ptu_c) LocalFree(ptu_c);
- if (hToken_s && hToken_s != INVALID_HANDLE_VALUE)
- CloseHandle(hToken_s);
- if (ptu_s) LocalFree(ptu_s);
- if (status) cci_debug_printf("%s returning %u", __FUNCTION__, status);
- return status;
- }
-
-RPC_STATUS RPC_ENTRY sec_callback( IN RPC_IF_ID *Interface,
- IN void *Context) {
- char peer_name[1024];
- char client_name[1024];
- RPC_STATUS peer_status;
- RPC_STATUS client_status;
-
- cci_debug_printf("%s", __FUNCTION__);
- peer_status = GetPeerName(Context, peer_name, sizeof(peer_name));
- client_status = GetClientId(Context, client_name, sizeof(client_name), 0);
- print_client_info(peer_status, peer_name, client_status, client_name, 0);
- DWORD sid_status = sid_check();
- cci_debug_printf("%s returning (%u)", __FUNCTION__, sid_status);
- return sid_status;
- }
-
-
-
-/*********************************************************************/
-/* MIDL allocate and free */
-/*********************************************************************/
-
-extern "C" void __RPC_FAR * __RPC_USER midl_user_allocate(size_t len) {
- return(malloc(len));
- }
-
-extern "C" void __RPC_USER midl_user_free(void __RPC_FAR * ptr) {
- free(ptr);
- }
-
-/* stubs */
-extern "C" cc_int32
-ccs_os_notify_cache_collection_changed (ccs_cache_collection_t cc)
-{
- return 0;
-}
-
-extern "C" cc_int32
-ccs_os_notify_ccache_changed (ccs_cache_collection_t cc, const char *name)
-{
- return 0;
-}
+/*
+ * $Header$
+ *
+ * Copyright 2008 Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ */
+
+#include "process.h"
+#include "windows.h"
+
+extern "C" {
+#include "ccs_common.h"
+#include "ccs_os_notify.h"
+#include "ccs_os_server.h"
+#include "ccs_reply.h"
+#include "ccs_request.h"
+#include "win-utils.h"
+#include "ccutils.h"
+ }
+
+#include "WorkQueue.h"
+#include "util.h"
+#include "opts.hxx"
+#include "init.hxx"
+
+#pragma warning (disable : 4996)
+
+BOOL bListen = TRUE; /* Why aren't bool and true defined? */
+const char* sessID = NULL; /* The logon session we are running on behalf of. */
+time_t _sst = 0;
+unsigned char* pszNetworkAddress = NULL;
+unsigned char* pszStringBinding = NULL;
+BOOL bRpcHandleInited = FALSE;
+_RPC_ASYNC_STATE* rpcState = NULL;
+
+/* Thread procedures can take only one void* argument. We put all the args we want
+ to pass into this struct and then pass a pointer to the struct: */
+struct RpcRcvArgs {
+ char* networkAddress;
+ unsigned char* protocolSequence;
+ unsigned char* sessID; /* Used for this server's endpoint */
+ unsigned char* uuid; /* Used for client's UUID */
+ ParseOpts::Opts* opts;
+ RPC_STATUS status;
+ } rpcargs = { NULL, /* pszNetworkAddress */
+ (unsigned char*)"ncalrpc", /* pszProtocolSequence */
+ NULL, /* sessID placeholder */
+ NULL, /* uuid placeholder */
+ NULL }; /* Opts placeholder */
+
+/* Command line format:
+ argv[0] Program name
+ argv[1] session ID to use
+ argv[2] "D" Debug: go into infinite loop in ccs_os_server_initialize so process
+ can be attached in debugger.
+ Any other value: continue
+ */
+#define N_FIXED_ARGS 3
+#define SERVER_REPLY_RPC_HANDLE ccs_reply_IfHandle
+
+/* Forward declarations: */
+void receiveLoop(void* rpcargs);
+void connectionListener(void* rpcargs);
+void Usage(const char* argv0);
+void printError(TCHAR* msg);
+void setMySST() {_sst = time(&_sst);}
+time_t getMySST() {return _sst;}
+RPC_STATUS send_connection_reply(ccs_pipe_t in_pipe);
+void RPC_ENTRY clientListener( _RPC_ASYNC_STATE*,
+ void* Context,
+ RPC_ASYNC_EVENT Event);
+RPC_STATUS RPC_ENTRY sec_callback( IN RPC_IF_ID *Interface,
+ IN void *Context);
+RPC_STATUS send_init(char* clientUUID);
+//DWORD alloc_name(LPSTR* pname, LPSTR postfix);
+
+
+/* The layout of the rest of this module:
+
+ The four entrypoints defined in ccs_os_server.h:
+ ccs_os_server_initialize
+ cc_int32 ccs_os_server_cleanup
+ cc_int32 ccs_os_server_listen_loop
+ cc_int32 ccs_os_server_send_reply
+
+ Other routines needed by those four.
+ */
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_os_server_initialize (int argc, const char *argv[]) {
+ cc_int32 err = 0;
+ ParseOpts::Opts opts = { 0 };
+ ParseOpts PO;
+ BOOL bAdjustedShutdown = FALSE;
+ HMODULE hKernel32 = GetModuleHandle("kernel32");
+
+ if (!err) {
+ sessID = argv[1];
+ setMySST();
+
+ opts.cMinCalls = 1;
+ opts.cMaxCalls = 20;
+ opts.fDontWait = TRUE;
+
+#ifdef CCAPI_TEST_OPTIONS
+ PO.SetValidOpts("kemnfubc");
+#else
+ PO.SetValidOpts("kc");
+#endif
+
+ PO.Parse(opts, argc, (char**)argv);
+
+// while(*argv[2] == 'D') {} /* Hang here to attach process with debugger. */
+
+ if (hKernel32) {
+ typedef BOOL (WINAPI *FP_SetProcessShutdownParameters)(DWORD, DWORD);
+ FP_SetProcessShutdownParameters pSetProcessShutdownParameters =
+ (FP_SetProcessShutdownParameters)
+ GetProcAddress(hKernel32, "SetProcessShutdownParameters");
+ if (pSetProcessShutdownParameters) {
+ bAdjustedShutdown = pSetProcessShutdownParameters(100, 0);
+ }
+ }
+ cci_debug_printf("%s Shutdown Parameters",
+ bAdjustedShutdown ? "Adjusted" : "Did not adjust");
+
+ err = Init::Initialize();
+ }
+
+// if (!err) {
+// if (opts.bShutdown) {
+// status = shutdown_server(opts.pszEndpoint);
+// }
+// }
+// else {
+// status = startup_server(opts);
+// }
+
+ if (err) {
+ Init::Cleanup();
+ fprintf( stderr, "An error occured while %s the server (%u)\n",
+ opts.bShutdown ? "shutting down" : "starting/running",
+ err);
+ exit(cci_check_error (err));
+ }
+
+ return cci_check_error (err);
+ }
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_os_server_cleanup (int argc, const char *argv[]) {
+ cc_int32 err = 0;
+
+ cci_debug_printf("%s for user <%s> shutting down.", argv[0], argv[1]);
+
+ return cci_check_error (err);
+ }
+
+/* ------------------------------------------------------------------------ */
+
+/* This function takes work items off the work queue and executes them.
+ * This is the one and only place where the multi-threaded Windows code
+ * calls into the single-threaded common code.
+ *
+ * The actual 'listening' for requests from clients happens after receiveloop
+ * establishes the RPC endpoint the clients will connect to and the RPC procedures
+ * put the work items into the work queue.
+ */
+cc_int32 ccs_os_server_listen_loop (int argc, const char *argv[]) {
+ cc_int32 err = 0;
+ uintptr_t threadStatus;
+ unsigned int loopCounter = 0;
+
+ ParseOpts::Opts opts = { 0 };
+ ParseOpts PO;
+
+ opts.cMinCalls = 1;
+ opts.cMaxCalls = 20;
+ opts.fDontWait = TRUE;
+
+#ifdef CCAPI_TEST_OPTIONS
+ PO.SetValidOpts("kemnfubc");
+#else
+ PO.SetValidOpts("kc");
+#endif
+ PO.Parse(opts, argc, (char**)argv);
+
+
+ //++ debug stuff
+ #define INFO_BUFFER_SIZE 32767
+ TCHAR infoBuf[INFO_BUFFER_SIZE];
+ DWORD bufCharCount = INFO_BUFFER_SIZE;
+ // Get and display the user name.
+ bufCharCount = INFO_BUFFER_SIZE;
+ if( !GetUserName( infoBuf, &bufCharCount ) ) printError( TEXT("GetUserName") );
+ //--
+
+ /* Sending the reply from within the request RPC handler doesn't seem to work.
+ So we listen for requests in a separate thread and put the requests in a
+ queue. */
+ rpcargs.sessID = (unsigned char*)sessID;
+ rpcargs.opts = &opts;
+ threadStatus = _beginthread(receiveLoop, 0, (void*)&rpcargs);
+
+ /* We handle the queue entries here. Work loop: */
+ while (TRUE) {
+ loopCounter++;
+ if (worklist_isEmpty() & 1) {
+ SleepEx(1000, TRUE);
+ }
+ else if (TRUE) { // Take next WorkItem from the queue:
+ k5_ipc_stream buf = NULL;
+ long rpcmsg = CCMSG_INVALID;
+ time_t serverStartTime = 0xDEADDEAD;
+ RPC_STATUS status = 0;
+ char* uuid = NULL;
+ k5_ipc_stream stream = NULL;
+ ccs_pipe_t pipe = NULL;
+ ccs_pipe_t pipe2 = NULL;
+
+ if (worklist_remove(&rpcmsg, &pipe, &buf, &serverStartTime)) {
+ uuid = ccs_win_pipe_getUuid(pipe);
+#if 0
+ cci_debug_printf("%s: processing WorkItem msg:%ld pipeUUID:<%s> pipeHandle:0x%X SST:%ld",
+ __FUNCTION__, rpcmsg, uuid, ccs_win_pipe_getHandle(pipe), serverStartTime);
+#endif
+ if (serverStartTime <= getMySST()) {
+ switch (rpcmsg) {
+ case CCMSG_CONNECT: {
+ cci_debug_printf(" Processing CONNECT");
+ rpcargs.uuid = (unsigned char*)uuid;
+
+ // Even if a disconnect message is received before this code finishes,
+ // it won't be dequeued and processed until after this code finishes.
+ // So we can add the client after starting the connection listener.
+ connectionListener((void*)&rpcargs);
+ status = rpcargs.status;
+
+ if (!status) {
+ status = ccs_server_add_client(pipe);
+ }
+ if (!status) {status = send_connection_reply(pipe);}
+ break;
+ }
+ case CCMSG_DISCONNECT: {
+ cci_debug_printf(" Processing DISCONNECT");
+ if (!status) {
+ status = ccs_server_remove_client(pipe);
+ }
+ break;
+ }
+ case CCMSG_REQUEST:
+ cci_debug_printf(" Processing REQUEST");
+ ccs_pipe_copy(&pipe2, pipe);
+ // Dispatch message here, setting both pipes to the client UUID:
+ err = ccs_server_handle_request (pipe, pipe2, buf);
+ break;
+ case CCMSG_PING:
+ cci_debug_printf(" Processing PING");
+ err = krb5int_ipc_stream_new (&stream);
+ err = krb5int_ipc_stream_write(stream, "This is a test of the emergency broadcasting system", 52);
+ err = ccs_os_server_send_reply(pipe, stream);
+ break;
+ default:
+ cci_debug_printf("Huh? Received invalid message type %ld from UUID:<%s>",
+ rpcmsg, uuid);
+ break;
+ }
+ if (buf) krb5int_ipc_stream_release(buf);
+ /* Don't free uuid, which was allocated here. A pointer to it is in the
+ rpcargs struct which was passed to connectionListener which will be
+ received by ccapi_listen when the client exits. ccapi_listen needs
+ the uuid to know which client to disconnect.
+ */
+ }
+ // Server's start time is different from what the client thinks.
+ // That means the server has rebooted since the client connected.
+ else {
+ cci_debug_printf("Whoops! Server has rebooted since client established connection.");
+ }
+ }
+ else {cci_debug_printf("Huh? Queue not empty but no item to remove.");}
+ }
+ }
+
+ return cci_check_error (err);
+ }
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 ccs_os_server_send_reply (ccs_pipe_t in_pipe,
+ k5_ipc_stream in_reply_stream) {
+
+ /* ccs_pipe_t in_reply_pipe is a char* reply endpoint.
+ k5_ipc_stream in_reply_stream is the data to be sent.
+ */
+
+ cc_int32 err = 0;
+ char* uuid = ccs_win_pipe_getUuid(in_pipe);
+ HANDLE h = ccs_win_pipe_getHandle(in_pipe);
+
+ if (!err) {
+ err = send_init(uuid); // Sets RPC handle to be used.
+ }
+
+ if (!err) {
+ RpcTryExcept {
+ long status;
+ ccs_rpc_request_reply( // make call with user message
+ CCMSG_REQUEST_REPLY, /* Message type */
+ (unsigned char*)&h, /* client's tspdata* */
+ (unsigned char*)uuid,
+ getMySST(),
+ krb5int_ipc_stream_size(in_reply_stream), /* Length of buffer */
+ (const unsigned char*)krb5int_ipc_stream_data(in_reply_stream), /* Data buffer */
+ &status ); /* Return code */
+ }
+ RpcExcept(1) {
+ cci_check_error(RpcExceptionCode());
+ }
+ RpcEndExcept
+ }
+
+ /* The calls to the remote procedures are complete. */
+ /* Free whatever we allocated: */
+ err = RpcBindingFree(&SERVER_REPLY_RPC_HANDLE);
+
+ return cci_check_error (err);
+ }
+
+
+/* Windows-specific routines: */
+
+void Usage(const char* argv0) {
+ printf("Usage:\n");
+ printf("%s [m maxcalls] [n mincalls] [f dontwait] [h|?]]\n", argv0);
+ printf(" CCAPI server process.\n");
+ printf(" h|? whow usage message. <\n");
+ }
+
+/* ------------------------------------------------------------------------ */
+/* The receive thread repeatedly issues RpcServerListen.
+ When a message arrives, it is handled in the RPC procedure.
+ */
+void receiveLoop(void* rpcargs) {
+
+ struct RpcRcvArgs* rcvargs = (struct RpcRcvArgs*)rpcargs;
+ RPC_STATUS status = FALSE;
+ unsigned char* pszSecurity = NULL;
+ LPSTR endpoint = NULL;
+ LPSTR event_name = NULL;
+ PSECURITY_DESCRIPTOR psd = NULL;
+ HANDLE hEvent = 0;
+ Init::InitInfo info;
+
+ cci_debug_printf("THREAD BEGIN: %s", __FUNCTION__);
+
+ status = Init::Info(info);
+
+ /* Build complete RPC endpoint using previous CCAPI implementation: */
+ if (!status) {
+ if (!rcvargs->opts->pszEndpoint) {
+ if (!status) {
+ status = alloc_name(&endpoint, "ep", isNT());
+ }
+
+ if (!status) {
+ status = alloc_name(&event_name, "startup", isNT());
+ }
+
+ if (!status) {
+ hEvent = OpenEvent(EVENT_MODIFY_STATE, FALSE, event_name);
+ // We ignore any error opening the event because we do not know who started us.
+ // [Comment paraphrased from previous implementation, whence it was copied.]
+ }
+ }
+ else {
+ endpoint = rcvargs->opts->pszEndpoint;
+ }
+ }
+
+ cci_debug_printf("%s Registering endpoint %s", __FUNCTION__, endpoint);
+
+ if (!status && isNT()) {
+ status = alloc_own_security_descriptor_NT(&psd);
+ }
+
+ if (!status) {
+ status = RpcServerUseProtseqEp(rcvargs->protocolSequence,
+ rcvargs->opts->cMaxCalls,
+ (RPC_CSTR)endpoint,
+ rcvargs->opts->bDontProtect ? 0 : psd); // SD
+ }
+
+ if (!status) {
+ status = RpcServerRegisterAuthInfo(0, // server principal
+ RPC_C_AUTHN_WINNT,
+ 0,
+ 0);
+ }
+
+ while (bListen && !status) {
+ cci_debug_printf("%s is listening ...", __FUNCTION__);
+
+ if (!info.isNT) {
+ status = RpcServerRegisterIf(ccs_request_ServerIfHandle, // interface
+ NULL, // MgrTypeUuid
+ NULL); // MgrEpv; null means use default
+ }
+ else {
+ status = info.fRpcServerRegisterIfEx(ccs_request_ServerIfHandle, // interface
+ NULL, // MgrTypeUuid
+ NULL, // MgrEpv; 0 means default
+ RPC_IF_ALLOW_SECURE_ONLY,
+ rcvargs->opts->cMaxCalls,
+ rcvargs->opts->bSecCallback ?
+ (RPC_IF_CALLBACK_FN*)sec_callback : 0 );
+ }
+
+ if (!status) {
+ status = RpcServerListen(rcvargs->opts->cMinCalls,
+ rcvargs->opts->cMaxCalls,
+ rcvargs->opts->fDontWait);
+ }
+
+ if (!status) {
+ if (rcvargs->opts->fDontWait) {
+ if (hEvent) SetEvent(hEvent); // Ignore any error -- SetEvent is an optimization.
+ status = RpcMgmtWaitServerListen();
+ }
+ }
+ }
+
+ if (status) { // Cleanup in case of errors:
+ if (hEvent) CloseHandle(hEvent);
+ free_alloc_p(&event_name);
+ free_alloc_p(&psd);
+ if (endpoint && (endpoint != rcvargs->opts->pszEndpoint))
+ free_alloc_p(&endpoint);
+ }
+
+ _endthread();
+ } // End receiveLoop
+
+
+#if 0
+
+ return status;
+}
+#endif
+
+
+
+/* ------------------------------------------------------------------------ */
+/* The connection listener thread waits forever for a call to the CCAPI_CLIENT_<UUID>
+ endpoint, ccapi_listen function to complete. If the call completes or gets an
+ RPC exception, it means the client has disappeared.
+
+ A separate connectionListener is started for each client that has connected to the server.
+ */
+
+void connectionListener(void* rpcargs) {
+
+ struct RpcRcvArgs* rcvargs = (struct RpcRcvArgs*)rpcargs;
+ RPC_STATUS status = FALSE;
+ char* endpoint;
+ unsigned char* pszOptions = NULL;
+ unsigned char * pszUuid = NULL;
+
+ endpoint = clientEndpoint((char*)rcvargs->uuid);
+ rpcState = (RPC_ASYNC_STATE*)malloc(sizeof(RPC_ASYNC_STATE));
+ status = RpcAsyncInitializeHandle(rpcState, sizeof(RPC_ASYNC_STATE));
+ cci_debug_printf("");
+ cci_debug_printf("%s About to LISTEN to <%s>", __FUNCTION__, endpoint);
+
+ rpcState->UserInfo = rcvargs->uuid;
+ rpcState->NotificationType = RpcNotificationTypeApc;
+ rpcState->u.APC.NotificationRoutine = clientListener;
+ rpcState->u.APC.hThread = 0;
+
+ /* [If in use] Free previous binding: */
+ if (bRpcHandleInited) {
+ // Free previous binding (could have been used to call ccapi_listen
+ // in a different client thread).
+ // Don't check result or update status.
+ RpcStringFree(&pszStringBinding);
+ RpcBindingFree(&SERVER_REPLY_RPC_HANDLE);
+ bRpcHandleInited = FALSE;
+ }
+
+ /* Set up binding to the client's endpoint: */
+ if (!status) {
+ status = RpcStringBindingCompose(
+ pszUuid,
+ pszProtocolSequence,
+ pszNetworkAddress,
+ (RPC_CSTR)endpoint,
+ pszOptions,
+ &pszStringBinding);
+ }
+
+ /* Set the binding handle that will be used to bind to the server. */
+ if (!status) {
+ status = RpcBindingFromStringBinding(pszStringBinding, &SERVER_REPLY_RPC_HANDLE);
+ }
+ if (!status) {bRpcHandleInited = TRUE;}
+
+ RpcTryExcept {
+ cci_debug_printf(" Calling remote procedure ccapi_listen");
+ ccapi_listen(rpcState, SERVER_REPLY_RPC_HANDLE, CCMSG_LISTEN, &status);
+ /* Asynchronous call will return immediately. */
+ }
+ RpcExcept(1) {
+ status = cci_check_error(RpcExceptionCode());
+ }
+ RpcEndExcept
+
+ rcvargs->status = status;
+ } // End connectionListener
+
+
+void RPC_ENTRY clientListener(
+ _RPC_ASYNC_STATE* pAsync,
+ void* Context,
+ RPC_ASYNC_EVENT Event
+ ) {
+
+ ccs_pipe_t pipe = ccs_win_pipe_new((char*)pAsync->UserInfo, NULL);
+
+ cci_debug_printf("%s(0x%X, ...) async routine for <0x%X:%s>!",
+ __FUNCTION__, pAsync, pAsync->UserInfo, pAsync->UserInfo);
+
+ worklist_add( CCMSG_DISCONNECT,
+ pipe,
+ NULL, /* No payload with connect request */
+ (const time_t)0 ); /* No server session number with connect request */
+ }
+
+
+void printError( TCHAR* msg ) {
+ DWORD eNum;
+ TCHAR sysMsg[256];
+ TCHAR* p;
+
+ eNum = GetLastError( );
+ FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL, eNum,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ sysMsg, 256, NULL );
+
+ // Trim the end of the line and terminate it with a null
+ p = sysMsg;
+ while( ( *p > 31 ) || ( *p == 9 ) )
+ ++p;
+ do { *p-- = 0; } while( ( p >= sysMsg ) &&
+ ( ( *p == '.' ) || ( *p < 33 ) ) );
+
+ // Display the message
+ cci_debug_printf("%s failed with error %d (%s)", msg, eNum, sysMsg);
+ }
+
+
+RPC_STATUS send_init(char* clientUUID) {
+ RPC_STATUS status;
+ unsigned char * pszUuid = NULL;
+ unsigned char * pszOptions = NULL;
+
+ /* Use a convenience function to concatenate the elements of */
+ /* the string binding into the proper sequence. */
+ status = RpcStringBindingCompose(pszUuid,
+ pszProtocolSequence,
+ pszNetworkAddress,
+ (unsigned char*)clientEndpoint(clientUUID),
+ pszOptions,
+ &pszStringBinding);
+ if (status) {return (status);}
+
+ /* Set the binding handle that will be used to bind to the RPC server [the 'client']. */
+ status = RpcBindingFromStringBinding(pszStringBinding, &SERVER_REPLY_RPC_HANDLE);
+ return (status);
+ }
+
+RPC_STATUS send_finish() {
+ RPC_STATUS status;
+ /* Can't shut down client -- it runs listen function which */
+ /* server uses to detect the client going away. */
+
+ /* The calls to the remote procedures are complete. */
+ /* Free the string and the binding handle */
+ status = RpcStringFree(&pszStringBinding); // remote calls done; unbind
+ if (status) {return (status);}
+
+ status = RpcBindingFree(&SERVER_REPLY_RPC_HANDLE); // remote calls done; unbind
+
+ return (status);
+ }
+
+RPC_STATUS send_connection_reply(ccs_pipe_t in_pipe) {
+ char* uuid = ccs_win_pipe_getUuid (in_pipe);
+ HANDLE h = ccs_win_pipe_getHandle(in_pipe);
+ RPC_STATUS status = send_init(uuid);
+
+ RpcTryExcept {
+ ccs_rpc_connect_reply( // make call with user message
+ CCMSG_CONNECT_REPLY, /* Message type */
+ (unsigned char*)&h, /* client's tspdata* */
+ (unsigned char*)uuid,
+ getMySST(), /* Server's session number = it's start time */
+ &status ); /* Return code */
+ }
+ RpcExcept(1) {
+ cci_check_error(RpcExceptionCode());
+ }
+ RpcEndExcept
+
+ status = send_finish();
+ return (status);
+ }
+
+#if 0
+DWORD alloc_name(LPSTR* pname, LPSTR postfix) {
+ DWORD len = strlen(sessID) + 1 + strlen(postfix) + 1;
+
+ *pname = (LPSTR)malloc(len);
+ if (!*pname) return GetLastError();
+ _snprintf(*pname, len, "%s.%s", sessID, postfix);
+ return 0;
+ }
+#endif
+
+RPC_STATUS GetPeerName( RPC_BINDING_HANDLE hClient,
+ LPTSTR pszClientName,
+ int iMaxLen) {
+ RPC_STATUS Status = RPC_S_OK;
+ RPC_BINDING_HANDLE hServer = NULL;
+ PTBYTE pszStringBinding = NULL;
+ PTBYTE pszClientNetAddr = NULL;
+ PTBYTE pszProtSequence = NULL;
+
+ memset(pszClientName, 0, iMaxLen * sizeof(TCHAR));
+
+ __try {
+ // Create a partially bound server handle from the client handle.
+ Status = RpcBindingServerFromClient (hClient, &hServer);
+ if (Status != RPC_S_OK) __leave;
+
+ // Get the partially bound server string binding and parse it.
+ Status = RpcBindingToStringBinding (hServer,
+ &pszStringBinding);
+ if (Status != RPC_S_OK) __leave;
+
+ // String binding only contains protocol sequence and client
+ // address, and is not currently implemented for named pipes.
+ Status = RpcStringBindingParse (pszStringBinding, NULL,
+ &pszProtSequence, &pszClientNetAddr,
+ NULL, NULL);
+ if (Status != RPC_S_OK)
+ __leave;
+ int iLen = lstrlen(pszClientName) + 1;
+ if (iMaxLen < iLen)
+ Status = RPC_S_BUFFER_TOO_SMALL;
+ lstrcpyn(pszClientName, (LPCTSTR)pszClientNetAddr, iMaxLen);
+ }
+ __finally {
+ if (pszProtSequence)
+ RpcStringFree (&pszProtSequence);
+
+ if (pszClientNetAddr)
+ RpcStringFree (&pszClientNetAddr);
+
+ if (pszStringBinding)
+ RpcStringFree (&pszStringBinding);
+
+ if (hServer)
+ RpcBindingFree (&hServer);
+ }
+ return Status;
+}
+
+struct client_auth_info {
+ RPC_AUTHZ_HANDLE authz_handle;
+ unsigned char* server_principal; // need to RpcFreeString this
+ ULONG authn_level;
+ ULONG authn_svc;
+ ULONG authz_svc;
+};
+
+RPC_STATUS
+GetClientId(
+ RPC_BINDING_HANDLE hClient,
+ char* client_id,
+ int max_len,
+ client_auth_info* info
+ )
+{
+ RPC_AUTHZ_HANDLE authz_handle = 0;
+ unsigned char* server_principal = 0;
+ ULONG authn_level = 0;
+ ULONG authn_svc = 0;
+ ULONG authz_svc = 0;
+ RPC_STATUS status = 0;
+
+ memset(client_id, 0, max_len);
+
+ if (info) {
+ memset(info, 0, sizeof(client_auth_info));
+ }
+
+ status = RpcBindingInqAuthClient(hClient, &authz_handle,
+ info ? &server_principal : 0,
+ &authn_level, &authn_svc, &authz_svc);
+ if (status == RPC_S_OK)
+ {
+ if (info) {
+ info->server_principal = server_principal;
+ info->authz_handle = authz_handle;
+ info->authn_level = authn_level;
+ info->authn_svc = authn_svc;
+ info->authz_svc = authz_svc;
+ }
+
+ if (authn_svc == RPC_C_AUTHN_WINNT) {
+ WCHAR* username = (WCHAR*)authz_handle;
+ int len = lstrlenW(username) + 1;
+ if (max_len < len)
+ status = RPC_S_BUFFER_TOO_SMALL;
+ _snprintf(client_id, max_len, "%S", username);
+ } else {
+ status = RPC_S_UNKNOWN_AUTHN_SERVICE;
+ }
+ }
+ return status;
+}
+
+char*
+rpc_error_to_string(
+ RPC_STATUS status
+ )
+{
+ switch(status) {
+ case RPC_S_OK:
+ return "OK";
+ case RPC_S_INVALID_BINDING:
+ return "Invalid binding";
+ case RPC_S_WRONG_KIND_OF_BINDING:
+ return "Wrong binding";
+ case RPC_S_BINDING_HAS_NO_AUTH:
+ RpcRaiseException(RPC_S_BINDING_HAS_NO_AUTH);
+ return "Binding has no auth";
+ default:
+ return "BUG: I am confused";
+ }
+}
+
+void
+print_client_info(
+ RPC_STATUS peer_status,
+ const char* peer_name,
+ RPC_STATUS client_status,
+ const char* client_id,
+ client_auth_info* info
+ )
+{
+ if (peer_status == RPC_S_OK || peer_status == RPC_S_BUFFER_TOO_SMALL) {
+ cci_debug_printf("%s Peer Name is \"%s\"", __FUNCTION__, peer_name);
+ } else {
+ cci_debug_printf("%s Error %u getting Peer Name (%s)",
+ __FUNCTION__, peer_status, rpc_error_to_string(peer_status));
+ }
+
+ if (client_status == RPC_S_OK || client_status == RPC_S_BUFFER_TOO_SMALL) {
+ if (info) {
+ cci_debug_printf("%s Client Auth Info"
+ "\tServer Principal: %s\n"
+ "\tAuthentication Level: %d\n"
+ "\tAuthentication Service: %d\n"
+ "\tAuthorization Service: %d\n",
+ __FUNCTION__,
+ info->server_principal,
+ info->authn_level,
+ info->authn_svc,
+ info->authz_svc);
+ }
+ cci_debug_printf("%s Client ID is \"%s\"", __FUNCTION__, client_id);
+ } else {
+ cci_debug_printf("%s Error getting Client Info (%u = %s)",
+ __FUNCTION__, client_status, rpc_error_to_string(client_status));
+ }
+}
+
+DWORD sid_check() {
+ DWORD status = 0;
+ HANDLE hToken_c = 0;
+ HANDLE hToken_s = 0;
+ PTOKEN_USER ptu_c = 0;
+ PTOKEN_USER ptu_s = 0;
+ DWORD len = 0;
+ BOOL bImpersonate = FALSE;
+
+ // Note GetUserName will fail while impersonating at identify
+ // level. The workaround is to impersonate, OpenThreadToken,
+ // revert, call GetTokenInformation, and finally, call
+ // LookupAccountSid.
+
+ // XXX - Note: This workaround does not appear to work.
+ // OpenThreadToken fails with error 1346: "Either a requid
+ // impersonation level was not provided or the provided
+ // impersonation level is invalid".
+
+ status = RpcImpersonateClient(0);
+
+ if (!status) {
+ bImpersonate = TRUE;
+ if (!OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, FALSE, &hToken_c))
+ status = GetLastError();
+ }
+
+ if (!status) {
+ status = RpcRevertToSelf();
+ }
+
+ if (!status) {
+ bImpersonate = FALSE;
+
+ len = 0;
+ GetTokenInformation(hToken_c, TokenUser, ptu_c, 0, &len);
+ if (len == 0) status = 1;
+ }
+
+ if (!status) {
+ if (!(ptu_c = (PTOKEN_USER)LocalAlloc(0, len)))
+ status = GetLastError();
+ }
+
+ if (!status) {
+ if (!GetTokenInformation(hToken_c, TokenUser, ptu_c, len, &len))
+ status = GetLastError();
+ }
+
+ if (!status) {
+ if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken_s))
+ status = GetLastError();
+ }
+
+ if (!status) {
+ len = 0;
+ GetTokenInformation(hToken_s, TokenUser, ptu_s, 0, &len);
+ if (len == 0) status = GetLastError();
+ }
+
+ if (!status) {
+ if (!(ptu_s = (PTOKEN_USER)LocalAlloc(0, len)))
+ status = GetLastError();
+ }
+
+ if (!status) {
+ if (!GetTokenInformation(hToken_s, TokenUser, ptu_s, len, &len))
+ status = GetLastError();
+ }
+
+ if (!EqualSid(ptu_s->User.Sid, ptu_c->User.Sid))
+ status = RPC_S_ACCESS_DENIED;
+
+/* Cleanup: */
+ if (!hToken_c && !bImpersonate)
+ cci_debug_printf("%s Cannot impersonate (%u)", __FUNCTION__, status);
+ else if (!hToken_c)
+ cci_debug_printf("%s Failed to open client token (%u)", __FUNCTION__, status);
+ else if (bImpersonate)
+ cci_debug_printf("%s Failed to revert (%u)", __FUNCTION__, status);
+ else if (!ptu_c)
+ cci_debug_printf("%s Failed to get client token user info (%u)",
+ __FUNCTION__, status);
+ else if (!hToken_s)
+ cci_debug_printf("%s Failed to open server token (%u)", __FUNCTION__, status);
+ else if (!ptu_s)
+ cci_debug_printf("%s Failed to get server token user info (%u)",
+ __FUNCTION__, status);
+ else if (status == RPC_S_ACCESS_DENIED)
+ cci_debug_printf("%s SID **does not** match!", __FUNCTION__);
+ else if (status == RPC_S_OK)
+ cci_debug_printf("%s SID matches!", __FUNCTION__);
+ else
+ if (status) {
+ cci_debug_printf("%s unrecognized error %u", __FUNCTION__, status);
+ abort();
+ }
+
+ if (bImpersonate) RpcRevertToSelf();
+ if (hToken_c && hToken_c != INVALID_HANDLE_VALUE)
+ CloseHandle(hToken_c);
+ if (ptu_c) LocalFree(ptu_c);
+ if (hToken_s && hToken_s != INVALID_HANDLE_VALUE)
+ CloseHandle(hToken_s);
+ if (ptu_s) LocalFree(ptu_s);
+ if (status) cci_debug_printf("%s returning %u", __FUNCTION__, status);
+ return status;
+ }
+
+RPC_STATUS RPC_ENTRY sec_callback( IN RPC_IF_ID *Interface,
+ IN void *Context) {
+ char peer_name[1024];
+ char client_name[1024];
+ RPC_STATUS peer_status;
+ RPC_STATUS client_status;
+
+ cci_debug_printf("%s", __FUNCTION__);
+ peer_status = GetPeerName(Context, peer_name, sizeof(peer_name));
+ client_status = GetClientId(Context, client_name, sizeof(client_name), 0);
+ print_client_info(peer_status, peer_name, client_status, client_name, 0);
+ DWORD sid_status = sid_check();
+ cci_debug_printf("%s returning (%u)", __FUNCTION__, sid_status);
+ return sid_status;
+ }
+
+
+
+/*********************************************************************/
+/* MIDL allocate and free */
+/*********************************************************************/
+
+extern "C" void __RPC_FAR * __RPC_USER midl_user_allocate(size_t len) {
+ return(malloc(len));
+ }
+
+extern "C" void __RPC_USER midl_user_free(void __RPC_FAR * ptr) {
+ free(ptr);
+ }
+
+/* stubs */
+extern "C" cc_int32
+ccs_os_notify_cache_collection_changed (ccs_cache_collection_t cc)
+{
+ return 0;
+}
+
+extern "C" cc_int32
+ccs_os_notify_ccache_changed (ccs_cache_collection_t cc, const char *name)
+{
+ return 0;
+}
diff --git a/src/ccapi/test/Makefile.in b/src/ccapi/test/Makefile.in
index 175e06bf04..bf950b6a7f 100644
--- a/src/ccapi/test/Makefile.in
+++ b/src/ccapi/test/Makefile.in
@@ -6,7 +6,7 @@ CCAPI=$(BUILDTOP)$(S)CCAPI
KFWINC= /I$(BUILDTOP)\..\..\krbcc\include
!endif
-# Because all the sources are in .,
+# Because all the sources are in .,
# the only includes we need are to directories outside of ccapi.
LOCALINCLUDES = /I$(BUILDTOP) /I$(BUILDTOP)$(S)include /I$(BUILDTOP)$(S)include$(S)krb5 $(KFWINC) \
-I$(BUILDTOP)$(S)util$(S)et /I. -I$(CCAPI)$(S)COMMON -I$(CCAPI)$(S)LIB
@@ -21,7 +21,6 @@ LOCALINCLUDES = /I$(BUILDTOP) /I$(BUILDTOP)$(S)include /I$(BUILDTOP)$(S)include$
##DOS## ccs_reply.h \
##DOS## ccs_request.h \
##DOS## ccs_request_c.c \
-##DOS## cci_stream.h \
##DOS## cci_types.h \
##DOS## win-utils.h
@@ -29,6 +28,7 @@ LOCALINCLUDES = /I$(BUILDTOP) /I$(BUILDTOP)$(S)include /I$(BUILDTOP)$(S)include$
##DOS## ccapi_ccache_iterator.c \
##DOS## ccapi_context.c \
##DOS## ccapi_context_change_time.c \
+##DOS## ccapi_err.c \
##DOS## ccapi_ipc.c \
##DOS## ccapi_credentials.c \
##DOS## ccapi_credentials_iterator.c \
@@ -37,8 +37,7 @@ LOCALINCLUDES = /I$(BUILDTOP) /I$(BUILDTOP)$(S)include /I$(BUILDTOP)$(S)include$
##DOS##COMSRC=cci_cred_union.c \
##DOS## cci_identifier.c \
-##DOS## cci_message.c \
-##DOS## cci_stream.c
+##DOS## cci_message.c
##DOS##COWSRC=cci_os_identifier.c
@@ -65,6 +64,7 @@ PINGOBJS = $(OUTPRE)ccapi_ccache.$(OBJEXT) \
$(OUTPRE)ccapi_ccache_iterator.$(OBJEXT) \
$(OUTPRE)ccapi_context.$(OBJEXT) \
$(OUTPRE)ccapi_context_change_time.$(OBJEXT) \
+ $(OUTPRE)ccapi_err.$(OBJEXT) \
$(OUTPRE)ccapi_ipc.$(OBJEXT) \
$(OUTPRE)ccapi_credentials.$(OBJEXT) \
$(OUTPRE)ccapi_credentials_iterator.$(OBJEXT) \
@@ -74,7 +74,6 @@ PINGOBJS = $(OUTPRE)ccapi_ccache.$(OBJEXT) \
$(OUTPRE)cci_identifier.$(OBJEXT) \
$(OUTPRE)cci_os_identifier.$(OBJEXT) \
$(OUTPRE)cci_message.$(OBJEXT) \
- $(OUTPRE)cci_stream.$(OBJEXT) \
$(OUTPRE)ccs_request_c.$(OBJEXT) \
$(OUTPRE)pingtest.$(OBJEXT) \
$(OBJECTS)
@@ -86,7 +85,7 @@ TEST_NAMES = test_cc_ccache_iterator_next \
test_constants \
test_cc_initialize \
test_cc_credentials_iterator_next
-
+
MORE_TESTS = test_cc_context_release \
test_cc_context_get_change_time \
test_cc_context_get_default_ccache_name \
@@ -136,7 +135,7 @@ MORE_TESTS = test_cc_context_release \
##### Linker
LINK = link
LIBS = -lkrb5
-##DOS##LIBS = advapi32.lib rpcrt4.lib user32.lib ws2_32.lib ccapi.lib
+##DOS##LIBS = $(CLIB) $(SLIB) advapi32.lib rpcrt4.lib user32.lib ws2_32.lib ccapi.lib
LFLAGS = /nologo $(LOPTS)
all-mac:: setup-test-dir pingtest simple_lock_test build-base build-tests link-tests copy-script success-message
@@ -149,14 +148,14 @@ build-base: $(PINGOBJS)
# compile each test
build-tests: $(TEST_NAMES)
@echo build-tests complete.
-
-$(TEST_NAMES):
- @echo DBG: $@
+
+$(TEST_NAMES):
+ @echo DBG: $@
$(CC) $(ALL_CFLAGS) -Fe$(TESTDIR)$(S)$@.exe -Fd$(OBJDIR)$(S)$@.obj $@.c $(OBJECTS) $(LIBS)
# Clean .obj from .:
$(RM) $@.$(OBJEXT)
##-- These two rules build each element of the list.
-
+
# Make a build directory
setup-test-dir:
@echo "Removing old destination directory... $(DSTDIR)"
@@ -164,13 +163,13 @@ setup-test-dir:
mkdir -p "$(TESTDIR)"
if [ -d "$(OBJDIR)" ]; then chmod -R u+w "$(OBJDIR)" && rm -rf "$(OBJDIR)"; fi
mkdir -p "$(OBJDIR)"
-
+
## The same trick as used in TEST_NAMES to run an action on each element ofthe list WINH:
setup-windows: $(WINH) $(LIBSRC) $(COMSRC) $(COWSRC)
if NOT exist $(TESTDIR) mkdir $(TESTDIR)
if NOT exist $(OBJDIR) mkdir $(OBJDIR)
set LINK = link
-
+
# This rule assumes that nmake in ..\lib\win has already run.
# That is how ..\Makefile.in is set up.
$(WINH):
@@ -187,8 +186,8 @@ $(COWSRC):
# This rule assumes that nmake in ..\lib\win\ has already run.
$(OUTPRE)pingtest.exe: $(OBJECTS) $(PINGOBJS)
-# There doesn't appear to be any way to examine a variable and return a value
-# indicating whether a string is present in it. We use a perl script to
+# There doesn't appear to be any way to examine a variable and return a value
+# indicating whether a string is present in it. We use a perl script to
# check the LIB variable. If the path to ccapi.lib isn't present, the script
# deletes a.tmp and the following nmake actions correct LIB.
echo %%PATH%% > a.tmp
@@ -197,8 +196,8 @@ $(OUTPRE)pingtest.exe: $(OBJECTS) $(PINGOBJS)
@echo Adding ..\lib\win\srctmp to LIB
set LIB=%%LIB%%;..\lib\win\srctmp
)
- $(LINK) $(linkdebug) /map:$(@B)1.map -out:$(*B)1.exe $(conflags) $(PINGOBJS) $(LIBS)
- $(LINK) $(LFLAGS) /map:$(@B)2.map /out:$(*B)2.exe $(conflags) $(PINGOBJS) $(LIBS) $(conlibsdll)
+ $(LINK) $(linkdebug) /map:$(@B)1.map -out:$(*B)1.exe $(conflags) $(PINGOBJS) $(LIBS)
+ $(LINK) $(LFLAGS) /map:$(@B)2.map /out:$(*B)2.exe $(conflags) $(PINGOBJS) $(LIBS) $(conlibsdll)
link-tests: $(TEST_NAMES)
@@ -212,10 +211,7 @@ simple_lock_test:
$(CC) -o $(TESTDIR)/simple_lock_test simple_lock_test.c $(LIBS)
copy-script:
- echo Copy script ...
- cd
- dir ccapi_test
- cp $(SCRIPT_NAME) $(DSTDIR)$(S)$(SCRIPT_NAME)
+ $(CP) $(SCRIPT_NAME) $(DSTDIR)$(S)$(SCRIPT_NAME)
success-message:
@echo
diff --git a/src/ccapi/test/pingtest.c b/src/ccapi/test/pingtest.c
index d64db2e4b6..d44839f71a 100644
--- a/src/ccapi/test/pingtest.c
+++ b/src/ccapi/test/pingtest.c
@@ -9,7 +9,6 @@
#include "cci_debugging.h"
#include "CredentialsCache.h"
-#include "cci_stream.h"
#include "win-utils.h"
#include "ccs_request.h"
@@ -18,9 +17,9 @@
extern cc_int32 cci_os_ipc_thread_init (void);
extern cc_int32 cci_os_ipc_msg( cc_int32 in_launch_server,
- cci_stream_t in_request_stream,
+ k5_ipc_stream in_request_stream,
cc_int32 in_msg,
- cci_stream_t* out_reply_stream);
+ k5_ipc_stream* out_reply_stream);
static DWORD dwTlsIndex;
@@ -68,8 +67,8 @@ RPC_STATUS send_test(char* endpoint) {
int main( int argc, char *argv[]) {
cc_int32 err = 0;
cc_context_t context = NULL;
- cci_stream_t send_stream = NULL;
- cci_stream_t reply_stream = NULL;
+ k5_ipc_stream send_stream = NULL;
+ k5_ipc_stream reply_stream = NULL;
char* message = "Hello, RPC!";
@@ -85,8 +84,9 @@ int main( int argc, char *argv[]) {
err = cci_os_ipc_thread_init();
}
if (!err) {
- err = cci_stream_new (&send_stream);
- err = cci_stream_write(send_stream, message, 1+strlen(message));
+ err = krb5int_ipc_stream_new (&send_stream);
+ err = krb5int_ipc_stream_write(send_stream, message,
+ 1+strlen(message));
}
if (!err) {