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.

979 lines
24 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 || (UserName [0] == 0)) {
  389. LOG ((LOG_MODULE_ERROR, (PCSTR) MSG_ACCOUNT_INVALID_PARAMETERS));
  390. SetLastError (ERROR_INVALID_PARAMETER);
  391. __leave;
  392. }
  393. accountName = JoinPaths (Domain, UserName);
  394. //
  395. // Obtain the buffer sizes needed to obtain the user's SID
  396. //
  397. sidSize = 0;
  398. domainSize = 0;
  399. b = LookupAccountName (
  400. NULL,
  401. accountName,
  402. NULL,
  403. &sidSize,
  404. NULL,
  405. &domainSize,
  406. &use
  407. );
  408. if (!b && GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
  409. LOG ((LOG_MODULE_ERROR, (PCSTR) MSG_CANT_FIND_ACCOUNT, accountName));
  410. __leave;
  411. }
  412. //
  413. // Allocate the buffers
  414. //
  415. domainBuffer = AllocText (domainSize);
  416. sidBuffer = MemAllocUninit (sidSize);
  417. if (!domainBuffer || !sidBuffer) {
  418. __leave;
  419. }
  420. //
  421. // Get the SID
  422. //
  423. b = LookupAccountName (
  424. NULL,
  425. accountName,
  426. sidBuffer,
  427. &sidSize,
  428. domainBuffer,
  429. &domainSize,
  430. &use
  431. );
  432. if (!b) {
  433. LOG ((LOG_MODULE_ERROR, (PCSTR) MSG_CANT_FIND_ACCOUNT_SID, accountName));
  434. __leave;
  435. }
  436. if (use != SidTypeUser) {
  437. SetLastError (ERROR_INVALID_ACCOUNT_NAME);
  438. LOG ((LOG_MODULE_ERROR, (PCSTR) MSG_NOT_USER_ACCOUNT, accountName));
  439. __leave;
  440. }
  441. //
  442. // Copy the default profile
  443. //
  444. b = pCloneDefaultUserProfile (sidBuffer, UserName, userProfileRoot);
  445. if (!b) {
  446. __leave;
  447. }
  448. //
  449. // convert SID into a string SID
  450. //
  451. if (!pOurConvertSidToStringSid (sidBuffer, &sidString) || !sidString) {
  452. LOG ((LOG_MODULE_ERROR, (PCSTR) MSG_CONVERT_SID_FAILURE));
  453. __leave;
  454. }
  455. //
  456. // Load the user's hive
  457. //
  458. RegUnLoadKey (HKEY_USERS, sidString);
  459. hiveFile = JoinPaths (userProfileRoot, TEXT("ntuser.dat"));
  460. rc = RegLoadKey (HKEY_USERS, sidString, hiveFile);
  461. if (rc != ERROR_SUCCESS) {
  462. SetLastError (rc);
  463. LOG ((LOG_MODULE_ERROR, (PCSTR) MSG_CANT_LOAD_HIVE, hiveFile));
  464. __leave;
  465. }
  466. //
  467. // Make the hive the new HKCU
  468. //
  469. key = OpenRegKey (HKEY_USERS, sidString);
  470. if (!key) {
  471. LOG ((LOG_MODULE_ERROR, (PCSTR) MSG_CANT_MAP_HIVE, hiveFile));
  472. __leave;
  473. }
  474. if (g_CurrentOverrideUser) {
  475. pOurRegOverridePredefKey (HKEY_CURRENT_USER, NULL);
  476. g_CurrentOverrideUser = NULL;
  477. }
  478. rc = pOurRegOverridePredefKey (HKEY_CURRENT_USER, key);
  479. if (rc != ERROR_SUCCESS) {
  480. LOG ((LOG_MODULE_ERROR, (PCSTR) MSG_CANT_REDIRECT_HIVE, hiveFile));
  481. __leave;
  482. }
  483. //
  484. // Prepare outbound handle
  485. //
  486. allocPool = PmCreateNamedPool ("TempProfile");
  487. if (!allocPool) {
  488. __leave;
  489. }
  490. result = (PTEMPORARYPROFILE) PmGetMemory (allocPool, sizeof (TEMPORARYPROFILE));
  491. if (!result) {
  492. __leave;
  493. }
  494. g_CurrentOverrideUser = result;
  495. result->AllocPool = allocPool;
  496. result->UserName = PmDuplicateString (allocPool, UserName);
  497. result->DomainName = PmDuplicateString (allocPool, Domain);
  498. result->AccountName = PmDuplicateString (allocPool, accountName);
  499. result->UserProfileRoot = PmDuplicateString (allocPool, userProfileRoot);
  500. result->MapKey = PmDuplicateString (allocPool, sidString);
  501. result->UserStringSid = PmDuplicateString (allocPool, sidString);
  502. result->UserHive = PmDuplicateString (allocPool, hiveFile);
  503. result->UserSid = (PSID) PmDuplicateMemory (
  504. allocPool,
  505. sidBuffer,
  506. GetLengthSid (sidBuffer)
  507. );
  508. // Everything went just fine. Last thing, let's write the mapped location of
  509. // the user hive in the environment
  510. IsmSetEnvironmentString (PLATFORM_DESTINATION, NULL, S_VER_HIVEMAPPEDLOCATION, sidString);
  511. }
  512. __finally {
  513. FreePathString (hiveFile);
  514. FreePathString (accountName);
  515. FreeText (domainBuffer);
  516. if (sidBuffer) {
  517. FreeAlloc (sidBuffer);
  518. INVALID_POINTER (sidBuffer);
  519. }
  520. if (key) {
  521. CloseRegKey (key);
  522. }
  523. if (!result) {
  524. if (sidString) {
  525. RegTerminateCache ();
  526. RegUnLoadKey (HKEY_USERS, sidString);
  527. }
  528. pOurRegOverridePredefKey (HKEY_CURRENT_USER, NULL);
  529. }
  530. if (sidString) {
  531. LocalFree (sidString);
  532. }
  533. }
  534. return result;
  535. }
  536. BOOL
  537. SelectTemporaryProfile (
  538. IN PTEMPORARYPROFILE Profile
  539. )
  540. {
  541. LONG rc;
  542. HKEY key;
  543. if (g_CurrentOverrideUser == Profile) {
  544. return TRUE;
  545. }
  546. key = OpenRegKey (HKEY_LOCAL_MACHINE, Profile->MapKey);
  547. if (!key) {
  548. LOG ((LOG_MODULE_ERROR, (PCSTR) MSG_CANT_OPEN_USER_REGISTRY, Profile->UserName));
  549. return FALSE;
  550. }
  551. if (g_CurrentOverrideUser) {
  552. pOurRegOverridePredefKey (HKEY_CURRENT_USER, NULL);
  553. g_CurrentOverrideUser = NULL;
  554. }
  555. rc = pOurRegOverridePredefKey (HKEY_CURRENT_USER, key);
  556. CloseRegKey (key);
  557. if (rc == ERROR_SUCCESS) {
  558. g_CurrentOverrideUser = Profile;
  559. return TRUE;
  560. }
  561. return FALSE;
  562. }
  563. BOOL
  564. CloseTemporaryProfile (
  565. IN PTEMPORARYPROFILE Profile,
  566. IN BOOL MakeProfilePermanent
  567. )
  568. {
  569. BOOL result = TRUE;
  570. LONG rc;
  571. DWORD error;
  572. MIG_OSVERSIONINFO osVersionInfo;
  573. if (g_CurrentOverrideUser == Profile) {
  574. pOurRegOverridePredefKey (HKEY_CURRENT_USER, NULL);
  575. g_CurrentOverrideUser = NULL;
  576. }
  577. RegTerminateCache ();
  578. rc = RegUnLoadKey (HKEY_USERS, Profile->MapKey);
  579. DEBUGMSG_IF ((
  580. rc != ERROR_SUCCESS,
  581. DBG_WHOOPS,
  582. "Can't unload mapped hive: rc=%u; check for registry handle leaks",
  583. rc
  584. ));
  585. if (MakeProfilePermanent) {
  586. if (!pOurCreateUserProfile (
  587. Profile->UserSid,
  588. Profile->UserName,
  589. Profile->UserHive,
  590. NULL,
  591. 0
  592. )) {
  593. // on Win2k it is known that this will fail with error ERROR_SHARING_VIOLATION
  594. // but the hive will actually be OK. So, if this is Win2k
  595. // and the error is ERROR_SHARING_VIOLATION we'll just consider a success.
  596. result = FALSE;
  597. error = GetLastError ();
  598. if (IsmGetOsVersionInfo (PLATFORM_DESTINATION, &osVersionInfo)) {
  599. if ((osVersionInfo.OsType == OSTYPE_WINDOWSNT) &&
  600. (osVersionInfo.OsMajorVersion == OSMAJOR_WINNT5) &&
  601. (osVersionInfo.OsMinorVersion == OSMINOR_GOLD) &&
  602. (error == ERROR_SHARING_VIOLATION)
  603. ) {
  604. result = TRUE;
  605. }
  606. }
  607. if (!result) {
  608. SetLastError (error);
  609. }
  610. }
  611. }
  612. if (result) {
  613. PmDestroyPool (Profile->AllocPool);
  614. INVALID_POINTER (Profile);
  615. }
  616. return result;
  617. }
  618. BOOL
  619. MapUserProfile (
  620. IN PCTSTR UserStringSid,
  621. IN PCTSTR UserProfilePath
  622. )
  623. {
  624. PCTSTR hiveFile = NULL;
  625. LONG rc;
  626. HKEY key;
  627. //
  628. // Unload UserStringSid if loaded
  629. //
  630. RegUnLoadKey (HKEY_USERS, UserStringSid);
  631. hiveFile = JoinPaths (UserProfilePath, TEXT("ntuser.dat"));
  632. rc = RegLoadKey (HKEY_USERS, UserStringSid, hiveFile);
  633. if (rc != ERROR_SUCCESS) {
  634. SetLastError (rc);
  635. LOG ((LOG_MODULE_ERROR, (PCSTR) MSG_CANT_LOAD_HIVE, hiveFile));
  636. FreePathString (hiveFile);
  637. return FALSE;
  638. }
  639. //
  640. // Make the hive the new HKCU
  641. //
  642. key = OpenRegKey (HKEY_USERS, UserStringSid);
  643. if (!key) {
  644. LOG ((LOG_MODULE_ERROR, (PCSTR) MSG_CANT_MAP_HIVE, hiveFile));
  645. RegUnLoadKey (HKEY_USERS, UserStringSid);
  646. FreePathString (hiveFile);
  647. return FALSE;
  648. }
  649. rc = pOurRegOverridePredefKey (HKEY_CURRENT_USER, key);
  650. if (rc != ERROR_SUCCESS) {
  651. LOG ((LOG_MODULE_ERROR, (PCSTR) MSG_CANT_REDIRECT_HIVE, hiveFile));
  652. CloseRegKey (key);
  653. RegTerminateCache ();
  654. RegUnLoadKey (HKEY_USERS, UserStringSid);
  655. FreePathString (hiveFile);
  656. return FALSE;
  657. }
  658. CloseRegKey (key);
  659. FreePathString (hiveFile);
  660. return TRUE;
  661. }
  662. BOOL
  663. UnmapUserProfile (
  664. IN PCTSTR UserStringSid
  665. )
  666. {
  667. LONG rc;
  668. pOurRegOverridePredefKey (HKEY_CURRENT_USER, NULL);
  669. RegTerminateCache ();
  670. rc = RegUnLoadKey (HKEY_USERS, UserStringSid);
  671. DEBUGMSG_IF ((
  672. rc != ERROR_SUCCESS,
  673. DBG_WHOOPS,
  674. "Can't unmap user profile: rc=%u; check for registry handle leaks",
  675. rc
  676. ));
  677. return TRUE;
  678. }
  679. BOOL
  680. DeleteUserProfile (
  681. IN PCTSTR UserStringSid,
  682. IN PCTSTR UserProfilePath
  683. )
  684. {
  685. RegTerminateCache ();
  686. RegUnLoadKey (HKEY_USERS, UserStringSid);
  687. return pOurDeleteProfile (UserStringSid, UserProfilePath, NULL);
  688. }
  689. PCURRENT_USER_DATA
  690. GetCurrentUserData (
  691. VOID
  692. )
  693. {
  694. PCURRENT_USER_DATA result = NULL;
  695. HANDLE token;
  696. DWORD bytesRequired;
  697. PTOKEN_USER tokenUser;
  698. PMHANDLE allocPool;
  699. PTSTR sidString = NULL;
  700. TCHAR userName[256];
  701. DWORD nameSize;
  702. TCHAR userDomain[256];
  703. DWORD domainSize;
  704. SID_NAME_USE dontCare;
  705. //
  706. // Open the process token.
  707. //
  708. if (!OpenProcessToken (GetCurrentProcess(), TOKEN_QUERY, &token)) {
  709. return FALSE;
  710. }
  711. bytesRequired = 0;
  712. if (GetTokenInformation (token, TokenUser, NULL, 0, &bytesRequired)) {
  713. return FALSE;
  714. }
  715. if (GetLastError () != ERROR_INSUFFICIENT_BUFFER) {
  716. return FALSE;
  717. }
  718. tokenUser = (PTOKEN_USER) MemAllocUninit (bytesRequired);
  719. if (!GetTokenInformation (token, TokenUser, tokenUser, bytesRequired, &bytesRequired)) {
  720. FreeAlloc (tokenUser);
  721. return FALSE;
  722. }
  723. nameSize = ARRAYSIZE (userName);
  724. domainSize = ARRAYSIZE (userDomain);
  725. ZeroMemory (userName, nameSize);
  726. ZeroMemory (userDomain, domainSize);
  727. LookupAccountSid (
  728. NULL,
  729. tokenUser->User.Sid,
  730. userName,
  731. &nameSize,
  732. userDomain,
  733. &domainSize,
  734. &dontCare
  735. );
  736. allocPool = PmCreateNamedPool ("CurrentUser");
  737. if (!allocPool) {
  738. FreeAlloc (tokenUser);
  739. return FALSE;
  740. }
  741. PmDisableTracking (allocPool);
  742. result = (PCURRENT_USER_DATA) PmGetMemory (allocPool, sizeof (CURRENT_USER_DATA));
  743. if (!result) {
  744. FreeAlloc (tokenUser);
  745. return FALSE;
  746. }
  747. result->AllocPool = allocPool;
  748. result->UserName = PmDuplicateString (result->AllocPool, userName);
  749. result->UserDomain = PmDuplicateString (result->AllocPool, userDomain);
  750. if (!pOurConvertSidToStringSid (tokenUser->User.Sid, &sidString) || !sidString) {
  751. PmDestroyPool (allocPool);
  752. FreeAlloc (tokenUser);
  753. return FALSE;
  754. }
  755. result->UserStringSid = PmDuplicateString (allocPool, sidString);
  756. LocalFree (sidString);
  757. FreeAlloc (tokenUser);
  758. // now just get the current user profile path
  759. bytesRequired = MAX_TCHAR_PATH;
  760. result->UserProfilePath = PmGetMemory (allocPool, bytesRequired);
  761. if (!pOurGetUserProfileDirectory (token, (PTSTR)result->UserProfilePath, &bytesRequired)) {
  762. result->UserProfilePath = PmGetMemory (allocPool, bytesRequired);
  763. if (!pOurGetUserProfileDirectory (token, (PTSTR)result->UserProfilePath, &bytesRequired)) {
  764. PmDestroyPool (allocPool);
  765. return FALSE;
  766. }
  767. }
  768. return result;
  769. }
  770. VOID
  771. FreeCurrentUserData (
  772. IN PCURRENT_USER_DATA CurrentUserData
  773. )
  774. {
  775. PmDestroyPool (CurrentUserData->AllocPool);
  776. }
  777. PCTSTR
  778. IsmGetCurrentSidString (
  779. VOID
  780. )
  781. {
  782. if (!g_CurrentOverrideUser) {
  783. return NULL;
  784. } else {
  785. return PmDuplicateString (g_IsmPool, g_CurrentOverrideUser->UserStringSid);
  786. }
  787. }