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.

1356 lines
37 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1999 - 1999
  6. //
  7. // File: rename.cpp
  8. //
  9. //--------------------------------------------------------------------------
  10. #include "stdafx.h"
  11. #include "resource.h"
  12. #include "dsutil.h"
  13. #include "rename.h"
  14. #include "dsdirect.h"
  15. #include "dsdlgs.h"
  16. #include "dssnap.h"
  17. #include "querysup.h"
  18. #include <dsgetdc.h> // DsValidateSubnetName
  19. ////////////////////////////////////////////////////////////////////////////
  20. // CDSRenameObject
  21. //
  22. HRESULT CDSRenameObject::CommitRenameToDS()
  23. {
  24. //
  25. // Verify data members
  26. //
  27. if (m_pUINode == NULL || m_pCookie == NULL || m_pComponentData == NULL)
  28. {
  29. ASSERT(FALSE);
  30. return E_INVALIDARG;
  31. }
  32. HRESULT hr = S_OK;
  33. hr = m_pComponentData->GetActiveDS()->RenameObject (m_pCookie, m_szNewName);
  34. if (FAILED(hr))
  35. {
  36. TRACE (_T("ADsI::RenameObject failed with hr = %lx\n"), hr);
  37. PVOID apv[1] = {(BSTR)(LPWSTR)(LPCWSTR)m_pCookie->GetName()};
  38. ReportErrorEx (m_hwnd,IDS_12_OBJECT_RENAME_FAILED,hr,
  39. MB_OK | MB_ICONERROR, apv, 1);
  40. }
  41. if (SUCCEEDED(hr))
  42. {
  43. //
  44. // update the data to be displayed
  45. //
  46. hr = m_pComponentData->UpdateFromDS(m_pUINode);
  47. }
  48. if ((SUCCEEDED(hr) && (hr != S_FALSE)) && m_pUINode->IsContainer())
  49. {
  50. if (m_pComponentData->IsSelectionAnywhere (m_pUINode))
  51. {
  52. m_pComponentData->Refresh (m_pUINode);
  53. }
  54. else
  55. {
  56. m_pComponentData->ClearSubtreeHelperForRename(m_pUINode);
  57. }
  58. }
  59. return hr;
  60. }
  61. //+------------------------------------------------------------------
  62. //
  63. // Function: CDSRenameObject::ValidateAndModifyName
  64. //
  65. // Synopsis: Takes a string and prompts the user to replace it
  66. // with the replacement char if it contains any of the
  67. // "illegal" characters
  68. //
  69. // Returns: HRESULT - S_OK if the string does not contain any of
  70. // illegal chars
  71. // S_FALSE if the user chose to replace the
  72. // illegal chars
  73. // E_FAIL if the string contained illegal
  74. // chars but the user did not choose
  75. // to replace them
  76. //
  77. //---------------------------------------------------------------------
  78. HRESULT CDSRenameObject::ValidateAndModifyName(CString& refName,
  79. PCWSTR pszIllegalChars,
  80. WCHAR wReplacementChar,
  81. UINT nModifyStringID,
  82. HWND hWnd)
  83. {
  84. HRESULT hr = S_OK;
  85. int iFind = refName.FindOneOf(pszIllegalChars);
  86. if (iFind != -1 && !refName.IsEmpty())
  87. {
  88. PVOID apv[1] = {(LPWSTR)(LPCWSTR)refName};
  89. if (IDYES == ReportErrorEx (hWnd,nModifyStringID,S_OK,
  90. MB_YESNO | MB_ICONWARNING, apv, 1))
  91. {
  92. while (iFind != -1)
  93. {
  94. refName.SetAt(iFind, wReplacementChar);
  95. iFind = refName.FindOneOf(pszIllegalChars);
  96. hr = S_FALSE;
  97. }
  98. }
  99. else
  100. {
  101. hr = E_FAIL;
  102. }
  103. }
  104. return hr;
  105. }
  106. HRESULT CDSRenameObject::DoRename()
  107. {
  108. HRESULT hr = S_OK;
  109. hr = CommitRenameToDS();
  110. return hr;
  111. }
  112. /////////////////////////////////////////////////////////////////////////////
  113. // CDSRenameUser
  114. //
  115. HRESULT CDSRenameUser::DoRename()
  116. {
  117. CThemeContextActivator activator;
  118. //
  119. // Verify data members
  120. //
  121. if (m_pUINode == NULL || m_pCookie == NULL || m_pComponentData == NULL)
  122. {
  123. ASSERT(FALSE);
  124. return E_INVALIDARG;
  125. }
  126. HRESULT hr = S_OK;
  127. //
  128. // Need to warn user that renaming themselves may cause problems if they
  129. // don't logoff and back on.
  130. //
  131. PCWSTR path = m_pCookie->GetPath();
  132. if (IsThisUserLoggedIn(path))
  133. {
  134. PWSTR name = 0;
  135. CComBSTR sbstrRDN;
  136. (void) DSPROP_RetrieveRDN( path, &sbstrRDN );
  137. name = sbstrRDN;
  138. PVOID apv[1] = {(PVOID)name};
  139. if (IDYES != ReportMessageEx (m_hwnd, IDS_12_USER_LOGGED_IN_RENAME,
  140. MB_YESNO, apv, 1))
  141. {
  142. return HRESULT_FROM_WIN32(ERROR_CANCELLED);
  143. }
  144. }
  145. //
  146. // rename user : get the new name from the dialog
  147. //
  148. CRenameUserDlg dlgRename(m_pComponentData);
  149. dlgRename.m_cn = m_szNewName;
  150. if ((dlgRename.m_cn).GetLength() > 64)
  151. {
  152. ReportErrorEx (m_hwnd, IDS_NAME_TOO_LONG, S_OK,
  153. MB_OK | MB_ICONWARNING, NULL, 0, FALSE);
  154. dlgRename.m_cn = (dlgRename.m_cn).Left(64);
  155. }
  156. LPWSTR pAttrNames[] = {L"distinguishedName",
  157. L"userPrincipalName",
  158. L"sAMAccountName",
  159. L"givenName",
  160. L"displayName",
  161. L"sn",
  162. L"cn"};
  163. PADS_ATTR_INFO pAttrs = NULL;
  164. ULONG cAttrs = 0;
  165. LPWSTR pszLocalDomain = NULL;
  166. LPWSTR pszDomain = NULL;
  167. LPWSTR pszUPN = NULL;
  168. LPWSTR pszFirstName = NULL;
  169. LPWSTR pszSurName = NULL;
  170. LPWSTR pszSAMName = NULL;
  171. LPWSTR pszDispName = NULL;
  172. CString strAtDomain;
  173. CString serverName;
  174. BOOL error = TRUE;
  175. BOOL fAccessDenied = FALSE;
  176. BOOL NoRename = FALSE;
  177. INT_PTR answer = IDCANCEL;
  178. //
  179. // Bind to the DS object
  180. //
  181. CComPtr<IDirectoryObject> spDirObj;
  182. CString szPath;
  183. m_pComponentData->GetBasePathsInfo()->ComposeADsIPath(szPath, m_pCookie->GetPath());
  184. hr = DSAdminOpenObject(szPath,
  185. IID_IDirectoryObject,
  186. (void **)&spDirObj,
  187. TRUE /*bServer*/);
  188. if (SUCCEEDED(hr))
  189. {
  190. //
  191. // Get the object attributes needed
  192. //
  193. hr = spDirObj->GetObjectAttributes (pAttrNames, sizeof(pAttrNames)/sizeof(LPWSTR), &pAttrs, &cAttrs);
  194. if (SUCCEEDED(hr))
  195. {
  196. for (UINT i = 0; i < cAttrs; i++)
  197. {
  198. //
  199. // Distinguished Name
  200. //
  201. if (_wcsicmp (L"distinguishedName", pAttrs[i].pszAttrName) == 0)
  202. {
  203. hr = CrackName (pAttrs[i].pADsValues->CaseIgnoreString,
  204. &pszDomain, GET_NT4_DOMAIN_NAME, NULL);
  205. if (SUCCEEDED(hr))
  206. {
  207. ASSERT(pszDomain != NULL);
  208. if (pszDomain != NULL)
  209. {
  210. dlgRename.m_dldomain = pszDomain;
  211. dlgRename.m_dldomain += L'\\';
  212. }
  213. }
  214. //
  215. // get the Domain of this object, need it later.
  216. //
  217. CComBSTR bsDN;
  218. CPathCracker pathCracker;
  219. pathCracker.SetDisplayType(ADS_DISPLAY_FULL);
  220. pathCracker.Set(CComBSTR(szPath), ADS_SETTYPE_FULL);
  221. pathCracker.Retrieve(ADS_FORMAT_X500_DN, &bsDN);
  222. // NTRAID#NTBUG9-698115-2002/09/04-artm
  223. // Get the server name we're connected to, we'll need it later for getting root domains.
  224. // If we fail to get it that's okay, we'll still get the root domains
  225. // unless the user is running dsadmin under "runas". If that's the case,
  226. // the we won't show parent domains (but everything else will work).
  227. CComBSTR tempServerName;
  228. hr = pathCracker.Retrieve(ADS_FORMAT_SERVER, &tempServerName);
  229. if (SUCCEEDED(hr))
  230. {
  231. serverName = tempServerName;
  232. }
  233. //
  234. // get the NT 5 (dns) domain name
  235. //
  236. TRACE(L"CrackName(%s, &pszDomain, GET_DNS_DOMAIN_NAME, NULL);\n", bsDN);
  237. hr = CrackName(bsDN, &pszLocalDomain, GET_DNS_DOMAIN_NAME, NULL);
  238. TRACE(L"CrackName returned hr = 0x%x, pszLocalDomain = <%s>\n", hr, pszLocalDomain);
  239. } // if distinguishedName
  240. //
  241. // User Principle Name
  242. //
  243. if (_wcsicmp (L"userPrincipalName", pAttrs[i].pszAttrName) == 0)
  244. {
  245. CString csTemp = pAttrs[i].pADsValues->CaseIgnoreString;
  246. INT loc = csTemp.Find (L'@');
  247. if (loc > 0)
  248. {
  249. dlgRename.m_login = csTemp.Left(loc);
  250. dlgRename.m_domain = csTemp.Right (csTemp.GetLength() - loc);
  251. }
  252. else
  253. {
  254. dlgRename.m_login = csTemp;
  255. ASSERT (0 && L"can't find @ in upn");
  256. }
  257. } // if userPrincipalName
  258. //
  259. // sAMAccountName
  260. //
  261. if (_wcsicmp (L"sAMAccountName", pAttrs[i].pszAttrName) == 0)
  262. {
  263. dlgRename.m_samaccountname = pAttrs[i].pADsValues->CaseIgnoreString;
  264. } // if sAMAccountName
  265. //
  266. // givenName
  267. //
  268. if (_wcsicmp (L"givenName", pAttrs[i].pszAttrName) == 0)
  269. {
  270. dlgRename.m_first = pAttrs[i].pADsValues->CaseIgnoreString;
  271. } // if givenName
  272. //
  273. // displayName
  274. //
  275. if (_wcsicmp (L"displayName", pAttrs[i].pszAttrName) == 0)
  276. {
  277. dlgRename.m_displayname = pAttrs[i].pADsValues->CaseIgnoreString;
  278. } // if displayName
  279. //
  280. // sn
  281. //
  282. if (_wcsicmp (L"sn", pAttrs[i].pszAttrName) == 0)
  283. {
  284. dlgRename.m_last = pAttrs[i].pADsValues->CaseIgnoreString;
  285. } // if sn
  286. //
  287. // cn
  288. //
  289. if (_wcsicmp (L"cn", pAttrs[i].pszAttrName) == 0)
  290. {
  291. dlgRename.m_oldcn = pAttrs[i].pADsValues->CaseIgnoreString;
  292. } // if cn
  293. }
  294. }
  295. //
  296. // get UPN suffixes from this OU, if present
  297. //
  298. CComPtr<IADs> spIADs;
  299. CComPtr<IADs> spContIADs;
  300. CComBSTR bsParentPath;
  301. CStringList UPNs;
  302. hr = spDirObj->QueryInterface (IID_IADs, (void **)&spIADs);
  303. ASSERT (SUCCEEDED(hr));
  304. hr = spIADs->get_Parent(&bsParentPath);
  305. ASSERT (SUCCEEDED(hr));
  306. hr = DSAdminOpenObject(bsParentPath,
  307. IID_IADs,
  308. (void **)&spContIADs,
  309. TRUE /*bServer*/);
  310. ASSERT(SUCCEEDED(hr));
  311. CComVariant Var;
  312. hr = spContIADs->Get ( CComBSTR(L"uPNSuffixes"), &Var);
  313. if (SUCCEEDED(hr))
  314. {
  315. hr = HrVariantToStringList (Var, UPNs);
  316. if (SUCCEEDED(hr))
  317. {
  318. POSITION pos = UPNs.GetHeadPosition();
  319. CString csSuffix;
  320. while (pos != NULL)
  321. {
  322. csSuffix = L"@";
  323. csSuffix += UPNs.GetNext(INOUT pos);
  324. TRACE(_T("UPN suffix: %s\n"), csSuffix);
  325. if (wcscmp (csSuffix, dlgRename.m_domain) &&
  326. !dlgRename.m_domains.Find(csSuffix))
  327. {
  328. dlgRename.m_domains.AddTail (csSuffix);
  329. }
  330. }
  331. }
  332. }
  333. else
  334. {
  335. //
  336. // now get the domain options
  337. //
  338. CComPtr<IDsBrowseDomainTree> spDsDomains = NULL;
  339. PDOMAIN_TREE pNewDomains = NULL;
  340. do // false loop
  341. {
  342. hr = ::CoCreateInstance(CLSID_DsDomainTreeBrowser,
  343. NULL,
  344. CLSCTX_INPROC_SERVER,
  345. IID_IDsBrowseDomainTree,
  346. (LPVOID*)&spDsDomains);
  347. if (FAILED(hr) || spDsDomains == NULL)
  348. {
  349. ASSERT(SUCCEEDED(hr) && spDsDomains != NULL);
  350. break;
  351. }
  352. // NTRAID#NTBUG9-698115-2002/09/04-artm
  353. // Ensure that the domains we request are correctly scoped.
  354. hr = spDsDomains->SetComputer(serverName, NULL, NULL);
  355. if (FAILED(hr))
  356. {
  357. ASSERT(SUCCEEDED(hr));
  358. break;
  359. }
  360. hr = spDsDomains->GetDomains(&pNewDomains, 0);
  361. if (FAILED(hr) || pNewDomains == NULL)
  362. {
  363. // Only expect to get here with failed hresult.
  364. ASSERT(FAILED(hr));
  365. break;
  366. }
  367. for (UINT index = 0; index < pNewDomains->dwCount; index++)
  368. {
  369. if (pNewDomains->aDomains[index].pszTrustParent == NULL)
  370. {
  371. // Add the root domain only if it is a substring of the current
  372. // domain.
  373. //
  374. size_t cchRoot = wcslen(pNewDomains->aDomains[index].pszName);
  375. PWSTR pRoot = pszLocalDomain + wcslen(pszLocalDomain) - cchRoot;
  376. if (pRoot >= pszLocalDomain &&
  377. !_wcsicmp(pRoot, pNewDomains->aDomains[index].pszName))
  378. {
  379. strAtDomain = "@";
  380. strAtDomain += pNewDomains->aDomains[index].pszName;
  381. if (_wcsicmp(pNewDomains->aDomains[index].pszName, dlgRename.m_domain) &&
  382. !dlgRename.m_domains.Find(strAtDomain))
  383. {
  384. dlgRename.m_domains.AddTail (strAtDomain);
  385. }
  386. }
  387. }
  388. } // end for loop
  389. } while (false);
  390. if (spDsDomains != NULL && pNewDomains != NULL)
  391. {
  392. spDsDomains->FreeDomains(&pNewDomains);
  393. pNewDomains = NULL;
  394. }
  395. LocalFreeStringW(&pszDomain);
  396. // If the local domain isn't the same as the root, then add it
  397. CString strAtLocalDomain = L"@";
  398. strAtLocalDomain += pszLocalDomain;
  399. if (!dlgRename.m_domains.Find(strAtLocalDomain))
  400. {
  401. dlgRename.m_domains.AddTail(strAtLocalDomain);
  402. }
  403. //
  404. // get UPN suffixes
  405. //
  406. CString csPartitions;
  407. CStringList UPNsList;
  408. //
  409. // get config path from main object
  410. //
  411. csPartitions = m_pComponentData->GetBasePathsInfo()->GetProviderAndServerName();
  412. csPartitions += L"CN=Partitions,";
  413. csPartitions += m_pComponentData->GetBasePathsInfo()->GetConfigNamingContext();
  414. CComPtr<IADs> spPartitions;
  415. hr = DSAdminOpenObject(csPartitions,
  416. IID_IADs,
  417. (void **)&spPartitions,
  418. TRUE /*bServer*/);
  419. if (SUCCEEDED(hr))
  420. {
  421. CComVariant sVar;
  422. hr = spPartitions->Get ( CComBSTR(L"uPNSuffixes"), &sVar);
  423. if (SUCCEEDED(hr))
  424. {
  425. hr = HrVariantToStringList (sVar, UPNsList);
  426. if (SUCCEEDED(hr))
  427. {
  428. POSITION pos = UPNsList.GetHeadPosition();
  429. CString csSuffix;
  430. while (pos != NULL)
  431. {
  432. csSuffix = L"@";
  433. csSuffix += UPNsList.GetNext(INOUT pos);
  434. TRACE(_T("UPN suffix: %s\n"), csSuffix);
  435. if (wcscmp (csSuffix, dlgRename.m_domain) &&
  436. !dlgRename.m_domains.Find(csSuffix))
  437. {
  438. dlgRename.m_domains.AddTail (csSuffix);
  439. }
  440. }
  441. }
  442. }
  443. }
  444. }
  445. while ((error) && (!fAccessDenied))
  446. {
  447. answer = dlgRename.DoModal();
  448. if (answer == IDOK)
  449. {
  450. ADSVALUE avUPN = {ADSTYPE_CASE_IGNORE_STRING, NULL};
  451. ADS_ATTR_INFO aiUPN = {L"userPrincipalName", ADS_ATTR_UPDATE,
  452. ADSTYPE_CASE_IGNORE_STRING, &avUPN, 1};
  453. ADSVALUE avSAMName = {ADSTYPE_CASE_IGNORE_STRING, NULL};
  454. ADS_ATTR_INFO aiSAMName = {L"sAMAccountName", ADS_ATTR_UPDATE,
  455. ADSTYPE_CASE_IGNORE_STRING, &avSAMName, 1};
  456. ADSVALUE avGiven = {ADSTYPE_CASE_IGNORE_STRING, NULL};
  457. ADS_ATTR_INFO aiGiven = {L"givenName", ADS_ATTR_UPDATE,
  458. ADSTYPE_CASE_IGNORE_STRING, &avGiven, 1};
  459. ADSVALUE avSurName = {ADSTYPE_CASE_IGNORE_STRING, NULL};
  460. ADS_ATTR_INFO aiSurName = {L"sn", ADS_ATTR_UPDATE,
  461. ADSTYPE_CASE_IGNORE_STRING, &avSurName, 1};
  462. ADSVALUE avDispName = {ADSTYPE_CASE_IGNORE_STRING, NULL};
  463. ADS_ATTR_INFO aiDispName = {L"displayName", ADS_ATTR_UPDATE,
  464. ADSTYPE_CASE_IGNORE_STRING, &avDispName, 1};
  465. ADS_ATTR_INFO rgAttrs[5];
  466. ULONG cModified = 0;
  467. cAttrs = 0;
  468. if (!dlgRename.m_login.IsEmpty() && !dlgRename.m_domain.IsEmpty())
  469. {
  470. dlgRename.m_login.TrimRight();
  471. dlgRename.m_login.TrimLeft();
  472. dlgRename.m_domain.TrimRight();
  473. dlgRename.m_domain.TrimLeft();
  474. CString csTemp;
  475. if (!dlgRename.m_login.IsEmpty())
  476. {
  477. csTemp = (dlgRename.m_login + dlgRename.m_domain);
  478. pszUPN = new WCHAR[wcslen(csTemp) + 1];
  479. if (pszUPN != NULL)
  480. {
  481. wcscpy (pszUPN, csTemp);
  482. avUPN.CaseIgnoreString = pszUPN;
  483. }
  484. }
  485. else
  486. {
  487. aiUPN.dwControlCode = ADS_ATTR_CLEAR;
  488. }
  489. }
  490. else
  491. {
  492. aiUPN.dwControlCode = ADS_ATTR_CLEAR;
  493. }
  494. rgAttrs[cAttrs++] = aiUPN;
  495. //
  496. // test UPN for duplication
  497. // validate UPN with GC before doing the put.
  498. //
  499. BOOL fDomainSearchFailed = FALSE;
  500. BOOL fGCSearchFailed = FALSE;
  501. HRESULT hr2 = S_OK;
  502. BOOL dup = FALSE;
  503. CString strFilter;
  504. if (pszUPN != NULL && *pszUPN != '\0')
  505. {
  506. LPWSTR pAttributes[1] = {L"cn"};
  507. CComPtr<IDirectorySearch> spGCObj = NULL;
  508. CDSSearch DSS (m_pComponentData->GetClassCache(), m_pComponentData);
  509. hr = DSPROP_GetGCSearchOnDomain(pszLocalDomain,
  510. IID_IDirectorySearch,
  511. (void **)&spGCObj);
  512. if (FAILED(hr))
  513. {
  514. fGCSearchFailed = TRUE;
  515. }
  516. else
  517. {
  518. DSS.Init (spGCObj);
  519. strFilter = L"(userPrincipalName=";
  520. strFilter += pszUPN;
  521. strFilter += L")";
  522. DSS.SetAttributeList (pAttributes, 1);
  523. DSS.SetFilterString ((LPWSTR)(LPCWSTR)strFilter);
  524. DSS.SetSearchScope (ADS_SCOPE_SUBTREE);
  525. DSS.DoQuery();
  526. hr = DSS.GetNextRow();
  527. while ((hr == S_OK) && (dup == FALSE)) // this means a row was returned, so we're dup
  528. {
  529. ADS_SEARCH_COLUMN Col;
  530. hr = DSS.GetColumn(pAttributes[0], &Col);
  531. if (SUCCEEDED(hr))
  532. {
  533. if (_wcsicmp(Col.pADsValues->CaseIgnoreString, dlgRename.m_oldcn))
  534. {
  535. dup = TRUE;
  536. ReportErrorEx (m_hwnd, IDS_UPN_DUP, hr,
  537. MB_OK, NULL, 0);
  538. }
  539. }
  540. else
  541. {
  542. fGCSearchFailed = TRUE;
  543. }
  544. hr = DSS.GetNextRow();
  545. }
  546. if (hr != S_ADS_NOMORE_ROWS)
  547. {
  548. fGCSearchFailed = TRUE;
  549. }
  550. }
  551. if (dup)
  552. {
  553. continue;
  554. }
  555. else
  556. {
  557. CString strInitPath = L"LDAP://";
  558. strInitPath += pszLocalDomain;
  559. TRACE(_T("Initialize Domain search object with: %s...\n"), strInitPath);
  560. hr2 = DSS.Init (strInitPath);
  561. if (SUCCEEDED(hr2))
  562. {
  563. LPWSTR pAttributes2[1] = {L"cn"};
  564. strFilter = L"(userPrincipalName=";
  565. strFilter += pszUPN;
  566. strFilter += L")";
  567. TRACE(_T("searching current domain for %s...\n"), pszUPN);
  568. DSS.SetAttributeList (pAttributes2, 1);
  569. DSS.SetFilterString ((LPWSTR)(LPCWSTR)strFilter);
  570. DSS.SetSearchScope (ADS_SCOPE_SUBTREE);
  571. DSS.DoQuery();
  572. hr2 = DSS.GetNextRow();
  573. TRACE(_T("done searching current domain for %s...\n"), pszUPN);
  574. }
  575. while ((hr2 == S_OK) && (dup == FALSE)) // this means a row was returned, so we're dup
  576. {
  577. ADS_SEARCH_COLUMN Col;
  578. HRESULT hr3 = DSS.GetColumn(pAttributes[0], &Col);
  579. ASSERT (hr3 == S_OK);
  580. if (_wcsicmp(Col.pADsValues->CaseIgnoreString, dlgRename.m_oldcn))
  581. {
  582. dup = TRUE;
  583. ReportErrorEx (m_hwnd, IDS_UPN_DUP, hr,
  584. MB_OK, NULL, 0);
  585. }
  586. hr2 = DSS.GetNextRow();
  587. }
  588. if (hr2 != S_ADS_NOMORE_ROWS) // oops, had another problem
  589. {
  590. fDomainSearchFailed = TRUE;
  591. }
  592. }
  593. }
  594. if (dup)
  595. {
  596. continue;
  597. }
  598. else
  599. {
  600. if (fDomainSearchFailed ||
  601. fGCSearchFailed)
  602. {
  603. if (fDomainSearchFailed)
  604. {
  605. ReportErrorEx (m_hwnd,IDS_UPN_SEARCH_FAILED2,hr2,
  606. MB_OK | MB_ICONWARNING, NULL, 0);
  607. }
  608. else if (fGCSearchFailed)
  609. {
  610. ReportErrorEx (m_hwnd,IDS_UPN_SEARCH_FAILED2,hr,
  611. MB_OK | MB_ICONWARNING, NULL, 0);
  612. }
  613. else
  614. {
  615. ReportErrorEx (m_hwnd, IDS_UPN_SEARCH_FAILED3, hr,
  616. MB_OK | MB_ICONWARNING, NULL, 0);
  617. }
  618. }
  619. }
  620. dlgRename.m_cn.TrimRight();
  621. dlgRename.m_cn.TrimLeft();
  622. m_szNewName = dlgRename.m_cn;
  623. if (dlgRename.m_cn == dlgRename.m_oldcn)
  624. {
  625. NoRename = TRUE;
  626. }
  627. if (!dlgRename.m_displayname.IsEmpty())
  628. {
  629. dlgRename.m_displayname.TrimLeft();
  630. dlgRename.m_displayname.TrimRight();
  631. //NTRAID#NTBUG9-569671-2002/03/10-jmessec this should be + 1, not + sizeof(WCHAR)
  632. pszDispName = new WCHAR[wcslen(dlgRename.m_displayname) + 1];
  633. if (pszDispName != NULL)
  634. {
  635. wcscpy (pszDispName, dlgRename.m_displayname);
  636. avDispName.CaseIgnoreString = pszDispName;
  637. }
  638. }
  639. else
  640. {
  641. aiDispName.dwControlCode = ADS_ATTR_CLEAR;
  642. }
  643. rgAttrs[cAttrs++] = aiDispName;
  644. if (!dlgRename.m_first.IsEmpty())
  645. {
  646. dlgRename.m_first.TrimLeft();
  647. dlgRename.m_first.TrimRight();
  648. //NTRAID#NTBUG9-569671-2002/03/10-jmessec this should be + 1, not + sizeof(WCHAR)
  649. pszFirstName = new WCHAR[wcslen(dlgRename.m_first) + 1];
  650. if (pszFirstName != NULL)
  651. {
  652. wcscpy (pszFirstName, dlgRename.m_first);
  653. avGiven.CaseIgnoreString = pszFirstName;
  654. }
  655. }
  656. else
  657. {
  658. aiGiven.dwControlCode = ADS_ATTR_CLEAR;
  659. }
  660. rgAttrs[cAttrs++] = aiGiven;
  661. if (!dlgRename.m_last.IsEmpty())
  662. {
  663. dlgRename.m_last.TrimLeft();
  664. dlgRename.m_last.TrimRight();
  665. //NTRAID#NTBUG9-569671-2002/03/10-jmessec this should be + 1, not + sizeof(WCHAR)
  666. pszSurName = new WCHAR[wcslen(dlgRename.m_last) + 1];
  667. if (pszSurName != NULL)
  668. {
  669. wcscpy (pszSurName, dlgRename.m_last);
  670. avSurName.CaseIgnoreString = pszSurName;
  671. }
  672. }
  673. else
  674. {
  675. aiSurName.dwControlCode = ADS_ATTR_CLEAR;
  676. }
  677. rgAttrs[cAttrs++] = aiSurName;
  678. if (!dlgRename.m_samaccountname.IsEmpty())
  679. {
  680. dlgRename.m_samaccountname.TrimLeft();
  681. dlgRename.m_samaccountname.TrimRight();
  682. //
  683. // Check for illegal characters in the SAM account name
  684. //
  685. HRESULT hrValidate = ValidateAndModifyName(dlgRename.m_samaccountname,
  686. INVALID_ACCOUNT_NAME_CHARS_WITH_AT,
  687. L'_',
  688. IDS_SAMNAME_ILLEGAL,
  689. m_hwnd);
  690. if (FAILED(hrValidate))
  691. {
  692. continue;
  693. }
  694. //NTRAID#NTBUG9-569671-2002/03/10-jmessec this should be + 1, not + sizeof(WCHAR)
  695. pszSAMName = new WCHAR[wcslen(dlgRename.m_samaccountname) + 1];
  696. if (pszSAMName != NULL)
  697. {
  698. wcscpy (pszSAMName, dlgRename.m_samaccountname);
  699. avSAMName.CaseIgnoreString = pszSAMName;
  700. }
  701. }
  702. else
  703. {
  704. aiSAMName.dwControlCode = ADS_ATTR_CLEAR;
  705. }
  706. rgAttrs[cAttrs++] = aiSAMName;
  707. hr = spDirObj->SetObjectAttributes (rgAttrs, cAttrs, &cModified);
  708. if (FAILED(hr))
  709. {
  710. if (hr == E_ACCESSDENIED)
  711. {
  712. fAccessDenied = TRUE;
  713. NoRename = TRUE;
  714. }
  715. else
  716. {
  717. ReportErrorEx (m_hwnd, IDS_NAME_CHANGE_FAILED, hr,
  718. MB_OK|MB_ICONERROR, NULL, 0, 0, TRUE);
  719. }
  720. }
  721. else
  722. {
  723. error = FALSE;
  724. }
  725. }
  726. else
  727. {
  728. error = FALSE;
  729. }
  730. }
  731. }
  732. else
  733. {
  734. answer = IDCANCEL;
  735. PVOID apv[1] = {(BSTR)(LPWSTR)(LPCWSTR)m_pCookie->GetName()};
  736. ReportErrorEx (m_hwnd,IDS_12_USER_OBJECT_NOT_ACCESSABLE,hr,
  737. MB_OK | MB_ICONERROR, apv, 1);
  738. }
  739. if ((answer == IDOK) && (error == FALSE) && (NoRename == FALSE))
  740. {
  741. hr = CommitRenameToDS();
  742. }
  743. if (fAccessDenied)
  744. {
  745. PVOID apv[1] = {(BSTR)(LPWSTR)(LPCWSTR)m_pCookie->GetName()};
  746. ReportErrorEx(m_hwnd,IDS_12_RENAME_NOT_ALLOWED,hr,
  747. MB_OK | MB_ICONERROR, apv, 1);
  748. }
  749. //
  750. // Cleanup
  751. //
  752. if (pszLocalDomain != NULL)
  753. {
  754. LocalFreeStringW(&pszLocalDomain);
  755. }
  756. if (pszUPN != NULL)
  757. {
  758. delete[] pszUPN;
  759. }
  760. if (pszFirstName != NULL)
  761. {
  762. delete[] pszFirstName;
  763. }
  764. if (pszSurName != NULL)
  765. {
  766. delete[] pszSurName;
  767. }
  768. if (pszSAMName != NULL)
  769. {
  770. delete[] pszSAMName;
  771. }
  772. if (pszDispName != NULL)
  773. {
  774. delete[] pszDispName;
  775. }
  776. return hr;
  777. }
  778. /////////////////////////////////////////////////////////////////////////////
  779. // CDSRenameGroup
  780. //
  781. HRESULT CDSRenameGroup::DoRename()
  782. {
  783. CThemeContextActivator activator;
  784. //
  785. // Verify data members
  786. //
  787. if (m_pUINode == NULL || m_pCookie == NULL || m_pComponentData == NULL)
  788. {
  789. ASSERT(FALSE);
  790. return E_INVALIDARG;
  791. }
  792. //
  793. // Rename Group
  794. //
  795. HRESULT hr = S_OK;
  796. BOOL error = FALSE;
  797. BOOL fAccessDenied = FALSE;
  798. BOOL NoRename = FALSE;
  799. INT_PTR answer = IDCANCEL;
  800. CRenameGroupDlg dlgRename;
  801. dlgRename.m_cn = m_szNewName;
  802. //
  803. // Check the length of the new name
  804. //
  805. if ((dlgRename.m_cn).GetLength() > 64)
  806. {
  807. ReportErrorEx (m_hwnd, IDS_NAME_TOO_LONG, S_OK,
  808. MB_OK | MB_ICONWARNING, NULL, 0, FALSE);
  809. dlgRename.m_cn = (dlgRename.m_cn).Left(64);
  810. }
  811. //
  812. // Bind to the object
  813. //
  814. CComPtr<IADs> spIADs;
  815. CString szPath;
  816. m_pComponentData->GetBasePathsInfo()->ComposeADsIPath(szPath, m_pCookie->GetPath());
  817. hr = DSAdminOpenObject(szPath,
  818. IID_IADs,
  819. (void **)&spIADs,
  820. TRUE /*bServer*/);
  821. if (SUCCEEDED(hr))
  822. {
  823. //
  824. // Retrieve the sAMAccountName
  825. //
  826. CComVariant Var;
  827. hr = spIADs->Get (CComBSTR(L"sAMAccountName"), &Var);
  828. ASSERT (SUCCEEDED(hr));
  829. CString csSam = Var.bstrVal;
  830. dlgRename.m_samaccountname = csSam;
  831. error = TRUE;
  832. while ((error) && (!fAccessDenied))
  833. {
  834. answer = dlgRename.DoModal();
  835. if (answer == IDOK)
  836. {
  837. dlgRename.m_cn.TrimRight();
  838. dlgRename.m_cn.TrimLeft();
  839. m_szNewName = dlgRename.m_cn;
  840. Var.vt = VT_BSTR;
  841. //
  842. // Trim whitespace from samaccountname
  843. //
  844. dlgRename.m_samaccountname.TrimLeft();
  845. dlgRename.m_samaccountname.TrimRight();
  846. //
  847. // Check for illegal characters in the login name
  848. //
  849. HRESULT hrValidate = ValidateAndModifyName(dlgRename.m_samaccountname,
  850. INVALID_ACCOUNT_NAME_CHARS,
  851. L'_',
  852. IDS_GROUP_SAMNAME_ILLEGAL,
  853. m_hwnd);
  854. if (FAILED(hrValidate))
  855. {
  856. continue;
  857. }
  858. csSam = dlgRename.m_samaccountname;
  859. //
  860. // Put changes to samaccountname
  861. //
  862. Var.bstrVal = SysAllocString(csSam);
  863. hr = spIADs->Put (CComBSTR(L"sAMAccountName"), Var);
  864. ASSERT (SUCCEEDED(hr));
  865. if (FAILED(hr))
  866. {
  867. continue;
  868. }
  869. //
  870. // Commit the changes
  871. //
  872. hr = spIADs->SetInfo();
  873. if (FAILED(hr))
  874. {
  875. if (hr == E_ACCESSDENIED)
  876. {
  877. fAccessDenied = TRUE;
  878. NoRename = TRUE;
  879. }
  880. else
  881. {
  882. ReportErrorEx (m_hwnd, IDS_NAME_CHANGE_FAILED, hr,
  883. MB_OK|MB_ICONERROR, NULL, 0, 0, TRUE);
  884. }
  885. }
  886. else
  887. {
  888. error = FALSE;
  889. }
  890. }
  891. else
  892. {
  893. error = FALSE;
  894. }
  895. }
  896. }
  897. else
  898. {
  899. answer = IDCANCEL;
  900. }
  901. if ((answer == IDOK) && (error == FALSE) && (NoRename == FALSE))
  902. {
  903. hr = CommitRenameToDS();
  904. }
  905. if (fAccessDenied)
  906. {
  907. PVOID apv[1] = {(BSTR)(LPWSTR)(LPCWSTR)m_pCookie->GetName()};
  908. ReportErrorEx(::GetParent(m_hwnd),IDS_12_RENAME_NOT_ALLOWED,hr,
  909. MB_OK | MB_ICONERROR, apv, 1);
  910. }
  911. return hr;
  912. }
  913. /////////////////////////////////////////////////////////////////////////////
  914. // CDSRenameContact
  915. //
  916. HRESULT CDSRenameContact::DoRename()
  917. {
  918. CThemeContextActivator activator;
  919. //
  920. // Verify data members
  921. //
  922. if (m_pUINode == NULL || m_pCookie == NULL || m_pComponentData == NULL)
  923. {
  924. ASSERT(FALSE);
  925. return E_INVALIDARG;
  926. }
  927. BOOL error = FALSE;
  928. BOOL fAccessDenied = FALSE;
  929. BOOL NoRename = FALSE;
  930. INT_PTR answer = IDCANCEL;
  931. HRESULT hr = S_OK;
  932. //
  933. // rename contact
  934. //
  935. CRenameContactDlg dlgRename;
  936. dlgRename.m_cn = m_szNewName;
  937. //
  938. // Check the length of the new name
  939. //
  940. if ((dlgRename.m_cn).GetLength() > 64)
  941. {
  942. ReportErrorEx (m_hwnd, IDS_NAME_TOO_LONG, S_OK,
  943. MB_OK | MB_ICONWARNING, NULL, 0, FALSE);
  944. dlgRename.m_cn = (dlgRename.m_cn).Left(64);
  945. }
  946. //
  947. // Bind to the DS object
  948. //
  949. CComPtr<IADs> spIADs;
  950. CString szPath;
  951. m_pComponentData->GetBasePathsInfo()->ComposeADsIPath(szPath, m_pCookie->GetPath());
  952. hr = DSAdminOpenObject(szPath,
  953. IID_IADs,
  954. (void **)&spIADs,
  955. TRUE /*bServer*/);
  956. if (SUCCEEDED(hr))
  957. {
  958. //
  959. // Retrieve the needed attributes
  960. //
  961. //
  962. // givenName
  963. //
  964. CComVariant Var;
  965. hr = spIADs->Get (CComBSTR(L"givenName"), &Var);
  966. ASSERT (SUCCEEDED(hr) || (hr == E_ADS_PROPERTY_NOT_FOUND));
  967. if (SUCCEEDED(hr))
  968. {
  969. dlgRename.m_first = Var.bstrVal;
  970. }
  971. //
  972. // sur name
  973. //
  974. hr = spIADs->Get (CComBSTR(L"sn"), &Var);
  975. ASSERT (SUCCEEDED(hr) || (hr == E_ADS_PROPERTY_NOT_FOUND));
  976. if (SUCCEEDED(hr))
  977. {
  978. dlgRename.m_last = Var.bstrVal;
  979. }
  980. //
  981. // Display name
  982. //
  983. hr = spIADs->Get (CComBSTR(L"displayName"), &Var);
  984. ASSERT (SUCCEEDED(hr) || (hr == E_ADS_PROPERTY_NOT_FOUND));
  985. if (SUCCEEDED(hr))
  986. {
  987. dlgRename.m_disp = Var.bstrVal;
  988. }
  989. error = TRUE;
  990. while ((error) && (!fAccessDenied))
  991. {
  992. answer = dlgRename.DoModal();
  993. if (answer == IDOK)
  994. {
  995. dlgRename.m_cn.TrimRight();
  996. dlgRename.m_cn.TrimLeft();
  997. m_szNewName = dlgRename.m_cn;
  998. Var.vt = VT_BSTR;
  999. //
  1000. // Put givenName
  1001. //
  1002. if (!dlgRename.m_first.IsEmpty())
  1003. {
  1004. dlgRename.m_first.TrimLeft();
  1005. dlgRename.m_first.TrimRight();
  1006. Var.bstrVal = SysAllocString (dlgRename.m_first);
  1007. hr = spIADs->Put (CComBSTR(L"givenName"), Var);
  1008. ASSERT (SUCCEEDED(hr));
  1009. SysFreeString(Var.bstrVal);
  1010. }
  1011. //
  1012. // Put sur name
  1013. //
  1014. if (!dlgRename.m_last.IsEmpty())
  1015. {
  1016. dlgRename.m_last.TrimLeft();
  1017. dlgRename.m_last.TrimRight();
  1018. Var.bstrVal = SysAllocString(dlgRename.m_last);
  1019. hr = spIADs->Put (CComBSTR(L"sn"), Var);
  1020. ASSERT (SUCCEEDED(hr));
  1021. SysFreeString (Var.bstrVal);
  1022. }
  1023. //
  1024. // Put displayName
  1025. //
  1026. if (!dlgRename.m_disp.IsEmpty())
  1027. {
  1028. dlgRename.m_disp.TrimLeft();
  1029. dlgRename.m_disp.TrimRight();
  1030. Var.bstrVal = SysAllocString(dlgRename.m_disp);
  1031. hr = spIADs->Put (CComBSTR(L"displayName"), Var);
  1032. ASSERT (SUCCEEDED(hr));
  1033. SysFreeString (Var.bstrVal);
  1034. }
  1035. //
  1036. // Commit changes to DS object
  1037. //
  1038. hr = spIADs->SetInfo();
  1039. if (FAILED(hr))
  1040. {
  1041. if (hr == E_ACCESSDENIED)
  1042. {
  1043. fAccessDenied = TRUE;
  1044. NoRename = TRUE;
  1045. }
  1046. else
  1047. {
  1048. ReportErrorEx (m_hwnd, IDS_NAME_CHANGE_FAILED, hr,
  1049. MB_OK|MB_ICONERROR, NULL, 0, 0, TRUE);
  1050. }
  1051. }
  1052. else
  1053. {
  1054. error = FALSE;
  1055. }
  1056. }
  1057. else
  1058. {
  1059. error = FALSE;
  1060. }
  1061. }
  1062. }
  1063. else
  1064. {
  1065. answer = IDCANCEL;
  1066. }
  1067. if ((answer == IDOK) && (error == FALSE) && (NoRename == FALSE))
  1068. {
  1069. hr = CommitRenameToDS();
  1070. }
  1071. if (fAccessDenied)
  1072. {
  1073. PVOID apv[1] = {(BSTR)(LPWSTR)(LPCWSTR)m_pCookie->GetName()};
  1074. ReportErrorEx(::GetParent(m_hwnd),IDS_12_RENAME_NOT_ALLOWED,hr,
  1075. MB_OK | MB_ICONERROR, apv, 1);
  1076. }
  1077. return hr;
  1078. }
  1079. /////////////////////////////////////////////////////////////////////////////
  1080. // CDSRenameSite
  1081. //
  1082. HRESULT CDSRenameSite::DoRename()
  1083. {
  1084. //
  1085. // Verify data members
  1086. //
  1087. if (m_pUINode == NULL || m_pCookie == NULL || m_pComponentData == NULL)
  1088. {
  1089. ASSERT(FALSE);
  1090. return E_INVALIDARG;
  1091. }
  1092. HRESULT hr = S_OK;
  1093. //
  1094. // Rename site
  1095. //
  1096. BOOL fNonRfcSiteName = FALSE;
  1097. // NTRAID#NTBUG9-472020-2002/01/16-ronmart-Add support for new invalid char flag
  1098. BOOL fInvalidNameChar = FALSE;
  1099. BOOL fValidSiteName = IsValidSiteName( m_szNewName, &fNonRfcSiteName, &fInvalidNameChar );
  1100. if ( !fValidSiteName )
  1101. {
  1102. // NTRAID#NTBUG9-472020-2002/01/16-ronmart-display new message if invalid char flag set
  1103. if ( fInvalidNameChar )
  1104. {
  1105. ReportErrorEx (m_hwnd,IDS_SITE_INVALID_NAME_CHAR,S_OK,
  1106. MB_OK, NULL, 0);
  1107. }
  1108. // NTRAID#NTBUG9-472020-2002/01/16-ronmart-otherwise display the old msg
  1109. else
  1110. {
  1111. ReportErrorEx (m_hwnd,IDS_SITE_NAME,S_OK,
  1112. MB_OK, NULL, 0);
  1113. }
  1114. }
  1115. else if (fNonRfcSiteName)
  1116. {
  1117. LPCWSTR pszNewName = m_szNewName;
  1118. PVOID apv[1];
  1119. apv[0] = (PVOID)pszNewName;
  1120. if (IDYES != ReportMessageEx( m_hwnd,
  1121. IDS_1_NON_RFC_SITE_NAME,
  1122. MB_YESNO | MB_ICONWARNING,
  1123. apv,
  1124. 1 ) )
  1125. {
  1126. fValidSiteName = FALSE;
  1127. }
  1128. }
  1129. if ( fValidSiteName )
  1130. {
  1131. hr = CommitRenameToDS();
  1132. }
  1133. return hr;
  1134. }
  1135. /////////////////////////////////////////////////////////////////////////////
  1136. // CDSRenameNTDSConnection
  1137. //
  1138. HRESULT CDSRenameNTDSConnection::DoRename()
  1139. {
  1140. //
  1141. // Verify data members
  1142. //
  1143. if (m_pUINode == NULL || m_pCookie == NULL || m_pComponentData == NULL)
  1144. {
  1145. ASSERT(FALSE);
  1146. return E_INVALIDARG;
  1147. }
  1148. HRESULT hr = S_OK;
  1149. //
  1150. // JonN 5/10/01 283026
  1151. // Duplicate connection objects named
  1152. // "<automatically generated>" can be created
  1153. //
  1154. CString strKCCGenerated;
  1155. CString strNewName = m_szNewName;
  1156. strNewName.TrimLeft();
  1157. strNewName.TrimRight();
  1158. strKCCGenerated.LoadString (IDS_CONNECTION_KCC_GENERATED);
  1159. if ( !strNewName.CompareNoCase(strKCCGenerated) )
  1160. {
  1161. TRACE (_T("CDSRenameNTDSConnection::DoRename blocked rename"));
  1162. ReportErrorEx (m_hwnd,IDS_CONNECTION_RENAME_KCCSTRING,hr,
  1163. MB_OK | MB_ICONWARNING, NULL, 0);
  1164. return S_OK;
  1165. }
  1166. //
  1167. // Rename nTDSConnection
  1168. //
  1169. if (m_pComponentData->RenameConnectionFixup(m_pCookie))
  1170. {
  1171. hr = CommitRenameToDS();
  1172. }
  1173. return hr;
  1174. }
  1175. /////////////////////////////////////////////////////////////////////////////
  1176. // CDSRenameSubnet
  1177. //
  1178. HRESULT CDSRenameSubnet::DoRename()
  1179. {
  1180. //
  1181. // Verify data members
  1182. //
  1183. if (m_pUINode == NULL || m_pCookie == NULL || m_pComponentData == NULL)
  1184. {
  1185. ASSERT(FALSE);
  1186. return E_INVALIDARG;
  1187. }
  1188. HRESULT hr = S_OK;
  1189. //
  1190. // Rename subnet
  1191. //
  1192. DWORD dw = ::DsValidateSubnetName( m_szNewName );
  1193. if (ERROR_SUCCESS == dw)
  1194. {
  1195. hr = CommitRenameToDS();
  1196. }
  1197. else
  1198. {
  1199. ReportErrorEx (m_hwnd,IDS_SUBNET_NAME,S_OK,
  1200. MB_OK, NULL, 0);
  1201. }
  1202. return hr;
  1203. }