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.

1337 lines
32 KiB

  1. /*++
  2. Copyright (c) 2001 Microsoft Corporation
  3. All rights reserved
  4. Module Name:
  5. lsasspi.cxx
  6. Abstract:
  7. lsasspi
  8. Author:
  9. Larry Zhu (LZhu) December 1, 2001 Created
  10. Environment:
  11. User Mode -Win32
  12. Revision History:
  13. --*/
  14. #include "precomp.hxx"
  15. #pragma hdrstop
  16. #include "lsasspi.hxx"
  17. #include "dbgstate.hxx"
  18. #define SECUR32DLL TEXT("secur32.dll")
  19. PCSTR
  20. LogonType2Str(
  21. IN ULONG LogonType
  22. )
  23. {
  24. static PCSTR g_cszLogonTypes[] =
  25. {
  26. "Invalid",
  27. "Invalid",
  28. "Interactive",
  29. "Network",
  30. "Batch",
  31. "Service",
  32. "Proxy",
  33. "Unlock",
  34. "NetworkCleartext",
  35. "NewCredentials",
  36. "RemoteInteractive", // Remote, yet interactive. Terminal server
  37. "CachedInteractive",
  38. };
  39. return ((LogonType < COUNTOF(g_cszLogonTypes)) ?
  40. g_cszLogonTypes[LogonType] : "Invalid");
  41. }
  42. PCSTR
  43. ImpLevel2Str(
  44. IN ULONG Level
  45. )
  46. {
  47. static PCSTR ImpLevels[] = {
  48. "Anonymous",
  49. "Identification",
  50. "Impersonation",
  51. "Delegation"
  52. };
  53. return ((Level < COUNTOF(ImpLevels)) ? ImpLevels[Level] : "Illegal!");
  54. }
  55. NTSTATUS
  56. GetLsaHandleAndPackageId(
  57. IN PCSTR pszPackageNameA,
  58. OUT HANDLE* pLsaHandle,
  59. OUT ULONG* pPackageId
  60. )
  61. {
  62. BOOLEAN bWasTcbPrivEnabled = FALSE;
  63. BOOLEAN bIsImpersonating = TRUE;
  64. return GetLsaHandleAndPackageIdEx(
  65. pszPackageNameA,
  66. pLsaHandle,
  67. pPackageId,
  68. &bWasTcbPrivEnabled,
  69. &bIsImpersonating
  70. );
  71. }
  72. NTSTATUS
  73. GetLsaHandleAndPackageIdEx(
  74. IN PCSTR pszPackageNameA,
  75. OUT HANDLE* pLsaHandle,
  76. OUT ULONG* pPackageId,
  77. OUT BOOLEAN* pbWasTcbPrivEnabled,
  78. OUT BOOLEAN* pbIsImpersonating
  79. )
  80. {
  81. TNtStatus Status = STATUS_UNSUCCESSFUL;
  82. STRING Name = {0};
  83. LSA_OPERATIONAL_MODE Ignored = 0;
  84. HANDLE LogonHandle = NULL;
  85. ULONG PackageId = -1;
  86. BOOLEAN bIsImpersonating = TRUE;
  87. DWORD UserInfoResponseLength = 0;
  88. DebugPrintf(SSPI_LOG, "GetLsaHandleAndPackageId looking for %s\n", pszPackageNameA);
  89. *pLsaHandle = NULL;
  90. *pPackageId = -1;
  91. //
  92. // Turn on the TCB privilege
  93. //
  94. DBGCFG2(Status, STATUS_PRIVILEGE_NOT_HELD, STATUS_NO_TOKEN);
  95. Status DBGCHK = RtlAdjustPrivilege(SE_TCB_PRIVILEGE, TRUE, *pbIsImpersonating, pbWasTcbPrivEnabled);
  96. if (STATUS_NO_TOKEN == (NTSTATUS) Status)
  97. {
  98. *pbIsImpersonating = FALSE;
  99. Status DBGCHK = RtlAdjustPrivilege(SE_TCB_PRIVILEGE, TRUE, *pbIsImpersonating, pbWasTcbPrivEnabled);
  100. }
  101. else if (!NT_SUCCESS(Status))
  102. {
  103. *pbIsImpersonating = TRUE;
  104. }
  105. if (NT_SUCCESS(Status))
  106. {
  107. RtlInitString(
  108. &Name,
  109. "SspTest"
  110. );
  111. Status DBGCHK = LsaRegisterLogonProcess(
  112. &Name,
  113. &LogonHandle,
  114. &Ignored
  115. );
  116. if (NT_SUCCESS(Status))
  117. {
  118. DebugPrintf(SSPI_LOG, "LsaRegisterLogonProcess succeeded\n");
  119. }
  120. }
  121. else
  122. {
  123. Status DBGCHK = LsaConnectUntrusted(&LogonHandle);
  124. if (NT_SUCCESS(Status))
  125. {
  126. DebugPrintf(SSPI_LOG, "LsaConnectUntrusted succeeded\n");
  127. }
  128. }
  129. RtlInitString(
  130. &Name,
  131. pszPackageNameA
  132. );
  133. if (NT_SUCCESS(Status))
  134. {
  135. Status DBGCHK = LsaLookupAuthenticationPackage(
  136. LogonHandle,
  137. &Name,
  138. &PackageId
  139. );
  140. }
  141. *pPackageId = PackageId;
  142. *pLsaHandle = LogonHandle;
  143. return Status;
  144. }
  145. NTSTATUS
  146. FindAndOpenWinlogon(
  147. OUT HANDLE* phWinlogon
  148. )
  149. {
  150. TNtStatus Status;
  151. HANDLE hWinlogon = NULL;
  152. SYSTEM_PROCESS_INFORMATION* pSystemInfo = NULL;
  153. SYSTEM_PROCESS_INFORMATION* pWalk = NULL;
  154. OBJECT_ATTRIBUTES Obja = {0};
  155. CLIENT_ID ClientId = {0};
  156. UNICODE_STRING Winlogon = CONSTANT_UNICODE_STRING(L"winlogon.exe");
  157. pSystemInfo = (SYSTEM_PROCESS_INFORMATION*) new CHAR[sizeof(SYSTEM_PROCESS_INFORMATION) * 1024];
  158. Status DBGCHK = pSystemInfo ? STATUS_SUCCESS : STATUS_NO_MEMORY;
  159. if (NT_SUCCESS(Status))
  160. {
  161. Status DBGCHK = NtQuerySystemInformation(
  162. SystemProcessInformation,
  163. pSystemInfo,
  164. sizeof(SYSTEM_PROCESS_INFORMATION) * 1024,
  165. NULL
  166. );
  167. }
  168. if (NT_SUCCESS(Status))
  169. {
  170. pWalk = pSystemInfo ;
  171. while (RtlCompareUnicodeString(&pWalk->ImageName, &Winlogon, TRUE) != 0)
  172. {
  173. if (pWalk->NextEntryOffset == 0)
  174. {
  175. pWalk = NULL ;
  176. break;
  177. }
  178. pWalk = (SYSTEM_PROCESS_INFORMATION*) ((UCHAR*) pWalk + pWalk->NextEntryOffset);
  179. }
  180. Status DBGCHK = pWalk ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
  181. }
  182. if (NT_SUCCESS(Status))
  183. {
  184. ClientId.UniqueThread = (HANDLE)NULL;
  185. ClientId.UniqueProcess = (HANDLE)LongToHandle(PtrToUlong(pWalk->UniqueProcessId));
  186. InitializeObjectAttributes(
  187. &Obja,
  188. NULL,
  189. 0, // (bInheritHandle ? OBJ_INHERIT : 0),
  190. NULL,
  191. NULL
  192. );
  193. Status DBGCHK = NtOpenProcess(
  194. &hWinlogon,
  195. (ACCESS_MASK)PROCESS_QUERY_INFORMATION,
  196. &Obja,
  197. &ClientId
  198. );
  199. }
  200. if (NT_SUCCESS(Status))
  201. {
  202. *phWinlogon = hWinlogon;
  203. hWinlogon = NULL;
  204. }
  205. if (pSystemInfo)
  206. {
  207. delete [] pSystemInfo;
  208. }
  209. if (hWinlogon)
  210. {
  211. NtClose(hWinlogon);
  212. }
  213. return Status ;
  214. }
  215. NTSTATUS
  216. GetSystemToken(
  217. OUT HANDLE* phSystemToken
  218. )
  219. {
  220. TNtStatus Status;
  221. HANDLE hWinlogon = NULL;
  222. Status DBGCHK = FindAndOpenWinlogon(&hWinlogon);
  223. if (NT_SUCCESS(Status))
  224. {
  225. Status DBGCHK = GetProcessToken(hWinlogon, phSystemToken);
  226. }
  227. if (hWinlogon)
  228. {
  229. NtClose(hWinlogon);
  230. }
  231. return Status;
  232. }
  233. NTSTATUS
  234. Impersonate(
  235. IN OPTIONAL HANDLE hToken
  236. )
  237. {
  238. TNtStatus Status = STATUS_SUCCESS;
  239. TOKEN_TYPE Type;
  240. ULONG cbType;
  241. HANDLE hImpToken = NULL;
  242. HANDLE hDupToken = NULL;
  243. SECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;
  244. OBJECT_ATTRIBUTES ObjectAttributes;
  245. if (hToken)
  246. {
  247. Status DBGCHK = NtQueryInformationToken(
  248. hToken,
  249. TokenType,
  250. &Type,
  251. sizeof(TOKEN_TYPE),
  252. &cbType
  253. );
  254. if (NT_SUCCESS(Status))
  255. {
  256. if (Type == TokenPrimary)
  257. {
  258. InitializeObjectAttributes(
  259. &ObjectAttributes,
  260. NULL,
  261. 0L,
  262. NULL,
  263. NULL
  264. );
  265. SecurityQualityOfService.Length = sizeof(SECURITY_QUALITY_OF_SERVICE);
  266. SecurityQualityOfService.ImpersonationLevel = SecurityImpersonation;
  267. SecurityQualityOfService.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
  268. SecurityQualityOfService.EffectiveOnly = FALSE;
  269. ObjectAttributes.SecurityQualityOfService = &SecurityQualityOfService;
  270. Status DBGCHK = NtDuplicateToken(
  271. hToken,
  272. TOKEN_IMPERSONATE | TOKEN_QUERY,
  273. &ObjectAttributes,
  274. FALSE,
  275. TokenImpersonation,
  276. &hDupToken
  277. );
  278. if (NT_SUCCESS(Status))
  279. {
  280. hImpToken = hDupToken;
  281. }
  282. }
  283. else
  284. {
  285. hImpToken = hToken;
  286. }
  287. }
  288. }
  289. if (NT_SUCCESS(Status))
  290. {
  291. Status DBGCHK = NtSetInformationThread(
  292. NtCurrentThread(),
  293. ThreadImpersonationToken,
  294. &hImpToken,
  295. sizeof(hImpToken)
  296. );
  297. }
  298. if (hDupToken)
  299. {
  300. NtClose(hDupToken);
  301. }
  302. return Status;
  303. }
  304. HRESULT
  305. GetProcessToken(
  306. IN HANDLE hProcess,
  307. OUT HANDLE* phProcessToken
  308. )
  309. {
  310. THResult hRetval;
  311. HANDLE hProcessToken = NULL;
  312. HANDLE hSubToken = NULL;
  313. HANDLE hDupToken = NULL;
  314. SECURITY_DESCRIPTOR SdNullDACL = {0};
  315. SECURITY_DESCRIPTOR* pSave = NULL;
  316. ULONG cbSdSize = 0;
  317. BOOLEAN bNeedRestoreSd = FALSE;
  318. DBGCFG1(hRetval, HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED));
  319. hRetval DBGCHK = OpenProcessToken(
  320. hProcess,
  321. TOKEN_IMPERSONATE | TOKEN_QUERY | TOKEN_DUPLICATE,
  322. &hProcessToken
  323. ) ? S_OK : GetLastErrorAsHResult();
  324. if (FAILED(hRetval) && (HRESULT_CODE(hRetval) == ERROR_ACCESS_DENIED))
  325. {
  326. SspiPrint(SSPI_WARN,
  327. TEXT("GetProcessToken failed with access denied to get token for process %p\n"),
  328. hProcess);
  329. hRetval DBGCHK = OpenProcessToken(
  330. hProcess,
  331. READ_CONTROL | WRITE_DAC,
  332. &hSubToken
  333. ) ? S_OK : GetLastErrorAsHResult();
  334. if (SUCCEEDED(hRetval))
  335. {
  336. cbSdSize = 1024;
  337. pSave = (SECURITY_DESCRIPTOR*) new CHAR[cbSdSize];
  338. hRetval DBGCHK = pSave ? S_OK : E_OUTOFMEMORY;
  339. }
  340. if (SUCCEEDED(hRetval))
  341. {
  342. hRetval DBGCHK = GetKernelObjectSecurity(
  343. hSubToken,
  344. DACL_SECURITY_INFORMATION,
  345. pSave,
  346. cbSdSize,
  347. &cbSdSize
  348. ) ? S_OK : GetLastErrorAsHResult();
  349. if (FAILED(hRetval) && (ERROR_INSUFFICIENT_BUFFER == HRESULT_CODE(hRetval)))
  350. {
  351. delete [] pSave;
  352. pSave = (SECURITY_DESCRIPTOR*) new CHAR[cbSdSize];
  353. hRetval DBGCHK = pSave ? S_OK : E_OUTOFMEMORY;
  354. if (SUCCEEDED(hRetval))
  355. {
  356. hRetval DBGCHK = GetKernelObjectSecurity(
  357. hSubToken,
  358. DACL_SECURITY_INFORMATION,
  359. pSave,
  360. cbSdSize,
  361. &cbSdSize
  362. ) ? S_OK : GetLastErrorAsHResult();
  363. }
  364. }
  365. }
  366. if (SUCCEEDED(hRetval))
  367. {
  368. bNeedRestoreSd = TRUE;
  369. hRetval DBGCHK = InitializeSecurityDescriptor(&SdNullDACL, SECURITY_DESCRIPTOR_REVISION) ? S_OK : GetLastErrorAsHResult();
  370. }
  371. if (SUCCEEDED(hRetval))
  372. {
  373. hRetval DBGCHK = SetSecurityDescriptorDacl(&SdNullDACL, TRUE, NULL, FALSE) ? S_OK : GetLastErrorAsHResult();
  374. }
  375. if (SUCCEEDED(hRetval))
  376. {
  377. hRetval DBGCHK = SetKernelObjectSecurity(
  378. hSubToken,
  379. DACL_SECURITY_INFORMATION,
  380. &SdNullDACL
  381. ) ? S_OK : GetLastErrorAsHResult();
  382. }
  383. if (SUCCEEDED(hRetval))
  384. {
  385. hRetval DBGCHK = OpenProcessToken(
  386. hProcess,
  387. TOKEN_IMPERSONATE | TOKEN_QUERY | TOKEN_DUPLICATE,
  388. &hProcessToken
  389. ) ? S_OK : GetLastErrorAsHResult();
  390. }
  391. }
  392. if (SUCCEEDED(hRetval))
  393. {
  394. hRetval DBGCHK = DuplicateTokenEx(
  395. hProcessToken,
  396. MAXIMUM_ALLOWED,
  397. NULL,
  398. SecurityImpersonation,
  399. TokenPrimary,
  400. &hDupToken
  401. );
  402. }
  403. if (SUCCEEDED(hRetval))
  404. {
  405. *phProcessToken = hDupToken;
  406. hDupToken = NULL;
  407. }
  408. if (hSubToken)
  409. {
  410. CloseHandle(hSubToken);
  411. }
  412. if (hDupToken)
  413. {
  414. CloseHandle(hDupToken);
  415. }
  416. if (hProcessToken)
  417. {
  418. CloseHandle(hProcessToken);
  419. }
  420. if (bNeedRestoreSd)
  421. {
  422. SetKernelObjectSecurity(
  423. hSubToken,
  424. DACL_SECURITY_INFORMATION,
  425. pSave
  426. );
  427. }
  428. if (pSave)
  429. {
  430. delete [] pSave;
  431. }
  432. return hRetval;
  433. }
  434. HRESULT
  435. GetProcessTokenWithNullDACL(
  436. IN HANDLE hProcess,
  437. OUT HANDLE* phProcessToken
  438. )
  439. {
  440. THResult hRetval;
  441. HANDLE hProcessToken = NULL;
  442. HANDLE hSubToken = NULL;
  443. HANDLE hDupToken = NULL;
  444. SECURITY_DESCRIPTOR SdNullDACL = {0};
  445. hRetval DBGCHK = OpenProcessToken(
  446. hProcess,
  447. READ_CONTROL | WRITE_DAC,
  448. &hSubToken
  449. ) ? S_OK : GetLastErrorAsHResult();
  450. if (SUCCEEDED(hRetval))
  451. {
  452. hRetval DBGCHK = InitializeSecurityDescriptor(&SdNullDACL, SECURITY_DESCRIPTOR_REVISION) ? S_OK : GetLastErrorAsHResult();
  453. }
  454. if (SUCCEEDED(hRetval))
  455. {
  456. hRetval DBGCHK = SetSecurityDescriptorDacl(&SdNullDACL, TRUE, NULL, FALSE) ? S_OK : GetLastErrorAsHResult();
  457. }
  458. if (SUCCEEDED(hRetval))
  459. {
  460. hRetval DBGCHK = SetKernelObjectSecurity(
  461. hSubToken,
  462. DACL_SECURITY_INFORMATION,
  463. &SdNullDACL
  464. ) ? S_OK : GetLastErrorAsHResult();
  465. }
  466. if (SUCCEEDED(hRetval))
  467. {
  468. hRetval DBGCHK = OpenProcessToken(
  469. hProcess,
  470. TOKEN_IMPERSONATE | TOKEN_QUERY | TOKEN_DUPLICATE,
  471. &hProcessToken
  472. ) ? S_OK : GetLastErrorAsHResult();
  473. }
  474. if (SUCCEEDED(hRetval))
  475. {
  476. hRetval DBGCHK = DuplicateTokenEx(
  477. hProcessToken,
  478. MAXIMUM_ALLOWED,
  479. NULL,
  480. SecurityImpersonation,
  481. TokenPrimary,
  482. &hDupToken
  483. );
  484. }
  485. if (SUCCEEDED(hRetval))
  486. {
  487. *phProcessToken = hDupToken;
  488. hDupToken = NULL;
  489. }
  490. if (hSubToken)
  491. {
  492. CloseHandle(hSubToken);
  493. }
  494. if (hDupToken)
  495. {
  496. CloseHandle(hDupToken);
  497. }
  498. if (hProcessToken)
  499. {
  500. CloseHandle(hProcessToken);
  501. }
  502. return hRetval;
  503. }
  504. HRESULT
  505. CreateProcessAsUserEx(
  506. IN HANDLE hToken,
  507. IN UNICODE_STRING* pApplication
  508. )
  509. {
  510. THResult hRetval = S_OK;
  511. PROCESS_INFORMATION pi = {INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE, 0, 0};
  512. STARTUPINFOW si = {0};
  513. HANDLE hTokenNew = NULL;
  514. si.cb = sizeof(si);
  515. DBGCFG1(hRetval, HRESULT_FROM_WIN32(ERROR_BAD_TOKEN_TYPE));
  516. DebugPrintf(SSPI_LOG, "CreateProcessAsUserEx hTokenNew %p, Application %wZ\n", hToken, pApplication);
  517. hRetval DBGCHK = CreateProcessAsUserW(
  518. hToken,
  519. NULL,
  520. pApplication->Buffer,
  521. NULL,
  522. NULL,
  523. FALSE,
  524. CREATE_NEW_PROCESS_GROUP | CREATE_NEW_CONSOLE,
  525. NULL,
  526. NULL,
  527. &si,
  528. &pi
  529. ) ? S_OK : GetLastErrorAsHResult();
  530. if (FAILED(hRetval) && (ERROR_BAD_TOKEN_TYPE == HRESULT_CODE(hRetval)))
  531. {
  532. DebugPrintf(SSPI_WARN, "CreateProcessAsUserW failed with ERROR_BAD_TOKEN_TYPE\n");
  533. hRetval DBGCHK = DuplicateTokenEx(
  534. hToken,
  535. TOKEN_QUERY | TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY,
  536. NULL,
  537. SecurityImpersonation,
  538. TokenPrimary,
  539. &hTokenNew
  540. ) ? S_OK : GetLastErrorAsHResult();
  541. if (SUCCEEDED(hRetval))
  542. {
  543. hRetval DBGCHK = CreateProcessAsUserW(
  544. hTokenNew,
  545. NULL,
  546. pApplication->Buffer,
  547. NULL,
  548. NULL,
  549. FALSE,
  550. CREATE_NEW_PROCESS_GROUP | CREATE_NEW_CONSOLE,
  551. NULL,
  552. NULL,
  553. &si,
  554. &pi
  555. ) ? S_OK : GetLastErrorAsHResult();
  556. }
  557. }
  558. if (hTokenNew)
  559. {
  560. CloseHandle(hTokenNew);
  561. }
  562. if (pi.hProcess != INVALID_HANDLE_VALUE)
  563. {
  564. // WaitForSingleObject(pi.hProcess, INFINITE);
  565. CloseHandle(pi.hProcess);
  566. }
  567. if (pi.hThread != INVALID_HANDLE_VALUE)
  568. {
  569. CloseHandle(pi.hThread);
  570. }
  571. return hRetval;
  572. }
  573. NTSTATUS
  574. CheckUserToken(
  575. IN HANDLE hToken
  576. )
  577. {
  578. TNtStatus Status;
  579. TOKEN_STATISTICS TokenStat = {0};
  580. CHAR Buff[sizeof(TOKEN_USER) + SECURITY_MAX_SID_SIZE] = {0};
  581. TOKEN_USER* pTokenUserData = (TOKEN_USER*) Buff;
  582. ULONG cbReturnLength = 0;
  583. PSECURITY_LOGON_SESSION_DATA pLogonSessionData = NULL;
  584. Status DBGCHK = NtQueryInformationToken(
  585. hToken,
  586. TokenStatistics,
  587. &TokenStat,
  588. sizeof(TokenStat),
  589. &cbReturnLength
  590. );
  591. if (NT_SUCCESS(Status))
  592. {
  593. DebugPrintf(SSPI_LOG, "LogonId %#x:%#x, Impersonation Level %s, TokenType %s\n",
  594. TokenStat.AuthenticationId.HighPart,
  595. TokenStat.AuthenticationId.LowPart,
  596. ImpLevel2Str(TokenStat.ImpersonationLevel),
  597. TokenStat.TokenType == TokenPrimary ? "Primary" : "Impersonation");
  598. Status DBGCHK = LsaGetLogonSessionData(&TokenStat.AuthenticationId, &pLogonSessionData);
  599. if (NT_SUCCESS(Status))
  600. {
  601. DebugPrintLogonSessionData(SSPI_LOG, pLogonSessionData);
  602. }
  603. else if ( (STATUS_NO_SUCH_LOGON_SESSION == (NTSTATUS) Status)
  604. || (STATUS_ACCESS_DENIED == (NTSTATUS) Status) )
  605. {
  606. Status DBGCHK = NtQueryInformationToken(
  607. hToken,
  608. TokenUser,
  609. Buff,
  610. sizeof(Buff),
  611. &cbReturnLength
  612. );
  613. if (NT_SUCCESS(Status))
  614. {
  615. DebugPrintSidFriendlyName(SSPI_LOG, "Sid", pTokenUserData->User.Sid);
  616. }
  617. }
  618. }
  619. if (pLogonSessionData)
  620. {
  621. LsaFreeReturnBuffer(pLogonSessionData);
  622. }
  623. return Status;
  624. }
  625. HRESULT
  626. CheckUserData(
  627. VOID
  628. )
  629. {
  630. THResult hRetval = E_FAIL;
  631. TOKEN_STATISTICS TokenStat = {0};
  632. ULONG cbReturnLength = 0;
  633. PSECURITY_LOGON_SESSION_DATA pLogonSessionData = NULL;
  634. HANDLE hNullToken = NULL;
  635. HANDLE hToken = NULL;
  636. BOOL bIsImpersonating = FALSE;
  637. hRetval DBGCHK = NtOpenThreadToken(
  638. NtCurrentThread(), // handle to thread
  639. MAXIMUM_ALLOWED, // access to process
  640. TRUE, // process or thread security
  641. &hToken // handle to open access token
  642. );
  643. if (STATUS_NO_TOKEN == (HRESULT) hRetval)
  644. {
  645. hRetval DBGCHK = NtOpenProcessToken(
  646. NtCurrentProcess(), // handle to process
  647. MAXIMUM_ALLOWED, // access to process
  648. &hToken // handle to open access token
  649. );
  650. }
  651. else if (SUCCEEDED(hRetval))
  652. {
  653. bIsImpersonating = TRUE;
  654. }
  655. //
  656. // Revert to self
  657. //
  658. if (SUCCEEDED(hRetval) && bIsImpersonating)
  659. {
  660. hRetval DBGCHK = NtSetInformationThread(
  661. NtCurrentThread(),
  662. ThreadImpersonationToken,
  663. &hNullToken,
  664. sizeof( HANDLE )
  665. );
  666. }
  667. if (SUCCEEDED(hRetval))
  668. {
  669. hRetval DBGCHK = CheckUserToken(hToken);
  670. }
  671. //
  672. // restore thread token
  673. //
  674. if (bIsImpersonating)
  675. {
  676. TNtStatus hr;
  677. hr DBGCHK = NtSetInformationThread(
  678. NtCurrentThread(),
  679. ThreadImpersonationToken,
  680. &hToken,
  681. sizeof( HANDLE )
  682. );
  683. if (SUCCEEDED(hRetval) && FAILED(hr))
  684. {
  685. hRetval DBGNOCHK = hr;
  686. }
  687. }
  688. if (pLogonSessionData)
  689. {
  690. LsaFreeReturnBuffer(pLogonSessionData);
  691. }
  692. if (hToken)
  693. {
  694. NtClose(hToken);
  695. }
  696. return hRetval;
  697. }
  698. NTSTATUS
  699. GetProcessHandleByCid(
  700. IN ULONG ProcessID,
  701. OUT HANDLE* phProcess
  702. )
  703. {
  704. TNtStatus Status;
  705. HANDLE hProcess = NULL;
  706. CLIENT_ID ClientId = {0};
  707. OBJECT_ATTRIBUTES Obja = {0};
  708. SspiPrint(SSPI_LOG, TEXT("GetProcessHandleByCid %#x(%d)\n"), ProcessID, ProcessID);
  709. InitializeObjectAttributes(
  710. &Obja,
  711. NULL,
  712. 0,
  713. NULL,
  714. NULL
  715. );
  716. ClientId.UniqueProcess = LongToHandle(ProcessID);
  717. ClientId.UniqueThread = NULL;
  718. Status DBGCHK = NtOpenProcess(
  719. &hProcess,
  720. PROCESS_QUERY_INFORMATION,
  721. &Obja,
  722. &ClientId
  723. );
  724. if (NT_SUCCESS(Status))
  725. {
  726. *phProcess = hProcess;
  727. hProcess = NULL;
  728. }
  729. if (hProcess)
  730. {
  731. NtClose(hProcess);
  732. }
  733. return Status;
  734. }
  735. HRESULT
  736. GetProcessTokenByProcessId(
  737. IN ULONG ProcessID,
  738. OUT HANDLE* phToken
  739. )
  740. {
  741. THResult hRetval;
  742. HANDLE hProcess = NULL;
  743. HANDLE hToken = NULL;
  744. SspiPrint(SSPI_LOG, TEXT("GetProcessTokenByProcessId: ProcessID %#x(%d)\n"), ProcessID, ProcessID);
  745. hProcess = OpenProcess(
  746. PROCESS_QUERY_INFORMATION,
  747. FALSE,
  748. ProcessID
  749. );
  750. hRetval DBGCHK = hProcess ? S_OK : GetLastErrorAsHResult();
  751. if (SUCCEEDED(hRetval))
  752. {
  753. hRetval DBGCHK = GetProcessToken(hProcess, &hToken);
  754. }
  755. if (SUCCEEDED(hRetval))
  756. {
  757. *phToken = hToken;
  758. hToken = NULL;
  759. }
  760. if (hProcess)
  761. {
  762. CloseHandle(hProcess);
  763. }
  764. if (hToken)
  765. {
  766. CloseHandle(hToken);
  767. }
  768. return hRetval;
  769. }
  770. PCSTR
  771. GetSidTypeStr(
  772. IN SID_NAME_USE eUse
  773. )
  774. {
  775. static PCSTR acszSidTypeStr[] =
  776. {
  777. "Invalid", "User", "Group", "Domain", "Alias", "Well Known Group",
  778. "Deleted Account", "Invalid", "Unknown", "Computer",
  779. };
  780. if (eUse < SidTypeUser || eUse > SidTypeComputer)
  781. {
  782. throw "Unrecognized SID";
  783. }
  784. return acszSidTypeStr[eUse];
  785. }
  786. VOID
  787. DebugPrintSidFriendlyName(
  788. IN ULONG Level,
  789. IN PCSTR pszBanner,
  790. IN PSID pSid
  791. )
  792. {
  793. TNtStatus NtStatus;
  794. UNICODE_STRING ucsSid = {0};
  795. NtStatus DBGCHK = RtlConvertSidToUnicodeString(&ucsSid, pSid, TRUE);
  796. if (NT_SUCCESS(NtStatus))
  797. {
  798. THResult hRetval = E_FAIL;
  799. CHAR szName[MAX_PATH] = {0};
  800. CHAR szDomainName[MAX_PATH] ={0};
  801. SID_NAME_USE eUse = SidTypeInvalid;
  802. DWORD cbName = sizeof(szName) - 1;
  803. DWORD cbDomainName = sizeof(szDomainName) - 1;
  804. DBGCFG1(hRetval, HRESULT_FROM_WIN32(ERROR_NONE_MAPPED));
  805. hRetval DBGCHK = LookupAccountSidA(
  806. NULL,
  807. pSid,
  808. szName,
  809. &cbName,
  810. szDomainName,
  811. &cbDomainName,
  812. &eUse
  813. ) ? S_OK : GetLastErrorAsHResult();
  814. if (SUCCEEDED(hRetval))
  815. {
  816. DebugPrintf(Level, "%s %wZ -> (%s: %s\\%s)\n",
  817. pszBanner,
  818. &ucsSid,
  819. GetSidTypeStr(eUse),
  820. *szDomainName ? szDomainName : "localhost", szName);
  821. }
  822. else if (FAILED(hRetval) && (ERROR_NONE_MAPPED == HRESULT_CODE(hRetval)))
  823. {
  824. DebugPrintf(SSPI_LOG, "%s %wZ -> (no name mapped)\n", pszBanner,&ucsSid);
  825. }
  826. }
  827. RtlFreeUnicodeString(&ucsSid);
  828. }
  829. VOID
  830. DebugPrintLogonSessionData(
  831. IN ULONG Level,
  832. IN SECURITY_LOGON_SESSION_DATA* pLogonSessionData
  833. )
  834. {
  835. if (pLogonSessionData && (pLogonSessionData->Size >= sizeof(SECURITY_LOGON_SESSION_DATA_OLD)))
  836. {
  837. DebugPrintf(Level, "LogonSession Data for LogonId %#x:%#x\n", pLogonSessionData->LogonId.HighPart, pLogonSessionData->LogonId.HighPart);
  838. DebugPrintf(Level, "UserName %wZ\n", &pLogonSessionData->UserName);
  839. DebugPrintf(Level, "LogonDomain %wZ\n", &pLogonSessionData->LogonDomain);
  840. DebugPrintf(Level, "AuthenticationPackage %wZ\n", &pLogonSessionData->AuthenticationPackage);
  841. DebugPrintf(Level, "LogonType %#x (%s)\n", pLogonSessionData->LogonType, LogonType2Str(pLogonSessionData->LogonType));
  842. DebugPrintf(Level, "Session %#x\n", pLogonSessionData->Session);
  843. DebugPrintSidFriendlyName(Level, "Sid", pLogonSessionData->Sid);
  844. DebugPrintSysTimeAsLocalTime(Level, "LogonTime", &pLogonSessionData->LogonTime);
  845. if (pLogonSessionData->Size >= sizeof(SECURITY_LOGON_SESSION_DATA))
  846. {
  847. DebugPrintf(Level, "LogonServer %wZ\n", &pLogonSessionData->LogonServer);
  848. DebugPrintf(Level, "DnsDomainName %wZ\n", &pLogonSessionData->DnsDomainName);
  849. DebugPrintf(Level, "Upn %wZ\n", &pLogonSessionData->Upn);
  850. }
  851. }
  852. }
  853. NTSTATUS
  854. LsaGetLogonSessionData(
  855. IN PLUID LogonId,
  856. OUT PSECURITY_LOGON_SESSION_DATA * ppLogonSessionData
  857. )
  858. {
  859. THResult hRetval;
  860. PFuncLsaGetLogonSessionData pFuncLsaGetLogonSessionData = NULL;
  861. HMODULE hLib = LoadLibrary(SECUR32DLL);
  862. hRetval DBGCHK = hLib ? S_OK : GetLastErrorAsHResult();
  863. if (SUCCEEDED(hRetval))
  864. {
  865. pFuncLsaGetLogonSessionData =
  866. (PFuncLsaGetLogonSessionData) GetProcAddress(hLib, "LsaGetLogonSessionData");
  867. hRetval DBGCHK = pFuncLsaGetLogonSessionData ? S_OK : GetLastErrorAsHResult();
  868. }
  869. if (SUCCEEDED(hRetval))
  870. {
  871. hRetval DBGCHK = (*pFuncLsaGetLogonSessionData)(LogonId, ppLogonSessionData);
  872. }
  873. if (hLib)
  874. {
  875. FreeLibrary(hLib);
  876. }
  877. return hRetval;
  878. }
  879. NTSTATUS
  880. LsaRegisterLogonProcess (
  881. IN PLSA_STRING LogonProcessName,
  882. OUT PHANDLE LsaHandle,
  883. OUT PLSA_OPERATIONAL_MODE SecurityMode
  884. )
  885. {
  886. THResult hRetval;
  887. PFuncLsaRegisterLogonProcess pFuncLsaRegisterLogonProcess = NULL;
  888. HMODULE hLib = LoadLibrary(SECUR32DLL);
  889. hRetval DBGCHK = hLib ? S_OK : GetLastErrorAsHResult();
  890. if (SUCCEEDED(hRetval))
  891. {
  892. pFuncLsaRegisterLogonProcess =
  893. (PFuncLsaRegisterLogonProcess) GetProcAddress(hLib, "LsaRegisterLogonProcess");
  894. hRetval DBGCHK = pFuncLsaRegisterLogonProcess ? S_OK : GetLastErrorAsHResult();
  895. }
  896. if (SUCCEEDED(hRetval))
  897. {
  898. hRetval DBGCHK = (*pFuncLsaRegisterLogonProcess)(LogonProcessName, LsaHandle, SecurityMode);
  899. }
  900. if (hLib)
  901. {
  902. FreeLibrary(hLib);
  903. }
  904. return hRetval;
  905. }
  906. NTSTATUS
  907. LsaLookupAuthenticationPackage(
  908. IN HANDLE LsaHandle,
  909. IN PLSA_STRING PackageName,
  910. OUT PULONG AuthenticationPackage
  911. )
  912. {
  913. THResult hRetval;
  914. PFuncLsaLookupAuthenticationPackage pFuncLsaLookupAuthenticationPackage = NULL;
  915. HMODULE hLib = LoadLibrary(SECUR32DLL);
  916. hRetval DBGCHK = hLib ? S_OK : GetLastErrorAsHResult();
  917. if (SUCCEEDED(hRetval))
  918. {
  919. pFuncLsaLookupAuthenticationPackage =
  920. (PFuncLsaLookupAuthenticationPackage) GetProcAddress(hLib, "LsaLookupAuthenticationPackage");
  921. hRetval DBGCHK = pFuncLsaLookupAuthenticationPackage ? S_OK : GetLastErrorAsHResult();
  922. }
  923. if (SUCCEEDED(hRetval))
  924. {
  925. hRetval DBGCHK = (*pFuncLsaLookupAuthenticationPackage)(LsaHandle, PackageName, AuthenticationPackage);
  926. }
  927. if (hLib)
  928. {
  929. FreeLibrary(hLib);
  930. }
  931. return hRetval;
  932. }
  933. NTSTATUS
  934. LsaLogonUser(
  935. IN HANDLE LsaHandle,
  936. IN PLSA_STRING OriginName,
  937. IN SECURITY_LOGON_TYPE LogonType,
  938. IN ULONG AuthenticationPackage,
  939. IN PVOID AuthenticationInformation,
  940. IN ULONG AuthenticationInformationLength,
  941. IN PTOKEN_GROUPS LocalGroups OPTIONAL,
  942. IN PTOKEN_SOURCE SourceContext,
  943. OUT PVOID *ProfileBuffer,
  944. OUT PULONG ProfileBufferLength,
  945. OUT PLUID LogonId,
  946. OUT PHANDLE Token,
  947. OUT PQUOTA_LIMITS Quotas,
  948. OUT PNTSTATUS SubStatus
  949. )
  950. {
  951. THResult hRetval;
  952. PFuncLsaLogonUser pFuncLsaLogonUser = NULL;
  953. HMODULE hLib = LoadLibrary(SECUR32DLL);
  954. hRetval DBGCHK = hLib ? S_OK : GetLastErrorAsHResult();
  955. if (SUCCEEDED(hRetval))
  956. {
  957. pFuncLsaLogonUser =
  958. (PFuncLsaLogonUser) GetProcAddress(hLib, "LsaLogonUser");
  959. hRetval DBGCHK = pFuncLsaLogonUser ? S_OK : GetLastErrorAsHResult();
  960. }
  961. if (SUCCEEDED(hRetval))
  962. {
  963. hRetval DBGCHK = (*pFuncLsaLogonUser)(
  964. LsaHandle,
  965. OriginName,
  966. LogonType,
  967. AuthenticationPackage,
  968. AuthenticationInformation,
  969. AuthenticationInformationLength,
  970. LocalGroups,
  971. SourceContext,
  972. ProfileBuffer,
  973. ProfileBufferLength,
  974. LogonId,
  975. Token,
  976. Quotas,
  977. SubStatus
  978. );
  979. }
  980. if (hLib)
  981. {
  982. FreeLibrary(hLib);
  983. }
  984. return hRetval;
  985. }
  986. NTSTATUS
  987. LsaFreeReturnBuffer(
  988. IN PVOID Buffer
  989. )
  990. {
  991. THResult hRetval;
  992. PFuncLsaFreeReturnBuffer pFuncLsaFreeReturnBuffer = NULL;
  993. HMODULE hLib = LoadLibrary(SECUR32DLL);
  994. hRetval DBGCHK = hLib ? S_OK : GetLastErrorAsHResult();
  995. if (SUCCEEDED(hRetval))
  996. {
  997. pFuncLsaFreeReturnBuffer =
  998. (PFuncLsaFreeReturnBuffer) GetProcAddress(hLib, "LsaFreeReturnBuffer");
  999. hRetval DBGCHK = pFuncLsaFreeReturnBuffer ? S_OK : GetLastErrorAsHResult();
  1000. }
  1001. if (SUCCEEDED(hRetval))
  1002. {
  1003. hRetval DBGCHK = (*pFuncLsaFreeReturnBuffer)(Buffer);
  1004. }
  1005. if (hLib)
  1006. {
  1007. FreeLibrary(hLib);
  1008. }
  1009. return hRetval;
  1010. }
  1011. NTSTATUS
  1012. LsaConnectUntrusted(
  1013. OUT PHANDLE LsaHandle
  1014. )
  1015. {
  1016. THResult hRetval;
  1017. PFuncLsaConnectUntrusted pFuncLsaConnectUntrusted = NULL;
  1018. HMODULE hLib = LoadLibrary(SECUR32DLL);
  1019. hRetval DBGCHK = hLib ? S_OK : GetLastErrorAsHResult();
  1020. if (SUCCEEDED(hRetval))
  1021. {
  1022. pFuncLsaConnectUntrusted =
  1023. (PFuncLsaConnectUntrusted) GetProcAddress(hLib, "LsaConnectUntrusted");
  1024. hRetval DBGCHK = pFuncLsaConnectUntrusted ? S_OK : GetLastErrorAsHResult();
  1025. }
  1026. if (SUCCEEDED(hRetval))
  1027. {
  1028. hRetval DBGCHK = (*pFuncLsaConnectUntrusted)(LsaHandle);
  1029. }
  1030. if (hLib)
  1031. {
  1032. FreeLibrary(hLib);
  1033. }
  1034. return hRetval;
  1035. }
  1036. NTSTATUS
  1037. LsaDeregisterLogonProcess(
  1038. IN HANDLE LsaHandle
  1039. )
  1040. {
  1041. THResult hRetval;
  1042. PFuncLsaDeregisterLogonProcess pFuncLsaDeregisterLogonProcess = NULL;
  1043. HMODULE hLib = LoadLibrary(SECUR32DLL);
  1044. hRetval DBGCHK = hLib ? S_OK : GetLastErrorAsHResult();
  1045. if (SUCCEEDED(hRetval))
  1046. {
  1047. pFuncLsaDeregisterLogonProcess =
  1048. (PFuncLsaDeregisterLogonProcess) GetProcAddress(hLib, "LsaDeregisterLogonProcess");
  1049. hRetval DBGCHK = pFuncLsaDeregisterLogonProcess ? S_OK : GetLastErrorAsHResult();
  1050. }
  1051. if (SUCCEEDED(hRetval))
  1052. {
  1053. hRetval DBGCHK = (*pFuncLsaDeregisterLogonProcess)(LsaHandle);
  1054. }
  1055. if (hLib)
  1056. {
  1057. FreeLibrary(hLib);
  1058. }
  1059. return hRetval;
  1060. }
  1061. NTSTATUS
  1062. LsaCallAuthenticationPackage(
  1063. IN HANDLE LsaHandle,
  1064. IN ULONG AuthenticationPackage,
  1065. IN PVOID ProtocolSubmitBuffer,
  1066. IN ULONG SubmitBufferLength,
  1067. OUT PVOID* ProtocolReturnBuffer,
  1068. OUT PULONG ReturnBufferLength,
  1069. OUT PNTSTATUS ProtocolStatus
  1070. )
  1071. {
  1072. THResult hRetval;
  1073. PFuncLsaCallAuthenticationPackage pFuncLsaCallAuthenticationPackage = NULL;
  1074. HMODULE hLib = LoadLibrary(SECUR32DLL);
  1075. hRetval DBGCHK = hLib ? S_OK : GetLastErrorAsHResult();
  1076. if (SUCCEEDED(hRetval))
  1077. {
  1078. pFuncLsaCallAuthenticationPackage =
  1079. (PFuncLsaCallAuthenticationPackage) GetProcAddress(hLib, "LsaCallAuthenticationPackage");
  1080. hRetval DBGCHK = pFuncLsaCallAuthenticationPackage ? S_OK : GetLastErrorAsHResult();
  1081. }
  1082. if (SUCCEEDED(hRetval))
  1083. {
  1084. hRetval DBGCHK = (*pFuncLsaCallAuthenticationPackage)(
  1085. LsaHandle,
  1086. AuthenticationPackage,
  1087. ProtocolSubmitBuffer,
  1088. SubmitBufferLength,
  1089. ProtocolReturnBuffer,
  1090. ReturnBufferLength,
  1091. ProtocolStatus
  1092. );
  1093. }
  1094. if (hLib)
  1095. {
  1096. FreeLibrary(hLib);
  1097. }
  1098. return hRetval;
  1099. }
  1100. FARPROC
  1101. WINAPI
  1102. DelayLoadFailureHook (
  1103. LPCSTR pszDllName,
  1104. LPCSTR pszProcName
  1105. )
  1106. {
  1107. SspiPrint(SSPI_ERROR, TEXT("pszDllName %s, pszProcName %s\n"), pszDllName, pszProcName);
  1108. return NULL; // fool compiler
  1109. }