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.

920 lines
28 KiB

  1. #if _WIN64
  2. #include <global.h>
  3. #include "msp.h"
  4. #include "nlp.h"
  5. #include "msvwow.h"
  6. #define RELOCATE_WOW_UNICODE_STRING(WOWString, NativeString, Offset) \
  7. NativeString.Length = WOWString.Length; \
  8. NativeString.MaximumLength = WOWString.MaximumLength; \
  9. NativeString.Buffer = (LPWSTR) ((LPBYTE) UlongToPtr(WOWString.Buffer) + Offset);
  10. #define RELOCATE_WOW_ANSI_STRING(WOWString, NativeString, Offset) \
  11. NativeString.Length = WOWString.Length; \
  12. NativeString.MaximumLength = WOWString.MaximumLength; \
  13. NativeString.Buffer = (LPSTR) ((LPBYTE) UlongToPtr(WOWString.Buffer) + Offset);
  14. //+-------------------------------------------------------------------------
  15. //
  16. // Function: MsvPutWOWString
  17. //
  18. // Synopsis: Copies a UNICODE_STRING into a buffer
  19. //
  20. // Effects:
  21. //
  22. // Arguments: InputString - String to 'put'
  23. // OutputString - Receives 'put' string
  24. // Offset - Difference in addresses of local and client buffers.
  25. // Where - Location in local buffer to place string.
  26. //
  27. // Requires:
  28. //
  29. // Returns:
  30. //
  31. // Notes: This code is (effectively) duplicated in
  32. // KerbPutString. Make sure any changes
  33. // made here are applied there as well.
  34. //
  35. //--------------------------------------------------------------------------
  36. VOID
  37. MsvPutWOWString(
  38. IN PUNICODE_STRING InputString,
  39. OUT PUNICODE_STRING_WOW64 OutputString,
  40. IN LONG_PTR Offset,
  41. IN OUT PBYTE * Where
  42. )
  43. {
  44. OutputString->Length = OutputString->MaximumLength = InputString->Length;
  45. OutputString->Buffer = PtrToUlong (*Where + Offset);
  46. RtlCopyMemory(
  47. *Where,
  48. InputString->Buffer,
  49. InputString->Length
  50. );
  51. *Where += InputString->Length;
  52. }
  53. //+-------------------------------------------------------------------------
  54. //
  55. // Function: MsvPutWOWClientString
  56. //
  57. // Synopsis: Copies a string into a buffer that will be copied to the
  58. // 32-bit client's address space
  59. //
  60. // Effects:
  61. //
  62. // Arguments: Where - Location in local buffer to place string.
  63. // OutString - Receives 'put' string
  64. // InString - String to 'put'
  65. //
  66. // Requires:
  67. //
  68. // Returns:
  69. //
  70. // Notes: This code is (effectively) duplicated in
  71. // KerbPutClientString. Make sure any changes
  72. // made here are applied there as well.
  73. //
  74. //--------------------------------------------------------------------------
  75. VOID
  76. MsvPutWOWClientString(
  77. IN OUT PCLIENT_BUFFER_DESC ClientBufferDesc,
  78. IN PUNICODE_STRING_WOW64 OutString,
  79. IN PUNICODE_STRING InString
  80. )
  81. /*++
  82. Routine Description:
  83. This routine copies the InString string to the memory pointed to by
  84. ClientBufferDesc->StringOffset, and fixes the OutString string to point
  85. to that new copy.
  86. Parameters:
  87. ClientBufferDesc - Descriptor of a buffer allocated in the client's
  88. address space.
  89. InString - A pointer to an NT string to be copied
  90. OutString - A pointer to a destination NT string. This string structure
  91. is in the "Mirror" allocated buffer.
  92. Return Status:
  93. STATUS_SUCCESS - Indicates the service completed successfully.
  94. --*/
  95. {
  96. //
  97. // Ensure our caller passed good data.
  98. //
  99. ASSERT( OutString != NULL );
  100. ASSERT( InString != NULL );
  101. ASSERT( COUNT_IS_ALIGNED( ClientBufferDesc->StringOffset, sizeof(WCHAR)) );
  102. ASSERT( (LPBYTE)OutString >= ClientBufferDesc->MsvBuffer );
  103. ASSERT( (LPBYTE)OutString <
  104. ClientBufferDesc->MsvBuffer + ClientBufferDesc->TotalSize - sizeof(UNICODE_STRING) );
  105. ASSERT( ClientBufferDesc->StringOffset + InString->Length + sizeof(WCHAR) <=
  106. ClientBufferDesc->TotalSize );
  107. #ifdef notdef
  108. KdPrint(("NlpPutClientString: %ld %Z\n", InString->Length, InString ));
  109. KdPrint((" Orig: UserBuffer: %lx Offset: 0x%lx TotalSize: 0x%lx\n",
  110. ClientBufferDesc->UserBuffer,
  111. ClientBufferDesc->StringOffset,
  112. ClientBufferDesc->TotalSize ));
  113. #endif
  114. //
  115. // Build a string structure and copy the text to the Mirror buffer.
  116. //
  117. if ( InString->Length > 0 ) {
  118. ULONG_PTR TmpPtr;
  119. //
  120. // Copy the string (Add a zero character)
  121. //
  122. RtlCopyMemory(
  123. ClientBufferDesc->MsvBuffer + ClientBufferDesc->StringOffset,
  124. InString->Buffer,
  125. InString->Length );
  126. // Do one byte at a time since some callers don't pass in an even
  127. // InString->Length
  128. *(ClientBufferDesc->MsvBuffer + ClientBufferDesc->StringOffset +
  129. InString->Length) = '\0';
  130. *(ClientBufferDesc->MsvBuffer + ClientBufferDesc->StringOffset +
  131. InString->Length+1) = '\0';
  132. //
  133. // Build the string structure to point to the data in the client's
  134. // address space.
  135. //
  136. TmpPtr = (ULONG_PTR)(ClientBufferDesc->UserBuffer +
  137. ClientBufferDesc->StringOffset);
  138. OutString->Buffer = (ULONG)TmpPtr;
  139. OutString->Length = InString->Length;
  140. OutString->MaximumLength = OutString->Length + sizeof(WCHAR);
  141. //
  142. // Adjust the offset to past the newly copied string.
  143. //
  144. ClientBufferDesc->StringOffset += OutString->MaximumLength;
  145. } else {
  146. ZeroMemory( OutString, sizeof(*OutString) );
  147. }
  148. return;
  149. }
  150. //+-------------------------------------------------------------------------
  151. //
  152. // Function: MsvConvertWOWInteractiveLogonBuffer
  153. //
  154. // Synopsis: Converts logon buffers passed in from WOW clients to 64-bit
  155. //
  156. // Effects:
  157. //
  158. // Arguments: ProtocolSubmitBuffer -- original 32-bit logon buffer
  159. // pSubmitBufferSize -- size of the 32-bit logon buffer
  160. // MessageType -- format of the logon buffer
  161. // ppTempSubmitBuffer -- filled in with the converted buffer
  162. //
  163. // Requires:
  164. //
  165. // Returns:
  166. //
  167. // Notes: This routine allocates the converted buffer and returns it
  168. // on success. It is the caller's responsibility to free it.
  169. //
  170. //
  171. //--------------------------------------------------------------------------
  172. NTSTATUS
  173. MsvConvertWOWInteractiveLogonBuffer(
  174. IN PVOID ProtocolSubmitBuffer,
  175. IN PVOID ClientBufferBase,
  176. IN OUT PULONG pSubmitBufferSize,
  177. OUT PVOID *ppTempSubmitBuffer
  178. )
  179. {
  180. NTSTATUS Status = STATUS_SUCCESS;
  181. PVOID pTempBuffer = NULL;
  182. ULONG dwBufferSize = *pSubmitBufferSize;
  183. PMSV1_0_INTERACTIVE_LOGON Logon;
  184. PMSV1_0_INTERACTIVE_LOGON_WOW64 LogonWOW;
  185. DWORD dwOffset;
  186. DWORD dwWOWOffset;
  187. //
  188. // Pacify the compiler
  189. //
  190. UNREFERENCED_PARAMETER(ClientBufferBase);
  191. //
  192. // Scale up the size and add on 3 PVOIDs for the worst-case
  193. // scenario to align the three embedded UNICODE_STRINGs
  194. //
  195. dwBufferSize += sizeof(MSV1_0_INTERACTIVE_LOGON)
  196. - sizeof(MSV1_0_INTERACTIVE_LOGON_WOW64);
  197. if (dwBufferSize < sizeof(MSV1_0_INTERACTIVE_LOGON))
  198. {
  199. #if 0
  200. DebugLog((DEB_ERROR,
  201. "Submit buffer to logon too small: %d. %ws, line %d\n",
  202. dwBufferSize,
  203. THIS_FILE,
  204. __LINE__));
  205. #endif
  206. Status = STATUS_INVALID_PARAMETER;
  207. goto Cleanup;
  208. }
  209. pTempBuffer = NtLmAllocatePrivateHeap(dwBufferSize);
  210. if (pTempBuffer == NULL)
  211. {
  212. Status = STATUS_INSUFFICIENT_RESOURCES;
  213. goto Cleanup;
  214. }
  215. Logon = (PMSV1_0_INTERACTIVE_LOGON) pTempBuffer;
  216. LogonWOW = (PMSV1_0_INTERACTIVE_LOGON_WOW64) ProtocolSubmitBuffer;
  217. Logon->MessageType = LogonWOW->MessageType;
  218. dwOffset = sizeof(MSV1_0_INTERACTIVE_LOGON);
  219. dwWOWOffset = sizeof(MSV1_0_INTERACTIVE_LOGON_WOW64);
  220. //
  221. // Copy the variable-length data
  222. //
  223. RtlCopyMemory((LPBYTE) Logon + dwOffset,
  224. (LPBYTE) LogonWOW + dwWOWOffset,
  225. *pSubmitBufferSize - dwWOWOffset);
  226. //
  227. // Set up the pointers in the native struct
  228. //
  229. RELOCATE_WOW_UNICODE_STRING(LogonWOW->LogonDomainName,
  230. Logon->LogonDomainName,
  231. dwOffset - dwWOWOffset);
  232. RELOCATE_WOW_UNICODE_STRING(LogonWOW->UserName,
  233. Logon->UserName,
  234. dwOffset - dwWOWOffset);
  235. RELOCATE_WOW_UNICODE_STRING(LogonWOW->Password,
  236. Logon->Password,
  237. dwOffset - dwWOWOffset);
  238. *pSubmitBufferSize = dwBufferSize;
  239. *ppTempSubmitBuffer = pTempBuffer;
  240. return STATUS_SUCCESS;
  241. Cleanup:
  242. ASSERT(!NT_SUCCESS(Status));
  243. if (pTempBuffer)
  244. {
  245. NtLmFreePrivateHeap(pTempBuffer);
  246. }
  247. return Status;
  248. }
  249. NTSTATUS
  250. MsvConvertWOWNetworkLogonBuffer(
  251. IN PVOID ProtocolSubmitBuffer,
  252. IN PVOID ClientBufferBase,
  253. IN OUT PULONG pSubmitBufferSize,
  254. OUT PVOID *ppTempSubmitBuffer
  255. )
  256. {
  257. NTSTATUS Status = STATUS_SUCCESS;
  258. PVOID pTempBuffer = NULL;
  259. ULONG dwBufferSize = *pSubmitBufferSize;
  260. PMSV1_0_LM20_LOGON Logon;
  261. PMSV1_0_LM20_LOGON_WOW64 LogonWOW;
  262. DWORD dwOffset;
  263. DWORD dwWOWOffset;
  264. //
  265. // Pacify the compiler
  266. //
  267. UNREFERENCED_PARAMETER(ClientBufferBase);
  268. //
  269. // Scale up the size and add on 5 PVOIDs for the worst-case
  270. // scenario to align the three embedded UNICODE_STRINGs
  271. //
  272. dwBufferSize += sizeof(MSV1_0_LM20_LOGON)
  273. - sizeof(MSV1_0_LM20_LOGON_WOW64);
  274. if (dwBufferSize < sizeof(MSV1_0_LM20_LOGON))
  275. {
  276. #if 0
  277. DebugLog((DEB_ERROR,
  278. "Submit buffer to logon too small: %d. %ws, line %d\n",
  279. dwBufferSize,
  280. THIS_FILE,
  281. __LINE__));
  282. #endif
  283. Status = STATUS_INVALID_PARAMETER;
  284. goto Cleanup;
  285. }
  286. pTempBuffer = NtLmAllocatePrivateHeap(dwBufferSize);
  287. if (pTempBuffer == NULL)
  288. {
  289. Status = STATUS_INSUFFICIENT_RESOURCES;
  290. goto Cleanup;
  291. }
  292. Logon = (PMSV1_0_LM20_LOGON) pTempBuffer;
  293. LogonWOW = (PMSV1_0_LM20_LOGON_WOW64) ProtocolSubmitBuffer;
  294. //
  295. // copy fixed fields.
  296. //
  297. Logon->MessageType = LogonWOW->MessageType;
  298. Logon->ParameterControl = LogonWOW->ParameterControl;
  299. RtlCopyMemory(Logon->ChallengeToClient, LogonWOW->ChallengeToClient, MSV1_0_CHALLENGE_LENGTH);
  300. dwOffset = sizeof(MSV1_0_LM20_LOGON);
  301. dwWOWOffset = sizeof(MSV1_0_LM20_LOGON_WOW64);
  302. //
  303. // Copy the variable-length data
  304. //
  305. RtlCopyMemory((LPBYTE) Logon + dwOffset,
  306. (LPBYTE) LogonWOW + dwWOWOffset,
  307. *pSubmitBufferSize - dwWOWOffset);
  308. //
  309. // Set up the pointers in the native struct
  310. //
  311. RELOCATE_WOW_UNICODE_STRING(LogonWOW->LogonDomainName,
  312. Logon->LogonDomainName,
  313. dwOffset - dwWOWOffset);
  314. RELOCATE_WOW_UNICODE_STRING(LogonWOW->UserName,
  315. Logon->UserName,
  316. dwOffset - dwWOWOffset);
  317. RELOCATE_WOW_UNICODE_STRING(LogonWOW->Workstation,
  318. Logon->Workstation,
  319. dwOffset - dwWOWOffset);
  320. RELOCATE_WOW_ANSI_STRING(LogonWOW->CaseSensitiveChallengeResponse,
  321. Logon->CaseSensitiveChallengeResponse,
  322. dwOffset - dwWOWOffset);
  323. RELOCATE_WOW_ANSI_STRING(LogonWOW->CaseInsensitiveChallengeResponse,
  324. Logon->CaseInsensitiveChallengeResponse,
  325. dwOffset - dwWOWOffset);
  326. *pSubmitBufferSize = dwBufferSize;
  327. *ppTempSubmitBuffer = pTempBuffer;
  328. return STATUS_SUCCESS;
  329. Cleanup:
  330. ASSERT(!NT_SUCCESS(Status));
  331. if (pTempBuffer)
  332. {
  333. NtLmFreePrivateHeap(pTempBuffer);
  334. }
  335. return Status;
  336. }
  337. //+-------------------------------------------------------------------------
  338. //
  339. // Function: MsvConvertWOWChangePasswordBuffer
  340. //
  341. // Synopsis: Converts change password buffers passed in from
  342. // WOW clients to 64-bit
  343. //
  344. // Effects:
  345. //
  346. // Arguments: ProtocolSubmitBuffer -- original 32-bit buffer
  347. // ClientBufferBase -- base address
  348. // pSubmitBufferSize -- size of the 32-bit buffer
  349. // ppTempSubmitBuffer -- filled in with the converted buffer
  350. //
  351. // Requires:
  352. //
  353. // Returns:
  354. //
  355. // Notes: This routine allocates the converted buffer and returns it
  356. // on success. It is the caller's responsibility to free it.
  357. //
  358. //
  359. //--------------------------------------------------------------------------
  360. NTSTATUS
  361. MsvConvertWOWChangePasswordBuffer(
  362. IN PVOID ProtocolSubmitBuffer,
  363. IN PVOID ClientBufferBase,
  364. IN OUT PULONG pSubmitBufferSize,
  365. OUT PVOID *ppTempSubmitBuffer
  366. )
  367. {
  368. NTSTATUS Status = STATUS_SUCCESS;
  369. PVOID pTempBuffer = NULL;
  370. ULONG dwBufferSize = *pSubmitBufferSize;
  371. PMSV1_0_CHANGEPASSWORD_REQUEST PasswordRequest;
  372. PMSV1_0_CHANGEPASSWORD_REQUEST_WOW64 PasswordRequestWOW;
  373. DWORD dwOffset;
  374. DWORD dwWOWOffset;
  375. //
  376. // Pacify the compiler
  377. //
  378. UNREFERENCED_PARAMETER(ClientBufferBase);
  379. //
  380. // Scale up the size
  381. //
  382. dwBufferSize += sizeof(MSV1_0_CHANGEPASSWORD_REQUEST)
  383. - sizeof(MSV1_0_CHANGEPASSWORD_REQUEST_WOW64);
  384. if (dwBufferSize < sizeof(MSV1_0_CHANGEPASSWORD_REQUEST))
  385. {
  386. #if 0
  387. DebugLog((DEB_ERROR,
  388. "Submit buffer to logon too small: %d. %ws, line %d\n",
  389. dwBufferSize,
  390. THIS_FILE,
  391. __LINE__));
  392. #endif
  393. Status = STATUS_INVALID_PARAMETER;
  394. goto Cleanup;
  395. }
  396. pTempBuffer = NtLmAllocatePrivateHeap(dwBufferSize);
  397. if (pTempBuffer == NULL)
  398. {
  399. Status = STATUS_INSUFFICIENT_RESOURCES;
  400. goto Cleanup;
  401. }
  402. PasswordRequest = (PMSV1_0_CHANGEPASSWORD_REQUEST) pTempBuffer;
  403. PasswordRequestWOW = (PMSV1_0_CHANGEPASSWORD_REQUEST_WOW64) ProtocolSubmitBuffer;
  404. //
  405. // copy fixed fields.
  406. //
  407. PasswordRequest->MessageType = PasswordRequestWOW->MessageType;
  408. PasswordRequest->Impersonating = PasswordRequestWOW->Impersonating;
  409. dwOffset = sizeof(MSV1_0_CHANGEPASSWORD_REQUEST);
  410. dwWOWOffset = sizeof(MSV1_0_CHANGEPASSWORD_REQUEST_WOW64);
  411. //
  412. // Copy the variable-length data
  413. //
  414. RtlCopyMemory((LPBYTE) PasswordRequest + dwOffset,
  415. (LPBYTE) PasswordRequestWOW + dwWOWOffset,
  416. *pSubmitBufferSize - dwWOWOffset);
  417. //
  418. // Set up the pointers in the native struct
  419. //
  420. RELOCATE_WOW_UNICODE_STRING(PasswordRequestWOW->DomainName,
  421. PasswordRequest->DomainName,
  422. dwOffset - dwWOWOffset);
  423. RELOCATE_WOW_UNICODE_STRING(PasswordRequestWOW->AccountName,
  424. PasswordRequest->AccountName,
  425. dwOffset - dwWOWOffset);
  426. RELOCATE_WOW_UNICODE_STRING(PasswordRequestWOW->OldPassword,
  427. PasswordRequest->OldPassword,
  428. dwOffset - dwWOWOffset);
  429. RELOCATE_WOW_UNICODE_STRING(PasswordRequestWOW->NewPassword,
  430. PasswordRequest->NewPassword,
  431. dwOffset - dwWOWOffset);
  432. *pSubmitBufferSize = dwBufferSize;
  433. *ppTempSubmitBuffer = pTempBuffer;
  434. return STATUS_SUCCESS;
  435. Cleanup:
  436. ASSERT(!NT_SUCCESS(Status));
  437. if (pTempBuffer)
  438. {
  439. NtLmFreePrivateHeap(pTempBuffer);
  440. }
  441. return Status;
  442. }
  443. NTSTATUS
  444. MsvAllocateInteractiveWOWProfile (
  445. IN PLSA_CLIENT_REQUEST ClientRequest,
  446. OUT PMSV1_0_INTERACTIVE_PROFILE *ProfileBuffer,
  447. OUT PULONG ProfileBufferSize,
  448. IN PNETLOGON_VALIDATION_SAM_INFO4 NlpUser
  449. )
  450. /*++
  451. Routine Description:
  452. This allocates and fills in the clients interactive profile.
  453. Arguments:
  454. ClientRequest - Is a pointer to an opaque data structure
  455. representing the client's request.
  456. ProfileBuffer - Is used to return the address of the profile
  457. buffer in the client process. This routine is
  458. responsible for allocating and returning the profile buffer
  459. within the client process. However, if the caller subsequently
  460. encounters an error which prevents a successful logon, then
  461. then it will take care of deallocating the buffer. This
  462. buffer is allocated with the AllocateClientBuffer() service.
  463. ProfileBufferSize - Receives the Size (in bytes) of the
  464. returned profile buffer.
  465. NlpUser - Contains the validation information which is
  466. to be copied in the ProfileBuffer.
  467. Return Value:
  468. STATUS_SUCCESS - Indicates the service completed successfully.
  469. STATUS_QUOTA_EXCEEDED - This error indicates that the logon
  470. could not be completed because the client does not have
  471. sufficient quota to allocate the return buffer.
  472. --*/
  473. {
  474. NTSTATUS Status;
  475. CLIENT_BUFFER_DESC ClientBufferDesc;
  476. PMSV1_0_INTERACTIVE_PROFILE_WOW64 LocalProfileBuffer;
  477. //
  478. // Alocate the profile buffer to return to the client
  479. //
  480. NlpInitClientBuffer( &ClientBufferDesc, ClientRequest );
  481. *ProfileBuffer = NULL;
  482. *ProfileBufferSize = sizeof(MSV1_0_INTERACTIVE_PROFILE_WOW64) +
  483. NlpUser->LogonScript.Length + sizeof(WCHAR) +
  484. NlpUser->HomeDirectory.Length + sizeof(WCHAR) +
  485. NlpUser->HomeDirectoryDrive.Length + sizeof(WCHAR) +
  486. NlpUser->FullName.Length + sizeof(WCHAR) +
  487. NlpUser->ProfilePath.Length + sizeof(WCHAR) +
  488. NlpUser->LogonServer.Length + sizeof(WCHAR);
  489. Status = NlpAllocateClientBuffer( &ClientBufferDesc,
  490. sizeof(MSV1_0_INTERACTIVE_PROFILE_WOW64),
  491. *ProfileBufferSize );
  492. if ( !NT_SUCCESS( Status ) ) {
  493. goto Cleanup;
  494. }
  495. LocalProfileBuffer = (PMSV1_0_INTERACTIVE_PROFILE_WOW64) ClientBufferDesc.MsvBuffer;
  496. //
  497. // Copy the scalar fields into the profile buffer.
  498. //
  499. LocalProfileBuffer->MessageType = MsV1_0InteractiveProfile;
  500. LocalProfileBuffer->LogonCount = NlpUser->LogonCount;
  501. LocalProfileBuffer->BadPasswordCount= NlpUser->BadPasswordCount;
  502. OLD_TO_NEW_LARGE_INTEGER( NlpUser->LogonTime,
  503. LocalProfileBuffer->LogonTime );
  504. OLD_TO_NEW_LARGE_INTEGER( NlpUser->LogoffTime,
  505. LocalProfileBuffer->LogoffTime );
  506. OLD_TO_NEW_LARGE_INTEGER( NlpUser->KickOffTime,
  507. LocalProfileBuffer->KickOffTime );
  508. OLD_TO_NEW_LARGE_INTEGER( NlpUser->PasswordLastSet,
  509. LocalProfileBuffer->PasswordLastSet );
  510. OLD_TO_NEW_LARGE_INTEGER( NlpUser->PasswordCanChange,
  511. LocalProfileBuffer->PasswordCanChange );
  512. OLD_TO_NEW_LARGE_INTEGER( NlpUser->PasswordMustChange,
  513. LocalProfileBuffer->PasswordMustChange );
  514. LocalProfileBuffer->UserFlags = NlpUser->UserFlags;
  515. //
  516. // Copy the Unicode strings into the profile buffer.
  517. //
  518. MsvPutWOWClientString( &ClientBufferDesc,
  519. &LocalProfileBuffer->LogonScript,
  520. &NlpUser->LogonScript );
  521. MsvPutWOWClientString( &ClientBufferDesc,
  522. &LocalProfileBuffer->HomeDirectory,
  523. &NlpUser->HomeDirectory );
  524. MsvPutWOWClientString( &ClientBufferDesc,
  525. &LocalProfileBuffer->HomeDirectoryDrive,
  526. &NlpUser->HomeDirectoryDrive );
  527. MsvPutWOWClientString( &ClientBufferDesc,
  528. &LocalProfileBuffer->FullName,
  529. &NlpUser->FullName );
  530. MsvPutWOWClientString( &ClientBufferDesc,
  531. &LocalProfileBuffer->ProfilePath,
  532. &NlpUser->ProfilePath );
  533. MsvPutWOWClientString( &ClientBufferDesc,
  534. &LocalProfileBuffer->LogonServer,
  535. &NlpUser->LogonServer );
  536. //
  537. // Flush the buffer to the client's address space.
  538. //
  539. Status = NlpFlushClientBuffer( &ClientBufferDesc,
  540. (PVOID *) ProfileBuffer );
  541. Cleanup:
  542. //
  543. // If the copy wasn't successful,
  544. // cleanup resources we would have returned to the caller.
  545. //
  546. if ( !NT_SUCCESS(Status) ) {
  547. NlpFreeClientBuffer( &ClientBufferDesc );
  548. }
  549. return Status;
  550. }
  551. NTSTATUS
  552. MsvAllocateNetworkWOWProfile (
  553. IN PLSA_CLIENT_REQUEST ClientRequest,
  554. OUT PMSV1_0_LM20_LOGON_PROFILE *ProfileBuffer,
  555. OUT PULONG ProfileBufferSize,
  556. IN PNETLOGON_VALIDATION_SAM_INFO4 NlpUser,
  557. IN ULONG ParameterControl
  558. )
  559. /*++
  560. Routine Description:
  561. This allocates and fills in the clients network profile.
  562. Arguments:
  563. ClientRequest - Is a pointer to an opaque data structure
  564. representing the client's request.
  565. ProfileBuffer - Is used to return the address of the profile
  566. buffer in the client process. This routine is
  567. responsible for allocating and returning the profile buffer
  568. within the client process. However, if the caller subsequently
  569. encounters an error which prevents a successful logon, then
  570. then it will take care of deallocating the buffer. This
  571. buffer is allocated with the AllocateClientBuffer() service.
  572. ProfileBufferSize - Receives the Size (in bytes) of the
  573. returned profile buffer.
  574. NlpUser - Contains the validation information which is
  575. to be copied in the ProfileBuffer. Will be NULL to indicate a
  576. NULL session.
  577. Return Value:
  578. STATUS_SUCCESS - Indicates the service completed successfully.
  579. STATUS_QUOTA_EXCEEDED - This error indicates that the logon
  580. could not be completed because the client does not have
  581. sufficient quota to allocate the return buffer.
  582. --*/
  583. {
  584. NTSTATUS Status;
  585. NTSTATUS SubAuthStatus = STATUS_SUCCESS;
  586. CLIENT_BUFFER_DESC ClientBufferDesc;
  587. PMSV1_0_LM20_LOGON_PROFILE_WOW64 LocalProfile;
  588. //
  589. // Alocate the profile buffer to return to the client
  590. //
  591. NlpInitClientBuffer( &ClientBufferDesc, ClientRequest );
  592. *ProfileBuffer = NULL;
  593. *ProfileBufferSize = sizeof(MSV1_0_LM20_LOGON_PROFILE_WOW64);
  594. if ( NlpUser != NULL ) {
  595. *ProfileBufferSize += NlpUser->LogonDomainName.Length + sizeof(WCHAR) +
  596. NlpUser->LogonServer.Length + sizeof(WCHAR) +
  597. NlpUser->HomeDirectoryDrive.Length + sizeof(WCHAR);
  598. }
  599. Status = NlpAllocateClientBuffer( &ClientBufferDesc,
  600. sizeof(MSV1_0_LM20_LOGON_PROFILE_WOW64),
  601. *ProfileBufferSize );
  602. if ( !NT_SUCCESS( Status ) ) {
  603. goto Cleanup;
  604. }
  605. LocalProfile = (PMSV1_0_LM20_LOGON_PROFILE_WOW64) ClientBufferDesc.MsvBuffer;
  606. LocalProfile->MessageType = MsV1_0Lm20LogonProfile;
  607. //
  608. // For a NULL session, return a constant profile buffer
  609. //
  610. if ( NlpUser == NULL ) {
  611. LocalProfile->KickOffTime.HighPart = 0x7FFFFFFF;
  612. LocalProfile->KickOffTime.LowPart = 0xFFFFFFFF;
  613. LocalProfile->LogoffTime.HighPart = 0x7FFFFFFF;
  614. LocalProfile->LogoffTime.LowPart = 0xFFFFFFFF;
  615. LocalProfile->UserFlags = 0;
  616. RtlZeroMemory( LocalProfile->UserSessionKey,
  617. sizeof(LocalProfile->UserSessionKey));
  618. RtlZeroMemory( LocalProfile->LanmanSessionKey,
  619. sizeof(LocalProfile->LanmanSessionKey));
  620. RtlZeroMemory( &LocalProfile->LogonDomainName, sizeof(LocalProfile->LogonDomainName) );
  621. RtlZeroMemory( &LocalProfile->LogonServer, sizeof(LocalProfile->LogonServer) );
  622. RtlZeroMemory( &LocalProfile->UserParameters, sizeof(LocalProfile->UserParameters) );
  623. //
  624. // For non-null sessions,
  625. // fill in the profile buffer.
  626. //
  627. } else {
  628. //
  629. // Copy the individual scalar fields into the profile buffer.
  630. //
  631. if ((ParameterControl & MSV1_0_RETURN_PASSWORD_EXPIRY) != 0) {
  632. OLD_TO_NEW_LARGE_INTEGER( NlpUser->PasswordMustChange,
  633. LocalProfile->LogoffTime);
  634. } else {
  635. OLD_TO_NEW_LARGE_INTEGER( NlpUser->LogoffTime,
  636. LocalProfile->LogoffTime);
  637. }
  638. OLD_TO_NEW_LARGE_INTEGER( NlpUser->KickOffTime,
  639. LocalProfile->KickOffTime);
  640. LocalProfile->UserFlags = NlpUser->UserFlags;
  641. RtlCopyMemory( LocalProfile->UserSessionKey,
  642. &NlpUser->UserSessionKey,
  643. sizeof(LocalProfile->UserSessionKey) );
  644. ASSERT( SAMINFO_LM_SESSION_KEY_SIZE ==
  645. sizeof(LocalProfile->LanmanSessionKey) );
  646. RtlCopyMemory(
  647. LocalProfile->LanmanSessionKey,
  648. &NlpUser->ExpansionRoom[SAMINFO_LM_SESSION_KEY],
  649. SAMINFO_LM_SESSION_KEY_SIZE );
  650. // We need to extract the true status sent back for subauth users,
  651. // but not by a sub auth package
  652. SubAuthStatus = NlpUser->ExpansionRoom[SAMINFO_SUBAUTH_STATUS];
  653. //
  654. // Copy the Unicode strings into the profile buffer.
  655. //
  656. MsvPutWOWClientString( &ClientBufferDesc,
  657. &LocalProfile->LogonDomainName,
  658. &NlpUser->LogonDomainName );
  659. MsvPutWOWClientString( &ClientBufferDesc,
  660. &LocalProfile->LogonServer,
  661. &NlpUser->LogonServer );
  662. //
  663. // Kludge: Pass back UserParameters in HomeDirectoryDrive since we
  664. // can't change the NETLOGON_VALIDATION_SAM_INFO structure between
  665. // releases NT 1.0 and NT 1.0A. HomeDirectoryDrive was NULL for release 1.0A
  666. // so we'll use that field.
  667. //
  668. MsvPutWOWClientString( &ClientBufferDesc,
  669. &LocalProfile->UserParameters,
  670. &NlpUser->HomeDirectoryDrive );
  671. }
  672. //
  673. // Flush the buffer to the client's address space.
  674. //
  675. Status = NlpFlushClientBuffer( &ClientBufferDesc,
  676. (PVOID*)ProfileBuffer );
  677. Cleanup:
  678. //
  679. // If the copy wasn't successful,
  680. // cleanup resources we would have returned to the caller.
  681. //
  682. if ( !NT_SUCCESS(Status) ) {
  683. NlpFreeClientBuffer( &ClientBufferDesc );
  684. }
  685. // Save the status for subauth logons
  686. if (NT_SUCCESS(Status) && !NT_SUCCESS(SubAuthStatus))
  687. {
  688. Status = SubAuthStatus;
  689. }
  690. return Status;
  691. }
  692. #endif // _WIN64