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.

1926 lines
69 KiB

  1. /*++ BUILD Version: 0009 // Increment this if a change has global effects
  2. Copyright (c) 1987-1993 Microsoft Corporation
  3. Module Name:
  4. sessetup.c
  5. Abstract:
  6. This module implements the Session setup related routines
  7. Author:
  8. Balan Sethu Raman (SethuR) 06-Mar-95 Created
  9. --*/
  10. #include "precomp.h"
  11. #pragma hdrstop
  12. #include "exsessup.h"
  13. #include "ntlsapi.h"
  14. #include "mrxsec.h"
  15. #include "rdrssp\kfuncs.h"
  16. #include "rdrssp\secret.h"
  17. #include <wincred.h>
  18. #include <secpkg.h>
  19. #ifdef ALLOC_PRAGMA
  20. #pragma alloc_text(PAGE, BuildSessionSetupSmb)
  21. #pragma alloc_text(PAGE, BuildNtLanmanResponsePrologue)
  22. #pragma alloc_text(PAGE, BuildNtLanmanResponseEpilogue)
  23. #pragma alloc_text(PAGE, BuildExtendedSessionSetupResponsePrologue)
  24. #pragma alloc_text(PAGE, BuildExtendedSessionSetupResponseEpilogue)
  25. #endif
  26. extern BOOLEAN MRxSmbSecuritySignaturesEnabled;
  27. UNICODE_STRING CifsServiceName = { 8, 10, L"cifs" };
  28. NTSTATUS
  29. BuildSessionSetupSmb(
  30. PSMB_EXCHANGE pExchange,
  31. PGENERIC_ANDX pAndXSmb,
  32. PULONG pAndXSmbBufferSize)
  33. /*++
  34. Routine Description:
  35. This routine builds the session setup SMB for a NT server
  36. Arguments:
  37. pExchange - the exchange instance
  38. pAndXSmb - the session setup to be filled in
  39. pAndXSmbBufferSize - the SMB buffer size on input modified to remaining size on
  40. output.
  41. Return Value:
  42. NTSTATUS - The return status for the operation
  43. Notes:
  44. Eventhough the general structure of the code tries to isolate dialect specific issues
  45. as much as possible this routine takes the opposite approach. This is because of the
  46. preamble and prologue to security interaction which far outweigh the dialect specific
  47. work required to be done. Therefore in the interests of a smaller footprint this approach
  48. has been adopted.
  49. --*/
  50. {
  51. NTSTATUS Status;
  52. PSMBCEDB_SESSION_ENTRY pSessionEntry;
  53. PSMBCE_SERVER pServer;
  54. PSMBCE_SESSION pSession;
  55. PREQ_SESSION_SETUP_ANDX pSessionSetup;
  56. PREQ_NT_SESSION_SETUP_ANDX pNtSessionSetup;
  57. PREQ_NT_EXTENDED_SESSION_SETUP_ANDX pExtendedNtSessionSetup;
  58. ULONG OriginalBufferSize = *pAndXSmbBufferSize;
  59. PAGED_CODE();
  60. pSessionEntry = SmbCeGetExchangeSessionEntry(pExchange);
  61. pServer = SmbCeGetExchangeServer(pExchange);
  62. pSession = SmbCeGetExchangeSession(pExchange);
  63. // There are three different variants of session setup and X that can be shipped to the
  64. // server. All three of them share some common fields. The setting of these common fields
  65. // is done in all the three cases by accessing the passed in buffer as an instance of
  66. // REQ_SESSION_SETUP_ANDX. The fields specific to the remaining two are conditionalized upon
  67. // accessing the same buffer as an instance of REQ_NT_SESSION_SETUP_ANDX and
  68. // REQ_EXTENDED_NT_SESSION_SETUP_ANDX respectively. This implies that great care must be
  69. // taken in shuffling the fields in these three structs.
  70. pSessionSetup = (PREQ_SESSION_SETUP_ANDX)pAndXSmb;
  71. pNtSessionSetup = (PREQ_NT_SESSION_SETUP_ANDX)pSessionSetup;
  72. pExtendedNtSessionSetup = (PREQ_NT_EXTENDED_SESSION_SETUP_ANDX)pSessionSetup;
  73. pSessionSetup->AndXCommand = 0xff; // No ANDX
  74. pSessionSetup->AndXReserved = 0x00; // Reserved (MBZ)
  75. SmbPutUshort(&pSessionSetup->AndXOffset, 0x0000); // No AndX as of yet.
  76. // Since we can allocate pool dynamically, we set our buffer size
  77. // to match that of the server.
  78. SmbPutUshort(&pSessionSetup->MaxBufferSize, (USHORT)pServer->MaximumBufferSize);
  79. SmbPutUshort(&pSessionSetup->MaxMpxCount, pServer->MaximumRequests);
  80. SmbPutUshort(&pSessionSetup->VcNumber, (USHORT)pSessionEntry->SessionVCNumber);
  81. SmbPutUlong(&pSessionSetup->SessionKey, pServer->SessionKey);
  82. SmbPutUlong(&pSessionSetup->Reserved, 0);
  83. if (pServer->Dialect == NTLANMAN_DIALECT) {
  84. // Set up the NT server session setup specific parameters.
  85. if (FlagOn(pServer->DialectFlags,DF_EXTENDED_SECURITY) &&
  86. !FlagOn(pSession->Flags,SMBCE_SESSION_FLAGS_REMOTE_BOOT_SESSION)) {
  87. SmbPutUshort(&pExtendedNtSessionSetup->WordCount,12);
  88. // Set the capabilities
  89. SmbPutUlong(
  90. &pExtendedNtSessionSetup->Capabilities,
  91. (CAP_NT_STATUS |
  92. CAP_UNICODE |
  93. CAP_LEVEL_II_OPLOCKS |
  94. CAP_NT_SMBS |
  95. CAP_DYNAMIC_REAUTH |
  96. CAP_EXTENDED_SECURITY));
  97. } else {
  98. SmbPutUshort(&pNtSessionSetup->WordCount,13);
  99. // Set the capabilities
  100. SmbPutUlong(
  101. &pNtSessionSetup->Capabilities,
  102. (CAP_NT_STATUS |
  103. CAP_UNICODE |
  104. CAP_LEVEL_II_OPLOCKS |
  105. CAP_NT_SMBS ));
  106. }
  107. } else {
  108. SmbPutUshort(&pSessionSetup->WordCount,10);
  109. }
  110. // Build the security information in the session setup SMB.
  111. Status = BuildSessionSetupSecurityInformation(
  112. pExchange,
  113. (PBYTE)pSessionSetup,
  114. pAndXSmbBufferSize);
  115. if (NT_SUCCESS(Status)) {
  116. // Copy the operating system name and the LANMAN version info
  117. // position the buffer for copying the operating system name and the lanman type.
  118. PBYTE pBuffer = (PBYTE)pSessionSetup +
  119. OriginalBufferSize -
  120. *pAndXSmbBufferSize;
  121. if (FlagOn(pServer->DialectFlags,DF_UNICODE)){
  122. //
  123. // Make sure the UNICODE string is suitably aligned
  124. //
  125. if( ((ULONG_PTR)pBuffer) & 01 ) {
  126. if (*pAndXSmbBufferSize > 0) {
  127. pBuffer++;
  128. (*pAndXSmbBufferSize)--;
  129. } else {
  130. Status = STATUS_BUFFER_OVERFLOW;
  131. }
  132. }
  133. if (NT_SUCCESS(Status)) {
  134. Status = SmbPutUnicodeString(
  135. &pBuffer,
  136. &SmbCeContext.OperatingSystem,
  137. pAndXSmbBufferSize);
  138. }
  139. if (NT_SUCCESS(Status)) {
  140. Status = SmbPutUnicodeString(
  141. &pBuffer,
  142. &SmbCeContext.LanmanType,
  143. pAndXSmbBufferSize);
  144. }
  145. } else {
  146. Status = SmbPutUnicodeStringAsOemString(
  147. &pBuffer,
  148. &SmbCeContext.OperatingSystem,
  149. pAndXSmbBufferSize);
  150. if (NT_SUCCESS(Status)) {
  151. Status = SmbPutUnicodeStringAsOemString(
  152. &pBuffer,
  153. &SmbCeContext.LanmanType,
  154. pAndXSmbBufferSize);
  155. }
  156. }
  157. if (NT_SUCCESS(Status)) {
  158. if (pServer->Dialect == NTLANMAN_DIALECT) {
  159. if (FlagOn(pServer->DialectFlags,DF_EXTENDED_SECURITY) &&
  160. !FlagOn(pSession->Flags,SMBCE_SESSION_FLAGS_REMOTE_BOOT_SESSION)) {
  161. SmbPutUshort(
  162. &pExtendedNtSessionSetup->ByteCount,
  163. (USHORT)(OriginalBufferSize -
  164. FIELD_OFFSET(REQ_NT_EXTENDED_SESSION_SETUP_ANDX,Buffer) -
  165. *pAndXSmbBufferSize));
  166. } else {
  167. SmbPutUshort(
  168. &pNtSessionSetup->ByteCount,
  169. (USHORT)(OriginalBufferSize -
  170. FIELD_OFFSET(REQ_NT_SESSION_SETUP_ANDX,Buffer) -
  171. *pAndXSmbBufferSize));
  172. }
  173. } else {
  174. SmbPutUshort(
  175. &pSessionSetup->ByteCount,
  176. (USHORT)(OriginalBufferSize -
  177. FIELD_OFFSET(REQ_SESSION_SETUP_ANDX,Buffer) -
  178. *pAndXSmbBufferSize));
  179. }
  180. }
  181. }
  182. return Status;
  183. }
  184. NTSTATUS
  185. BuildNtLanmanResponsePrologue(
  186. PSMB_EXCHANGE pExchange,
  187. PUNICODE_STRING pUserName,
  188. PUNICODE_STRING pDomainName,
  189. PSTRING pCaseSensitiveResponse,
  190. PSTRING pCaseInsensitiveResponse,
  191. PSECURITY_RESPONSE_CONTEXT pResponseContext)
  192. /*++
  193. Routine Description:
  194. This routine builds the security related information for the session setup SMB to
  195. without extended security negotiation
  196. Arguments:
  197. Return Value:
  198. RXSTATUS - The return status for the operation
  199. Notes:
  200. This routine needs to be executed in the system process in order to protect virtual memory
  201. --*/
  202. {
  203. NTSTATUS Status;
  204. NTSTATUS FinalStatus;
  205. UNICODE_STRING ServerName;
  206. UNICODE_STRING TargetServerName;
  207. PVOID pTargetInformation;
  208. ULONG TargetInformationSize;
  209. ULONG ExtraSize = 0;
  210. PVOID ExtraServerTargetInfo = NULL;
  211. SecBufferDesc InputToken;
  212. SecBuffer InputBuffer[2];
  213. SecBufferDesc *pOutputBufferDescriptor = NULL;
  214. SecBuffer *pOutputBuffer = NULL;
  215. ULONG_PTR OutputBufferDescriptorSize;
  216. ULONG LsaFlags = ISC_REQ_ALLOCATE_MEMORY;
  217. TimeStamp Expiry;
  218. PCHALLENGE_MESSAGE InToken = NULL;
  219. ULONG InTokenSize;
  220. PNTLM_CHALLENGE_MESSAGE NtlmInToken = NULL;
  221. ULONG NtlmInTokenSize = 0;
  222. PAUTHENTICATE_MESSAGE OutToken = NULL;
  223. PNTLM_INITIALIZE_RESPONSE NtlmOutToken = NULL;
  224. PUCHAR p = NULL;
  225. ULONG_PTR AllocateSize;
  226. PSMBCE_SERVER pServer = SmbCeGetExchangeServer(pExchange);
  227. PSMBCE_SESSION pSession = SmbCeGetExchangeSession(pExchange);
  228. PSMBCEDB_SERVER_ENTRY pServerEntry = SmbCeGetExchangeServerEntry(pExchange);
  229. PAGED_CODE();
  230. try {
  231. pResponseContext->KerberosSetup.pOutputContextBuffer = NULL;
  232. #if defined(REMOTE_BOOT)
  233. //
  234. // If this is a remote boot session and we do not have the proper
  235. // credentials to log in to the machine account, then use the NULL
  236. // session.
  237. //
  238. if (FlagOn(pSession->Flags, SMBCE_SESSION_FLAGS_REMOTE_BOOT_SESSION) &&
  239. !MRxSmbRemoteBootDoMachineLogon) {
  240. //
  241. // Remote boot session with no credentials. Set up a NULL session.
  242. //
  243. pCaseSensitiveResponse->Length = 0;
  244. pCaseSensitiveResponse->MaximumLength = 0;
  245. pCaseSensitiveResponse->Buffer = NULL;
  246. pCaseInsensitiveResponse->Length = 0;
  247. pCaseInsensitiveResponse->MaximumLength = 0;
  248. pCaseInsensitiveResponse->Buffer = NULL;
  249. pDomainName->Length = 0;
  250. pDomainName->MaximumLength = 0;
  251. pDomainName->Buffer = NULL;
  252. pUserName->Length = 0;
  253. pUserName->MaximumLength = 0;
  254. pUserName->Buffer = NULL;
  255. Status = STATUS_SUCCESS;
  256. } else
  257. #endif // defined(REMOTE_BOOT)
  258. {
  259. SmbCeGetServerName(
  260. pExchange->SmbCeContext.pVNetRoot->pNetRoot->pSrvCall,
  261. &ServerName);
  262. if (pServerEntry->DomainName.Length && pServerEntry->DomainName.Buffer) {
  263. TargetServerName = ServerName;
  264. ExtraSize = ServerName.Length;
  265. ExtraServerTargetInfo = ServerName.Buffer;
  266. ServerName = pServerEntry->DomainName;
  267. }
  268. TargetInformationSize = ServerName.Length;
  269. pTargetInformation = ServerName.Buffer;
  270. InTokenSize = sizeof(CHALLENGE_MESSAGE) + TargetInformationSize + ExtraSize;
  271. NtlmInTokenSize = sizeof(NTLM_CHALLENGE_MESSAGE);
  272. if (pSession->pPassword != NULL) {
  273. NtlmInTokenSize += pSession->pPassword->Length;
  274. LsaFlags |= ISC_REQ_USE_SUPPLIED_CREDS;
  275. }
  276. if (pSession->pUserName != NULL) {
  277. NtlmInTokenSize += pSession->pUserName->Length;
  278. LsaFlags |= ISC_REQ_USE_SUPPLIED_CREDS;
  279. }
  280. if (pSession->pUserDomainName != NULL) {
  281. NtlmInTokenSize += pSession->pUserDomainName->Length;
  282. LsaFlags |= ISC_REQ_USE_SUPPLIED_CREDS;
  283. }
  284. // For Alignment purposes, we want InTokenSize rounded up to
  285. // the nearest word size.
  286. AllocateSize = ((InTokenSize + 3) & ~3) + NtlmInTokenSize;
  287. InToken = ExAllocatePool(
  288. PagedPool,
  289. AllocateSize );
  290. if ( InToken == NULL )
  291. {
  292. Status = STATUS_NO_MEMORY;
  293. try_return( Status );
  294. }
  295. // Allocate the output buffer
  296. OutputBufferDescriptorSize = sizeof(SecBufferDesc) + 2 * sizeof(SecBuffer);
  297. pOutputBufferDescriptor = ExAllocatePool(
  298. PagedPool,
  299. OutputBufferDescriptorSize );
  300. if ( pOutputBufferDescriptor == NULL )
  301. {
  302. Status = STATUS_NO_MEMORY ;
  303. try_return( Status );
  304. }
  305. pOutputBuffer = (SecBuffer *)(pOutputBufferDescriptor + 1);
  306. pResponseContext->KerberosSetup.pOutputContextBuffer = pOutputBufferDescriptor;
  307. RxDbgTrace(0,Dbg,("Allocate pool %p\n", InToken));
  308. // partition off the NTLM in token part of the
  309. // buffer
  310. if (LsaFlags & ISC_REQ_USE_SUPPLIED_CREDS)
  311. {
  312. NtlmInToken = (PNTLM_CHALLENGE_MESSAGE) ((PUCHAR) InToken + InTokenSize);
  313. NtlmInToken = (PNTLM_CHALLENGE_MESSAGE) (((ULONG_PTR) NtlmInToken + 3) & ~3);
  314. RtlZeroMemory(NtlmInToken,NtlmInTokenSize);
  315. p = (PUCHAR) NtlmInToken + sizeof(NTLM_CHALLENGE_MESSAGE);
  316. }
  317. if(!SecIsValidHandle(&pSession->CredentialHandle)) {
  318. UNICODE_STRING LMName;
  319. TimeStamp LifeTime;
  320. LMName.Buffer = (PWSTR) InToken;
  321. LMName.Length = NTLMSP_NAME_SIZE;
  322. LMName.MaximumLength = LMName.Length;
  323. RtlCopyMemory(
  324. LMName.Buffer,
  325. NTLMSP_NAME,
  326. NTLMSP_NAME_SIZE);
  327. if (FlagOn(pSession->Flags,SMBCE_SESSION_FLAGS_REMOTE_BOOT_SESSION) ||
  328. MRxSmbUseKernelModeSecurity) {
  329. ULONG fCredentialUse = SECPKG_CRED_OUTBOUND;
  330. if (FlagOn(pSession->Flags,SMBCE_SESSION_FLAGS_REMOTE_BOOT_SESSION)) {
  331. fCredentialUse |= SECPKG_CRED_OWF_PASSWORD;
  332. }
  333. Status = AcquireCredentialsHandleK(
  334. NULL,
  335. &LMName,
  336. fCredentialUse,
  337. &pSession->LogonId,
  338. NULL,
  339. NULL,
  340. (PVOID)1,
  341. &pSession->CredentialHandle,
  342. &LifeTime);
  343. } else {
  344. Status = AcquireCredentialsHandleW(
  345. NULL,
  346. &LMName,
  347. SECPKG_CRED_OUTBOUND,
  348. &pSession->LogonId,
  349. NULL,
  350. NULL,
  351. (PVOID)1,
  352. &pSession->CredentialHandle,
  353. &LifeTime);
  354. }
  355. if(!NT_SUCCESS(Status)) {
  356. SecInvalidateHandle( &pSession->CredentialHandle );
  357. SmbLogError(Status,
  358. LOG,
  359. BuildNtLanmanResponsePrologue_1,
  360. LOGPTR(pSession)
  361. LOGULONG(Status)
  362. LOGUSTR(ServerName));
  363. // We need to free the output buffer (and description) because if they are valid,
  364. // BuildNtLanmanResponseEpilogue will try and parse them, and they have not been
  365. // initialized yet...
  366. ExFreePool( pOutputBufferDescriptor );
  367. pResponseContext->KerberosSetup.pOutputContextBuffer = NULL;
  368. try_return(Status);
  369. }
  370. }
  371. // Copy in the pass,user,domain if they were specified
  372. if(pSession->pPassword != NULL) {
  373. NtlmInToken->Password.Length = pSession->pPassword->Length;
  374. NtlmInToken->Password.MaximumLength = pSession->pPassword->Length;
  375. RtlCopyMemory(
  376. p,
  377. pSession->pPassword->Buffer,
  378. pSession->pPassword->Length);
  379. NtlmInToken->Password.Buffer = (ULONG) (p - (PUCHAR)NtlmInToken);
  380. p += pSession->pPassword->Length;
  381. }
  382. if(pSession->pUserName != NULL) {
  383. NtlmInToken->UserName.Length = pSession->pUserName->Length;
  384. NtlmInToken->UserName.MaximumLength = pSession->pUserName->Length;
  385. RtlCopyMemory(
  386. p,
  387. pSession->pUserName->Buffer,
  388. pSession->pUserName->Length);
  389. NtlmInToken->UserName.Buffer = (ULONG) (p - (PUCHAR)NtlmInToken);
  390. p += pSession->pUserName->Length;
  391. }
  392. if (pSession->pUserDomainName != NULL) {
  393. NtlmInToken->DomainName.Length = pSession->pUserDomainName->Length;
  394. NtlmInToken->DomainName.MaximumLength = pSession->pUserDomainName->Length;
  395. RtlCopyMemory(
  396. p,
  397. pSession->pUserDomainName->Buffer,
  398. pSession->pUserDomainName->Length);
  399. NtlmInToken->DomainName.Buffer = (ULONG) (p - (PUCHAR)NtlmInToken);
  400. p += pSession->pUserDomainName->Length;
  401. }
  402. RtlCopyMemory(
  403. InToken->Signature,
  404. NTLMSSP_SIGNATURE,
  405. sizeof(NTLMSSP_SIGNATURE));
  406. InToken->MessageType = NtLmChallenge;
  407. InToken->NegotiateFlags = NTLMSSP_NEGOTIATE_UNICODE |
  408. NTLMSSP_NEGOTIATE_OEM |
  409. NTLMSSP_REQUEST_INIT_RESPONSE;
  410. if (pServerEntry->Server.SecurityMode == SECURITY_MODE_SHARE_LEVEL) {
  411. InToken->NegotiateFlags |= NTLMSSP_NEGOTIATE_EXPORTED_CONTEXT;
  412. }
  413. RtlCopyMemory(
  414. InToken->Challenge,
  415. pServer->EncryptionKey,
  416. MSV1_0_CHALLENGE_LENGTH);
  417. InToken->TargetName.Length =
  418. InToken->TargetName.MaximumLength = (USHORT)TargetInformationSize;
  419. InToken->TargetName.Buffer = sizeof(CHALLENGE_MESSAGE);
  420. RtlCopyMemory(
  421. (PCHAR)InToken + sizeof(CHALLENGE_MESSAGE),
  422. pTargetInformation,
  423. TargetInformationSize);
  424. TargetServerName.Buffer = (PWCHAR) ((PCHAR)InToken +
  425. sizeof(CHALLENGE_MESSAGE) +
  426. TargetInformationSize);
  427. if (ExtraSize) {
  428. RtlCopyMemory(
  429. TargetServerName.Buffer,
  430. ExtraServerTargetInfo,
  431. ExtraSize);
  432. InToken->NegotiateFlags |= NTLMSSP_TARGET_TYPE_DOMAIN;
  433. } else {
  434. InToken->NegotiateFlags |= NTLMSSP_TARGET_TYPE_SERVER;
  435. }
  436. InputToken.pBuffers = InputBuffer;
  437. InputToken.cBuffers = 1;
  438. InputToken.ulVersion = 0;
  439. InputBuffer[0].pvBuffer = InToken;
  440. InputBuffer[0].cbBuffer = InTokenSize;
  441. InputBuffer[0].BufferType = SECBUFFER_TOKEN;
  442. if (LsaFlags & ISC_REQ_USE_SUPPLIED_CREDS)
  443. {
  444. InputToken.cBuffers = 2;
  445. InputBuffer[1].pvBuffer = NtlmInToken;
  446. InputBuffer[1].cbBuffer = NtlmInTokenSize;
  447. InputBuffer[1].BufferType = SECBUFFER_TOKEN;
  448. }
  449. pOutputBufferDescriptor->pBuffers = pOutputBuffer;
  450. pOutputBufferDescriptor->cBuffers = 2;
  451. pOutputBufferDescriptor->ulVersion = 0;
  452. pOutputBuffer[0].pvBuffer = NULL;
  453. pOutputBuffer[0].cbBuffer = 0;
  454. pOutputBuffer[0].BufferType = SECBUFFER_TOKEN;
  455. pOutputBuffer[1].pvBuffer = NULL;
  456. pOutputBuffer[1].cbBuffer = 0;
  457. pOutputBuffer[1].BufferType = SECBUFFER_TOKEN;
  458. if (FlagOn(pSession->Flags,SMBCE_SESSION_FLAGS_REMOTE_BOOT_SESSION) ||
  459. MRxSmbUseKernelModeSecurity) {
  460. Status = InitializeSecurityContextK(
  461. &pSession->CredentialHandle,
  462. (PCtxtHandle)NULL,
  463. ExtraSize ? &TargetServerName : NULL,
  464. LsaFlags,
  465. 0,
  466. SECURITY_NATIVE_DREP,
  467. &InputToken,
  468. 0,
  469. &pSession->SecurityContextHandle,
  470. pOutputBufferDescriptor,
  471. &FinalStatus,
  472. &Expiry);
  473. } else {
  474. Status = InitializeSecurityContextW(
  475. &pSession->CredentialHandle,
  476. (PCtxtHandle)NULL,
  477. ExtraSize ? &TargetServerName : NULL,
  478. LsaFlags,
  479. 0,
  480. SECURITY_NATIVE_DREP,
  481. &InputToken,
  482. 0,
  483. &pSession->SecurityContextHandle,
  484. pOutputBufferDescriptor,
  485. &FinalStatus,
  486. &Expiry);
  487. }
  488. if(!NT_SUCCESS(Status)) {
  489. if (FlagOn(pSession->Flags,SMBCE_SESSION_FLAGS_REMOTE_BOOT_SESSION) ||
  490. MRxSmbUseKernelModeSecurity) {
  491. Status = MapSecurityErrorK(Status);
  492. } else {
  493. Status = MapSecurityError(Status);
  494. }
  495. SmbCeLog(("IniSecCtxStat %p %lx\n",SmbCeGetExchangeSessionEntry(pExchange),Status));
  496. SmbLogError(Status,
  497. LOG,
  498. BuildNtLanmanResponsePrologue_2,
  499. LOGPTR(pSession)
  500. LOGULONG(Status)
  501. LOGUSTR(ServerName));
  502. try_return(Status);
  503. }
  504. OutToken = (PAUTHENTICATE_MESSAGE) pOutputBuffer[0].pvBuffer;
  505. ASSERT(OutToken != NULL);
  506. RxDbgTrace(0,Dbg,("InitSecCtxt OutToken is %p\n", OutToken));
  507. if (OutToken == NULL) {
  508. Status = STATUS_UNSUCCESSFUL;
  509. SmbLogError(Status,
  510. LOG,
  511. BuildNtLanmanResponsePrologue_3,
  512. LOGPTR(pSession)
  513. LOGULONG(Status)
  514. LOGUSTR(ServerName));
  515. try_return(Status);
  516. }
  517. // The security response the pointers are encoded in terms off the offset
  518. // from the beginning of the buffer. Make the appropriate adjustments.
  519. if (ARGUMENT_PRESENT(pCaseSensitiveResponse)) {
  520. pCaseSensitiveResponse->Length = OutToken->NtChallengeResponse.Length;
  521. pCaseSensitiveResponse->MaximumLength = OutToken->NtChallengeResponse.MaximumLength;
  522. pCaseSensitiveResponse->Buffer = (PBYTE)OutToken + (ULONG_PTR)OutToken->NtChallengeResponse.Buffer;
  523. }
  524. if (ARGUMENT_PRESENT(pCaseInsensitiveResponse)) {
  525. pCaseInsensitiveResponse->Length = OutToken->LmChallengeResponse.Length;
  526. pCaseInsensitiveResponse->MaximumLength = OutToken->LmChallengeResponse.MaximumLength;
  527. pCaseInsensitiveResponse->Buffer = (PBYTE)OutToken + (ULONG_PTR)OutToken->LmChallengeResponse.Buffer;
  528. }
  529. if (pSession->pUserDomainName != NULL) {
  530. *pDomainName = *(pSession->pUserDomainName);
  531. } else {
  532. pDomainName->Length = OutToken->DomainName.Length;
  533. pDomainName->MaximumLength = pDomainName->Length;
  534. pDomainName->Buffer = (PWCHAR)((PBYTE)OutToken + (ULONG_PTR)OutToken->DomainName.Buffer);
  535. }
  536. if (pSession->pUserName != NULL) {
  537. *pUserName = *(pSession->pUserName);
  538. } else {
  539. pUserName->Length = OutToken->UserName.Length;
  540. pUserName->MaximumLength = OutToken->UserName.MaximumLength;
  541. pUserName->Buffer = (PWCHAR)((PBYTE)OutToken + (ULONG_PTR)OutToken->UserName.Buffer);
  542. }
  543. NtlmOutToken = pOutputBuffer[1].pvBuffer;
  544. if (NtlmOutToken != NULL) {
  545. RtlCopyMemory(
  546. pSession->UserSessionKey,
  547. NtlmOutToken->UserSessionKey,
  548. MSV1_0_USER_SESSION_KEY_LENGTH);
  549. RtlCopyMemory(
  550. pSession->LanmanSessionKey,
  551. NtlmOutToken->LanmanSessionKey,
  552. MSV1_0_LANMAN_SESSION_KEY_LENGTH);
  553. }
  554. }
  555. try_exit:NOTHING;
  556. } finally {
  557. if (InToken != NULL) {
  558. ExFreePool( InToken );
  559. }
  560. if (!NT_SUCCESS(Status)) {
  561. BuildNtLanmanResponseEpilogue(pExchange, pResponseContext);
  562. } else {
  563. // This routine can be call from tree connect request, the SecurityContextHandle
  564. // will be overwritten if not deleted, which causes pool leak on LSA.
  565. DeleteSecurityContextForSession(pSession);
  566. }
  567. }
  568. SmbLogError(Status,
  569. LOG,
  570. BuildNtLanmanResponsePrologue,
  571. LOGPTR(pSession)
  572. LOGULONG(Status));
  573. return Status;
  574. }
  575. NTSTATUS
  576. BuildNtLanmanResponseEpilogue(
  577. PSMB_EXCHANGE pExchange,
  578. PSECURITY_RESPONSE_CONTEXT pResponseContext)
  579. /*++
  580. This routine needs to be executed in the system process in order to protect virtual memory
  581. --*/
  582. {
  583. NTSTATUS Status = STATUS_SUCCESS;
  584. PSMBCE_SESSION pSession = SmbCeGetExchangeSession(pExchange);
  585. PAGED_CODE();
  586. if (pResponseContext->KerberosSetup.pOutputContextBuffer != NULL) {
  587. ULONG i = 0;
  588. SecBufferDesc *pBufferDescriptor = (SecBufferDesc *)pResponseContext->KerberosSetup.pOutputContextBuffer;
  589. SecBuffer *pBuffer = pBufferDescriptor->pBuffers;
  590. ULONG_PTR BufferDescriptorSize = sizeof(SecBufferDesc) + 2 * sizeof(SecBuffer);
  591. for (i = 0; i < pBufferDescriptor->cBuffers; i++) {
  592. if (pBuffer[i].pvBuffer != NULL) {
  593. if (FlagOn(pSession->Flags,SMBCE_SESSION_FLAGS_REMOTE_BOOT_SESSION) ||
  594. MRxSmbUseKernelModeSecurity) {
  595. FreeContextBufferK(pBuffer[i].pvBuffer);
  596. } else {
  597. FreeContextBuffer(pBuffer[i].pvBuffer);
  598. }
  599. }
  600. }
  601. ExFreePool( pBufferDescriptor );
  602. pResponseContext->KerberosSetup.pOutputContextBuffer = NULL;
  603. }
  604. return Status;
  605. }
  606. NTSTATUS
  607. BuildExtendedSessionSetupResponsePrologue(
  608. PSMB_EXCHANGE pExchange,
  609. PVOID pSecurityBlobPtr,
  610. PUSHORT pSecurityBlobSize,
  611. PSECURITY_RESPONSE_CONTEXT pResponseContext)
  612. /*++
  613. Routine Description:
  614. This routine builds the security related information for the session setup SMB to
  615. a NT server with extended security
  616. Arguments:
  617. pExchange - the SMB_EXCHANGE that's going on for this call. If this is a
  618. subsequent call, this exchange will have the server's security
  619. blob.
  620. pSecurityBlobPtr - On entry, pointer to where in the SMB to stick the security
  621. blob destined for the server.
  622. pSecurityBlobSize - On entry, the max size allowed for a security blob. On
  623. exit, the actual size of the blob.
  624. pResponseContext -
  625. Return Value:
  626. NTSTATUS - The return status for the operation
  627. Notes:
  628. Eventhough the genral structure of the code tries to isolate dialect specific issues
  629. as much as possible this routine takes the opposite approach. This is because of the
  630. preamble and prologue to security interaction which far outweigh the dialect specific
  631. work required to be done. Therefore in the interests of a smaller footprint this approach
  632. has been adopted.
  633. This routine needs to be executed in the system process in order to protect virtual memory
  634. --*/
  635. {
  636. NTSTATUS Status;
  637. SECURITY_STATUS SecStatus;
  638. ULONG Catts;
  639. TimeStamp Expiry;
  640. ULONG LsaFlags = (ISC_REQ_MUTUAL_AUTH |
  641. ISC_REQ_DELEGATE |
  642. ISC_REQ_FRAGMENT_TO_FIT );
  643. ULONG_PTR RemoteBlobOffset;
  644. ULONG_PTR OutputBufferSize;
  645. UNICODE_STRING PrincipalName = { 0 };
  646. PUNICODE_STRING pServerPrincipalName;
  647. PVOID pServerSecurityBlob;
  648. ULONG ServerSecurityBlobSize;
  649. PUCHAR pTempBlob = NULL;
  650. PSMBCE_SERVER pServer = SmbCeGetExchangeServer(pExchange);
  651. PSMBCE_SESSION pSession = SmbCeGetExchangeSession(pExchange);
  652. PSMBCEDB_SERVER_ENTRY pServerEntry = SmbCeGetExchangeServerEntry(pExchange);
  653. UNICODE_STRING ServerName;
  654. BOOLEAN bTempServerName = FALSE;
  655. PUNICODE_STRING pServerDomainName;
  656. UNICODE_STRING TargetInfoMarshalled;
  657. PSMBCE_EXTENDED_SESSION pExtendedSession;
  658. PSMB_EXTENDED_SESSION_SETUP_EXCHANGE pExtendedSessionSetupExchange;
  659. SecBufferDesc InputToken;
  660. SecBuffer InputBuffer;
  661. SecBufferDesc OutputToken;
  662. SecBuffer OutputBuffer;
  663. PCtxtHandle pInputContextHandle = NULL;
  664. ULONG SpnSize = 0;
  665. PAGED_CODE();
  666. ASSERT((pExchange->Type == EXTENDED_SESSION_SETUP_EXCHANGE) &&
  667. (pSession->Type == EXTENDED_NT_SESSION));
  668. SmbCeAcquireResource();
  669. if (pServerEntry->DnsName.Buffer != NULL) {
  670. ServerName.Length = pServerEntry->DnsName.Length;
  671. ServerName.MaximumLength = pServerEntry->DnsName.MaximumLength;
  672. ServerName.Buffer = RxAllocatePoolWithTag(PagedPool,ServerName.MaximumLength,MRXSMB_SERVER_POOLTAG);
  673. if (ServerName.Buffer) {
  674. RtlCopyMemory(ServerName.Buffer,
  675. pServerEntry->DnsName.Buffer,
  676. pServerEntry->DnsName.Length);
  677. bTempServerName = TRUE;
  678. } else {
  679. SmbCeReleaseResource();
  680. Status = STATUS_INSUFFICIENT_RESOURCES;
  681. goto FINALLY;
  682. }
  683. //DbgPrint("DNS name is used for session setup %wZ\n", &ServerName);
  684. } else {
  685. SmbCeGetServerName(
  686. pExchange->SmbCeContext.pVNetRoot->pNetRoot->pSrvCall,
  687. &ServerName);
  688. }
  689. SmbCeReleaseResource();
  690. ASSERT(ServerName.MaximumLength > (ServerName.Length + sizeof(WCHAR)));
  691. if ((pExchange->RxContext != NULL) &&
  692. (pExchange->RxContext->MajorFunction == IRP_MJ_CREATE) &&
  693. ((pExchange->RxContext->Create.NtCreateParameters.DfsContext == UIntToPtr(DFS_OPEN_CONTEXT)) ||
  694. (pExchange->RxContext->Create.NtCreateParameters.DfsContext == UIntToPtr(DFS_DOWNLEVEL_OPEN_CONTEXT)))) {
  695. ASSERT(pExchange->RxContext->Create.NtCreateParameters.DfsNameContext != NULL);
  696. if (pSession->TargetInfoMarshalled == NULL) {
  697. PDFS_NAME_CONTEXT DfsNameContext = (PDFS_NAME_CONTEXT)pExchange->RxContext->Create.NtCreateParameters.DfsNameContext;
  698. if (DfsNameContext->pDfsTargetInfo) {
  699. PCREDENTIAL_TARGET_INFORMATIONW InTargetInfo = DfsNameContext->pDfsTargetInfo;
  700. #if 0
  701. DbgPrint("DFS TargetInfo is used %x\n",InTargetInfo);
  702. DbgPrint("TargeInfo TargetName %ws\n",InTargetInfo->TargetName);
  703. DbgPrint("TargeInfo NetbiosServerName %ws\n",InTargetInfo->NetbiosServerName);
  704. DbgPrint("TargeInfo DnsServerName %ws\n",InTargetInfo->DnsServerName);
  705. DbgPrint("TargeInfo NetbiosDomainName %ws\n",InTargetInfo->NetbiosDomainName);
  706. DbgPrint("TargeInfo DnsDomainName %ws\n",InTargetInfo->DnsDomainName);
  707. DbgPrint("TargeInfo DnsTreeName %ws\n",InTargetInfo->DnsTreeName);
  708. DbgPrint("TargeInfo CredTypes %ws\n",InTargetInfo->CredTypes);
  709. DbgPrint("TargeInfo TargetNameFlags %x\n",InTargetInfo->Flags);
  710. DbgPrint("TargeInfo CredTypeCount %x\n",InTargetInfo->CredTypeCount);
  711. #endif
  712. Status = CredMarshalTargetInfo(
  713. InTargetInfo,
  714. &pSession->TargetInfoMarshalled,
  715. &pSession->TargetInfoLength);
  716. if(!NT_SUCCESS(Status)) {
  717. goto FINALLY;
  718. }
  719. } else if (DfsNameContext->pLMRTargetInfo){
  720. PLMR_QUERY_TARGET_INFO LmrTargetInfo = DfsNameContext->pLMRTargetInfo;
  721. #if 0
  722. DbgPrint("LMR TargetInfo is used %x\n",LmrTargetInfo);
  723. #endif
  724. pSession->TargetInfoMarshalled = RxAllocatePoolWithTag(PagedPool,
  725. LmrTargetInfo->BufferLength,
  726. MRXSMB_SESSION_POOLTAG);
  727. if (pSession->TargetInfoMarshalled == NULL) {
  728. Status = STATUS_INSUFFICIENT_RESOURCES;
  729. goto FINALLY;
  730. }
  731. pSession->TargetInfoLength = LmrTargetInfo->BufferLength;
  732. RtlCopyMemory(pSession->TargetInfoMarshalled,
  733. LmrTargetInfo->TargetInfoMarshalled,
  734. LmrTargetInfo->BufferLength);
  735. }
  736. }
  737. }
  738. TargetInfoMarshalled.Buffer = pSession->TargetInfoMarshalled;
  739. TargetInfoMarshalled.Length =
  740. TargetInfoMarshalled.MaximumLength = (USHORT)pSession->TargetInfoLength;
  741. Status = SecMakeSPNEx(
  742. &CifsServiceName,
  743. &ServerName,
  744. NULL,
  745. 0,
  746. NULL,
  747. (pSession->TargetInfoMarshalled? &TargetInfoMarshalled : NULL),
  748. &PrincipalName,
  749. &SpnSize,
  750. TRUE );
  751. pExtendedSessionSetupExchange = (PSMB_EXTENDED_SESSION_SETUP_EXCHANGE)pExchange;
  752. pExtendedSession = (PSMBCE_EXTENDED_SESSION)pSession;
  753. pResponseContext->KerberosSetup.pOutputContextBuffer = NULL;
  754. pServerPrincipalName = pExchange->SmbCeContext.pVNetRoot->pNetRoot->pSrvCall->pPrincipalName;
  755. RxDbgTrace(0,Dbg,("KerberosResponsePrologue: Prinicpal name length %ld\n",PrincipalName.Length));
  756. if ( ( pExtendedSessionSetupExchange->pServerResponseBlob == NULL) &&
  757. ( !SecIsValidHandle( &pExtendedSession->SecurityContextHandle ) ) ) {
  758. // This is the first time. Pass in the BLOB obtained during NEGOTIATE to
  759. // the client side security package.
  760. ServerSecurityBlobSize = pServer->NtServer.SecurityBlobLength;
  761. pServerSecurityBlob = pServer->NtServer.pSecurityBlob;
  762. } else {
  763. ServerSecurityBlobSize = pExtendedSessionSetupExchange->ServerResponseBlobLength;
  764. pServerSecurityBlob = pExtendedSessionSetupExchange->pServerResponseBlob;
  765. }
  766. try {
  767. if( !SecIsValidHandle( &pExtendedSession->CredentialHandle )) {
  768. // Obtain a credential handle
  769. UNICODE_STRING KerberosName;
  770. TimeStamp LifeTime;
  771. ULONG_PTR CredentialBufferLength;
  772. PSEC_WINNT_AUTH_IDENTITY_EX pCredentialBuffer;
  773. PBYTE pStringBuffer;
  774. // The supplied credentials need to be packaged for the kerberos package
  775. // These need to be supplied in a special format as speced out by the
  776. // security packages.
  777. CredentialBufferLength = 0;
  778. pCredentialBuffer = NULL;
  779. if(pSession->pUserName != NULL) {
  780. CredentialBufferLength += pSession->pUserName->Length + sizeof(WCHAR);
  781. }
  782. if (pSession->pUserDomainName != NULL) {
  783. CredentialBufferLength += pSession->pUserDomainName->Length + sizeof(WCHAR);
  784. }
  785. if(pSession->pPassword != NULL) {
  786. CredentialBufferLength += pSession->pPassword->Length + sizeof(WCHAR);
  787. }
  788. if (CredentialBufferLength != 0) {
  789. CredentialBufferLength += sizeof(SEC_WINNT_AUTH_IDENTITY_EX);
  790. pCredentialBuffer = ExAllocatePool( PagedPool, CredentialBufferLength );
  791. if ( pCredentialBuffer == NULL )
  792. {
  793. Status = STATUS_NO_MEMORY ;
  794. try_return( Status );
  795. }
  796. //
  797. // Zero all the fixed length fields
  798. //
  799. RtlZeroMemory( pCredentialBuffer, sizeof( SEC_WINNT_AUTH_IDENTITY_EX ) );
  800. pCredentialBuffer->Version = SEC_WINNT_AUTH_IDENTITY_VERSION ;
  801. pCredentialBuffer->Length = sizeof( SEC_WINNT_AUTH_IDENTITY_EX );
  802. pCredentialBuffer->Flags = (SEC_WINNT_AUTH_IDENTITY_UNICODE |
  803. SEC_WINNT_AUTH_IDENTITY_MARSHALLED);
  804. pStringBuffer = (PBYTE) (pCredentialBuffer + 1);
  805. if (pSession->pUserName != NULL) {
  806. pCredentialBuffer->UserLength = pSession->pUserName->Length / sizeof(WCHAR);
  807. pCredentialBuffer->User = (PWCHAR)pStringBuffer;
  808. RtlCopyMemory(
  809. pCredentialBuffer->User,
  810. pSession->pUserName->Buffer,
  811. pSession->pUserName->Length);
  812. pStringBuffer += pSession->pUserName->Length;
  813. SmbPutUshort(pStringBuffer,L'\0');
  814. pStringBuffer += sizeof(WCHAR);
  815. }
  816. if (pSession->pUserDomainName != NULL) {
  817. pCredentialBuffer->DomainLength = pSession->pUserDomainName->Length / sizeof(WCHAR);
  818. pCredentialBuffer->Domain = (PWCHAR)pStringBuffer;
  819. RtlCopyMemory(
  820. pCredentialBuffer->Domain,
  821. pSession->pUserDomainName->Buffer,
  822. pSession->pUserDomainName->Length);
  823. pStringBuffer += pSession->pUserDomainName->Length;
  824. SmbPutUshort(pStringBuffer,L'\0');
  825. pStringBuffer += sizeof(WCHAR);
  826. }
  827. if (pSession->pPassword != NULL) {
  828. pCredentialBuffer->PasswordLength = pSession->pPassword->Length / sizeof(WCHAR);
  829. pCredentialBuffer->Password = (PWCHAR)pStringBuffer;
  830. RtlCopyMemory(
  831. pCredentialBuffer->Password,
  832. pSession->pPassword->Buffer,
  833. pSession->pPassword->Length);
  834. pStringBuffer += pSession->pPassword->Length;
  835. SmbPutUshort(pStringBuffer, L'\0');
  836. pStringBuffer += sizeof(WCHAR);
  837. }
  838. }
  839. RxDbgTrace(0,Dbg,("KerberosResponsePrologue: Acquiring Credential handle\n"));
  840. RtlInitUnicodeString(&KerberosName, NEGOSSP_NAME_W);
  841. SecStatus = AcquireCredentialsHandleW(
  842. NULL,
  843. &KerberosName,
  844. SECPKG_CRED_OUTBOUND,
  845. &pExtendedSession->LogonId,
  846. pCredentialBuffer,
  847. NULL,
  848. NULL,
  849. &pExtendedSession->CredentialHandle,
  850. &LifeTime);
  851. Status = MapSecurityError( SecStatus );
  852. if ( pCredentialBuffer )
  853. {
  854. ExFreePool( pCredentialBuffer );
  855. pCredentialBuffer = NULL ;
  856. }
  857. if(!NT_SUCCESS(Status)) {
  858. SecInvalidateHandle( &pExtendedSession->CredentialHandle );
  859. SmbLogError(Status,
  860. LOG,
  861. BuildExtendedSessionSetupResponsePrologue_1,
  862. LOGPTR(pSession)
  863. LOGULONG(Status)
  864. LOGUSTR(ServerName));
  865. try_return(Status);
  866. }
  867. }
  868. if (SecIsValidHandle( &pExtendedSession->SecurityContextHandle) ) {
  869. pInputContextHandle = &pExtendedSession->SecurityContextHandle;
  870. }
  871. InputToken.pBuffers = &InputBuffer;
  872. InputToken.cBuffers = 1;
  873. InputToken.ulVersion = 0;
  874. InputBuffer.pvBuffer = pServerSecurityBlob;
  875. InputBuffer.cbBuffer = ServerSecurityBlobSize;
  876. InputBuffer.BufferType = SECBUFFER_TOKEN;
  877. RxDbgTrace(0,Dbg,("ExtendedSessionSetupResponsePrologue: Finished setting up input token\n"));
  878. OutputBuffer.pvBuffer = pSecurityBlobPtr ;
  879. OutputBuffer.cbBuffer = SmbCeGetExchangeServer( pExchange )->MaximumBufferSize ;
  880. OutputBuffer.cbBuffer -= (sizeof( REQ_SESSION_SETUP_ANDX ) + sizeof( SMB_HEADER ) + 0x80 );
  881. ASSERT( OutputBuffer.cbBuffer <= *pSecurityBlobSize );
  882. OutputBuffer.BufferType = SECBUFFER_TOKEN;
  883. OutputBufferSize = OutputBuffer.cbBuffer;
  884. OutputToken.pBuffers = &OutputBuffer;
  885. OutputToken.cBuffers = 1;
  886. OutputToken.ulVersion = SECBUFFER_VERSION ;
  887. if (MRxSmbSecuritySignaturesEnabled) {
  888. LsaFlags |= ISC_REQ_INTEGRITY;
  889. }
  890. RxDbgTrace(0,Dbg,("ExtendedSessionSetupResponsePrologue: Finished setting up output token\n"));
  891. SecStatus = InitializeSecurityContextW(
  892. &pExtendedSession->CredentialHandle,
  893. pInputContextHandle,
  894. &PrincipalName,
  895. LsaFlags,
  896. 0, // reserved
  897. SECURITY_NATIVE_DREP,
  898. &InputToken,
  899. 0, // reserved
  900. &pExtendedSession->SecurityContextHandle,
  901. &OutputToken,
  902. &Catts,
  903. &Expiry);
  904. Status = MapSecurityError( SecStatus );
  905. #if DBG
  906. //
  907. // RDR or SRV is sending in a corrupt security blob to LSA -- need to
  908. // find out what the source is.
  909. //
  910. if( NT_SUCCESS(Status) )
  911. {
  912. if( (OutputBuffer.pvBuffer != NULL) &&
  913. (OutputBuffer.cbBuffer >= sizeof(DWORD))
  914. )
  915. {
  916. PUCHAR pValidate = (PUCHAR) OutputBuffer.pvBuffer ;
  917. ASSERT( (pValidate[0] != 0) ||
  918. (pValidate[1] != 0) ||
  919. (pValidate[2] != 0) ||
  920. (pValidate[3] != 0) );
  921. }
  922. }
  923. #endif
  924. if((Status != STATUS_SUCCESS) &&
  925. (SecStatus != SEC_I_COMPLETE_NEEDED) &&
  926. (SecStatus != SEC_I_CONTINUE_NEEDED)) {
  927. SmbLogError(Status,
  928. LOG,
  929. BuildExtendedSessionSetupResponsePrologue_2,
  930. LOGPTR(pSession)
  931. LOGULONG(Status)
  932. LOGUSTR(ServerName));
  933. try_return(Status);
  934. }
  935. if ((SecStatus == SEC_I_COMPLETE_NEEDED) ||
  936. (SecStatus == SEC_I_CONTINUE_NEEDED)) {
  937. Status = STATUS_SUCCESS;
  938. }
  939. if (SecStatus == STATUS_SUCCESS) {
  940. SecPkgContext_SessionKey SecKeys;
  941. SecStatus = QueryContextAttributesW(
  942. &pExtendedSession->SecurityContextHandle,
  943. SECPKG_ATTR_SESSION_KEY,
  944. &SecKeys);
  945. Status = MapSecurityError( SecStatus );
  946. if (Status == STATUS_SUCCESS) {
  947. ULONG SessionKeyLength = (MSV1_0_USER_SESSION_KEY_LENGTH >
  948. SecKeys.SessionKeyLength) ?
  949. MSV1_0_USER_SESSION_KEY_LENGTH :
  950. SecKeys.SessionKeyLength;
  951. RtlZeroMemory(
  952. (PVOID) pSession->UserSessionKey,
  953. MSV1_0_USER_SESSION_KEY_LENGTH);
  954. RtlCopyMemory(
  955. (PVOID) pSession->UserSessionKey,
  956. SecKeys.SessionKey,
  957. SessionKeyLength);
  958. pSession->SessionKeyLength = SessionKeyLength;
  959. if (SecKeys.SessionKey != NULL) {
  960. FreeContextBuffer( SecKeys.SessionKey );
  961. }
  962. } else {
  963. SmbLogError(Status,
  964. LOG,
  965. BuildExtendedSessionSetupResponsePrologue_3,
  966. LOGPTR(pSession)
  967. LOGULONG(Status)
  968. LOGUSTR(ServerName));
  969. }
  970. }
  971. RxDbgTrace(0,Dbg,("ExtendedSessionSetupResponsePrologue: Initialize security context successful\n"));
  972. *pSecurityBlobSize = (USHORT)OutputBuffer.cbBuffer;
  973. try_exit:NOTHING;
  974. } finally {
  975. NOTHING ;
  976. }
  977. FINALLY:
  978. if(bTempServerName == TRUE) {
  979. RxFreePool(ServerName.Buffer);
  980. }
  981. if ( PrincipalName.Buffer )
  982. {
  983. ExFreePool( PrincipalName.Buffer );
  984. }
  985. if ((Status != STATUS_SUCCESS) &&
  986. (Status != STATUS_WRONG_PASSWORD) &&
  987. (Status != STATUS_MORE_PROCESSING_REQUIRED)) {
  988. /*
  989. if (!pServer->EventLogPosted) {
  990. RxLogFailure(
  991. MRxSmbDeviceObject,
  992. NULL,
  993. EVENT_RDR_CANT_GET_SECURITY_CONTEXT,
  994. Status);
  995. pServer->EventLogPosted = TRUE;
  996. } */
  997. SmbCeLog(("KerbProlg %lx Status %lx\n",SmbCeGetExchangeSessionEntry(pExchange),Status));
  998. SmbLogError(Status,
  999. LOG,
  1000. BuildExtendedSessionSetupResponsePrologue,
  1001. LOGPTR(pSession)
  1002. LOGULONG(Status));
  1003. }
  1004. return Status;
  1005. }
  1006. NTSTATUS
  1007. BuildExtendedSessionSetupResponseEpilogue(
  1008. PSECURITY_RESPONSE_CONTEXT pResponseContext)
  1009. {
  1010. ULONG_PTR Zero = 0 ;
  1011. PAGED_CODE();
  1012. return STATUS_SUCCESS;
  1013. }
  1014. NTSTATUS
  1015. ValidateServerExtendedSessionSetupResponse(
  1016. PSMB_EXTENDED_SESSION_SETUP_EXCHANGE pExtendedSessionSetupExchange,
  1017. PVOID pServerResponseBlob,
  1018. ULONG ServerResponseBlobLength)
  1019. /*++
  1020. Routine Description:
  1021. This routine builds the security related information for the session setup SMB to
  1022. a server with extended security negotiation
  1023. Arguments:
  1024. Return Value:
  1025. RXSTATUS - The return status for the operation
  1026. Notes:
  1027. Eventhough the genral structure of the code tries to isolate dialect specific issues
  1028. as much as possible this routine takes the opposite approach. This is because of the
  1029. preamble and prologue to security interaction which far outweigh the dialect specific
  1030. work required to be done. Therefore in the interests of a smaller footprint this approach
  1031. has been adopted.
  1032. --*/
  1033. {
  1034. NTSTATUS Status;
  1035. SECURITY_STATUS SecStatus;
  1036. ULONG Catts = 0;
  1037. TimeStamp Expiry;
  1038. ULONG LsaFlags = ISC_REQ_MUTUAL_AUTH | ISC_REQ_ALLOCATE_MEMORY;
  1039. UNICODE_STRING PrincipalName;
  1040. PUNICODE_STRING pServerPrincipalName;
  1041. PUCHAR pTempBlob = NULL;
  1042. PSMBCE_SERVER pServer = SmbCeGetExchangeServer(pExtendedSessionSetupExchange);
  1043. PSMBCE_SESSION pSession = SmbCeGetExchangeSession(pExtendedSessionSetupExchange);
  1044. UNICODE_STRING ServerName;
  1045. PUNICODE_STRING pServerDomainName;
  1046. PSMBCE_EXTENDED_SESSION pExtendedSession;
  1047. SecBufferDesc InputToken;
  1048. SecBuffer InputBuffer;
  1049. SecBufferDesc OutputToken;
  1050. SecBuffer OutputBuffer;
  1051. SecPkgContext_SessionKey SecKeys;
  1052. KAPC_STATE ApcState;
  1053. BOOLEAN AttachToSystemProcess = FALSE;
  1054. PAGED_CODE();
  1055. ASSERT((pExtendedSessionSetupExchange->Type == EXTENDED_SESSION_SETUP_EXCHANGE) &&
  1056. (pSession->Type == EXTENDED_NT_SESSION));
  1057. SecKeys.SessionKey = NULL;
  1058. pExtendedSession = (PSMBCE_EXTENDED_SESSION)pSession;
  1059. if (pExtendedSession == NULL ||
  1060. !SecIsValidHandle(&pExtendedSession->CredentialHandle)) {
  1061. return STATUS_INVALID_HANDLE;
  1062. }
  1063. SmbCeGetServerName(
  1064. pExtendedSessionSetupExchange->SmbCeContext.pVNetRoot->pNetRoot->pSrvCall,&ServerName);
  1065. try {
  1066. RxDbgTrace(0,Dbg,("ValidateServerResponse: Blob Length %ld\n",pExtendedSessionSetupExchange->ServerResponseBlobLength));
  1067. InputToken.pBuffers = &InputBuffer;
  1068. InputToken.cBuffers = 1;
  1069. InputToken.ulVersion = 0;
  1070. InputBuffer.pvBuffer = pServerResponseBlob ;
  1071. InputBuffer.cbBuffer = pExtendedSessionSetupExchange->ServerResponseBlobLength;
  1072. InputBuffer.BufferType = SECBUFFER_TOKEN;
  1073. RxDbgTrace(0,Dbg,("ValidateKerberosServerResponse: filled in input token\n"));
  1074. OutputToken.pBuffers = &OutputBuffer;
  1075. OutputToken.cBuffers = 1;
  1076. OutputToken.ulVersion = 0;
  1077. OutputBuffer.pvBuffer = NULL;
  1078. OutputBuffer.cbBuffer = 0;
  1079. OutputBuffer.BufferType = SECBUFFER_TOKEN;
  1080. RxDbgTrace(0,Dbg,("ValidateKerberosServerResponse: filled in output token\n"));
  1081. SecStatus = InitializeSecurityContextW(
  1082. &pExtendedSession->CredentialHandle,
  1083. &pExtendedSession->SecurityContextHandle,
  1084. NULL,
  1085. LsaFlags,
  1086. 0, // reserved
  1087. SECURITY_NATIVE_DREP,
  1088. &InputToken,
  1089. 0, // reserved
  1090. &pExtendedSession->SecurityContextHandle,
  1091. &OutputToken,
  1092. &Catts,
  1093. &Expiry);
  1094. Status = MapSecurityError( SecStatus );
  1095. if((Status != STATUS_SUCCESS) &&
  1096. (SecStatus != SEC_I_COMPLETE_NEEDED) &&
  1097. (SecStatus != SEC_I_CONTINUE_NEEDED)) {
  1098. SmbLogError(Status,
  1099. LOG,
  1100. ValidateServerExtendedSessionSetupResponse_1,
  1101. LOGPTR(pSession)
  1102. LOGULONG(Status)
  1103. LOGUSTR(ServerName));
  1104. try_return(Status);
  1105. }
  1106. if ((SecStatus == SEC_I_COMPLETE_NEEDED) ||
  1107. (SecStatus == SEC_I_CONTINUE_NEEDED)) {
  1108. Status = STATUS_MORE_PROCESSING_REQUIRED;
  1109. }
  1110. if (Status == STATUS_SUCCESS) {
  1111. SecStatus = QueryContextAttributesW(
  1112. &pExtendedSession->SecurityContextHandle,
  1113. SECPKG_ATTR_SESSION_KEY,
  1114. &SecKeys);
  1115. Status = MapSecurityError( SecStatus );
  1116. if (Status == STATUS_SUCCESS) {
  1117. ULONG SessionKeyLength = (MSV1_0_USER_SESSION_KEY_LENGTH >
  1118. SecKeys.SessionKeyLength) ?
  1119. MSV1_0_USER_SESSION_KEY_LENGTH :
  1120. SecKeys.SessionKeyLength;
  1121. RtlZeroMemory(
  1122. (PVOID) pSession->UserSessionKey,
  1123. MSV1_0_USER_SESSION_KEY_LENGTH);
  1124. RtlCopyMemory(
  1125. (PVOID) pSession->UserSessionKey,
  1126. SecKeys.SessionKey,
  1127. SessionKeyLength);
  1128. pSession->SessionKeyLength = SessionKeyLength;
  1129. } else {
  1130. SmbLogError(Status,
  1131. LOG,
  1132. ValidateServerExtendedSessionSetupResponse_2,
  1133. LOGPTR(pSession)
  1134. LOGULONG(Status)
  1135. LOGUSTR(ServerName));
  1136. }
  1137. if (SecKeys.SessionKey != NULL) {
  1138. FreeContextBuffer( SecKeys.SessionKey );
  1139. }
  1140. }
  1141. RxDbgTrace(0,Dbg,("ValidateKerberosServerResponse: SecuritContext returned %ld\n",Status));
  1142. if (OutputBuffer.pvBuffer != NULL) {
  1143. FreeContextBuffer(OutputBuffer.pvBuffer);
  1144. }
  1145. try_exit:NOTHING;
  1146. } finally {
  1147. NOTHING ;
  1148. }
  1149. if ((Status != STATUS_SUCCESS) &&
  1150. (Status != STATUS_WRONG_PASSWORD) &&
  1151. (Status != STATUS_MORE_PROCESSING_REQUIRED)) {
  1152. /*
  1153. if (!pServer->EventLogPosted) {
  1154. RxLogFailure(
  1155. MRxSmbDeviceObject,
  1156. NULL,
  1157. EVENT_RDR_CANT_GET_SECURITY_CONTEXT,
  1158. Status);
  1159. pServer->EventLogPosted = TRUE;
  1160. } */
  1161. SmbCeLog((
  1162. "ValServer %lx Status %lx\n",
  1163. SmbCeGetExchangeSessionEntry(
  1164. (PSMB_EXCHANGE)pExtendedSessionSetupExchange),
  1165. Status));
  1166. SmbLogError(Status,
  1167. LOG,
  1168. ValidateServerExtendedSessionSetupResponse,
  1169. LOGPTR(pSession)
  1170. LOGULONG(Status));
  1171. }
  1172. return Status;
  1173. }
  1174. VOID
  1175. UninitializeSecurityContextsForSession(
  1176. PSMBCE_SESSION pSession)
  1177. {
  1178. CtxtHandle CredentialHandle,SecurityContextHandle ;
  1179. SmbCeLog(("UninitSecCont %lx\n",pSession));
  1180. SmbLog(LOG,
  1181. UninitializeSecurityContextsForSession,
  1182. LOGPTR(pSession));
  1183. SmbCeAcquireSpinLock();
  1184. CredentialHandle = pSession->CredentialHandle;
  1185. SecInvalidateHandle( &pSession->CredentialHandle );
  1186. SecurityContextHandle = pSession->SecurityContextHandle;
  1187. SecInvalidateHandle( &pSession->SecurityContextHandle );
  1188. SmbCeReleaseSpinLock();
  1189. if (SecIsValidHandle(&CredentialHandle)) {
  1190. if (FlagOn(pSession->Flags,SMBCE_SESSION_FLAGS_REMOTE_BOOT_SESSION) ||
  1191. MRxSmbUseKernelModeSecurity) {
  1192. FreeCredentialsHandleK(&CredentialHandle);
  1193. } else {
  1194. FreeCredentialsHandle(&CredentialHandle);
  1195. }
  1196. }
  1197. if (SecIsValidHandle(&SecurityContextHandle)) {
  1198. if (FlagOn(pSession->Flags,SMBCE_SESSION_FLAGS_REMOTE_BOOT_SESSION) ||
  1199. MRxSmbUseKernelModeSecurity) {
  1200. DeleteSecurityContextK(&SecurityContextHandle);
  1201. } else {
  1202. DeleteSecurityContext(&SecurityContextHandle);
  1203. }
  1204. }
  1205. }
  1206. VOID
  1207. DeleteSecurityContextForSession(
  1208. PSMBCE_SESSION pSession)
  1209. {
  1210. CtxtHandle SecurityContextHandle ;
  1211. SmbCeLog(("DelSecContext %lx\n",pSession));
  1212. SmbLog(LOG,
  1213. DeleteSecurityContextForSession,
  1214. LOGPTR(pSession));
  1215. SmbCeAcquireSpinLock();
  1216. SecurityContextHandle = pSession->SecurityContextHandle;
  1217. SecInvalidateHandle( &pSession->SecurityContextHandle);
  1218. SmbCeReleaseSpinLock();
  1219. if (SecIsValidHandle(&SecurityContextHandle)) {
  1220. if (FlagOn(pSession->Flags,SMBCE_SESSION_FLAGS_REMOTE_BOOT_SESSION) ||
  1221. MRxSmbUseKernelModeSecurity) {
  1222. DeleteSecurityContextK(&SecurityContextHandle);
  1223. } else {
  1224. DeleteSecurityContext(&SecurityContextHandle);
  1225. }
  1226. }
  1227. }
  1228. NTSTATUS
  1229. BuildExtendedSessionSetupResponsePrologueFake(
  1230. PSMB_EXCHANGE pExchange)
  1231. /*++
  1232. Routine Description:
  1233. This routine builds the security related information for the session setup SMB to
  1234. a NT server with extended security
  1235. Arguments:
  1236. Return Value:
  1237. NTSTATUS - The return status for the operation
  1238. Notes:
  1239. Eventhough the genral structure of the code tries to isolate dialect specific issues
  1240. as much as possible this routine takes the opposite approach. This is because of the
  1241. preamble and prologue to security interaction which far outweigh the dialect specific
  1242. work required to be done. Therefore in the interests of a smaller footprint this approach
  1243. has been adopted.
  1244. This routine needs to be executed in the system process in order to protect virtual memory
  1245. --*/
  1246. {
  1247. NTSTATUS Status;
  1248. SECURITY_STATUS SecStatus;
  1249. TimeStamp Expiry;
  1250. ULONG Catts = ISC_RET_MUTUAL_AUTH;
  1251. ULONG LsaFlags = (ISC_REQ_DELEGATE |
  1252. ISC_REQ_MUTUAL_AUTH |
  1253. ISC_REQ_FRAGMENT_TO_FIT);
  1254. ULONG_PTR RegionSize = 0;
  1255. ULONG_PTR OutputBufferSize;
  1256. UNICODE_STRING PrincipalName;
  1257. PUNICODE_STRING pServerPrincipalName;
  1258. PVOID pServerSecurityBlob;
  1259. ULONG ServerSecurityBlobSize;
  1260. PSMBCE_SERVER pServer = SmbCeGetExchangeServer(pExchange);
  1261. PSMBCE_SESSION pSession = SmbCeGetExchangeSession(pExchange);
  1262. PSMBCEDB_SERVER_ENTRY pServerEntry = SmbCeGetExchangeServerEntry(pExchange);
  1263. UNICODE_STRING ServerName;
  1264. PUNICODE_STRING pServerDomainName;
  1265. SMBCE_EXTENDED_SESSION ExtendedSession;
  1266. SecBufferDesc InputToken;
  1267. SecBuffer InputBuffer = { 0 };
  1268. SecBufferDesc OutputToken;
  1269. SecBuffer OutputBuffer = { 0 };
  1270. PCtxtHandle pInputContextHandle = NULL;
  1271. SecPkgContext_NegotiationInfoW NegInfo = { 0 };
  1272. PAGED_CODE();
  1273. SmbCeGetServerName(
  1274. pExchange->SmbCeContext.pVNetRoot->pNetRoot->pSrvCall,
  1275. &ServerName);
  1276. ASSERT(ServerName.MaximumLength > (ServerName.Length + sizeof(WCHAR)));
  1277. ExtendedSession.Flags = pSession->Flags;
  1278. ExtendedSession.LogonId = pSession->LogonId;
  1279. SecInvalidateHandle( &ExtendedSession.CredentialHandle );
  1280. SecInvalidateHandle( &ExtendedSession.SecurityContextHandle );
  1281. pServerPrincipalName = pExchange->SmbCeContext.pVNetRoot->pNetRoot->pSrvCall->pPrincipalName;
  1282. ServerSecurityBlobSize = 0; //there is no security blob in case of NTLM
  1283. pServerSecurityBlob = NULL;
  1284. try {
  1285. UNICODE_STRING KerberosName;
  1286. TimeStamp LifeTime;
  1287. ULONG_PTR CredentialBufferLength;
  1288. PSEC_WINNT_AUTH_IDENTITY_EXW pCredentialBuffer;
  1289. PBYTE pStringBuffer;
  1290. CredentialBufferLength = 0;
  1291. pCredentialBuffer = NULL;
  1292. if(pSession->pUserName != NULL) {
  1293. CredentialBufferLength += pSession->pUserName->Length + sizeof(WCHAR);
  1294. }
  1295. if (pSession->pUserDomainName != NULL) {
  1296. CredentialBufferLength += pSession->pUserDomainName->Length + sizeof(WCHAR);
  1297. }
  1298. if(pSession->pPassword != NULL) {
  1299. CredentialBufferLength += pSession->pPassword->Length + sizeof(WCHAR);
  1300. }
  1301. if (CredentialBufferLength != 0) {
  1302. CredentialBufferLength += sizeof(SEC_WINNT_AUTH_IDENTITY_EXW);
  1303. pCredentialBuffer = (PSEC_WINNT_AUTH_IDENTITY_EXW) ExAllocatePool(
  1304. PagedPool,
  1305. CredentialBufferLength );
  1306. if ( !pCredentialBuffer )
  1307. {
  1308. Status = STATUS_NO_MEMORY ;
  1309. try_return( Status );
  1310. }
  1311. //
  1312. // Zero the fixed portion
  1313. //
  1314. RtlZeroMemory( pCredentialBuffer, sizeof( SEC_WINNT_AUTH_IDENTITY_EXW ));
  1315. pCredentialBuffer->Version = SEC_WINNT_AUTH_IDENTITY_VERSION ;
  1316. pCredentialBuffer->Length = sizeof( SEC_WINNT_AUTH_IDENTITY_EXW );
  1317. pCredentialBuffer->Flags = (SEC_WINNT_AUTH_IDENTITY_UNICODE |
  1318. SEC_WINNT_AUTH_IDENTITY_MARSHALLED);
  1319. pStringBuffer = (PBYTE)( pCredentialBuffer + 1 );
  1320. if (pSession->pUserName != NULL) {
  1321. pCredentialBuffer->UserLength = pSession->pUserName->Length / sizeof(WCHAR);
  1322. pCredentialBuffer->User = (PWCHAR)pStringBuffer;
  1323. RtlCopyMemory(
  1324. pCredentialBuffer->User,
  1325. pSession->pUserName->Buffer,
  1326. pSession->pUserName->Length);
  1327. pStringBuffer += pSession->pUserName->Length;
  1328. SmbPutUshort(pStringBuffer,L'\0');
  1329. pStringBuffer += sizeof(WCHAR);
  1330. }
  1331. if (pSession->pUserDomainName != NULL) {
  1332. pCredentialBuffer->DomainLength = pSession->pUserDomainName->Length / sizeof(WCHAR);
  1333. pCredentialBuffer->Domain = (PWCHAR)pStringBuffer;
  1334. RtlCopyMemory(
  1335. pCredentialBuffer->Domain,
  1336. pSession->pUserDomainName->Buffer,
  1337. pSession->pUserDomainName->Length);
  1338. pStringBuffer += pSession->pUserDomainName->Length;
  1339. SmbPutUshort(pStringBuffer,L'\0');
  1340. pStringBuffer += sizeof(WCHAR);
  1341. }
  1342. if (pSession->pPassword != NULL) {
  1343. pCredentialBuffer->PasswordLength = pSession->pPassword->Length / sizeof(WCHAR);
  1344. pCredentialBuffer->Password = (PWCHAR)pStringBuffer;
  1345. RtlCopyMemory(
  1346. pCredentialBuffer->Password,
  1347. pSession->pPassword->Buffer,
  1348. pSession->pPassword->Length);
  1349. pStringBuffer += pSession->pPassword->Length;
  1350. SmbPutUshort(pStringBuffer, L'\0');
  1351. pStringBuffer += sizeof(WCHAR);
  1352. }
  1353. }
  1354. RxDbgTrace(0,Dbg,("KerberosResponsePrologue: Acquiring Credential handle\n"));
  1355. RtlInitUnicodeString(&KerberosName, NEGOSSP_NAME_W);
  1356. SecStatus = AcquireCredentialsHandleW(
  1357. NULL,
  1358. &KerberosName,
  1359. SECPKG_CRED_OUTBOUND,
  1360. &ExtendedSession.LogonId,
  1361. pCredentialBuffer,
  1362. NULL,
  1363. NULL,
  1364. &ExtendedSession.CredentialHandle,
  1365. &LifeTime);
  1366. Status = MapSecurityError( SecStatus );
  1367. if (pCredentialBuffer != NULL) {
  1368. ExFreePool( pCredentialBuffer );
  1369. }
  1370. if(!NT_SUCCESS(Status)) {
  1371. SecInvalidateHandle( &ExtendedSession.CredentialHandle );
  1372. SmbLogError(Status,
  1373. LOG,
  1374. BuildExtendedSessionSetupResponsePrologueFake_1,
  1375. LOGPTR(pSession)
  1376. LOGULONG(Status)
  1377. LOGUSTR(ServerName));
  1378. try_return(Status);
  1379. }
  1380. Status = SecMakeSPN(
  1381. &CifsServiceName,
  1382. &ServerName,
  1383. NULL,
  1384. 0,
  1385. NULL,
  1386. &PrincipalName,
  1387. NULL,
  1388. TRUE );
  1389. InputToken.pBuffers = &InputBuffer;
  1390. InputToken.cBuffers = 1;
  1391. InputToken.ulVersion = 0;
  1392. InputBuffer.pvBuffer = pServerSecurityBlob;
  1393. InputBuffer.cbBuffer = ServerSecurityBlobSize;
  1394. InputBuffer.BufferType = SECBUFFER_TOKEN;
  1395. OutputBuffer.pvBuffer = NULL;
  1396. OutputBuffer.cbBuffer = SmbCeGetExchangeServer( pExchange )->MaximumBufferSize;
  1397. OutputBuffer.cbBuffer -= (sizeof( REQ_SESSION_SETUP_ANDX ) + sizeof( SMB_HEADER ) + 0x80 );
  1398. OutputBuffer.BufferType = SECBUFFER_TOKEN;
  1399. OutputBufferSize = OutputBuffer.cbBuffer;
  1400. OutputBuffer.pvBuffer = ExAllocatePool( PagedPool, OutputBufferSize );
  1401. if ( OutputBuffer.pvBuffer == NULL )
  1402. {
  1403. Status = STATUS_NO_MEMORY ;
  1404. try_return( Status );
  1405. }
  1406. OutputToken.pBuffers = &OutputBuffer;
  1407. OutputToken.cBuffers = 1;
  1408. OutputToken.ulVersion = SECBUFFER_VERSION ;
  1409. if (pServerEntry->Server.SecurityMode == SECURITY_MODE_SHARE_LEVEL)
  1410. {
  1411. LsaFlags |= ISC_REQ_USE_SUPPLIED_CREDS;
  1412. }
  1413. SecStatus = InitializeSecurityContextW(
  1414. &ExtendedSession.CredentialHandle,
  1415. pInputContextHandle,
  1416. &PrincipalName,
  1417. LsaFlags,
  1418. 0, // reserved
  1419. SECURITY_NATIVE_DREP,
  1420. &InputToken,
  1421. 0, // reserved
  1422. &ExtendedSession.SecurityContextHandle,
  1423. &OutputToken,
  1424. &Catts,
  1425. &Expiry);
  1426. Status = MapSecurityError( SecStatus );
  1427. if((Status != STATUS_SUCCESS) &&
  1428. (SecStatus != SEC_I_COMPLETE_NEEDED) &&
  1429. (SecStatus != SEC_I_CONTINUE_NEEDED)) {
  1430. RxLog(("ISC returned %lx\n",Status));
  1431. SmbLogError(Status,
  1432. LOG,
  1433. BuildExtendedSessionSetupResponsePrologueFake_2,
  1434. LOGPTR(pSession)
  1435. LOGULONG(Status)
  1436. LOGUSTR(ServerName));
  1437. try_return(Status);
  1438. }
  1439. SecStatus = QueryContextAttributesW(
  1440. &ExtendedSession.SecurityContextHandle,
  1441. SECPKG_ATTR_NEGOTIATION_INFO,
  1442. &NegInfo);
  1443. Status = MapSecurityError( SecStatus );
  1444. if (Status != STATUS_SUCCESS) {
  1445. RxLog(("QCA returned %lx\n",Status));
  1446. SmbLogError(Status,
  1447. LOG,
  1448. BuildExtendedSessionSetupResponsePrologueFake_3,
  1449. LOGPTR(pSession)
  1450. LOGULONG(Status)
  1451. LOGUSTR(ServerName));
  1452. }
  1453. try_exit:NOTHING;
  1454. } finally {
  1455. if (Status == STATUS_SUCCESS) {
  1456. if (NegInfo.PackageInfo->wRPCID != NTLMSP_RPCID) {
  1457. Status = STATUS_LOGIN_WKSTA_RESTRICTION;
  1458. //RxLogFailure(
  1459. // MRxSmbDeviceObject,
  1460. // NULL,
  1461. // EVENT_RDR_ENCOUNTER_DOWNGRADE_ATTACK,
  1462. // Status);
  1463. RxLog(("NTLM downgrade attack from %wZ\n",&pServerEntry->Name));
  1464. #if DBG
  1465. DbgPrint("NTLM downgrade attack from %wZ\n",&pServerEntry->Name);
  1466. #endif
  1467. SmbLogError(Status,
  1468. LOG,
  1469. BuildExtendedSessionSetupResponsePrologueFake_4,
  1470. LOGPTR(pSession)
  1471. LOGULONG(Status)
  1472. LOGUSTR(ServerName));
  1473. }
  1474. }
  1475. UninitializeSecurityContextsForSession((PSMBCE_SESSION)(&ExtendedSession));
  1476. if ( NegInfo.PackageInfo != NULL) {
  1477. FreeContextBuffer(NegInfo.PackageInfo);
  1478. }
  1479. if (OutputBuffer.pvBuffer != NULL) {
  1480. ExFreePool( OutputBuffer.pvBuffer );
  1481. }
  1482. SmbLogError(Status,
  1483. LOG,
  1484. BuildExtendedSessionSetupResponsePrologueFake,
  1485. LOGPTR(pSession)
  1486. LOGULONG(Status));
  1487. }
  1488. return Status;
  1489. }