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.

1169 lines
28 KiB

  1. /*++
  2. Copyright(c) 1995 Microsoft Corporation
  3. MODULE NAME
  4. impersn.c
  5. ABSTRACT
  6. Impersonation routines for the automatic connection service.
  7. AUTHOR
  8. Anthony Discolo (adiscolo) 04-Aug-1995
  9. REVISION HISTORY
  10. --*/
  11. #define UNICODE
  12. #define _UNICODE
  13. #include <nt.h>
  14. #include <ntrtl.h>
  15. #include <nturtl.h>
  16. #include <stdlib.h>
  17. #include <windows.h>
  18. #include <stdio.h>
  19. #include <npapi.h>
  20. #include <acd.h>
  21. #include <debug.h>
  22. #include "reg.h"
  23. #include "misc.h"
  24. #include "process.h"
  25. #include "imperson.h"
  26. #include "mprlog.h"
  27. #include "rtutils.h"
  28. #include "rasman.h"
  29. extern HANDLE g_hLogEvent;
  30. extern DWORD g_dwCritSecFlags;
  31. DWORD
  32. LoadGroupMemberships();
  33. //
  34. // The static information we
  35. // need to impersonate the currently
  36. // logged-in user.
  37. //
  38. IMPERSONATION_INFO ImpersonationInfoG;
  39. //
  40. // TRUE if ImpersonationInfoG has been initialized
  41. //
  42. BOOLEAN ImpersonationInfoInitializedG = FALSE;
  43. //
  44. // Security attributes and descriptor
  45. // necessary for creating shareable handles.
  46. //
  47. SECURITY_ATTRIBUTES SecurityAttributeG;
  48. SECURITY_DESCRIPTOR SecurityDescriptorG;
  49. HKEY hkeyCUG = NULL;
  50. #ifdef notdef
  51. BOOLEAN
  52. InteractiveSession()
  53. /*++
  54. DESCRIPTION
  55. Determine whether the active process is owned by the
  56. currently logged-in user.
  57. ARGUMENTS
  58. None.
  59. RETURNS
  60. TRUE if it is, FALSE if it isn't.
  61. --*/
  62. {
  63. HANDLE hToken;
  64. BOOLEAN bStatus;
  65. ULONG ulInfoLength;
  66. PTOKEN_GROUPS pTokenGroupList;
  67. PTOKEN_USER pTokenUser;
  68. ULONG ulGroupIndex;
  69. BOOLEAN bFoundInteractive = FALSE;
  70. PSID InteractiveSid;
  71. SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
  72. static BOOLEAN fIsInteractiveSession = 0xffff;
  73. #if 0
  74. //
  75. // Return the previous value of this function
  76. // if we're called multiple times?! Doesn't
  77. // GetCurrentProcess() return different values?
  78. //
  79. if (fIsInteractiveSession != 0xffff) {
  80. return fIsInteractiveSession;
  81. }
  82. #endif
  83. bStatus = AllocateAndInitializeSid(
  84. &NtAuthority,
  85. 1,
  86. SECURITY_INTERACTIVE_RID,
  87. 0, 0, 0, 0, 0, 0, 0,
  88. &InteractiveSid);
  89. if (!bStatus) {
  90. RASAUTO_TRACE("InteractiveSession: AllocateAndInitializeSid failed");
  91. return (fIsInteractiveSession = FALSE);
  92. }
  93. if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken)) {
  94. RASAUTO_TRACE("InteractiveSession: OpenProcessToken failed");
  95. FreeSid(InteractiveSid);
  96. return (fIsInteractiveSession = FALSE);
  97. }
  98. //
  99. // Get a list of groups in the token.
  100. //
  101. GetTokenInformation(
  102. hToken,
  103. TokenGroups,
  104. NULL,
  105. 0,
  106. &ulInfoLength);
  107. pTokenGroupList = (PTOKEN_GROUPS)LocalAlloc(LPTR, ulInfoLength);
  108. if (pTokenGroupList == NULL) {
  109. RASAUTO_TRACE("InteractiveSession: LocalAlloc failed");
  110. FreeSid(InteractiveSid);
  111. return (fIsInteractiveSession = FALSE);
  112. }
  113. bStatus = GetTokenInformation(
  114. hToken,
  115. TokenGroups,
  116. pTokenGroupList,
  117. ulInfoLength,
  118. &ulInfoLength);
  119. if (!bStatus) {
  120. RASAUTO_TRACE("InteractiveSession: GetTokenInformation failed");
  121. FreeSid(InteractiveSid);
  122. LocalFree(pTokenGroupList);
  123. return (fIsInteractiveSession = FALSE);
  124. }
  125. //
  126. // Search group list for admin alias. If we
  127. // find a match, it most certainly is an
  128. // interactive process.
  129. //
  130. bFoundInteractive = FALSE;
  131. for (ulGroupIndex=0; ulGroupIndex < pTokenGroupList->GroupCount;
  132. ulGroupIndex++)
  133. {
  134. if (EqualSid(
  135. pTokenGroupList->Groups[ulGroupIndex].Sid,
  136. InteractiveSid))
  137. {
  138. bFoundInteractive = TRUE;
  139. break;
  140. }
  141. }
  142. if (!bFoundInteractive) {
  143. //
  144. // If we haven't found a match,
  145. // query and check the user ID.
  146. //
  147. GetTokenInformation(
  148. hToken,
  149. TokenUser,
  150. NULL,
  151. 0,
  152. &ulInfoLength);
  153. pTokenUser = LocalAlloc(LPTR, ulInfoLength);
  154. if (pTokenUser == NULL) {
  155. RASAUTO_TRACE("InteractiveSession: LocalAlloc failed");
  156. FreeSid(InteractiveSid);
  157. LocalFree(pTokenGroupList);
  158. return (fIsInteractiveSession = FALSE);
  159. }
  160. bStatus = GetTokenInformation(
  161. hToken,
  162. TokenUser,
  163. pTokenUser,
  164. ulInfoLength,
  165. &ulInfoLength);
  166. if (!bStatus) {
  167. RASAUTO_TRACE("InteractiveSession: GetTokenInformation failed");
  168. FreeSid(InteractiveSid);
  169. LocalFree(pTokenGroupList);
  170. LocalFree(pTokenUser);
  171. return (fIsInteractiveSession = FALSE);
  172. }
  173. if (EqualSid(pTokenUser->User.Sid, InteractiveSid))
  174. fIsInteractiveSession = TRUE;
  175. LocalFree(pTokenUser);
  176. }
  177. FreeSid(InteractiveSid);
  178. LocalFree(pTokenGroupList);
  179. return (fIsInteractiveSession = bFoundInteractive);
  180. }
  181. #endif
  182. BOOLEAN
  183. SetProcessImpersonationToken(
  184. HANDLE hProcess
  185. )
  186. {
  187. NTSTATUS status;
  188. HANDLE hThread,
  189. hToken = NULL;
  190. //
  191. // Open the impersonation token for the
  192. // process we want to impersonate.
  193. //
  194. if (ImpersonationInfoG.hTokenImpersonation == NULL)
  195. {
  196. if (!OpenProcessToken(
  197. hProcess,
  198. TOKEN_ALL_ACCESS,
  199. &hToken))
  200. {
  201. RASAUTO_TRACE1(
  202. "SetProcessImpersonationToken: OpenProcessToken failed (dwErr=%d)",
  203. GetLastError());
  204. return FALSE;
  205. }
  206. //
  207. // Duplicate the impersonation token.
  208. //
  209. if(!DuplicateToken(
  210. hToken,
  211. TokenImpersonation,
  212. &ImpersonationInfoG.hTokenImpersonation))
  213. {
  214. RASAUTO_TRACE1(
  215. "SetProcessImpersonationToken: NtSetInformationThread failed (error=%d)",
  216. GetLastError());
  217. return FALSE;
  218. }
  219. }
  220. //
  221. // Set the impersonation token on the current
  222. // thread. We are now running in the same
  223. // security context as the supplied process.
  224. //
  225. hThread = NtCurrentThread();
  226. status = NtSetInformationThread(
  227. hThread,
  228. ThreadImpersonationToken,
  229. (PVOID)&ImpersonationInfoG.hTokenImpersonation,
  230. sizeof (ImpersonationInfoG.hTokenImpersonation));
  231. if (status != STATUS_SUCCESS)
  232. {
  233. RASAUTO_TRACE1(
  234. "SetProcessImpersonationToken: NtSetInformationThread failed (error=%d)",
  235. GetLastError());
  236. }
  237. if(NULL != hToken)
  238. {
  239. CloseHandle(hToken);
  240. }
  241. return (status == STATUS_SUCCESS);
  242. } // SetProcessImpersonationToken
  243. VOID
  244. ClearImpersonationToken()
  245. {
  246. //
  247. // Clear the impersonation token on the current
  248. // thread. We are now running in LocalSystem
  249. // security context.
  250. //
  251. if (!SetThreadToken(NULL, NULL)) {
  252. DWORD retcode = GetLastError();
  253. RASAUTO_TRACE1(
  254. "ClearImpersonationToken: SetThreadToken failed (error=%d)",
  255. retcode);
  256. //
  257. // Event log that thread failed to revert.
  258. //
  259. RouterLogWarning(
  260. g_hLogEvent,
  261. ROUTERLOG_CANNOT_REVERT_IMPERSONATION,
  262. 0, NULL, retcode) ;
  263. }
  264. } // ClearImpersonationToken
  265. BOOLEAN
  266. SetPrivilege(
  267. HANDLE hToken,
  268. LPCTSTR Privilege,
  269. BOOLEAN fEnable
  270. )
  271. {
  272. TOKEN_PRIVILEGES tp;
  273. LUID luid;
  274. TOKEN_PRIVILEGES tpPrevious;
  275. DWORD cbPrevious = sizeof(TOKEN_PRIVILEGES);
  276. if (!LookupPrivilegeValue(NULL, Privilege, &luid))
  277. return FALSE;
  278. //
  279. // First pass. Get current privilege setting.
  280. //
  281. tp.PrivilegeCount = 1;
  282. tp.Privileges[0].Luid = luid;
  283. tp.Privileges[0].Attributes = 0;
  284. AdjustTokenPrivileges(
  285. hToken,
  286. FALSE,
  287. &tp,
  288. sizeof(TOKEN_PRIVILEGES),
  289. &tpPrevious,
  290. &cbPrevious);
  291. if (GetLastError() != ERROR_SUCCESS)
  292. return FALSE;
  293. //
  294. // Second pass. Set privilege based on previous setting
  295. //
  296. tpPrevious.PrivilegeCount = 1;
  297. tpPrevious.Privileges[0].Luid = luid;
  298. if (fEnable)
  299. tpPrevious.Privileges[0].Attributes |= (SE_PRIVILEGE_ENABLED);
  300. else {
  301. tpPrevious.Privileges[0].Attributes ^= (SE_PRIVILEGE_ENABLED &
  302. tpPrevious.Privileges[0].Attributes);
  303. }
  304. AdjustTokenPrivileges(
  305. hToken,
  306. FALSE,
  307. &tpPrevious,
  308. cbPrevious,
  309. NULL,
  310. NULL);
  311. if (GetLastError() != ERROR_SUCCESS)
  312. return FALSE;
  313. return TRUE;
  314. } // SetPrivilege
  315. BOOLEAN
  316. GetCurrentlyLoggedOnUser(
  317. HANDLE *phProcess
  318. )
  319. {
  320. BOOLEAN fSuccess = FALSE;
  321. HKEY hkey;
  322. DWORD dwErr, dwType;
  323. DWORD dwDisp;
  324. WCHAR *pszShell = NULL, **pszShellArray = NULL;
  325. PSYSTEM_PROCESS_INFORMATION pSystemInfo, pProcessInfo;
  326. PWCHAR psz, pszStart;
  327. DWORD i, dwSize, dwcCommands;
  328. NTSTATUS status;
  329. HANDLE hProcess = NULL;
  330. DWORD dwPid = 0;
  331. //
  332. // Get the shell process name. We will look for this
  333. // to find out who the currently logged-on user is.
  334. // Create a unicode string that describes this name.
  335. //
  336. if (RegCreateKeyEx(
  337. HKEY_LOCAL_MACHINE,
  338. SHELL_REGKEY,
  339. 0,
  340. NULL,
  341. REG_OPTION_NON_VOLATILE,
  342. KEY_ALL_ACCESS,
  343. NULL,
  344. &hkey,
  345. &dwDisp) == ERROR_SUCCESS)
  346. {
  347. dwSize = 0;
  348. if (RegQueryValueEx(
  349. hkey,
  350. SHELL_REGVAL,
  351. NULL,
  352. &dwType,
  353. NULL,
  354. &dwSize) == ERROR_SUCCESS)
  355. {
  356. pszShell = (PWCHAR)LocalAlloc(LPTR, dwSize + sizeof (WCHAR));
  357. if (pszShell == NULL) {
  358. RegCloseKey(hkey);
  359. return FALSE;
  360. }
  361. dwErr = RegQueryValueEx(
  362. hkey,
  363. SHELL_REGVAL,
  364. NULL,
  365. &dwType,
  366. (LPBYTE)pszShell,
  367. &dwSize);
  368. RegCloseKey(hkey);
  369. if (dwErr != ERROR_SUCCESS || dwType != REG_SZ) {
  370. LocalFree(pszShell);
  371. pszShell = NULL;
  372. }
  373. }
  374. }
  375. //
  376. // If no shell was found, use DEFAULT_SHELL.
  377. //
  378. if (pszShell == NULL) {
  379. pszShell = (PWCHAR)LocalAlloc(
  380. LPTR,
  381. (lstrlen(DEFAULT_SHELL) + 1) * sizeof (WCHAR));
  382. if (pszShell == NULL)
  383. return FALSE;
  384. lstrcpy(pszShell, DEFAULT_SHELL);
  385. }
  386. RASAUTO_TRACE1("ImpersonateCurrentlyLoggedInUser: pszShell is %S", pszShell);
  387. //
  388. // This string can be a comma separated list,
  389. // so we need to parse it into a list of commands.
  390. //
  391. dwcCommands = 1;
  392. for (psz = pszShell; *psz != L'\0'; psz++) {
  393. if (*psz == L',')
  394. dwcCommands++;
  395. }
  396. //
  397. // Allocate the list of string pointers.
  398. //
  399. pszShellArray = LocalAlloc(LPTR, sizeof (PWCHAR) * dwcCommands);
  400. if (pszShellArray == NULL) {
  401. LocalFree(pszShell);
  402. return FALSE;
  403. }
  404. //
  405. // Ignore any arguments from the command line.
  406. //
  407. dwcCommands = 0;
  408. psz = pszShell;
  409. pszStart = NULL;
  410. for (;;) {
  411. if (*psz == L'\0') {
  412. if (pszStart != NULL)
  413. pszShellArray[dwcCommands++] = pszStart;
  414. break;
  415. }
  416. else if (*psz == L',') {
  417. if (pszStart != NULL)
  418. pszShellArray[dwcCommands++] = pszStart;
  419. *psz = L'\0';
  420. pszStart = NULL;
  421. }
  422. else if (*psz == L' ') {
  423. if (pszStart != NULL)
  424. *psz = L'\0';
  425. }
  426. else {
  427. if (pszStart == NULL)
  428. pszStart = psz;
  429. }
  430. psz++;
  431. }
  432. for (i = 0; i < dwcCommands; i++) {
  433. RASAUTO_TRACE2(
  434. "ImpersonateCurrentlyLoggedInUser: pszShellArray[%d] is %S",
  435. i,
  436. pszShellArray[i]);
  437. }
  438. //
  439. // Get the process list.
  440. //
  441. pSystemInfo = GetSystemProcessInfo();
  442. if(NULL == pSystemInfo)
  443. {
  444. LocalFree(pszShell);
  445. LocalFree(pszShellArray);
  446. return FALSE;
  447. }
  448. while(TRUE)
  449. {
  450. //
  451. // See if any of the processes are running.
  452. //
  453. pProcessInfo =
  454. FindProcessByNameList(
  455. pSystemInfo,
  456. pszShellArray,
  457. dwcCommands,
  458. dwPid,
  459. ImpersonationInfoG.fSessionInitialized,
  460. ImpersonationInfoG.dwCurSessionId);
  461. //
  462. // Open the process token if we've found a match.
  463. //
  464. if (pProcessInfo != NULL)
  465. {
  466. HANDLE hToken;
  467. //
  468. // Open the process.
  469. //
  470. hProcess = OpenProcess(
  471. PROCESS_ALL_ACCESS,
  472. FALSE,
  473. PtrToUlong(pProcessInfo->UniqueProcessId));
  474. if (hProcess == NULL)
  475. {
  476. RASAUTO_TRACE2(
  477. "ImpersonateCurrentlyLoggedInUser: OpenProcess(%d) failed (dwErr=%d)",
  478. PtrToUlong(pProcessInfo->UniqueProcessId),
  479. GetLastError());
  480. dwPid = PtrToUlong(pProcessInfo->UniqueProcessId);
  481. }
  482. else
  483. {
  484. fSuccess = TRUE;
  485. break;
  486. }
  487. }
  488. else
  489. {
  490. break;
  491. }
  492. }
  493. #ifdef notdef
  494. done:
  495. #endif
  496. //
  497. // Free resources.
  498. //
  499. FreeSystemProcessInfo(pSystemInfo);
  500. if (pszShell != NULL)
  501. LocalFree(pszShell);
  502. if (pszShellArray != NULL)
  503. LocalFree(pszShellArray);
  504. //
  505. // Return process handle.
  506. //
  507. *phProcess = hProcess;
  508. return fSuccess;
  509. } // GetCurrentlyLoggedOnUser
  510. DWORD
  511. SetCurrentLoginSession(
  512. IN DWORD dwSessionId)
  513. {
  514. RASAUTO_TRACE1("SetCurrentLoginSession %d", dwSessionId);
  515. EnterCriticalSection(&ImpersonationInfoG.csLock);
  516. ImpersonationInfoG.dwCurSessionId = dwSessionId;
  517. ImpersonationInfoG.fSessionInitialized = TRUE;
  518. LeaveCriticalSection(&ImpersonationInfoG.csLock);
  519. return NO_ERROR;
  520. }
  521. HANDLE
  522. RefreshImpersonation(
  523. HANDLE hProcess
  524. )
  525. {
  526. NTSTATUS status;
  527. EnterCriticalSection(&ImpersonationInfoG.csLock);
  528. //
  529. // If the process still exists,
  530. // we can return.
  531. //
  532. if (ImpersonationInfoG.hProcess != NULL &&
  533. hProcess == ImpersonationInfoG.hProcess)
  534. {
  535. RASAUTO_TRACE1("RefreshImpersonation: hProcess=0x%x no change", hProcess);
  536. goto done;
  537. }
  538. //
  539. // Otherwise recalcuate the current information.
  540. // We have to clear the previous impersonation token,
  541. // if any.
  542. //
  543. if (hProcess != NULL)
  544. ClearImpersonationToken();
  545. if (ImpersonationInfoG.hProcess == NULL) {
  546. RASAUTO_TRACE("RefreshImpersonation: recalcuating token");
  547. if (!GetCurrentlyLoggedOnUser(&ImpersonationInfoG.hProcess)) {
  548. RASAUTO_TRACE("RefreshImpersonation: GetCurrentlyLoggedOnUser failed");
  549. goto done;
  550. }
  551. RASAUTO_TRACE("RefreshImpersonation: new user logged in");
  552. }
  553. //
  554. // Impersonate the currently logged-in user.
  555. //
  556. if (!SetProcessImpersonationToken(ImpersonationInfoG.hProcess))
  557. {
  558. RASAUTO_TRACE(
  559. "RefreshImpersonation: SetProcessImpersonationToken failed");
  560. goto done;
  561. }
  562. #ifdef notdef // imperson
  563. //
  564. // Reset HKEY_CURRENT_USER to get the
  565. // correct value with the new impersonation
  566. // token.
  567. //
  568. RegCloseKey(HKEY_CURRENT_USER);
  569. #endif
  570. RASAUTO_TRACE1(
  571. "RefreshImpersonation: new hProcess=0x%x",
  572. ImpersonationInfoG.hProcess);
  573. TraceCurrentUser();
  574. //
  575. // Open the currently logged on users hive and store it in a global
  576. //
  577. if(NULL != hkeyCUG)
  578. {
  579. NtClose(hkeyCUG);
  580. hkeyCUG = NULL;
  581. }
  582. if(STATUS_SUCCESS != RtlOpenCurrentUser(KEY_ALL_ACCESS, &hkeyCUG))
  583. {
  584. RASAUTO_TRACE("Failed to open HKCU for the current user");
  585. }
  586. done:
  587. LeaveCriticalSection(&ImpersonationInfoG.csLock);
  588. return ImpersonationInfoG.hProcess;
  589. } // RefreshImpersonation
  590. VOID
  591. RevertImpersonation()
  592. /*++
  593. DESCRIPTION
  594. Close all open handles associated with the
  595. logged-in user who has just logged out.
  596. ARGUMENTS
  597. None.
  598. RETURN VALUE
  599. None.
  600. --*/
  601. {
  602. EnterCriticalSection(&ImpersonationInfoG.csLock);
  603. if(ImpersonationInfoG.hToken != NULL)
  604. {
  605. CloseHandle(ImpersonationInfoG.hToken);
  606. ImpersonationInfoG.hToken = NULL;
  607. }
  608. if(ImpersonationInfoG.hTokenImpersonation != NULL)
  609. {
  610. CloseHandle(ImpersonationInfoG.hTokenImpersonation);
  611. ImpersonationInfoG.hTokenImpersonation = NULL;
  612. }
  613. if(ImpersonationInfoG.hProcess != NULL)
  614. {
  615. CloseHandle(ImpersonationInfoG.hProcess);
  616. ImpersonationInfoG.hProcess = NULL;
  617. }
  618. ImpersonationInfoG.fGroupsLoaded = FALSE;
  619. if(NULL != hkeyCUG)
  620. {
  621. NtClose(hkeyCUG);
  622. hkeyCUG = NULL;
  623. }
  624. //
  625. // Clear the thread's impersonation
  626. // token, or it won't be able to open
  627. // another user's process the next
  628. // time around.
  629. //
  630. ClearImpersonationToken();
  631. LeaveCriticalSection(&ImpersonationInfoG.csLock);
  632. } // RevertImpersonation
  633. DWORD
  634. InitSecurityDescriptor(
  635. IN PSECURITY_DESCRIPTOR pSecurityDescriptor
  636. )
  637. /*++
  638. DESCRIPTION
  639. Initialize a security descriptor allowing administrator
  640. access for the sharing of handles between rasman.dll.
  641. This code courtesy of Gurdeep. You need to ask him
  642. exactly what it does.
  643. ARGUMENTS
  644. pSecurityDescriptor: a pointer to the security descriptor
  645. to be initialized.
  646. RETURN VALUE
  647. Win32 error code.
  648. --*/
  649. {
  650. DWORD dwErr = 0;
  651. DWORD cbDaclSize;
  652. PULONG pSubAuthority;
  653. PSID pObjSid = NULL;
  654. PACL pDacl = NULL;
  655. SID_IDENTIFIER_AUTHORITY sidIdentifierWorldAuth =
  656. SECURITY_WORLD_SID_AUTHORITY;
  657. DWORD dwAcls;
  658. //
  659. // Set up the SID for the adminstrators that
  660. // will be allowed access. This SID will have
  661. // 1 sub-authorities: SECURITY_BUILTIN_DOMAIN_RID.
  662. //
  663. pObjSid = (PSID)LocalAlloc(LPTR, GetSidLengthRequired(1));
  664. if (pObjSid == NULL) {
  665. RASAUTO_TRACE("InitSecurityDescriptor: LocalAlloc failed");
  666. return GetLastError();
  667. }
  668. if (!InitializeSid(pObjSid, &sidIdentifierWorldAuth, 1)) {
  669. dwErr = GetLastError();
  670. RASAUTO_TRACE1("InitSecurityDescriptor: InitializeSid failed (dwErr=0x%x)", dwErr);
  671. goto done;
  672. }
  673. //
  674. // Set the sub-authorities.
  675. //
  676. pSubAuthority = GetSidSubAuthority(pObjSid, 0);
  677. *pSubAuthority = SECURITY_WORLD_RID;
  678. //
  679. // Set up the DACL that will allow
  680. // all processes with the above SID all
  681. // access. It should be large enough to
  682. // hold all ACEs.
  683. //
  684. cbDaclSize = sizeof(ACCESS_ALLOWED_ACE) +
  685. GetLengthSid(pObjSid) +
  686. sizeof (ACL);
  687. pDacl = (PACL)LocalAlloc(LPTR, cbDaclSize);
  688. if (pDacl == NULL ) {
  689. RASAUTO_TRACE("InitSecurityDescriptor: LocalAlloc failed");
  690. dwErr = GetLastError();
  691. goto done;
  692. }
  693. if (!InitializeAcl(pDacl, cbDaclSize, ACL_REVISION2)) {
  694. dwErr = GetLastError();
  695. RASAUTO_TRACE1("InitSecurityDescriptor: InitializeAcl failed (dwErr=0x%x)", dwErr);
  696. goto done;
  697. }
  698. dwAcls = SPECIFIC_RIGHTS_ALL | STANDARD_RIGHTS_ALL;
  699. dwAcls &= ~(WRITE_DAC | WRITE_OWNER);
  700. //
  701. // Add the ACE to the DACL
  702. //
  703. if (!AddAccessAllowedAce(
  704. pDacl,
  705. ACL_REVISION2,
  706. dwAcls,
  707. pObjSid))
  708. {
  709. dwErr = GetLastError();
  710. RASAUTO_TRACE1("InitSecurityDescriptor: AddAccessAllowedAce failed (dwErr=0x%x)", dwErr);
  711. goto done;
  712. }
  713. //
  714. // Create the security descriptor an put
  715. // the DACL in it.
  716. //
  717. if (!InitializeSecurityDescriptor(pSecurityDescriptor, 1)) {
  718. dwErr = GetLastError();
  719. RASAUTO_TRACE1("InitSecurityDescriptor: InitializeSecurityDescriptor failed (dwErr=0x%x)", dwErr);
  720. goto done;
  721. }
  722. if (!SetSecurityDescriptorDacl(
  723. pSecurityDescriptor,
  724. TRUE,
  725. pDacl,
  726. FALSE))
  727. {
  728. dwErr = GetLastError();
  729. RASAUTO_TRACE1("InitSecurityDescriptor: SetSecurityDescriptorDacl failed (dwErr=0x%x)", dwErr);
  730. goto done;
  731. }
  732. //
  733. // Set owner for the descriptor.
  734. //
  735. if (!SetSecurityDescriptorOwner(pSecurityDescriptor, NULL, FALSE)) {
  736. dwErr = GetLastError();
  737. RASAUTO_TRACE1("InitSecurityDescriptor: SetSecurityDescriptorOwner failed (dwErr=0x%x)", dwErr);
  738. goto done;
  739. }
  740. //
  741. // Set group for the descriptor.
  742. //
  743. if (!SetSecurityDescriptorGroup(pSecurityDescriptor, NULL, FALSE)) {
  744. dwErr = GetLastError();
  745. RASAUTO_TRACE1("InitSecurityDescriptor: SetSecurityDescriptorGroup failed (dwErr=0x%x)", dwErr);
  746. goto done;
  747. }
  748. done:
  749. //
  750. // Cleanup if necessary.
  751. //
  752. if (dwErr) {
  753. if (pObjSid != NULL)
  754. LocalFree(pObjSid);
  755. if (pDacl != NULL)
  756. LocalFree(pDacl);
  757. }
  758. return dwErr;
  759. }
  760. DWORD
  761. InitSecurityAttribute()
  762. /*++
  763. DESCRIPTION
  764. Initializes the global security attribute used in
  765. creating shareable handles.
  766. This code courtesy of Gurdeep. You need to ask him
  767. exactly what it does.
  768. ARGUMENTS
  769. None.
  770. RETURN VALUE
  771. Win32 error code.
  772. --*/
  773. {
  774. DWORD dwErr;
  775. //
  776. // Initialize the security descriptor.
  777. //
  778. dwErr = InitSecurityDescriptor(&SecurityDescriptorG);
  779. if (dwErr)
  780. return dwErr;
  781. //
  782. // Initialize the security attributes.
  783. //
  784. SecurityAttributeG.nLength = sizeof(SECURITY_ATTRIBUTES);
  785. SecurityAttributeG.lpSecurityDescriptor = &SecurityDescriptorG;
  786. SecurityAttributeG.bInheritHandle = TRUE;
  787. return 0;
  788. }
  789. VOID
  790. TraceCurrentUser(VOID)
  791. {
  792. //WCHAR szUserName[512];
  793. //DWORD dwSize = sizeof (szUserName) - 1;
  794. //GetUserName(szUserName, &dwSize);
  795. RASAUTO_TRACE1(
  796. "TraceCurrentUser: impersonating Current User %d",
  797. ImpersonationInfoG.dwCurSessionId);
  798. } // TraceCurrentUser
  799. DWORD
  800. DwGetHkcu()
  801. {
  802. DWORD dwErr = ERROR_SUCCESS;
  803. if(NULL == hkeyCUG)
  804. {
  805. dwErr = RtlOpenCurrentUser(
  806. KEY_ALL_ACCESS,
  807. &hkeyCUG);
  808. if(ERROR_SUCCESS != dwErr)
  809. {
  810. RASAUTO_TRACE1("DwGetHhcu: failed to open current user. 0x%x",
  811. dwErr);
  812. goto done;
  813. }
  814. }
  815. done:
  816. return dwErr;
  817. }
  818. DWORD
  819. InitializeImpersonation()
  820. /*++
  821. DESCRIPTION
  822. Initializes the global structures used for impersonation
  823. ARGUMENTS
  824. None
  825. RETURN VALUE
  826. Win32 error code.
  827. --*/
  828. {
  829. DWORD dwError = ERROR_SUCCESS;
  830. if (!ImpersonationInfoInitializedG)
  831. {
  832. ZeroMemory(&ImpersonationInfoG, sizeof(ImpersonationInfoG));
  833. RasInitializeCriticalSection(&ImpersonationInfoG.csLock, &dwError);
  834. if(dwError != ERROR_SUCCESS)
  835. {
  836. return dwError;
  837. }
  838. g_dwCritSecFlags |= RASAUTO_CRITSEC_IMPERSON;
  839. ImpersonationInfoInitializedG = TRUE;
  840. }
  841. return dwError;
  842. }
  843. VOID
  844. CleanupImpersonation()
  845. /*++
  846. DESCRIPTION
  847. Cleans up the global structures used for impersonation
  848. ARGUMENTS
  849. None
  850. RETURN VALUE
  851. None
  852. --*/
  853. {
  854. if (ImpersonationInfoInitializedG)
  855. {
  856. EnterCriticalSection(&ImpersonationInfoG.csLock);
  857. if (NULL != ImpersonationInfoG.pGuestSid)
  858. {
  859. FreeSid(ImpersonationInfoG.pGuestSid);
  860. ImpersonationInfoG.pGuestSid = NULL;
  861. }
  862. LeaveCriticalSection(&ImpersonationInfoG.csLock);
  863. DeleteCriticalSection(&ImpersonationInfoG.csLock);
  864. g_dwCritSecFlags &= ~(RASAUTO_CRITSEC_IMPERSON);
  865. ImpersonationInfoInitializedG = FALSE;
  866. }
  867. }
  868. BOOLEAN
  869. ImpersonatingGuest()
  870. /*++
  871. DESCRIPTION
  872. Returns whether or not the user that is currently being impersonating
  873. is a member of the local guests group
  874. ARGUMENTS
  875. None
  876. RETURN VALUE
  877. BOOLEAN -- TRUE if currently impersonating a guests, FALSE otherwise
  878. --*/
  879. {
  880. BOOLEAN fIsGuest = FALSE;
  881. ASSERT(ImpersonationInfoInitializedG);
  882. EnterCriticalSection(&ImpersonationInfoG.csLock);
  883. if (ERROR_SUCCESS == LoadGroupMemberships())
  884. {
  885. fIsGuest = ImpersonationInfoG.fGuest;
  886. }
  887. LeaveCriticalSection(&ImpersonationInfoG.csLock);
  888. return fIsGuest;
  889. }
  890. DWORD
  891. LoadGroupMemberships()
  892. /*++
  893. DESCRIPTION
  894. Caches the group membership information for the impersonated user.
  895. ARGUMENTS
  896. None
  897. RETURN VALUE
  898. Win32 error code.
  899. --*/
  900. {
  901. DWORD dwError = ERROR_SUCCESS;
  902. SID_IDENTIFIER_AUTHORITY IdentifierAuthority = SECURITY_NT_AUTHORITY;
  903. BOOL fIsGuest;
  904. EnterCriticalSection(&ImpersonationInfoG.csLock);
  905. do
  906. {
  907. if (ImpersonationInfoG.fGroupsLoaded)
  908. {
  909. //
  910. // Information already loaded
  911. //
  912. break;
  913. }
  914. if (NULL == ImpersonationInfoG.hTokenImpersonation)
  915. {
  916. //
  917. // There isn't an impersonated user.
  918. //
  919. dwError = ERROR_CAN_NOT_COMPLETE;
  920. break;
  921. }
  922. if (NULL == ImpersonationInfoG.pGuestSid)
  923. {
  924. //
  925. // Allocate the SID for the local guests group;
  926. //
  927. if (!AllocateAndInitializeSid(
  928. &IdentifierAuthority,
  929. 2,
  930. SECURITY_BUILTIN_DOMAIN_RID,
  931. DOMAIN_ALIAS_RID_GUESTS,
  932. 0,
  933. 0,
  934. 0,
  935. 0,
  936. 0,
  937. 0,
  938. &ImpersonationInfoG.pGuestSid
  939. ))
  940. {
  941. dwError = GetLastError();
  942. break;
  943. }
  944. }
  945. if (!CheckTokenMembership(
  946. ImpersonationInfoG.hTokenImpersonation,
  947. ImpersonationInfoG.pGuestSid,
  948. &fIsGuest
  949. ))
  950. {
  951. dwError = GetLastError();
  952. break;
  953. }
  954. ImpersonationInfoG.fGuest = !!fIsGuest;
  955. } while (FALSE);
  956. LeaveCriticalSection(&ImpersonationInfoG.csLock);
  957. return dwError;
  958. }
  959. VOID
  960. LockImpersonation()
  961. {
  962. ASSERT(ImpersonationInfoInitializedG);
  963. if(ImpersonationInfoInitializedG)
  964. {
  965. EnterCriticalSection(&ImpersonationInfoG.csLock);
  966. }
  967. }
  968. VOID
  969. UnlockImpersonation()
  970. {
  971. ASSERT(ImpersonationInfoInitializedG);
  972. if(ImpersonationInfoInitializedG)
  973. {
  974. LeaveCriticalSection(&ImpersonationInfoG.csLock);
  975. }
  976. }