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.

513 lines
13 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(false)
  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. SetDefaultExcludedSystemProperties();
  154. VerifyInterIntraForest();
  155. VerifyCallerDelegated();
  156. ValidateMigrationParameters();
  157. if (m_bMigrateSids)
  158. {
  159. VerifyCanAddSidHistory();
  160. }
  161. VerifyPasswordOption();
  162. DoOption(lOptions, vntInclude, vntExclude);
  163. }
  164. catch (_com_error& ce)
  165. {
  166. _Module.Log(ErrE, IDS_E_CANT_MIGRATE_USERS, ce);
  167. hr = AdmtSetError(CLSID_Migration, IID_IUserMigration, ce, IDS_E_CANT_MIGRATE_USERS);
  168. }
  169. catch (...)
  170. {
  171. _Module.Log(ErrE, IDS_E_CANT_MIGRATE_USERS, _com_error(E_FAIL));
  172. hr = AdmtSetError(CLSID_Migration, IID_IUserMigration, E_FAIL, IDS_E_CANT_MIGRATE_USERS);
  173. }
  174. if (bLogOpen)
  175. {
  176. _Module.CloseLog();
  177. }
  178. MutexRelease();
  179. return hr;
  180. }
  181. // Implementation -----------------------------------------------------------
  182. // ValidateMigrationParameters Method
  183. void CUserMigration::ValidateMigrationParameters()
  184. {
  185. bool bIntraForest = m_spInternal->IntraForest ? true : false;
  186. if (bIntraForest)
  187. {
  188. // validate conflict option
  189. long lConflictOptions = m_spInternal->ConflictOptions;
  190. long lConflictOption = lConflictOptions & 0x0F;
  191. if (lConflictOption == admtReplaceConflicting)
  192. {
  193. AdmtThrowError(GUID_NULL, GUID_NULL, E_INVALIDARG, IDS_E_INTRA_FOREST_REPLACE);
  194. }
  195. }
  196. }
  197. // DoNames Method
  198. void CUserMigration::DoNames()
  199. {
  200. CDomainAccounts aUsers;
  201. m_SourceDomain.QueryUsers(GetSourceContainer(), m_setIncludeNames, m_setExcludeNames, aUsers);
  202. DoUsers(aUsers, GetTargetContainer());
  203. }
  204. // DoDomain Method
  205. void CUserMigration::DoDomain()
  206. {
  207. CContainer& rSource = GetSourceContainer();
  208. CContainer& rTarget = GetTargetContainer();
  209. if (m_nRecurseMaintain == 2)
  210. {
  211. rTarget.CreateContainerHierarchy(rSource);
  212. }
  213. DoContainers(rSource, rTarget);
  214. }
  215. // DoContainers Method
  216. void CUserMigration::DoContainers(CContainer& rSource, CContainer& rTarget)
  217. {
  218. DoUsers(rSource, rTarget);
  219. if (m_nRecurseMaintain == 2)
  220. {
  221. ContainerVector aContainers;
  222. rSource.QueryContainers(aContainers);
  223. for (ContainerVector::iterator it = aContainers.begin(); it != aContainers.end(); it++)
  224. {
  225. DoContainers(*it, rTarget.GetContainer(it->GetName()));
  226. }
  227. }
  228. }
  229. // DoUsers Method
  230. void CUserMigration::DoUsers(CContainer& rSource, CContainer& rTarget)
  231. {
  232. CDomainAccounts aUsers;
  233. rSource.QueryUsers(m_nRecurseMaintain == 1, m_setExcludeNames, aUsers);
  234. DoUsers(aUsers, rTarget);
  235. }
  236. // DoUsers Method
  237. void CUserMigration::DoUsers(CDomainAccounts& rUsers, CContainer& rTarget)
  238. {
  239. if (rUsers.size() > 0)
  240. {
  241. if (!m_bMigrateServiceAccounts)
  242. {
  243. RemoveServiceAccounts(rUsers);
  244. }
  245. if (rUsers.size() > 0)
  246. {
  247. CVarSet aVarSet;
  248. SetOptions(rTarget.GetPath(), aVarSet);
  249. SetAccountOptions(aVarSet);
  250. VerifyRenameConflictPrefixSuffixValid();
  251. FillInVarSetForUsers(rUsers, aVarSet);
  252. rUsers.clear();
  253. #ifdef _DEBUG
  254. aVarSet.Dump();
  255. #endif
  256. PerformMigration(aVarSet);
  257. SaveSettings(aVarSet);
  258. if ((m_nRecurseMaintain == 2) && m_bMigrateGroups)
  259. {
  260. FixObjectsInHierarchy(_T("group"));
  261. }
  262. }
  263. }
  264. }
  265. // RemoveServiceAccounts Method
  266. void CUserMigration::RemoveServiceAccounts(CDomainAccounts& rUsers)
  267. {
  268. try
  269. {
  270. CVarSet varset;
  271. IIManageDBPtr spDatabase(__uuidof(IManageDB));
  272. IUnknownPtr spunkVarSet(varset.GetInterface());
  273. IUnknown* punkVarset = spunkVarSet;
  274. spDatabase->GetServiceAccount(_bstr_t(_T("")), &punkVarset);
  275. long lCount = varset.Get(_T("ServiceAccountEntries"));
  276. if (lCount > 0)
  277. {
  278. StringSet setNames;
  279. for (long lIndex = 0; lIndex < lCount; lIndex++)
  280. {
  281. setNames.insert(_bstr_t(varset.Get(_T("ServiceAccount.%ld"), lIndex)));
  282. }
  283. _bstr_t strDomain = m_SourceDomain.NameFlat();
  284. for (CDomainAccounts::iterator itUser = rUsers.begin(); itUser != rUsers.end(); )
  285. {
  286. bool bFound = false;
  287. _bstr_t strAccountName = strDomain + _T("\\") + itUser->GetSamAccountName();
  288. _bstr_t strUserPrincipalName = itUser->GetUserPrincipalName();
  289. PCTSTR pszAccountName = strAccountName;
  290. PCTSTR pszUserPrincipalName = strUserPrincipalName;
  291. for (StringSet::iterator itName = setNames.begin(); itName != setNames.end(); itName++)
  292. {
  293. PCTSTR pszName = *itName;
  294. if (pszName)
  295. {
  296. if (pszAccountName && (_tcsicmp(pszName, pszAccountName) == 0))
  297. {
  298. bFound = true;
  299. break;
  300. }
  301. if (pszUserPrincipalName && (_tcsicmp(pszName, pszUserPrincipalName) == 0))
  302. {
  303. bFound = true;
  304. break;
  305. }
  306. }
  307. }
  308. if (bFound)
  309. {
  310. itUser = rUsers.erase(itUser);
  311. }
  312. else
  313. {
  314. ++itUser;
  315. }
  316. }
  317. }
  318. }
  319. catch (_com_error& ce)
  320. {
  321. AdmtThrowError(GUID_NULL, GUID_NULL, ce, IDS_E_REMOVING_SERVICE_ACCOUNTS);
  322. }
  323. }
  324. // SetOptions Method
  325. void CUserMigration::SetOptions(_bstr_t strTargetOu, CVarSet& rVarSet)
  326. {
  327. CVarSetOptions aOptions(rVarSet);
  328. aOptions.SetTest(m_spInternal->TestMigration ? true : false);
  329. aOptions.SetUndo(false);
  330. aOptions.SetWizard(_T("user"));
  331. aOptions.SetIntraForest(m_spInternal->IntraForest ? true : false);
  332. aOptions.SetSourceDomain(m_SourceDomain.NameFlat(), m_SourceDomain.NameDns(), m_SourceDomain.Sid());
  333. aOptions.SetTargetDomain(m_TargetDomain.NameFlat(), m_TargetDomain.NameDns());
  334. aOptions.SetTargetOu(strTargetOu);
  335. if (m_bMigrateSids || (m_spInternal->PasswordOption == admtCopyPassword))
  336. {
  337. aOptions.SetTargetServer(
  338. m_TargetDomain.DomainControllerNameFlat(),
  339. m_TargetDomain.DomainControllerNameDns()
  340. );
  341. }
  342. aOptions.SetRenameOptions(m_spInternal->RenameOption, m_spInternal->RenamePrefixOrSuffix);
  343. }
  344. // SetAccountOptions Method
  345. void CUserMigration::SetAccountOptions(CVarSet& rVarSet)
  346. {
  347. CVarSetAccountOptions aOptions(rVarSet);
  348. aOptions.SetPasswordOption(m_spInternal->PasswordOption, m_spInternal->PasswordServer);
  349. aOptions.SetPasswordFile(m_spInternal->PasswordFile);
  350. aOptions.SetConflictOptions(m_spInternal->ConflictOptions, m_spInternal->ConflictPrefixOrSuffix);
  351. aOptions.SetDisableOption(m_lDisableOption);
  352. aOptions.SetSourceExpiration(m_lSourceExpiration);
  353. aOptions.SetMigrateSids(m_bMigrateSids);
  354. aOptions.SetUserMigrationOptions(m_bMigrateGroups, m_bUpdatePreviouslyMigratedObjects);
  355. aOptions.SetFixGroupMembership(m_bFixGroupMembership);
  356. aOptions.SetUpdateUserRights(m_bUpdateUserRights);
  357. aOptions.SetTranslateRoamingProfile(m_bTranslateRoamingProfile);
  358. aOptions.SetExcludedUserProps(m_spInternal->UserPropertiesToExclude);
  359. aOptions.SetExcludedInetOrgPersonProps(m_spInternal->InetOrgPersonPropertiesToExclude);
  360. if (m_bMigrateGroups)
  361. {
  362. aOptions.SetExcludedGroupProps(m_spInternal->GroupPropertiesToExclude);
  363. }
  364. }