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.

494 lines
10 KiB

  1. #include "StdAfx.h"
  2. #include "ADMTScript.h"
  3. #include "UserMigration.h"
  4. #include "Error.h"
  5. #include "VarSetOptions.h"
  6. #include "VarSetAccountOptions.h"
  7. #include "VarSetSecurity.h"
  8. //---------------------------------------------------------------------------
  9. // CUserMigration
  10. //---------------------------------------------------------------------------
  11. CUserMigration::CUserMigration() :
  12. m_lDisableOption(admtEnableTarget),
  13. m_lSourceExpiration(-1),
  14. m_bMigrateSids(false),
  15. m_bTranslateRoamingProfile(false),
  16. m_bUpdateUserRights(false),
  17. m_bMigrateGroups(false),
  18. m_bUpdatePreviouslyMigratedObjects(false),
  19. m_bFixGroupMembership(true),
  20. m_bMigrateServiceAccounts(true)
  21. {
  22. }
  23. CUserMigration::~CUserMigration()
  24. {
  25. }
  26. // IUserMigration Implementation --------------------------------------------
  27. // DisableOption Property
  28. STDMETHODIMP CUserMigration::put_DisableOption(long lOption)
  29. {
  30. HRESULT hr = S_OK;
  31. if (IsDisableOptionValid(lOption))
  32. {
  33. m_lDisableOption = lOption;
  34. }
  35. else
  36. {
  37. hr = AdmtSetError(CLSID_Migration, IID_IUserMigration, E_INVALIDARG, IDS_E_DISABLE_OPTION_INVALID);
  38. }
  39. return hr;
  40. }
  41. STDMETHODIMP CUserMigration::get_DisableOption(long* plOption)
  42. {
  43. *plOption = m_lDisableOption;
  44. return S_OK;
  45. }
  46. // SourceExpiration Property
  47. STDMETHODIMP CUserMigration::put_SourceExpiration(long lExpiration)
  48. {
  49. HRESULT hr = S_OK;
  50. if (IsSourceExpirationValid(lExpiration))
  51. {
  52. m_lSourceExpiration = lExpiration;
  53. }
  54. else
  55. {
  56. hr = AdmtSetError(CLSID_Migration, IID_IUserMigration, E_INVALIDARG, IDS_E_SOURCE_EXPIRATION_INVALID);
  57. }
  58. return hr;
  59. }
  60. STDMETHODIMP CUserMigration::get_SourceExpiration(long* plExpiration)
  61. {
  62. *plExpiration = m_lSourceExpiration;
  63. return S_OK;
  64. }
  65. // MigrateSIDs Property
  66. STDMETHODIMP CUserMigration::put_MigrateSIDs(VARIANT_BOOL bMigrate)
  67. {
  68. m_bMigrateSids = bMigrate ? true : false;
  69. return S_OK;
  70. }
  71. STDMETHODIMP CUserMigration::get_MigrateSIDs(VARIANT_BOOL* pbMigrate)
  72. {
  73. *pbMigrate = m_bMigrateSids ? VARIANT_TRUE : VARIANT_FALSE;
  74. return S_OK;
  75. }
  76. // TranslateRoamingProfile Property
  77. STDMETHODIMP CUserMigration::put_TranslateRoamingProfile(VARIANT_BOOL bTranslate)
  78. {
  79. m_bTranslateRoamingProfile = bTranslate ? true : false;
  80. return S_OK;
  81. }
  82. STDMETHODIMP CUserMigration::get_TranslateRoamingProfile(VARIANT_BOOL* pbTranslate)
  83. {
  84. *pbTranslate = m_bTranslateRoamingProfile ? VARIANT_TRUE : VARIANT_FALSE;
  85. return S_OK;
  86. }
  87. // UpdateUserRights Property
  88. STDMETHODIMP CUserMigration::put_UpdateUserRights(VARIANT_BOOL bUpdate)
  89. {
  90. m_bUpdateUserRights = bUpdate ? true : false;
  91. return S_OK;
  92. }
  93. STDMETHODIMP CUserMigration::get_UpdateUserRights(VARIANT_BOOL* pbUpdate)
  94. {
  95. *pbUpdate = m_bUpdateUserRights ? VARIANT_TRUE : VARIANT_FALSE;
  96. return S_OK;
  97. }
  98. // MigrateGroups Property
  99. STDMETHODIMP CUserMigration::put_MigrateGroups(VARIANT_BOOL bMigrate)
  100. {
  101. m_bMigrateGroups = bMigrate ? true : false;
  102. return S_OK;
  103. }
  104. STDMETHODIMP CUserMigration::get_MigrateGroups(VARIANT_BOOL* pbMigrate)
  105. {
  106. *pbMigrate = m_bMigrateGroups ? VARIANT_TRUE : VARIANT_FALSE;
  107. return S_OK;
  108. }
  109. // UpdatePreviouslyMigratedObjects Property
  110. STDMETHODIMP CUserMigration::put_UpdatePreviouslyMigratedObjects(VARIANT_BOOL bUpdate)
  111. {
  112. m_bUpdatePreviouslyMigratedObjects = bUpdate ? true : false;
  113. return S_OK;
  114. }
  115. STDMETHODIMP CUserMigration::get_UpdatePreviouslyMigratedObjects(VARIANT_BOOL* pbUpdate)
  116. {
  117. *pbUpdate = m_bUpdatePreviouslyMigratedObjects ? VARIANT_TRUE : VARIANT_FALSE;
  118. return S_OK;
  119. }
  120. // FixGroupMembership Property
  121. STDMETHODIMP CUserMigration::put_FixGroupMembership(VARIANT_BOOL bFix)
  122. {
  123. m_bFixGroupMembership = bFix ? true : false;
  124. return S_OK;
  125. }
  126. STDMETHODIMP CUserMigration::get_FixGroupMembership(VARIANT_BOOL* pbFix)
  127. {
  128. *pbFix = m_bFixGroupMembership ? VARIANT_TRUE : VARIANT_FALSE;
  129. return S_OK;
  130. }
  131. // MigrateServiceAccounts Property
  132. STDMETHODIMP CUserMigration::put_MigrateServiceAccounts(VARIANT_BOOL bMigrate)
  133. {
  134. m_bMigrateServiceAccounts = bMigrate ? true : false;
  135. return S_OK;
  136. }
  137. STDMETHODIMP CUserMigration::get_MigrateServiceAccounts(VARIANT_BOOL* pbMigrate)
  138. {
  139. *pbMigrate = m_bMigrateServiceAccounts ? VARIANT_TRUE : VARIANT_FALSE;
  140. return S_OK;
  141. }
  142. // Migrate Method
  143. STDMETHODIMP CUserMigration::Migrate(long lOptions, VARIANT vntInclude, VARIANT vntExclude)
  144. {
  145. HRESULT hr = S_OK;
  146. MutexWait();
  147. bool bLogOpen = _Module.OpenLog();
  148. try
  149. {
  150. _Module.Log(ErrI, IDS_STARTED_USER_MIGRATION);
  151. InitSourceDomainAndContainer();
  152. InitTargetDomainAndContainer();
  153. VerifyInterIntraForest();
  154. ValidateMigrationParameters();
  155. if (m_bMigrateSids)
  156. {
  157. VerifyCanAddSidHistory();
  158. }
  159. VerifyPasswordOption();
  160. DoOption(lOptions, vntInclude, vntExclude);
  161. }
  162. catch (_com_error& ce)
  163. {
  164. hr = AdmtSetError(CLSID_Migration, IID_IUserMigration, ce, IDS_E_CANT_MIGRATE_USERS);
  165. }
  166. catch (...)
  167. {
  168. hr = AdmtSetError(CLSID_Migration, IID_IUserMigration, E_FAIL, IDS_E_CANT_MIGRATE_USERS);
  169. }
  170. if (bLogOpen)
  171. {
  172. _Module.CloseLog();
  173. }
  174. MutexRelease();
  175. return hr;
  176. }
  177. // Implementation -----------------------------------------------------------
  178. // ValidateMigrationParameters Method
  179. void CUserMigration::ValidateMigrationParameters()
  180. {
  181. bool bIntraForest = m_spInternal->IntraForest ? true : false;
  182. if (bIntraForest)
  183. {
  184. // validate conflict option
  185. long lConflictOptions = m_spInternal->ConflictOptions;
  186. long lConflictOption = lConflictOptions & 0x0F;
  187. if (lConflictOption == admtReplaceConflicting)
  188. {
  189. AdmtThrowError(GUID_NULL, GUID_NULL, E_INVALIDARG, IDS_E_INTRA_FOREST_REPLACE);
  190. }
  191. }
  192. }
  193. // DoNames Method
  194. void CUserMigration::DoNames()
  195. {
  196. CDomainAccounts aUsers;
  197. m_SourceDomain.QueryUsers(GetSourceContainer(), m_setIncludeNames, m_setExcludeNames, aUsers);
  198. DoUsers(aUsers, GetTargetContainer());
  199. }
  200. // DoDomain Method
  201. void CUserMigration::DoDomain()
  202. {
  203. CContainer& rSource = GetSourceContainer();
  204. CContainer& rTarget = GetTargetContainer();
  205. if (m_nRecurseMaintain == 2)
  206. {
  207. rTarget.CreateContainerHierarchy(rSource);
  208. }
  209. DoContainers(rSource, rTarget);
  210. }
  211. // DoContainers Method
  212. void CUserMigration::DoContainers(CContainer& rSource, CContainer& rTarget)
  213. {
  214. DoUsers(rSource, rTarget);
  215. if (m_nRecurseMaintain == 2)
  216. {
  217. ContainerVector aContainers;
  218. rSource.QueryContainers(aContainers);
  219. for (ContainerVector::iterator it = aContainers.begin(); it != aContainers.end(); it++)
  220. {
  221. DoContainers(*it, rTarget.GetContainer(it->GetName()));
  222. }
  223. }
  224. }
  225. // DoUsers Method
  226. void CUserMigration::DoUsers(CContainer& rSource, CContainer& rTarget)
  227. {
  228. CDomainAccounts aUsers;
  229. rSource.QueryUsers(m_nRecurseMaintain == 1, m_setExcludeNames, aUsers);
  230. DoUsers(aUsers, rTarget);
  231. }
  232. // DoUsers Method
  233. void CUserMigration::DoUsers(CDomainAccounts& rUsers, CContainer& rTarget)
  234. {
  235. if (rUsers.size() > 0)
  236. {
  237. if (!m_bMigrateServiceAccounts)
  238. {
  239. RemoveServiceAccounts(rUsers);
  240. }
  241. if (rUsers.size() > 0)
  242. {
  243. CVarSet aVarSet;
  244. SetOptions(rTarget.GetPath(), aVarSet);
  245. SetAccountOptions(aVarSet);
  246. VerifyRenameConflictPrefixSuffixValid();
  247. FillInVarSetForUsers(rUsers, aVarSet);
  248. rUsers.clear();
  249. #ifdef _DEBUG
  250. aVarSet.Dump();
  251. #endif
  252. PerformMigration(aVarSet);
  253. SaveSettings(aVarSet);
  254. if ((m_nRecurseMaintain == 2) && m_bMigrateGroups)
  255. {
  256. FixObjectsInHierarchy(_T("group"));
  257. }
  258. }
  259. }
  260. }
  261. // RemoveServiceAccounts Method
  262. void CUserMigration::RemoveServiceAccounts(CDomainAccounts& rUsers)
  263. {
  264. try
  265. {
  266. CVarSet varset;
  267. IIManageDBPtr spDatabase(__uuidof(IManageDB));
  268. IUnknownPtr spunkVarSet(varset.GetInterface());
  269. IUnknown* punkVarset = spunkVarSet;
  270. spDatabase->GetServiceAccount(_bstr_t(_T("")), &punkVarset);
  271. long lCount = varset.Get(_T("ServiceAccountEntries"));
  272. if (lCount > 0)
  273. {
  274. StringSet setNames;
  275. for (long lIndex = 0; lIndex < lCount; lIndex++)
  276. {
  277. setNames.insert(_bstr_t(varset.Get(_T("ServiceAccount.%ld"), lIndex)));
  278. }
  279. _bstr_t strDomain = m_SourceDomain.NameFlat();
  280. for (CDomainAccounts::iterator itUser = rUsers.begin(); itUser != rUsers.end(); )
  281. {
  282. bool bFound = false;
  283. for (StringSet::iterator itName = setNames.begin(); itName != setNames.end(); itName++)
  284. {
  285. if (*itName == itUser->GetUserPrincipalName())
  286. {
  287. bFound = true;
  288. break;
  289. }
  290. if (*itName == (strDomain + _T("\\") + itUser->GetSamAccountName()))
  291. {
  292. bFound = true;
  293. break;
  294. }
  295. }
  296. if (bFound)
  297. {
  298. itUser = rUsers.erase(itUser);
  299. }
  300. else
  301. {
  302. ++itUser;
  303. }
  304. }
  305. }
  306. }
  307. catch (_com_error& ce)
  308. {
  309. AdmtThrowError(GUID_NULL, GUID_NULL, ce, IDS_E_REMOVING_SERVICE_ACCOUNTS);
  310. }
  311. }
  312. // SetOptions Method
  313. void CUserMigration::SetOptions(_bstr_t strTargetOu, CVarSet& rVarSet)
  314. {
  315. CVarSetOptions aOptions(rVarSet);
  316. aOptions.SetTest(m_spInternal->TestMigration ? true : false);
  317. aOptions.SetUndo(false);
  318. aOptions.SetWizard(_T("user"));
  319. aOptions.SetIntraForest(m_spInternal->IntraForest ? true : false);
  320. aOptions.SetSourceDomain(m_SourceDomain.NameFlat(), m_SourceDomain.NameDns(), m_SourceDomain.Sid());
  321. aOptions.SetTargetDomain(m_TargetDomain.NameFlat(), m_TargetDomain.NameDns());
  322. aOptions.SetTargetOu(strTargetOu);
  323. if (m_spInternal->PasswordOption == admtCopyPassword)
  324. {
  325. aOptions.SetTargetServer(m_TargetDomain.DomainControllerName());
  326. }
  327. aOptions.SetRenameOptions(m_spInternal->RenameOption, m_spInternal->RenamePrefixOrSuffix);
  328. }
  329. // SetAccountOptions Method
  330. void CUserMigration::SetAccountOptions(CVarSet& rVarSet)
  331. {
  332. CVarSetAccountOptions aOptions(rVarSet);
  333. aOptions.SetPasswordOption(m_spInternal->PasswordOption, m_spInternal->PasswordServer);
  334. aOptions.SetPasswordFile(m_spInternal->PasswordFile);
  335. aOptions.SetConflictOptions(m_spInternal->ConflictOptions, m_spInternal->ConflictPrefixOrSuffix);
  336. aOptions.SetDisableOption(m_lDisableOption);
  337. aOptions.SetSourceExpiration(m_lSourceExpiration);
  338. aOptions.SetMigrateSids(m_bMigrateSids);
  339. aOptions.SetUserMigrationOptions(m_bMigrateGroups, m_bUpdatePreviouslyMigratedObjects);
  340. // aOptions.SetSidHistoryCredentials(NULL, NULL, NULL);
  341. aOptions.SetFixGroupMembership(m_bFixGroupMembership);
  342. aOptions.SetUpdateUserRights(m_bUpdateUserRights);
  343. aOptions.SetTranslateRoamingProfile(m_bTranslateRoamingProfile);
  344. aOptions.SetExcludedUserProps(m_spInternal->UserPropertiesToExclude);
  345. if (m_bMigrateGroups)
  346. {
  347. aOptions.SetExcludedGroupProps(m_spInternal->GroupPropertiesToExclude);
  348. }
  349. }