Source code of Windows XP (NT5)
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.

975 lines
22 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. users.c
  5. Abstract:
  6. Creates user profiles and enumerates users
  7. Author:
  8. Jim Schmidt (jimschm) 15-May-2000
  9. Revision History:
  10. <alias> <date> <comments>
  11. --*/
  12. //
  13. // Includes
  14. //
  15. #include "pch.h"
  16. #include "ism.h"
  17. #include "ismp.h"
  18. #define DBG_ISMUSERS "IsmUsers"
  19. //
  20. // Strings
  21. //
  22. #define S_TEMP_HKCU TEXT("$HKCU$")
  23. //
  24. // Constants
  25. //
  26. // None
  27. //
  28. // Macros
  29. //
  30. // None
  31. //
  32. // Types
  33. //
  34. typedef BOOL (WINAPI GETDEFAULTUSERPROFILEDIRECTORY)(PTSTR ProfileDir, PDWORD Size);
  35. typedef GETDEFAULTUSERPROFILEDIRECTORY * PGETDEFAULTUSERPROFILEDIRECTORY;
  36. typedef BOOL (WINAPI GETPROFILESDIRECTORY)(PTSTR ProfileDir, PDWORD Size);
  37. typedef GETPROFILESDIRECTORY * PGETPROFILESDIRECTORY;
  38. typedef LONG (WINAPI REGOVERRIDEPREDEFKEY)(HKEY hKey, HKEY hNewHKey);
  39. typedef REGOVERRIDEPREDEFKEY * PREGOVERRIDEPREDEFKEY;
  40. typedef BOOL (WINAPI CONVERTSIDTOSTRINGSID)(PSID Sid, PTSTR *SidString);
  41. typedef CONVERTSIDTOSTRINGSID * PCONVERTSIDTOSTRINGSID;
  42. typedef BOOL (WINAPI CREATEUSERPROFILE)(
  43. PSID Sid,
  44. PCTSTR UserName,
  45. PCTSTR UserHive,
  46. PTSTR ProfileDir,
  47. DWORD DirSize,
  48. BOOL IsWin9xUpgrade
  49. );
  50. typedef CREATEUSERPROFILE * PCREATEUSERPROFILE;
  51. typedef BOOL (WINAPI OLDCREATEUSERPROFILE)(
  52. PSID Sid,
  53. PCTSTR UserName,
  54. PCTSTR UserHive,
  55. PTSTR ProfileDir,
  56. DWORD DirSize
  57. );
  58. typedef OLDCREATEUSERPROFILE * POLDCREATEUSERPROFILE;
  59. typedef BOOL (WINAPI GETUSERPROFILEDIRECTORY)(HANDLE hToken, PTSTR lpProfileDir, PDWORD lpcchSize);
  60. typedef GETUSERPROFILEDIRECTORY * PGETUSERPROFILEDIRECTORY;
  61. typedef BOOL (WINAPI DELETEPROFILE)(PCTSTR lpSidString, PCTSTR lpProfilePath, PCTSTR lpComputerName);
  62. typedef DELETEPROFILE * PDELETEPROFILE;
  63. //
  64. // Globals
  65. //
  66. PTEMPORARYPROFILE g_CurrentOverrideUser;
  67. //
  68. // Macro expansion list
  69. //
  70. // None
  71. //
  72. // Private function prototypes
  73. //
  74. // None
  75. //
  76. // Macro expansion definition
  77. //
  78. // None
  79. //
  80. // Code
  81. //
  82. HANDLE
  83. pGetUserEnvLib (
  84. VOID
  85. )
  86. {
  87. static HANDLE lib;
  88. if (lib) {
  89. return lib;
  90. }
  91. lib = LoadLibrary (TEXT("userenv.dll"));
  92. if (!lib) {
  93. LOG ((LOG_MODULE_ERROR, (PCSTR) MSG_CANT_LOAD_USERENV));
  94. }
  95. return lib;
  96. }
  97. HANDLE
  98. pGetAdvApi32Lib (
  99. VOID
  100. )
  101. {
  102. static HANDLE lib;
  103. if (lib) {
  104. return lib;
  105. }
  106. lib = LoadLibrary (TEXT("advapi32.dll"));
  107. if (!lib) {
  108. LOG ((LOG_MODULE_ERROR, (PCSTR) MSG_CANT_LOAD_ADVAPI32));
  109. }
  110. return lib;
  111. }
  112. BOOL
  113. pOurGetDefaultUserProfileDirectory (
  114. OUT PTSTR ProfileDir,
  115. IN OUT PDWORD Size
  116. )
  117. {
  118. HANDLE lib;
  119. PGETDEFAULTUSERPROFILEDIRECTORY getDefaultUserProfileDirectory;
  120. lib = pGetUserEnvLib();
  121. if (!lib) {
  122. return FALSE;
  123. }
  124. #ifdef UNICODE
  125. getDefaultUserProfileDirectory = (PGETDEFAULTUSERPROFILEDIRECTORY) GetProcAddress (lib, "GetDefaultUserProfileDirectoryW");
  126. #else
  127. getDefaultUserProfileDirectory = (PGETDEFAULTUSERPROFILEDIRECTORY) GetProcAddress (lib, "GetDefaultUserProfileDirectoryA");
  128. #endif
  129. if (!getDefaultUserProfileDirectory) {
  130. LOG ((LOG_MODULE_ERROR, (PCSTR) MSG_CANT_FIND_GETDEFAULTUSERPROFILEDIRECTORY));
  131. return FALSE;
  132. }
  133. return getDefaultUserProfileDirectory (ProfileDir, Size);
  134. }
  135. BOOL
  136. pOurGetProfilesDirectory (
  137. OUT PTSTR ProfileDir,
  138. IN OUT PDWORD Size
  139. )
  140. {
  141. HANDLE lib;
  142. PGETPROFILESDIRECTORY getProfilesDirectory;
  143. lib = pGetUserEnvLib();
  144. if (!lib) {
  145. return FALSE;
  146. }
  147. #ifdef UNICODE
  148. getProfilesDirectory = (PGETPROFILESDIRECTORY) GetProcAddress (lib, "GetProfilesDirectoryW");
  149. #else
  150. getProfilesDirectory = (PGETPROFILESDIRECTORY) GetProcAddress (lib, "GetProfilesDirectoryA");
  151. #endif
  152. if (!getProfilesDirectory) {
  153. LOG ((LOG_MODULE_ERROR, (PCSTR) MSG_CANT_FIND_GETPROFILESDIRECTORY));
  154. return FALSE;
  155. }
  156. return getProfilesDirectory (ProfileDir, Size);
  157. }
  158. LONG
  159. pOurConvertSidToStringSid (
  160. IN PSID Sid,
  161. IN PTSTR *SidString
  162. )
  163. {
  164. HANDLE lib;
  165. PCONVERTSIDTOSTRINGSID convertSidToStringSid;
  166. BOOL result = FALSE;
  167. DWORD error;
  168. lib = pGetAdvApi32Lib();
  169. if (!lib) {
  170. error = GetLastError();
  171. if (error == ERROR_SUCCESS) {
  172. SetLastError (ERROR_PROC_NOT_FOUND);
  173. }
  174. } else {
  175. #ifdef UNICODE
  176. convertSidToStringSid = (PCONVERTSIDTOSTRINGSID) GetProcAddress(lib, "ConvertSidToStringSidW");
  177. #else
  178. convertSidToStringSid = (PCONVERTSIDTOSTRINGSID) GetProcAddress(lib, "ConvertSidToStringSidA");
  179. #endif
  180. if (convertSidToStringSid) {
  181. result = convertSidToStringSid (Sid, SidString);
  182. }
  183. }
  184. return result;
  185. }
  186. BOOL
  187. pOurGetUserProfileDirectory (
  188. IN HANDLE Token,
  189. IN PTSTR ProfileDir,
  190. IN PDWORD ProfileDirSize
  191. )
  192. {
  193. HANDLE lib;
  194. PGETUSERPROFILEDIRECTORY getUserProfileDirectory;
  195. BOOL result = FALSE;
  196. DWORD error;
  197. lib = pGetUserEnvLib();
  198. if (!lib) {
  199. error = GetLastError();
  200. if (error == ERROR_SUCCESS) {
  201. SetLastError (ERROR_PROC_NOT_FOUND);
  202. }
  203. } else {
  204. #ifdef UNICODE
  205. getUserProfileDirectory = (PGETUSERPROFILEDIRECTORY) GetProcAddress (lib, "GetUserProfileDirectoryW");
  206. #else
  207. getUserProfileDirectory = (PGETUSERPROFILEDIRECTORY) GetProcAddress (lib, "GetUserProfileDirectoryA");
  208. #endif
  209. if (getUserProfileDirectory) {
  210. result = getUserProfileDirectory (Token, ProfileDir, ProfileDirSize);
  211. }
  212. }
  213. return result;
  214. }
  215. BOOL
  216. pOurDeleteProfile (
  217. IN PCTSTR UserStringSid,
  218. IN PCTSTR UserProfilePath,
  219. IN PCTSTR ComputerName
  220. )
  221. {
  222. HANDLE lib;
  223. PDELETEPROFILE deleteProfile;
  224. BOOL result = FALSE;
  225. DWORD error;
  226. lib = pGetUserEnvLib();
  227. if (!lib) {
  228. error = GetLastError();
  229. if (error == ERROR_SUCCESS) {
  230. SetLastError (ERROR_PROC_NOT_FOUND);
  231. }
  232. } else {
  233. #ifdef UNICODE
  234. deleteProfile = (PDELETEPROFILE) GetProcAddress (lib, "DeleteProfileW");
  235. #else
  236. deleteProfile = (PDELETEPROFILE) GetProcAddress (lib, "DeleteProfileA");
  237. #endif
  238. if (deleteProfile) {
  239. result = deleteProfile (UserStringSid, UserProfilePath, ComputerName);
  240. }
  241. }
  242. return result;
  243. }
  244. LONG
  245. pOurRegOverridePredefKey (
  246. IN HKEY hKey,
  247. IN HKEY hNewHKey
  248. )
  249. {
  250. HANDLE lib;
  251. PREGOVERRIDEPREDEFKEY regOverridePredefKey;
  252. LONG result;
  253. lib = pGetAdvApi32Lib();
  254. if (!lib) {
  255. result = GetLastError();
  256. if (result == ERROR_SUCCESS) {
  257. result = ERROR_PROC_NOT_FOUND;
  258. }
  259. } else {
  260. regOverridePredefKey = (PREGOVERRIDEPREDEFKEY) GetProcAddress (lib, "RegOverridePredefKey");
  261. if (!regOverridePredefKey) {
  262. result = GetLastError();
  263. } else {
  264. result = regOverridePredefKey (hKey, hNewHKey);
  265. }
  266. }
  267. return result;
  268. }
  269. BOOL
  270. pOurCreateUserProfile (
  271. IN PSID Sid,
  272. IN PCTSTR UserName,
  273. IN PCTSTR UserHive,
  274. OUT PTSTR ProfileDir,
  275. IN DWORD DirSize
  276. )
  277. {
  278. HANDLE lib;
  279. PCREATEUSERPROFILE createUserProfile;
  280. POLDCREATEUSERPROFILE oldCreateUserProfile;
  281. MIG_OSVERSIONINFO versionInfo;
  282. BOOL useNew = FALSE;
  283. lib = pGetUserEnvLib();
  284. if (!lib) {
  285. return FALSE;
  286. }
  287. if (IsmGetOsVersionInfo (g_IsmCurrentPlatform, &versionInfo)) {
  288. if ((versionInfo.OsMajorVersion > OSMAJOR_WINNT5) ||
  289. (versionInfo.OsMajorVersion == OSMAJOR_WINNT5 &&
  290. ((versionInfo.OsMinorVersion > OSMINOR_WINNT51) ||
  291. ((versionInfo.OsMinorVersion == OSMINOR_WINNT51) &&
  292. (versionInfo.OsBuildNumber >= 2464))))) {
  293. useNew = TRUE;
  294. }
  295. }
  296. if (useNew) {
  297. #ifdef UNICODE
  298. createUserProfile = (PCREATEUSERPROFILE) GetProcAddress (lib, (PCSTR) 154);
  299. #else
  300. createUserProfile = (PCREATEUSERPROFILE) GetProcAddress (lib, (PCSTR) 153);
  301. #endif
  302. if (!createUserProfile) {
  303. LOG ((LOG_MODULE_ERROR, (PCSTR) MSG_CANT_FIND_CREATEUSERPROFILE));
  304. return FALSE;
  305. }
  306. return createUserProfile (
  307. Sid,
  308. UserName,
  309. UserHive,
  310. ProfileDir,
  311. DirSize,
  312. FALSE
  313. );
  314. } else {
  315. #ifdef UNICODE
  316. oldCreateUserProfile = (POLDCREATEUSERPROFILE) GetProcAddress (lib, (PCSTR) 110);
  317. #else
  318. oldCreateUserProfile = (POLDCREATEUSERPROFILE) GetProcAddress (lib, (PCSTR) 109);
  319. #endif
  320. if (!oldCreateUserProfile) {
  321. LOG ((LOG_MODULE_ERROR, (PCSTR) MSG_CANT_FIND_CREATEUSERPROFILE));
  322. return FALSE;
  323. }
  324. return oldCreateUserProfile (
  325. Sid,
  326. UserName,
  327. UserHive,
  328. ProfileDir,
  329. DirSize
  330. );
  331. }
  332. }
  333. BOOL
  334. pCloneDefaultUserProfile (
  335. IN PSID Sid,
  336. IN PCTSTR UserName,
  337. OUT PTSTR OutUserProfileRoot
  338. )
  339. {
  340. TCHAR userProfile[MAX_TCHAR_PATH];
  341. BOOL result = FALSE;
  342. __try {
  343. if (!pOurCreateUserProfile (
  344. Sid,
  345. UserName,
  346. NULL,
  347. userProfile,
  348. ARRAYSIZE(userProfile)
  349. )) {
  350. LOG ((LOG_MODULE_ERROR, (PCSTR) MSG_CANT_CREATE_PROFILE, UserName));
  351. __leave;
  352. }
  353. MYASSERT (OutUserProfileRoot);
  354. StringCopy (OutUserProfileRoot, userProfile);
  355. result = TRUE;
  356. }
  357. __finally {
  358. if (result) {
  359. LOG ((LOG_INFORMATION, (PCSTR) MSG_PROFILE_INFO, UserName, OutUserProfileRoot));
  360. }
  361. }
  362. return result;
  363. }
  364. PTEMPORARYPROFILE
  365. OpenTemporaryProfile (
  366. IN PCTSTR UserName,
  367. IN PCTSTR Domain
  368. )
  369. {
  370. DWORD sidSize;
  371. DWORD domainSize;
  372. SID_NAME_USE use;
  373. PTSTR domainBuffer = NULL;
  374. PSID sidBuffer = NULL;
  375. PTSTR sidString = NULL;
  376. PTEMPORARYPROFILE result = NULL;
  377. PCTSTR accountName = NULL;
  378. TCHAR userProfileRoot[MAX_TCHAR_PATH];
  379. PCTSTR hiveFile = NULL;
  380. LONG rc;
  381. HKEY key = NULL;
  382. PMHANDLE allocPool;
  383. BOOL b;
  384. __try {
  385. //
  386. // Generate the account name
  387. //
  388. if (!UserName || !Domain) {
  389. DEBUGMSG ((DBG_WHOOPS, "EstablishTemporaryProfile requires user and domain"));
  390. __leave;
  391. }
  392. accountName = JoinPaths (Domain, UserName);
  393. //
  394. // Obtain the buffer sizes needed to obtain the user's SID
  395. //
  396. sidSize = 0;
  397. domainSize = 0;
  398. b = LookupAccountName (
  399. NULL,
  400. accountName,
  401. NULL,
  402. &sidSize,
  403. NULL,
  404. &domainSize,
  405. &use
  406. );
  407. if (!b && GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
  408. LOG ((LOG_MODULE_ERROR, (PCSTR) MSG_CANT_FIND_ACCOUNT, accountName));
  409. __leave;
  410. }
  411. //
  412. // Allocate the buffers
  413. //
  414. domainBuffer = AllocText (domainSize);
  415. sidBuffer = MemAllocUninit (sidSize);
  416. if (!domainBuffer || !sidBuffer) {
  417. __leave;
  418. }
  419. //
  420. // Get the SID
  421. //
  422. b = LookupAccountName (
  423. NULL,
  424. accountName,
  425. sidBuffer,
  426. &sidSize,
  427. domainBuffer,
  428. &domainSize,
  429. &use
  430. );
  431. if (!b) {
  432. LOG ((LOG_MODULE_ERROR, (PCSTR) MSG_CANT_FIND_ACCOUNT_SID, accountName));
  433. __leave;
  434. }
  435. if (use != SidTypeUser) {
  436. SetLastError (ERROR_INVALID_ACCOUNT_NAME);
  437. LOG ((LOG_MODULE_ERROR, (PCSTR) MSG_NOT_USER_ACCOUNT, accountName));
  438. __leave;
  439. }
  440. //
  441. // Copy the default profile
  442. //
  443. b = pCloneDefaultUserProfile (sidBuffer, UserName, userProfileRoot);
  444. if (!b) {
  445. __leave;
  446. }
  447. //
  448. // convert SID into a string SID
  449. //
  450. if (!pOurConvertSidToStringSid (sidBuffer, &sidString) || !sidString) {
  451. LOG ((LOG_MODULE_ERROR, (PCSTR) MSG_CONVERT_SID_FAILURE));
  452. __leave;
  453. }
  454. //
  455. // Load the user's hive
  456. //
  457. RegUnLoadKey (HKEY_USERS, sidString);
  458. hiveFile = JoinPaths (userProfileRoot, TEXT("ntuser.dat"));
  459. rc = RegLoadKey (HKEY_USERS, sidString, hiveFile);
  460. if (rc != ERROR_SUCCESS) {
  461. SetLastError (rc);
  462. LOG ((LOG_MODULE_ERROR, (PCSTR) MSG_CANT_LOAD_HIVE, hiveFile));
  463. __leave;
  464. }
  465. //
  466. // Make the hive the new HKCU
  467. //
  468. key = OpenRegKey (HKEY_USERS, sidString);
  469. if (!key) {
  470. LOG ((LOG_MODULE_ERROR, (PCSTR) MSG_CANT_MAP_HIVE, hiveFile));
  471. __leave;
  472. }
  473. if (g_CurrentOverrideUser) {
  474. pOurRegOverridePredefKey (HKEY_CURRENT_USER, NULL);
  475. g_CurrentOverrideUser = NULL;
  476. }
  477. rc = pOurRegOverridePredefKey (HKEY_CURRENT_USER, key);
  478. if (rc != ERROR_SUCCESS) {
  479. LOG ((LOG_MODULE_ERROR, (PCSTR) MSG_CANT_REDIRECT_HIVE, hiveFile));
  480. __leave;
  481. }
  482. //
  483. // Prepare outbound handle
  484. //
  485. allocPool = PmCreateNamedPool ("TempProfile");
  486. if (!allocPool) {
  487. __leave;
  488. }
  489. result = (PTEMPORARYPROFILE) PmGetMemory (allocPool, sizeof (TEMPORARYPROFILE));
  490. if (!result) {
  491. __leave;
  492. }
  493. g_CurrentOverrideUser = result;
  494. result->AllocPool = allocPool;
  495. result->UserName = PmDuplicateString (allocPool, UserName);
  496. result->DomainName = PmDuplicateString (allocPool, Domain);
  497. result->AccountName = PmDuplicateString (allocPool, accountName);
  498. result->UserProfileRoot = PmDuplicateString (allocPool, userProfileRoot);
  499. result->MapKey = PmDuplicateString (allocPool, sidString);
  500. result->UserStringSid = PmDuplicateString (allocPool, sidString);
  501. result->UserHive = PmDuplicateString (allocPool, hiveFile);
  502. result->UserSid = (PSID) PmDuplicateMemory (
  503. allocPool,
  504. sidBuffer,
  505. GetLengthSid (sidBuffer)
  506. );
  507. }
  508. __finally {
  509. FreePathString (hiveFile);
  510. FreePathString (accountName);
  511. FreeText (domainBuffer);
  512. if (sidBuffer) {
  513. FreeAlloc (sidBuffer);
  514. INVALID_POINTER (sidBuffer);
  515. }
  516. if (key) {
  517. CloseRegKey (key);
  518. }
  519. if (!result) {
  520. if (sidString) {
  521. RegTerminateCache ();
  522. RegUnLoadKey (HKEY_USERS, sidString);
  523. }
  524. pOurRegOverridePredefKey (HKEY_CURRENT_USER, NULL);
  525. }
  526. if (sidString) {
  527. LocalFree (sidString);
  528. }
  529. }
  530. return result;
  531. }
  532. BOOL
  533. SelectTemporaryProfile (
  534. IN PTEMPORARYPROFILE Profile
  535. )
  536. {
  537. LONG rc;
  538. HKEY key;
  539. if (g_CurrentOverrideUser == Profile) {
  540. return TRUE;
  541. }
  542. key = OpenRegKey (HKEY_LOCAL_MACHINE, Profile->MapKey);
  543. if (!key) {
  544. LOG ((LOG_MODULE_ERROR, (PCSTR) MSG_CANT_OPEN_USER_REGISTRY, Profile->UserName));
  545. return FALSE;
  546. }
  547. if (g_CurrentOverrideUser) {
  548. pOurRegOverridePredefKey (HKEY_CURRENT_USER, NULL);
  549. g_CurrentOverrideUser = NULL;
  550. }
  551. rc = pOurRegOverridePredefKey (HKEY_CURRENT_USER, key);
  552. CloseRegKey (key);
  553. if (rc == ERROR_SUCCESS) {
  554. g_CurrentOverrideUser = Profile;
  555. return TRUE;
  556. }
  557. return FALSE;
  558. }
  559. BOOL
  560. CloseTemporaryProfile (
  561. IN PTEMPORARYPROFILE Profile,
  562. IN BOOL MakeProfilePermanent
  563. )
  564. {
  565. BOOL result = TRUE;
  566. LONG rc;
  567. DWORD error;
  568. MIG_OSVERSIONINFO osVersionInfo;
  569. if (g_CurrentOverrideUser == Profile) {
  570. pOurRegOverridePredefKey (HKEY_CURRENT_USER, NULL);
  571. g_CurrentOverrideUser = NULL;
  572. }
  573. RegTerminateCache ();
  574. rc = RegUnLoadKey (HKEY_USERS, Profile->MapKey);
  575. DEBUGMSG_IF ((
  576. rc != ERROR_SUCCESS,
  577. DBG_WHOOPS,
  578. "Can't unload mapped hive: rc=%u; check for registry handle leaks",
  579. rc
  580. ));
  581. if (MakeProfilePermanent) {
  582. if (!pOurCreateUserProfile (
  583. Profile->UserSid,
  584. Profile->UserName,
  585. Profile->UserHive,
  586. NULL,
  587. 0
  588. )) {
  589. // on Win2k it is known that this will fail with error ERROR_SHARING_VIOLATION
  590. // but the hive will actually be OK. So, if this is Win2k
  591. // and the error is ERROR_SHARING_VIOLATION we'll just consider a success.
  592. result = FALSE;
  593. error = GetLastError ();
  594. if (IsmGetOsVersionInfo (PLATFORM_DESTINATION, &osVersionInfo)) {
  595. if ((osVersionInfo.OsType == OSTYPE_WINDOWSNT) &&
  596. (osVersionInfo.OsMajorVersion == OSMAJOR_WINNT5) &&
  597. (osVersionInfo.OsMinorVersion == OSMINOR_GOLD) &&
  598. (error == ERROR_SHARING_VIOLATION)
  599. ) {
  600. result = TRUE;
  601. }
  602. }
  603. if (!result) {
  604. SetLastError (error);
  605. }
  606. }
  607. }
  608. if (result) {
  609. PmDestroyPool (Profile->AllocPool);
  610. INVALID_POINTER (Profile);
  611. }
  612. return result;
  613. }
  614. BOOL
  615. MapUserProfile (
  616. IN PCTSTR UserStringSid,
  617. IN PCTSTR UserProfilePath
  618. )
  619. {
  620. PCTSTR hiveFile = NULL;
  621. LONG rc;
  622. HKEY key;
  623. //
  624. // Unload UserStringSid if loaded
  625. //
  626. RegUnLoadKey (HKEY_USERS, UserStringSid);
  627. hiveFile = JoinPaths (UserProfilePath, TEXT("ntuser.dat"));
  628. rc = RegLoadKey (HKEY_USERS, UserStringSid, hiveFile);
  629. if (rc != ERROR_SUCCESS) {
  630. SetLastError (rc);
  631. LOG ((LOG_MODULE_ERROR, (PCSTR) MSG_CANT_LOAD_HIVE, hiveFile));
  632. FreePathString (hiveFile);
  633. return FALSE;
  634. }
  635. //
  636. // Make the hive the new HKCU
  637. //
  638. key = OpenRegKey (HKEY_USERS, UserStringSid);
  639. if (!key) {
  640. LOG ((LOG_MODULE_ERROR, (PCSTR) MSG_CANT_MAP_HIVE, hiveFile));
  641. RegUnLoadKey (HKEY_USERS, UserStringSid);
  642. FreePathString (hiveFile);
  643. return FALSE;
  644. }
  645. rc = pOurRegOverridePredefKey (HKEY_CURRENT_USER, key);
  646. if (rc != ERROR_SUCCESS) {
  647. LOG ((LOG_MODULE_ERROR, (PCSTR) MSG_CANT_REDIRECT_HIVE, hiveFile));
  648. CloseRegKey (key);
  649. RegTerminateCache ();
  650. RegUnLoadKey (HKEY_USERS, UserStringSid);
  651. FreePathString (hiveFile);
  652. return FALSE;
  653. }
  654. CloseRegKey (key);
  655. FreePathString (hiveFile);
  656. return TRUE;
  657. }
  658. BOOL
  659. UnmapUserProfile (
  660. IN PCTSTR UserStringSid
  661. )
  662. {
  663. LONG rc;
  664. pOurRegOverridePredefKey (HKEY_CURRENT_USER, NULL);
  665. RegTerminateCache ();
  666. rc = RegUnLoadKey (HKEY_USERS, UserStringSid);
  667. DEBUGMSG_IF ((
  668. rc != ERROR_SUCCESS,
  669. DBG_WHOOPS,
  670. "Can't unmap user profile: rc=%u; check for registry handle leaks",
  671. rc
  672. ));
  673. return TRUE;
  674. }
  675. BOOL
  676. DeleteUserProfile (
  677. IN PCTSTR UserStringSid,
  678. IN PCTSTR UserProfilePath
  679. )
  680. {
  681. RegTerminateCache ();
  682. RegUnLoadKey (HKEY_USERS, UserStringSid);
  683. return pOurDeleteProfile (UserStringSid, UserProfilePath, NULL);
  684. }
  685. PCURRENT_USER_DATA
  686. GetCurrentUserData (
  687. VOID
  688. )
  689. {
  690. PCURRENT_USER_DATA result = NULL;
  691. HANDLE token;
  692. DWORD bytesRequired;
  693. PTOKEN_USER tokenUser;
  694. PMHANDLE allocPool;
  695. PTSTR sidString = NULL;
  696. TCHAR userName[256];
  697. DWORD nameSize;
  698. TCHAR userDomain[256];
  699. DWORD domainSize;
  700. SID_NAME_USE dontCare;
  701. //
  702. // Open the process token.
  703. //
  704. if (!OpenProcessToken (GetCurrentProcess(), TOKEN_QUERY, &token)) {
  705. return FALSE;
  706. }
  707. bytesRequired = 0;
  708. if (GetTokenInformation (token, TokenUser, NULL, 0, &bytesRequired)) {
  709. return FALSE;
  710. }
  711. if (GetLastError () != ERROR_INSUFFICIENT_BUFFER) {
  712. return FALSE;
  713. }
  714. tokenUser = (PTOKEN_USER) MemAllocUninit (bytesRequired);
  715. if (!GetTokenInformation (token, TokenUser, tokenUser, bytesRequired, &bytesRequired)) {
  716. FreeAlloc (tokenUser);
  717. return FALSE;
  718. }
  719. nameSize = ARRAYSIZE (userName);
  720. domainSize = ARRAYSIZE (userDomain);
  721. ZeroMemory (userName, nameSize);
  722. ZeroMemory (userDomain, domainSize);
  723. LookupAccountSid (
  724. NULL,
  725. tokenUser->User.Sid,
  726. userName,
  727. &nameSize,
  728. userDomain,
  729. &domainSize,
  730. &dontCare
  731. );
  732. allocPool = PmCreateNamedPool ("CurrentUser");
  733. if (!allocPool) {
  734. FreeAlloc (tokenUser);
  735. return FALSE;
  736. }
  737. PmDisableTracking (allocPool);
  738. result = (PCURRENT_USER_DATA) PmGetMemory (allocPool, sizeof (CURRENT_USER_DATA));
  739. if (!result) {
  740. FreeAlloc (tokenUser);
  741. return FALSE;
  742. }
  743. result->AllocPool = allocPool;
  744. result->UserName = PmDuplicateString (result->AllocPool, userName);
  745. result->UserDomain = PmDuplicateString (result->AllocPool, userDomain);
  746. if (!pOurConvertSidToStringSid (tokenUser->User.Sid, &sidString) || !sidString) {
  747. PmDestroyPool (allocPool);
  748. FreeAlloc (tokenUser);
  749. return FALSE;
  750. }
  751. result->UserStringSid = PmDuplicateString (allocPool, sidString);
  752. LocalFree (sidString);
  753. FreeAlloc (tokenUser);
  754. // now just get the current user profile path
  755. bytesRequired = MAX_TCHAR_PATH;
  756. result->UserProfilePath = PmGetMemory (allocPool, bytesRequired);
  757. if (!pOurGetUserProfileDirectory (token, (PTSTR)result->UserProfilePath, &bytesRequired)) {
  758. result->UserProfilePath = PmGetMemory (allocPool, bytesRequired);
  759. if (!pOurGetUserProfileDirectory (token, (PTSTR)result->UserProfilePath, &bytesRequired)) {
  760. PmDestroyPool (allocPool);
  761. return FALSE;
  762. }
  763. }
  764. return result;
  765. }
  766. VOID
  767. FreeCurrentUserData (
  768. IN PCURRENT_USER_DATA CurrentUserData
  769. )
  770. {
  771. PmDestroyPool (CurrentUserData->AllocPool);
  772. }
  773. PCTSTR
  774. IsmGetCurrentSidString (
  775. VOID
  776. )
  777. {
  778. if (!g_CurrentOverrideUser) {
  779. return NULL;
  780. } else {
  781. return PmDuplicateString (g_IsmPool, g_CurrentOverrideUser->UserStringSid);
  782. }
  783. }