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.

1296 lines
37 KiB

  1. /*++
  2. Copyright (c) 2001 Microsoft Corporation
  3. Module Name:
  4. sspi.cxx
  5. Abstract:
  6. sspi
  7. Author:
  8. Larry Zhu (LZhu) January 1, 2002 Created
  9. Environment:
  10. User Mode
  11. Revision History:
  12. --*/
  13. // #include "precomp.hxx"
  14. // #pragma hdrstop
  15. extern "C" {
  16. #define SECURITY_KERNEL
  17. #include <ntosp.h>
  18. #include <zwapi.h>
  19. #include <security.h>
  20. #include <ntlmsp.h>
  21. #include <string.h>
  22. #include <wcstr.h>
  23. #include <ntiologc.h>
  24. }
  25. #include "ntstatus.hxx"
  26. #include "sspi.hxx"
  27. #include "sspioutput.hxx"
  28. // #include <kbfiltr.h>
  29. #include <winerror.h>
  30. #include <tchar.h>
  31. #ifdef ALLOC_PRAGMA
  32. #pragma alloc_text (PAGE, GetCredHandle)
  33. #pragma alloc_text (PAGE, CheckUserData)
  34. #pragma alloc_text (PAGE, CheckUserToken)
  35. #pragma alloc_text (PAGE, LogonType2Str)
  36. #pragma alloc_text (PAGE, ImpLevel2Str)
  37. #pragma alloc_text (PAGE, GetSecurityContextHandles)
  38. #pragma alloc_text (PAGE, SspiMain)
  39. #pragma alloc_text (PAGE, IsContinueNeeded)
  40. #pragma alloc_text (PAGE, DoMessages)
  41. #endif
  42. typedef struct _SECURITY_LOGON_SESSION_DATA_OLD {
  43. ULONG Size;
  44. LUID LogonId;
  45. LSA_UNICODE_STRING UserName;
  46. LSA_UNICODE_STRING LogonDomain;
  47. LSA_UNICODE_STRING AuthenticationPackage;
  48. ULONG LogonType;
  49. ULONG Session;
  50. PSID Sid;
  51. LARGE_INTEGER LogonTime;
  52. } SECURITY_LOGON_SESSION_DATA_OLD, * PSECURITY_LOGON_SESSION_DATA_OLD;
  53. EXTERN_C
  54. SECURITY_STATUS
  55. SealMessage(IN PCtxtHandle phContext,
  56. IN ULONG fQOP,
  57. IN OUT PSecBufferDesc pMessage,
  58. IN ULONG MessageSeqNo);
  59. EXTERN_C
  60. SECURITY_STATUS
  61. UnsealMessage(IN PCtxtHandle phContext,
  62. IN OUT PSecBufferDesc pMessage,
  63. IN ULONG MessageSeqNo,
  64. OUT ULONG* pfQOP);
  65. EXTERN_C
  66. SECURITY_STATUS
  67. MakeSignature(IN PCtxtHandle phContext,
  68. IN ULONG fQOP,
  69. IN OUT PSecBufferDesc pMessage,
  70. IN ULONG MessageSeqNo);
  71. EXTERN_C
  72. SECURITY_STATUS
  73. VerifySignature(IN PCtxtHandle phContext,
  74. IN PSecBufferDesc pMessage,
  75. IN OUT ULONG MessageSeqNo,
  76. OUT ULONG* pfQOP);
  77. NTSTATUS
  78. DoMessages(
  79. IN PCtxtHandle phServerCtxt,
  80. IN PCtxtHandle phClientCtxt
  81. )
  82. {
  83. TNtStatus Status = STATUS_SUCCESS;
  84. SecBufferDesc MessageDesc = {0};
  85. SecBuffer SecBuffers[2] = {0};
  86. CHAR DataBuffer[20] = {0};
  87. CHAR SigBuffer[100] = {0};
  88. TCHAR szOutput[256] = {0};
  89. SecPkgContext_Sizes ContextSizes = {0};
  90. ULONG fQOP = 0;
  91. _sntprintf(szOutput, COUNTOF(szOutput) - 1, TEXT("DoMessages phServerCtxt %#x:%#x, phClientCtxt %#x:%#x\n"),
  92. phServerCtxt->dwUpper, phServerCtxt->dwLower, phClientCtxt->dwUpper, phClientCtxt->dwLower);
  93. SspiPrint(SSPI_LOG, szOutput);
  94. Status DBGCHK = QueryContextAttributes(
  95. phServerCtxt, // phClientCtxt
  96. SECPKG_ATTR_SIZES,
  97. &ContextSizes
  98. );
  99. if (NT_SUCCESS(Status))
  100. {
  101. Status DBGCHK = ( (sizeof(SigBuffer) >= ContextSizes.cbSecurityTrailer)
  102. && (sizeof(SigBuffer) >= ContextSizes.cbMaxSignature) )
  103. ? STATUS_SUCCESS : STATUS_BUFFER_OVERFLOW;
  104. }
  105. if (NT_SUCCESS(Status))
  106. {
  107. SecBuffers[0].pvBuffer = SigBuffer;
  108. SecBuffers[0].cbBuffer = sizeof(SigBuffer); // ContextSizes.cbSecurityTrailer;
  109. SecBuffers[0].BufferType = SECBUFFER_TOKEN;
  110. SecBuffers[1].cbBuffer = sizeof(DataBuffer);
  111. SecBuffers[1].BufferType = SECBUFFER_DATA;
  112. SecBuffers[1].pvBuffer = DataBuffer;
  113. MessageDesc.pBuffers = SecBuffers;
  114. MessageDesc.cBuffers = 2;
  115. MessageDesc.ulVersion = 0;
  116. memset(
  117. DataBuffer,
  118. 0xeb,
  119. sizeof(DataBuffer)
  120. );
  121. Status DBGCHK = SealMessage(
  122. phClientCtxt,
  123. fQOP,
  124. &MessageDesc,
  125. 0 // MessageSeqNo
  126. );
  127. }
  128. if (NT_SUCCESS(Status))
  129. {
  130. Status DBGCHK = UnsealMessage(
  131. phServerCtxt,
  132. &MessageDesc,
  133. 0, // MessageSeqNo
  134. &fQOP
  135. );
  136. }
  137. if (NT_SUCCESS(Status))
  138. {
  139. SecBuffers[1].pvBuffer = SigBuffer;
  140. SecBuffers[1].cbBuffer = sizeof(SigBuffer); // ContextSizes.cbMaxSignature;
  141. SecBuffers[1].BufferType = SECBUFFER_TOKEN;
  142. SecBuffers[0].pvBuffer = DataBuffer;
  143. SecBuffers[0].cbBuffer = sizeof(DataBuffer);
  144. SecBuffers[0].BufferType = SECBUFFER_DATA;
  145. memset(
  146. DataBuffer,
  147. 0xeb,
  148. sizeof(DataBuffer)
  149. );
  150. MessageDesc.pBuffers = SecBuffers;
  151. MessageDesc.cBuffers = 2;
  152. MessageDesc.ulVersion = 0;
  153. Status DBGCHK = MakeSignature(
  154. phServerCtxt,
  155. fQOP,
  156. &MessageDesc,
  157. 1 // MessageSeqNo
  158. );
  159. }
  160. if (NT_SUCCESS(Status))
  161. {
  162. Status DBGCHK = VerifySignature(
  163. phClientCtxt,
  164. &MessageDesc,
  165. 1, // MessageSeqNo
  166. &fQOP
  167. );
  168. }
  169. return Status;
  170. }
  171. NTSTATUS
  172. GetCredHandle(
  173. IN OPTIONAL UNICODE_STRING* pPrincipal,
  174. IN OPTIONAL LUID* pLogonID,
  175. IN UNICODE_STRING* pPackage,
  176. IN OPTIONAL VOID* pAuthData,
  177. IN ULONG fCredentialUse,
  178. OUT CredHandle* phCred
  179. )
  180. {
  181. PAGED_CODE();
  182. TNtStatus Status = STATUS_UNSUCCESSFUL;
  183. CredHandle hCred;
  184. LARGE_INTEGER Lifetime = {0};
  185. TCHAR szOutput[256] = {0};
  186. _sntprintf(szOutput, COUNTOF(szOutput) - 1, TEXT("GetCredHandle pszPrincipal %wZ, Package %wZ, fCredentialUse %#x, pLogonID %p, pAuthData %p\n"),
  187. pPrincipal, pPackage, fCredentialUse,
  188. pLogonID, pAuthData);
  189. SspiPrint(SSPI_LOG, szOutput);
  190. SecInvalidateHandle(&hCred);
  191. SecInvalidateHandle(phCred);
  192. if (pLogonID)
  193. {
  194. _sntprintf(szOutput, COUNTOF(szOutput) - 1, TEXT("LogonId %#x:%#x\n"), pLogonID->HighPart, pLogonID->LowPart);
  195. SspiPrint(SSPI_LOG, szOutput);
  196. }
  197. if (pAuthData)
  198. {
  199. SEC_WINNT_AUTH_IDENTITY* pNtAuth = (SEC_WINNT_AUTH_IDENTITY*) pAuthData;
  200. _sntprintf(szOutput, COUNTOF(szOutput) - 1, TEXT("AuthData User %s, UserLength %#x, Domain %s, DomainLength %#x, Password %s, PasswordLength %#x, Flags %#x\n"),
  201. pNtAuth->User, pNtAuth->UserLength,
  202. pNtAuth->Domain, pNtAuth->DomainLength,
  203. pNtAuth->Password, pNtAuth->PasswordLength,
  204. pNtAuth->Flags);
  205. SspiPrint(SSPI_LOG, szOutput);
  206. }
  207. SspiPrint(SSPI_LOG, TEXT("GetCredHandle calling AcquireCredentialsHandle\n"));
  208. Status DBGCHK = AcquireCredentialsHandle(
  209. pPrincipal, // NULL
  210. pPackage,
  211. fCredentialUse, // SECPKG_CRED_INBOUND,
  212. pLogonID, // NULL
  213. pAuthData, // ServerAuthIdentity,
  214. NULL, // GetKey
  215. NULL, // value to pass to GetKey
  216. &hCred,
  217. &Lifetime
  218. );
  219. if (NT_SUCCESS(Status))
  220. {
  221. _sntprintf(szOutput, COUNTOF(szOutput) - 1, TEXT("CredHandle %#x:%#x, Lifetime %#I64x\n"),
  222. hCred.dwUpper, hCred.dwLower, Lifetime.QuadPart);
  223. SspiPrint(SSPI_LOG, szOutput);
  224. *phCred = hCred;
  225. SecInvalidateHandle(&hCred);
  226. }
  227. if (SecIsValidHandle(&hCred))
  228. {
  229. FreeCredentialsHandle(&hCred);
  230. }
  231. return Status;
  232. }
  233. void __cdecl operator delete(void * pvMem)
  234. {
  235. if (pvMem)
  236. {
  237. ExFreePool(pvMem);
  238. }
  239. }
  240. #if 0
  241. void* __cdecl operator new(size_t cbSize)
  242. {
  243. return ExAllocatePool(PagedPool, cbSize);
  244. }
  245. #endif
  246. void
  247. SspiMain(
  248. void
  249. )
  250. {
  251. PAGED_CODE();
  252. TNtStatus Status = STATUS_SUCCESS;
  253. HANDLE hNullToken = NULL;
  254. LUID ClientCredLogonID = {0x3e4, 0x0};
  255. LUID ServerCredLogonID = {0x3e4, 0x0};
  256. HANDLE hToken = NULL;
  257. HANDLE hKey = NULL;
  258. CredHandle hClientCred;
  259. CredHandle hServerCred;
  260. CtxtHandle hClientCtxt;
  261. CtxtHandle hServerCtxt;
  262. ULONG ClientTargetDataRep = SECURITY_NATIVE_DREP;
  263. ULONG ServerTargetDataRep = SECURITY_NATIVE_DREP;
  264. ULONG ClientFlags = ISC_REQ_MUTUAL_AUTH | ISC_REQ_REPLAY_DETECT | ISC_REQ_CONFIDENTIALITY;
  265. ULONG ServerFlags = ASC_REQ_EXTENDED_ERROR;
  266. UNICODE_STRING ClientPackageName = {0}; // TEXT("NTLM");
  267. UNICODE_STRING ServerPackageName = {0}; // TEXT("NTLM");
  268. UNICODE_STRING RegistryPath = {0};
  269. UNICODE_STRING ClientCredLogonIdHighPartValue = {0};
  270. UNICODE_STRING ClientCredLogonIdLowPartValue = {0};
  271. OBJECT_ATTRIBUTES Attributes = {0};
  272. UCHAR ValueBuffer[sizeof(KEY_VALUE_FULL_INFORMATION) + 256] = {0};
  273. KEY_VALUE_FULL_INFORMATION* pKeyValue = (KEY_VALUE_FULL_INFORMATION*) ValueBuffer;
  274. SecPkgCredentials_Names CredNames = {0};
  275. ULONG cbRead = 0;
  276. TCHAR szOutput[256] = {0};
  277. SecInvalidateHandle(&hClientCred);
  278. SecInvalidateHandle(&hServerCred);
  279. SecInvalidateHandle(&hClientCtxt);
  280. SecInvalidateHandle(&hServerCtxt);
  281. RtlInitUnicodeString(&ClientPackageName, TEXT("NTLM"));
  282. RtlInitUnicodeString(&ServerPackageName, TEXT("NTLM"));
  283. RtlInitUnicodeString(&RegistryPath, TEXT("\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Lsa\\MSV1_0"));
  284. RtlInitUnicodeString(&ClientCredLogonIdHighPartValue, TEXT("ClientCredLogonIdHighPart"));
  285. RtlInitUnicodeString(&ClientCredLogonIdLowPartValue, TEXT("ClientCredLogonIdLowPart"));
  286. //
  287. // Open our service key and retrieve the hack table
  288. //
  289. InitializeObjectAttributes(
  290. &Attributes,
  291. &RegistryPath,
  292. OBJ_CASE_INSENSITIVE,
  293. NULL, // no SD
  294. NULL // no Security QoS
  295. );
  296. _sntprintf(szOutput, COUNTOF(szOutput) - 1, TEXT("SspiMain opening key %wZ\n"), &RegistryPath);
  297. SspiPrint(SSPI_ERROR, szOutput);
  298. Status DBGCHK = ZwOpenKey(
  299. &hKey,
  300. KEY_READ,
  301. &Attributes
  302. );
  303. DBGCFG1(Status, STATUS_OBJECT_NAME_NOT_FOUND);
  304. if (NT_SUCCESS(Status))
  305. {
  306. _sntprintf(szOutput, COUNTOF(szOutput) - 1, TEXT("SspiMain querying value key %wZ\n"), &ClientCredLogonIdHighPartValue);
  307. SspiPrint(SSPI_ERROR, szOutput);
  308. Status DBGCHK = ZwQueryValueKey(
  309. hKey,
  310. &ClientCredLogonIdHighPartValue,
  311. KeyValueFullInformation,
  312. pKeyValue,
  313. sizeof(ValueBuffer),
  314. &cbRead
  315. );
  316. }
  317. if (NT_SUCCESS(Status))
  318. {
  319. Status DBGCHK = (pKeyValue->Type == REG_DWORD) ? STATUS_SUCCESS : STATUS_INTERNAL_ERROR;
  320. if (NT_SUCCESS(Status))
  321. {
  322. ClientCredLogonID.HighPart = *( (ULONG*) (((PCHAR)pKeyValue) + pKeyValue->DataOffset) );
  323. }
  324. }
  325. else if (STATUS_OBJECT_NAME_NOT_FOUND == (NTSTATUS) Status)
  326. {
  327. Status DBGCHK = STATUS_SUCCESS;
  328. }
  329. if (NT_SUCCESS(Status))
  330. {
  331. _sntprintf(szOutput, COUNTOF(szOutput) - 1, TEXT("SspiMain querying value key %wZ\n"), &ClientCredLogonIdLowPartValue);
  332. SspiPrint(SSPI_ERROR, szOutput);
  333. Status DBGCHK = ZwQueryValueKey(
  334. hKey,
  335. &ClientCredLogonIdLowPartValue,
  336. KeyValueFullInformation,
  337. pKeyValue,
  338. sizeof(ValueBuffer),
  339. &cbRead
  340. );
  341. }
  342. if (NT_SUCCESS(Status))
  343. {
  344. Status DBGCHK = (pKeyValue->Type == REG_DWORD) ? STATUS_SUCCESS : STATUS_INTERNAL_ERROR;
  345. if (NT_SUCCESS(Status))
  346. {
  347. ClientCredLogonID.LowPart = *( (ULONG*) (((PCHAR)pKeyValue) + pKeyValue->DataOffset) );
  348. }
  349. }
  350. else if (STATUS_OBJECT_NAME_NOT_FOUND == (NTSTATUS) Status)
  351. {
  352. Status DBGCHK = STATUS_SUCCESS;
  353. }
  354. if (NT_SUCCESS(Status))
  355. {
  356. Status DBGCHK = GetCredHandle(
  357. NULL, // pszClientCredPrincipal,
  358. &ClientCredLogonID,
  359. &ServerPackageName,
  360. NULL, // pClientAuthData,
  361. SECPKG_CRED_OUTBOUND,
  362. &hClientCred
  363. );
  364. }
  365. if (NT_SUCCESS(Status))
  366. {
  367. Status DBGCHK = GetCredHandle(
  368. NULL, // pszServerCredPrincipal,
  369. NULL, // &ServerCredLogonID,
  370. &ServerPackageName,
  371. NULL, // pServerAuthData,
  372. SECPKG_CRED_INBOUND,
  373. &hServerCred
  374. );
  375. }
  376. if (NT_SUCCESS(Status))
  377. {
  378. Status DBGCHK = GetSecurityContextHandles(
  379. NULL, // pTargetName,
  380. ClientFlags,
  381. ServerFlags,
  382. ClientTargetDataRep,
  383. ServerTargetDataRep,
  384. &hClientCred,
  385. &hServerCred,
  386. &hClientCtxt,
  387. &hServerCtxt
  388. );
  389. }
  390. if (NT_SUCCESS(Status))
  391. {
  392. SspiPrint(SSPI_LOG, TEXT("***************Checking server ctxt handle*************\n"));
  393. Status DBGCHK = CheckSecurityContextHandle(&hServerCtxt);
  394. }
  395. if (NT_SUCCESS(Status))
  396. {
  397. Status DBGCHK = ImpersonateSecurityContext(&hServerCtxt);
  398. }
  399. if (NT_SUCCESS(Status))
  400. {
  401. SspiPrint(SSPI_LOG, TEXT("**************Server checking user data via ImpersonateSecurityContext ******\n"));
  402. Status DBGCHK = CheckUserData();
  403. }
  404. if (NT_SUCCESS(Status))
  405. {
  406. Status DBGCHK = RevertSecurityContext(&hServerCtxt);
  407. }
  408. if (NT_SUCCESS(Status))
  409. {
  410. Status DBGCHK = QuerySecurityContextToken(&hServerCtxt, &hToken);
  411. }
  412. if (NT_SUCCESS(Status))
  413. {
  414. SspiPrint(SSPI_LOG, TEXT("**************Server checking user data via QuerySecurityContextToken ******\n"));
  415. Status DBGCHK = CheckUserToken(hToken);
  416. }
  417. if (NT_SUCCESS(Status))
  418. {
  419. Status DBGCHK = DoMessages(&hServerCtxt, &hClientCtxt);
  420. }
  421. if (NT_SUCCESS(Status))
  422. {
  423. _sntprintf(szOutput, COUNTOF(szOutput) - 1, TEXT("Credential names address %p\n"), &CredNames.sUserName);
  424. SspiPrint(SSPI_LOG, szOutput);
  425. Status DBGCHK = QueryCredentialsAttributes(
  426. &hServerCred,
  427. SECPKG_CRED_ATTR_NAMES,
  428. &CredNames
  429. );
  430. }
  431. if (NT_SUCCESS(Status))
  432. {
  433. _sntprintf(szOutput, COUNTOF(szOutput) - 1, TEXT("Credential names: %s\n"), CredNames.sUserName);
  434. SspiPrint(SSPI_LOG, szOutput);
  435. if (CredNames.sUserName)
  436. {
  437. FreeContextBuffer(CredNames.sUserName);
  438. CredNames.sUserName = NULL;
  439. }
  440. Status DBGCHK = QueryCredentialsAttributes(
  441. &hClientCred,
  442. SECPKG_CRED_ATTR_NAMES,
  443. &CredNames
  444. );
  445. }
  446. if (NT_SUCCESS(Status))
  447. {
  448. _sntprintf(szOutput, COUNTOF(szOutput) - 1, TEXT("Credential names: %s\n"), CredNames.sUserName);
  449. SspiPrint(SSPI_LOG, szOutput);
  450. }
  451. //
  452. // revert to self...
  453. //
  454. ZwSetInformationThread(
  455. NtCurrentThread(),
  456. ThreadImpersonationToken,
  457. &hNullToken,
  458. sizeof( HANDLE )
  459. );
  460. if (CredNames.sUserName)
  461. {
  462. FreeContextBuffer(CredNames.sUserName);
  463. }
  464. if (SecIsValidHandle(&hClientCtxt))
  465. {
  466. DeleteSecurityContext(&hClientCtxt);
  467. }
  468. if (SecIsValidHandle(&hServerCtxt))
  469. {
  470. DeleteSecurityContext(&hServerCtxt);
  471. }
  472. if (SecIsValidHandle(&hServerCred))
  473. {
  474. FreeCredentialsHandle(&hServerCred);
  475. }
  476. if (SecIsValidHandle(&hClientCred))
  477. {
  478. FreeCredentialsHandle(&hClientCred);
  479. }
  480. if (hToken)
  481. {
  482. ZwClose(hToken);
  483. }
  484. }
  485. NTSTATUS
  486. GetSecurityContextHandles(
  487. IN OPTIONAL UNICODE_STRING* pTargetName,
  488. IN ULONG ClientFlags,
  489. IN ULONG ServerFlags,
  490. IN ULONG ClientTargetDataRep,
  491. IN ULONG ServerTargetDataRep,
  492. IN PCredHandle phClientCred,
  493. IN PCredHandle phServerCred,
  494. OUT PCtxtHandle phClientCtxt,
  495. OUT PCtxtHandle phServerCtxt
  496. )
  497. {
  498. PAGED_CODE();
  499. TNtStatus Status = STATUS_SUCCESS;
  500. SECURITY_STATUS ProtocolStatus;
  501. TNtStatus SrvProtoclStatus;
  502. ULONG ContextAttributes = 0;
  503. TimeStamp SrvCtxtLifetime = {0};
  504. TimeStamp CliCtxtLifetime = {0};
  505. CtxtHandle hClientCtxt;
  506. CtxtHandle hServerCtxt;
  507. ULONG cbRead = 0;
  508. SecBufferDesc OutBuffDesc = {0};
  509. SecBuffer OutSecBuff = {0};
  510. SecBufferDesc InBuffDesc = {0};
  511. SecBuffer InSecBuff = {0};
  512. BOOLEAN bIsContinueNeeded = FALSE;
  513. BOOLEAN bIsSrvContinueNeeded = FALSE;
  514. // SecPkgCredentials_Names CredNames = {0};
  515. TCHAR szOutput[256] = {0};
  516. SecInvalidateHandle(phClientCtxt);
  517. SecInvalidateHandle(&hClientCtxt);
  518. SecInvalidateHandle(&hServerCtxt);
  519. SecInvalidateHandle(phServerCtxt);
  520. //
  521. // prepare output buffer
  522. //
  523. OutBuffDesc.ulVersion = 0;
  524. OutBuffDesc.cBuffers = 1;
  525. OutBuffDesc.pBuffers = &OutSecBuff;
  526. OutSecBuff.cbBuffer = 0;
  527. OutSecBuff.BufferType = SECBUFFER_TOKEN;
  528. OutSecBuff.pvBuffer = NULL;
  529. if (0 == (ServerFlags & ASC_REQ_ALLOCATE_MEMORY))
  530. {
  531. SspiPrint(SSPI_LOG, TEXT("GetSecurityContextHandles ASC_REQ_ALLOCATE_MEMORY is not requested, added\n"));
  532. ServerFlags |= ASC_REQ_ALLOCATE_MEMORY;
  533. }
  534. //
  535. // prepare input buffer
  536. //
  537. InBuffDesc.ulVersion = 0;
  538. InBuffDesc.cBuffers = 1;
  539. InBuffDesc.pBuffers = &InSecBuff;
  540. InSecBuff.cbBuffer = 0;
  541. InSecBuff.BufferType = SECBUFFER_TOKEN;
  542. InSecBuff.pvBuffer = NULL;
  543. if (0 == (ClientFlags & ISC_REQ_ALLOCATE_MEMORY))
  544. {
  545. SspiPrint(SSPI_LOG, TEXT("GetSecurityContextHandles ISC_REQ_ALLOCATE_MEMORY is not requested, added\n"));
  546. ClientFlags |= ISC_REQ_ALLOCATE_MEMORY;
  547. }
  548. _sntprintf(szOutput, COUNTOF(szOutput) - 1,
  549. TEXT("GetClientSecurityContextHandle pTargetName %wZ, ClientFlags %#x, ServerFlags %#x, ClientTargetDataRep %#x, ServerTargetDataRep %#x, phClientCred %#x:%#x, phServerCred %#x:%#x\n"),
  550. pTargetName, ClientFlags, ServerFlags, ClientTargetDataRep, ServerTargetDataRep, phClientCred->dwUpper, phClientCred->dwLower, phServerCred->dwUpper, phServerCred->dwLower);
  551. SspiPrint(SSPI_LOG, szOutput);
  552. Status DBGCHK = InitializeSecurityContext(
  553. phClientCred,
  554. NULL, // No Client context yet
  555. pTargetName, // Faked target name
  556. ClientFlags,
  557. 0, // Reserved 1
  558. ClientTargetDataRep,
  559. NULL, // No initial input token
  560. 0, // Reserved 2
  561. &hClientCtxt,
  562. &OutBuffDesc,
  563. &ContextAttributes,
  564. &CliCtxtLifetime
  565. );
  566. SspiPrintHex(SSPI_LOG, TEXT("GetClientSecurityContextHandle output from ISC"), OutSecBuff.cbBuffer, OutSecBuff.pvBuffer);
  567. if (NT_SUCCESS(Status))
  568. {
  569. Status DBGCHK = IsContinueNeeded(Status, &bIsContinueNeeded);
  570. }
  571. _sntprintf(szOutput, COUNTOF(szOutput) - 1,
  572. TEXT("GetClientSecurityContextHandle InitializeSecurityContext returned %#x, bIsContinueNeeded %#x\n"),
  573. (NTSTATUS) Status, bIsContinueNeeded);
  574. SspiPrint(SSPI_LOG, szOutput);
  575. if (NT_SUCCESS(Status))
  576. {
  577. _sntprintf(szOutput, COUNTOF(szOutput) - 1, TEXT("GetClientSecurityContextHandle calling AcceptSecurityContext ServerFlags %#x, TargetDataRep %#x, phServerCred %#x:%#x\n"),
  578. ServerFlags, ServerTargetDataRep, phServerCred->dwUpper, phServerCred->dwLower);
  579. SspiPrint(SSPI_LOG, szOutput);
  580. Status DBGCHK = AcceptSecurityContext(
  581. phServerCred,
  582. NULL, // No Server context yet
  583. &OutBuffDesc,
  584. ServerFlags,
  585. ServerTargetDataRep,
  586. &hServerCtxt,
  587. &InBuffDesc,
  588. &ContextAttributes,
  589. &SrvCtxtLifetime
  590. );
  591. }
  592. if (NT_SUCCESS(Status))
  593. {
  594. Status DBGCHK = IsContinueNeeded(Status, &bIsSrvContinueNeeded);
  595. }
  596. SspiPrintHex(SSPI_LOG, TEXT("GetClientSecurityContextHandle output from ASC"), InSecBuff.cbBuffer, InSecBuff.pvBuffer);
  597. _sntprintf(szOutput, COUNTOF(szOutput) - 1,
  598. TEXT("GetClientSecurityContextHandle AcceptSecurityContext returned %#x, bIsSrvContinueNeeded %#x\n"),
  599. (NTSTATUS) Status, bIsSrvContinueNeeded);
  600. SspiPrint(SSPI_LOG, szOutput);
  601. while (NT_SUCCESS(Status) && (bIsContinueNeeded || bIsSrvContinueNeeded))
  602. {
  603. if (bIsContinueNeeded)
  604. {
  605. _sntprintf(szOutput, COUNTOF(szOutput) - 1, TEXT("GetClientSecurityContextHandle calling InitializeSecurityContext pTargetName %wZ, ClientFlags %#x, TargetDataRep %#x, hClientCtxt %#x:%#x\n"),
  606. pTargetName, ClientFlags, ClientTargetDataRep, hClientCtxt.dwUpper, hClientCtxt.dwLower);
  607. SspiPrint(SSPI_LOG, szOutput);
  608. if (OutSecBuff.pvBuffer)
  609. {
  610. FreeContextBuffer(OutSecBuff.pvBuffer);
  611. }
  612. OutSecBuff.pvBuffer = NULL;
  613. OutSecBuff.cbBuffer = 0;
  614. Status DBGCHK = InitializeSecurityContext(
  615. NULL, // no cred handle
  616. &hClientCtxt,
  617. pTargetName,
  618. ClientFlags,
  619. 0,
  620. ClientTargetDataRep,
  621. &InBuffDesc,
  622. 0,
  623. &hClientCtxt,
  624. &OutBuffDesc,
  625. &ContextAttributes,
  626. &CliCtxtLifetime
  627. );
  628. if (NT_SUCCESS(Status))
  629. {
  630. Status DBGCHK = IsContinueNeeded(Status, &bIsContinueNeeded);
  631. }
  632. SspiPrintHex(SSPI_LOG, TEXT("GetClientSecurityContextHandle output from ISC"), OutSecBuff.cbBuffer, OutSecBuff.pvBuffer);
  633. _sntprintf(szOutput, COUNTOF(szOutput),
  634. TEXT("GetClientSecurityContextHandle InitializeSecurityContext returned %#x, bIsContinueNeeded %#x\n"),
  635. (NTSTATUS) Status, bIsContinueNeeded);
  636. SspiPrint(SSPI_LOG, szOutput);
  637. }
  638. if (NT_SUCCESS(Status) && bIsSrvContinueNeeded)
  639. {
  640. _sntprintf(szOutput, COUNTOF(szOutput) - 1, TEXT("GetClientSecurityContextHandle calling AcceptSecurityContext ServerFlags %#x, TargetDataRep %#x, hServerCtxt %#x:%#x\n"),
  641. ServerFlags, ServerTargetDataRep, hServerCtxt.dwUpper, hServerCtxt.dwLower);
  642. SspiPrint(SSPI_LOG, szOutput);
  643. if (InSecBuff.pvBuffer)
  644. {
  645. FreeContextBuffer(InSecBuff.pvBuffer);
  646. }
  647. InSecBuff.pvBuffer = NULL;
  648. InSecBuff.cbBuffer = 0;
  649. Status DBGCHK = AcceptSecurityContext(
  650. NULL, // no cred handle
  651. &hServerCtxt,
  652. &OutBuffDesc,
  653. ServerFlags,
  654. ServerTargetDataRep,
  655. &hServerCtxt,
  656. &InBuffDesc,
  657. &ContextAttributes,
  658. &SrvCtxtLifetime
  659. );
  660. if (NT_SUCCESS(Status))
  661. {
  662. Status DBGCHK = IsContinueNeeded(Status, &bIsSrvContinueNeeded);
  663. }
  664. SspiPrintHex(SSPI_LOG, TEXT("GetClientSecurityContextHandle output from ASC"), InSecBuff.cbBuffer, InSecBuff.pvBuffer);
  665. _sntprintf(szOutput, COUNTOF(szOutput) - 1,
  666. TEXT("GetClientSecurityContextHandle AcceptSecurityContext returned %#x, bIsSrvContinueNeeded %#x\n"),
  667. (NTSTATUS) Status, bIsSrvContinueNeeded);
  668. SspiPrint(SSPI_LOG, szOutput);
  669. }
  670. }
  671. if (NT_SUCCESS(Status))
  672. {
  673. TimeStamp CurrentTime = {0};
  674. _sntprintf(szOutput, COUNTOF(szOutput),
  675. TEXT("Authentication succeeded: hClientCtxt %#x:%#x, CliCtxtLifetime %#I64x, hServerCtxt %#x:%#x, SrvCtxtLifetime %#I64x\n"),
  676. hClientCtxt.dwUpper, hClientCtxt.dwLower, CliCtxtLifetime, hServerCtxt.dwUpper, hServerCtxt.dwLower, SrvCtxtLifetime
  677. );
  678. SspiPrint(SSPI_LOG, szOutput);
  679. *phClientCtxt = hClientCtxt;
  680. SecInvalidateHandle(&hClientCtxt)
  681. *phServerCtxt = hServerCtxt;
  682. SecInvalidateHandle(&hServerCtxt);
  683. }
  684. if (SecIsValidHandle(&hClientCtxt))
  685. {
  686. DeleteSecurityContext(&hClientCtxt);
  687. }
  688. if (SecIsValidHandle(&hServerCtxt))
  689. {
  690. DeleteSecurityContext(&hServerCtxt);
  691. }
  692. return Status;
  693. }
  694. NTSTATUS
  695. IsContinueNeeded(
  696. IN NTSTATUS ntstatus,
  697. OUT BOOLEAN* pbIsContinueNeeded
  698. )
  699. {
  700. PAGED_CODE();
  701. *pbIsContinueNeeded = FALSE;
  702. if ((SEC_I_CONTINUE_NEEDED == ntstatus) || (SEC_I_COMPLETE_AND_CONTINUE == ntstatus))
  703. {
  704. *pbIsContinueNeeded = TRUE;
  705. }
  706. return ntstatus;
  707. }
  708. NTSTATUS
  709. CheckSecurityContextHandle(
  710. IN PCtxtHandle phCtxt
  711. )
  712. {
  713. PAGED_CODE();
  714. TNtStatus Status = STATUS_SUCCESS;
  715. LARGE_INTEGER CurrentTime = {0};
  716. SecPkgContext_NativeNames NativeNames = {0};
  717. SecPkgContext_DceInfo ContextDceInfo = {0};
  718. SecPkgContext_Lifespan ContextLifespan = {0};
  719. SecPkgContext_PackageInfo ContextPackageInfo = {0};
  720. SecPkgContext_Sizes ContextSizes = {0};
  721. SecPkgContext_Flags ContextFlags = {0};
  722. SecPkgContext_KeyInfo KeyInfo = {0};
  723. SecPkgContext_Names ContextNames = {0};
  724. TCHAR szOutput[256] = {0};
  725. DBGCFG1(Status, STATUS_NOT_SUPPORTED);
  726. //
  727. // Query as many attributes as possible
  728. //
  729. Status DBGCHK = QueryContextAttributes(
  730. phCtxt,
  731. SECPKG_ATTR_SIZES,
  732. &ContextSizes
  733. );
  734. if (NT_SUCCESS(Status))
  735. {
  736. _sntprintf(szOutput, COUNTOF(szOutput) - 1, TEXT("SECPKG_ATTR_SIZES cbBlockSize %#x, cbMaxSignature %#x, cbMaxToken %#x, cbSecurityTrailer %#x\n"),
  737. ContextSizes.cbBlockSize,
  738. ContextSizes.cbMaxSignature,
  739. ContextSizes.cbMaxToken,
  740. ContextSizes.cbSecurityTrailer);
  741. SspiPrint(SSPI_LOG, szOutput);
  742. Status DBGCHK = QueryContextAttributes(
  743. phCtxt,
  744. SECPKG_ATTR_FLAGS,
  745. &ContextFlags
  746. );
  747. }
  748. if (NT_SUCCESS(Status))
  749. {
  750. _sntprintf(szOutput, COUNTOF(szOutput) - 1, TEXT("SECPKG_ATTR_FLAGS %#x\n"), ContextFlags.Flags);
  751. SspiPrint(SSPI_LOG, szOutput);
  752. }
  753. else if (STATUS_NOT_SUPPORTED == (NTSTATUS) Status)
  754. {
  755. Status DBGCHK = STATUS_SUCCESS;
  756. SspiPrint(SSPI_WARN, TEXT("QueryContextAttributes does not support SECPKG_ATTR_FLAGS\n"));
  757. }
  758. if (NT_SUCCESS(Status))
  759. {
  760. Status DBGCHK = QueryContextAttributes(
  761. phCtxt,
  762. SECPKG_ATTR_KEY_INFO,
  763. &KeyInfo
  764. );
  765. }
  766. if (NT_SUCCESS(Status))
  767. {
  768. _sntprintf(szOutput, COUNTOF(szOutput) - 1, TEXT("SECPKG_ATTR_KEY_INFO EncryptAlgorithm %#x, KeySize %#x, sEncryptAlgorithmName %s, SignatureAlgorithm %#x, sSignatureAlgorithmName %s\n"),
  769. KeyInfo.EncryptAlgorithm,
  770. KeyInfo.KeySize,
  771. KeyInfo.sEncryptAlgorithmName,
  772. KeyInfo.SignatureAlgorithm,
  773. KeyInfo.sSignatureAlgorithmName);
  774. SspiPrint(SSPI_LOG, szOutput);
  775. }
  776. else if (STATUS_NOT_SUPPORTED == (NTSTATUS) Status)
  777. {
  778. Status DBGCHK = STATUS_SUCCESS;
  779. SspiPrint(SSPI_WARN, TEXT("QueryContextAttributes does not support SECPKG_ATTR_KEY_INFO\n"));
  780. }
  781. if (NT_SUCCESS(Status))
  782. {
  783. Status DBGCHK = QueryContextAttributes(
  784. phCtxt,
  785. SECPKG_ATTR_NAMES,
  786. &ContextNames
  787. );
  788. }
  789. if (NT_SUCCESS(Status))
  790. {
  791. _sntprintf(szOutput, COUNTOF(szOutput) - 1, TEXT("QueryNames for sUserName %s\n"), ContextNames.sUserName);
  792. SspiPrint(SSPI_LOG, szOutput);
  793. }
  794. else if (STATUS_NOT_SUPPORTED == (NTSTATUS) Status)
  795. {
  796. Status DBGCHK = STATUS_SUCCESS;
  797. SspiPrint(SSPI_WARN, TEXT("QueryContextAttributes does not support SECPKG_ATTR_NAMES\n"));
  798. }
  799. if (NT_SUCCESS(Status))
  800. {
  801. Status DBGCHK = QueryContextAttributes(
  802. phCtxt,
  803. SECPKG_ATTR_NATIVE_NAMES,
  804. &NativeNames
  805. );
  806. }
  807. if (NT_SUCCESS(Status))
  808. {
  809. _sntprintf(szOutput, COUNTOF(szOutput) - 1, TEXT("QueryNativeNames sClientName %s, sServerName %s\n"),
  810. NativeNames.sClientName,
  811. NativeNames.sServerName);
  812. SspiPrint(SSPI_LOG, szOutput);
  813. }
  814. else if (STATUS_NOT_SUPPORTED == (NTSTATUS) Status)
  815. {
  816. Status DBGCHK = STATUS_SUCCESS;
  817. SspiPrint(SSPI_WARN, TEXT("QueryContextAttributes does not support SECPKG_ATTR_NATIVE_NAMES\n"));
  818. }
  819. if (NT_SUCCESS(Status))
  820. {
  821. Status DBGCHK = QueryContextAttributes(
  822. phCtxt,
  823. SECPKG_ATTR_DCE_INFO,
  824. &ContextDceInfo
  825. );
  826. }
  827. if (NT_SUCCESS(Status))
  828. {
  829. _sntprintf(szOutput, COUNTOF(szOutput) - 1, TEXT("QueryDceInfo: AuthzSvc %#x, pPac %ws\n"), ContextDceInfo.AuthzSvc, ContextDceInfo.pPac);
  830. SspiPrint(SSPI_LOG, szOutput);
  831. }
  832. else if (STATUS_NOT_SUPPORTED == (NTSTATUS) Status)
  833. {
  834. Status DBGCHK = STATUS_SUCCESS;
  835. SspiPrint(SSPI_WARN, TEXT("QueryContextAttributes does not support SECPKG_ATTR_DCE_INFO\n"));
  836. }
  837. if (NT_SUCCESS(Status))
  838. {
  839. Status DBGCHK = QueryContextAttributes(
  840. phCtxt,
  841. SECPKG_ATTR_LIFESPAN,
  842. &ContextLifespan
  843. );
  844. }
  845. if (NT_SUCCESS(Status))
  846. {
  847. _sntprintf(szOutput, COUNTOF(szOutput) - 1, TEXT("Start %#x:%#x, Expiry %#x:%#x\n"),
  848. ((LARGE_INTEGER*) &ContextLifespan.tsStart)->HighPart,
  849. ((LARGE_INTEGER*) &ContextLifespan.tsStart)->LowPart,
  850. ((LARGE_INTEGER*) &ContextLifespan.tsExpiry)->HighPart,
  851. ((LARGE_INTEGER*) &ContextLifespan.tsExpiry)->LowPart);
  852. SspiPrint(SSPI_LOG, szOutput);
  853. }
  854. else if (STATUS_NOT_SUPPORTED == (NTSTATUS) Status)
  855. {
  856. Status DBGCHK = STATUS_SUCCESS;
  857. SspiPrint(SSPI_WARN, TEXT("QueryContextAttributes does not support SECPKG_ATTR_LIFESPAN\n"));
  858. }
  859. if (NT_SUCCESS(Status))
  860. {
  861. Status DBGCHK = QueryContextAttributes(
  862. phCtxt,
  863. SECPKG_ATTR_PACKAGE_INFO,
  864. &ContextPackageInfo
  865. );
  866. }
  867. if (NT_SUCCESS(Status))
  868. {
  869. _sntprintf(szOutput, COUNTOF(szOutput) - 1, TEXT("ContextPackageInfo cbMaxToken %#x, Comment %s, fCapabilities %#x, Name %s, wRPCID %#x, wVersion %#x\n"),
  870. ContextPackageInfo.PackageInfo->cbMaxToken,
  871. ContextPackageInfo.PackageInfo->Comment,
  872. ContextPackageInfo.PackageInfo->fCapabilities,
  873. ContextPackageInfo.PackageInfo->Name,
  874. ContextPackageInfo.PackageInfo->wRPCID,
  875. ContextPackageInfo.PackageInfo->wVersion);
  876. SspiPrint(SSPI_LOG, szOutput);
  877. }
  878. else if (STATUS_NOT_SUPPORTED == (NTSTATUS) Status)
  879. {
  880. Status DBGCHK = STATUS_SUCCESS;
  881. SspiPrint(SSPI_WARN, TEXT("QueryContextAttributes does not support SECPKG_ATTR_PACKAGE_INFO\n"));
  882. }
  883. if (NativeNames.sClientName != NULL)
  884. {
  885. FreeContextBuffer(NativeNames.sClientName);
  886. }
  887. if (NativeNames.sServerName != NULL)
  888. {
  889. FreeContextBuffer(NativeNames.sServerName);
  890. }
  891. if (ContextNames.sUserName)
  892. {
  893. FreeContextBuffer(ContextNames.sUserName);
  894. }
  895. if (ContextPackageInfo.PackageInfo)
  896. {
  897. FreeContextBuffer(ContextPackageInfo.PackageInfo);
  898. }
  899. if (ContextDceInfo.pPac)
  900. {
  901. FreeContextBuffer(ContextDceInfo.pPac);
  902. }
  903. return Status;
  904. }
  905. NTSTATUS
  906. CheckUserData(
  907. VOID
  908. )
  909. {
  910. PAGED_CODE();
  911. TNtStatus Status = E_FAIL;
  912. HANDLE hThreadToken = NULL;
  913. TOKEN_STATISTICS TokenStat = {0};
  914. ULONG cbReturnLength = 0;
  915. PSECURITY_LOGON_SESSION_DATA pLogonSessionData = NULL;
  916. HANDLE hNullToken = NULL;
  917. TCHAR szOutput[256] = {0};
  918. Status DBGCHK = ZwOpenThreadToken(
  919. NtCurrentThread(), // handle to thread
  920. MAXIMUM_ALLOWED, // access to process
  921. TRUE, // process or thread security
  922. &hThreadToken // handle to open access token
  923. );
  924. //
  925. // Revert to self
  926. //
  927. if (NT_SUCCESS(Status))
  928. {
  929. Status DBGCHK = ZwSetInformationThread(
  930. NtCurrentThread(),
  931. ThreadImpersonationToken,
  932. &hNullToken,
  933. sizeof( HANDLE )
  934. );
  935. }
  936. if (NT_SUCCESS(Status))
  937. {
  938. Status DBGCHK = ZwQueryInformationToken(
  939. hThreadToken,
  940. TokenStatistics,
  941. &TokenStat,
  942. sizeof(TokenStat),
  943. &cbReturnLength
  944. );
  945. }
  946. if (NT_SUCCESS(Status))
  947. {
  948. _sntprintf(szOutput, COUNTOF(szOutput) - 1,
  949. TEXT("LogonId %#x:%#x, Impersonation Level %s, TokenType %s\n"),
  950. TokenStat.AuthenticationId.HighPart,
  951. TokenStat.AuthenticationId.LowPart,
  952. ImpLevel2Str(TokenStat.ImpersonationLevel),
  953. TokenStat.TokenType == TokenPrimary ? TEXT("Primary") : TEXT("Impersonation"));
  954. SspiPrint(SSPI_LOG, szOutput);
  955. Status DBGCHK = LsaGetLogonSessionData(&TokenStat.AuthenticationId, &pLogonSessionData);
  956. }
  957. if (NT_SUCCESS(Status))
  958. {
  959. PrintLogonSessionData(SSPI_LOG, pLogonSessionData);
  960. }
  961. //
  962. // restore thread token
  963. //
  964. if (hThreadToken)
  965. {
  966. Status DBGCHK = ZwSetInformationThread(
  967. NtCurrentThread(),
  968. ThreadImpersonationToken,
  969. &hThreadToken,
  970. sizeof( HANDLE )
  971. );
  972. ZwClose(hThreadToken);
  973. }
  974. if (pLogonSessionData)
  975. {
  976. LsaFreeReturnBuffer(pLogonSessionData);
  977. }
  978. return Status;
  979. }
  980. NTSTATUS
  981. CheckUserToken(
  982. IN HANDLE hToken
  983. )
  984. {
  985. PAGED_CODE();
  986. TNtStatus Status;
  987. TOKEN_STATISTICS TokenStat = {0};
  988. ULONG cbReturnLength = 0;
  989. PSECURITY_LOGON_SESSION_DATA pLogonSessionData = NULL;
  990. TCHAR szOutput[256] = {0};
  991. Status DBGCHK = ZwQueryInformationToken(
  992. hToken,
  993. TokenStatistics,
  994. &TokenStat,
  995. sizeof(TokenStat),
  996. &cbReturnLength
  997. );
  998. if (NT_SUCCESS(Status))
  999. {
  1000. _sntprintf(szOutput, COUNTOF(szOutput) - 1,
  1001. TEXT("LogonId %#x:%#x, Impersonation Level %s, TokenType %s\n"),
  1002. TokenStat.AuthenticationId.HighPart,
  1003. TokenStat.AuthenticationId.LowPart,
  1004. ImpLevel2Str(TokenStat.ImpersonationLevel),
  1005. TokenStat.TokenType == TokenPrimary ? TEXT("Primary") : TEXT("Impersonation"));
  1006. SspiPrint(SSPI_LOG, szOutput);
  1007. Status DBGCHK = LsaGetLogonSessionData(&TokenStat.AuthenticationId, &pLogonSessionData);
  1008. }
  1009. if (NT_SUCCESS(Status))
  1010. {
  1011. PrintLogonSessionData(SSPI_LOG, pLogonSessionData);
  1012. }
  1013. if (pLogonSessionData)
  1014. {
  1015. LsaFreeReturnBuffer(pLogonSessionData);
  1016. }
  1017. return Status;
  1018. }
  1019. VOID
  1020. PrintLogonSessionData(
  1021. IN ULONG Level,
  1022. IN SECURITY_LOGON_SESSION_DATA* pLogonSessionData
  1023. )
  1024. {
  1025. PAGED_CODE();
  1026. TCHAR szOutput[256] = {0};
  1027. int cbUsed = 0;
  1028. if (pLogonSessionData && (pLogonSessionData->Size >= sizeof(SECURITY_LOGON_SESSION_DATA_OLD)))
  1029. {
  1030. cbUsed = _sntprintf(szOutput, COUNTOF(szOutput) - 1,
  1031. TEXT("LogonSession Data for LogonId %#x:%#x, UserName %wZ, LogonDomain %wZ, ")
  1032. TEXT("AuthenticationPackage %wZ, LogonType %#x (%s), Session %#x, Sid %p, LogonTime %#x:%#x\n"),
  1033. pLogonSessionData->LogonId.HighPart, pLogonSessionData->LogonId.HighPart, &pLogonSessionData->UserName, &pLogonSessionData->LogonDomain,
  1034. &pLogonSessionData->AuthenticationPackage, pLogonSessionData->LogonType, LogonType2Str(pLogonSessionData->LogonType),
  1035. pLogonSessionData->Session, pLogonSessionData->Sid, ((LARGE_INTEGER*)&pLogonSessionData->LogonTime)->HighPart, ((LARGE_INTEGER*)&pLogonSessionData->LogonTime)->HighPart);
  1036. if ((cbUsed > 0) && (pLogonSessionData->Size >= sizeof(SECURITY_LOGON_SESSION_DATA)))
  1037. {
  1038. _sntprintf(szOutput + cbUsed, COUNTOF(szOutput) - 1 - cbUsed, TEXT("LogonServer %wZ, DnsDomainName %wZ, Upn %wZ\n"),
  1039. &pLogonSessionData->LogonServer, &pLogonSessionData->DnsDomainName, &pLogonSessionData->Upn);
  1040. }
  1041. SspiPrint(Level, szOutput);
  1042. }
  1043. }
  1044. PCTSTR
  1045. LogonType2Str(
  1046. IN ULONG LogonType
  1047. )
  1048. {
  1049. PAGED_CODE();
  1050. static PCTSTR g_cszLogonTypes[] =
  1051. {
  1052. TEXT("Invalid"),
  1053. TEXT("Invalid"),
  1054. TEXT("Interactive"),
  1055. TEXT("Network"),
  1056. TEXT("Batch"),
  1057. TEXT("Service"),
  1058. TEXT("Proxy"),
  1059. TEXT("Unlock"),
  1060. TEXT("NetworkCleartext"),
  1061. TEXT("NewCredentials"),
  1062. TEXT("RemoteInteractive"), // Remote, yet interactive. Terminal server
  1063. TEXT("CachedInteractive"),
  1064. };
  1065. return ((LogonType < COUNTOF(g_cszLogonTypes)) ?
  1066. g_cszLogonTypes[LogonType] : TEXT("Invalid"));
  1067. }
  1068. PCTSTR
  1069. ImpLevel2Str(
  1070. IN ULONG Level
  1071. )
  1072. {
  1073. static PCTSTR ImpLevels[] = {
  1074. TEXT("Anonymous"),
  1075. TEXT("Identification"),
  1076. TEXT("Impersonation"),
  1077. TEXT("Delegation")
  1078. };
  1079. return ((Level < COUNTOF(ImpLevels)) ? ImpLevels[Level] : TEXT("Illegal!"));
  1080. }