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.

1247 lines
32 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. //
  118. // Verify data members
  119. //
  120. if (m_pUINode == NULL || m_pCookie == NULL || m_pComponentData == NULL)
  121. {
  122. ASSERT(FALSE);
  123. return E_INVALIDARG;
  124. }
  125. HRESULT hr = S_OK;
  126. //
  127. // rename user : get the new name from the dialog
  128. //
  129. CRenameUserDlg dlgRename(m_pComponentData);
  130. dlgRename.m_cn = m_szNewName;
  131. if ((dlgRename.m_cn).GetLength() > 64)
  132. {
  133. ReportErrorEx (m_hwnd, IDS_NAME_TOO_LONG, S_OK,
  134. MB_OK | MB_ICONWARNING, NULL, 0, FALSE);
  135. dlgRename.m_cn = (dlgRename.m_cn).Left(64);
  136. }
  137. LPWSTR pAttrNames[] = {L"distinguishedName",
  138. L"userPrincipalName",
  139. L"sAMAccountName",
  140. L"givenName",
  141. L"displayName",
  142. L"sn",
  143. L"cn"};
  144. PADS_ATTR_INFO pAttrs = NULL;
  145. ULONG cAttrs = 0;
  146. LPWSTR pszLocalDomain = NULL;
  147. LPWSTR pszDomain = NULL;
  148. LPWSTR pszUPN = NULL;
  149. LPWSTR pszFirstName = NULL;
  150. LPWSTR pszSurName = NULL;
  151. LPWSTR pszSAMName = NULL;
  152. LPWSTR pszDispName = NULL;
  153. BOOL error = TRUE;
  154. BOOL fAccessDenied = FALSE;
  155. BOOL NoRename = FALSE;
  156. INT_PTR answer = IDCANCEL;
  157. //
  158. // Bind to the DS object
  159. //
  160. CComPtr<IDirectoryObject> spDirObj;
  161. CString szPath;
  162. m_pComponentData->GetBasePathsInfo()->ComposeADsIPath(szPath, m_pCookie->GetPath());
  163. hr = DSAdminOpenObject(szPath,
  164. IID_IDirectoryObject,
  165. (void **)&spDirObj,
  166. TRUE /*bServer*/);
  167. if (SUCCEEDED(hr))
  168. {
  169. //
  170. // Get the object attributes needed
  171. //
  172. hr = spDirObj->GetObjectAttributes (pAttrNames, sizeof(pAttrNames)/sizeof(LPWSTR), &pAttrs, &cAttrs);
  173. if (SUCCEEDED(hr))
  174. {
  175. for (UINT i = 0; i < cAttrs; i++)
  176. {
  177. //
  178. // Distinguished Name
  179. //
  180. if (_wcsicmp (L"distinguishedName", pAttrs[i].pszAttrName) == 0)
  181. {
  182. hr = CrackName (pAttrs[i].pADsValues->CaseIgnoreString,
  183. &pszDomain, GET_NT4_DOMAIN_NAME, NULL);
  184. if (SUCCEEDED(hr))
  185. {
  186. ASSERT(pszDomain != NULL);
  187. if (pszDomain != NULL)
  188. {
  189. dlgRename.m_dldomain = pszDomain;
  190. dlgRename.m_dldomain += L'\\';
  191. }
  192. }
  193. //
  194. // get the Domain of this object, need it later.
  195. //
  196. CComBSTR bsDN;
  197. CPathCracker pathCracker;
  198. pathCracker.SetDisplayType(ADS_DISPLAY_FULL);
  199. pathCracker.Set((LPTSTR)(LPCTSTR)szPath, ADS_SETTYPE_FULL);
  200. pathCracker.Retrieve(ADS_FORMAT_X500_DN, &bsDN);
  201. //
  202. // get the NT 5 (dns) domain name
  203. //
  204. TRACE(L"CrackName(%s, &pszDomain, GET_DNS_DOMAIN_NAME, NULL);\n", bsDN);
  205. hr = CrackName(bsDN, &pszLocalDomain, GET_DNS_DOMAIN_NAME, NULL);
  206. TRACE(L"CrackName returned hr = 0x%x, pszLocalDomain = <%s>\n", hr, pszLocalDomain);
  207. } // if distinguishedName
  208. //
  209. // User Principle Name
  210. //
  211. if (_wcsicmp (L"userPrincipalName", pAttrs[i].pszAttrName) == 0)
  212. {
  213. CString csTemp = pAttrs[i].pADsValues->CaseIgnoreString;
  214. INT loc = csTemp.Find (L'@');
  215. if (loc > 0)
  216. {
  217. dlgRename.m_login = csTemp.Left(loc);
  218. dlgRename.m_domain = csTemp.Right (csTemp.GetLength() - loc);
  219. }
  220. else
  221. {
  222. dlgRename.m_login = csTemp;
  223. ASSERT (0 && L"can't find @ in upn");
  224. }
  225. } // if userPrincipalName
  226. //
  227. // sAMAccountName
  228. //
  229. if (_wcsicmp (L"sAMAccountName", pAttrs[i].pszAttrName) == 0)
  230. {
  231. dlgRename.m_samaccountname = pAttrs[i].pADsValues->CaseIgnoreString;
  232. } // if sAMAccountName
  233. //
  234. // givenName
  235. //
  236. if (_wcsicmp (L"givenName", pAttrs[i].pszAttrName) == 0)
  237. {
  238. dlgRename.m_first = pAttrs[i].pADsValues->CaseIgnoreString;
  239. } // if givenName
  240. //
  241. // displayName
  242. //
  243. if (_wcsicmp (L"displayName", pAttrs[i].pszAttrName) == 0)
  244. {
  245. dlgRename.m_displayname = pAttrs[i].pADsValues->CaseIgnoreString;
  246. } // if displayName
  247. //
  248. // sn
  249. //
  250. if (_wcsicmp (L"sn", pAttrs[i].pszAttrName) == 0)
  251. {
  252. dlgRename.m_last = pAttrs[i].pADsValues->CaseIgnoreString;
  253. } // if sn
  254. //
  255. // cn
  256. //
  257. if (_wcsicmp (L"cn", pAttrs[i].pszAttrName) == 0)
  258. {
  259. dlgRename.m_oldcn = pAttrs[i].pADsValues->CaseIgnoreString;
  260. } // if cn
  261. }
  262. }
  263. //
  264. // get UPN suffixes from this OU, if present
  265. //
  266. CComPtr<IADs> spIADs;
  267. CComPtr<IADs> spContIADs;
  268. CComBSTR bsParentPath;
  269. CStringList UPNs;
  270. hr = spDirObj->QueryInterface (IID_IADs, (void **)&spIADs);
  271. ASSERT (SUCCEEDED(hr));
  272. hr = spIADs->get_Parent(&bsParentPath);
  273. ASSERT (SUCCEEDED(hr));
  274. hr = DSAdminOpenObject(bsParentPath,
  275. IID_IADs,
  276. (void **)&spContIADs,
  277. TRUE /*bServer*/);
  278. ASSERT(SUCCEEDED(hr));
  279. CComVariant Var;
  280. hr = spContIADs->Get ( L"uPNSuffixes", &Var);
  281. if (SUCCEEDED(hr))
  282. {
  283. hr = HrVariantToStringList (Var, UPNs);
  284. if (SUCCEEDED(hr))
  285. {
  286. POSITION pos = UPNs.GetHeadPosition();
  287. CString csSuffix;
  288. while (pos != NULL)
  289. {
  290. csSuffix = L"@";
  291. csSuffix += UPNs.GetNext(INOUT pos);
  292. TRACE(_T("UPN suffix: %s\n"), csSuffix);
  293. if (wcscmp (csSuffix, dlgRename.m_domain))
  294. {
  295. dlgRename.m_domains.AddTail (csSuffix);
  296. }
  297. }
  298. }
  299. }
  300. else
  301. {
  302. //
  303. // now get the domain options
  304. //
  305. CComPtr<IDsBrowseDomainTree> spDsDomains;
  306. hr = ::CoCreateInstance(CLSID_DsDomainTreeBrowser,
  307. NULL,
  308. CLSCTX_INPROC_SERVER,
  309. IID_IDsBrowseDomainTree,
  310. (LPVOID*)&spDsDomains);
  311. ASSERT(SUCCEEDED(hr));
  312. PDOMAIN_TREE pNewDomains = NULL;
  313. hr = spDsDomains->GetDomains(&pNewDomains, 0);
  314. if (SUCCEEDED(hr))
  315. {
  316. ASSERT(pNewDomains);
  317. for (UINT index = 0; index < pNewDomains->dwCount; index++)
  318. {
  319. if (pNewDomains->aDomains[index].pszTrustParent == NULL)
  320. {
  321. CString strAtDomain = "@";
  322. strAtDomain += pNewDomains->aDomains[index].pszName;
  323. if (wcscmp (strAtDomain, dlgRename.m_domain))
  324. {
  325. dlgRename.m_domains.AddTail (strAtDomain);
  326. }
  327. }
  328. }
  329. spDsDomains->FreeDomains(&pNewDomains);
  330. }
  331. LocalFreeStringW(&pszDomain);
  332. //
  333. // get UPN suffixes
  334. //
  335. CString csPartitions;
  336. CStringList UPNsList;
  337. //
  338. // get config path from main object
  339. //
  340. csPartitions = m_pComponentData->GetBasePathsInfo()->GetProviderAndServerName();
  341. csPartitions += L"CN=Partitions,";
  342. csPartitions += m_pComponentData->GetBasePathsInfo()->GetConfigNamingContext();
  343. CComPtr<IADs> spPartitions;
  344. hr = DSAdminOpenObject(csPartitions,
  345. IID_IADs,
  346. (void **)&spPartitions,
  347. TRUE /*bServer*/);
  348. if (SUCCEEDED(hr))
  349. {
  350. CComVariant sVar;
  351. hr = spPartitions->Get ( L"uPNSuffixes", &sVar);
  352. if (SUCCEEDED(hr))
  353. {
  354. hr = HrVariantToStringList (sVar, UPNsList);
  355. if (SUCCEEDED(hr))
  356. {
  357. POSITION pos = UPNsList.GetHeadPosition();
  358. CString csSuffix;
  359. while (pos != NULL)
  360. {
  361. csSuffix = L"@";
  362. csSuffix += UPNsList.GetNext(INOUT pos);
  363. TRACE(_T("UPN suffix: %s\n"), csSuffix);
  364. if (wcscmp (csSuffix, dlgRename.m_domain))
  365. {
  366. dlgRename.m_domains.AddTail (csSuffix);
  367. }
  368. }
  369. }
  370. }
  371. }
  372. }
  373. while ((error) && (!fAccessDenied))
  374. {
  375. answer = dlgRename.DoModal();
  376. if (answer == IDOK)
  377. {
  378. ADSVALUE avUPN = {ADSTYPE_CASE_IGNORE_STRING, NULL};
  379. ADS_ATTR_INFO aiUPN = {L"userPrincipalName", ADS_ATTR_UPDATE,
  380. ADSTYPE_CASE_IGNORE_STRING, &avUPN, 1};
  381. ADSVALUE avSAMName = {ADSTYPE_CASE_IGNORE_STRING, NULL};
  382. ADS_ATTR_INFO aiSAMName = {L"sAMAccountName", ADS_ATTR_UPDATE,
  383. ADSTYPE_CASE_IGNORE_STRING, &avSAMName, 1};
  384. ADSVALUE avGiven = {ADSTYPE_CASE_IGNORE_STRING, NULL};
  385. ADS_ATTR_INFO aiGiven = {L"givenName", ADS_ATTR_UPDATE,
  386. ADSTYPE_CASE_IGNORE_STRING, &avGiven, 1};
  387. ADSVALUE avSurName = {ADSTYPE_CASE_IGNORE_STRING, NULL};
  388. ADS_ATTR_INFO aiSurName = {L"sn", ADS_ATTR_UPDATE,
  389. ADSTYPE_CASE_IGNORE_STRING, &avSurName, 1};
  390. ADSVALUE avDispName = {ADSTYPE_CASE_IGNORE_STRING, NULL};
  391. ADS_ATTR_INFO aiDispName = {L"displayName", ADS_ATTR_UPDATE,
  392. ADSTYPE_CASE_IGNORE_STRING, &avDispName, 1};
  393. ADS_ATTR_INFO rgAttrs[5];
  394. ULONG cModified = 0;
  395. cAttrs = 0;
  396. if (!dlgRename.m_login.IsEmpty() && !dlgRename.m_domain.IsEmpty())
  397. {
  398. dlgRename.m_login.TrimRight();
  399. dlgRename.m_login.TrimLeft();
  400. //
  401. // Check for illegal characters in the login name
  402. //
  403. HRESULT hrValidate = ValidateAndModifyName(dlgRename.m_login,
  404. INVALID_ACCOUNT_NAME_CHARS,
  405. L'_',
  406. IDS_LOGINNAME_ILLEGAL,
  407. m_hwnd);
  408. if (FAILED(hrValidate))
  409. {
  410. continue;
  411. }
  412. dlgRename.m_domain.TrimRight();
  413. dlgRename.m_domain.TrimLeft();
  414. CString csTemp = (dlgRename.m_login + dlgRename.m_domain);
  415. pszUPN = new WCHAR[wcslen(csTemp) + sizeof(WCHAR)];
  416. if (pszUPN != NULL)
  417. {
  418. wcscpy (pszUPN, csTemp);
  419. avUPN.CaseIgnoreString = pszUPN;
  420. }
  421. }
  422. else
  423. {
  424. aiUPN.dwControlCode = ADS_ATTR_CLEAR;
  425. }
  426. rgAttrs[cAttrs++] = aiUPN;
  427. //
  428. // test UPN for duplication
  429. // validate UPN with GC before doing the put.
  430. //
  431. BOOL fDomainSearchFailed = FALSE;
  432. BOOL fGCSearchFailed = FALSE;
  433. HRESULT hr2 = S_OK;
  434. BOOL dup = FALSE;
  435. CString strFilter;
  436. if (pszUPN != NULL && *pszUPN != '\0')
  437. {
  438. LPWSTR pAttributes[1] = {L"cn"};
  439. CComPtr<IDirectorySearch> spGCObj = NULL;
  440. CDSSearch DSS (m_pComponentData->GetClassCache(), m_pComponentData);
  441. hr = DSPROP_GetGCSearchOnDomain(pszLocalDomain,
  442. IID_IDirectorySearch,
  443. (void **)&spGCObj);
  444. if (FAILED(hr))
  445. {
  446. fGCSearchFailed = TRUE;
  447. }
  448. else
  449. {
  450. DSS.Init (spGCObj);
  451. strFilter = L"(userPrincipalName=";
  452. strFilter += pszUPN;
  453. strFilter += L")";
  454. DSS.SetAttributeList (pAttributes, 1);
  455. DSS.SetFilterString ((LPWSTR)(LPCWSTR)strFilter);
  456. DSS.SetSearchScope (ADS_SCOPE_SUBTREE);
  457. DSS.DoQuery();
  458. hr = DSS.GetNextRow();
  459. while ((hr == S_OK) && (dup == FALSE)) // this means a row was returned, so we're dup
  460. {
  461. ADS_SEARCH_COLUMN Col;
  462. hr = DSS.GetColumn(pAttributes[0], &Col);
  463. if (_wcsicmp(Col.pADsValues->CaseIgnoreString, dlgRename.m_oldcn))
  464. {
  465. dup = TRUE;
  466. ReportErrorEx (m_hwnd, IDS_UPN_DUP, hr,
  467. MB_OK, NULL, 0);
  468. }
  469. hr = DSS.GetNextRow();
  470. }
  471. if (hr != S_ADS_NOMORE_ROWS)
  472. {
  473. fGCSearchFailed = TRUE;
  474. }
  475. }
  476. if (dup)
  477. {
  478. continue;
  479. }
  480. else
  481. {
  482. CString strInitPath = L"LDAP://";
  483. strInitPath += pszLocalDomain;
  484. TRACE(_T("Initialize Domain search object with: %s...\n"), strInitPath);
  485. hr2 = DSS.Init (strInitPath);
  486. if (SUCCEEDED(hr2))
  487. {
  488. LPWSTR pAttributes2[1] = {L"cn"};
  489. strFilter = L"(userPrincipalName=";
  490. strFilter += pszUPN;
  491. strFilter += L")";
  492. TRACE(_T("searching current domain for %s...\n"), pszUPN);
  493. DSS.SetAttributeList (pAttributes2, 1);
  494. DSS.SetFilterString ((LPWSTR)(LPCWSTR)strFilter);
  495. DSS.SetSearchScope (ADS_SCOPE_SUBTREE);
  496. DSS.DoQuery();
  497. hr2 = DSS.GetNextRow();
  498. TRACE(_T("done searching current domain for %s...\n"), pszUPN);
  499. }
  500. while ((hr2 == S_OK) && (dup == FALSE)) // this means a row was returned, so we're dup
  501. {
  502. ADS_SEARCH_COLUMN Col;
  503. HRESULT hr3 = DSS.GetColumn(pAttributes[0], &Col);
  504. ASSERT (hr3 == S_OK);
  505. if (_wcsicmp(Col.pADsValues->CaseIgnoreString, dlgRename.m_oldcn))
  506. {
  507. dup = TRUE;
  508. ReportErrorEx (m_hwnd, IDS_UPN_DUP, hr,
  509. MB_OK, NULL, 0);
  510. }
  511. hr2 = DSS.GetNextRow();
  512. }
  513. if (hr2 != S_ADS_NOMORE_ROWS) // oops, had another problem
  514. {
  515. fDomainSearchFailed = TRUE;
  516. }
  517. }
  518. }
  519. if (dup)
  520. {
  521. continue;
  522. }
  523. else
  524. {
  525. if (fDomainSearchFailed ||
  526. fGCSearchFailed ||
  527. pszUPN == NULL ||
  528. *pszUPN == L'\0')
  529. {
  530. if (fDomainSearchFailed)
  531. {
  532. ReportErrorEx (m_hwnd,IDS_UPN_SEARCH_FAILED2,hr2,
  533. MB_OK | MB_ICONWARNING, NULL, 0);
  534. }
  535. else if (fGCSearchFailed)
  536. {
  537. ReportErrorEx (m_hwnd,IDS_UPN_SEARCH_FAILED2,hr,
  538. MB_OK | MB_ICONWARNING, NULL, 0);
  539. }
  540. else
  541. {
  542. ReportErrorEx (m_hwnd, IDS_UPN_SEARCH_FAILED3, hr,
  543. MB_OK | MB_ICONWARNING, NULL, 0);
  544. }
  545. }
  546. }
  547. dlgRename.m_cn.TrimRight();
  548. dlgRename.m_cn.TrimLeft();
  549. m_szNewName = dlgRename.m_cn;
  550. if (dlgRename.m_cn == dlgRename.m_oldcn)
  551. {
  552. NoRename = TRUE;
  553. }
  554. if (!dlgRename.m_displayname.IsEmpty())
  555. {
  556. dlgRename.m_displayname.TrimLeft();
  557. dlgRename.m_displayname.TrimRight();
  558. pszDispName = new WCHAR[wcslen(dlgRename.m_displayname) + sizeof(WCHAR)];
  559. if (pszDispName != NULL)
  560. {
  561. wcscpy (pszDispName, dlgRename.m_displayname);
  562. avDispName.CaseIgnoreString = pszDispName;
  563. }
  564. }
  565. else
  566. {
  567. aiDispName.dwControlCode = ADS_ATTR_CLEAR;
  568. }
  569. rgAttrs[cAttrs++] = aiDispName;
  570. if (!dlgRename.m_first.IsEmpty())
  571. {
  572. dlgRename.m_first.TrimLeft();
  573. dlgRename.m_first.TrimRight();
  574. pszFirstName = new WCHAR[wcslen(dlgRename.m_first) + sizeof(WCHAR)];
  575. if (pszFirstName != NULL)
  576. {
  577. wcscpy (pszFirstName, dlgRename.m_first);
  578. avGiven.CaseIgnoreString = pszFirstName;
  579. }
  580. }
  581. else
  582. {
  583. aiGiven.dwControlCode = ADS_ATTR_CLEAR;
  584. }
  585. rgAttrs[cAttrs++] = aiGiven;
  586. if (!dlgRename.m_last.IsEmpty())
  587. {
  588. dlgRename.m_last.TrimLeft();
  589. dlgRename.m_last.TrimRight();
  590. pszSurName = new WCHAR[wcslen(dlgRename.m_last) + sizeof(WCHAR)];
  591. if (pszSurName != NULL)
  592. {
  593. wcscpy (pszSurName, dlgRename.m_last);
  594. avSurName.CaseIgnoreString = pszSurName;
  595. }
  596. }
  597. else
  598. {
  599. aiSurName.dwControlCode = ADS_ATTR_CLEAR;
  600. }
  601. rgAttrs[cAttrs++] = aiSurName;
  602. if (!dlgRename.m_samaccountname.IsEmpty())
  603. {
  604. dlgRename.m_samaccountname.TrimLeft();
  605. dlgRename.m_samaccountname.TrimRight();
  606. //
  607. // Check for illegal characters in the SAM account name
  608. //
  609. HRESULT hrValidate = ValidateAndModifyName(dlgRename.m_samaccountname,
  610. INVALID_ACCOUNT_NAME_CHARS_WITH_AT,
  611. L'_',
  612. IDS_SAMNAME_ILLEGAL,
  613. m_hwnd);
  614. if (FAILED(hrValidate))
  615. {
  616. continue;
  617. }
  618. pszSAMName = new WCHAR[wcslen(dlgRename.m_samaccountname) + sizeof(WCHAR)];
  619. if (pszSAMName != NULL)
  620. {
  621. wcscpy (pszSAMName, dlgRename.m_samaccountname);
  622. avSAMName.CaseIgnoreString = pszSAMName;
  623. }
  624. }
  625. else
  626. {
  627. aiSAMName.dwControlCode = ADS_ATTR_CLEAR;
  628. }
  629. rgAttrs[cAttrs++] = aiSAMName;
  630. hr = spDirObj->SetObjectAttributes (rgAttrs, cAttrs, &cModified);
  631. if (FAILED(hr))
  632. {
  633. if (hr == E_ACCESSDENIED)
  634. {
  635. fAccessDenied = TRUE;
  636. NoRename = TRUE;
  637. }
  638. else
  639. {
  640. ReportErrorEx (m_hwnd, IDS_NAME_CHANGE_FAILED, hr,
  641. MB_OK|MB_ICONERROR, NULL, 0, 0, TRUE);
  642. }
  643. }
  644. else
  645. {
  646. error = FALSE;
  647. }
  648. }
  649. else
  650. {
  651. error = FALSE;
  652. }
  653. }
  654. }
  655. else
  656. {
  657. answer = IDCANCEL;
  658. PVOID apv[1] = {(BSTR)(LPWSTR)(LPCWSTR)m_pCookie->GetName()};
  659. ReportErrorEx (m_hwnd,IDS_12_USER_OBJECT_NOT_ACCESSABLE,hr,
  660. MB_OK | MB_ICONERROR, apv, 1);
  661. }
  662. if ((answer == IDOK) && (error == FALSE) && (NoRename == FALSE))
  663. {
  664. hr = CommitRenameToDS();
  665. }
  666. if (fAccessDenied)
  667. {
  668. PVOID apv[1] = {(BSTR)(LPWSTR)(LPCWSTR)m_pCookie->GetName()};
  669. ReportErrorEx(::GetParent(m_hwnd),IDS_12_RENAME_NOT_ALLOWED,hr,
  670. MB_OK | MB_ICONERROR, apv, 1);
  671. }
  672. //
  673. // Cleanup
  674. //
  675. if (pszLocalDomain != NULL)
  676. {
  677. LocalFreeStringW(&pszLocalDomain);
  678. }
  679. if (pszUPN != NULL)
  680. {
  681. delete pszUPN;
  682. }
  683. if (pszFirstName != NULL)
  684. {
  685. delete pszFirstName;
  686. }
  687. if (pszSurName != NULL)
  688. {
  689. delete pszSurName;
  690. }
  691. if (pszSAMName != NULL)
  692. {
  693. delete pszSAMName;
  694. }
  695. if (pszDispName != NULL)
  696. {
  697. delete pszDispName;
  698. }
  699. return hr;
  700. }
  701. /////////////////////////////////////////////////////////////////////////////
  702. // CDSRenameGroup
  703. //
  704. HRESULT CDSRenameGroup::DoRename()
  705. {
  706. //
  707. // Verify data members
  708. //
  709. if (m_pUINode == NULL || m_pCookie == NULL || m_pComponentData == NULL)
  710. {
  711. ASSERT(FALSE);
  712. return E_INVALIDARG;
  713. }
  714. //
  715. // Rename Group
  716. //
  717. HRESULT hr = S_OK;
  718. BOOL error = FALSE;
  719. BOOL fAccessDenied = FALSE;
  720. BOOL NoRename = FALSE;
  721. INT_PTR answer = IDCANCEL;
  722. CRenameGroupDlg dlgRename;
  723. dlgRename.m_cn = m_szNewName;
  724. //
  725. // Check the length of the new name
  726. //
  727. if ((dlgRename.m_cn).GetLength() > 64)
  728. {
  729. ReportErrorEx (m_hwnd, IDS_NAME_TOO_LONG, S_OK,
  730. MB_OK | MB_ICONWARNING, NULL, 0, FALSE);
  731. dlgRename.m_cn = (dlgRename.m_cn).Left(64);
  732. }
  733. //
  734. // Bind to the object
  735. //
  736. CComPtr<IADs> spIADs;
  737. CString szPath;
  738. m_pComponentData->GetBasePathsInfo()->ComposeADsIPath(szPath, m_pCookie->GetPath());
  739. hr = DSAdminOpenObject(szPath,
  740. IID_IADs,
  741. (void **)&spIADs,
  742. TRUE /*bServer*/);
  743. if (SUCCEEDED(hr))
  744. {
  745. //
  746. // Retrieve the sAMAccountName
  747. //
  748. CComVariant Var;
  749. hr = spIADs->Get (L"sAMAccountName", &Var);
  750. ASSERT (SUCCEEDED(hr));
  751. CString csSam = Var.bstrVal;
  752. dlgRename.m_samaccountname = csSam;
  753. error = TRUE;
  754. while ((error) && (!fAccessDenied))
  755. {
  756. answer = dlgRename.DoModal();
  757. if (answer == IDOK)
  758. {
  759. dlgRename.m_cn.TrimRight();
  760. dlgRename.m_cn.TrimLeft();
  761. m_szNewName = dlgRename.m_cn;
  762. Var.vt = VT_BSTR;
  763. //
  764. // Trim whitespace from samaccountname
  765. //
  766. dlgRename.m_samaccountname.TrimLeft();
  767. dlgRename.m_samaccountname.TrimRight();
  768. //
  769. // Check for illegal characters in the login name
  770. //
  771. HRESULT hrValidate = ValidateAndModifyName(dlgRename.m_samaccountname,
  772. INVALID_ACCOUNT_NAME_CHARS,
  773. L'_',
  774. IDS_GROUP_SAMNAME_ILLEGAL,
  775. m_hwnd);
  776. if (FAILED(hrValidate))
  777. {
  778. continue;
  779. }
  780. csSam = dlgRename.m_samaccountname;
  781. //
  782. // Put changes to samaccountname
  783. //
  784. Var.bstrVal = SysAllocString(csSam);
  785. hr = spIADs->Put (L"sAMAccountName", Var);
  786. ASSERT (SUCCEEDED(hr));
  787. SysFreeString (Var.bstrVal);
  788. if (FAILED(hr))
  789. {
  790. continue;
  791. }
  792. //
  793. // Commit the changes
  794. //
  795. hr = spIADs->SetInfo();
  796. if (FAILED(hr))
  797. {
  798. if (hr == E_ACCESSDENIED)
  799. {
  800. fAccessDenied = TRUE;
  801. NoRename = TRUE;
  802. }
  803. else
  804. {
  805. ReportErrorEx (m_hwnd, IDS_NAME_CHANGE_FAILED, hr,
  806. MB_OK|MB_ICONERROR, NULL, 0, 0, TRUE);
  807. }
  808. }
  809. else
  810. {
  811. error = FALSE;
  812. }
  813. }
  814. else
  815. {
  816. error = FALSE;
  817. }
  818. }
  819. }
  820. else
  821. {
  822. answer = IDCANCEL;
  823. }
  824. if ((answer == IDOK) && (error == FALSE) && (NoRename == FALSE))
  825. {
  826. hr = CommitRenameToDS();
  827. }
  828. if (fAccessDenied)
  829. {
  830. PVOID apv[1] = {(BSTR)(LPWSTR)(LPCWSTR)m_pCookie->GetName()};
  831. ReportErrorEx(::GetParent(m_hwnd),IDS_12_RENAME_NOT_ALLOWED,hr,
  832. MB_OK | MB_ICONERROR, apv, 1);
  833. }
  834. return hr;
  835. }
  836. /////////////////////////////////////////////////////////////////////////////
  837. // CDSRenameContact
  838. //
  839. HRESULT CDSRenameContact::DoRename()
  840. {
  841. //
  842. // Verify data members
  843. //
  844. if (m_pUINode == NULL || m_pCookie == NULL || m_pComponentData == NULL)
  845. {
  846. ASSERT(FALSE);
  847. return E_INVALIDARG;
  848. }
  849. BOOL error = FALSE;
  850. BOOL fAccessDenied = FALSE;
  851. BOOL NoRename = FALSE;
  852. INT_PTR answer = IDCANCEL;
  853. HRESULT hr = S_OK;
  854. //
  855. // rename contact
  856. //
  857. CRenameContactDlg dlgRename;
  858. dlgRename.m_cn = m_szNewName;
  859. //
  860. // Check the length of the new name
  861. //
  862. if ((dlgRename.m_cn).GetLength() > 64)
  863. {
  864. ReportErrorEx (m_hwnd, IDS_NAME_TOO_LONG, S_OK,
  865. MB_OK | MB_ICONWARNING, NULL, 0, FALSE);
  866. dlgRename.m_cn = (dlgRename.m_cn).Left(64);
  867. }
  868. //
  869. // Bind to the DS object
  870. //
  871. CComPtr<IADs> spIADs;
  872. CString szPath;
  873. m_pComponentData->GetBasePathsInfo()->ComposeADsIPath(szPath, m_pCookie->GetPath());
  874. hr = DSAdminOpenObject(szPath,
  875. IID_IADs,
  876. (void **)&spIADs,
  877. TRUE /*bServer*/);
  878. if (SUCCEEDED(hr))
  879. {
  880. //
  881. // Retrieve the needed attributes
  882. //
  883. //
  884. // givenName
  885. //
  886. CComVariant Var;
  887. hr = spIADs->Get (L"givenName", &Var);
  888. ASSERT (SUCCEEDED(hr) || (hr == E_ADS_PROPERTY_NOT_FOUND));
  889. if (SUCCEEDED(hr))
  890. {
  891. dlgRename.m_first = Var.bstrVal;
  892. }
  893. //
  894. // sur name
  895. //
  896. hr = spIADs->Get (L"sn", &Var);
  897. ASSERT (SUCCEEDED(hr) || (hr == E_ADS_PROPERTY_NOT_FOUND));
  898. if (SUCCEEDED(hr))
  899. {
  900. dlgRename.m_last = Var.bstrVal;
  901. }
  902. //
  903. // Display name
  904. //
  905. hr = spIADs->Get (L"displayName", &Var);
  906. ASSERT (SUCCEEDED(hr) || (hr == E_ADS_PROPERTY_NOT_FOUND));
  907. if (SUCCEEDED(hr))
  908. {
  909. dlgRename.m_disp = Var.bstrVal;
  910. }
  911. error = TRUE;
  912. while ((error) && (!fAccessDenied))
  913. {
  914. answer = dlgRename.DoModal();
  915. if (answer == IDOK)
  916. {
  917. dlgRename.m_cn.TrimRight();
  918. dlgRename.m_cn.TrimLeft();
  919. m_szNewName = dlgRename.m_cn;
  920. Var.vt = VT_BSTR;
  921. //
  922. // Put givenName
  923. //
  924. if (!dlgRename.m_first.IsEmpty())
  925. {
  926. dlgRename.m_first.TrimLeft();
  927. dlgRename.m_first.TrimRight();
  928. Var.bstrVal = SysAllocString (dlgRename.m_first);
  929. hr = spIADs->Put (L"givenName", Var);
  930. ASSERT (SUCCEEDED(hr));
  931. SysFreeString(Var.bstrVal);
  932. }
  933. //
  934. // Put sur name
  935. //
  936. if (!dlgRename.m_last.IsEmpty())
  937. {
  938. dlgRename.m_last.TrimLeft();
  939. dlgRename.m_last.TrimRight();
  940. Var.bstrVal = SysAllocString(dlgRename.m_last);
  941. hr = spIADs->Put (L"sn", Var);
  942. ASSERT (SUCCEEDED(hr));
  943. SysFreeString (Var.bstrVal);
  944. }
  945. //
  946. // Put displayName
  947. //
  948. if (!dlgRename.m_disp.IsEmpty())
  949. {
  950. dlgRename.m_disp.TrimLeft();
  951. dlgRename.m_disp.TrimRight();
  952. Var.bstrVal = SysAllocString(dlgRename.m_disp);
  953. hr = spIADs->Put (L"displayName", Var);
  954. ASSERT (SUCCEEDED(hr));
  955. SysFreeString (Var.bstrVal);
  956. }
  957. //
  958. // Commit changes to DS object
  959. //
  960. hr = spIADs->SetInfo();
  961. if (FAILED(hr))
  962. {
  963. if (hr == E_ACCESSDENIED)
  964. {
  965. fAccessDenied = TRUE;
  966. NoRename = TRUE;
  967. }
  968. else
  969. {
  970. ReportErrorEx (m_hwnd, IDS_NAME_CHANGE_FAILED, hr,
  971. MB_OK|MB_ICONERROR, NULL, 0, 0, TRUE);
  972. }
  973. }
  974. else
  975. {
  976. error = FALSE;
  977. }
  978. }
  979. else
  980. {
  981. error = FALSE;
  982. }
  983. }
  984. }
  985. else
  986. {
  987. answer = IDCANCEL;
  988. }
  989. if ((answer == IDOK) && (error == FALSE) && (NoRename == FALSE))
  990. {
  991. hr = CommitRenameToDS();
  992. }
  993. if (fAccessDenied)
  994. {
  995. PVOID apv[1] = {(BSTR)(LPWSTR)(LPCWSTR)m_pCookie->GetName()};
  996. ReportErrorEx(::GetParent(m_hwnd),IDS_12_RENAME_NOT_ALLOWED,hr,
  997. MB_OK | MB_ICONERROR, apv, 1);
  998. }
  999. return hr;
  1000. }
  1001. /////////////////////////////////////////////////////////////////////////////
  1002. // CDSRenameSite
  1003. //
  1004. HRESULT CDSRenameSite::DoRename()
  1005. {
  1006. //
  1007. // Verify data members
  1008. //
  1009. if (m_pUINode == NULL || m_pCookie == NULL || m_pComponentData == NULL)
  1010. {
  1011. ASSERT(FALSE);
  1012. return E_INVALIDARG;
  1013. }
  1014. HRESULT hr = S_OK;
  1015. //
  1016. // Rename site
  1017. //
  1018. BOOL fNonRfcSiteName = FALSE;
  1019. BOOL fValidSiteName = IsValidSiteName( m_szNewName, &fNonRfcSiteName );
  1020. if ( !fValidSiteName )
  1021. {
  1022. ReportErrorEx (m_hwnd,IDS_SITE_NAME,S_OK,
  1023. MB_OK, NULL, 0);
  1024. }
  1025. else if (fNonRfcSiteName)
  1026. {
  1027. LPCWSTR pszNewName = m_szNewName;
  1028. PVOID apv[1];
  1029. apv[0] = (PVOID)pszNewName;
  1030. if (IDYES != ReportMessageEx( m_hwnd,
  1031. IDS_1_NON_RFC_SITE_NAME,
  1032. MB_YESNO | MB_ICONWARNING,
  1033. apv,
  1034. 1 ) )
  1035. {
  1036. fValidSiteName = FALSE;
  1037. }
  1038. }
  1039. if ( fValidSiteName )
  1040. {
  1041. hr = CommitRenameToDS();
  1042. }
  1043. return hr;
  1044. }
  1045. /////////////////////////////////////////////////////////////////////////////
  1046. // CDSRenameNTDSConnection
  1047. //
  1048. HRESULT CDSRenameNTDSConnection::DoRename()
  1049. {
  1050. //
  1051. // Verify data members
  1052. //
  1053. if (m_pUINode == NULL || m_pCookie == NULL || m_pComponentData == NULL)
  1054. {
  1055. ASSERT(FALSE);
  1056. return E_INVALIDARG;
  1057. }
  1058. HRESULT hr = S_OK;
  1059. //
  1060. // JonN 5/10/01 283026
  1061. // Duplicate connection objects named
  1062. // "<automatically generated>" can be created
  1063. //
  1064. CString strKCCGenerated;
  1065. CString strNewName = m_szNewName;
  1066. strNewName.TrimLeft();
  1067. strNewName.TrimRight();
  1068. strKCCGenerated.LoadString (IDS_CONNECTION_KCC_GENERATED);
  1069. if ( !strNewName.CompareNoCase(strKCCGenerated) )
  1070. {
  1071. TRACE (_T("CDSRenameNTDSConnection::DoRename blocked rename"));
  1072. ReportErrorEx (m_hwnd,IDS_CONNECTION_RENAME_KCCSTRING,hr,
  1073. MB_OK | MB_ICONWARNING, NULL, 0);
  1074. return S_OK;
  1075. }
  1076. //
  1077. // Rename nTDSConnection
  1078. //
  1079. if (m_pComponentData->RenameConnectionFixup(m_pCookie))
  1080. {
  1081. hr = CommitRenameToDS();
  1082. }
  1083. return hr;
  1084. }
  1085. /////////////////////////////////////////////////////////////////////////////
  1086. // CDSRenameSubnet
  1087. //
  1088. HRESULT CDSRenameSubnet::DoRename()
  1089. {
  1090. //
  1091. // Verify data members
  1092. //
  1093. if (m_pUINode == NULL || m_pCookie == NULL || m_pComponentData == NULL)
  1094. {
  1095. ASSERT(FALSE);
  1096. return E_INVALIDARG;
  1097. }
  1098. HRESULT hr = S_OK;
  1099. //
  1100. // Rename subnet
  1101. //
  1102. DWORD dw = ::DsValidateSubnetName( m_szNewName );
  1103. if (ERROR_SUCCESS == dw)
  1104. {
  1105. hr = CommitRenameToDS();
  1106. }
  1107. else
  1108. {
  1109. ReportErrorEx (m_hwnd,IDS_SUBNET_NAME,S_OK,
  1110. MB_OK, NULL, 0);
  1111. }
  1112. return hr;
  1113. }