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.

516 lines
16 KiB

  1. #include "private.h"
  2. #include "multiusr.h"
  3. UINT WM_IDENTITY_CHANGED;
  4. UINT WM_QUERY_IDENTITY_CHANGE;
  5. UINT WM_IDENTITY_INFO_CHANGED;
  6. extern "C" int _fltused = 0; // define this so that floats and doubles don't bring in the CRT
  7. // Count number of objects and number of locks.
  8. ULONG g_cObj=0;
  9. ULONG g_cLock=0;
  10. // DLL Instance handle
  11. HINSTANCE g_hInst=0;
  12. // mutex for preventing logon re-entrancy
  13. HANDLE g_hMutex = NULL;
  14. #define IDENTITY_LOGIN_VALUE 0x00098053
  15. #define DEFINE_STRING_CONSTANTS
  16. #include "StrConst.h"
  17. #define MLUI_SUPPORT
  18. #define MLUI_INIT
  19. #include "mluisup.h"
  20. BOOL g_fNotifyComplete = TRUE;
  21. GUID g_uidOldUserId = {0x0};
  22. GUID g_uidNewUserId = {0x0};
  23. TCHAR szHKCUPolicyPath[] = "Software\\Microsoft\\Outlook Express\\Identities";
  24. void FixMissingIdentityNames();
  25. void UnloadPStore();
  26. PSECURITY_DESCRIPTOR CreateSd(void);
  27. // This is needed so we can link to libcmt.dll, because floating-point
  28. // initialization code is required.
  29. void __cdecl main()
  30. {
  31. }
  32. #ifdef DISABIDENT
  33. void DisableOnFirstRun(void)
  34. {
  35. // disable identities in Whistler
  36. HKEY hKey = NULL;
  37. DWORD dwVal = 0;
  38. DWORD dwType = 0;
  39. ULONG cbData = sizeof(DWORD);
  40. OSVERSIONINFO OSInfo = {0};
  41. TCHAR szPolicyPath[] = "Identities";
  42. TCHAR szPolicyKey[] = "Locked Down";
  43. TCHAR szFirstRun[] = "FirstRun";
  44. TCHAR szRegisteredVersion[] = "RegisteredVersion";
  45. OSInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  46. GetVersionEx(&OSInfo);
  47. if((OSInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) && (OSInfo.dwMajorVersion >= 5))
  48. {
  49. if(!(((OSInfo.dwMajorVersion == 5) && (OSInfo.dwMinorVersion > 0)) || (OSInfo.dwMajorVersion > 5)))
  50. return;
  51. }
  52. else
  53. return; // No disabling on Win 9x and NT4
  54. // Check: first time run?
  55. if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, szHKCUPolicyPath, 0, NULL, 0,
  56. KEY_ALL_ACCESS, NULL, &hKey, NULL) == ERROR_SUCCESS)
  57. {
  58. RegQueryValueEx(hKey, szRegisteredVersion, NULL, &dwType, (LPBYTE) &dwVal, &cbData);
  59. RegCloseKey(hKey);
  60. if(dwVal != OSInfo.dwBuildNumber)
  61. return; // already checked.
  62. }
  63. else
  64. return;
  65. if (RegCreateKeyEx(HKEY_CURRENT_USER, szPolicyPath, 0, NULL, 0,
  66. KEY_ALL_ACCESS, NULL, &hKey, NULL) == ERROR_SUCCESS)
  67. {
  68. RegQueryValueEx(hKey, szFirstRun, NULL, &dwType, (LPBYTE) &dwVal, &cbData);
  69. if(dwVal != 1)
  70. {
  71. dwVal = 1;
  72. RegSetValueEx(hKey, szFirstRun, NULL, REG_DWORD, (LPBYTE) &dwVal, cbData);
  73. }
  74. else
  75. {
  76. RegCloseKey(hKey);
  77. return; // already checked.
  78. }
  79. }
  80. else
  81. return;
  82. if(MU_CountUsers() < 2)
  83. RegSetValueEx(hKey, szPolicyKey, NULL, REG_DWORD, (LPBYTE) &dwVal, cbData);
  84. RegCloseKey(hKey);
  85. }
  86. #endif // DISABIDENT
  87. //////////////////////////////////////////////////////////////////////////
  88. //
  89. // DLL entry point
  90. //
  91. //////////////////////////////////////////////////////////////////////////
  92. EXTERN_C BOOL WINAPI LibMain(HINSTANCE hInstance, ULONG ulReason, LPVOID pvReserved)
  93. {
  94. WM_IDENTITY_CHANGED= RegisterWindowMessage("WM_IDENTITY_CHANGED");
  95. WM_QUERY_IDENTITY_CHANGE= RegisterWindowMessage("WM_QUERY_IDENTITY_CHANGE");
  96. WM_IDENTITY_INFO_CHANGED= RegisterWindowMessage("WM_IDENTITY_INFO_CHANGED");
  97. switch (ulReason)
  98. {
  99. case DLL_PROCESS_ATTACH:
  100. // MessageBox(NULL, "Debug", "Debug", MB_OK);
  101. SHFusionInitializeFromModule(hInstance);
  102. MLLoadResources(hInstance, TEXT("msidntld.dll"));
  103. if (MLGetHinst() == NULL)
  104. return FALSE;
  105. if (g_hMutex == NULL)
  106. {
  107. SECURITY_ATTRIBUTES sa;
  108. PSECURITY_DESCRIPTOR psd;
  109. psd = CreateSd();
  110. if (psd)
  111. {
  112. sa.nLength = sizeof(SECURITY_ATTRIBUTES);
  113. sa.lpSecurityDescriptor = psd;
  114. sa.bInheritHandle = TRUE;
  115. g_hMutex = CreateMutex(&sa, FALSE, "MSIdent Logon");
  116. LocalFree(psd);
  117. }
  118. else
  119. // in the worst case drop down to unshared object
  120. g_hMutex = CreateMutex(NULL, FALSE, "MSIdent Logon");
  121. if (g_hMutex == NULL) // Try to open mutex, if we cannot create mutex IE6 32769
  122. g_hMutex = OpenMutex(MUTEX_MODIFY_STATE, FALSE, "MSIdent Logon");
  123. if (GetLastError() != ERROR_ALREADY_EXISTS)
  124. {
  125. GUID uidStart;
  126. USERINFO uiLogin;
  127. #ifdef DISABIDENT
  128. DisableOnFirstRun();
  129. #endif // DISABIDENT
  130. // in case something got stuck in a switch, wipe it out here.
  131. CUserIdentityManager::ClearChangingIdentities();
  132. FixMissingIdentityNames();
  133. // we are the first instance to come up.
  134. // may need to reset the last user.....
  135. if (GetProp(GetDesktopWindow(),"IDENTITY_LOGIN") != (HANDLE)IDENTITY_LOGIN_VALUE)
  136. {
  137. _MigratePasswords();
  138. MU_GetLoginOption(&uidStart);
  139. // if there is a password on this identity, we can't auto start as them
  140. if (uidStart != GUID_NULL && MU_GetUserInfo(&uidStart, &uiLogin) && (uiLogin.fUsePassword || !uiLogin.fPasswordValid))
  141. {
  142. uidStart = GUID_NULL;
  143. }
  144. if (uidStart == GUID_NULL)
  145. {
  146. MU_SwitchToUser("");
  147. SetProp(GetDesktopWindow(),"IDENTITY_LOGIN", (HANDLE)IDENTITY_LOGIN_VALUE);
  148. }
  149. else
  150. {
  151. if(MU_GetUserInfo(&uidStart, &uiLogin))
  152. MU_SwitchToUser(uiLogin.szUsername);
  153. else
  154. MU_SwitchToUser("");
  155. }
  156. SetProp(GetDesktopWindow(),"IDENTITY_LOGIN", (HANDLE)IDENTITY_LOGIN_VALUE);
  157. }
  158. }
  159. }
  160. DisableThreadLibraryCalls(hInstance);
  161. g_hInst = hInstance;
  162. break;
  163. case DLL_PROCESS_DETACH:
  164. MLFreeResources(hInstance);
  165. UnloadPStore();
  166. CloseHandle(g_hMutex);
  167. g_hMutex = NULL;
  168. SHFusionUninitialize();
  169. break;
  170. }
  171. return TRUE;
  172. }
  173. //////////////////////////////////////////////////////////////////////////
  174. //
  175. // Standard OLE entry points
  176. //
  177. //////////////////////////////////////////////////////////////////////////
  178. // Class factory -
  179. // For classes with no special needs these macros should take care of it.
  180. // If your class needs some special stuff just to get the ball rolling,
  181. // implement your own CreateInstance method. (ala, CConnectionAgent)
  182. #define DEFINE_CREATEINSTANCE(cls, iface) \
  183. HRESULT cls##_CreateInstance(IUnknown *punkOuter, IUnknown **ppunk) \
  184. { \
  185. *ppunk = (iface *)new cls; \
  186. return (NULL != *ppunk) ? S_OK : E_OUTOFMEMORY; \
  187. }
  188. #define DEFINE_AGGREGATED_CREATEINSTANCE(cls, iface) \
  189. HRESULT cls##_CreateInstance(IUnknown *punkOuter, IUnknown **ppunk) \
  190. { \
  191. *ppunk = (iface *)new cls(punkOuter); \
  192. return (NULL != *ppunk) ? S_OK : E_OUTOFMEMORY; \
  193. }
  194. DEFINE_CREATEINSTANCE(CUserIdentityManager, IUserIdentityManager)
  195. const CFactoryData g_FactoryData[] =
  196. {
  197. { &CLSID_UserIdentityManager, CUserIdentityManager_CreateInstance, 0 }
  198. };
  199. HRESULT APIENTRY DllGetClassObject(REFCLSID rclsid, REFIID riid, void **ppv)
  200. {
  201. HRESULT hr = S_OK;
  202. IUnknown *punk = NULL;
  203. *ppv = NULL;
  204. MU_Init();
  205. // Validate request
  206. for (int i = 0; i < ARRAYSIZE(g_FactoryData); i++)
  207. {
  208. if (rclsid == *g_FactoryData[i].m_pClsid)
  209. {
  210. punk = new CClassFactory(&g_FactoryData[i]);
  211. break;
  212. }
  213. }
  214. if (ARRAYSIZE(g_FactoryData) <= i)
  215. {
  216. hr = CLASS_E_CLASSNOTAVAILABLE;
  217. }
  218. else if (NULL == punk)
  219. {
  220. hr = E_OUTOFMEMORY;
  221. }
  222. else
  223. {
  224. hr = punk->QueryInterface(riid, ppv);
  225. punk->Release();
  226. }
  227. return hr;
  228. }
  229. STDAPI DllCanUnloadNow(void)
  230. {
  231. // check objects and locks
  232. return (0L == DllGetRef() && 0L == DllGetLock()) ? S_OK : S_FALSE;
  233. }
  234. //////////////////////////////////////////////////////////////////////////
  235. //
  236. // Autoregistration entry points
  237. //
  238. //////////////////////////////////////////////////////////////////////////
  239. HRESULT CallRegInstall(LPSTR szSection)
  240. {
  241. HRESULT hr = E_FAIL;
  242. char szDll[MAX_PATH];
  243. int cch;
  244. STRENTRY seReg[2];
  245. STRTABLE stReg;
  246. HINSTANCE hinstAdvPack = LoadLibrary(TEXT("ADVPACK.DLL"));
  247. if (hinstAdvPack)
  248. {
  249. REGINSTALL pfnri = (REGINSTALL)GetProcAddress(hinstAdvPack, achREGINSTALL);
  250. if (pfnri)
  251. {
  252. // Get our location
  253. GetModuleFileName(g_hInst, szDll, sizeof(szDll));
  254. // Setup special registration stuff
  255. // Do this instead of relying on _SYS_MOD_PATH which loses spaces under '95
  256. stReg.cEntries = 0;
  257. seReg[stReg.cEntries].pszName = "SYS_MOD_PATH";
  258. seReg[stReg.cEntries].pszValue = szDll;
  259. stReg.cEntries++;
  260. stReg.pse = seReg;
  261. hr = pfnri(g_hInst, szSection, &stReg);
  262. }
  263. FreeLibrary(hinstAdvPack);
  264. }
  265. return hr;
  266. }
  267. STDAPI DllRegisterServer(void)
  268. {
  269. // Delete any old registration entries, then add the new ones.
  270. // Keep ADVPACK.DLL loaded across multiple calls to RegInstall.
  271. HINSTANCE hinstAdvPack = LoadLibrary(TEXT("ADVPACK.DLL"));
  272. HKEY hKey = NULL;
  273. DWORD dwVal = 1;
  274. ULONG cbData = sizeof(DWORD);
  275. OSVERSIONINFO OSInfo = {0};
  276. TCHAR szPolicyPath[] = "Identities";
  277. TCHAR szRegisteredVersion[] = "RegisteredVersion";
  278. TCHAR szPolPath[] = "Software\\Policies\\Microsoft\\Windows\\CurrentVersion\\Identities";
  279. TCHAR szPolicyKey[] = "Locked Down";
  280. CallRegInstall("Reg");
  281. if (hinstAdvPack)
  282. {
  283. FreeLibrary(hinstAdvPack);
  284. }
  285. #ifdef DISABIDENT
  286. OSInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  287. GetVersionEx(&OSInfo);
  288. if((OSInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) && (OSInfo.dwMajorVersion >= 5))
  289. {
  290. if(!(((OSInfo.dwMajorVersion == 5) && (OSInfo.dwMinorVersion > 0)) || (OSInfo.dwMajorVersion > 5)))
  291. return NOERROR;
  292. }
  293. else
  294. return NOERROR; // No disable for Win9x
  295. // Set registration value
  296. if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, szHKCUPolicyPath, 0, NULL, 0,
  297. KEY_ALL_ACCESS, NULL, &hKey, NULL) == ERROR_SUCCESS)
  298. {
  299. dwVal = OSInfo.dwBuildNumber;
  300. RegSetValueEx(hKey, szRegisteredVersion, NULL, REG_DWORD, (LPBYTE) &dwVal, cbData);
  301. RegCloseKey(hKey);
  302. }
  303. #endif // DISABIDENT
  304. // DISABLING identities in Win64
  305. #ifdef _WIN64
  306. // Set registration value
  307. if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, szPolPath, 0, NULL, 0,
  308. KEY_WOW64_32KEY | KEY_ALL_ACCESS, NULL, &hKey, NULL) == ERROR_SUCCESS)
  309. {
  310. RegSetValueEx(hKey, szPolicyKey, NULL, REG_DWORD, (LPBYTE) &dwVal, cbData);
  311. }
  312. #endif // _WIN64
  313. return NOERROR;
  314. }
  315. STDAPI
  316. DllUnregisterServer(void)
  317. {
  318. return NOERROR;
  319. }
  320. PSECURITY_DESCRIPTOR CreateSd(void)
  321. {
  322. PSID AuthenticatedUsers = NULL;
  323. PSID BuiltInAdministrators = NULL;
  324. PSID PowerUsers = NULL;
  325. PSECURITY_DESCRIPTOR RetVal = NULL;
  326. PSECURITY_DESCRIPTOR Sd = NULL;
  327. SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
  328. ULONG AclSize;
  329. //
  330. // Each RID represents a sub-unit of the authority. Two of the SIDs we
  331. // want to build, Local Administrators, and Power Users, are in the "built
  332. // in" domain. The other SID, for Authenticated users, is based directly
  333. // off of the authority.
  334. //
  335. // For examples of other useful SIDs consult the list in
  336. // \nt\public\sdk\inc\ntseapi.h.
  337. //
  338. if (!AllocateAndInitializeSid(&NtAuthority,
  339. 2, // 2 sub-authorities
  340. SECURITY_BUILTIN_DOMAIN_RID,
  341. DOMAIN_ALIAS_RID_ADMINS,
  342. 0,0,0,0,0,0,
  343. &BuiltInAdministrators))
  344. goto ErrorExit;
  345. if (!AllocateAndInitializeSid(&NtAuthority,
  346. 2, // 2 sub-authorities
  347. SECURITY_BUILTIN_DOMAIN_RID,
  348. DOMAIN_ALIAS_RID_POWER_USERS,
  349. 0,0,0,0,0,0,
  350. &PowerUsers))
  351. goto ErrorExit;
  352. if (!AllocateAndInitializeSid(&NtAuthority,
  353. 1, // 1 sub-authority
  354. SECURITY_AUTHENTICATED_USER_RID,
  355. 0,0,0,0,0,0,0,
  356. &AuthenticatedUsers))
  357. goto ErrorExit;
  358. //
  359. // Calculate the size of and allocate a buffer for the DACL, we need
  360. // this value independently of the total alloc size for ACL init.
  361. //
  362. // "- sizeof (ULONG)" represents the SidStart field of the
  363. // ACCESS_ALLOWED_ACE. Since we're adding the entire length of the
  364. // SID, this field is counted twice.
  365. //
  366. AclSize = sizeof (ACL) +
  367. (3 * (sizeof (ACCESS_ALLOWED_ACE) - sizeof (ULONG))) +
  368. GetLengthSid(AuthenticatedUsers) +
  369. GetLengthSid(BuiltInAdministrators) +
  370. GetLengthSid(PowerUsers);
  371. Sd = (PSECURITY_DESCRIPTOR)LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH + AclSize);
  372. if (Sd)
  373. {
  374. ACL *Acl;
  375. Acl = (ACL *)((BYTE *)Sd + SECURITY_DESCRIPTOR_MIN_LENGTH);
  376. if (!InitializeAcl(Acl,
  377. AclSize,
  378. ACL_REVISION)) {
  379. // Error
  380. } else if (!AddAccessAllowedAce(Acl,
  381. ACL_REVISION,
  382. SYNCHRONIZE | MUTEX_MODIFY_STATE,
  383. AuthenticatedUsers)) {
  384. // Failed to build the ACE granting "Authenticated users"
  385. // (SYNCHRONIZE | GENERIC_READ | GENERIC_WRITE) access.
  386. } else if (!AddAccessAllowedAce(Acl,
  387. ACL_REVISION,
  388. SYNCHRONIZE | MUTEX_MODIFY_STATE,
  389. PowerUsers)) {
  390. // Failed to build the ACE granting "Power users"
  391. // (SYNCHRONIZE | GENERIC_READ | GENERIC_WRITE) access.
  392. } else if (!AddAccessAllowedAce(Acl,
  393. ACL_REVISION,
  394. MUTEX_ALL_ACCESS,
  395. BuiltInAdministrators)) {
  396. // Failed to build the ACE granting "Built-in Administrators"
  397. // GENERIC_ALL access.
  398. } else if (!InitializeSecurityDescriptor(Sd,
  399. SECURITY_DESCRIPTOR_REVISION)) {
  400. // error
  401. } else if (!SetSecurityDescriptorDacl(Sd,
  402. TRUE,
  403. Acl,
  404. FALSE)) {
  405. // error
  406. } else {
  407. // success
  408. RetVal = Sd;
  409. }
  410. // only free Sd if we encountered a failure
  411. if (!RetVal)
  412. LocalFree(Sd);
  413. }
  414. ErrorExit:
  415. if (AuthenticatedUsers)
  416. FreeSid(AuthenticatedUsers);
  417. if (BuiltInAdministrators)
  418. FreeSid(BuiltInAdministrators);
  419. if (PowerUsers)
  420. FreeSid(PowerUsers);
  421. return RetVal;
  422. }