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.

849 lines
23 KiB

  1. /*++
  2. Copyright (c) 1993 Microsoft Corporation
  3. Module Name:
  4. authpkg.c
  5. Abstract:
  6. This module is the NetWare authentication package. It saves
  7. credentials in LSA, and notifies the workstation of a logoff.
  8. Author:
  9. Jim Kelly (jimk) 11-Mar-1991
  10. Cliff Van Dyke (cliffv) 25-Apr-1991
  11. Revision History:
  12. Rita Wong (ritaw) 1-Apr-1993 Cloned for NetWare
  13. --*/
  14. #include <string.h>
  15. #include <stdlib.h>
  16. #include <nwclient.h>
  17. #include <ntlsa.h>
  18. #include <nwreg.h>
  19. #include <nwauth.h>
  20. //
  21. // Netware authentication manager credential
  22. //
  23. #define NW_CREDENTIAL_KEY "NWCS_Credential"
  24. //-------------------------------------------------------------------//
  25. // //
  26. // Local functions //
  27. // //
  28. //-------------------------------------------------------------------//
  29. NTSTATUS
  30. AuthpSetCredential(
  31. IN PLUID LogonId,
  32. IN LPWSTR UserName,
  33. IN LPWSTR Password
  34. );
  35. NTSTATUS
  36. AuthpGetCredential(
  37. IN PLUID LogonId,
  38. OUT PNWAUTH_GET_CREDENTIAL_RESPONSE CredBuf
  39. );
  40. VOID
  41. ApLogonTerminatedSingleUser(IN PLUID LogonId);
  42. VOID
  43. ApLogonTerminatedMultiUser(IN PLUID LogonId);
  44. NTSTATUS
  45. NwAuthGetCredential(
  46. IN PLSA_CLIENT_REQUEST ClientRequest,
  47. IN PVOID ProtocolSubmitBuffer,
  48. IN PVOID ClientBufferBase,
  49. IN ULONG SubmitBufferSize,
  50. OUT PVOID *ProtocolReturnBuffer,
  51. OUT PULONG ReturnBufferSize,
  52. OUT PNTSTATUS ProtocolStatus
  53. );
  54. NTSTATUS
  55. NwAuthSetCredential(
  56. IN PLSA_CLIENT_REQUEST ClientRequest,
  57. IN PVOID ProtocolSubmitBuffer,
  58. IN PVOID ClientBufferBase,
  59. IN ULONG SubmitBufferSize,
  60. OUT PVOID *ProtocolReturnBuffer,
  61. OUT PULONG ReturnBufferSize,
  62. OUT PNTSTATUS ProtocolStatus
  63. );
  64. PVOID NwAuthHeap;
  65. ULONG NwAuthPackageId;
  66. LSA_DISPATCH_TABLE Lsa;
  67. //
  68. // LsaApCallPackage() function dispatch table
  69. //
  70. PLSA_AP_CALL_PACKAGE
  71. NwCallPackageDispatch[] = {
  72. NwAuthGetCredential,
  73. NwAuthSetCredential
  74. };
  75. //
  76. // Structure of the credential saved in LSA.
  77. //
  78. typedef struct _NWCREDENTIAL {
  79. LPWSTR UserName;
  80. LPWSTR Password;
  81. } NWCREDENTIAL, *PNWCREDENTIAL;
  82. //-------------------------------------------------------------------//
  83. // //
  84. // Authentication package dispatch routines. //
  85. // //
  86. //-------------------------------------------------------------------//
  87. NTSTATUS
  88. LsaApInitializePackage (
  89. IN ULONG AuthenticationPackageId,
  90. IN PLSA_DISPATCH_TABLE LsaDispatchTable,
  91. IN PSTRING Database OPTIONAL,
  92. IN PSTRING Confidentiality OPTIONAL,
  93. OUT PSTRING *AuthenticationPackageName
  94. )
  95. /*++
  96. Routine Description:
  97. This service is called once by the LSA during system initialization to
  98. provide the DLL a chance to initialize itself.
  99. Arguments:
  100. AuthenticationPackageId - The ID assigned to the authentication
  101. package.
  102. LsaDispatchTable - Provides the address of a table of LSA
  103. services available to authentication packages. The services
  104. of this table are ordered according to the enumerated type
  105. LSA_DISPATCH_TABLE_API.
  106. Database - This parameter is not used by this authentication package.
  107. Confidentiality - This parameter is not used by this authentication
  108. package.
  109. AuthenticationPackageName - Receives the name of the
  110. authentication package. The authentication package is
  111. responsible for allocating the buffer that the string is in
  112. (using the AllocateLsaHeap() service) and returning its
  113. address here. The buffer will be deallocated by LSA when it
  114. is no longer needed.
  115. Return Value:
  116. STATUS_SUCCESS - Indicates the service completed successfully.
  117. --*/
  118. {
  119. PSTRING NameString;
  120. PCHAR NameBuffer;
  121. UNREFERENCED_PARAMETER(Database);
  122. UNREFERENCED_PARAMETER(Confidentiality);
  123. //
  124. // Use the process heap for memory allocations.
  125. //
  126. NwAuthHeap = RtlProcessHeap();
  127. NwAuthPackageId = AuthenticationPackageId;
  128. //
  129. // Copy the LSA service dispatch table
  130. //
  131. Lsa.CreateLogonSession = LsaDispatchTable->CreateLogonSession;
  132. Lsa.DeleteLogonSession = LsaDispatchTable->DeleteLogonSession;
  133. Lsa.AddCredential = LsaDispatchTable->AddCredential;
  134. Lsa.GetCredentials = LsaDispatchTable->GetCredentials;
  135. Lsa.DeleteCredential = LsaDispatchTable->DeleteCredential;
  136. Lsa.AllocateLsaHeap = LsaDispatchTable->AllocateLsaHeap;
  137. Lsa.FreeLsaHeap = LsaDispatchTable->FreeLsaHeap;
  138. Lsa.AllocateClientBuffer = LsaDispatchTable->AllocateClientBuffer;
  139. Lsa.FreeClientBuffer = LsaDispatchTable->FreeClientBuffer;
  140. Lsa.CopyToClientBuffer = LsaDispatchTable->CopyToClientBuffer;
  141. Lsa.CopyFromClientBuffer = LsaDispatchTable->CopyFromClientBuffer;
  142. //
  143. // Allocate and return our package name
  144. //
  145. NameBuffer = (*Lsa.AllocateLsaHeap)(sizeof(NW_AUTH_PACKAGE_NAME));
  146. strcpy(NameBuffer, NW_AUTH_PACKAGE_NAME);
  147. NameString = (*Lsa.AllocateLsaHeap)(sizeof(STRING));
  148. RtlInitString(NameString, NameBuffer);
  149. (*AuthenticationPackageName) = NameString;
  150. //
  151. // Delete outdated credential information in the registry
  152. //
  153. NwDeleteInteractiveLogon(NULL);
  154. (void) NwDeleteServiceLogon(NULL);
  155. return STATUS_SUCCESS;
  156. }
  157. NTSTATUS
  158. LsaApLogonUser (
  159. IN PLSA_CLIENT_REQUEST ClientRequest,
  160. IN SECURITY_LOGON_TYPE LogonType,
  161. IN PVOID ProtocolSubmitBuffer,
  162. IN PVOID ClientBufferBase,
  163. IN ULONG SubmitBufferSize,
  164. OUT PVOID *ProfileBuffer,
  165. OUT PULONG ProfileBufferSize,
  166. OUT PLUID LogonId,
  167. OUT PNTSTATUS SubStatus,
  168. OUT PLSA_TOKEN_INFORMATION_TYPE TokenInformationType,
  169. OUT PVOID *TokenInformation,
  170. OUT PUNICODE_STRING *AccountName,
  171. OUT PUNICODE_STRING *AuthenticatingAuthority
  172. )
  173. /*++
  174. Routine Description:
  175. This routine is used to authenticate a user logon attempt. This may be
  176. the user's initial logon, necessary to gain access to NT, or may
  177. be a subsequent logon attempt. If the logon is the user's initial
  178. logon, then a new LSA logon session will be established for the user
  179. and a PrimaryToken will be returned. Otherwise, the authentication
  180. package will associated appropriate credentials with the already logged
  181. on user's existing LSA logon session.
  182. Arguments:
  183. ClientRequest - Is a pointer to an opaque data structure
  184. representing the client's request.
  185. LogonType - Identifies the type of logon being attempted.
  186. ProtocolSubmitBuffer - Supplies the authentication
  187. information specific to the authentication package.
  188. ClientBufferBase - Provides the address within the client
  189. process at which the authentication information was resident.
  190. This may be necessary to fix-up any pointers within the
  191. authentication information buffer.
  192. SubmitBufferSize - Indicates the Size, in bytes,
  193. of the authentication information buffer.
  194. ProfileBuffer - Is used to return the address of the profile
  195. buffer in the client process. The authentication package is
  196. responsible for allocating and returning the profile buffer
  197. within the client process. However, if the LSA subsequently
  198. encounters an error which prevents a successful logon, then
  199. the LSA will take care of deallocating that buffer. This
  200. buffer is expected to have been allocated with the
  201. AllocateClientBuffer() service.
  202. The format and semantics of this buffer are specific to the
  203. authentication package.
  204. ProfileBufferSize - Receives the size (in bytes) of the
  205. returned profile buffer.
  206. LogonId - Points to a buffer into which the authentication
  207. package must return a logon ID that uniquely
  208. identifies this logon session.
  209. SubStatus - If the logon failed due to account restrictions, the
  210. reason for the failure should be returned via this parameter.
  211. The reason is authentication-package specific. The substatus
  212. values for authentication package "MSV1.0" are:
  213. STATUS_INVALID_LOGON_HOURS
  214. STATUS_INVALID_WORKSTATION
  215. STATUS_PASSWORD_EXPIRED
  216. STATUS_ACCOUNT_DISABLED
  217. TokenInformationType - If the logon is successful, this field is
  218. used to indicate what level of information is being returned
  219. for inclusion in the Token to be created. This information
  220. is returned via the TokenInformation parameter.
  221. TokenInformation - If the logon is successful, this parameter is
  222. used by the authentication package to return information to
  223. be included in the token. The format and content of the
  224. buffer returned is indicated by the TokenInformationLevel
  225. return value.
  226. AccountName - A Unicode string describing the account name
  227. being logged on to. This parameter must always be returned
  228. regardless of the success or failure of the operation.
  229. AuthenticatingAuthority - A Unicode string describing the Authenticating
  230. Authority for the logon. This string may optionally be omitted.
  231. Return Value:
  232. STATUS_NOT_IMPLEMENTED - NetWare authentication package does not
  233. support login.
  234. --*/
  235. {
  236. UNREFERENCED_PARAMETER(ClientRequest);
  237. UNREFERENCED_PARAMETER(LogonType);
  238. UNREFERENCED_PARAMETER(ProtocolSubmitBuffer);
  239. UNREFERENCED_PARAMETER(ClientBufferBase);
  240. UNREFERENCED_PARAMETER(SubmitBufferSize);
  241. UNREFERENCED_PARAMETER(ProfileBuffer);
  242. UNREFERENCED_PARAMETER(ProfileBufferSize);
  243. UNREFERENCED_PARAMETER(LogonId);
  244. UNREFERENCED_PARAMETER(SubStatus);
  245. UNREFERENCED_PARAMETER(TokenInformationType);
  246. UNREFERENCED_PARAMETER(TokenInformation);
  247. UNREFERENCED_PARAMETER(AccountName);
  248. UNREFERENCED_PARAMETER(AuthenticatingAuthority);
  249. return STATUS_NOT_IMPLEMENTED;
  250. }
  251. NTSTATUS
  252. LsaApCallPackage (
  253. IN PLSA_CLIENT_REQUEST ClientRequest,
  254. IN PVOID ProtocolSubmitBuffer,
  255. IN PVOID ClientBufferBase,
  256. IN ULONG SubmitBufferLength,
  257. OUT PVOID *ProtocolReturnBuffer,
  258. OUT PULONG ReturnBufferLength,
  259. OUT PNTSTATUS ProtocolStatus
  260. )
  261. /*++
  262. Routine Description:
  263. This routine is the dispatch routine for
  264. LsaCallAuthenticationPackage().
  265. Arguments:
  266. ClientRequest - Is a pointer to an opaque data structure
  267. representing the client's request.
  268. ProtocolSubmitBuffer - Supplies a protocol message specific to
  269. the authentication package.
  270. ClientSubmitBufferBase - Supplies the client address of the submitted
  271. protocol message.
  272. SubmitBufferLength - Indicates the length of the submitted
  273. protocol message buffer.
  274. ProtocolReturnBuffer - Is used to return the address of the
  275. protocol buffer in the client process. The authentication
  276. package is responsible for allocating and returning the
  277. protocol buffer within the client process. This buffer is
  278. expected to have been allocated with the
  279. AllocateClientBuffer() service.
  280. The format and semantics of this buffer are specific to the
  281. authentication package.
  282. ReturnBufferLength - Receives the length (in bytes) of the
  283. returned protocol buffer.
  284. ProtocolStatus - Assuming the services completion is
  285. STATUS_SUCCESS, this parameter will receive completion status
  286. returned by the specified authentication package. The list
  287. of status values that may be returned are authentication
  288. package specific.
  289. Return Status:
  290. --*/
  291. {
  292. ULONG MessageType;
  293. //
  294. // Get the messsage type from the protocol submit buffer.
  295. //
  296. if ( SubmitBufferLength < sizeof(NWAUTH_MESSAGE_TYPE) ) {
  297. return STATUS_INVALID_PARAMETER;
  298. }
  299. MessageType =
  300. (ULONG) *((PNWAUTH_MESSAGE_TYPE)(ProtocolSubmitBuffer));
  301. if ( MessageType >=
  302. (sizeof(NwCallPackageDispatch)/sizeof(NwCallPackageDispatch[0])) ) {
  303. return STATUS_INVALID_PARAMETER;
  304. }
  305. //
  306. // Allow the dispatch routines to only set the return buffer information
  307. // on success conditions.
  308. //
  309. *ProtocolReturnBuffer = NULL;
  310. *ReturnBufferLength = 0;
  311. //
  312. // Call the appropriate routine for this message.
  313. //
  314. return (*(NwCallPackageDispatch[MessageType]))(
  315. ClientRequest,
  316. ProtocolSubmitBuffer,
  317. ClientBufferBase,
  318. SubmitBufferLength,
  319. ProtocolReturnBuffer,
  320. ReturnBufferLength,
  321. ProtocolStatus
  322. ) ;
  323. }
  324. VOID
  325. LsaApLogonTerminated (
  326. IN PLUID LogonId
  327. )
  328. /*++
  329. Routine Description:
  330. This routine is used to notify each authentication package when a logon
  331. session terminates. A logon session terminates when the last token
  332. referencing the logon session is deleted.
  333. Arguments:
  334. LogonId - Is the logon ID that just logged off.
  335. Return Status:
  336. None.
  337. --*/
  338. {
  339. #if DBG
  340. IF_DEBUG(LOGON) {
  341. KdPrint(("\nNWPROVAU: LsaApLogonTerminated\n"));
  342. }
  343. #endif
  344. RpcTryExcept {
  345. //
  346. // The logon ID may be for a service login
  347. //
  348. if (NwDeleteServiceLogon(LogonId) == NO_ERROR) {
  349. //
  350. // Tell workstation to log off the service.
  351. //
  352. (void) NwrLogoffUser(NULL, LogonId);
  353. goto Done;
  354. }
  355. if (NwDeleteInteractiveLogon( LogonId ) == NO_ERROR ) {
  356. //
  357. // Tell workstation to log off the
  358. // interactive user.
  359. //
  360. (void) NwrLogoffUser(NULL, LogonId);
  361. goto Done;
  362. }
  363. Done: ;
  364. }
  365. RpcExcept(1) {
  366. //status = NwpMapRpcError(RpcExceptionCode());
  367. }
  368. RpcEndExcept
  369. }
  370. NTSTATUS
  371. NwAuthGetCredential(
  372. IN PLSA_CLIENT_REQUEST ClientRequest,
  373. IN PVOID ProtocolSubmitBuffer,
  374. IN PVOID ClientBufferBase,
  375. IN ULONG SubmitBufferSize,
  376. OUT PVOID *ProtocolReturnBuffer,
  377. OUT PULONG ReturnBufferSize,
  378. OUT PNTSTATUS ProtocolStatus
  379. )
  380. /*++
  381. Routine Description:
  382. This routine is the dispatch routine for LsaCallAuthenticationPackage()
  383. with a message type of NwAuth_GetCredential. It is called by
  384. the NetWare workstation service to get the username and password
  385. associated with a logon ID.
  386. Arguments:
  387. The arguments to this routine are identical to those of LsaApCallPackage.
  388. Only the special attributes of these parameters as they apply to
  389. this routine are mentioned here.
  390. Return Value:
  391. STATUS_SUCCESS - Indicates the service completed successfully.
  392. --*/
  393. {
  394. NTSTATUS Status;
  395. PNWAUTH_GET_CREDENTIAL_RESPONSE LocalBuf;
  396. UNREFERENCED_PARAMETER(ClientBufferBase);
  397. //
  398. // Ensure the specified Submit Buffer is of reasonable size.
  399. //
  400. if (SubmitBufferSize < sizeof(NWAUTH_GET_CREDENTIAL_REQUEST)) {
  401. return STATUS_INVALID_PARAMETER;
  402. }
  403. //
  404. // Allocate a local buffer and a buffer in client's address space.
  405. //
  406. *ReturnBufferSize = sizeof(NWAUTH_GET_CREDENTIAL_RESPONSE);
  407. LocalBuf = RtlAllocateHeap(NwAuthHeap, 0, *ReturnBufferSize);
  408. if (LocalBuf == NULL) {
  409. return STATUS_NO_MEMORY;
  410. }
  411. Status = (*Lsa.AllocateClientBuffer)(
  412. ClientRequest,
  413. *ReturnBufferSize,
  414. (PVOID *) ProtocolReturnBuffer
  415. );
  416. if (! NT_SUCCESS( Status )) {
  417. RtlFreeHeap(NwAuthHeap, 0, LocalBuf);
  418. return Status;
  419. }
  420. //
  421. // Get the credential from LSA
  422. //
  423. Status = AuthpGetCredential(
  424. &(((PNWAUTH_GET_CREDENTIAL_REQUEST) ProtocolSubmitBuffer)->LogonId),
  425. LocalBuf
  426. );
  427. if (! NT_SUCCESS(Status)) {
  428. goto Cleanup;
  429. }
  430. //
  431. // Copy the data to the client's address space.
  432. //
  433. Status = (*Lsa.CopyToClientBuffer)(
  434. ClientRequest,
  435. *ReturnBufferSize,
  436. (PVOID) *ProtocolReturnBuffer,
  437. (PVOID) LocalBuf
  438. );
  439. Cleanup:
  440. RtlFreeHeap(NwAuthHeap, 0, LocalBuf);
  441. //
  442. // If we weren't successful, free the buffer in the clients address space.
  443. // Otherwise, the client will free the memory when done.
  444. //
  445. if (! NT_SUCCESS(Status)) {
  446. (VOID) (*Lsa.FreeClientBuffer)(
  447. ClientRequest,
  448. *ProtocolReturnBuffer
  449. );
  450. *ProtocolReturnBuffer = NULL;
  451. }
  452. //
  453. // Return status to the caller.
  454. //
  455. *ProtocolStatus = Status;
  456. return STATUS_SUCCESS;
  457. }
  458. NTSTATUS
  459. NwAuthSetCredential(
  460. IN PLSA_CLIENT_REQUEST ClientRequest,
  461. IN PVOID ProtocolSubmitBuffer,
  462. IN PVOID ClientBufferBase,
  463. IN ULONG SubmitBufferSize,
  464. OUT PVOID *ProtocolReturnBuffer,
  465. OUT PULONG ReturnBufferSize,
  466. OUT PNTSTATUS ProtocolStatus
  467. )
  468. /*++
  469. Routine Description:
  470. This routine is the dispatch routine for LsaCallAuthenticationPackage()
  471. with a message type of NwAuth_SetCredential. It is called by
  472. the NetWare credential manager DLL on user logon to save the username
  473. and password of the logon session.
  474. Arguments:
  475. The arguments to this routine are identical to those of LsaApCallPackage.
  476. Only the special attributes of these parameters as they apply to
  477. this routine are mentioned here.
  478. Return Value:
  479. STATUS_SUCCESS - Indicates the service completed successfully.
  480. --*/
  481. {
  482. NTSTATUS Status;
  483. UNREFERENCED_PARAMETER(ClientBufferBase);
  484. //
  485. // Ensure the specified Submit Buffer is of reasonable size.
  486. //
  487. if (SubmitBufferSize < sizeof(NWAUTH_SET_CREDENTIAL_REQUEST)) {
  488. return STATUS_INVALID_PARAMETER;
  489. }
  490. #if DBG
  491. IF_DEBUG(LOGON) {
  492. KdPrint(("NwAuthSetCredential: LogonId %08lx%08lx Username %ws\n",
  493. ((PNWAUTH_SET_CREDENTIAL_REQUEST) ProtocolSubmitBuffer)->LogonId.HighPart,
  494. ((PNWAUTH_SET_CREDENTIAL_REQUEST) ProtocolSubmitBuffer)->LogonId.LowPart,
  495. ((PNWAUTH_SET_CREDENTIAL_REQUEST) ProtocolSubmitBuffer)->UserName
  496. ));
  497. }
  498. #endif
  499. //
  500. // Set the credential in LSA
  501. //
  502. Status = AuthpSetCredential(
  503. &(((PNWAUTH_SET_CREDENTIAL_REQUEST) ProtocolSubmitBuffer)->LogonId),
  504. ((PNWAUTH_SET_CREDENTIAL_REQUEST) ProtocolSubmitBuffer)->UserName,
  505. ((PNWAUTH_SET_CREDENTIAL_REQUEST) ProtocolSubmitBuffer)->Password
  506. );
  507. *ProtocolStatus = Status;
  508. return STATUS_SUCCESS;
  509. }
  510. NTSTATUS
  511. AuthpGetCredential(
  512. IN PLUID LogonId,
  513. OUT PNWAUTH_GET_CREDENTIAL_RESPONSE CredBuf
  514. )
  515. /*++
  516. Routine Description:
  517. This routine retrieves the credential saved in LSA given the
  518. logon ID.
  519. Arguments:
  520. LogonId - Supplies the logon ID for the logon session.
  521. CredBuf - Buffer to receive the credential.
  522. Return Value:
  523. --*/
  524. {
  525. NTSTATUS Status;
  526. STRING KeyString;
  527. STRING CredString;
  528. ULONG QueryContext = 0;
  529. ULONG KeyLength;
  530. PNWCREDENTIAL Credential;
  531. RtlInitString(&KeyString, NW_CREDENTIAL_KEY);
  532. Status = (*Lsa.GetCredentials)(
  533. LogonId,
  534. NwAuthPackageId,
  535. &QueryContext,
  536. (BOOLEAN) FALSE, // Just retrieve matching key
  537. &KeyString,
  538. &KeyLength,
  539. &CredString
  540. );
  541. if (! NT_SUCCESS(Status)) {
  542. return Status;
  543. }
  544. Credential = (PNWCREDENTIAL) CredString.Buffer;
  545. #if DBG
  546. IF_DEBUG(LOGON) {
  547. KdPrint(("AuthpGetCredential: Got CredentialSize %lu\n", CredString.Length));
  548. }
  549. #endif
  550. //
  551. // Make the pointers absolute.
  552. //
  553. Credential->UserName = (LPWSTR) ((DWORD_PTR) Credential->UserName +
  554. (DWORD_PTR) Credential);
  555. Credential->Password = (LPWSTR) ((DWORD_PTR) Credential->Password +
  556. (DWORD_PTR) Credential);
  557. wcscpy(CredBuf->UserName, Credential->UserName);
  558. wcscpy(CredBuf->Password, Credential->Password);
  559. return STATUS_SUCCESS;
  560. }
  561. NTSTATUS
  562. AuthpSetCredential(
  563. IN PLUID LogonId,
  564. IN LPWSTR UserName,
  565. IN LPWSTR Password
  566. )
  567. /*++
  568. Routine Description:
  569. This routine saves the credential in LSA.
  570. Arguments:
  571. LogonId - Supplies the logon ID for the logon session.
  572. UserName, Password - Credential for the logon session.
  573. Return Value:
  574. --*/
  575. {
  576. NTSTATUS Status;
  577. PNWCREDENTIAL Credential;
  578. DWORD CredentialSize;
  579. STRING CredString;
  580. STRING KeyString;
  581. //
  582. // Allocate memory to package the credential.
  583. //
  584. CredentialSize = sizeof(NWCREDENTIAL) +
  585. (wcslen(UserName) + wcslen(Password) + 2) *
  586. sizeof(WCHAR);
  587. #if DBG
  588. IF_DEBUG(LOGON) {
  589. KdPrint(("AuthpSetCredential: CredentialSize is %lu\n", CredentialSize));
  590. }
  591. #endif
  592. Credential = RtlAllocateHeap(NwAuthHeap, 0, CredentialSize);
  593. if (Credential == NULL) {
  594. return STATUS_NO_MEMORY;
  595. }
  596. RtlZeroMemory(Credential, CredentialSize);
  597. //
  598. // Pack the credential
  599. //
  600. Credential->UserName = (LPWSTR) (((DWORD_PTR) Credential) + sizeof(NWCREDENTIAL));
  601. wcscpy(Credential->UserName, UserName);
  602. Credential->Password = (LPWSTR) ((DWORD_PTR) Credential->UserName +
  603. (wcslen(UserName) + 1) * sizeof(WCHAR));
  604. wcscpy(Credential->Password, Password);
  605. //
  606. // Make the pointers self-relative.
  607. //
  608. Credential->UserName = (LPWSTR) ((DWORD_PTR) Credential->UserName -
  609. (DWORD_PTR) Credential);
  610. Credential->Password = (LPWSTR) ((DWORD_PTR) Credential->Password -
  611. (DWORD_PTR) Credential);
  612. //
  613. // Add credential to logon session
  614. //
  615. RtlInitString(&KeyString, NW_CREDENTIAL_KEY);
  616. CredString.Buffer = (PCHAR) Credential;
  617. CredString.Length = (USHORT) CredentialSize;
  618. CredString.MaximumLength = (USHORT) CredentialSize;
  619. Status = (*Lsa.AddCredential)(
  620. LogonId,
  621. NwAuthPackageId,
  622. &KeyString,
  623. &CredString
  624. );
  625. if (! NT_SUCCESS(Status)) {
  626. KdPrint(( "NWPROVAU: AuthpSetCredential: error from AddCredential %lX\n",
  627. Status));
  628. }
  629. return Status;
  630. }