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.

551 lines
15 KiB

  1. /*++
  2. Copyright (c) 2001 Microsoft Corporation
  3. Module Name:
  4. main.cxx
  5. Abstract:
  6. main
  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 "main.hxx"
  16. #include "msvsharelevelcli.hxx"
  17. #include "msvsharelevelsrv.hxx"
  18. #include <sockcomm.h>
  19. #include <transport.hxx>
  20. VOID
  21. Usage(
  22. IN PCTSTR pszApp
  23. )
  24. {
  25. SspiPrint(SSPI_ERROR,
  26. TEXT("\n\nUsage: %s [-srvcomputerdomainname srvcomputerdomainname>] ")
  27. TEXT("[-supplieduser <user>] [-supplieddomain <domain>] [-suppliedpassword <password>] ")
  28. TEXT("[-serverhostname <serverhostname>] [-portnum <portnum>] [-nocheckclictxt] [-nochecksrvctxt] \n\n"), pszApp);
  29. exit(-1);
  30. }
  31. VOID
  32. checkpoint(
  33. VOID
  34. )
  35. {
  36. SspiPrint(SSPI_LOG, TEXT("checkpoint\n"));
  37. ASSERT(FALSE);
  38. }
  39. struct TClientParameter {
  40. AUTHENTICATE_MESSAGE* pAuthMessage;
  41. ULONG cbAuthMessage;
  42. NTLM_AUTHENTICATE_MESSAGE* pNtlmAuthMessage;
  43. PCSTR pszServer;
  44. USHORT ServerSocketPort;
  45. };
  46. DWORD WINAPI
  47. ClientThread(
  48. IN PVOID pParameter // thread data
  49. )
  50. {
  51. THResult hRetval = S_OK;
  52. TClientParameter *pCliParam = (TClientParameter* ) pParameter;
  53. SOCKET ClientSocket = INVALID_SOCKET;
  54. ULONG MessageNum = 0;
  55. SspiPrint(SSPI_LOG, TEXT("ClientThread entering %#x\n"), g_MessageNumTlsIndex);
  56. hRetval DBGCHK = TlsSetValue(g_MessageNumTlsIndex, &MessageNum) ? S_OK : GetLastErrorAsHResult();
  57. if (SUCCEEDED(hRetval))
  58. {
  59. hRetval DBGCHK = ClientConnect(
  60. pCliParam->pszServer,
  61. pCliParam->ServerSocketPort,
  62. &ClientSocket
  63. );
  64. }
  65. if (SUCCEEDED(hRetval))
  66. {
  67. hRetval DBGCHK = WriteMessage(
  68. ClientSocket,
  69. pCliParam->cbAuthMessage,
  70. pCliParam->pAuthMessage
  71. );
  72. }
  73. if (SUCCEEDED(hRetval))
  74. {
  75. hRetval DBGCHK = WriteMessage(
  76. ClientSocket,
  77. sizeof(NTLM_AUTHENTICATE_MESSAGE),
  78. pCliParam->pNtlmAuthMessage
  79. );
  80. }
  81. if (INVALID_SOCKET != ClientSocket)
  82. {
  83. closesocket(ClientSocket);
  84. }
  85. SspiPrint(SSPI_LOG, TEXT("ClientThread leaving\n"));
  86. return hRetval;
  87. }
  88. VOID __cdecl
  89. _tmain(
  90. IN INT argc,
  91. IN PTSTR argv[]
  92. )
  93. {
  94. TNtStatus Status = STATUS_SUCCESS;
  95. ULONG mark = 1;
  96. CtxtHandle hCliCtxt;
  97. CtxtHandle hSrvCtxt;
  98. HANDLE hToken = NULL;
  99. SOCKET SocketListen = INVALID_SOCKET;
  100. SOCKET ServerSocket = INVALID_SOCKET;
  101. HANDLE hClientThread = NULL;
  102. SEC_WINNT_AUTH_IDENTITY SrvAuthData = {0};
  103. SEC_WINNT_AUTH_IDENTITY* pSrvAuth = NULL;
  104. SEC_WINNT_AUTH_IDENTITY_EXW* pCliAuth = NULL;
  105. UNICODE_STRING TargetInfo = {0};
  106. UNICODE_STRING TargetName = {0};
  107. AUTHENTICATE_MESSAGE* pAuthMessage = NULL;
  108. ULONG cbAuthMessage = 0;
  109. TClientParameter CliParam = {0};
  110. ULONG ClientThreadId = 0;
  111. ULONG MessageNum = 0;
  112. NTLM_AUTHENTICATE_MESSAGE NtlmAuthMessage = {0};
  113. UNICODE_STRING SrvDnsDomainName = {0};
  114. UNICODE_STRING SrvDnsComputerName = {0};
  115. UNICODE_STRING SrvDnsTreeName = {0};
  116. UNICODE_STRING SrvComputerName = {0};
  117. UNICODE_STRING SrvComputerDomainName = {0};
  118. PCTSTR pszClientName = NULL;
  119. PCTSTR pszClientDomain = NULL;
  120. PCTSTR pszClientPassword = NULL;
  121. PCTSTR pszServerName = NULL;
  122. PCTSTR pszServerDomain = NULL;
  123. PCTSTR pszServerPassword = NULL;
  124. PTSTR pszSrvCredPrincipal = NULL;
  125. PTSTR pszCliCredPrincipal = NULL;
  126. UNICODE_STRING UserName = {0};
  127. UNICODE_STRING Password = {0};
  128. UNICODE_STRING DomainName = {0};
  129. OEM_STRING CliOemDomainName = {0};
  130. OEM_STRING CliOemWorkstationName = {0};
  131. ULONG CliNegotiateFlags =
  132. NTLMSSP_NEGOTIATE_UNICODE
  133. | NTLMSSP_NEGOTIATE_OEM
  134. | NTLMSSP_REQUEST_TARGET
  135. | NTLMSSP_NEGOTIATE_NTLM
  136. | NTLMSSP_NEGOTIATE_ALWAYS_SIGN
  137. | NTLMSSP_NEGOTIATE_NTLM2
  138. | NTLMSSP_NEGOTIATE_IDENTIFY
  139. | NTLMSSP_NEGOTIATE_128;
  140. ULONG CliTargetFlags = NTLMSSP_TARGET_TYPE_SERVER; // NTLMSSP_TARGET_TYPE_DOMAIN
  141. BOOLEAN bCliForceGuest = FALSE;
  142. ULONG CliContextAttr = ISC_REQ_MUTUAL_AUTH | ISC_REQ_REPLAY_DETECT | ISC_REQ_CONFIDENTIALITY;
  143. ULONG SrvContextAttr = ASC_REQ_EXTENDED_ERROR;
  144. LUID* pCliCredLogonID = NULL;
  145. LUID CliCredLogonId = {0};
  146. LUID* pSrvCredLogonID = NULL;
  147. LUID SrvCredLogonId = {0};
  148. ULONG CliTargetDataRep = SECURITY_NATIVE_DREP;
  149. ULONG SrvTargetDataRep = SECURITY_NATIVE_DREP;
  150. BOOLEAN bCheckClientCtxt = TRUE;
  151. BOOLEAN bCheckServerCtxt = TRUE;
  152. BOOLEAN bServerCheckUserData = FALSE;
  153. BOOLEAN bServerCheckUserToken = FALSE;
  154. BOOLEAN bStartServer = TRUE;
  155. BOOLEAN bStartClient = TRUE;
  156. USHORT PortNum = 6217;
  157. PSTR pszServerHostName = NULL;
  158. UNICODE_STRING ServerHostName = {0};
  159. ANSI_STRING ServerAnsiName = {0};
  160. TPrivilege* pPriv = NULL;
  161. SspiLogOpen(TEXT("msv.exe"), SSPI_LOG | SSPI_WARN | SSPI_ERROR | SSPI_MSG);
  162. DebugLogOpen("msv", SSPI_LOG | SSPI_WARN | SSPI_ERROR | SSPI_MSG);
  163. SecInvalidateHandle(&hCliCtxt);
  164. SecInvalidateHandle(&hSrvCtxt);
  165. (VOID) RtlGenRandom(NtlmAuthMessage.ChallengeToClient, MSV1_0_CHALLENGE_LENGTH);
  166. argc--;
  167. while (argc)
  168. {
  169. if (!lstrcmp(argv[mark], TEXT("-srvcomputerdomainname")) && argc > 1)
  170. {
  171. argc--; mark++;
  172. RtlInitUnicodeString(&SrvComputerDomainName, argv[mark]);
  173. argc--; mark++;
  174. }
  175. else if (!lstrcmp(argv[mark], TEXT("-supplieduser")) && argc > 1)
  176. {
  177. argc--; mark++;
  178. RtlInitUnicodeString(&UserName, argv[mark]);
  179. pszClientName = UserName.Buffer;
  180. argc--; mark++;
  181. }
  182. else if (!lstrcmp(argv[mark], TEXT("-supplieddomain")) && argc > 1)
  183. {
  184. argc--; mark++;
  185. RtlInitUnicodeString(&DomainName, argv[mark]);
  186. pszClientDomain = DomainName.Buffer;
  187. argc--; mark++;
  188. }
  189. else if (!lstrcmp(argv[mark], TEXT("-suppliedpassword")) && argc > 1)
  190. {
  191. argc--; mark++;
  192. RtlInitUnicodeString(&Password, argv[mark]);
  193. pszClientPassword = Password.Buffer;
  194. argc--; mark++;
  195. }
  196. else if (!lstrcmp(argv[mark], TEXT("-serverhostname")) && argc > 1)
  197. {
  198. argc--; mark++;
  199. RtlInitUnicodeString(&ServerHostName, argv[mark]);
  200. Status DBGCHK = RtlUnicodeStringToAnsiString(&ServerAnsiName, &ServerHostName, TRUE);
  201. bStartServer = FALSE;
  202. argc--; mark++;
  203. }
  204. else if (!lstrcmp(argv[mark], TEXT("-portnum")) && argc > 1)
  205. {
  206. argc--; mark++;
  207. PortNum = (USHORT) lstrtol(argv[mark], NULL, 0);
  208. argc--; mark++;
  209. }
  210. else if (!lstrcmp(argv[mark], TEXT("-noserver")))
  211. {
  212. argc--; mark++;
  213. bStartServer = FALSE;
  214. }
  215. else if (!lstrcmp(argv[mark], TEXT("-noclient")))
  216. {
  217. argc--; mark++;
  218. bStartClient = FALSE;
  219. }
  220. else if (!lstrcmp(argv[mark], TEXT("-nocheckclictxt")))
  221. {
  222. argc--; mark++;
  223. bCheckClientCtxt = FALSE;
  224. }
  225. else if (!lstrcmp(argv[mark], TEXT("-nochecksrvctxt")))
  226. {
  227. argc--; mark++;
  228. bCheckServerCtxt = FALSE;
  229. }
  230. else if (!lstrcmp(argv[mark], TEXT("-h")))
  231. {
  232. argc--; mark++;
  233. Usage(argv[0]);
  234. }
  235. else
  236. {
  237. Usage(argv[0]);
  238. }
  239. }
  240. SOCKET Socket = INVALID_SOCKET;
  241. Status DBGCHK = InitWinsock() ? S_OK : GetLastErrorAsHResult();
  242. if (NT_SUCCESS(Status) && (TLS_OUT_OF_INDEXES == g_MessageNumTlsIndex))
  243. {
  244. g_MessageNumTlsIndex = TlsAlloc();
  245. Status DBGCHK = (TLS_OUT_OF_INDEXES != g_MessageNumTlsIndex) ? S_OK : GetLastErrorAsHResult();
  246. }
  247. if (NT_SUCCESS(Status) && bStartServer)
  248. {
  249. Status DBGCHK = ServerInit(PortNum, "msvsharelevel server", &SocketListen);
  250. if (NT_SUCCESS(Status))
  251. {
  252. Status DBGCHK = TlsSetValue(g_MessageNumTlsIndex, &MessageNum) ? S_OK : GetLastErrorAsHResult();
  253. }
  254. //
  255. // server must hold TCB
  256. //
  257. if (NT_SUCCESS(Status))
  258. {
  259. pPriv = new TPrivilege(SE_TCB_PRIVILEGE, TRUE);
  260. Status DBGCHK = pPriv ? pPriv->Validate() : E_OUTOFMEMORY;
  261. }
  262. }
  263. if (NT_SUCCESS(Status) && bStartClient)
  264. {
  265. if (pszClientName || pszClientDomain || pszClientPassword)
  266. {
  267. Status DBGCHK = GetAuthdataExWMarshalled(
  268. pszClientName,
  269. pszClientDomain,
  270. pszClientPassword,
  271. L"ntlm",
  272. &pCliAuth
  273. );
  274. }
  275. if (NT_SUCCESS(Status))
  276. {
  277. Status DBGCHK = MsvChallenge(
  278. pszCliCredPrincipal,
  279. pCliCredLogonID,
  280. pCliAuth,
  281. &CliOemDomainName,
  282. &CliOemWorkstationName,
  283. CliNegotiateFlags,
  284. CliTargetFlags,
  285. bCliForceGuest,
  286. CliContextAttr,
  287. CliTargetDataRep,
  288. &Password,
  289. &UserName,
  290. &DomainName,
  291. (UCHAR*) NtlmAuthMessage.ChallengeToClient,
  292. &SrvDnsDomainName,
  293. &SrvDnsComputerName,
  294. &SrvDnsTreeName,
  295. &SrvComputerName,
  296. &SrvComputerDomainName,
  297. &cbAuthMessage,
  298. &pAuthMessage,
  299. &hCliCtxt,
  300. &CliContextAttr
  301. );
  302. }
  303. if (NT_SUCCESS(Status) && bCheckClientCtxt)
  304. {
  305. SspiPrint(SSPI_LOG, TEXT("***************Checking client ctxt handle*************\n"));
  306. Status DBGCHK = CheckSecurityContextHandle(&hCliCtxt);
  307. }
  308. if (NT_SUCCESS(Status))
  309. {
  310. CliParam.cbAuthMessage = cbAuthMessage;
  311. CliParam.pAuthMessage = pAuthMessage;
  312. CliParam.pNtlmAuthMessage = &NtlmAuthMessage;
  313. CliParam.pszServer = ServerAnsiName.Buffer;
  314. CliParam.ServerSocketPort = PortNum;
  315. hClientThread = CreateThread(
  316. NULL, // no SD
  317. 0, // user default stack size
  318. ClientThread,
  319. &CliParam, // thread parameter
  320. 0, // no creation flags
  321. &ClientThreadId
  322. );
  323. Status DBGCHK = hClientThread ? S_OK : GetLastErrorAsHResult();
  324. }
  325. }
  326. //
  327. // server must hold TCB for sharelevels
  328. //
  329. if (NT_SUCCESS(Status) && bStartServer)
  330. {
  331. BOOLEAN WasEnabled = FALSE;
  332. ULONG cbAuthMsg = 0;
  333. CHAR AuthMsg[NTLMSSP_MAX_MESSAGE_SIZE] = {0};
  334. NTLM_AUTHENTICATE_MESSAGE NtLmAuthMsg = {0};
  335. AUTHENTICATE_MESSAGE* pAuthMsg = (AUTHENTICATE_MESSAGE*) AuthMsg;
  336. ServerSocket = accept(SocketListen, NULL, NULL);
  337. Status DBGCHK = INVALID_SOCKET != ServerSocket ? S_OK : GetLastErrorAsHResult();
  338. if (NT_SUCCESS(Status))
  339. {
  340. Status DBGCHK = ReadMessage(
  341. ServerSocket,
  342. NTLMSSP_MAX_MESSAGE_SIZE,
  343. AuthMsg,
  344. &cbAuthMsg
  345. );
  346. }
  347. if (NT_SUCCESS(Status))
  348. {
  349. ULONG cbRead = 0;
  350. Status DBGCHK = ReadMessage(
  351. ServerSocket,
  352. sizeof(NtLmAuthMsg),
  353. &NtLmAuthMsg,
  354. &cbRead
  355. );
  356. }
  357. if (NT_SUCCESS(Status) && (pszServerName || pszServerDomain || pszServerPassword))
  358. {
  359. pSrvAuth = &SrvAuthData;
  360. GetAuthdata(
  361. pszServerName,
  362. pszServerDomain,
  363. pszServerPassword,
  364. &SrvAuthData
  365. );
  366. }
  367. if (NT_SUCCESS(Status))
  368. {
  369. Status DBGCHK = MsvAuthenticate(
  370. pszSrvCredPrincipal,
  371. pSrvCredLogonID,
  372. pSrvAuth,
  373. SrvContextAttr,
  374. SrvTargetDataRep,
  375. cbAuthMsg,
  376. pAuthMsg,
  377. &NtLmAuthMsg,
  378. &hSrvCtxt,
  379. &SrvContextAttr
  380. );
  381. }
  382. if (NT_SUCCESS(Status) && bCheckServerCtxt)
  383. {
  384. SspiPrint(SSPI_LOG, TEXT("***************Checking server ctxt handle*************\n"));
  385. Status DBGCHK = CheckSecurityContextHandle(&hSrvCtxt);
  386. }
  387. if (NT_SUCCESS(Status))
  388. {
  389. Status DBGCHK = ImpersonateSecurityContext(&hSrvCtxt);
  390. }
  391. if (NT_SUCCESS(Status) && bServerCheckUserData)
  392. {
  393. SspiPrint(SSPI_LOG, TEXT("**************Server checking user data via ImpersonateSecurityContext ******\n"));
  394. Status DBGCHK = CheckUserData();
  395. }
  396. if (NT_SUCCESS(Status))
  397. {
  398. Status DBGCHK = RevertSecurityContext(&hSrvCtxt);
  399. }
  400. if (NT_SUCCESS(Status) && bServerCheckUserToken)
  401. {
  402. Status DBGCHK = QuerySecurityContextToken(&hSrvCtxt, &hToken);
  403. }
  404. if (NT_SUCCESS(Status) && bServerCheckUserToken)
  405. {
  406. SspiPrint(SSPI_LOG, TEXT("**************Server checking user data via QuerySecurityContextToken ******\n"));
  407. Status DBGCHK = CheckUserToken(hToken);
  408. }
  409. }
  410. if (NT_SUCCESS(Status) && hClientThread)
  411. {
  412. Status DBGCHK = HResultFromWin32(WaitForSingleObject(hClientThread, INFINITE));
  413. }
  414. if (pPriv)
  415. {
  416. delete pPriv;
  417. }
  418. if (pCliAuth)
  419. {
  420. delete [] pCliAuth;
  421. }
  422. if (NT_SUCCESS(Status))
  423. {
  424. SspiPrint(SSPI_LOG, TEXT("Operation succeeded\n"));
  425. }
  426. else
  427. {
  428. SspiPrint(SSPI_ERROR, TEXT("Operation failed\n"));
  429. }
  430. TermWinsock();
  431. if (pAuthMessage)
  432. {
  433. FreeContextBuffer(pAuthMessage);
  434. }
  435. if (SecIsValidHandle(&hCliCtxt))
  436. {
  437. DeleteSecurityContext(&hCliCtxt);
  438. }
  439. if (SecIsValidHandle(&hSrvCtxt))
  440. {
  441. DeleteSecurityContext(&hSrvCtxt);
  442. }
  443. if (hToken)
  444. {
  445. CloseHandle(hToken);
  446. }
  447. if (TLS_OUT_OF_INDEXES != g_MessageNumTlsIndex)
  448. {
  449. TlsFree(g_MessageNumTlsIndex);
  450. g_MessageNumTlsIndex = TLS_OUT_OF_INDEXES;
  451. }
  452. if (hClientThread)
  453. {
  454. CloseHandle(hClientThread);
  455. }
  456. if (INVALID_SOCKET != SocketListen)
  457. {
  458. closesocket(SocketListen);
  459. }
  460. if (INVALID_SOCKET != ServerSocket)
  461. {
  462. closesocket(ServerSocket);
  463. }
  464. DebugLogClose();
  465. SspiLogClose();
  466. }