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.

554 lines
22 KiB

  1. //---------------------------------------------------------------------------
  2. // DisableTarget.cpp
  3. //
  4. // Comment: This is a COM object extension for the MCS DCTAccountReplicator.
  5. // This object implements the IExtendAccountMigration interface. In
  6. // the process method this object disables the Source and the Target
  7. // accounts depending on the settings in the VarSet.
  8. //
  9. // (c) Copyright 1995-1998, Mission Critical Software, Inc., All Rights Reserved
  10. //
  11. // Proprietary and confidential to Mission Critical Software, Inc.
  12. //---------------------------------------------------------------------------
  13. #include "stdafx.h"
  14. #include "ResStr.h"
  15. #include <lm.h>
  16. #include <activeds.h>
  17. #include "AcctDis.h"
  18. #include "DisAcct.h"
  19. #include "ARExt.h"
  20. #include "ARExt_i.c"
  21. #include "ErrDCT.hpp"
  22. //#import "\bin\McsVarSetMin.tlb" no_namespace
  23. //#import "\bin\DBManager.tlb" no_namespace
  24. #import "VarSet.tlb" no_namespace rename("property", "aproperty")
  25. #import "DBMgr.tlb" no_namespace
  26. const int LEN_Path = 255;
  27. StringLoader gString;
  28. #define AR_Status_PasswordError (0x00000400)
  29. /////////////////////////////////////////////////////////////////////////////
  30. // CDisableTarget
  31. //---------------------------------------------------------------------------
  32. // Get and set methods for the properties.
  33. //---------------------------------------------------------------------------
  34. STDMETHODIMP CDisableTarget::get_sName(BSTR *pVal)
  35. {
  36. *pVal = m_sName;
  37. return S_OK;
  38. }
  39. STDMETHODIMP CDisableTarget::put_sName(BSTR newVal)
  40. {
  41. m_sName = newVal;
  42. return S_OK;
  43. }
  44. STDMETHODIMP CDisableTarget::get_sDesc(BSTR *pVal)
  45. {
  46. *pVal = m_sDesc;
  47. return S_OK;
  48. }
  49. STDMETHODIMP CDisableTarget::put_sDesc(BSTR newVal)
  50. {
  51. m_sDesc = newVal;
  52. return S_OK;
  53. }
  54. //---------------------------------------------------------------------------
  55. // ProcessObject : This method doesn't do anything.
  56. //---------------------------------------------------------------------------
  57. STDMETHODIMP CDisableTarget::PreProcessObject(
  58. IUnknown *pSource, //in- Pointer to the source AD object
  59. IUnknown *pTarget, //in- Pointer to the target AD object
  60. IUnknown *pMainSettings, //in- Varset filled with the settings supplied by user
  61. IUnknown **ppPropsToSet, //in,out - Varset filled with Prop-Value pairs that will be set
  62. // once all extension objects are executed.
  63. EAMAccountStats* pStats
  64. )
  65. {
  66. // Check if the object is of user type. if not then there is no point in disabling that account.
  67. IVarSetPtr pVs = pMainSettings;
  68. _bstr_t sType = pVs->get(GET_BSTR(DCTVS_CopiedAccount_Type));
  69. if (!sType.length())
  70. return HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
  71. if (UStrICmp((WCHAR*)sType,L"user") && UStrICmp((WCHAR*)sType,L"inetOrgPerson"))
  72. return S_OK;
  73. if ( pSource )
  74. {
  75. // HRESULT hr = S_OK;
  76. _variant_t vtExp;
  77. _variant_t vtFlag;
  78. _bstr_t sSourceType;
  79. IIManageDBPtr pDb = pVs->get(GET_BSTR(DCTVS_DBManager));
  80. sSourceType = pVs->get(GET_BSTR(DCTVS_CopiedAccount_Type));
  81. if ( !_wcsicmp((WCHAR*) sSourceType, L"user") || !_wcsicmp((WCHAR*) sSourceType, L"inetOrgPerson") )
  82. {
  83. // Get the expiration date and put it into the AR Node.
  84. _bstr_t sSam = pVs->get(GET_BSTR(DCTVS_CopiedAccount_SourceSam));
  85. _bstr_t sComp = pVs->get(GET_BSTR(DCTVS_Options_SourceServer));
  86. USER_INFO_3 * pInfo = NULL;
  87. DWORD rc = NetUserGetInfo((WCHAR*) sComp, (WCHAR*)sSam, 3, (LPBYTE*)&pInfo);
  88. if ( !rc )
  89. {
  90. vtExp = (long)pInfo->usri3_acct_expires;
  91. pVs->put(GET_BSTR(DCTVS_CopiedAccount_ExpDate), vtExp);
  92. // Get the ControlFlag and store it into the AR Node.
  93. vtFlag = (long)pInfo->usri3_flags;
  94. pVs->put(GET_BSTR(DCTVS_CopiedAccount_UserFlags), vtFlag);
  95. if ( pInfo ) NetApiBufferFree(pInfo);
  96. }
  97. }
  98. pDb->raw_SaveUserProps(pMainSettings);
  99. }
  100. return S_OK;
  101. }
  102. //---------------------------------------------------------------------------
  103. // ProcessObject : This method checks in varset if it needs to disable any
  104. // accounts. If it does then it disables those accounts.
  105. //---------------------------------------------------------------------------
  106. STDMETHODIMP CDisableTarget::ProcessObject(
  107. IUnknown *pSource, //in- Pointer to the source AD object
  108. IUnknown *pTarget, //in- Pointer to the target AD object
  109. IUnknown *pMainSettings, //in- Varset filled with the settings supplied by user
  110. IUnknown **ppPropsToSet, //in,out - Varset filled with Prop-Value pairs that will be set
  111. // once all extension objects are executed.
  112. EAMAccountStats* pStats
  113. )
  114. {
  115. IVarSetPtr pVarSet = pMainSettings;
  116. _variant_t var;
  117. DWORD paramErr;
  118. USER_INFO_3 * info = NULL;
  119. long rc;
  120. WCHAR strDomain[LEN_Path];
  121. WCHAR strAcct[LEN_Path];
  122. HRESULT hr = S_OK;
  123. TErrorDct err;
  124. WCHAR fileName[LEN_Path];
  125. BOOL bDisableSource = FALSE;
  126. BOOL bExpireSource = FALSE;
  127. _bstr_t temp;
  128. time_t expireTime = 0;
  129. _bstr_t bstrSameForest;
  130. BOOL bSameAsSource = FALSE;
  131. BOOL bDisableTarget = FALSE;
  132. BOOL bGotSrcState = FALSE;
  133. BOOL bSrcDisabled = FALSE;
  134. bstrSameForest = pVarSet->get(GET_BSTR(DCTVS_Options_IsIntraforest));
  135. if (! UStrICmp((WCHAR*)bstrSameForest,GET_STRING(IDS_YES)) )
  136. {
  137. // in the intra-forest case, we are moving the user accounts, not
  138. // copying them, so these disabling/expiring options don't make any sense
  139. return S_OK;
  140. }
  141. // Get the Error log filename from the Varset
  142. var = pVarSet->get(GET_BSTR(DCTVS_Options_Logfile));
  143. wcscpy(fileName, (WCHAR*)V_BSTR(&var));
  144. VariantInit(&var);
  145. // Open the error log
  146. err.LogOpen(fileName, 1);
  147. // Check if the object is of user type. if not then there is no point in disabling that account.
  148. var = pVarSet->get(GET_BSTR(DCTVS_CopiedAccount_Type));
  149. if ( UStrICmp(var.bstrVal,L"user") && UStrICmp(var.bstrVal,L"inetOrgPerson") )
  150. {
  151. return S_OK;
  152. }
  153. //set flags based on user selections
  154. temp = pVarSet->get(GET_BSTR(DCTVS_AccountOptions_DisableSourceAccounts));
  155. if ( ! UStrICmp(temp,GET_STRING(IDS_YES)) )
  156. {
  157. bDisableSource = TRUE;
  158. }
  159. //
  160. // If disable target account option is true or unable to
  161. // set password for this account then disable account.
  162. //
  163. temp = pVarSet->get(GET_BSTR(DCTVS_AccountOptions_DisableCopiedAccounts));
  164. long lStatus = pVarSet->get(GET_BSTR(DCTVS_CopiedAccount_Status));
  165. if ( ! UStrICmp(temp,GET_STRING(IDS_YES)) || (lStatus & AR_Status_PasswordError) )
  166. {
  167. bDisableTarget = TRUE;
  168. }
  169. temp = pVarSet->get(GET_BSTR(DCTVS_AccountOptions_TgtStateSameAsSrc));
  170. if ( ! UStrICmp(temp,GET_STRING(IDS_YES)) )
  171. {
  172. bSameAsSource = TRUE;
  173. }
  174. /* process the source account */
  175. //if expire source accounts was set, retrieve the expire time, now given to us in
  176. //number of days from now
  177. temp = pVarSet->get(GET_BSTR(DCTVS_AccountOptions_ExpireSourceAccounts));
  178. if ( temp.length() )
  179. {
  180. long oneDay = 24 * 60 * 60; // number of seconds in 1 day
  181. //get days until expire
  182. long lExpireDays = _wtol(temp);
  183. //get the current time
  184. time_t currentTime = time(NULL);
  185. //convert current time to local time
  186. struct tm * convtm;
  187. convtm = localtime(&currentTime);
  188. //rollback to this morning
  189. convtm->tm_hour = 0;
  190. convtm->tm_min = 0;
  191. convtm->tm_sec = 0;
  192. //convert this time back to GMT
  193. expireTime = mktime(convtm);
  194. //move forward to tonight at midnight
  195. expireTime += oneDay;
  196. //now add the desired number of days
  197. expireTime += lExpireDays * oneDay;
  198. bExpireSource = TRUE;
  199. }
  200. //get source account state
  201. var = pVarSet->get(GET_BSTR(DCTVS_CopiedAccount_SourceSam));
  202. wcscpy(strAcct, (WCHAR*)V_BSTR(&var));
  203. var = pVarSet->get(GET_BSTR(DCTVS_Options_SourceServer));
  204. wcscpy(strDomain, (WCHAR*)V_BSTR(&var));
  205. // we will use the net APIs to disable the source account
  206. rc = NetUserGetInfo(strDomain, strAcct, 3, (LPBYTE *)&info);
  207. if (rc != 0)
  208. {
  209. hr = S_FALSE;
  210. if (bDisableSource || bExpireSource || bSameAsSource)
  211. {
  212. if (pStats != NULL)
  213. {
  214. pStats->errors.users++;
  215. }
  216. err.SysMsgWrite(ErrE, rc, DCT_MSG_UNABLE_RETRIEVE_SOURCE_DISABLE_STATE_S, strAcct);
  217. if (bDisableSource || bExpireSource)
  218. {
  219. err.MsgWrite(ErrE, DCT_MSG_ACCOUNT_DISABLE_OR_EXPIRE_FAILED_S, strAcct);
  220. }
  221. if (bSameAsSource)
  222. {
  223. err.MsgWrite(ErrE, DCT_MSG_CANNOT_ENABLEDISABLE_TARGET_SAMEASSOURCE_S, strAcct);
  224. }
  225. }
  226. }
  227. else
  228. {
  229. bGotSrcState = TRUE;
  230. //set current source account state
  231. if (info->usri3_flags & UF_ACCOUNTDISABLE)
  232. bSrcDisabled = TRUE;
  233. //also save the flags in the varset to be used in setpass ARExt
  234. _variant_t vtFlag = (long)info->usri3_flags;
  235. pVarSet->put(GET_BSTR(DCTVS_CopiedAccount_UserFlags), vtFlag);
  236. //disable the source account if requested
  237. if (bDisableSource)
  238. {
  239. // Set the disable flag
  240. info->usri3_flags |= UF_ACCOUNTDISABLE;
  241. }
  242. //expire the account in given timeframe, if requested
  243. if ( bExpireSource )
  244. {
  245. if (((time_t)info->usri3_acct_expires == TIMEQ_FOREVER)
  246. || ((time_t)info->usri3_acct_expires > expireTime))
  247. {
  248. info->usri3_acct_expires = (DWORD)expireTime;
  249. }
  250. }
  251. //if changed, set the source information into the Domain.
  252. if (bDisableSource || bExpireSource)
  253. {
  254. rc = NetUserSetInfo(strDomain,strAcct, 3, (LPBYTE)info, &paramErr);
  255. if (rc == NERR_Success)
  256. {
  257. if (bDisableSource)
  258. {
  259. err.MsgWrite(0, DCT_MSG_SOURCE_DISABLED_S, strAcct);
  260. }
  261. if ( bExpireSource )
  262. {
  263. if (((time_t)info->usri3_acct_expires == TIMEQ_FOREVER) ||
  264. ((time_t)info->usri3_acct_expires > expireTime))
  265. {
  266. err.MsgWrite(0, DCT_MSG_SOURCE_EXPIRED_S, strAcct);
  267. }
  268. else
  269. {
  270. err.MsgWrite(0, DCT_MSG_SOURCE_EXPIRATION_EARLY_S, strAcct);
  271. }
  272. }
  273. }
  274. else
  275. {
  276. if (pStats != NULL)
  277. pStats->errors.users++;
  278. err.SysMsgWrite(ErrE, rc, DCT_MSG_ACCOUNT_DISABLE_OR_EXPIRE_FAILED_S, strAcct);
  279. }
  280. }
  281. NetApiBufferFree((LPVOID) info);
  282. }//if got current src account state
  283. /* process the target account */
  284. //get the target state
  285. var = pVarSet->get(GET_BSTR(DCTVS_CopiedAccount_TargetSam));
  286. wcscpy(strAcct, (WCHAR*)V_BSTR(&var));
  287. var = pVarSet->get(GET_BSTR(DCTVS_Options_TargetServer));
  288. wcscpy(strDomain, (WCHAR*)V_BSTR(&var));
  289. // we will use the net APIs to disable the target account
  290. rc = NetUserGetInfo(strDomain, strAcct, 3, (LPBYTE *)&info);
  291. if (rc != NERR_Success)
  292. {
  293. hr = S_FALSE;
  294. if (pStats != NULL)
  295. pStats->errors.users++;
  296. err.SysMsgWrite(ErrE, rc, DCT_MSG_DISABLE_TARGET_FAILED_S, strAcct);
  297. }
  298. else
  299. {
  300. //disable the target if requested
  301. if (bDisableTarget)
  302. {
  303. // Set the disable flag
  304. info->usri3_flags |= UF_ACCOUNTDISABLE;
  305. // Set the information into the Domain.
  306. rc = NetUserSetInfo(strDomain, strAcct, 3, (LPBYTE)info, &paramErr);
  307. if (rc == NERR_Success)
  308. {
  309. err.MsgWrite(0, DCT_MSG_TARGET_DISABLED_S, strAcct);
  310. }
  311. else
  312. {
  313. if (pStats != NULL)
  314. pStats->errors.users++;
  315. err.SysMsgWrite(ErrE, rc, DCT_MSG_DISABLE_TARGET_FAILED_S, strAcct);
  316. }
  317. }
  318. //else make target same state as source was
  319. else if (bSameAsSource)
  320. {
  321. //if the source was disabled or unable to retrieve source state, disable the target
  322. if (bSrcDisabled || !bGotSrcState)
  323. {
  324. //disable the target
  325. info->usri3_flags |= UF_ACCOUNTDISABLE;
  326. // Set the information into the Domain.
  327. rc = NetUserSetInfo( strDomain, strAcct, 3, (LPBYTE)info, &paramErr);
  328. if (rc == NERR_Success)
  329. {
  330. err.MsgWrite(0, DCT_MSG_TARGET_DISABLED_S, strAcct);
  331. }
  332. else
  333. {
  334. if (pStats != NULL)
  335. pStats->errors.users++;
  336. err.SysMsgWrite(ErrE, rc, DCT_MSG_DISABLE_TARGET_FAILED_S, strAcct);
  337. }
  338. }
  339. else //else make sure target is enabled and not set to expire
  340. {
  341. info->usri3_flags &= ~UF_ACCOUNTDISABLE;
  342. rc = NetUserSetInfo(strDomain,strAcct,3,(LPBYTE)info,&paramErr);
  343. if (rc != NERR_Success)
  344. {
  345. if (pStats != NULL)
  346. pStats->warnings.users++;
  347. err.SysMsgWrite(ErrW, rc, DCT_MSG_ENABLE_TARGET_FAILED_S, strAcct);
  348. }
  349. }
  350. }
  351. else //else make sure target is enabled and not set to expire
  352. {
  353. info->usri3_flags &= ~UF_ACCOUNTDISABLE;
  354. rc = NetUserSetInfo(strDomain,strAcct,3,(LPBYTE)info,&paramErr);
  355. if (rc != NERR_Success)
  356. {
  357. if (pStats != NULL)
  358. pStats->warnings.users++;
  359. err.SysMsgWrite(ErrW, rc, DCT_MSG_ENABLE_TARGET_FAILED_S, strAcct);
  360. }
  361. }
  362. NetApiBufferFree((LPVOID) info);
  363. }
  364. return hr;
  365. }
  366. //---------------------------------------------------------------------------
  367. // ProcessUndo : This function Enables the accounts that were previously
  368. // disabled..
  369. //---------------------------------------------------------------------------
  370. STDMETHODIMP CDisableTarget::ProcessUndo(
  371. IUnknown *pSource, //in- Pointer to the source AD object
  372. IUnknown *pTarget, //in- Pointer to the target AD object
  373. IUnknown *pMainSettings, //in- Varset filled with the settings supplied by user
  374. IUnknown **ppPropsToSet, //in,out - Varset filled with Prop-Value pairs that will be set
  375. // once all extension objects are executed.
  376. EAMAccountStats* pStats
  377. )
  378. {
  379. IVarSetPtr pVarSet = pMainSettings;
  380. IIManageDBPtr pDb = pVarSet->get(GET_BSTR(DCTVS_DBManager));
  381. _variant_t var;
  382. DWORD paramErr;
  383. USER_INFO_3 * info;
  384. long rc;
  385. WCHAR strDomain[LEN_Path];
  386. WCHAR strAcct[LEN_Path];
  387. HRESULT hr = S_OK;
  388. TErrorDct err;
  389. IUnknown * pUnk = NULL;
  390. _bstr_t sSourceName, sSourceDomain, sTgtDomain;
  391. WCHAR fileName[LEN_Path];
  392. IVarSetPtr pVs(__uuidof(VarSet));
  393. _variant_t vtExp, vtFlag;
  394. _bstr_t sDomainName = pVarSet->get(GET_BSTR(DCTVS_Options_SourceDomain));
  395. pVs->QueryInterface(IID_IUnknown, (void**)&pUnk);
  396. sSourceName = pVarSet->get(GET_BSTR(DCTVS_CopiedAccount_SourceSam));
  397. sSourceDomain = pVarSet->get(GET_BSTR(DCTVS_Options_SourceDomain));
  398. sTgtDomain = pVarSet->get(GET_BSTR(DCTVS_Options_TargetDomain));
  399. hr = pDb->raw_GetUserProps(sSourceDomain, sSourceName, &pUnk);
  400. if ( pUnk ) pUnk->Release();
  401. if ( hr == S_OK )
  402. {
  403. vtExp = pVs->get(GET_BSTR(DCTVS_CopiedAccount_ExpDate));
  404. vtFlag = pVs->get(GET_BSTR(DCTVS_CopiedAccount_UserFlags));
  405. }
  406. // Get the Error log filename from the Varset
  407. var = pVarSet->get(GET_BSTR(DCTVS_Options_Logfile));
  408. wcscpy(fileName, (WCHAR*)V_BSTR(&var));
  409. VariantInit(&var);
  410. // Open the error log
  411. err.LogOpen(fileName, 1);
  412. // Check if the object is of user type. if not then there is no point in disabling that account.
  413. var = pVarSet->get(GET_BSTR(DCTVS_CopiedAccount_Type));
  414. if ( _wcsicmp((WCHAR*)V_BSTR(&var),L"user") != 0 && _wcsicmp((WCHAR*)V_BSTR(&var),L"inetOrgPerson") != 0 )
  415. return S_OK;
  416. _bstr_t sDis = pVarSet->get(GET_BSTR(DCTVS_AccountOptions_DisableSourceAccounts));
  417. _bstr_t sExp = pVarSet->get(GET_BSTR(DCTVS_AccountOptions_ExpireSourceAccounts));
  418. if ( !wcscmp((WCHAR*)sDis,GET_STRING(IDS_YES)) || sExp.length() )
  419. {
  420. // Reset the flag and the expiration date for the source account.
  421. var = pVarSet->get(GET_BSTR(DCTVS_CopiedAccount_SourceSam));
  422. wcscpy(strAcct, (WCHAR*)V_BSTR(&var));
  423. var = pVarSet->get(GET_BSTR(DCTVS_Options_SourceServer));
  424. wcscpy(strDomain, (WCHAR*)V_BSTR(&var));
  425. // we will use the net APIs to disable the source account
  426. rc = NetUserGetInfo( strDomain, strAcct, 3, (LPBYTE *)&info);
  427. if (rc != NERR_Success)
  428. {
  429. hr = S_FALSE;
  430. if (pStats != NULL)
  431. pStats->warnings.users++;
  432. err.SysMsgWrite(ErrW, rc, DCT_MSG_ENABLE_SOURCE_FAILED_S, strAcct);
  433. }
  434. else
  435. {
  436. // Set the disable flag
  437. info->usri3_flags = vtFlag.lVal;
  438. info->usri3_acct_expires = vtExp.lVal;
  439. // Set the information into the Domain.
  440. rc = NetUserSetInfo(strDomain,strAcct, 3, (LPBYTE)info, &paramErr);
  441. NetApiBufferFree((LPVOID) info);
  442. if (rc == NERR_Success)
  443. {
  444. err.MsgWrite(0, DCT_MSG_SOURCE_ENABLED_S, strAcct);
  445. }
  446. else
  447. {
  448. if (pStats != NULL)
  449. pStats->warnings.users++;
  450. err.SysMsgWrite(ErrW, rc, DCT_MSG_ENABLE_SOURCE_FAILED_S, strAcct);
  451. }
  452. }
  453. }
  454. // Process the target account if the Varset is set
  455. var = pVarSet->get(GET_BSTR(DCTVS_AccountOptions_DisableCopiedAccounts));
  456. if ( (var.vt == VT_BSTR) && (_wcsicmp((WCHAR*)V_BSTR(&var),GET_STRING(IDS_YES)) == 0) )
  457. {
  458. var = pVarSet->get(GET_BSTR(DCTVS_CopiedAccount_TargetSam));
  459. wcscpy(strAcct, (WCHAR*)V_BSTR(&var));
  460. var = pVarSet->get(GET_BSTR(DCTVS_Options_TargetServer));
  461. wcscpy(strDomain, (WCHAR*)V_BSTR(&var));
  462. // we will use the net APIs to disable the target account
  463. rc = NetUserGetInfo( strDomain, strAcct, 3, (LPBYTE *)&info);
  464. if (rc != NERR_Success)
  465. {
  466. hr = S_FALSE;
  467. if (pStats != NULL)
  468. pStats->warnings.users++;
  469. err.SysMsgWrite(ErrW, rc, DCT_MSG_ENABLE_TARGET_FAILED_S, strAcct);
  470. }
  471. else
  472. {
  473. // clear the disable flag
  474. info->usri3_flags &= ~(UF_ACCOUNTDISABLE);
  475. // Set the information into the Domain.
  476. rc = NetUserSetInfo( strDomain, strAcct, 3, (LPBYTE)info, &paramErr);
  477. NetApiBufferFree((LPVOID) info);
  478. if (rc == NERR_Success)
  479. {
  480. err.MsgWrite(0, DCT_MSG_TARGET_ENABLED_S, strAcct);
  481. }
  482. else
  483. {
  484. if (pStats != NULL)
  485. pStats->warnings.users++;
  486. err.SysMsgWrite(ErrW, rc, DCT_MSG_ENABLE_TARGET_FAILED_S, strAcct);
  487. }
  488. }
  489. }
  490. WCHAR sFilter[5000];
  491. wsprintf(sFilter, L"SourceDomain='%s' and SourceSam='%s'", (WCHAR*)sDomainName, strAcct);
  492. _variant_t Filter = sFilter;
  493. pDb->raw_ClearTable(L"UserProps", Filter);
  494. err.LogClose();
  495. return hr;
  496. }