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

  1. /*++
  2. Copyright (c) 2001 Microsoft Corporation
  3. Module Name:
  4. sspics.cxx
  5. Abstract:
  6. sspics
  7. Author:
  8. Larry Zhu (LZhu) January 1, 2002 Created
  9. Environment:
  10. User Mode
  11. Revision History:
  12. --*/
  13. #include "precomp.hxx"
  14. #pragma hdrstop
  15. #include "sspics.hxx"
  16. TSspiClientThreadParam::TSspiClientThreadParam(
  17. VOID
  18. ) : ParameterType(kSspiCliThreadParameters),
  19. ServerSocketPort(kServerSocketPort),
  20. ClientSocketPort(kClientSocketPort),
  21. pszServer(NULL)
  22. {
  23. }
  24. TSspiClientThreadParam::~TSspiClientThreadParam(
  25. VOID
  26. )
  27. {
  28. }
  29. TSspiServerThreadParam::TSspiServerThreadParam(
  30. VOID
  31. ) : ParameterType(kSspiSrvThreadParameters),
  32. ServerSocket(INVALID_SOCKET)
  33. {
  34. }
  35. TSspiServerThreadParam::~TSspiServerThreadParam(
  36. VOID
  37. )
  38. {
  39. }
  40. TSsiServerMainLoopThreadParam::TSsiServerMainLoopThreadParam(
  41. VOID
  42. ) : ParameterType(kSspiSrvMainThreadParameters),
  43. ServerSocketPort(kServerSocketPort)
  44. {
  45. }
  46. TSsiServerMainLoopThreadParam::~TSsiServerMainLoopThreadParam(
  47. VOID
  48. )
  49. {
  50. }
  51. DWORD WINAPI
  52. SspiClientThread(
  53. IN PVOID pParameter // thread data
  54. )
  55. {
  56. THResult hRetval = E_FAIL;
  57. CHAR szClientComputerName[DNS_MAX_NAME_LENGTH + 1] = {0};
  58. TSspiClientThreadParam* pCliParam = (TSspiClientThreadParam*) pParameter;
  59. SOCKET ClientSocketListen = INVALID_SOCKET;
  60. SOCKET ServerSocket = INVALID_SOCKET;
  61. SOCKET ClientSocket = INVALID_SOCKET;
  62. DWORD ServerThreadId = 0;
  63. ULONG MessageNum = 0;
  64. DebugPrintf(SSPI_LOG, "SspiClientThread ParameterType %#x\n", pCliParam->ParameterType);
  65. hRetval DBGCHK = pCliParam->ParameterType == kSspiCliThreadParameters ? S_OK : E_INVALIDARG;
  66. if (SUCCEEDED(hRetval))
  67. {
  68. hRetval DBGCHK = TlsSetValue(g_MessageNumTlsIndex, &MessageNum) ? S_OK : GetLastErrorAsHResult();
  69. }
  70. if (SUCCEEDED(hRetval))
  71. {
  72. hRetval DBGCHK = gethostname(szClientComputerName, sizeof(szClientComputerName) - 1) == ERROR_SUCCESS ? S_OK : HResultFromWin32(WSAGetLastError());
  73. }
  74. if (SUCCEEDED(hRetval))
  75. {
  76. hRetval DBGCHK = ServerInit(pCliParam->ClientSocketPort, "SspiClient", &ClientSocketListen);
  77. }
  78. if (SUCCEEDED(hRetval))
  79. {
  80. DebugPrintf(SSPI_LOG, "SspiClientThread connecting to %s:%#x\n", pCliParam->pszServer, pCliParam->ServerSocketPort);
  81. hRetval DBGCHK = ClientConnect(
  82. pCliParam->pszServer,
  83. pCliParam->ServerSocketPort,
  84. &ServerSocket
  85. );
  86. }
  87. if (SUCCEEDED(hRetval))
  88. {
  89. hRetval DBGCHK = WriteMessage(
  90. ServerSocket,
  91. sizeof(pCliParam->ClientSocketPort),
  92. &pCliParam->ClientSocketPort
  93. );
  94. }
  95. if (SUCCEEDED(hRetval))
  96. {
  97. hRetval DBGCHK = WriteMessage(
  98. ServerSocket,
  99. strlen(szClientComputerName),
  100. szClientComputerName
  101. );
  102. }
  103. if (SUCCEEDED(hRetval))
  104. {
  105. ClientSocket = accept(ClientSocketListen, NULL, NULL);
  106. hRetval DBGCHK = (INVALID_SOCKET != ClientSocket) ? S_OK : HResultFromWin32(WSAGetLastError());
  107. }
  108. if (SUCCEEDED(hRetval))
  109. {
  110. ULONG cbRead = 0;
  111. hRetval DBGCHK = ReadMessage(
  112. ClientSocket,
  113. sizeof(ServerThreadId),
  114. &ServerThreadId,
  115. &cbRead
  116. );
  117. }
  118. if (SUCCEEDED(hRetval))
  119. {
  120. DebugPrintf(SSPI_LOG, "SspiClientThread got ServerThreadId %#x\n", ServerThreadId);
  121. hRetval DBGCHK = SspiClientStart(
  122. pCliParam,
  123. ServerSocket,
  124. ClientSocket
  125. );
  126. }
  127. THResult hr;
  128. if (INVALID_SOCKET != ClientSocket)
  129. {
  130. hr DBGCHK = closesocket(ClientSocket) == ERROR_SUCCESS ? S_OK : HResultFromWin32(WSAGetLastError());
  131. }
  132. if (INVALID_SOCKET != ServerSocket)
  133. {
  134. hr DBGCHK = closesocket(ServerSocket) == ERROR_SUCCESS ? S_OK : HResultFromWin32(WSAGetLastError());
  135. }
  136. if (INVALID_SOCKET != ClientSocketListen)
  137. {
  138. hr DBGCHK = closesocket(ClientSocketListen) == ERROR_SUCCESS ? S_OK : HResultFromWin32(WSAGetLastError());
  139. }
  140. //
  141. // use SspiPrint to get around -quiet
  142. //
  143. SspiPrint(SSPI_LOG, TEXT("SspiClientThread terminating %#x\n"), (HRESULT) hRetval);
  144. return HRESULT_CODE(hRetval);
  145. }
  146. DWORD WINAPI
  147. SspiServerThread(
  148. IN PVOID pParameter // thread data
  149. )
  150. {
  151. THResult hRetval = E_FAIL;
  152. USHORT ClientSocketPort = 0;
  153. CHAR szClientMachineName[DNS_MAX_NAME_LENGTH + 1] = {0};
  154. SOCKET ClientSocket = INVALID_SOCKET;
  155. SOCKET ServerSocket = INVALID_SOCKET;
  156. ULONG cbRead = 0;
  157. ULONG MessageNum = 0;
  158. TSspiServerThreadParam* pSrvParam = (TSspiServerThreadParam*) pParameter;
  159. DebugPrintf(SSPI_LOG, "SspiServerThread ParameterType %#x\n", pSrvParam->ParameterType);
  160. hRetval DBGCHK = pSrvParam && pSrvParam->ParameterType == kSspiSrvThreadParameters ? S_OK : E_INVALIDARG;
  161. if (SUCCEEDED(hRetval))
  162. {
  163. hRetval DBGCHK = TlsSetValue(g_MessageNumTlsIndex, &MessageNum) ? S_OK : GetLastErrorAsHResult();
  164. }
  165. if (SUCCEEDED(hRetval))
  166. {
  167. ServerSocket = pSrvParam->ServerSocket;
  168. hRetval DBGCHK = ReadMessage(
  169. ServerSocket,
  170. sizeof(ClientSocketPort),
  171. &ClientSocketPort,
  172. &cbRead
  173. );
  174. }
  175. if (SUCCEEDED(hRetval))
  176. {
  177. hRetval DBGCHK = ReadMessage(
  178. ServerSocket,
  179. sizeof(szClientMachineName) - 1,
  180. szClientMachineName,
  181. &cbRead
  182. );
  183. }
  184. if (SUCCEEDED(hRetval))
  185. {
  186. DebugPrintf(SSPI_LOG, "SspiServerThread Client Machine %s, Client Port %#x\n", szClientMachineName, ClientSocketPort);
  187. hRetval DBGCHK = ClientConnect(
  188. szClientMachineName,
  189. ClientSocketPort,
  190. &ClientSocket
  191. );
  192. }
  193. if (SUCCEEDED(hRetval))
  194. {
  195. DWORD dwThreadId = GetCurrentThreadId();
  196. hRetval DBGCHK = WriteMessage(
  197. ClientSocket,
  198. sizeof(dwThreadId),
  199. &dwThreadId
  200. );
  201. }
  202. THResult hr;
  203. if (SUCCEEDED(hRetval))
  204. {
  205. hRetval DBGCHK = SspiServerStart(pSrvParam, ClientSocket);
  206. }
  207. if (ClientSocket != INVALID_SOCKET)
  208. {
  209. hr DBGCHK = closesocket(ClientSocket) == ERROR_SUCCESS ? S_OK : HResultFromWin32(WSAGetLastError());
  210. }
  211. if (ServerSocket != INVALID_SOCKET)
  212. {
  213. hr DBGCHK = closesocket(ServerSocket);
  214. }
  215. SspiReleaseServerParam(pSrvParam);
  216. //
  217. // use SspiPrint to get around -quiet
  218. //
  219. SspiPrint(SSPI_LOG, TEXT("SspiServerThread terminating %#x\n"), (HRESULT) hRetval);
  220. return HRESULT_CODE(hRetval);
  221. }
  222. HRESULT
  223. CheckForNoOtherServerWithSamePort(
  224. IN ULONG Port,
  225. OUT HANDLE* phEvent
  226. )
  227. {
  228. THResult hRetval = E_FAIL;
  229. WCHAR szEvent[MAX_PATH] = {0};
  230. UNICODE_STRING EventName = {0};
  231. OBJECT_ATTRIBUTES EventAttributes = {0};
  232. _snwprintf(szEvent, COUNTOF(szEvent) - 1, L"\\SspiServerWithPort%#x(%d)", Port, Port);
  233. RtlInitUnicodeString( &EventName, szEvent );
  234. InitializeObjectAttributes(
  235. &EventAttributes,
  236. &EventName,
  237. 0, // no attributes
  238. NULL, // no RootDirectory
  239. NULL // no SecurityQualityOfService
  240. );
  241. DBGCFG2(hRetval, STATUS_OBJECT_NAME_COLLISION, STATUS_ACCESS_DENIED);
  242. hRetval DBGCHK = NtCreateEvent(
  243. phEvent,
  244. MAXIMUM_ALLOWED, // SYNCHRONIZE | EVENT_MODIFY_STATE,
  245. &EventAttributes,
  246. NotificationEvent,
  247. FALSE // The event is initially not signaled
  248. );
  249. if (SUCCEEDED(hRetval))
  250. {
  251. DebugPrintf(SSPI_LOG, "CheckForNoOtherServerWithSamePort created event %s with handle %p\n", szEvent, *phEvent);
  252. }
  253. else if (STATUS_ACCESS_DENIED == (HRESULT) hRetval)
  254. {
  255. DebugPrintf(SSPI_WARN, "SspiServerMainLoopThread does not have permission to create events, brutal force\n");
  256. hRetval DBGCHK = S_OK;
  257. }
  258. return hRetval;
  259. }
  260. DWORD WINAPI
  261. SspiServerMainLoopThread(
  262. IN PVOID pParameter // thread data
  263. )
  264. {
  265. THResult hRetval = E_FAIL;
  266. DWORD ThreadId = -1;
  267. HANDLE hServerThread = NULL;
  268. USHORT Port = 0;
  269. SOCKET SocketListen = INVALID_SOCKET;
  270. HANDLE hEvent = NULL;
  271. TSsiServerMainLoopThreadParam* pSrvMainParam = (TSsiServerMainLoopThreadParam*) pParameter;
  272. DebugPrintf(SSPI_LOG, "SspiServerMainLoopThread ParameterType %#x\n", pSrvMainParam->ParameterType);
  273. hRetval DBGCHK = pSrvMainParam->ParameterType == kSspiSrvMainThreadParameters ? S_OK : E_INVALIDARG;
  274. if (SUCCEEDED(hRetval))
  275. {
  276. DBGCFG1(hRetval, STATUS_OBJECT_NAME_COLLISION);
  277. hRetval DBGCHK = CheckForNoOtherServerWithSamePort(pSrvMainParam->ServerSocketPort, &hEvent);
  278. if (STATUS_OBJECT_NAME_COLLISION == (HRESULT) hRetval)
  279. {
  280. SspiPrint(SSPI_WARN, TEXT("SspiServerMainLoopThread found existing sspi server listening on port %#x(%d)\n"), pSrvMainParam->ServerSocketPort, pSrvMainParam->ServerSocketPort);
  281. }
  282. }
  283. if (SUCCEEDED(hRetval))
  284. {
  285. DBGCFG1(hRetval, HRESULT_FROM_WIN32(WSAEADDRINUSE));
  286. hRetval DBGCHK = ServerInit(pSrvMainParam->ServerSocketPort, "SspiServerMainLoop", &SocketListen);
  287. }
  288. THResult hr;
  289. while (SUCCEEDED(hRetval))
  290. {
  291. SOCKET SocketClient = INVALID_SOCKET;
  292. TSspiServerThreadParam* pSrvParam = NULL;
  293. SocketClient = accept(SocketListen, NULL, NULL);
  294. hRetval DBGCHK = INVALID_SOCKET != SocketClient ? S_OK : GetLastErrorAsHResult();
  295. if (SUCCEEDED(hRetval))
  296. {
  297. hRetval DBGCHK = SspiAcquireServerParam(pSrvMainParam, &pSrvParam);
  298. }
  299. if (SUCCEEDED(hRetval))
  300. {
  301. pSrvParam->ServerSocket = SocketClient;
  302. hServerThread = CreateThread(
  303. NULL, // no SD
  304. 0, // user default stack size
  305. SspiServerThread,
  306. pSrvParam, // thread parameter
  307. 0, // no creation flags
  308. &ThreadId
  309. );
  310. hRetval DBGCHK = hServerThread ? S_OK : GetLastErrorAsHResult();
  311. }
  312. if (FAILED(hRetval))
  313. {
  314. if (INVALID_SOCKET != SocketClient)
  315. {
  316. hr DBGCHK = closesocket(SocketClient) == ERROR_SUCCESS ? S_OK : HResultFromWin32(WSAGetLastError());
  317. }
  318. if (pSrvParam)
  319. {
  320. SspiReleaseServerParam(pSrvParam);
  321. }
  322. }
  323. }
  324. if (hServerThread)
  325. {
  326. hr DBGCHK = CloseHandle(hServerThread) ? S_OK : GetLastErrorAsHResult();;
  327. }
  328. if (INVALID_SOCKET != SocketListen)
  329. {
  330. hr DBGCHK = closesocket(SocketListen) == ERROR_SUCCESS ? S_OK : HResultFromWin32(WSAGetLastError());
  331. }
  332. if (hEvent)
  333. {
  334. hr DBGCHK = CloseHandle(hEvent) ? S_OK : GetLastErrorAsHResult();
  335. }
  336. DebugPrintf(SSPI_LOG, "SspiServerMainLoopThread exiting %#x\n", (HRESULT) hRetval);
  337. return HRESULT_CODE(hRetval);
  338. }
  339. HRESULT
  340. SspiStartCS(
  341. IN OPTIONAL TSsiServerMainLoopThreadParam *pSrvMainParam,
  342. IN OPTIONAL TSspiClientThreadParam* pCliParam
  343. )
  344. {
  345. THResult hRetval = S_OK;
  346. HANDLE hClientThread = NULL;
  347. HANDLE hServerMainLoopThread = NULL;
  348. DWORD ServerMainLoopThreadId = -1;
  349. DWORD ClientThreadId = -1;
  350. DebugPrintf(SSPI_LOG, "SspiStartCS entering pSrvMainParam %p, pCliParam %p\n", pSrvMainParam, pCliParam);
  351. hRetval DBGCHK = InitWinsock() ? S_OK : GetLastErrorAsHResult();
  352. if (SUCCEEDED(hRetval) && (TLS_OUT_OF_INDEXES == g_MessageNumTlsIndex))
  353. {
  354. g_MessageNumTlsIndex = TlsAlloc();
  355. hRetval DBGCHK = (TLS_OUT_OF_INDEXES != g_MessageNumTlsIndex) ? S_OK : GetLastErrorAsHResult();
  356. }
  357. if (SUCCEEDED(hRetval) && pSrvMainParam)
  358. {
  359. hServerMainLoopThread = CreateThread(
  360. NULL, // no SD
  361. 0, // user default stack size
  362. SspiServerMainLoopThread,
  363. pSrvMainParam, // thread parameter
  364. 0, // no creation flags
  365. &ServerMainLoopThreadId
  366. );
  367. hRetval DBGCHK = hServerMainLoopThread ? S_OK : GetLastErrorAsHResult();
  368. }
  369. if (SUCCEEDED(hRetval) && pCliParam)
  370. {
  371. hClientThread = CreateThread(
  372. NULL, // no SD
  373. 0, // user default stack size
  374. SspiClientThread,
  375. pCliParam, // thread parameter
  376. 0, // no creation flags
  377. &ClientThreadId
  378. );
  379. hRetval DBGCHK = hClientThread ? S_OK : GetLastErrorAsHResult();
  380. }
  381. if (SUCCEEDED(hRetval) && hClientThread)
  382. {
  383. hRetval DBGCHK = HResultFromWin32(WaitForSingleObject(hClientThread, INFINITE));
  384. }
  385. if (SUCCEEDED(hRetval) && hServerMainLoopThread)
  386. {
  387. hRetval DBGCHK = HResultFromWin32(WaitForSingleObject(hServerMainLoopThread, INFINITE));
  388. }
  389. THResult hr;
  390. if (hServerMainLoopThread)
  391. {
  392. hr DBGCHK = CloseHandle(hServerMainLoopThread) ? S_OK : GetLastErrorAsHResult();
  393. }
  394. if (hClientThread)
  395. {
  396. hr DBGCHK = CloseHandle(hClientThread) ? S_OK : GetLastErrorAsHResult();
  397. }
  398. if (TLS_OUT_OF_INDEXES != g_MessageNumTlsIndex)
  399. {
  400. TlsFree(g_MessageNumTlsIndex);
  401. g_MessageNumTlsIndex = TLS_OUT_OF_INDEXES;
  402. }
  403. TermWinsock();
  404. DebugPrintf(SSPI_LOG, "SspiStartCS leaving %#x\n", (HRESULT) hRetval);
  405. return hRetval;
  406. }