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.

2379 lines
72 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1996 - 1999
  6. //
  7. // File: acelist.cpp
  8. //
  9. // This file contains the implementation for the advanced ACE list editor
  10. // permission and auditing pages.
  11. //
  12. //--------------------------------------------------------------------------
  13. #include "aclpriv.h"
  14. #include <accctrl.h>
  15. //Functions selects an Item in ListView. It first
  16. //Clears all exisiting selections
  17. VOID
  18. SelectSingleItemInLV( HWND hListView, INT iSelected )
  19. {
  20. INT cCount = ListView_GetItemCount( hListView );
  21. for( INT i = 0; i < cCount; ++i )
  22. ListView_SetItemState( hListView,
  23. i,
  24. 0,
  25. LVIS_SELECTED | LVIS_FOCUSED );
  26. //Now select the iSelected
  27. ListView_SetItemState( hListView,
  28. iSelected,
  29. LVIS_SELECTED | LVIS_FOCUSED,
  30. LVIS_SELECTED | LVIS_FOCUSED );
  31. return;
  32. }
  33. //This function checks if any of the aces selected in the listbox
  34. //is of type
  35. //type = fAppliedDirect ? Applied Directly on this object :
  36. // Inhereted from parent
  37. BOOL AnySelectedAceofType( HWND hListView, BOOL fAppliedDirect )
  38. {
  39. LVITEM lvi = {0};
  40. UINT cSelectedCount = 0; //Number of item selected in listbox
  41. lvi.iItem = -1;
  42. lvi.mask = LVIF_PARAM;
  43. lvi.iSubItem = 0;
  44. cSelectedCount = ListView_GetSelectedCount(hListView);
  45. while( cSelectedCount-- )
  46. {
  47. lvi.iItem = ListView_GetNextItem(hListView, lvi.iItem, LVNI_SELECTED);
  48. if (lvi.iItem != -1)
  49. {
  50. lvi.lParam = NULL;
  51. ListView_GetItem(hListView, &lvi);
  52. if( fAppliedDirect && ( (((PACE)lvi.lParam)->AceFlags & INHERITED_ACE) == 0 ) )
  53. return TRUE;
  54. if( !fAppliedDirect && ((PACE)lvi.lParam)->AceFlags & INHERITED_ACE )
  55. return TRUE;
  56. }
  57. }
  58. return FALSE;
  59. }
  60. LPARAM
  61. GetSelectedItemData(HWND hListView, int *pIndex)
  62. {
  63. int iSelected = ListView_GetNextItem(hListView, -1, LVNI_SELECTED);
  64. if (pIndex)
  65. *pIndex = iSelected;
  66. if (iSelected == -1)
  67. return NULL;
  68. LV_ITEM lvi;
  69. lvi.mask = LVIF_PARAM;
  70. lvi.iItem = iSelected;
  71. lvi.iSubItem = 0;
  72. lvi.lParam = NULL;
  73. ListView_GetItem(hListView, &lvi);
  74. return lvi.lParam;
  75. }
  76. void
  77. SelectListViewItem(HWND hListView, int iSelected)
  78. {
  79. ListView_SetItemState(hListView,
  80. iSelected,
  81. LVIS_SELECTED | LVIS_FOCUSED,
  82. LVIS_SELECTED | LVIS_FOCUSED);
  83. ListView_EnsureVisible(hListView, iSelected, FALSE);
  84. }
  85. void
  86. EnsureListViewSelectionIsVisible(HWND hListView)
  87. {
  88. int iSelected = ListView_GetNextItem(hListView, -1, LVNI_SELECTED);
  89. if (-1 != iSelected)
  90. ListView_EnsureVisible(hListView, iSelected, FALSE);
  91. }
  92. INT_PTR
  93. _ConfirmAclProtectProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  94. {
  95. switch (uMsg)
  96. {
  97. case WM_INITDIALOG:
  98. Static_SetIcon(GetDlgItem(hDlg, IDC_CONFIRM_ICON), LoadIcon(NULL, IDI_QUESTION));
  99. return TRUE;
  100. case WM_COMMAND:
  101. if (BN_CLICKED == GET_WM_COMMAND_CMD(wParam, lParam))
  102. {
  103. EndDialog(hDlg, GET_WM_COMMAND_ID(wParam, lParam));
  104. return TRUE;
  105. }
  106. break;
  107. }
  108. return FALSE;
  109. }
  110. int
  111. ConfirmAclProtect(HWND hwndParent, BOOL bDacl)
  112. {
  113. return (int)DialogBox(::hModule,
  114. MAKEINTRESOURCE(bDacl ? IDD_CONFIRM_DACL_PROTECT : IDD_CONFIRM_SACL_PROTECT),
  115. hwndParent,
  116. _ConfirmAclProtectProc);
  117. }
  118. //
  119. // Context Help IDs.
  120. //
  121. const static DWORD aAceListPermHelpIDs[] =
  122. {
  123. IDC_ACEL_DETAILS, IDH_ACEL_PERM_DETAILS,
  124. IDC_ACEL_ADD, IDH_ACEL_PERM_ADD,
  125. IDC_ACEL_REMOVE, IDH_ACEL_PERM_REMOVE,
  126. IDC_ACEL_EDIT, IDH_ACEL_PERM_EDIT,
  127. IDC_ACEL_RESET, IDH_ACEL_PERM_RESET,
  128. IDC_ACEL_DEFAULT_STATIC, IDH_ACEL_PERM_RESET,
  129. IDC_ACEL_PROTECT, IDH_ACEL_PERM_PROTECT,
  130. IDC_ACEL_DESCRIPTION, IDH_NOHELP,
  131. IDC_ACEL_RESET_ACL_TREE, IDH_ACEL_PERM_RESET_ACL_TREE,
  132. IDC_ACEL_STATIC, -1,
  133. 0, 0
  134. };
  135. const static DWORD aAceListAuditHelpIDs[] =
  136. {
  137. IDC_ACEL_DETAILS, IDH_ACEL_AUDIT_DETAILS,
  138. IDC_ACEL_ADD, IDH_ACEL_AUDIT_ADD,
  139. IDC_ACEL_REMOVE, IDH_ACEL_AUDIT_REMOVE,
  140. IDC_ACEL_EDIT, IDH_ACEL_AUDIT_EDIT,
  141. IDC_ACEL_RESET, IDH_ACEL_AUDIT_RESET,
  142. IDC_ACEL_DEFAULT_STATIC, IDH_ACEL_AUDIT_RESET,
  143. IDC_ACEL_PROTECT, IDH_ACEL_AUDIT_PROTECT,
  144. IDC_ACEL_DESCRIPTION, IDH_NOHELP,
  145. IDC_ACEL_RESET_ACL_TREE, IDH_ACEL_AUDIT_RESET_ACL_TREE,
  146. IDC_ACEL_STATIC, -1,
  147. 0, 0
  148. };
  149. class CAdvancedListPage : public CSecurityPage
  150. {
  151. private:
  152. PSI_ACCESS m_pAccess;
  153. ULONG m_cAccesses;
  154. PSI_INHERIT_TYPE m_pInheritType;
  155. ULONG m_cInheritTypes;
  156. int m_iLastColumnClick;
  157. int m_iSortDirection;
  158. BOOL m_fPageDirty:1;
  159. BOOL m_bReadOnly:1;
  160. BOOL m_bAuditPolicyOK:1;
  161. BOOL m_bWasDenyAcl:1;
  162. DWORD m_cInheritableAces;
  163. public:
  164. CAdvancedListPage( LPSECURITYINFO psi, SI_PAGE_TYPE siType )
  165. : CSecurityPage(psi, siType),
  166. m_iLastColumnClick(-1),
  167. m_iSortDirection(1),
  168. m_cInheritableAces(0){}
  169. private:
  170. virtual BOOL DlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
  171. PACL GetACL(PSECURITY_DESCRIPTOR *ppSD, LPBOOL pbProtected, BOOL bDefault);
  172. void FillAceList(HWND hListView, PACL pAcl, BOOL bSortList = TRUE);
  173. void InitDlg( HWND hDlg );
  174. int AddAce(HWND hListView, PACE_HEADER pAceHeader, int iRow, LPCTSTR pszInheritSource, int level);
  175. int AddAce(HWND hListView, PACE pAce, int iRow, LPCTSTR pszInheritSource, int level);
  176. LPCTSTR TranslateAceIntoRights(DWORD dwAceFlags,
  177. DWORD dwMask,
  178. const GUID *pObjectType,
  179. const GUID *pInheritedObjectType,
  180. LPCTSTR *ppszInheritType);
  181. LPCTSTR GetItemString(LPCTSTR pszItem, LPTSTR pszBuffer, UINT ccBuffer);
  182. void UpdateButtons(HWND hDlg);
  183. //NTRAID#NTBUG9-555470-2002/03/29-hiteshr
  184. HRESULT BuildAcl(HWND hListView,
  185. PACL *ppAcl);
  186. HRESULT ApplyAudits(HWND hDlg, HWND hListView, BOOL fProtected);
  187. HRESULT ApplyPermissions(HWND hDlg, HWND hListView, BOOL fProtected);
  188. void OnApply(HWND hDlg, BOOL bClose);
  189. void OnAdd(HWND hDlg);
  190. void OnRemove(HWND hDlg);
  191. void OnReset(HWND hDlg);
  192. void OnProtect(HWND hDlg);
  193. void OnEdit(HWND hDlg);
  194. int AddAcesFromDPA(HWND hListView, HDPA hEntries, int iSelected);
  195. void EditAce(HWND hDlg, PACE pAce, BOOL bDeleteSelection, LONG iSelected = MAXLONG);
  196. void CheckAuditPolicy(HWND hwndOwner);
  197. };
  198. typedef CAdvancedListPage *PADVANCEDLISTPAGE;
  199. int CALLBACK
  200. AceListCompareProc(LPARAM lParam1,
  201. LPARAM lParam2,
  202. LPARAM lParamSort)
  203. {
  204. int iResult = 0;
  205. PACE pAce1 = (PACE)lParam1;
  206. PACE pAce2 = (PACE)lParam2;
  207. short iColumn = LOWORD(lParamSort);
  208. short iSortDirection = HIWORD(lParamSort);
  209. LPTSTR psz1 = NULL;
  210. LPTSTR psz2 = NULL;
  211. TraceEnter(TRACE_ACELIST, "AceListCompareProc");
  212. if (iSortDirection == 0)
  213. iSortDirection = 1;
  214. if (pAce1 && pAce2)
  215. {
  216. switch (iColumn)
  217. {
  218. case 0:
  219. psz1 = pAce1->GetType();
  220. psz2 = pAce2->GetType();
  221. break;
  222. case 1:
  223. psz1 = pAce1->GetName();
  224. psz2 = pAce2->GetName();
  225. break;
  226. case 2:
  227. psz1 = pAce1->GetAccessType();
  228. psz2 = pAce2->GetAccessType();
  229. break;
  230. case 3:
  231. psz1 = pAce1->GetInheritSourceName();
  232. psz2 = pAce2->GetInheritSourceName();
  233. break;
  234. case 4:
  235. psz1 = pAce1->GetInheritType();
  236. psz2 = pAce2->GetInheritType();
  237. break;
  238. }
  239. if (iResult == 0 && psz1 && psz2)
  240. {
  241. iResult = CompareString(LOCALE_USER_DEFAULT, 0, psz1, -1, psz2, -1) - 2;
  242. }
  243. iResult *= iSortDirection;
  244. }
  245. TraceLeaveValue(iResult);
  246. }
  247. //
  248. //This function is used for cannonical sorting of the list
  249. //
  250. int CALLBACK
  251. AceListCompareProcCanno(LPARAM lParam1,
  252. LPARAM lParam2,
  253. LPARAM lParamSort)
  254. {
  255. int iResult = 0;
  256. PACE pAce1 = (PACE)lParam1;
  257. PACE pAce2 = (PACE)lParam2;
  258. short iColumn = LOWORD(lParamSort);
  259. short iSortDirection = HIWORD(lParamSort);
  260. LPTSTR psz1 = NULL;
  261. LPTSTR psz2 = NULL;
  262. TraceEnter(TRACE_ACELIST, "AceListCompareProc");
  263. if (iSortDirection == 0)
  264. iSortDirection = 1;
  265. if (pAce1 && pAce2)
  266. {
  267. switch (iColumn)
  268. {
  269. case 0:
  270. iResult = pAce1->CompareType(pAce2);
  271. // Fall through and use the name to differentiate ACEs of the same type
  272. case 1:
  273. psz1 = pAce1->GetName();
  274. psz2 = pAce2->GetName();
  275. break;
  276. }
  277. if (iResult == 0 && psz1 && psz2)
  278. {
  279. iResult = CompareString(LOCALE_USER_DEFAULT, 0, psz1, -1, psz2, -1) - 2;
  280. }
  281. iResult *= iSortDirection;
  282. }
  283. TraceLeaveValue(iResult);
  284. }
  285. //
  286. // CAdvancedListPage implementation
  287. //
  288. LPCTSTR
  289. CAdvancedListPage::TranslateAceIntoRights(DWORD dwAceFlags,
  290. DWORD dwMask,
  291. const GUID *pObjectType,
  292. const GUID *pInheritedObjectType,
  293. LPCTSTR *ppszInheritType)
  294. {
  295. LPCTSTR pszName = NULL;
  296. PSI_ACCESS pAccess = m_pAccess;
  297. ULONG cAccess = m_cAccesses;
  298. UINT iItem;
  299. TraceEnter(TRACE_ACELIST, "CAdvancedListPage::TranslateAceIntoRights");
  300. TraceAssert(pObjectType != NULL);
  301. TraceAssert(pInheritedObjectType != NULL);
  302. TraceAssert(!m_bAbortPage);
  303. // If this ACE applies to a different object type, ask the client
  304. // for the appropriate SI_ACCESS list.
  305. if ((m_siObjectInfo.dwFlags & SI_OBJECT_GUID)
  306. && !IsNullGUID(pInheritedObjectType)
  307. && !IsSameGUID(pInheritedObjectType, &m_siObjectInfo.guidObjectType))
  308. {
  309. ULONG iDefaultAccess;
  310. DWORD dwFlags = SI_ADVANCED;
  311. if (m_siPageType == SI_PAGE_AUDIT)
  312. dwFlags |= SI_EDIT_AUDITS;
  313. if (FAILED(m_psi->GetAccessRights(pInheritedObjectType,
  314. dwFlags,
  315. &pAccess,
  316. &cAccess,
  317. &iDefaultAccess)))
  318. {
  319. pAccess = m_pAccess;
  320. cAccess = m_cAccesses;
  321. }
  322. }
  323. if (pAccess && cAccess)
  324. {
  325. // Look for a name for the mask
  326. for (iItem = 0; iItem < cAccess; iItem++)
  327. {
  328. if ( dwMask == pAccess[iItem].mask &&
  329. IsSameGUID(pObjectType, pAccess[iItem].pguid) )
  330. {
  331. pszName = pAccess[iItem].pszName;
  332. break;
  333. }
  334. }
  335. }
  336. // Look for a name for the inheritance type
  337. if ((m_siObjectInfo.dwFlags & SI_CONTAINER) && ppszInheritType)
  338. {
  339. // Check these inherit bits for a match
  340. DWORD dwInheritMask = INHERIT_ONLY_ACE | ACE_INHERIT_ALL;
  341. // Don't check INHERIT_ONLY_ACE if the ACE inherit type
  342. // matches the current object
  343. if ((m_siObjectInfo.dwFlags & SI_OBJECT_GUID) &&
  344. IsSameGUID(&m_siObjectInfo.guidObjectType, pInheritedObjectType))
  345. {
  346. dwInheritMask &= ~INHERIT_ONLY_ACE;
  347. }
  348. *ppszInheritType = NULL;
  349. for (iItem = 0; iItem < m_cInheritTypes; iItem++)
  350. {
  351. if ((m_pInheritType[iItem].dwFlags & dwInheritMask) == (ULONG)(dwAceFlags & dwInheritMask)
  352. && IsSameGUID(pInheritedObjectType, m_pInheritType[iItem].pguid))
  353. {
  354. *ppszInheritType = m_pInheritType[iItem].pszName;
  355. break;
  356. }
  357. }
  358. }
  359. TraceLeaveValue(pszName);
  360. }
  361. LPCTSTR
  362. CAdvancedListPage::GetItemString(LPCTSTR pszItem,
  363. LPTSTR pszBuffer,
  364. UINT ccBuffer)
  365. {
  366. TraceEnter(TRACE_ACELIST, "CAdvancedListPage::GetItemString");
  367. if (pszItem == NULL)
  368. {
  369. LoadString(::hModule, IDS_SPECIAL, pszBuffer, ccBuffer);
  370. pszItem = pszBuffer;
  371. }
  372. else if (IS_INTRESOURCE(pszItem))
  373. {
  374. if (LoadString(m_siObjectInfo.hInstance,
  375. (UINT)((ULONG_PTR)pszItem),
  376. pszBuffer,
  377. ccBuffer) == 0)
  378. {
  379. LoadString(::hModule, IDS_SPECIAL, pszBuffer, ccBuffer);
  380. }
  381. pszItem = pszBuffer;
  382. }
  383. TraceLeaveValue(pszItem);
  384. }
  385. int
  386. CAdvancedListPage::AddAce(HWND hListView,
  387. PACE_HEADER pAceHeader,
  388. int iRow,
  389. LPCTSTR pszInheritSource,
  390. int level)
  391. {
  392. PACE pAce = new CAce(pAceHeader);
  393. if (pAce)
  394. {
  395. iRow = AddAce(hListView, pAce, iRow,pszInheritSource, level);
  396. }
  397. return iRow;
  398. }
  399. int
  400. CAdvancedListPage::AddAce(HWND hListView, PACE pAceNew, int iRow,LPCTSTR pszInheritSource, int level)
  401. {
  402. PACE pAceCompare;
  403. TCHAR szBuffer[MAX_COLUMN_CHARS];
  404. LPCTSTR pszInheritType;
  405. LPCTSTR pszRights;
  406. LV_ITEM lvi;
  407. UINT id = IDS_UNKNOWN;
  408. int iItem;
  409. int cItems;
  410. TraceEnter(TRACE_ACELIST, "CAdvancedListPage::AddAce");
  411. TraceAssert(hListView != NULL);
  412. TraceAssert(!m_bAbortPage);
  413. if (pAceNew == NULL)
  414. TraceLeaveValue(-1);
  415. pAceNew->SetInheritSourceInfo(pszInheritSource, level);
  416. m_psi->MapGeneric(&pAceNew->ObjectType, &pAceNew->AceFlags, &pAceNew->Mask);
  417. //
  418. // Try to merge the new ACE with an existing entry in the list.
  419. //
  420. cItems = ListView_GetItemCount(hListView);
  421. lvi.iSubItem = 0;
  422. lvi.mask = LVIF_PARAM;
  423. while (cItems > 0)
  424. {
  425. --cItems;
  426. lvi.iItem = cItems;
  427. ListView_GetItem(hListView, &lvi);
  428. pAceCompare = (PACE)lvi.lParam;
  429. if (pAceCompare != NULL)
  430. {
  431. switch (pAceNew->Merge(pAceCompare))
  432. {
  433. case MERGE_MODIFIED_FLAGS:
  434. case MERGE_MODIFIED_MASK:
  435. // The ACEs were merged into pAceNew.
  436. case MERGE_OK_1:
  437. //
  438. // The new ACE implies the existing ACE, so the existing
  439. // ACE can be removed.
  440. //
  441. // First copy the name so we don't have to look
  442. // it up again. (Don't copy the other strings
  443. // since they may be different.)
  444. //
  445. // Then keep looking. Maybe we can remove some more entries
  446. // before adding the new one.
  447. //
  448. if (pAceNew->GetName() == NULL)
  449. pAceNew->SetName(pAceCompare->GetName());
  450. ListView_DeleteItem(hListView, cItems);
  451. iRow = cItems; // try to insert here
  452. break;
  453. case MERGE_OK_2:
  454. //
  455. // The existing ACE implies the new ACE, so we don't
  456. // need to do anything here.
  457. //
  458. delete pAceNew;
  459. TraceLeaveValue(cItems);
  460. break;
  461. }
  462. }
  463. }
  464. //
  465. // Make sure we have a name for the SID.
  466. //
  467. pAceNew->LookupName(m_siObjectInfo.pszServerName, m_psi2);
  468. //
  469. // Get the Access Type and Inherit Type strings
  470. //
  471. pszRights = TranslateAceIntoRights(pAceNew->AceFlags,
  472. pAceNew->Mask,
  473. &pAceNew->ObjectType,
  474. &pAceNew->InheritedObjectType,
  475. &pszInheritType);
  476. //
  477. // If this is a property ACE, give it a name like "Read property" or
  478. // "Write property". Also, remember that it's a property ACE so we
  479. // can show the Property page first when editing this ACE.
  480. //
  481. // This is a bit slimy, since it assumes DS property access bits are
  482. // the only ones that will ever be used on the properties page.
  483. //
  484. if ((m_siObjectInfo.dwFlags & SI_EDIT_PROPERTIES) &&
  485. (pAceNew->Flags & ACE_OBJECT_TYPE_PRESENT) &&
  486. (pAceNew->Mask & (ACTRL_DS_READ_PROP | ACTRL_DS_WRITE_PROP)) &&
  487. !(pAceNew->Mask & ~(ACTRL_DS_READ_PROP | ACTRL_DS_WRITE_PROP)))
  488. {
  489. pAceNew->SetPropertyAce(TRUE);
  490. if (pszRights == NULL)
  491. {
  492. UINT idString = 0;
  493. switch (pAceNew->Mask & (ACTRL_DS_READ_PROP | ACTRL_DS_WRITE_PROP))
  494. {
  495. case ACTRL_DS_READ_PROP:
  496. idString = IDS_READ_PROP;
  497. break;
  498. case ACTRL_DS_WRITE_PROP:
  499. idString = IDS_WRITE_PROP;
  500. break;
  501. case (ACTRL_DS_READ_PROP | ACTRL_DS_WRITE_PROP):
  502. idString = IDS_READ_WRITE_PROP;
  503. break;
  504. }
  505. if (idString)
  506. {
  507. LoadString(::hModule, idString, szBuffer, ARRAYSIZE(szBuffer));
  508. pszRights = szBuffer;
  509. }
  510. }
  511. }
  512. pszRights = GetItemString(pszRights, szBuffer, ARRAYSIZE(szBuffer));
  513. pAceNew->SetAccessType(pszRights);
  514. if (m_siObjectInfo.dwFlags & SI_CONTAINER)
  515. {
  516. pszInheritType = GetItemString(pszInheritType,
  517. szBuffer,
  518. ARRAYSIZE(szBuffer));
  519. pAceNew->SetInheritType(pszInheritType);
  520. }
  521. lvi.mask = LVIF_TEXT | LVIF_PARAM | LVIF_STATE;
  522. lvi.state = 0;
  523. lvi.stateMask = LVIS_CUT;
  524. lvi.iItem = iRow;
  525. lvi.iSubItem = 0;
  526. lvi.pszText = LPSTR_TEXTCALLBACK;
  527. lvi.lParam = (LPARAM)pAceNew;
  528. if (pAceNew->AceFlags & INHERITED_ACE)
  529. {
  530. #ifdef USE_OVERLAY_IMAGE
  531. lvi.state = LVIS_CUT | INDEXTOOVERLAYMASK(1);
  532. #else
  533. lvi.state = LVIS_CUT;
  534. #endif
  535. }
  536. //
  537. // Get the string ID for the Type column
  538. //
  539. if (m_siPageType == SI_PAGE_ADVPERM)
  540. {
  541. switch(pAceNew->AceType)
  542. {
  543. case ACCESS_ALLOWED_ACE_TYPE:
  544. case ACCESS_ALLOWED_OBJECT_ACE_TYPE:
  545. id = IDS_ALLOW;
  546. break;
  547. case ACCESS_DENIED_ACE_TYPE:
  548. case ACCESS_DENIED_OBJECT_ACE_TYPE:
  549. id = IDS_DENY;
  550. break;
  551. case SYSTEM_AUDIT_ACE_TYPE:
  552. case SYSTEM_AUDIT_OBJECT_ACE_TYPE:
  553. id = IDS_AUDIT;
  554. break;
  555. case SYSTEM_ALARM_ACE_TYPE:
  556. case SYSTEM_ALARM_OBJECT_ACE_TYPE:
  557. id = IDS_ALARM;
  558. break;
  559. }
  560. }
  561. else
  562. {
  563. switch(pAceNew->AceFlags & (SUCCESSFUL_ACCESS_ACE_FLAG|FAILED_ACCESS_ACE_FLAG))
  564. {
  565. case SUCCESSFUL_ACCESS_ACE_FLAG:
  566. id = IDS_AUDITPASS;
  567. break;
  568. case FAILED_ACCESS_ACE_FLAG:
  569. id = IDS_AUDITFAIL;
  570. break;
  571. case SUCCESSFUL_ACCESS_ACE_FLAG | FAILED_ACCESS_ACE_FLAG:
  572. id = IDS_AUDITBOTH;
  573. break;
  574. }
  575. }
  576. // Load the Type string
  577. LoadString(::hModule, id, szBuffer, ARRAYSIZE(szBuffer));
  578. pAceNew->SetType(szBuffer);
  579. //
  580. // Finally, insert the item into the list
  581. //
  582. iItem = ListView_InsertItem(hListView, &lvi);
  583. if (iItem == -1)
  584. delete pAceNew;
  585. TraceLeaveValue(iItem);
  586. }
  587. void
  588. CAdvancedListPage::UpdateButtons( HWND hDlg )
  589. {
  590. HWND hListView;
  591. BOOL fEnableButtons = FALSE;
  592. LVITEM lvi = {0};
  593. UINT cSelectedCount = 0; //Number of item selected in listbox
  594. TraceEnter(TRACE_ACELIST, "CAdvancedListPage::UpdateButtons");
  595. hListView = GetDlgItem(hDlg, IDC_ACEL_DETAILS);
  596. cSelectedCount = ListView_GetSelectedCount(hListView);
  597. if (!m_bAbortPage)
  598. {
  599. //If SelectedCount > 1, disable View\Edit button
  600. if( cSelectedCount <= 1 )
  601. {
  602. lvi.iItem = ListView_GetNextItem(hListView, -1, LVNI_SELECTED);
  603. // Decide whether or not to enable edit button and decide what description
  604. // to display for the ACE
  605. if (lvi.iItem != -1)
  606. fEnableButtons = TRUE;
  607. }
  608. HWND hwndEdit = GetDlgItem(hDlg, IDC_ACEL_EDIT);
  609. // If we're disabling the edit button, make sure it doesn't have
  610. // focus or keyboard access gets hosed.
  611. if (!fEnableButtons && GetFocus() == hwndEdit)
  612. SetFocus(hListView);
  613. EnableWindow(hwndEdit, fEnableButtons);
  614. }
  615. if (m_bReadOnly)
  616. {
  617. const int idDisable[] =
  618. {
  619. IDC_ACEL_ADD,
  620. IDC_ACEL_REMOVE,
  621. IDC_ACEL_RESET,
  622. IDC_ACEL_PROTECT,
  623. IDC_ACEL_RESET_ACL_TREE,
  624. };
  625. for (int i = 0; i < ARRAYSIZE(idDisable); i++)
  626. EnableWindow(GetDlgItem(hDlg, idDisable[i]), FALSE);
  627. }
  628. else
  629. {
  630. // The Remove button is enabled if any selected ace is direct
  631. if ( AnySelectedAceofType( hListView, TRUE ) )
  632. fEnableButtons = TRUE;
  633. else
  634. fEnableButtons = FALSE;
  635. HWND hwndRemove = GetDlgItem(hDlg, IDC_ACEL_REMOVE);
  636. // If we're disabling the remove button, make sure it doesn't have
  637. // focus or keyboard access gets hosed.
  638. if (!fEnableButtons && GetFocus() == hwndRemove)
  639. SetFocus(hListView);
  640. EnableWindow(hwndRemove, fEnableButtons);
  641. }
  642. TraceLeaveVoid();
  643. }
  644. PACL
  645. CAdvancedListPage::GetACL(PSECURITY_DESCRIPTOR *ppSD, LPBOOL pbProtected, BOOL bDefault)
  646. {
  647. PACL pAcl = NULL;
  648. SECURITY_DESCRIPTOR_CONTROL sdControl = 0;
  649. DWORD dwRevision;
  650. BOOL bPresent;
  651. HRESULT hr;
  652. TraceEnter(TRACE_ACELIST, "CAdvancedListPage::GetACL");
  653. TraceAssert(ppSD != NULL);
  654. TraceAssert(pbProtected != NULL);
  655. TraceAssert(m_psi != NULL);
  656. TraceAssert(!m_bAbortPage);
  657. *pbProtected = FALSE;
  658. if (m_siPageType == SI_PAGE_ADVPERM)
  659. {
  660. hr = m_psi->GetSecurity(DACL_SECURITY_INFORMATION, ppSD, bDefault);
  661. if (SUCCEEDED(hr) && *ppSD != NULL)
  662. {
  663. GetSecurityDescriptorControl(*ppSD, &sdControl, &dwRevision);
  664. *pbProtected = ((sdControl & SE_DACL_PROTECTED) != 0);
  665. GetSecurityDescriptorDacl(*ppSD, &bPresent, &pAcl, &bDefault);
  666. }
  667. }
  668. else
  669. {
  670. DWORD dwPriv = SE_SECURITY_PRIVILEGE;
  671. HANDLE hToken = EnablePrivileges(&dwPriv, 1);
  672. hr = m_psi->GetSecurity(SACL_SECURITY_INFORMATION, ppSD, bDefault);
  673. ReleasePrivileges(hToken);
  674. if (SUCCEEDED(hr))
  675. {
  676. if (*ppSD != NULL)
  677. {
  678. GetSecurityDescriptorControl(*ppSD, &sdControl, &dwRevision);
  679. *pbProtected = ((sdControl & SE_SACL_PROTECTED) != 0);
  680. GetSecurityDescriptorSacl(*ppSD, &bPresent, &pAcl, &bDefault);
  681. }
  682. }
  683. else
  684. {
  685. // If we can't read the SACL, we can't write it either
  686. m_bReadOnly = TRUE;
  687. }
  688. }
  689. //Get the count of inheritable aces
  690. m_cInheritableAces = GetCountOfInheritableAces(pAcl);
  691. TraceLeaveValue(pAcl);
  692. }
  693. void
  694. CAdvancedListPage::FillAceList(HWND hListView, PACL pAcl, BOOL bSortList)
  695. {
  696. TraceEnter(TRACE_ACELIST, "CAdvancedListPage::FillAceList");
  697. TraceAssert(!m_bAbortPage);
  698. //
  699. // Enumerate the ACL into the ListView
  700. //
  701. // Turn off redraw and empty out the list
  702. SendMessage(hListView, WM_SETREDRAW, FALSE, 0);
  703. ListView_DeleteAllItems(hListView);
  704. if (pAcl)
  705. {
  706. PACE_HEADER pAceHeader;
  707. UINT AceCount;
  708. int iRow = 0;
  709. HRESULT hr = S_OK;
  710. SECURITY_INFORMATION si = (m_siPageType == SI_PAGE_ADVPERM) ? DACL_SECURITY_INFORMATION :SACL_SECURITY_INFORMATION;
  711. PINHERITED_FROM pInheritArray = NULL;
  712. if(m_psoti)
  713. {
  714. DWORD dwPriv = SE_SECURITY_PRIVILEGE;
  715. HANDLE hToken = EnablePrivileges(&dwPriv, 1);
  716. hr = m_psoti->GetInheritSource(si, pAcl, &pInheritArray);
  717. ReleasePrivileges(hToken);
  718. }
  719. //
  720. // Enumerate all of the ACEs, putting the data into the list view
  721. //
  722. ULONG i = 0;
  723. for (AceCount = pAcl->AceCount, pAceHeader = (PACE_HEADER)FirstAce(pAcl);
  724. AceCount > 0;
  725. AceCount--, pAceHeader = (PACE_HEADER)NextAce(pAceHeader), ++i)
  726. {
  727. iRow = AddAce(hListView,
  728. pAceHeader,
  729. iRow,
  730. pInheritArray? pInheritArray[i].AncestorName : NULL,
  731. pInheritArray? pInheritArray[i].GenerationGap :0
  732. ) + 1;
  733. }
  734. LocalFree(pInheritArray);
  735. }
  736. if (bSortList)
  737. {
  738. //
  739. // Sort the list,if no column is clicked so far,
  740. // sort in the cannonical order else in the last column clicked order
  741. //
  742. if(m_iLastColumnClick == -1)
  743. {
  744. ListView_SortItems(hListView,
  745. AceListCompareProcCanno,
  746. MAKELPARAM(0, 1));
  747. }
  748. else
  749. {
  750. ListView_SortItems(hListView,
  751. AceListCompareProc,
  752. MAKELPARAM(m_iLastColumnClick, m_iSortDirection));
  753. }
  754. }
  755. //
  756. // Now select the first item
  757. //
  758. SelectListViewItem(hListView, 0);
  759. // Redraw the list
  760. SendMessage(hListView, WM_SETREDRAW, TRUE, 0);
  761. ListView_RedrawItems(hListView, 0, -1);
  762. TraceLeaveVoid();
  763. }
  764. COL_FOR_LV perm_col_for_container[] =
  765. {
  766. IDS_ACE_PERM_COLUMN_TYPE, 10,
  767. IDS_ACE_PERM_COLUMN_NAME, 25,
  768. IDS_ACE_PERM_COLUMN_ACCESS, 20,
  769. IDS_ACE_PERM_COLUMN_PARENT, 20,
  770. IDS_ACE_PERM_COLUMN_INHERIT, 25,
  771. };
  772. COL_FOR_LV perm_col_for_noncontainer[] =
  773. {
  774. IDS_ACE_PERM_COLUMN_TYPE, 10,
  775. IDS_ACE_PERM_COLUMN_NAME, 35,
  776. IDS_ACE_PERM_COLUMN_ACCESS, 20,
  777. IDS_ACE_PERM_COLUMN_PARENT, 35,
  778. };
  779. COL_FOR_LV audit_col_for_container[] =
  780. {
  781. IDS_ACE_AUDIT_COLUMN_TYPE, 13,
  782. IDS_ACE_AUDIT_COLUMN_NAME, 25,
  783. IDS_ACE_AUDIT_COLUMN_ACCESS, 20,
  784. IDS_ACE_PERM_COLUMN_PARENT, 20,
  785. IDS_ACE_AUDIT_COLUMN_INHERIT, 25,
  786. };
  787. COL_FOR_LV audit_col_for_noncontainer[] =
  788. {
  789. IDS_ACE_AUDIT_COLUMN_TYPE, 10,
  790. IDS_ACE_AUDIT_COLUMN_NAME, 35,
  791. IDS_ACE_AUDIT_COLUMN_ACCESS, 20,
  792. IDS_ACE_PERM_COLUMN_PARENT, 35,
  793. };
  794. void
  795. CAdvancedListPage::InitDlg( HWND hDlg )
  796. {
  797. HWND hListView;
  798. RECT rc;
  799. TCHAR szBuffer[MAX_COLUMN_CHARS];
  800. LV_COLUMN col;
  801. UINT iTotal = 0;
  802. HCURSOR hcur = SetCursor(LoadCursor(NULL, IDC_WAIT));
  803. TraceEnter(TRACE_ACELIST, "CAdvancedListPage::InitDlg");
  804. // Hide the Reset button if it isn't supported.
  805. if (!(m_siObjectInfo.dwFlags & SI_RESET) &&
  806. !((m_siPageType == SI_PAGE_ADVPERM) && (m_siObjectInfo.dwFlags & SI_RESET_DACL)) &&
  807. !((m_siPageType == SI_PAGE_AUDIT) && (m_siObjectInfo.dwFlags & SI_RESET_SACL)) )
  808. {
  809. HWND hwnd = GetDlgItem(hDlg, IDC_ACEL_RESET);
  810. ShowWindow(hwnd, SW_HIDE);
  811. EnableWindow(hwnd, FALSE);
  812. hwnd = GetDlgItem(hDlg, IDC_ACEL_DEFAULT_STATIC);
  813. ShowWindow(hwnd, SW_HIDE);
  814. EnableWindow(hwnd, FALSE);
  815. }
  816. if (m_siObjectInfo.dwFlags & SI_NO_ACL_PROTECT)
  817. {
  818. // Hide the "Inherit permissions" box
  819. HWND hwnd = GetDlgItem(hDlg, IDC_ACEL_PROTECT);
  820. ShowWindow(hwnd, SW_HIDE);
  821. EnableWindow(hwnd, FALSE);
  822. }
  823. if (!(m_siObjectInfo.dwFlags & SI_CONTAINER) ||
  824. !(m_siObjectInfo.dwFlags & (m_siPageType == SI_PAGE_ADVPERM ? SI_RESET_DACL_TREE : SI_RESET_SACL_TREE)))
  825. {
  826. // Hide the "Reset ACL" box
  827. HWND hwnd = GetDlgItem(hDlg, IDC_ACEL_RESET_ACL_TREE);
  828. ShowWindow(hwnd, SW_HIDE);
  829. EnableWindow(hwnd, FALSE);
  830. }
  831. if (m_siPageType == SI_PAGE_ADVPERM)
  832. {
  833. m_bReadOnly = !!(m_siObjectInfo.dwFlags & SI_READONLY);
  834. }
  835. //If readonly, change edit button to view
  836. if(m_bReadOnly)
  837. {
  838. LoadString(::hModule, IDS_VIEW, szBuffer, ARRAYSIZE(szBuffer));
  839. SetDlgItemText(hDlg,IDC_ACEL_EDIT,szBuffer);
  840. LoadString(::hModule,
  841. (m_siPageType == SI_PAGE_ADVPERM)?IDS_ACL_EDIT_MORE_INFO:IDS_ACL_EDIT_MORE_INFO_1,
  842. szBuffer,
  843. ARRAYSIZE(szBuffer));
  844. SetDlgItemText(hDlg,IDC_ACEL_STATIC,szBuffer);
  845. }
  846. hListView = GetDlgItem( hDlg, IDC_ACEL_DETAILS );
  847. if (m_bAbortPage)
  848. {
  849. //
  850. // Disable everything
  851. //
  852. m_bReadOnly = TRUE;
  853. EnableWindow(hListView, FALSE);
  854. EnableWindow(GetDlgItem(hDlg, IDC_ACEL_EDIT), FALSE);
  855. }
  856. else
  857. {
  858. //
  859. // Get the ACL
  860. //
  861. PSECURITY_DESCRIPTOR pSD = NULL;
  862. BOOL fProtected = FALSE;
  863. PACL pAcl = GetACL(&pSD, &fProtected, FALSE);
  864. if (m_siPageType == SI_PAGE_AUDIT)
  865. {
  866. if (pAcl && pAcl->AceCount)
  867. {
  868. // Audits are already in place, don't bother checking
  869. // whether auditing is enabled later.
  870. m_bAuditPolicyOK = TRUE;
  871. }
  872. //Check if any of the ace in SACL is Callback type
  873. //if yes hide all the controls and show the error
  874. //message.
  875. if(IsCallBackAcePresentInAcl(pAcl))
  876. {
  877. HWND hwnd;
  878. for (hwnd = GetWindow(hDlg, GW_CHILD);
  879. hwnd != NULL;
  880. hwnd = GetWindow(hwnd, GW_HWNDNEXT))
  881. {
  882. ShowWindow(hwnd, SW_HIDE);
  883. EnableWindow(hwnd, FALSE);
  884. }
  885. // Enable and show the "No Security" message
  886. hwnd = GetDlgItem(hDlg, IDC_SPP_CALLBACK_PERMISSIONS);
  887. EnableWindow(hwnd, TRUE);
  888. ShowWindow(hwnd, SW_SHOW);
  889. if (pSD)
  890. LocalFree(pSD); // We're done with it, now free it
  891. return;
  892. }
  893. }
  894. else
  895. {
  896. DWORD dwFullControl = GENERIC_ALL;
  897. UCHAR aceFlags = 0;
  898. m_psi->MapGeneric(NULL, &aceFlags, &dwFullControl);
  899. if (IsDenyACL(pAcl,
  900. fProtected,
  901. dwFullControl,
  902. NULL))
  903. {
  904. // Already have Deny ACEs, don't bother warning again later.
  905. m_bWasDenyAcl = TRUE;
  906. }
  907. }
  908. //
  909. // Set up the listview control
  910. //
  911. // Set extended LV style for whole line selection with InfoTips
  912. ListView_SetExtendedListViewStyleEx(hListView,
  913. LVS_EX_FULLROWSELECT | LVS_EX_INFOTIP,
  914. LVS_EX_FULLROWSELECT | LVS_EX_INFOTIP);
  915. //
  916. // Add appropriate columns
  917. //
  918. GetClientRect(hListView, &rc);
  919. if (pAcl && pAcl->AceCount > 10)
  920. rc.right -= GetSystemMetrics(SM_CYHSCROLL); // Make room for scrollbar
  921. COL_FOR_LV *cfl;
  922. UINT iColCount;
  923. if (m_siObjectInfo.dwFlags & SI_CONTAINER)
  924. {
  925. // Get the inherit types for filling in the inherit column
  926. m_cInheritTypes = 0;
  927. m_pInheritType = NULL;
  928. m_psi->GetInheritTypes(&m_pInheritType, &m_cInheritTypes);
  929. cfl = perm_col_for_container;
  930. iColCount = ARRAYSIZE(perm_col_for_container);
  931. if (m_siPageType == SI_PAGE_AUDIT)
  932. {
  933. cfl = audit_col_for_container;
  934. iColCount = ARRAYSIZE(audit_col_for_container);
  935. }
  936. }
  937. else
  938. {
  939. // There is no inherit column for non-containers
  940. cfl = perm_col_for_noncontainer;
  941. iColCount = ARRAYSIZE(perm_col_for_noncontainer);
  942. if (m_siPageType == SI_PAGE_AUDIT)
  943. {
  944. cfl = audit_col_for_noncontainer;
  945. iColCount = ARRAYSIZE(audit_col_for_noncontainer);
  946. }
  947. }
  948. UINT iCol;
  949. iCol = 0;
  950. while (iCol < iColCount)
  951. {
  952. LoadString(::hModule, cfl[iCol].idText,
  953. szBuffer, ARRAYSIZE(szBuffer));
  954. col.mask = LVCF_FMT | LVCF_TEXT | LVCF_SUBITEM | LVCF_WIDTH;
  955. col.fmt = LVCFMT_LEFT;
  956. col.pszText = szBuffer;
  957. col.iSubItem = iCol;
  958. if (iCol == iColCount - 1)
  959. col.cx = rc.right - iTotal;
  960. else
  961. col.cx = (rc.right * cfl[iCol].iPercent) / 100;
  962. ListView_InsertColumn(hListView, iCol, &col);
  963. iTotal += col.cx;
  964. iCol++;
  965. }
  966. //
  967. // Get the access list for filling in the Rights column
  968. //
  969. ULONG iDefaultAccess;
  970. DWORD dwFlags = SI_ADVANCED;
  971. if (m_siPageType == SI_PAGE_AUDIT)
  972. dwFlags |= SI_EDIT_AUDITS;
  973. m_psi->GetAccessRights(NULL,
  974. dwFlags,
  975. &m_pAccess,
  976. &m_cAccesses,
  977. &iDefaultAccess);
  978. //
  979. // Enumerate the ACL into the ListView
  980. //
  981. FillAceList(hListView, pAcl, FALSE);
  982. // Set the protection checkbox
  983. CheckDlgButton(hDlg, IDC_ACEL_PROTECT, !fProtected);
  984. if (pSD)
  985. LocalFree(pSD); // We're done with it, now free it
  986. } // !m_bAbortPage
  987. // Update the other controls
  988. UpdateButtons(hDlg);
  989. SetCursor(hcur);
  990. TraceLeaveVoid();
  991. }
  992. //NTRAID#NTBUG9-555470-2002/03/29-hiteshr
  993. HRESULT
  994. CAdvancedListPage::BuildAcl(HWND hListView,
  995. PACL *ppAcl)
  996. {
  997. long cAces;
  998. long iEntry;
  999. long iLength = SIZEOF(ACL);
  1000. PACE pAce;
  1001. PACL pACL = NULL;
  1002. LV_ITEM lvi;
  1003. lvi.mask = LVIF_PARAM;
  1004. lvi.iSubItem = 0;
  1005. lvi.lParam = NULL;
  1006. TraceEnter(TRACE_ACELIST, "CAdvancedListPage::BuildAcl");
  1007. TraceAssert(hListView != NULL);
  1008. TraceAssert(ppAcl != NULL);
  1009. *ppAcl = NULL;
  1010. cAces = ListView_GetItemCount(hListView);
  1011. //
  1012. // Iterate through all of the ace's counting up size.
  1013. // If there are no ACEs, create an empty ACL.
  1014. //
  1015. for (iEntry = 0; iEntry < cAces; iEntry++)
  1016. {
  1017. lvi.iItem = iEntry;
  1018. ListView_GetItem(hListView, &lvi);
  1019. pAce = (PACE)lvi.lParam;
  1020. if (pAce)
  1021. {
  1022. if (!(pAce->AceFlags & INHERITED_ACE))
  1023. iLength += pAce->AceSize;
  1024. }
  1025. }
  1026. pACL = (PACL)LocalAlloc(LPTR, iLength);
  1027. if (pACL)
  1028. {
  1029. PACE_HEADER pAceDest;
  1030. InitializeAcl(pACL, iLength, ACL_REVISION);
  1031. for (iEntry = 0, pAceDest = (PACE_HEADER)FirstAce(pACL);
  1032. iEntry < cAces;
  1033. iEntry++)
  1034. {
  1035. lvi.iItem = iEntry;
  1036. ListView_GetItem(hListView, &lvi);
  1037. pAce = (PACE)lvi.lParam;
  1038. if (pAce)
  1039. {
  1040. if (!(pAce->AceFlags & INHERITED_ACE))
  1041. {
  1042. //Remveod the special casing for CREATOR_OWNER
  1043. //NTRAID#NTBUG9-467049-2001/11/29-hiteshr
  1044. pAce->CopyTo(pAceDest);
  1045. pACL->AceCount++;
  1046. pAceDest = (PACE_HEADER)NextAce(pAceDest);
  1047. // Is this an object ACE? If so, reset the ACL revision.
  1048. if (pAce->Flags != 0 && pACL->AclRevision < ACL_REVISION_DS)
  1049. pACL->AclRevision = ACL_REVISION_DS;
  1050. }
  1051. }
  1052. }
  1053. iLength = (ULONG)((PBYTE)pAceDest - (PBYTE)pACL);
  1054. TraceAssert(pACL->AclSize >= iLength);
  1055. if (pACL->AclSize > iLength)
  1056. pACL->AclSize = (WORD)iLength;
  1057. TraceAssert(IsValidAcl(pACL));
  1058. }
  1059. else
  1060. {
  1061. TraceLeaveResult(E_OUTOFMEMORY);
  1062. }
  1063. *ppAcl = pACL;
  1064. TraceLeaveResult(S_OK);
  1065. }
  1066. HRESULT
  1067. CAdvancedListPage::ApplyPermissions(HWND hDlg,
  1068. HWND hListView,
  1069. BOOL fProtected)
  1070. {
  1071. HRESULT hr = S_OK;
  1072. PACL pACL = NULL;
  1073. SECURITY_DESCRIPTOR sd;
  1074. SECURITY_INFORMATION si = DACL_SECURITY_INFORMATION;
  1075. BOOL bIsDenyAcl = FALSE;
  1076. TraceEnter(TRACE_ACELIST, "CAdvancedListPage::ApplyPermissions");
  1077. TraceAssert(hDlg != NULL);
  1078. TraceAssert(hListView != NULL);
  1079. TraceAssert(!m_bReadOnly);
  1080. TraceAssert(!m_bAbortPage);
  1081. if (IsDlgButtonChecked(hDlg, IDC_ACEL_RESET_ACL_TREE))
  1082. {
  1083. // Confirm this operation
  1084. if (IDNO == MsgPopup(hDlg,
  1085. MAKEINTRESOURCE(IDS_RESET_DACL_WARNING),
  1086. MAKEINTRESOURCE(IDS_SECURITY),
  1087. MB_YESNO | MB_ICONWARNING,
  1088. ::hModule,
  1089. m_siObjectInfo.pszObjectName))
  1090. {
  1091. // Return PSNRET_INVALID to abort the Apply and tell the sheet to
  1092. // select this page as the active page.
  1093. SetWindowLongPtr(hDlg, DWLP_MSGRESULT, PSNRET_INVALID);
  1094. ExitGracefully(hr, S_OK, "ApplyPermissions aborting");
  1095. }
  1096. si |= SI_RESET_DACL_TREE;
  1097. }
  1098. // Make sure the DACL is in canonical order. Note that OnApply
  1099. // will re-read the DACL and reinitialize the list with the
  1100. // current sort order.
  1101. ListView_SortItems(hListView,
  1102. AceListCompareProcCanno,
  1103. MAKELPARAM(0, 1));
  1104. // Build the new DACL
  1105. //NTRAID#NTBUG9-555470-2002/03/29-hiteshr
  1106. hr = BuildAcl(hListView, &pACL);
  1107. if(FAILED(hr))
  1108. TraceLeaveResult(hr);
  1109. // Check for Deny ACEs in the ACL
  1110. if (!m_bWasDenyAcl)
  1111. {
  1112. DWORD dwWarning = 0;
  1113. DWORD dwFullControl = GENERIC_ALL;
  1114. UCHAR aceFlags = 0;
  1115. m_psi->MapGeneric(NULL, &aceFlags, &dwFullControl);
  1116. bIsDenyAcl = IsDenyACL(pACL,
  1117. fProtected,
  1118. dwFullControl,
  1119. &dwWarning);
  1120. if (bIsDenyAcl)
  1121. {
  1122. TraceAssert(dwWarning != 0);
  1123. // Warn the user about Deny ACEs
  1124. if (IDNO == MsgPopup(hDlg,
  1125. MAKEINTRESOURCE(dwWarning),
  1126. MAKEINTRESOURCE(IDS_SECURITY),
  1127. MB_YESNO | MB_ICONWARNING,
  1128. ::hModule,
  1129. m_siObjectInfo.pszObjectName))
  1130. {
  1131. // Return PSNRET_INVALID to abort the Apply and tell the sheet to
  1132. // select this page as the active page.
  1133. SetWindowLongPtr(hDlg, DWLP_MSGRESULT, PSNRET_INVALID);
  1134. ExitGracefully(hr, S_OK, "ApplyPermissions aborting");
  1135. }
  1136. }
  1137. }
  1138. // Build the security descriptor
  1139. if(!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION))
  1140. {
  1141. DWORD dwErr = GetLastError();
  1142. ExitGracefully(hr, HRESULT_FROM_WIN32(dwErr),"InitializeSecurityDescriptor failed");
  1143. }
  1144. if(!SetSecurityDescriptorDacl(&sd, !!(pACL), pACL, FALSE))
  1145. {
  1146. DWORD dwErr = GetLastError();
  1147. ExitGracefully(hr, HRESULT_FROM_WIN32(dwErr),"SetSecurityDescriptorDacl failed");
  1148. }
  1149. sd.Control |= SE_DACL_AUTO_INHERIT_REQ;
  1150. if (fProtected)
  1151. sd.Control |= SE_DACL_PROTECTED;
  1152. if(IsAclBloated(hDlg, si, &sd, m_cInheritableAces,m_siObjectInfo.dwFlags & SI_EDIT_PROPERTIES))
  1153. {
  1154. SetWindowLongPtr(hDlg, DWLP_MSGRESULT, PSNRET_INVALID);
  1155. ExitGracefully(hr, S_FALSE, "ApplyPermissions aborting");
  1156. }
  1157. // Write out the new DACL
  1158. hr = m_psi->SetSecurity(si, &sd);
  1159. if (bIsDenyAcl && S_OK == hr)
  1160. m_bWasDenyAcl = TRUE;
  1161. exit_gracefully:
  1162. if (pACL)
  1163. LocalFree(pACL);
  1164. TraceLeaveResult(hr);
  1165. }
  1166. HRESULT
  1167. CAdvancedListPage::ApplyAudits(HWND hDlg,
  1168. HWND hListView,
  1169. BOOL fProtected)
  1170. {
  1171. HRESULT hr = S_OK;
  1172. PACL pACL = NULL;
  1173. SECURITY_DESCRIPTOR sd;
  1174. SECURITY_INFORMATION si = SACL_SECURITY_INFORMATION;
  1175. DWORD dwPriv = SE_SECURITY_PRIVILEGE;
  1176. HANDLE hToken = INVALID_HANDLE_VALUE;
  1177. TraceEnter(TRACE_ACELIST, "CAdvancedListPage::ApplyAudits");
  1178. TraceAssert(!m_bReadOnly);
  1179. TraceAssert(!m_bAbortPage);
  1180. if (IsDlgButtonChecked(hDlg, IDC_ACEL_RESET_ACL_TREE))
  1181. si |= SI_RESET_SACL_TREE;
  1182. // Build the SACL
  1183. //NTRAID#NTBUG9-555470-2002/03/29-hiteshr
  1184. hr = BuildAcl(hListView, &pACL);
  1185. if(FAILED(hr))
  1186. TraceLeaveResult(hr);
  1187. // Build the security descriptor
  1188. if(!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION))
  1189. {
  1190. DWORD dwErr = GetLastError();
  1191. ExitGracefully(hr, HRESULT_FROM_WIN32(dwErr),"InitializeSecurityDescriptor failed");
  1192. }
  1193. if(!SetSecurityDescriptorSacl(&sd, !!(pACL), pACL, FALSE))
  1194. {
  1195. DWORD dwErr = GetLastError();
  1196. ExitGracefully(hr, HRESULT_FROM_WIN32(dwErr),"SetSecurityDescriptorSacl failed");
  1197. }
  1198. sd.Control |= SE_SACL_AUTO_INHERIT_REQ;
  1199. if (fProtected)
  1200. sd.Control |= SE_SACL_PROTECTED;
  1201. // Enable the security privilege and write out the new SACL
  1202. hToken = EnablePrivileges(&dwPriv, 1);
  1203. if(IsAclBloated(hDlg, si, &sd, m_cInheritableAces,m_siObjectInfo.dwFlags & SI_EDIT_PROPERTIES))
  1204. {
  1205. SetWindowLongPtr(hDlg, DWLP_MSGRESULT, PSNRET_INVALID);
  1206. hr = S_FALSE;
  1207. }
  1208. else
  1209. hr = m_psi->SetSecurity(si, &sd);
  1210. ReleasePrivileges(hToken);
  1211. if (S_OK == hr)
  1212. CheckAuditPolicy(hDlg);
  1213. exit_gracefully:
  1214. if (pACL)
  1215. LocalFree(pACL);
  1216. TraceLeaveResult(hr);
  1217. }
  1218. void
  1219. CAdvancedListPage::OnApply(HWND hDlg, BOOL bClose)
  1220. {
  1221. HRESULT hr = S_OK;
  1222. HWND hListView;
  1223. BOOL fProtected;
  1224. if (!m_fPageDirty)
  1225. return;
  1226. TraceEnter(TRACE_ACELIST, "CAdvancedListPage::OnApply");
  1227. TraceAssert(hDlg != NULL);
  1228. TraceAssert(!m_bReadOnly);
  1229. TraceAssert(!m_bAbortPage);
  1230. hListView = GetDlgItem(hDlg, IDC_ACEL_DETAILS);
  1231. fProtected = !IsDlgButtonChecked(hDlg, IDC_ACEL_PROTECT);
  1232. if (m_siPageType == SI_PAGE_ADVPERM)
  1233. {
  1234. hr = ApplyPermissions(hDlg, hListView, fProtected);
  1235. }
  1236. else
  1237. {
  1238. hr = ApplyAudits(hDlg, hListView, fProtected);
  1239. }
  1240. if (FAILED(hr))
  1241. {
  1242. // Tell the user there was a problem. If they choose to cancel
  1243. // and the dialog is closing, do nothing (let the dialog close).
  1244. // Otherwise, tell the property sheet that we had a problem.
  1245. UINT nMsgID = IDS_PERM_WRITE_FAILED;
  1246. if (m_siPageType == SI_PAGE_AUDIT)
  1247. nMsgID = IDS_AUDIT_WRITE_FAILED;
  1248. if (IDCANCEL != SysMsgPopup(hDlg,
  1249. MAKEINTRESOURCE(nMsgID),
  1250. MAKEINTRESOURCE(IDS_SECURITY),
  1251. (bClose ? MB_RETRYCANCEL : MB_OK) | MB_ICONERROR,
  1252. ::hModule,
  1253. hr,
  1254. m_siObjectInfo.pszObjectName))
  1255. {
  1256. // Return PSNRET_INVALID to abort the Apply and cause the sheet to
  1257. // select this page as the active page.
  1258. SetWindowLongPtr(hDlg, DWLP_MSGRESULT, PSNRET_INVALID);
  1259. }
  1260. }
  1261. else if (S_FALSE == hr)
  1262. {
  1263. // S_FALSE is silent failure (the client should put up UI
  1264. // during SetSecurity before returning S_FALSE).
  1265. SetWindowLongPtr(hDlg, DWLP_MSGRESULT, PSNRET_INVALID);
  1266. }
  1267. else
  1268. {
  1269. m_fPageDirty = FALSE;
  1270. // If ApplyPermissions bailed due to user action ("No"),
  1271. // then the dialog won't be closing
  1272. if (PSNRET_INVALID == GetWindowLongPtr(hDlg, DWLP_MSGRESULT))
  1273. bClose = FALSE;
  1274. if (!bClose)
  1275. {
  1276. //
  1277. // Re-read the security descriptor and reinitialize the dialog
  1278. //
  1279. //Inform the Effective Permission tab that
  1280. //Permissions are changed
  1281. if(m_siPageType == SI_PAGE_ADVPERM)
  1282. PropSheet_QuerySiblings(GetParent(hDlg),0,0);
  1283. PSECURITY_DESCRIPTOR pSD = NULL;
  1284. BOOL fACLProtected = FALSE;
  1285. PACL pAcl = GetACL(&pSD, &fACLProtected, FALSE);
  1286. FillAceList(hListView, pAcl);
  1287. // Set the button states
  1288. CheckDlgButton(hDlg, IDC_ACEL_PROTECT, !fACLProtected);
  1289. CheckDlgButton(hDlg, IDC_ACEL_RESET_ACL_TREE, BST_UNCHECKED);
  1290. UpdateButtons(hDlg);
  1291. if (pSD)
  1292. LocalFree(pSD); // We're done with it, now free it
  1293. }
  1294. }
  1295. TraceLeaveVoid();
  1296. }
  1297. void
  1298. CAdvancedListPage::OnAdd(HWND hDlg)
  1299. {
  1300. PUSER_LIST pUserList = NULL;
  1301. TraceEnter(TRACE_ACELIST, "CAdvancedListPage::OnAdd");
  1302. TraceAssert(!m_bReadOnly);
  1303. if (S_OK == GetUserGroup(hDlg, FALSE, &pUserList))
  1304. {
  1305. // Build an empty ACE (mask = 0) using the SID we just
  1306. // got in pUserList.
  1307. CAce ace;
  1308. TraceAssert(NULL != pUserList);
  1309. TraceAssert(1 == pUserList->cUsers);
  1310. if (m_siPageType == SI_PAGE_AUDIT)
  1311. ace.AceType = SYSTEM_AUDIT_ACE_TYPE;
  1312. if (m_siObjectInfo.dwFlags & SI_CONTAINER)
  1313. ace.AceFlags = OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE;
  1314. ace.SetSid(pUserList->rgUsers[0].pSid,
  1315. pUserList->rgUsers[0].pszName,
  1316. pUserList->rgUsers[0].pszLogonName,
  1317. pUserList->rgUsers[0].SidType);
  1318. // Done with this now
  1319. LocalFree(pUserList);
  1320. // Edit the ACE
  1321. EditAce(hDlg, &ace, FALSE);
  1322. }
  1323. TraceLeaveVoid();
  1324. }
  1325. BOOL CanDeleteDirectAces( HWND hDlg )
  1326. {
  1327. TCHAR szBuffer[1024];
  1328. TCHAR szCaption[1024];
  1329. if( !LoadString( ::hModule, IDS_CONFIRM_MULTIPLE_DELETION, szBuffer, 1024 ) )
  1330. return FALSE;
  1331. if( !LoadString( ::hModule, IDS_SECURITY, szCaption, 1024 ) )
  1332. return FALSE;
  1333. return (IDYES == MessageBox( hDlg, szBuffer, szCaption, MB_YESNO | MB_ICONQUESTION | MB_APPLMODAL ));
  1334. }
  1335. void
  1336. CAdvancedListPage::OnRemove(HWND hDlg)
  1337. {
  1338. HWND hListView = GetDlgItem(hDlg, IDC_ACEL_DETAILS);
  1339. //if Any selected Ace is inherited from parent
  1340. //Ask user if to proceed with deletion of direct aces
  1341. if( AnySelectedAceofType(hListView, FALSE) && !CanDeleteDirectAces( hDlg ) )
  1342. return;
  1343. //Remember the positon of first selected permissons
  1344. //In end select the item at this position
  1345. int iFirstSelected = ListView_GetNextItem(hListView, -1, LVNI_SELECTED);
  1346. LVITEM lvi = {0};
  1347. lvi.iItem = iFirstSelected;
  1348. lvi.mask = LVIF_PARAM;
  1349. lvi.iSubItem = 0;
  1350. while( lvi.iItem != -1 )
  1351. {
  1352. lvi.lParam = NULL;
  1353. ListView_GetItem(hListView, &lvi);
  1354. if( (((PACE)lvi.lParam)->AceFlags & INHERITED_ACE) == 0 )
  1355. {
  1356. ListView_DeleteItem(hListView, lvi.iItem);
  1357. //Start from one item back as current item is deleted
  1358. --lvi.iItem;
  1359. }
  1360. lvi.iItem = ListView_GetNextItem(hListView, lvi.iItem, LVNI_SELECTED);
  1361. }
  1362. if (ListView_GetItemCount(hListView) <= iFirstSelected )
  1363. --iFirstSelected;
  1364. SelectListViewItem(hListView, iFirstSelected);
  1365. PropSheet_Changed(GetParent(hDlg),hDlg);
  1366. m_fPageDirty = TRUE;
  1367. }
  1368. void
  1369. CAdvancedListPage::OnReset(HWND hDlg)
  1370. {
  1371. //
  1372. // Get a default ACL and enumerate it into the ListView
  1373. //
  1374. PSECURITY_DESCRIPTOR pSD = NULL;
  1375. BOOL fProtected = FALSE;
  1376. FillAceList(GetDlgItem(hDlg, IDC_ACEL_DETAILS),
  1377. GetACL(&pSD, &fProtected, TRUE /*default*/));
  1378. // Set the button states
  1379. CheckDlgButton(hDlg, IDC_ACEL_PROTECT, !fProtected);
  1380. UpdateButtons(hDlg);
  1381. if (pSD)
  1382. LocalFree(pSD); // We're done with it, now free it
  1383. // Notify the property sheet that we've changed
  1384. PropSheet_Changed(GetParent(hDlg),hDlg);
  1385. m_fPageDirty = TRUE;
  1386. }
  1387. void
  1388. CAdvancedListPage::OnProtect(HWND hDlg)
  1389. {
  1390. // The "Inherit permissions" checkbox was clicked
  1391. if (!IsDlgButtonChecked(hDlg, IDC_ACEL_PROTECT))
  1392. {
  1393. BOOL bHaveInheritedAces = FALSE;
  1394. HWND hListView = GetDlgItem(hDlg, IDC_ACEL_DETAILS);
  1395. int cItems = ListView_GetItemCount(hListView);
  1396. int i;
  1397. PACE pAce;
  1398. LV_ITEM lvItem;
  1399. lvItem.iSubItem = 0;
  1400. lvItem.mask = LVIF_PARAM;
  1401. // Are there any inherited aces?
  1402. for (i = 0; i < cItems && !bHaveInheritedAces; i++)
  1403. {
  1404. lvItem.iItem = i;
  1405. ListView_GetItem(hListView, &lvItem);
  1406. pAce = (PACE)lvItem.lParam;
  1407. if (pAce)
  1408. bHaveInheritedAces = (pAce->AceFlags & INHERITED_ACE);
  1409. }
  1410. if (bHaveInheritedAces)
  1411. {
  1412. int nResult;
  1413. int iSelected;
  1414. // Turning protection on. Ask the user whether to convert
  1415. // inherited aces to non-inherited aces, or delete them.
  1416. nResult = ConfirmAclProtect(hDlg, m_siPageType == SI_PAGE_ADVPERM);
  1417. if (nResult == IDCANCEL)
  1418. {
  1419. // Reset the checkbox and bail
  1420. CheckDlgButton(hDlg, IDC_ACEL_PROTECT, BST_CHECKED);
  1421. return;
  1422. }
  1423. //
  1424. // Remember the current selection, if any.
  1425. //
  1426. iSelected = ListView_GetNextItem(hListView, -1, LVNI_SELECTED);
  1427. //
  1428. // Convert or delete inherited aces
  1429. //
  1430. while (cItems > 0)
  1431. {
  1432. --cItems;
  1433. lvItem.iItem = cItems;
  1434. //
  1435. // The AddAce call below merges entries, which
  1436. // can potentially remove entries from the list,
  1437. // so check the return value here. This also
  1438. // means we could see the same item more than
  1439. // once here, but after the first time it won't
  1440. // have the INHERITED_ACE flag set.
  1441. //
  1442. if (!ListView_GetItem(hListView, &lvItem))
  1443. continue;
  1444. pAce = (PACE)lvItem.lParam;
  1445. if (pAce && (pAce->AceFlags & INHERITED_ACE))
  1446. {
  1447. if (nResult == IDC_CONFIRM_REMOVE)
  1448. {
  1449. // Delete it
  1450. ListView_DeleteItem(hListView, cItems);
  1451. }
  1452. else
  1453. {
  1454. //
  1455. // Convert it to non-inherited. Do this
  1456. // by deleting and re-adding without
  1457. // INHERITED_ACE set. AddAce will try
  1458. // to merge into existing entries.
  1459. //
  1460. // Before deleting, be sure to set
  1461. // lParam to zero so pAce doesn't
  1462. // get freed.
  1463. //
  1464. pAce->AceFlags &= ~INHERITED_ACE;
  1465. lvItem.lParam = 0;
  1466. ListView_SetItem(hListView, &lvItem);
  1467. ListView_DeleteItem(hListView, cItems);
  1468. AddAce(hListView, pAce, cItems, NULL,0);
  1469. }
  1470. }
  1471. }
  1472. //
  1473. // Reset the selection
  1474. //
  1475. iSelected = min(ListView_GetItemCount(hListView)-1, iSelected);
  1476. SelectListViewItem(hListView, iSelected);
  1477. }
  1478. }
  1479. PropSheet_Changed(GetParent(hDlg), hDlg);
  1480. m_fPageDirty = TRUE;
  1481. }
  1482. void
  1483. CAdvancedListPage::OnEdit(HWND hDlg)
  1484. {
  1485. HWND hListView;
  1486. PACE pAce;
  1487. int iSelected;
  1488. TraceEnter(TRACE_ACELIST, "CAdvancedListPage::OnEdit");
  1489. TraceAssert(hDlg != NULL);
  1490. TraceAssert(!m_bAbortPage);
  1491. hListView = GetDlgItem(hDlg, IDC_ACEL_DETAILS);
  1492. pAce = (PACE)GetSelectedItemData(hListView, &iSelected);
  1493. if(iSelected != -1)
  1494. {
  1495. EditAce(hDlg, pAce, TRUE, iSelected);
  1496. }
  1497. TraceLeaveVoid();
  1498. }
  1499. int
  1500. CAdvancedListPage::AddAcesFromDPA(HWND hListView, HDPA hEntries, int iSelected)
  1501. {
  1502. UINT iItems = 0;
  1503. if (hEntries)
  1504. iItems = DPA_GetPtrCount(hEntries);
  1505. while (iItems)
  1506. {
  1507. --iItems;
  1508. iSelected = AddAce(hListView,
  1509. (PACE_HEADER)DPA_FastGetPtr(hEntries, iItems),
  1510. iSelected,
  1511. NULL,0) + 1;
  1512. }
  1513. return iSelected;
  1514. }
  1515. void
  1516. CAdvancedListPage::EditAce(HWND hDlg, PACE pAce, BOOL bDeleteSelection, LONG iSelected)
  1517. {
  1518. HWND hListView;
  1519. HDPA hEntries = NULL;
  1520. HDPA hPropertyEntries = NULL;
  1521. UINT iItems = 0;
  1522. UINT iPropertyItems = 0;
  1523. BOOL bUpdateList;
  1524. UINT nStartPage = 0;
  1525. DWORD dwResult = 0;
  1526. TraceEnter(TRACE_ACELIST, "CAdvancedListPage::EditAce");
  1527. TraceAssert(hDlg != NULL);
  1528. TraceAssert(!m_bAbortPage);
  1529. hListView = GetDlgItem(hDlg, IDC_ACEL_DETAILS);
  1530. if (pAce)
  1531. {
  1532. // If the ACE is inherited, don't delete it.
  1533. if (pAce->AceFlags & INHERITED_ACE)
  1534. bDeleteSelection = FALSE;
  1535. // If this is a property ACE, we want to show the property page first.
  1536. if (pAce->IsPropertyAce())
  1537. {
  1538. TraceAssert(m_siObjectInfo.dwFlags & SI_EDIT_PROPERTIES);
  1539. nStartPage = 1;
  1540. }
  1541. }
  1542. bUpdateList = EditACEEntry(hDlg,
  1543. m_psi,
  1544. pAce,
  1545. m_siPageType,
  1546. m_siObjectInfo.pszObjectName,
  1547. m_bReadOnly,
  1548. &dwResult,
  1549. &hEntries,
  1550. (m_siObjectInfo.dwFlags & SI_EDIT_PROPERTIES) ? &hPropertyEntries : NULL,
  1551. nStartPage)
  1552. && !m_bReadOnly;
  1553. if (bUpdateList)
  1554. {
  1555. if (hEntries)
  1556. iItems = DPA_GetPtrCount(hEntries);
  1557. if (hPropertyEntries)
  1558. iPropertyItems = DPA_GetPtrCount(hPropertyEntries);
  1559. if (iItems + iPropertyItems)
  1560. {
  1561. if (bDeleteSelection)
  1562. {
  1563. if ((nStartPage == 0 && iItems != 0) || (nStartPage == 1 && iPropertyItems != 0))
  1564. {
  1565. // The previous ace was modified, so delete it here.
  1566. ListView_DeleteItem(hListView, iSelected);
  1567. }
  1568. else if (iPropertyItems != 0 &&
  1569. !(pAce->Flags & ACE_OBJECT_TYPE_PRESENT) &&
  1570. (pAce->Mask & (ACTRL_DS_READ_PROP | ACTRL_DS_WRITE_PROP)))
  1571. {
  1572. //
  1573. // iPropertyItems != 0 implies nStartPage = 0 or else the
  1574. // "if" condition above would be true. nStartPage = 0
  1575. // implies iItems = 0 for the same reason. That means the
  1576. // ace has more in it that just property stuff (or it's a
  1577. // control access right), but the only changes occurred on the
  1578. // Property page. Make sure we get rid of any property bits
  1579. // in the original ace so that we don't incorrectly merge
  1580. // property changes into the original ace.
  1581. //
  1582. // An example of this:
  1583. // Suppose pAce->Mask == READ_CONTROL | ACTRL_DS_READ_PROP and
  1584. // no property GUID is present. Suppose the user edits the ace
  1585. // and clicks on the Property tab, then unchecks a bunch of
  1586. // things, including "Read all properties". The result
  1587. // "should be" a bunch of "Read <specific property>" aces.
  1588. // If we don't remove ACTRL_DS_READ_PROP from the original ace,
  1589. // then all of the "Read <specific property>" aces get merged
  1590. // back into the original ace for no net effect.
  1591. //
  1592. // The reverse situation (nStartPage = 1, iPropertyItems = 0,
  1593. // iItems != 0) is not a problem. In that case merging will
  1594. // occur correctly,
  1595. //
  1596. // Make a copy with everything except the property bits
  1597. if (pAce->Mask & ~(ACTRL_DS_READ_PROP | ACTRL_DS_WRITE_PROP))
  1598. {
  1599. EditAce_MakeCopyWithoutProperties:
  1600. PACE_HEADER pAceHeader = pAce->Copy();
  1601. if (pAceHeader != NULL)
  1602. {
  1603. // Turn off property bits
  1604. ((PKNOWN_ACE)pAceHeader)->Mask &= ~(ACTRL_DS_READ_PROP | ACTRL_DS_WRITE_PROP);
  1605. TraceAssert(((PKNOWN_ACE)pAceHeader)->Mask != 0);
  1606. // 370573
  1607. // Add it to hPropertyEntries instead of hEntries,
  1608. // since hEntries can be NULL here but we know
  1609. // hPropertyEntries is non-NULL (iPropertyItems!=0)
  1610. DPA_AppendPtr(hPropertyEntries, pAceHeader);
  1611. }
  1612. }
  1613. // Delete the old ace
  1614. ListView_DeleteItem(hListView, iSelected);
  1615. }
  1616. }
  1617. //
  1618. // Now merge the new aces into the existing list
  1619. //
  1620. iSelected = AddAcesFromDPA(hListView, hEntries, iSelected);
  1621. iSelected = AddAcesFromDPA(hListView, hPropertyEntries, iSelected);
  1622. //
  1623. // Now select the last item inserted
  1624. //
  1625. SelectSingleItemInLV( hListView, iSelected -1 );
  1626. // Re-sort the list so the new and/or modified entries
  1627. // appear in the right place.
  1628. if(m_iLastColumnClick == -1)
  1629. {
  1630. ListView_SortItems(hListView,
  1631. AceListCompareProcCanno,
  1632. MAKELPARAM(0, 1));
  1633. }
  1634. else
  1635. {
  1636. ListView_SortItems(hListView,
  1637. AceListCompareProc,
  1638. MAKELPARAM(m_iLastColumnClick, m_iSortDirection));
  1639. }
  1640. // After sorting, make sure the selection is visible.
  1641. EnsureListViewSelectionIsVisible(hListView);
  1642. }
  1643. else if (bDeleteSelection && dwResult)
  1644. {
  1645. // Everything succeeded, something was edited, but nothing was created
  1646. // (probably all boxes were unchecked). Delete the previous selection.
  1647. // 370573
  1648. // If the only change occurred on the Properties page, then we
  1649. // only want to turn off the property bits. We don't want to
  1650. // delete the whole thing.
  1651. if (EAE_NEW_PROPERTY_ACE == dwResult &&
  1652. (pAce->Mask & ~(ACTRL_DS_READ_PROP | ACTRL_DS_WRITE_PROP)))
  1653. {
  1654. if (!hPropertyEntries)
  1655. hPropertyEntries = DPA_Create(1);
  1656. if (hPropertyEntries)
  1657. goto EditAce_MakeCopyWithoutProperties;
  1658. }
  1659. // Delete the previous selection.
  1660. ListView_DeleteItem(hListView, iSelected);
  1661. }
  1662. // Was anything edited?
  1663. if (dwResult)
  1664. {
  1665. PropSheet_Changed(GetParent(hDlg),hDlg);
  1666. m_fPageDirty = TRUE;
  1667. }
  1668. }
  1669. if (hEntries)
  1670. DestroyDPA(hEntries);
  1671. if (hPropertyEntries)
  1672. DestroyDPA(hPropertyEntries);
  1673. TraceLeaveVoid();
  1674. }
  1675. void
  1676. CAdvancedListPage::CheckAuditPolicy(HWND hwndOwner)
  1677. {
  1678. //
  1679. // Check whether auditing is turned on and warn the user if not.
  1680. //
  1681. TraceEnter(TRACE_ACELIST, "CAdvancedListPage::CheckAuditPolicy");
  1682. if (!m_bAuditPolicyOK)
  1683. {
  1684. LSA_HANDLE hPolicy = GetLSAConnection(m_siObjectInfo.pszServerName,
  1685. POLICY_VIEW_AUDIT_INFORMATION);
  1686. if (hPolicy != NULL)
  1687. {
  1688. PPOLICY_AUDIT_EVENTS_INFO pAuditInfo = NULL;
  1689. LsaQueryInformationPolicy(hPolicy,
  1690. PolicyAuditEventsInformation,
  1691. (PVOID*)&pAuditInfo);
  1692. if (pAuditInfo != NULL)
  1693. {
  1694. // We don't need to do this work again
  1695. m_bAuditPolicyOK = TRUE;
  1696. if (!pAuditInfo->AuditingMode)
  1697. {
  1698. // Auditing is not on... warn the user
  1699. MsgPopup(hwndOwner,
  1700. MAKEINTRESOURCE(IDS_AUDIT_OFF_WARNING),
  1701. MAKEINTRESOURCE(IDS_SECURITY),
  1702. MB_OK | MB_ICONWARNING,
  1703. ::hModule);
  1704. }
  1705. LsaFreeMemory(pAuditInfo);
  1706. }
  1707. else
  1708. {
  1709. TraceMsg("LsaQueryInformationPolicy failed");
  1710. }
  1711. LsaClose(hPolicy);
  1712. }
  1713. else
  1714. {
  1715. TraceMsg("Unable to open LSA policy handle");
  1716. }
  1717. }
  1718. TraceLeaveVoid();
  1719. }
  1720. BOOL
  1721. CAdvancedListPage::DlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  1722. {
  1723. PACE pAce;
  1724. switch(uMsg)
  1725. {
  1726. case WM_INITDIALOG:
  1727. InitDlg(hDlg);
  1728. break;
  1729. case WM_NOTIFY:
  1730. {
  1731. LPNMHDR pnmh = (LPNMHDR)lParam;
  1732. LPNM_LISTVIEW pnmlv = (LPNM_LISTVIEW)lParam;
  1733. // Set default return value
  1734. SetWindowLongPtr(hDlg, DWLP_MSGRESULT, PSNRET_NOERROR);
  1735. switch (pnmh->code)
  1736. {
  1737. case NM_DBLCLK:
  1738. if (pnmh->idFrom == IDC_ACEL_DETAILS)
  1739. OnEdit(hDlg);
  1740. break;
  1741. case LVN_ITEMCHANGED:
  1742. if (pnmlv->uChanged & LVIF_STATE)
  1743. UpdateButtons(hDlg);
  1744. break;
  1745. case LVN_DELETEITEM:
  1746. pAce = (PACE)pnmlv->lParam;
  1747. delete pAce;
  1748. break;
  1749. case LVN_KEYDOWN:
  1750. if (((LPNMLVKEYDOWN)pnmh)->wVKey == VK_DELETE)
  1751. if( IsWindowEnabled( GetDlgItem( hDlg, IDC_ACEL_REMOVE ) ) )
  1752. SendMessage(hDlg,
  1753. WM_COMMAND,
  1754. GET_WM_COMMAND_MPS(IDC_ACEL_REMOVE, NULL, 0));
  1755. break;
  1756. #define lvi (((NMLVDISPINFO*)lParam)->item)
  1757. case LVN_GETDISPINFO:
  1758. pAce = (PACE)lvi.lParam;
  1759. if ((lvi.mask & LVIF_TEXT) && pAce)
  1760. {
  1761. switch (lvi.iSubItem)
  1762. {
  1763. case 0:
  1764. lvi.pszText = pAce->GetType();
  1765. break;
  1766. case 1:
  1767. lvi.pszText = pAce->GetName();
  1768. break;
  1769. case 2:
  1770. lvi.pszText = pAce->GetAccessType();
  1771. break;
  1772. case 3:
  1773. lvi.pszText = pAce->GetInheritSourceName();
  1774. break;
  1775. case 4:
  1776. lvi.pszText = pAce->GetInheritType();
  1777. break;
  1778. }
  1779. }
  1780. break;
  1781. #undef lvi
  1782. case LVN_COLUMNCLICK:
  1783. if (m_iLastColumnClick == pnmlv->iSubItem)
  1784. m_iSortDirection = -m_iSortDirection;
  1785. else
  1786. m_iSortDirection = 1;
  1787. m_iLastColumnClick = pnmlv->iSubItem;
  1788. ListView_SortItems(pnmh->hwndFrom,
  1789. AceListCompareProc,
  1790. MAKELPARAM(m_iLastColumnClick, m_iSortDirection));
  1791. EnsureListViewSelectionIsVisible(pnmh->hwndFrom);
  1792. break;
  1793. case PSN_APPLY:
  1794. OnApply(hDlg, (BOOL)(((LPPSHNOTIFY)lParam)->lParam));
  1795. break;
  1796. case NM_CLICK:
  1797. case NM_RETURN:
  1798. {
  1799. if(wParam == IDC_EFF_STATIC)
  1800. {
  1801. if(m_siPageType == SI_PAGE_AUDIT)
  1802. {
  1803. HtmlHelp(hDlg,
  1804. c_szAuditHelpLink,
  1805. HH_DISPLAY_TOPIC,
  1806. 0);
  1807. }
  1808. else
  1809. {
  1810. HtmlHelp(hDlg,
  1811. c_szPermHelpLink,
  1812. HH_DISPLAY_TOPIC,
  1813. 0);
  1814. }
  1815. }
  1816. }
  1817. break;
  1818. }
  1819. }
  1820. break;
  1821. case WM_COMMAND:
  1822. switch (GET_WM_COMMAND_ID(wParam, lParam))
  1823. {
  1824. case IDC_ACEL_ADD:
  1825. OnAdd(hDlg);
  1826. break;
  1827. case IDC_ACEL_REMOVE:
  1828. OnRemove(hDlg);
  1829. break;
  1830. case IDC_ACEL_EDIT:
  1831. OnEdit(hDlg);
  1832. break;
  1833. case IDC_ACEL_RESET:
  1834. OnReset(hDlg);
  1835. break;
  1836. case IDC_ACEL_RESET_ACL_TREE:
  1837. if (!m_fPageDirty)
  1838. {
  1839. PropSheet_Changed(GetParent(hDlg),hDlg);
  1840. m_fPageDirty = TRUE;
  1841. }
  1842. break;
  1843. case IDC_ACEL_PROTECT:
  1844. if (GET_WM_COMMAND_CMD(wParam, lParam) == BN_CLICKED
  1845. && !m_bReadOnly)
  1846. {
  1847. OnProtect(hDlg);
  1848. }
  1849. break;
  1850. default:
  1851. return FALSE;
  1852. }
  1853. break;
  1854. case WM_HELP:
  1855. if (IsWindowEnabled(hDlg))
  1856. {
  1857. const DWORD *pdwHelpIDs = aAceListPermHelpIDs;
  1858. if (m_siPageType == SI_PAGE_AUDIT)
  1859. pdwHelpIDs = aAceListAuditHelpIDs;
  1860. WinHelp((HWND)((LPHELPINFO)lParam)->hItemHandle,
  1861. c_szAcluiHelpFile,
  1862. HELP_WM_HELP,
  1863. (DWORD_PTR)pdwHelpIDs);
  1864. }
  1865. break;
  1866. case WM_CONTEXTMENU:
  1867. if (IsWindowEnabled(hDlg))
  1868. {
  1869. const DWORD *pdwHelpIDs = aAceListPermHelpIDs;
  1870. if (m_siPageType == SI_PAGE_AUDIT)
  1871. pdwHelpIDs = aAceListAuditHelpIDs;
  1872. WinHelp(hDlg,
  1873. c_szAcluiHelpFile,
  1874. HELP_CONTEXTMENU,
  1875. (DWORD_PTR)pdwHelpIDs);
  1876. }
  1877. break;
  1878. default:
  1879. return FALSE;
  1880. }
  1881. return TRUE;
  1882. }
  1883. HPROPSHEETPAGE
  1884. CreateAdvPermissionPage( LPSECURITYINFO psi )
  1885. {
  1886. HPROPSHEETPAGE hPage = NULL;
  1887. PADVANCEDLISTPAGE pPage;
  1888. TraceEnter(TRACE_ACELIST, "CreateAdvPermissionPage");
  1889. pPage = new CAdvancedListPage( psi, SI_PAGE_ADVPERM );
  1890. if (pPage)
  1891. {
  1892. hPage = pPage->CreatePropSheetPage(MAKEINTRESOURCE(IDD_ACELIST_PERM_PAGE));
  1893. if (!hPage)
  1894. delete pPage;
  1895. }
  1896. TraceLeaveValue(hPage);
  1897. }
  1898. HPROPSHEETPAGE
  1899. CreateAdvAuditPage( LPSECURITYINFO psi )
  1900. {
  1901. HPROPSHEETPAGE hPage = NULL;
  1902. PADVANCEDLISTPAGE pPage;
  1903. TraceEnter(TRACE_ACELIST, "CreateAdvAuditPage");
  1904. pPage = new CAdvancedListPage( psi, SI_PAGE_AUDIT );
  1905. if (pPage)
  1906. {
  1907. hPage = pPage->CreatePropSheetPage(MAKEINTRESOURCE(IDD_ACELIST_AUDIT_PAGE));
  1908. if (!hPage)
  1909. delete pPage;
  1910. }
  1911. TraceLeaveValue(hPage);
  1912. }
  1913. //
  1914. // Expose an api to get at the ace list editor
  1915. //
  1916. BOOL
  1917. ACLUIAPI
  1918. EditSecurityEx(HWND hwndOwner,
  1919. LPSECURITYINFO psi,
  1920. PPERMPAGE pPermPage,
  1921. UINT nStartPage,
  1922. BOOL &refbNoReadWriteCanWriteOwner)
  1923. {
  1924. HPROPSHEETPAGE hPage[4];
  1925. UINT cPages = 0;
  1926. BOOL bResult = FALSE;
  1927. SI_OBJECT_INFO siObjectInfo = {0};
  1928. HRESULT hr;
  1929. TraceEnter(TRACE_ACELIST, "EditSecurityEx");
  1930. // Get flags and object name information
  1931. hr = psi->GetObjectInformation(&siObjectInfo);
  1932. if (FAILED(hr))
  1933. {
  1934. SysMsgPopup(hwndOwner,
  1935. MAKEINTRESOURCE(IDS_OPERATION_FAILED),
  1936. MAKEINTRESOURCE(IDS_SECURITY),
  1937. MB_OK | MB_ICONERROR,
  1938. ::hModule,
  1939. hr);
  1940. TraceLeaveValue(FALSE);
  1941. }
  1942. hPage[cPages] = CreateAdvPermissionPage( psi );
  1943. if (hPage[cPages])
  1944. cPages++;
  1945. if (siObjectInfo.dwFlags & SI_EDIT_AUDITS)
  1946. {
  1947. hPage[cPages] = CreateAdvAuditPage( psi );
  1948. if (hPage[cPages])
  1949. cPages++;
  1950. }
  1951. if (siObjectInfo.dwFlags & SI_EDIT_OWNER)
  1952. {
  1953. hPage[cPages] = CreateOwnerPage( psi, &siObjectInfo, refbNoReadWriteCanWriteOwner );
  1954. if (hPage[cPages])
  1955. cPages++;
  1956. }
  1957. if((siObjectInfo.dwFlags & SI_EDIT_EFFECTIVE) && pPermPage->IsEffective())
  1958. {
  1959. hPage[cPages] = CreateEffectivePermPage( psi, &siObjectInfo );
  1960. if (hPage[cPages])
  1961. {
  1962. // pPermPage->SetEffectivePerm(hPage[cPages]);
  1963. cPages++;
  1964. }
  1965. }
  1966. if (cPages)
  1967. {
  1968. // Build dialog title string
  1969. LPTSTR pszCaption = NULL;
  1970. FormatStringID(&pszCaption, ::hModule, IDS_ACEL_TITLE, siObjectInfo.pszObjectName);
  1971. PROPSHEETHEADER psh = {0};
  1972. psh.dwSize = SIZEOF(psh);
  1973. psh.dwFlags = PSH_DEFAULT;
  1974. psh.hwndParent = hwndOwner;
  1975. psh.hInstance = ::hModule;
  1976. psh.pszCaption = pszCaption;
  1977. psh.nPages = cPages;
  1978. psh.nStartPage = 0;
  1979. psh.phpage = &hPage[0];
  1980. if (nStartPage < cPages)
  1981. psh.nStartPage = nStartPage;
  1982. bResult = (BOOL)(PropertySheet(&psh) + 1);
  1983. LocalFreeString(&pszCaption);
  1984. }
  1985. TraceLeaveValue(bResult);
  1986. }