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.

415 lines
13 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Windows NT Directory Service Administration SnapIn
  4. //
  5. // Microsoft Windows
  6. // Copyright (C) Microsoft Corporation, 1992 - 1999
  7. //
  8. // File: dssite.cpp
  9. //
  10. // Contents: DS App
  11. //
  12. // History: 04-nov-99 JeffJon Created
  13. //
  14. //--------------------------------------------------------------------------
  15. #include "stdafx.h"
  16. #include "resource.h"
  17. #include "dsutil.h"
  18. #include "uiutil.h"
  19. #include "dssnap.h"
  20. #include "dscmn.h"
  21. #include "ntdsapi.h"
  22. #ifdef FIXUPDC
  23. FixupOptionsMsg g_FixupOptionsMsg[NUM_FIXUP_OPTIONS] = {
  24. {DSROLE_DC_FIXUP_ACCOUNT, IDS_FIXUP_ACCOUNT, FALSE},
  25. {DSROLE_DC_FIXUP_ACCOUNT_PASSWORD, IDS_FIXUP_ACCOUNT_PASSWORD, TRUE},
  26. {DSROLE_DC_FIXUP_ACCOUNT_TYPE, IDS_FIXUP_ACCOUNT_TYPE, TRUE},
  27. {DSROLE_DC_FIXUP_TIME_SERVICE, IDS_FIXUP_TIME_SERVICE, FALSE},
  28. {DSROLE_DC_FIXUP_DC_SERVICES, IDS_FIXUP_DC_SERVICES, FALSE},
  29. {DSROLE_DC_FIXUP_FORCE_SYNC, IDS_FIXUP_FORCE_SYNC, TRUE}
  30. };
  31. #endif // FIXUPDC
  32. #ifdef FIXUPDC
  33. // put back in RESOURCE.H if/when this is restored
  34. #define IDD_FIXUP_DC 239
  35. #define IDC_FIXUP_DC_SERVER 265
  36. #define IDC_FIXUP_DC_CHECK0 266
  37. #define IDC_FIXUP_DC_CHECK1 267
  38. #define IDC_FIXUP_DC_CHECK2 268
  39. #define IDC_FIXUP_DC_CHECK3 269
  40. #define IDC_FIXUP_DC_CHECK4 270
  41. #define IDC_FIXUP_DC_CHECK5 271
  42. #define IDM_GEN_TASK_FIXUP_DC 720
  43. #define IDS_FIXUP_ITSELF 721
  44. #define IDS_FIXUP_REPORT_ERROR 722
  45. #define IDS_FIXUP_REPORT_SUCCESS 723
  46. #define IDS_FIXUP_GEN_ERROR 724
  47. #define IDS_FIXUP_ACCOUNT 725
  48. #define IDS_FIXUP_ACCOUNT_PASSWORD 726
  49. #define IDS_FIXUP_ACCOUNT_TYPE 727
  50. #define IDS_FIXUP_TIME_SERVICE 728
  51. #define IDS_FIXUP_DC_SERVICES 729
  52. #define IDS_FIXUP_FORCE_SYNC 730
  53. #define IDS_FIXUP_DC_SELECTION_WARNING 732
  54. // put back in DSSNAP.RC if/when this is restored
  55. IDD_FIXUP_DC DIALOGEX 0, 0, 211, 163
  56. STYLE DS_MODALFRAME | DS_CONTEXTHELP | WS_POPUP | WS_CAPTION | WS_SYSMENU
  57. CAPTION "Repair Domain Controller"
  58. FONT 8, "MS Shell Dlg", 0, 0, 0x1
  59. BEGIN
  60. LTEXT "Repair:",IDC_STATIC,12,14,33,8
  61. EDITTEXT IDC_FIXUP_DC_SERVER,49,14,155,12,ES_AUTOHSCROLL |
  62. ES_READONLY | NOT WS_BORDER
  63. CONTROL "Repair Computer &Account",IDC_FIXUP_DC_CHECK0,"Button",
  64. BS_AUTOCHECKBOX | WS_TABSTOP,18,35,151,10
  65. CONTROL "Repair Computer Account &Password",IDC_FIXUP_DC_CHECK1,
  66. "Button",BS_AUTOCHECKBOX | WS_TABSTOP,18,48,151,10
  67. CONTROL "Repair Computer Account &Type",IDC_FIXUP_DC_CHECK2,
  68. "Button",BS_AUTOCHECKBOX | WS_TABSTOP,18,61,151,10
  69. CONTROL "&Synchronize Time Service",IDC_FIXUP_DC_CHECK3,"Button",
  70. BS_AUTOCHECKBOX | WS_TABSTOP,18,74,151,10
  71. CONTROL "&Reset Active Directory Services",IDC_FIXUP_DC_CHECK4,
  72. "Button",BS_AUTOCHECKBOX | WS_TABSTOP,18,87,151,10
  73. CONTROL "Synchronize Active &Directory",IDC_FIXUP_DC_CHECK5,
  74. "Button",BS_AUTOCHECKBOX | WS_TABSTOP,18,100,151,10
  75. DEFPUSHBUTTON "&OK",IDOK,29,143,50,14
  76. PUSHBUTTON "&Cancel",IDCANCEL,108,143,50,14
  77. END
  78. IDM_GEN_TASK_FIXUP_DC "Repair Domain Controller...\nRepair domain controller."
  79. IDS_FIXUP_ITSELF "No other domain controllers in the domain can be contacted. Do you want to repair domain controller %1\nusing its local copy of the directory information?"
  80. IDS_FIXUP_REPORT_ERROR "The following operations succeeded:\n%2\nAn error occurred during the following operation:\n%3\nError:%1"
  81. IDS_FIXUP_REPORT_SUCCESS "The following operations succeeded:\n%1"
  82. IDS_FIXUP_GEN_ERROR "The repair of the domain controller was unsuccessful because:\n%1"
  83. IDS_FIXUP_ACCOUNT "\n Repair Computer Account."
  84. IDS_FIXUP_ACCOUNT_PASSWORD "\n Repair Computer Account Password."
  85. IDS_FIXUP_ACCOUNT_TYPE "\n Repair Computer Account Type."
  86. IDS_FIXUP_TIME_SERVICE "\n Synchronize Time Service."
  87. IDS_FIXUP_DC_SERVICES "\n Reset Active Directory Services."
  88. IDS_FIXUP_FORCE_SYNC "\n Synchronize Active Directory."
  89. IDS_FIXUP_DC_SELECTION_WARNING "Make a selection."
  90. HRESULT CDSComponentData::_FixupDC(LPCWSTR pwszPath)
  91. /*++
  92. Routine Description:
  93. This function calls DsRoleFixDc() API to ssync and fixup
  94. local server against other DCs.
  95. Arguments:
  96. pwszPath: The LDAP Path of the local "server" object.
  97. We use this path to get the object, retrieve the server name
  98. and call the DsRoleFixDc() API.
  99. Return Value:
  100. HRESULT
  101. Report Error to user if any
  102. --*/
  103. {
  104. HRESULT hr = S_OK;
  105. CComPtr<IADs> spIADs;
  106. hr = DSAdminOpenObject(pwszPath,
  107. IID_IADs,
  108. (PVOID *)&spIADs,
  109. TRUE /*bServer*/);
  110. if ( SUCCEEDED(hr) ) {
  111. //
  112. // retrieve the local server name
  113. //
  114. CComVariant var;
  115. hr = spIADs->Get(L"dNSHostName", &var);
  116. if ( SUCCEEDED(hr) )
  117. {
  118. ASSERT((var.vt == VT_BSTR) && var.bstrVal && *(var.bstrVal));
  119. LPWSTR lpszServer = var.bstrVal;
  120. CFixupDC dlgFixupDC;
  121. dlgFixupDC.m_strServer = lpszServer;
  122. if (IDCANCEL == dlgFixupDC.DoModal())
  123. goto cleanup; // user cancelled the fixup process
  124. CWaitCursor wait;
  125. DWORD dwReturn = 0;
  126. BOOL fLocal = FALSE;
  127. CString strAccount = _T(""), strPassword = _T("");
  128. DWORD dwOptions = 0;
  129. ULONG ulCompletedOps = 0, ulFailedOps = 0;
  130. for (int i=0; i<NUM_FIXUP_OPTIONS; i++) {
  131. if (dlgFixupDC.m_bCheck[i])
  132. dwOptions |= g_FixupOptionsMsg[i].dwOption;
  133. }
  134. //
  135. // call DsRoleFixDc() API to ssync and fixup the local server
  136. //
  137. do {
  138. dwReturn = DsRoleFixDc(
  139. lpszServer,
  140. (fLocal ? lpszServer : NULL),
  141. (strAccount.IsEmpty() ? NULL : (LPCWSTR)strAccount),
  142. (strAccount.IsEmpty() ? NULL : (LPCWSTR)strPassword),
  143. dwOptions,
  144. &ulCompletedOps,
  145. &ulFailedOps
  146. );
  147. if (ERROR_NO_SUCH_DOMAIN == dwReturn) {
  148. //
  149. // lpszServer is the only DC found in the domain,
  150. // ask if he wants to ssync and fixup the local server against itself
  151. //
  152. PVOID apv[1] = {(PVOID)lpszServer};
  153. if (IDNO == ReportMessageEx(m_hwnd, IDS_FIXUP_ITSELF, MB_YESNO | MB_ICONWARNING, apv, 1) )
  154. goto cleanup; // user cancelled the fixup process
  155. fLocal = TRUE;
  156. } else if (ERROR_ACCESS_DENIED == dwReturn) {
  157. //
  158. // connection failed
  159. // prompt for username and password
  160. //
  161. CPasswordDlg dlgPassword;
  162. if (IDCANCEL == dlgPassword.DoModal())
  163. goto cleanup; // user cancelled the fixup process
  164. strAccount = dlgPassword.m_strUserName;
  165. strPassword = dlgPassword.m_strPassword;
  166. } else {
  167. // either ERROR_SUCCESS or some other error happened
  168. break;
  169. }
  170. } while (TRUE);
  171. //
  172. // report succeeded/failed operations to user
  173. //
  174. CString strCompletedOps = _T(""), strFailedOps = _T("");
  175. CString strMsg;
  176. for (i=0; i<NUM_FIXUP_OPTIONS; i++) {
  177. if (ulCompletedOps & g_FixupOptionsMsg[i].dwOption) {
  178. strMsg.LoadString(g_FixupOptionsMsg[i].nMsgID);
  179. strCompletedOps += strMsg;
  180. }
  181. if (ulFailedOps & g_FixupOptionsMsg[i].dwOption) {
  182. strMsg.LoadString(g_FixupOptionsMsg[i].nMsgID);
  183. strFailedOps += strMsg;
  184. }
  185. }
  186. PVOID apv[2];
  187. apv[0] = (PVOID)(LPCWSTR)strCompletedOps;
  188. apv[1] = (PVOID)(LPCWSTR)strFailedOps;
  189. if (dwReturn != ERROR_SUCCESS) {
  190. ReportErrorEx(m_hwnd, IDS_FIXUP_REPORT_ERROR, dwReturn,
  191. MB_OK | MB_ICONINFORMATION, apv, 2, 0);
  192. } else {
  193. ReportMessageEx(m_hwnd, IDS_FIXUP_REPORT_SUCCESS,
  194. MB_OK | MB_ICONINFORMATION, apv, 1);
  195. }
  196. } // Get()
  197. } // DSAdminOpenObject()
  198. if (FAILED(hr))
  199. ReportErrorEx(m_hwnd, IDS_FIXUP_GEN_ERROR, hr,
  200. MB_OK | MB_ICONINFORMATION, NULL, 0, 0);
  201. cleanup:
  202. return hr;
  203. }
  204. #endif // FIXUPDC
  205. HRESULT CDSComponentData::_RunKCC(LPCWSTR pwszPath)
  206. /*++
  207. Routine Description:
  208. This function calls DsReplicaConsistencyCheck()
  209. to force the KCC to recheck topology immediately.
  210. Arguments:
  211. pwszPath: The LDAP Path of the local "server" object.
  212. We use this path to get the object, retrieve the server name
  213. and call the DsReplicaConsistencyCheck() API.
  214. Return Value:
  215. HRESULT
  216. Report Error to user if any
  217. --*/
  218. {
  219. HRESULT hr = S_OK;
  220. CComPtr<IADs> spIADs;
  221. BOOL fSyncing = FALSE;
  222. CWaitCursor cwait;
  223. CComVariant var;
  224. LPWSTR lpszRunKCCServer = NULL;
  225. do { // false loop
  226. // Bind to "server" object
  227. hr = DSAdminOpenObject(pwszPath,
  228. IID_IADs,
  229. (PVOID *)&spIADs,
  230. TRUE /*bServer*/);
  231. if ( FAILED(hr) )
  232. break;
  233. // retrieve the local server name
  234. hr = spIADs->Get(L"dNSHostName", &var);
  235. if ( FAILED(hr) )
  236. break;
  237. if ((var.vt != VT_BSTR) || !(var.bstrVal) || !(*(var.bstrVal)))
  238. {
  239. ASSERT(FALSE);
  240. hr = E_FAIL;
  241. break;
  242. }
  243. lpszRunKCCServer = var.bstrVal;
  244. // now bind to the target DC
  245. Smart_DsHandle shDS;
  246. DWORD dwWinError = DsBind( lpszRunKCCServer, // DomainControllerAddress
  247. NULL, // DnsDomainName
  248. &shDS );
  249. if (ERROR_SUCCESS != dwWinError)
  250. {
  251. hr = HRESULT_FROM_WIN32(dwWinError);
  252. break;
  253. }
  254. // Run the KCC synchronously on this DSA
  255. fSyncing = TRUE;
  256. dwWinError = DsReplicaConsistencyCheck(
  257. shDS,
  258. DS_KCC_TASKID_UPDATE_TOPOLOGY,
  259. 0 ); // synchronous, not DS_KCC_FLAG_ASYNC_OP
  260. if (ERROR_SUCCESS != dwWinError)
  261. {
  262. hr = HRESULT_FROM_WIN32(dwWinError);
  263. break;
  264. }
  265. } while (FALSE); // false loop
  266. if (FAILED(hr))
  267. {
  268. (void) ReportErrorEx( m_hwnd,
  269. (fSyncing) ? IDS_RUN_KCC_1_FORCESYNC_ERROR
  270. : IDS_RUN_KCC_1_PARAMLOAD_ERROR,
  271. hr,
  272. MB_OK | MB_ICONEXCLAMATION,
  273. NULL,
  274. 0,
  275. IDS_RUN_KCC_TITLE );
  276. } else {
  277. // JonN 3/30/00
  278. // 26926: SITEREPL: Add popup after "Check Replication Topology" execution(DSLAB)
  279. LPCWSTR lpcwszDSADMINServer = NULL;
  280. if (NULL != GetBasePathsInfo())
  281. {
  282. lpcwszDSADMINServer = GetBasePathsInfo()->GetServerName();
  283. if ( !lpszRunKCCServer || !lpcwszDSADMINServer || !wcscmp( lpszRunKCCServer, lpcwszDSADMINServer ) )
  284. lpcwszDSADMINServer = NULL;
  285. }
  286. PVOID apv[2] = { (PVOID)lpszRunKCCServer, (PVOID)lpcwszDSADMINServer };
  287. (void) ReportMessageEx( m_hwnd,
  288. (NULL == lpcwszDSADMINServer)
  289. ? IDS_RUN_KCC_1_SUCCEEDED_LOCAL
  290. : IDS_RUN_KCC_2_SUCCEEDED_REMOTE,
  291. MB_OK | MB_ICONINFORMATION,
  292. apv,
  293. 2,
  294. IDS_RUN_KCC_TITLE );
  295. }
  296. return hr;
  297. }
  298. // JonN 7/23/99
  299. // 373806: Site&Svcs: Renaming an auto-generated connection should make it admin owned
  300. // RETURN TRUE iff rename should proceed, handles own errors
  301. BOOL CDSComponentData::RenameConnectionFixup(CDSCookie* pCookie)
  302. {
  303. ASSERT( NULL != pCookie );
  304. CDSCookieInfoConnection* pextrainfo =
  305. (CDSCookieInfoConnection*)(pCookie->GetExtraInfo());
  306. if ( (NULL == pextrainfo)
  307. || (pextrainfo->GetClass() != CDSCookieInfoBase::connection)
  308. || pextrainfo->m_fFRSConnection
  309. || !(NTDSCONN_OPT_IS_GENERATED & pextrainfo->m_nOptions)
  310. )
  311. return TRUE;
  312. int nResponse = ReportMessageEx (m_hwnd, IDS_CONNECTION_RENAME_WARNING,
  313. MB_YESNO | MB_ICONWARNING);
  314. if (IDYES != nResponse)
  315. return FALSE;
  316. CString szPath;
  317. GetBasePathsInfo()->ComposeADsIPath(szPath, pCookie->GetPath());
  318. CComPtr<IDirectoryObject> spDO;
  319. HRESULT hr = S_OK;
  320. do { // false loop
  321. hr = DSAdminOpenObject(szPath,
  322. IID_IDirectoryObject,
  323. (void **)&spDO,
  324. TRUE /*bServer*/);
  325. if ( FAILED(hr) )
  326. break;
  327. PWSTR rgpwzAttrNames[] = {L"options"};
  328. Smart_PADS_ATTR_INFO spAttrs;
  329. DWORD cAttrs = 1;
  330. hr = spDO->GetObjectAttributes(rgpwzAttrNames, 1, &spAttrs, &cAttrs);
  331. if (FAILED(hr))
  332. break;
  333. if ( !(NTDSCONN_OPT_IS_GENERATED & spAttrs[0].pADsValues->Integer) )
  334. break;
  335. spAttrs[0].pADsValues->Integer &= ~NTDSCONN_OPT_IS_GENERATED;
  336. spAttrs[0].dwControlCode = ADS_ATTR_UPDATE;
  337. ULONG cModified = 0;
  338. hr = spDO->SetObjectAttributes (spAttrs, 1, &cModified);
  339. } while (false); // false loop
  340. if (FAILED(hr)) {
  341. ReportErrorEx (m_hwnd, IDS_CONNECTION_RENAME_ERROR, hr,
  342. MB_OK|MB_ICONERROR, NULL, 0, 0, TRUE);
  343. return FALSE;
  344. }
  345. return TRUE;
  346. }