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.

638 lines
19 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1997 - 1999
  6. //
  7. // File: dsutil.h
  8. //
  9. //--------------------------------------------------------------------------
  10. #ifndef __DSUTIL_H_
  11. #define __DSUTIL_H_
  12. #include "util.h"
  13. #include "uiutil.h"
  14. #include "dssnap.h"
  15. #include "query.h"
  16. //
  17. // Common DS strings
  18. //
  19. extern PCWSTR g_pszAllowedAttributesEffective;
  20. extern PCWSTR g_pszPwdLastSet;
  21. /////////////////////////////////////////////////////////////////////////////////
  22. // ADSI path helpers
  23. //
  24. HRESULT GetServerFromLDAPPath(IN LPCWSTR lpszLdapPath, OUT BSTR* pbstrServerName);
  25. BOOL
  26. StripADsIPath(
  27. LPCWSTR lpszPath,
  28. CString& strref,
  29. bool bUseEscapedMode = true);
  30. BOOL
  31. StripADsIPath(
  32. LPCWSTR lpszPath,
  33. CString& strref,
  34. CPathCracker& pathCracker,
  35. bool bUseEscapedMode = true);
  36. // remove escape characters from a path
  37. // Arguments:
  38. // lpszPath = path to be escaped
  39. // bDN = if TRUE, the path os a distinguished name, if FALSE is an LDAP path
  40. // bstrUnescaped = returned unescaped path
  41. //
  42. inline HRESULT UnescapePath(IN LPCWSTR lpszPath, IN BOOL bDN, OUT CComBSTR& bstrUnescaped)
  43. {
  44. CPathCracker pathCracker;
  45. pathCracker.Set(CComBSTR(lpszPath), bDN ? ADS_SETTYPE_DN : ADS_SETTYPE_FULL);
  46. pathCracker.put_EscapedMode(ADS_ESCAPEDMODE_OFF);
  47. bstrUnescaped = (LPCWSTR)NULL;
  48. HRESULT hr = pathCracker.Retrieve(bDN ? ADS_FORMAT_X500_DN : ADS_FORMAT_X500, &bstrUnescaped);
  49. return hr;
  50. }
  51. class CObjectNamesFormatCracker; // fwd decl
  52. HRESULT AddDataObjListToGroup(CObjectNamesFormatCracker * pNames,
  53. HWND hwnd,
  54. CDSComponentData* pComponentData);
  55. HRESULT AddDataObjListToGivenGroup(CObjectNamesFormatCracker * pNames,
  56. LPCWSTR lpszGroup,
  57. LPCWSTR lpszGroupName,
  58. HWND hwnd,
  59. CDSComponentData* pComponentData);
  60. BOOL IsValidSiteName( LPCTSTR lpctszSiteName, BOOL* pfNonRfc = NULL, BOOL* pfInvalidNameChar = NULL );
  61. BOOL IsLocalLogin( void );
  62. BOOL IsThisUserLoggedIn( LPCTSTR pwszUserDN );
  63. BOOL CALLBACK AddPageProc(HPROPSHEETPAGE hPage, LPARAM pCall);
  64. BOOL IsHomogenousDSSelection(LPDATAOBJECT pDataObject, CString& szClassName);
  65. BOOL CALLBACK AddPageProc(HPROPSHEETPAGE hPage, LPARAM pCall);
  66. HRESULT GetDisplaySpecifierProperty(PCWSTR pszClassName,
  67. PCWSTR pszDisplayProperty,
  68. MyBasePathsInfo* pBasePathsInfo,
  69. CStringList& strListRef,
  70. bool bEnglishOnly = false);
  71. HRESULT TabCollect_GetDisplayGUIDs(LPCWSTR lpszClassName,
  72. LPCWSTR lpszDisplayProperty,
  73. MyBasePathsInfo* pBasePathsInfo,
  74. UINT* pnCount,
  75. GUID** ppGuids);
  76. BOOL FindCookieInSubtree(IN CUINode* pContainerNode,
  77. IN LPCWSTR lpszCookieDN,
  78. IN SnapinType snapinType,
  79. OUT CUINode** ppUINode);
  80. bool CanUserChangePassword(IN IDirectoryObject* pDirObject);
  81. /////////////////////////////////////////////////////////////////////
  82. // CChangePasswordPrivilegeAction
  83. // helper class to handle the revoking and the reading of the
  84. // change password control right on user objects
  85. class CChangePasswordPrivilegeAction
  86. {
  87. public:
  88. CChangePasswordPrivilegeAction() : m_pDacl(NULL)
  89. {
  90. }
  91. HRESULT Load(IADs * pIADs);
  92. HRESULT Read(BOOL* pbPasswordCannotChange);
  93. HRESULT Revoke();
  94. private:
  95. HRESULT _SetSids();
  96. CComBSTR m_bstrObjectLdapPath;
  97. CSimpleSecurityDescriptorHolder m_SDHolder;
  98. PACL m_pDacl;
  99. CSidHolder m_SelfSid;
  100. CSidHolder m_WorldSid;
  101. };
  102. /////////////////////////////////////////////////////////////////////
  103. // CDSNotifyHandlerTransaction
  104. class CDSNotifyHandlerManager; // fwd decl
  105. class CDSComponentData;
  106. class CDSNotifyHandlerTransaction
  107. {
  108. public:
  109. CDSNotifyHandlerTransaction(CDSComponentData* pCD);
  110. ~CDSNotifyHandlerTransaction()
  111. {
  112. if (m_bStarted)
  113. End();
  114. }
  115. void SetEventType(ULONG uEvent)
  116. {
  117. ASSERT(m_uEvent == 0);
  118. ASSERT(uEvent != 0);
  119. m_uEvent = uEvent;
  120. }
  121. // state veriables check
  122. UINT NeedNotifyCount();
  123. // handlers for visualization in confirnation dialog
  124. void SetCheckListBox(CCheckListBox* pCheckListBox);
  125. void ReadFromCheckListBox(CCheckListBox* pCheckListBox);
  126. // interfaces for transacted protocol
  127. HRESULT Begin(LPCWSTR lpszArg1Path, LPCWSTR lpszArg1Class, BOOL bArg1Cont,
  128. LPCWSTR lpszArg2Path, LPCWSTR lpszArg2Class, BOOL bArg2Cont);
  129. HRESULT Begin(CDSCookie* pArg1Cookie,
  130. LPCWSTR lpszArg2Path, LPCWSTR lpszArg2Class, BOOL bArg2Cont);
  131. HRESULT Begin(IDataObject* pArg1,
  132. LPCWSTR lpszArg2Path, LPCWSTR lpszArg2Class, BOOL bArg2Cont);
  133. void Notify(ULONG nItem);
  134. void End();
  135. static HRESULT BuildTransactionDataObject(LPCWSTR lpszArgPath,
  136. LPCWSTR lpszArgClass,
  137. BOOL bContainer,
  138. CDSComponentData* pCD,
  139. IDataObject** ppArg);
  140. private:
  141. HRESULT _BuildDataObject(LPCWSTR lpszArgPath,
  142. LPCWSTR lpszArgClass,
  143. BOOL bContainer,
  144. IDataObject** ppArg);
  145. BOOL m_bStarted;
  146. CDSComponentData* m_pCD;
  147. CDSNotifyHandlerManager* m_pMgr;
  148. ULONG m_uEvent;
  149. CComPtr<IDataObject> m_spArg1;
  150. CComPtr<IDataObject> m_spArg2;
  151. };
  152. ///////////////////////////////////////////////////////////////////////////
  153. // CUIOperationHandlerBase
  154. class CUIOperationHandlerBase
  155. {
  156. public:
  157. CUIOperationHandlerBase(CDSComponentData* pComponentData, HWND hwnd)
  158. : m_transaction(pComponentData)
  159. {
  160. m_pComponentData = pComponentData;
  161. m_hWndFrame = m_hWndParent = hwnd;
  162. }
  163. virtual ~CUIOperationHandlerBase(){}
  164. protected:
  165. // accessor functions
  166. HWND GetParentHwnd() { return m_hWndParent;}
  167. void SetParentHwnd(HWND hwnd) { m_hWndParent = hwnd;}
  168. CDSComponentData* GetComponentData() { return m_pComponentData;}
  169. CDSNotifyHandlerTransaction* GetTransaction() { return &m_transaction;}
  170. // JonN 6/2/00 99382
  171. // SITEREPL: Run interference when administrator attempts to
  172. // delete critical object (NTDS Settings)
  173. // reports own errors, returns true iff deletion should proceed
  174. /* bool CheckForNTDSDSAInSubtree(
  175. LPCTSTR lpszX500Path,
  176. LPCTSTR lpszItemName);
  177. */
  178. //
  179. // JeffJon 8/10/00 27377
  180. // Check for critical system objects in the subtree before
  181. // attempting a subtree delete. This includes objects with
  182. // isCriticalSystemObject=TRUE and NTDS Settings objects
  183. //
  184. bool CheckForCriticalSystemObjectInSubtree(
  185. LPCTSTR lpszX500Path,
  186. LPCTSTR lpszItemName);
  187. // JonN 6/15/00 13574
  188. // Centralizes the checks to make sure this is an OK object to delete
  189. // returns HRESULT_FROM_WIN32(ERROR_CANCELLED) on cancellation
  190. // returns fAlternateDeleteMethod=true iff ObjectDeletionCheck already
  191. // attempted an alternate deletion method (e.g. DsRemoveDsServer).
  192. HRESULT ObjectDeletionCheck(
  193. LPCTSTR lpszADsPath,
  194. LPCTSTR lpszName, // shortname to display to user, may be NULL
  195. LPCTSTR lpszClass,
  196. bool& fAlternateDeleteMethod );
  197. private:
  198. CDSComponentData* m_pComponentData;
  199. CDSNotifyHandlerTransaction m_transaction;
  200. HWND m_hWndFrame; // MMC frame window
  201. HWND m_hWndParent; // window to parent any UI created in the handler
  202. };
  203. ///////////////////////////////////////////////////////////////////////////
  204. // CSingleDeleteHandlerBase
  205. class CSingleDeleteHandlerBase : public CUIOperationHandlerBase
  206. {
  207. public:
  208. CSingleDeleteHandlerBase(CDSComponentData* pComponentData, HWND hwnd)
  209. : CUIOperationHandlerBase(pComponentData, hwnd)
  210. {
  211. GetTransaction()->SetEventType(DSA_NOTIFY_DEL);
  212. }
  213. HRESULT Delete();
  214. protected:
  215. // hooks for customization
  216. virtual HRESULT BeginTransaction() = 0;
  217. virtual HRESULT DeleteObject() = 0;
  218. virtual HRESULT DeleteSubtree() = 0;
  219. virtual void GetItemName(OUT CString& szName) = 0;
  220. virtual LPCWSTR GetItemClass() = 0;
  221. virtual LPCWSTR GetItemPath() = 0;
  222. };
  223. ///////////////////////////////////////////////////////////////////////////
  224. // CMultipleDeleteHandlerBase
  225. class CMultipleDeleteHandlerBase : public CUIOperationHandlerBase
  226. {
  227. public:
  228. CMultipleDeleteHandlerBase(CDSComponentData* pComponentData, HWND hwnd)
  229. : CUIOperationHandlerBase(pComponentData, hwnd)
  230. {
  231. GetTransaction()->SetEventType(DSA_NOTIFY_DEL);
  232. }
  233. void Delete();
  234. protected:
  235. // hooks for customization
  236. virtual UINT GetItemCount() = 0;
  237. virtual HRESULT BeginTransaction() = 0;
  238. virtual HRESULT DeleteObject(UINT i) = 0;
  239. virtual HRESULT DeleteSubtree(UINT i) = 0;
  240. virtual void OnItemDeleted(UINT) {}
  241. virtual void GetItemName(IN UINT i, OUT CString& szName) = 0;
  242. virtual void GetItemPath(UINT i, CString& szPath) = 0;
  243. virtual PCWSTR GetItemClass(UINT i) = 0;
  244. private:
  245. CMultipleDeletionConfirmationUI m_confirmationUI;
  246. void OnStart(HWND hwnd);
  247. HRESULT OnDeleteStep(UINT i,
  248. BOOL* pbContinue,
  249. CString& strrefPath,
  250. CString& strrefClass,
  251. BOOL bSilent = TRUE);
  252. friend class CMultipleDeleteProgressDialog; // for m_confirmationUI
  253. };
  254. ///////////////////////////////////////////////////////////////////////////
  255. // CMoveHandlerBase
  256. class CMultipleMoveProgressDialog; // fwd decl
  257. class CMoveHandlerBase : public CUIOperationHandlerBase
  258. {
  259. public:
  260. CMoveHandlerBase(CDSComponentData* pComponentData, HWND hwnd,
  261. LPCWSTR lpszBrowseRootPath)
  262. : CUIOperationHandlerBase(pComponentData, hwnd)
  263. {
  264. m_lpszBrowseRootPath = lpszBrowseRootPath;
  265. GetTransaction()->SetEventType(DSA_NOTIFY_MOV);
  266. }
  267. HRESULT Move(LPCWSTR lpszDestinationPath = NULL);
  268. protected:
  269. // hooks for customization
  270. virtual UINT GetItemCount() = 0;
  271. virtual HRESULT BeginTransaction() = 0;
  272. virtual void GetNewPath(UINT i, CString& szNewPath) = 0;
  273. virtual void GetName(UINT i, CString& strref) = 0;
  274. virtual HRESULT OnItemMoved(UINT i, IADs* pIADs) = 0;
  275. virtual void GetClassOfMovedItem(CString& szClass) = 0;
  276. virtual void GetItemPath(UINT i, CString& szPath) = 0;
  277. virtual PCWSTR GetItemClass(UINT i) = 0;
  278. // JonN 1/28/02 507549 move connection object
  279. virtual HRESULT _CheckMovedObject(LPCWSTR pwszClass, LPCWSTR pwszPath);
  280. LPCWSTR GetDestPath() { return m_szDestPath;}
  281. LPCWSTR GetDestClass() { return m_szDestClass;}
  282. BOOL IsDestContainer() { return m_bDestContainer; }
  283. private:
  284. LPCWSTR m_lpszBrowseRootPath; // LDAP path where to point the browser dialog
  285. CComPtr<IADsContainer> m_spDSDestination;
  286. CString m_szDestPath;
  287. CString m_szDestClass;
  288. BOOL m_bDestContainer;
  289. BOOL _ReportFailure(BOOL bLast, HRESULT hr, LPCWSTR lpszName);
  290. HRESULT _BrowseForDestination(LPCWSTR lpszDestinationPath);
  291. BOOL _BeginTransactionAndConfirmOperation();
  292. HRESULT _MoveSingleSel(PCWSTR pszNewName);
  293. HRESULT _MoveMultipleSel();
  294. HRESULT _OnMoveStep(IN UINT i,
  295. OUT BOOL* pbCanContinue,
  296. OUT CString& strrefPath,
  297. OUT CString& strrefClass);
  298. friend class CMultipleMoveProgressDialog;
  299. };
  300. ///////////////////////////////////////////////////////////////////////////
  301. // CMultiselectMoveHandler
  302. class CMultiselectMoveHandler : public CMoveHandlerBase
  303. {
  304. private:
  305. struct CMovedState
  306. {
  307. CMovedState()
  308. {
  309. m_bMoved = FALSE;
  310. }
  311. BOOL m_bMoved;
  312. CString m_szNewPath;
  313. };
  314. public:
  315. CMultiselectMoveHandler(CDSComponentData* pComponentData, HWND hwnd,
  316. LPCWSTR lpszBrowseRootPath)
  317. : CMoveHandlerBase(pComponentData, hwnd, lpszBrowseRootPath)
  318. {
  319. m_pMovedArr = NULL;
  320. }
  321. virtual ~CMultiselectMoveHandler()
  322. {
  323. if (m_pMovedArr != NULL)
  324. delete[] m_pMovedArr;
  325. }
  326. BOOL WasItemMoved(UINT i)
  327. {
  328. ASSERT(i < GetItemCount());
  329. return m_pMovedArr[i].m_bMoved;
  330. }
  331. LPCWSTR GetNewItemPath(UINT i)
  332. {
  333. ASSERT(WasItemMoved(i));
  334. return m_pMovedArr[i].m_szNewPath;
  335. }
  336. HRESULT Initialize(IDataObject* pDataObject,
  337. CObjectNamesFormatCracker* pObjectNamesFormatCracker,
  338. CInternalFormatCracker* pInternalFormatCracker)
  339. {
  340. if ((pDataObject == NULL) || (pObjectNamesFormatCracker == NULL))
  341. {
  342. ASSERT(FALSE);
  343. return E_INVALIDARG;
  344. }
  345. m_pDataObject = pDataObject;
  346. m_pInternalFormatCracker = pInternalFormatCracker;
  347. m_pObjectNamesFormatCracker = pObjectNamesFormatCracker;
  348. if (m_pObjectNamesFormatCracker->GetCount() < 1)
  349. {
  350. ASSERT(FALSE); // something is just wrong...
  351. return E_INVALIDARG;
  352. }
  353. // allocate an array of CMovedState structs to keep track of what actually got moved
  354. // and what the new name is
  355. m_pMovedArr = new CMovedState[GetItemCount()];
  356. return S_OK;
  357. }
  358. virtual UINT GetItemCount() { return m_pObjectNamesFormatCracker->GetCount();}
  359. virtual void GetItemPath(UINT i, CString& szPath)
  360. {
  361. szPath = m_pObjectNamesFormatCracker->GetName(i);
  362. }
  363. protected:
  364. virtual HRESULT BeginTransaction()
  365. {
  366. return GetTransaction()->Begin(m_pDataObject,
  367. GetDestPath(), GetDestClass(), IsDestContainer());
  368. }
  369. virtual void GetNewPath(UINT i, CString& szNewPath)
  370. {
  371. szNewPath = m_pObjectNamesFormatCracker->GetName(i);
  372. }
  373. virtual void GetName(UINT i, CString& strref)
  374. {
  375. HRESULT hr = S_OK;
  376. if ((m_pInternalFormatCracker != NULL) && m_pInternalFormatCracker->HasData())
  377. {
  378. CUINode* pUINode = m_pInternalFormatCracker->GetCookie(i);
  379. CDSCookie* pCookie = GetDSCookieFromUINode(pUINode);
  380. strref = pCookie->GetName();
  381. }
  382. else
  383. {
  384. // REVIEW_MARCOC_PORT: this might be inefficent, need to make a member variable
  385. CPathCracker pathCracker;
  386. hr = pathCracker.Set(CComBSTR(m_pObjectNamesFormatCracker->GetName(i)),
  387. ADS_SETTYPE_FULL);
  388. hr = pathCracker.SetDisplayType(ADS_DISPLAY_VALUE_ONLY);
  389. CComBSTR DestName;
  390. hr = pathCracker.GetElement( 0, &DestName );
  391. strref = DestName;
  392. }
  393. }
  394. virtual PCWSTR GetItemClass(UINT i)
  395. {
  396. return m_pObjectNamesFormatCracker->GetClass(i);
  397. }
  398. virtual HRESULT OnItemMoved(UINT i, IADs* pIADs)
  399. {
  400. HRESULT hr = S_OK;
  401. m_pMovedArr[i].m_bMoved = TRUE;
  402. CComBSTR bsPath;
  403. hr = pIADs->get_ADsPath(&bsPath);
  404. if (SUCCEEDED(hr))
  405. {
  406. // save the new LDAP path in the array
  407. m_pMovedArr[i].m_szNewPath = bsPath;
  408. }
  409. if ((m_pInternalFormatCracker != NULL) && m_pInternalFormatCracker->HasData())
  410. {
  411. CUINode* pUINode = m_pInternalFormatCracker->GetCookie(i);
  412. CDSCookie* pCookie = GetDSCookieFromUINode(pUINode);
  413. pUINode->SetExtOp(OPCODE_MOVE);
  414. if (SUCCEEDED(hr))
  415. {
  416. CUINode* pParentNode = pUINode->GetParent();
  417. if (pParentNode != NULL)
  418. {
  419. if (!IS_CLASS(pParentNode, SAVED_QUERY_UI_NODE))
  420. {
  421. //
  422. // set the new DN in the cookie
  423. //
  424. CString szPath;
  425. StripADsIPath(bsPath, szPath);
  426. pCookie->SetPath(szPath);
  427. }
  428. }
  429. }
  430. }
  431. return hr;
  432. }
  433. virtual void GetClassOfMovedItem(CString& szClass)
  434. {
  435. szClass.Empty();
  436. if (NULL == m_pObjectNamesFormatCracker)
  437. return;
  438. UINT nCount = GetItemCount();
  439. if (0 == nCount)
  440. return;
  441. szClass = m_pObjectNamesFormatCracker->GetClass(0);
  442. for (UINT i = 1; i < nCount; i++)
  443. {
  444. if (0 != szClass.CompareNoCase( m_pObjectNamesFormatCracker->GetClass(i) ))
  445. {
  446. szClass.Empty();
  447. return;
  448. }
  449. }
  450. }
  451. protected:
  452. CMovedState* m_pMovedArr;
  453. CInternalFormatCracker* m_pInternalFormatCracker;
  454. private:
  455. IDataObject* m_pDataObject;
  456. CObjectNamesFormatCracker* m_pObjectNamesFormatCracker;
  457. };
  458. ///////////////////////////////////////////////////////////////////////////
  459. // CMultiselectMoveDataObject
  460. class CMultiselectMoveDataObject : public IDataObject, public CComObjectRoot
  461. {
  462. // ATL Maps
  463. DECLARE_NOT_AGGREGATABLE(CMultiselectMoveDataObject)
  464. BEGIN_COM_MAP(CMultiselectMoveDataObject)
  465. COM_INTERFACE_ENTRY(IDataObject)
  466. END_COM_MAP()
  467. // Construction/Destruction
  468. CMultiselectMoveDataObject()
  469. {
  470. m_pDSObjCached = NULL;
  471. m_nDSObjCachedBytes = 0;
  472. }
  473. ~CMultiselectMoveDataObject()
  474. {
  475. _Clear();
  476. }
  477. // Standard IDataObject methods
  478. public:
  479. // Implemented
  480. STDMETHOD(GetData)(FORMATETC * pformatetcIn, STGMEDIUM * pmedium);
  481. // Not Implemented
  482. private:
  483. STDMETHOD(GetDataHere)(FORMATETC*, STGMEDIUM*) { return E_NOTIMPL; };
  484. STDMETHOD(EnumFormatEtc)(DWORD, IEnumFORMATETC**) { return E_NOTIMPL; };
  485. STDMETHOD(SetData)(FORMATETC*, STGMEDIUM*,BOOL) { return E_NOTIMPL; };
  486. STDMETHOD(QueryGetData)(FORMATETC*) { return E_NOTIMPL; };
  487. STDMETHOD(GetCanonicalFormatEtc)(FORMATETC*, FORMATETC*) { return E_NOTIMPL; };
  488. STDMETHOD(DAdvise)(FORMATETC*, DWORD, IAdviseSink*, DWORD*) { return E_NOTIMPL; };
  489. STDMETHOD(DUnadvise)(DWORD) { return E_NOTIMPL; };
  490. STDMETHOD(EnumDAdvise)(IEnumSTATDATA**) { return E_NOTIMPL; };
  491. public:
  492. // Property Page Clipboard formats
  493. static CLIPFORMAT m_cfDsObjectNames;
  494. static HRESULT BuildPastedDataObject(
  495. IN CObjectNamesFormatCracker* pObjectNamesFormatPaste,
  496. IN CMultiselectMoveHandler* pMoveHandler,
  497. IN CDSComponentData* pCD,
  498. OUT IDataObject** ppSuccesfullyPastedDataObject);
  499. protected:
  500. // initialization
  501. HRESULT Init(IN CObjectNamesFormatCracker* pObjectNamesFormatPaste,
  502. IN CMultiselectMoveHandler* pMoveHandler,
  503. IN CDSComponentData* pCD);
  504. // Implementation
  505. private:
  506. void _Clear()
  507. {
  508. if (m_pDSObjCached != NULL)
  509. {
  510. ::free(m_pDSObjCached);
  511. m_pDSObjCached = NULL;
  512. m_nDSObjCachedBytes = 0;
  513. }
  514. }
  515. // chunk of memory with the clpboard format already computed
  516. LPDSOBJECTNAMES m_pDSObjCached;
  517. DWORD m_nDSObjCachedBytes;
  518. };
  519. ////////////////////////////////////////////////////////////////////////
  520. void EscapeFilterElement(PCWSTR pszElement, CString& refszEscapedElement);
  521. #endif // __DSUTIL_H_