Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

510 lines
15 KiB

/*++
Copyright (c) 2001 Microsoft Corporation
Module Name:
sspics.cxx
Abstract:
sspics
Author:
Larry Zhu (LZhu) January 1, 2002 Created
Environment:
User Mode
Revision History:
--*/
#include "precomp.hxx"
#pragma hdrstop
#include "sspics.hxx"
TSspiClientThreadParam::TSspiClientThreadParam(
VOID
) : ParameterType(kSspiCliThreadParameters),
ServerSocketPort(kServerSocketPort),
ClientSocketPort(kClientSocketPort),
pszServer(NULL)
{
}
TSspiClientThreadParam::~TSspiClientThreadParam(
VOID
)
{
}
TSspiServerThreadParam::TSspiServerThreadParam(
VOID
) : ParameterType(kSspiSrvThreadParameters),
ServerSocket(INVALID_SOCKET)
{
}
TSspiServerThreadParam::~TSspiServerThreadParam(
VOID
)
{
}
TSsiServerMainLoopThreadParam::TSsiServerMainLoopThreadParam(
VOID
) : ParameterType(kSspiSrvMainThreadParameters),
ServerSocketPort(kServerSocketPort)
{
}
TSsiServerMainLoopThreadParam::~TSsiServerMainLoopThreadParam(
VOID
)
{
}
DWORD WINAPI
SspiClientThread(
IN PVOID pParameter // thread data
)
{
THResult hRetval = E_FAIL;
CHAR szClientComputerName[DNS_MAX_NAME_LENGTH + 1] = {0};
TSspiClientThreadParam* pCliParam = (TSspiClientThreadParam*) pParameter;
SOCKET ClientSocketListen = INVALID_SOCKET;
SOCKET ServerSocket = INVALID_SOCKET;
SOCKET ClientSocket = INVALID_SOCKET;
DWORD ServerThreadId = 0;
ULONG MessageNum = 0;
DebugPrintf(SSPI_LOG, "SspiClientThread ParameterType %#x\n", pCliParam->ParameterType);
hRetval DBGCHK = pCliParam->ParameterType == kSspiCliThreadParameters ? S_OK : E_INVALIDARG;
if (SUCCEEDED(hRetval))
{
hRetval DBGCHK = TlsSetValue(g_MessageNumTlsIndex, &MessageNum) ? S_OK : GetLastErrorAsHResult();
}
if (SUCCEEDED(hRetval))
{
hRetval DBGCHK = gethostname(szClientComputerName, sizeof(szClientComputerName) - 1) == ERROR_SUCCESS ? S_OK : HResultFromWin32(WSAGetLastError());
}
if (SUCCEEDED(hRetval))
{
hRetval DBGCHK = ServerInit(pCliParam->ClientSocketPort, "SspiClient", &ClientSocketListen);
}
if (SUCCEEDED(hRetval))
{
DebugPrintf(SSPI_LOG, "SspiClientThread connecting to %s:%#x\n", pCliParam->pszServer, pCliParam->ServerSocketPort);
hRetval DBGCHK = ClientConnect(
pCliParam->pszServer,
pCliParam->ServerSocketPort,
&ServerSocket
);
}
if (SUCCEEDED(hRetval))
{
hRetval DBGCHK = WriteMessage(
ServerSocket,
sizeof(pCliParam->ClientSocketPort),
&pCliParam->ClientSocketPort
);
}
if (SUCCEEDED(hRetval))
{
hRetval DBGCHK = WriteMessage(
ServerSocket,
strlen(szClientComputerName),
szClientComputerName
);
}
if (SUCCEEDED(hRetval))
{
ClientSocket = accept(ClientSocketListen, NULL, NULL);
hRetval DBGCHK = (INVALID_SOCKET != ClientSocket) ? S_OK : HResultFromWin32(WSAGetLastError());
}
if (SUCCEEDED(hRetval))
{
ULONG cbRead = 0;
hRetval DBGCHK = ReadMessage(
ClientSocket,
sizeof(ServerThreadId),
&ServerThreadId,
&cbRead
);
}
if (SUCCEEDED(hRetval))
{
DebugPrintf(SSPI_LOG, "SspiClientThread got ServerThreadId %#x\n", ServerThreadId);
hRetval DBGCHK = SspiClientStart(
pCliParam,
ServerSocket,
ClientSocket
);
}
THResult hr;
if (INVALID_SOCKET != ClientSocket)
{
hr DBGCHK = closesocket(ClientSocket) == ERROR_SUCCESS ? S_OK : HResultFromWin32(WSAGetLastError());
}
if (INVALID_SOCKET != ServerSocket)
{
hr DBGCHK = closesocket(ServerSocket) == ERROR_SUCCESS ? S_OK : HResultFromWin32(WSAGetLastError());
}
if (INVALID_SOCKET != ClientSocketListen)
{
hr DBGCHK = closesocket(ClientSocketListen) == ERROR_SUCCESS ? S_OK : HResultFromWin32(WSAGetLastError());
}
//
// use SspiPrint to get around -quiet
//
SspiPrint(SSPI_LOG, TEXT("SspiClientThread terminating %#x\n"), (HRESULT) hRetval);
return HRESULT_CODE(hRetval);
}
DWORD WINAPI
SspiServerThread(
IN PVOID pParameter // thread data
)
{
THResult hRetval = E_FAIL;
USHORT ClientSocketPort = 0;
CHAR szClientMachineName[DNS_MAX_NAME_LENGTH + 1] = {0};
SOCKET ClientSocket = INVALID_SOCKET;
SOCKET ServerSocket = INVALID_SOCKET;
ULONG cbRead = 0;
ULONG MessageNum = 0;
TSspiServerThreadParam* pSrvParam = (TSspiServerThreadParam*) pParameter;
DebugPrintf(SSPI_LOG, "SspiServerThread ParameterType %#x\n", pSrvParam->ParameterType);
hRetval DBGCHK = pSrvParam && pSrvParam->ParameterType == kSspiSrvThreadParameters ? S_OK : E_INVALIDARG;
if (SUCCEEDED(hRetval))
{
hRetval DBGCHK = TlsSetValue(g_MessageNumTlsIndex, &MessageNum) ? S_OK : GetLastErrorAsHResult();
}
if (SUCCEEDED(hRetval))
{
ServerSocket = pSrvParam->ServerSocket;
hRetval DBGCHK = ReadMessage(
ServerSocket,
sizeof(ClientSocketPort),
&ClientSocketPort,
&cbRead
);
}
if (SUCCEEDED(hRetval))
{
hRetval DBGCHK = ReadMessage(
ServerSocket,
sizeof(szClientMachineName) - 1,
szClientMachineName,
&cbRead
);
}
if (SUCCEEDED(hRetval))
{
DebugPrintf(SSPI_LOG, "SspiServerThread Client Machine %s, Client Port %#x\n", szClientMachineName, ClientSocketPort);
hRetval DBGCHK = ClientConnect(
szClientMachineName,
ClientSocketPort,
&ClientSocket
);
}
if (SUCCEEDED(hRetval))
{
DWORD dwThreadId = GetCurrentThreadId();
hRetval DBGCHK = WriteMessage(
ClientSocket,
sizeof(dwThreadId),
&dwThreadId
);
}
THResult hr;
if (SUCCEEDED(hRetval))
{
hRetval DBGCHK = SspiServerStart(pSrvParam, ClientSocket);
}
if (ClientSocket != INVALID_SOCKET)
{
hr DBGCHK = closesocket(ClientSocket) == ERROR_SUCCESS ? S_OK : HResultFromWin32(WSAGetLastError());
}
if (ServerSocket != INVALID_SOCKET)
{
hr DBGCHK = closesocket(ServerSocket);
}
SspiReleaseServerParam(pSrvParam);
//
// use SspiPrint to get around -quiet
//
SspiPrint(SSPI_LOG, TEXT("SspiServerThread terminating %#x\n"), (HRESULT) hRetval);
return HRESULT_CODE(hRetval);
}
HRESULT
CheckForNoOtherServerWithSamePort(
IN ULONG Port,
OUT HANDLE* phEvent
)
{
THResult hRetval = E_FAIL;
WCHAR szEvent[MAX_PATH] = {0};
UNICODE_STRING EventName = {0};
OBJECT_ATTRIBUTES EventAttributes = {0};
_snwprintf(szEvent, COUNTOF(szEvent) - 1, L"\\SspiServerWithPort%#x(%d)", Port, Port);
RtlInitUnicodeString( &EventName, szEvent );
InitializeObjectAttributes(
&EventAttributes,
&EventName,
0, // no attributes
NULL, // no RootDirectory
NULL // no SecurityQualityOfService
);
DBGCFG2(hRetval, STATUS_OBJECT_NAME_COLLISION, STATUS_ACCESS_DENIED);
hRetval DBGCHK = NtCreateEvent(
phEvent,
MAXIMUM_ALLOWED, // SYNCHRONIZE | EVENT_MODIFY_STATE,
&EventAttributes,
NotificationEvent,
FALSE // The event is initially not signaled
);
if (SUCCEEDED(hRetval))
{
DebugPrintf(SSPI_LOG, "CheckForNoOtherServerWithSamePort created event %s with handle %p\n", szEvent, *phEvent);
}
else if (STATUS_ACCESS_DENIED == (HRESULT) hRetval)
{
DebugPrintf(SSPI_WARN, "SspiServerMainLoopThread does not have permission to create events, brutal force\n");
hRetval DBGCHK = S_OK;
}
return hRetval;
}
DWORD WINAPI
SspiServerMainLoopThread(
IN PVOID pParameter // thread data
)
{
THResult hRetval = E_FAIL;
DWORD ThreadId = -1;
HANDLE hServerThread = NULL;
USHORT Port = 0;
SOCKET SocketListen = INVALID_SOCKET;
HANDLE hEvent = NULL;
TSsiServerMainLoopThreadParam* pSrvMainParam = (TSsiServerMainLoopThreadParam*) pParameter;
DebugPrintf(SSPI_LOG, "SspiServerMainLoopThread ParameterType %#x\n", pSrvMainParam->ParameterType);
hRetval DBGCHK = pSrvMainParam->ParameterType == kSspiSrvMainThreadParameters ? S_OK : E_INVALIDARG;
if (SUCCEEDED(hRetval))
{
DBGCFG1(hRetval, STATUS_OBJECT_NAME_COLLISION);
hRetval DBGCHK = CheckForNoOtherServerWithSamePort(pSrvMainParam->ServerSocketPort, &hEvent);
if (STATUS_OBJECT_NAME_COLLISION == (HRESULT) hRetval)
{
SspiPrint(SSPI_WARN, TEXT("SspiServerMainLoopThread found existing sspi server listening on port %#x(%d)\n"), pSrvMainParam->ServerSocketPort, pSrvMainParam->ServerSocketPort);
}
}
if (SUCCEEDED(hRetval))
{
DBGCFG1(hRetval, HRESULT_FROM_WIN32(WSAEADDRINUSE));
hRetval DBGCHK = ServerInit(pSrvMainParam->ServerSocketPort, "SspiServerMainLoop", &SocketListen);
}
THResult hr;
while (SUCCEEDED(hRetval))
{
SOCKET SocketClient = INVALID_SOCKET;
TSspiServerThreadParam* pSrvParam = NULL;
SocketClient = accept(SocketListen, NULL, NULL);
hRetval DBGCHK = INVALID_SOCKET != SocketClient ? S_OK : GetLastErrorAsHResult();
if (SUCCEEDED(hRetval))
{
hRetval DBGCHK = SspiAcquireServerParam(pSrvMainParam, &pSrvParam);
}
if (SUCCEEDED(hRetval))
{
pSrvParam->ServerSocket = SocketClient;
hServerThread = CreateThread(
NULL, // no SD
0, // user default stack size
SspiServerThread,
pSrvParam, // thread parameter
0, // no creation flags
&ThreadId
);
hRetval DBGCHK = hServerThread ? S_OK : GetLastErrorAsHResult();
}
if (FAILED(hRetval))
{
if (INVALID_SOCKET != SocketClient)
{
hr DBGCHK = closesocket(SocketClient) == ERROR_SUCCESS ? S_OK : HResultFromWin32(WSAGetLastError());
}
if (pSrvParam)
{
SspiReleaseServerParam(pSrvParam);
}
}
}
if (hServerThread)
{
hr DBGCHK = CloseHandle(hServerThread) ? S_OK : GetLastErrorAsHResult();;
}
if (INVALID_SOCKET != SocketListen)
{
hr DBGCHK = closesocket(SocketListen) == ERROR_SUCCESS ? S_OK : HResultFromWin32(WSAGetLastError());
}
if (hEvent)
{
hr DBGCHK = CloseHandle(hEvent) ? S_OK : GetLastErrorAsHResult();
}
DebugPrintf(SSPI_LOG, "SspiServerMainLoopThread exiting %#x\n", (HRESULT) hRetval);
return HRESULT_CODE(hRetval);
}
HRESULT
SspiStartCS(
IN OPTIONAL TSsiServerMainLoopThreadParam *pSrvMainParam,
IN OPTIONAL TSspiClientThreadParam* pCliParam
)
{
THResult hRetval = S_OK;
HANDLE hClientThread = NULL;
HANDLE hServerMainLoopThread = NULL;
DWORD ServerMainLoopThreadId = -1;
DWORD ClientThreadId = -1;
DebugPrintf(SSPI_LOG, "SspiStartCS entering pSrvMainParam %p, pCliParam %p\n", pSrvMainParam, pCliParam);
hRetval DBGCHK = InitWinsock() ? S_OK : GetLastErrorAsHResult();
if (SUCCEEDED(hRetval) && (TLS_OUT_OF_INDEXES == g_MessageNumTlsIndex))
{
g_MessageNumTlsIndex = TlsAlloc();
hRetval DBGCHK = (TLS_OUT_OF_INDEXES != g_MessageNumTlsIndex) ? S_OK : GetLastErrorAsHResult();
}
if (SUCCEEDED(hRetval) && pSrvMainParam)
{
hServerMainLoopThread = CreateThread(
NULL, // no SD
0, // user default stack size
SspiServerMainLoopThread,
pSrvMainParam, // thread parameter
0, // no creation flags
&ServerMainLoopThreadId
);
hRetval DBGCHK = hServerMainLoopThread ? S_OK : GetLastErrorAsHResult();
}
if (SUCCEEDED(hRetval) && pCliParam)
{
hClientThread = CreateThread(
NULL, // no SD
0, // user default stack size
SspiClientThread,
pCliParam, // thread parameter
0, // no creation flags
&ClientThreadId
);
hRetval DBGCHK = hClientThread ? S_OK : GetLastErrorAsHResult();
}
if (SUCCEEDED(hRetval) && hClientThread)
{
hRetval DBGCHK = HResultFromWin32(WaitForSingleObject(hClientThread, INFINITE));
}
if (SUCCEEDED(hRetval) && hServerMainLoopThread)
{
hRetval DBGCHK = HResultFromWin32(WaitForSingleObject(hServerMainLoopThread, INFINITE));
}
THResult hr;
if (hServerMainLoopThread)
{
hr DBGCHK = CloseHandle(hServerMainLoopThread) ? S_OK : GetLastErrorAsHResult();
}
if (hClientThread)
{
hr DBGCHK = CloseHandle(hClientThread) ? S_OK : GetLastErrorAsHResult();
}
if (TLS_OUT_OF_INDEXES != g_MessageNumTlsIndex)
{
TlsFree(g_MessageNumTlsIndex);
g_MessageNumTlsIndex = TLS_OUT_OF_INDEXES;
}
TermWinsock();
DebugPrintf(SSPI_LOG, "SspiStartCS leaving %#x\n", (HRESULT) hRetval);
return hRetval;
}