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.

950 lines
24 KiB

  1. //+-----------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (c) Microsoft Corporation 1992 - 1997
  6. //
  7. // File: stubs.cxx
  8. //
  9. // Contents: user-mode stubs for security API
  10. //
  11. //
  12. // History: 3/5/94 MikeSw Created
  13. // 12/15/97 AdamBa Modified from security\lsa\security\ntlm
  14. //
  15. //------------------------------------------------------------------------
  16. #include <rdrssp.h>
  17. #include <nturtl.h>
  18. #include <align.h>
  19. #include "nlp.h"
  20. static CredHandle NullCredential = {0,0};
  21. #define NTLMSSP_REQUIRED_NEGOTIATE_FLAGS ( NTLMSSP_NEGOTIATE_UNICODE | \
  22. NTLMSSP_REQUEST_INIT_RESPONSE )
  23. NTSTATUS
  24. MspLm20GetChallengeResponse (
  25. IN PVOID ProtocolSubmitBuffer,
  26. IN ULONG SubmitBufferSize,
  27. OUT PVOID *ProtocolReturnBuffer,
  28. OUT PULONG ReturnBufferSize,
  29. IN BOOLEAN OwfPasswordProvided
  30. );
  31. //+-------------------------------------------------------------------------
  32. //
  33. // Function: AcquireCredentialsHandleK
  34. //
  35. // Synopsis:
  36. //
  37. // Effects:
  38. //
  39. // Arguments:
  40. //
  41. // Requires:
  42. //
  43. // Returns:
  44. //
  45. // Notes:
  46. //
  47. //
  48. //--------------------------------------------------------------------------
  49. SECURITY_STATUS SEC_ENTRY
  50. AcquireCredentialsHandleK(
  51. PSECURITY_STRING pssPrincipal, // Name of principal
  52. PSECURITY_STRING pssPackageName, // Name of package
  53. unsigned long fCredentialUse, // Flags indicating use
  54. void SEC_FAR * pvLogonId, // Pointer to logon ID
  55. void SEC_FAR * pAuthData, // Package specific data
  56. SEC_GET_KEY_FN pGetKeyFn, // Pointer to GetKey() func
  57. void SEC_FAR * pvGetKeyArgument, // Value to pass to GetKey()
  58. PCredHandle phCredential, // (out) Cred Handle
  59. PTimeStamp ptsExpiry // (out) Lifetime (optional)
  60. )
  61. {
  62. SECURITY_STATUS scRet;
  63. SECURITY_STRING Principal;
  64. TimeStamp OptionalTimeStamp;
  65. UNICODE_STRING PackageName;
  66. PMS_LOGON_CREDENTIAL LogonCredential;
  67. if (!pssPackageName)
  68. {
  69. return(SEC_E_SECPKG_NOT_FOUND);
  70. }
  71. //
  72. // We don't accept principal names either.
  73. //
  74. if (pssPrincipal)
  75. {
  76. return(SEC_E_UNKNOWN_CREDENTIALS);
  77. }
  78. //
  79. // Make sure they want the NTLM security package
  80. //
  81. RtlInitUnicodeString(
  82. &PackageName,
  83. NTLMSP_NAME
  84. );
  85. if (!RtlEqualUnicodeString(
  86. pssPackageName,
  87. &PackageName,
  88. TRUE))
  89. {
  90. return(SEC_E_SECPKG_NOT_FOUND);
  91. }
  92. #if 0
  93. //
  94. // For the moment, only accept OWF passwords. This is the
  95. // easiest for now since there is no place to record the
  96. // flag otherwise. The password provided is assumed to
  97. // be the LM and NT OWF passwords concatenated together.
  98. //
  99. if ((fCredentialUse & SECPKG_CRED_OWF_PASSWORD) == 0) {
  100. return(SEC_E_UNSUPPORTED_FUNCTION);
  101. }
  102. #endif
  103. //
  104. // The credential handle is the logon id
  105. //
  106. if (fCredentialUse & SECPKG_CRED_OUTBOUND)
  107. {
  108. if (pvLogonId != NULL)
  109. {
  110. LogonCredential = (PMS_LOGON_CREDENTIAL)SecAllocate(sizeof(MS_LOGON_CREDENTIAL));
  111. if (LogonCredential == NULL) {
  112. return(SEC_E_INSUFFICIENT_MEMORY);
  113. }
  114. LogonCredential->LogonId = *((PLUID)pvLogonId);
  115. LogonCredential->CredentialUse = fCredentialUse;
  116. *(PMS_LOGON_CREDENTIAL *)phCredential = LogonCredential;
  117. }
  118. else
  119. {
  120. return(SEC_E_UNKNOWN_CREDENTIALS);
  121. }
  122. }
  123. else if (fCredentialUse & SECPKG_CRED_INBOUND)
  124. {
  125. //
  126. // For inbound credentials, we will accept a logon id but
  127. // we don't require it.
  128. //
  129. if (pvLogonId != NULL)
  130. {
  131. LogonCredential = (PMS_LOGON_CREDENTIAL)SecAllocate(sizeof(MS_LOGON_CREDENTIAL));
  132. if (LogonCredential == NULL) {
  133. return(SEC_E_INSUFFICIENT_MEMORY);
  134. }
  135. LogonCredential->LogonId = *((PLUID)pvLogonId);
  136. LogonCredential->CredentialUse = fCredentialUse;
  137. *(PMS_LOGON_CREDENTIAL *)phCredential = LogonCredential;
  138. }
  139. else
  140. {
  141. *phCredential = NullCredential;
  142. }
  143. }
  144. else
  145. {
  146. return(SEC_E_UNSUPPORTED_FUNCTION);
  147. }
  148. return(SEC_E_OK);
  149. }
  150. //+-------------------------------------------------------------------------
  151. //
  152. // Function: FreeCredentialsHandleK
  153. //
  154. // Synopsis:
  155. //
  156. // Effects:
  157. //
  158. // Arguments:
  159. //
  160. // Requires:
  161. //
  162. // Returns:
  163. //
  164. // Notes:
  165. //
  166. //
  167. //--------------------------------------------------------------------------
  168. SECURITY_STATUS SEC_ENTRY
  169. FreeCredentialsHandleK(
  170. PCredHandle phCredential // Handle to free
  171. )
  172. {
  173. if ((phCredential != NULL) && (!RtlEqualMemory(phCredential, &NullCredential, sizeof(NullCredential)))) {
  174. PMS_LOGON_CREDENTIAL LogonCredential = *((PMS_LOGON_CREDENTIAL *)phCredential);
  175. if (LogonCredential != NULL) {
  176. SecFree(LogonCredential);
  177. *phCredential = NullCredential;
  178. }
  179. }
  180. return(SEC_E_OK);
  181. }
  182. VOID
  183. PutString(
  184. OUT PSTRING32 Destination,
  185. IN PSTRING Source,
  186. IN PVOID Base,
  187. IN OUT PUCHAR * Where
  188. )
  189. {
  190. Destination->Buffer = (ULONG)((ULONG_PTR) *Where - (ULONG_PTR) Base);
  191. Destination->Length =
  192. Source->Length;
  193. Destination->MaximumLength =
  194. Source->Length;
  195. RtlCopyMemory(
  196. *Where,
  197. Source->Buffer,
  198. Source->Length
  199. );
  200. *Where += Source->Length;
  201. }
  202. //+-------------------------------------------------------------------------
  203. //
  204. // Function: InitializeSecurityContextK
  205. //
  206. // Synopsis:
  207. //
  208. // Effects:
  209. //
  210. // Arguments:
  211. //
  212. // Requires:
  213. //
  214. // Returns:
  215. //
  216. // Notes:
  217. //
  218. //
  219. //--------------------------------------------------------------------------
  220. SECURITY_STATUS SEC_ENTRY
  221. InitializeSecurityContextK(
  222. PCredHandle phCredential, // Cred to base context
  223. PCtxtHandle phContext, // Existing context (OPT)
  224. PSECURITY_STRING pssTargetName, // Name of target
  225. unsigned long fContextReq, // Context Requirements
  226. unsigned long Reserved1, // Reserved, MBZ
  227. unsigned long TargetDataRep, // Data rep of target
  228. PSecBufferDesc pInput, // Input Buffers
  229. unsigned long Reserved2, // Reserved, MBZ
  230. PCtxtHandle phNewContext, // (out) New Context handle
  231. PSecBufferDesc pOutput, // (inout) Output Buffers
  232. unsigned long SEC_FAR * pfContextAttr, // (out) Context attrs
  233. PTimeStamp ptsExpiry // (out) Life span (OPT)
  234. )
  235. {
  236. SECURITY_STATUS scRet;
  237. PMSV1_0_GETCHALLENRESP_REQUEST ChallengeRequest = NULL;
  238. ULONG ChallengeRequestSize;
  239. PMSV1_0_GETCHALLENRESP_RESPONSE ChallengeResponse = NULL;
  240. ULONG ChallengeResponseSize;
  241. PCHALLENGE_MESSAGE ChallengeMessage = NULL;
  242. ULONG ChallengeMessageSize;
  243. PNTLM_CHALLENGE_MESSAGE NtlmChallengeMessage = NULL;
  244. ULONG NtlmChallengeMessageSize;
  245. PAUTHENTICATE_MESSAGE AuthenticateMessage = NULL;
  246. ULONG AuthenticateMessageSize;
  247. PNTLM_INITIALIZE_RESPONSE NtlmInitializeResponse = NULL;
  248. UNICODE_STRING PasswordToUse;
  249. UNICODE_STRING UserNameToUse;
  250. UNICODE_STRING DomainNameToUse;
  251. ULONG ParameterControl = USE_PRIMARY_PASSWORD |
  252. RETURN_PRIMARY_USERNAME |
  253. RETURN_PRIMARY_LOGON_DOMAINNAME;
  254. NTSTATUS FinalStatus = STATUS_SUCCESS;
  255. PUCHAR Where;
  256. PSecBuffer AuthenticationToken = NULL;
  257. PSecBuffer InitializeResponseToken = NULL;
  258. BOOLEAN UseSuppliedCreds = FALSE;
  259. RtlInitUnicodeString(
  260. &PasswordToUse,
  261. NULL
  262. );
  263. RtlInitUnicodeString(
  264. &UserNameToUse,
  265. NULL
  266. );
  267. RtlInitUnicodeString(
  268. &DomainNameToUse,
  269. NULL
  270. );
  271. //
  272. // Check for valid sizes, pointers, etc.:
  273. //
  274. if (!phCredential)
  275. {
  276. return(SEC_E_INVALID_HANDLE);
  277. }
  278. //
  279. // Locate the buffers with the input data
  280. //
  281. if (!GetTokenBuffer(
  282. pInput,
  283. 0, // get the first security token
  284. (PVOID *) &ChallengeMessage,
  285. &ChallengeMessageSize,
  286. TRUE // may be readonly
  287. ))
  288. {
  289. scRet = SEC_E_INVALID_TOKEN;
  290. goto Cleanup;
  291. }
  292. //
  293. // If we are using supplied creds, get them now too.
  294. //
  295. if (fContextReq & ISC_REQ_USE_SUPPLIED_CREDS)
  296. {
  297. if (!GetTokenBuffer(
  298. pInput,
  299. 1, // get the second security token
  300. (PVOID *) &NtlmChallengeMessage,
  301. &NtlmChallengeMessageSize,
  302. TRUE // may be readonly
  303. ))
  304. {
  305. scRet = SEC_E_INVALID_TOKEN;
  306. goto Cleanup;
  307. }
  308. else
  309. {
  310. UseSuppliedCreds = TRUE;
  311. }
  312. }
  313. //
  314. // Get the output tokens
  315. //
  316. if (!GetSecurityToken(
  317. pOutput,
  318. 0,
  319. &AuthenticationToken) ||
  320. !GetSecurityToken(
  321. pOutput,
  322. 1,
  323. &InitializeResponseToken ) )
  324. {
  325. scRet = SEC_E_INVALID_TOKEN;
  326. goto Cleanup;
  327. }
  328. //
  329. // Make sure the sizes are o.k.
  330. //
  331. if ((ChallengeMessageSize < sizeof(CHALLENGE_MESSAGE)) ||
  332. (UseSuppliedCreds &&
  333. !(NtlmChallengeMessageSize < sizeof(NTLM_CHALLENGE_MESSAGE))))
  334. {
  335. scRet = SEC_E_INVALID_TOKEN;
  336. }
  337. //
  338. // Make sure the caller wants us to allocate memory:
  339. //
  340. if (!(fContextReq & ISC_REQ_ALLOCATE_MEMORY))
  341. {
  342. scRet = SEC_E_UNSUPPORTED_FUNCTION;
  343. goto Cleanup;
  344. }
  345. //
  346. // KB: allow calls requesting PROMPT_FOR_CREDS to go through.
  347. // We won't prompt, but we will setup a context properly.
  348. // This is OK because PROMPT_FOR_CREDS flag doesnt' do anything
  349. // in the NTLM package
  350. //
  351. // if ((fContextReq & ISC_REQ_PROMPT_FOR_CREDS) != 0)
  352. // {
  353. // scRet = SEC_E_UNSUPPORTED_FUNCTION;
  354. // goto Cleanup;
  355. // }
  356. //
  357. // Verify the validity of the challenge message.
  358. //
  359. if (strncmp(
  360. ChallengeMessage->Signature,
  361. NTLMSSP_SIGNATURE,
  362. sizeof(NTLMSSP_SIGNATURE)))
  363. {
  364. scRet = SEC_E_INVALID_TOKEN;
  365. goto Cleanup;
  366. }
  367. if (ChallengeMessage->MessageType != NtLmChallenge)
  368. {
  369. scRet = SEC_E_INVALID_TOKEN;
  370. goto Cleanup;
  371. }
  372. if ((ChallengeMessage->NegotiateFlags & NTLMSSP_REQUIRED_NEGOTIATE_FLAGS) !=
  373. NTLMSSP_REQUIRED_NEGOTIATE_FLAGS)
  374. {
  375. scRet = SEC_E_UNSUPPORTED_FUNCTION;
  376. goto Cleanup;
  377. }
  378. if ((ChallengeMessage->NegotiateFlags & NTLMSSP_REQUEST_NON_NT_SESSION_KEY) != 0)
  379. {
  380. ParameterControl |= RETURN_NON_NT_USER_SESSION_KEY;
  381. }
  382. if ((fContextReq & ISC_REQ_USE_SUPPLIED_CREDS) != 0)
  383. {
  384. if ( NtlmChallengeMessage->Password.Buffer != 0)
  385. {
  386. ParameterControl &= ~USE_PRIMARY_PASSWORD;
  387. PasswordToUse.Length = NtlmChallengeMessage->Password.Length;
  388. PasswordToUse.MaximumLength = NtlmChallengeMessage->Password.MaximumLength;
  389. PasswordToUse.Buffer = (LPWSTR) (NtlmChallengeMessage->Password.Buffer +
  390. (PCHAR) NtlmChallengeMessage);
  391. }
  392. if (NtlmChallengeMessage->UserName.Length != 0)
  393. {
  394. UserNameToUse.Length = NtlmChallengeMessage->UserName.Length;
  395. UserNameToUse.MaximumLength = NtlmChallengeMessage->UserName.MaximumLength;
  396. UserNameToUse.Buffer = (LPWSTR) (NtlmChallengeMessage->UserName.Buffer +
  397. (PCHAR) NtlmChallengeMessage);
  398. ParameterControl &= ~RETURN_PRIMARY_USERNAME;
  399. }
  400. if (NtlmChallengeMessage->DomainName.Length != 0)
  401. {
  402. DomainNameToUse.Length = NtlmChallengeMessage->DomainName.Length;
  403. DomainNameToUse.MaximumLength = NtlmChallengeMessage->DomainName.MaximumLength;
  404. DomainNameToUse.Buffer = (LPWSTR) (NtlmChallengeMessage->DomainName.Buffer +
  405. (PCHAR) NtlmChallengeMessage);
  406. ParameterControl &= ~RETURN_PRIMARY_LOGON_DOMAINNAME;
  407. }
  408. }
  409. //
  410. // Package up the parameter for a call to the LSA.
  411. //
  412. ChallengeRequestSize = sizeof(MSV1_0_GETCHALLENRESP_REQUEST) +
  413. PasswordToUse.Length + UserNameToUse.Length + DomainNameToUse.Length;
  414. ChallengeRequest = SecAllocate(ChallengeRequestSize);
  415. if (ChallengeRequest == NULL) {
  416. scRet = SEC_E_INSUFFICIENT_MEMORY;
  417. goto Cleanup;
  418. }
  419. //
  420. // Build the challenge request message.
  421. //
  422. ChallengeRequest->MessageType = MsV1_0Lm20GetChallengeResponse;
  423. ChallengeRequest->ParameterControl = ParameterControl;
  424. if (RtlEqualMemory(phCredential, &NullCredential, sizeof(NullCredential))) {
  425. ChallengeRequest->LogonId = *((PLUID)&NullCredential);
  426. } else {
  427. ChallengeRequest->LogonId = (*((PMS_LOGON_CREDENTIAL *)phCredential))->LogonId;
  428. }
  429. RtlCopyMemory(
  430. ChallengeRequest->ChallengeToClient,
  431. ChallengeMessage->Challenge,
  432. MSV1_0_CHALLENGE_LENGTH
  433. );
  434. if ((ParameterControl & USE_PRIMARY_PASSWORD) == 0)
  435. {
  436. //
  437. // We assume the user specified SECPKG_CRED_OWF_PASSWORD when
  438. // AcquireSecurityContext was called, so the password is the
  439. // LM and NT OWF passwords concatenated together.
  440. //
  441. ChallengeRequest->Password.Buffer = (LPWSTR) (ChallengeRequest + 1);
  442. RtlCopyMemory(
  443. ChallengeRequest->Password.Buffer,
  444. PasswordToUse.Buffer,
  445. PasswordToUse.Length
  446. );
  447. ChallengeRequest->Password.Length = PasswordToUse.Length;
  448. ChallengeRequest->Password.MaximumLength = PasswordToUse.Length;
  449. //
  450. // need user name in NTLMv2
  451. //
  452. ChallengeRequest->UserName.Buffer = (PWSTR) (((UCHAR*) ChallengeRequest->Password.Buffer)
  453. + ChallengeRequest->Password.MaximumLength);
  454. RtlCopyMemory(
  455. ChallengeRequest->UserName.Buffer,
  456. UserNameToUse.Buffer,
  457. UserNameToUse.Length
  458. );
  459. ChallengeRequest->UserName.Length = UserNameToUse.Length;
  460. ChallengeRequest->UserName.MaximumLength = UserNameToUse.Length;
  461. //
  462. // need logon domain in NTLMv2
  463. //
  464. ChallengeRequest->LogonDomainName.Buffer = (PWSTR) (((UCHAR*) ChallengeRequest->UserName.Buffer)
  465. + ChallengeRequest->UserName.MaximumLength);
  466. RtlCopyMemory(
  467. ChallengeRequest->LogonDomainName.Buffer,
  468. DomainNameToUse.Buffer,
  469. DomainNameToUse.Length
  470. );
  471. ChallengeRequest->LogonDomainName.Length = DomainNameToUse.Length;
  472. ChallengeRequest->LogonDomainName.MaximumLength = DomainNameToUse.Length;
  473. }
  474. FinalStatus = MspLm20GetChallengeResponse(
  475. ChallengeRequest,
  476. ChallengeRequestSize,
  477. &ChallengeResponse,
  478. &ChallengeResponseSize,
  479. (BOOLEAN)((RtlEqualMemory(phCredential, &NullCredential, sizeof(NullCredential))) ?
  480. TRUE :
  481. ((*((PMS_LOGON_CREDENTIAL *)phCredential))->CredentialUse & SECPKG_CRED_OWF_PASSWORD) != 0x0)
  482. );
  483. if (!NT_SUCCESS(FinalStatus))
  484. {
  485. scRet = FinalStatus;
  486. goto Cleanup;
  487. }
  488. ASSERT(ChallengeResponse->MessageType == MsV1_0Lm20GetChallengeResponse);
  489. //
  490. // Now prepare the output message.
  491. //
  492. if (UserNameToUse.Buffer == NULL)
  493. {
  494. UserNameToUse = ChallengeResponse->UserName;
  495. }
  496. if (DomainNameToUse.Buffer == NULL)
  497. {
  498. DomainNameToUse = ChallengeResponse->LogonDomainName;
  499. }
  500. AuthenticateMessageSize = sizeof(AUTHENTICATE_MESSAGE) +
  501. UserNameToUse.Length +
  502. DomainNameToUse.Length +
  503. ChallengeResponse->CaseSensitiveChallengeResponse.Length +
  504. ChallengeResponse->CaseInsensitiveChallengeResponse.Length;
  505. AuthenticateMessage = (PAUTHENTICATE_MESSAGE) SecAllocate(AuthenticateMessageSize);
  506. if (AuthenticateMessage == NULL)
  507. {
  508. scRet = SEC_E_INSUFFICIENT_MEMORY;
  509. goto Cleanup;
  510. }
  511. Where = (PUCHAR) (AuthenticateMessage + 1);
  512. RtlCopyMemory(
  513. AuthenticateMessage->Signature,
  514. NTLMSSP_SIGNATURE,
  515. sizeof(NTLMSSP_SIGNATURE)
  516. );
  517. AuthenticateMessage->MessageType = NtLmAuthenticate;
  518. PutString(
  519. &AuthenticateMessage->LmChallengeResponse,
  520. &ChallengeResponse->CaseInsensitiveChallengeResponse,
  521. AuthenticateMessage,
  522. &Where
  523. );
  524. PutString(
  525. &AuthenticateMessage->NtChallengeResponse,
  526. &ChallengeResponse->CaseSensitiveChallengeResponse,
  527. AuthenticateMessage,
  528. &Where
  529. );
  530. PutString(
  531. &AuthenticateMessage->DomainName,
  532. (PSTRING) &DomainNameToUse,
  533. AuthenticateMessage,
  534. &Where
  535. );
  536. PutString(
  537. &AuthenticateMessage->UserName,
  538. (PSTRING) &UserNameToUse,
  539. AuthenticateMessage,
  540. &Where
  541. );
  542. //
  543. // KB. no workstation name to fill in. This is
  544. // OK because the workstation name is only used
  545. // in loopback detection, and this is not relevant
  546. // to this implementation of NTLM.
  547. //
  548. AuthenticateMessage->Workstation.Length = 0;
  549. AuthenticateMessage->Workstation.MaximumLength = 0;
  550. AuthenticateMessage->Workstation.Buffer = 0;
  551. //
  552. // Build the initialize response.
  553. //
  554. NtlmInitializeResponse = (PNTLM_INITIALIZE_RESPONSE) SecAllocate(sizeof(NTLM_INITIALIZE_RESPONSE));
  555. if (NtlmInitializeResponse == NULL)
  556. {
  557. scRet = SEC_E_INSUFFICIENT_MEMORY;
  558. goto Cleanup;
  559. }
  560. RtlCopyMemory(
  561. NtlmInitializeResponse->UserSessionKey,
  562. ChallengeResponse->UserSessionKey,
  563. MSV1_0_USER_SESSION_KEY_LENGTH
  564. );
  565. RtlCopyMemory(
  566. NtlmInitializeResponse->LanmanSessionKey,
  567. ChallengeResponse->LanmanSessionKey,
  568. MSV1_0_LANMAN_SESSION_KEY_LENGTH
  569. );
  570. //
  571. // Fill in the output buffers now.
  572. //
  573. AuthenticationToken->pvBuffer = AuthenticateMessage;
  574. AuthenticationToken->cbBuffer = AuthenticateMessageSize;
  575. InitializeResponseToken->pvBuffer = NtlmInitializeResponse;
  576. InitializeResponseToken->cbBuffer = sizeof(NTLM_INITIALIZE_RESPONSE);
  577. //
  578. // Make a local context for this
  579. //
  580. scRet = NtlmInitKernelContext(
  581. NtlmInitializeResponse->UserSessionKey,
  582. NtlmInitializeResponse->LanmanSessionKey,
  583. NULL, // no token,
  584. phNewContext
  585. );
  586. if (!NT_SUCCESS(scRet))
  587. {
  588. goto Cleanup;
  589. }
  590. scRet = SEC_E_OK;
  591. Cleanup:
  592. if (ChallengeRequest != NULL)
  593. {
  594. SecFree(ChallengeRequest);
  595. }
  596. if (ChallengeResponse != NULL)
  597. {
  598. ExFreePool( ChallengeResponse );
  599. }
  600. if (!NT_SUCCESS(scRet))
  601. {
  602. if (AuthenticateMessage != NULL)
  603. {
  604. SecFree(AuthenticateMessage);
  605. }
  606. if (NtlmInitializeResponse != NULL)
  607. {
  608. SecFree(NtlmInitializeResponse);
  609. }
  610. }
  611. return(scRet);
  612. }
  613. //+-------------------------------------------------------------------------
  614. //
  615. // Function: DeleteSecurityContextK
  616. //
  617. // Synopsis:
  618. //
  619. // Effects:
  620. //
  621. // Arguments:
  622. //
  623. // Requires:
  624. //
  625. // Returns:
  626. //
  627. // Notes:
  628. //
  629. //
  630. //--------------------------------------------------------------------------
  631. SECURITY_STATUS SEC_ENTRY
  632. DeleteSecurityContextK(
  633. PCtxtHandle phContext // Context to delete
  634. )
  635. {
  636. SECURITY_STATUS scRet;
  637. // For now, just delete the LSA context:
  638. if (!phContext)
  639. {
  640. return(SEC_E_INVALID_HANDLE);
  641. }
  642. scRet = NtlmDeleteKernelContext(phContext);
  643. return(scRet);
  644. }
  645. #if 0
  646. //+-------------------------------------------------------------------------
  647. //
  648. // Function: EnumerateSecurityPackagesK
  649. //
  650. // Synopsis:
  651. //
  652. // Effects:
  653. //
  654. // Arguments:
  655. //
  656. // Requires:
  657. //
  658. // Returns:
  659. //
  660. // Notes:
  661. //
  662. //
  663. //--------------------------------------------------------------------------
  664. SECURITY_STATUS SEC_ENTRY
  665. EnumerateSecurityPackagesK(
  666. unsigned long SEC_FAR * pcPackages, // Receives num. packages
  667. PSecPkgInfo SEC_FAR * ppPackageInfo // Receives array of info
  668. )
  669. {
  670. ULONG PackageInfoSize;
  671. PSecPkgInfoW PackageInfo = NULL;
  672. PUCHAR Where;
  673. //
  674. // Figure out the size of the returned data
  675. //
  676. PackageInfoSize = sizeof(SecPkgInfoW) +
  677. sizeof(NTLMSP_NAME) +
  678. sizeof(NTLMSP_COMMENT);
  679. PackageInfo = (PSecPkgInfoW) SecAllocate(PackageInfoSize);
  680. if (PackageInfo == NULL)
  681. {
  682. return(SEC_E_INSUFFICIENT_MEMORY);
  683. }
  684. //
  685. // Fill in the fixed length fields
  686. //
  687. PackageInfo->fCapabilities = SECPKG_FLAG_CONNECTION |
  688. SECPKG_FLAG_TOKEN_ONLY;
  689. PackageInfo->wVersion = NTLMSP_VERSION;
  690. PackageInfo->wRPCID = NTLMSP_RPCID;
  691. PackageInfo->cbMaxToken = NTLMSSP_MAX_MESSAGE_SIZE;
  692. //
  693. // Fill in the fields
  694. //
  695. Where = (PUCHAR) (PackageInfo+1);
  696. PackageInfo->Name = (LPWSTR) Where;
  697. RtlCopyMemory(
  698. PackageInfo->Name,
  699. NTLMSP_NAME,
  700. sizeof(NTLMSP_NAME)
  701. );
  702. Where += sizeof(NTLMSP_NAME);
  703. PackageInfo->Comment = (LPWSTR) Where;
  704. RtlCopyMemory(
  705. PackageInfo->Comment,
  706. NTLMSP_COMMENT,
  707. sizeof(NTLMSP_COMMENT)
  708. );
  709. Where += sizeof(NTLMSP_COMMENT);
  710. *pcPackages = 1;
  711. *ppPackageInfo = PackageInfo;
  712. return(SEC_E_OK);
  713. }
  714. //+-------------------------------------------------------------------------
  715. //
  716. // Function: QuerySecurityPackageInfoK
  717. //
  718. // Synopsis:
  719. //
  720. // Effects:
  721. //
  722. // Arguments:
  723. //
  724. // Requires:
  725. //
  726. // Returns:
  727. //
  728. // Notes:
  729. //
  730. //
  731. //--------------------------------------------------------------------------
  732. SECURITY_STATUS SEC_ENTRY
  733. QuerySecurityPackageInfoK(
  734. PSECURITY_STRING pssPackageName, // Name of package
  735. PSecPkgInfo * ppPackageInfo // Receives package info
  736. )
  737. {
  738. UNICODE_STRING PackageName;
  739. ULONG PackageCount;
  740. RtlInitUnicodeString(
  741. &PackageName,
  742. NTLMSP_NAME
  743. );
  744. if (!RtlEqualUnicodeString(
  745. pssPackageName,
  746. &PackageName,
  747. TRUE // case insensitive
  748. ))
  749. {
  750. return(SEC_E_SECPKG_NOT_FOUND);
  751. }
  752. return(EnumerateSecurityPackagesK(&PackageCount,ppPackageInfo));
  753. }
  754. #endif
  755. //+-------------------------------------------------------------------------
  756. //
  757. // Function: FreeContextBufferK
  758. //
  759. // Synopsis:
  760. //
  761. // Effects:
  762. //
  763. // Arguments:
  764. //
  765. // Requires:
  766. //
  767. // Returns:
  768. //
  769. // Notes:
  770. //
  771. //
  772. //--------------------------------------------------------------------------
  773. SECURITY_STATUS SEC_ENTRY
  774. FreeContextBufferK(
  775. void SEC_FAR * pvContextBuffer
  776. )
  777. {
  778. SecFree(pvContextBuffer);
  779. return(SEC_E_OK);
  780. }