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.

549 lines
14 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1996 - 1999
  6. //
  7. // File: owner.cpp
  8. //
  9. // This file contains the implementation of the Owner page.
  10. //
  11. //--------------------------------------------------------------------------
  12. #include "aclpriv.h"
  13. #include <initguid.h> // needed to get the GUIDs defined in oleacc.h
  14. #include <oleacc.h> // contains IAccProp* definitions
  15. //Context Help IDs
  16. const static DWORD aEffHelpIDs[] =
  17. {
  18. IDC_EFF_NAME_STATIC, IDH_EFF_NAME,
  19. IDC_EFF_NAME, IDH_EFF_NAME,
  20. IDC_EFF_SELECT, IDH_EFF_SELECT,
  21. IDC_EFF_PERMISSION_STATIC, IDH_EFF_PERM_LIST,
  22. IDC_EFF_PERM_LIST, IDH_EFF_PERM_LIST,
  23. IDC_EFF_STATIC, -1,
  24. 0, 0
  25. };
  26. LPCWSTR g_ListStateMap =
  27. L"A:0"
  28. L":0:0x50" // checked, disabled - STATE_SYSTEM_READONLY | STATE_SYSTEM_CHECKED
  29. L":1:0x40" // disabled - STATE_SYSTEM_READONLY
  30. L":";
  31. LPCWSTR g_ListRoleMap =
  32. L"A:0"
  33. L":0:0x2C" // checkbox - ROLE_SYSTEM_CHECKBUTTON (ie. checkbox)
  34. L":1:0x2C"
  35. L":";
  36. int LV_ADDITEM(HWND hwndList,
  37. LPCTSTR pszName,
  38. int index,
  39. PSI_ACCESS pAccess,
  40. BOOL bChecked)
  41. {
  42. LVITEM lvItem;
  43. TraceAssert(pAccess != NULL);
  44. TraceAssert(pszName != NULL);
  45. lvItem.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE;
  46. lvItem.iItem = index;
  47. lvItem.iSubItem = 0;
  48. lvItem.pszText = (LPTSTR)pszName;
  49. lvItem.lParam = (LPARAM)pAccess;
  50. lvItem.iImage = bChecked ? 0 : 1;
  51. // Insert item into list
  52. index = ListView_InsertItem(hwndList, &lvItem);
  53. ListView_SetCheckState(hwndList,index,bChecked);
  54. return index;
  55. }
  56. typedef struct _EffCacheItem
  57. {
  58. POBJECT_TYPE_LIST pObjectTypeList;
  59. ULONG cObjectTypeListLength;
  60. PACCESS_MASK pGrantedAccessList;
  61. PSID pSid;
  62. }EFFCACHEITEM,*PEFFCACHEITEM;
  63. //This Function checks is pAccess is granted.
  64. BOOL IsChecked( PSI_ACCESS pAccess,
  65. PEFFCACHEITEM pCacheItem)
  66. {
  67. TraceEnter(TRACE_EFFPERM, "IsChecked");
  68. TraceAssert(pCacheItem != NULL);
  69. TraceAssert(pAccess != NULL);
  70. POBJECT_TYPE_LIST pObjectTypeList = pCacheItem->pObjectTypeList;
  71. ULONG cObjectTypeListLength = pCacheItem->cObjectTypeListLength;
  72. PACCESS_MASK pGrantedAccessList = pCacheItem->pGrantedAccessList;
  73. //0th Grant is for full object.
  74. if( (pAccess->mask & pGrantedAccessList[0]) == pAccess->mask )
  75. return TRUE;
  76. BOOL bGuidNULL = pAccess->pguid ?IsEqualGUID(*(pAccess->pguid), GUID_NULL): TRUE;
  77. LPGUID pguid;
  78. for( UINT i = 1; i < cObjectTypeListLength; ++i )
  79. {
  80. pguid = pObjectTypeList[i].ObjectType;
  81. if( pguid == NULL ||
  82. IsEqualGUID(*pguid, GUID_NULL) ||
  83. (!bGuidNULL && IsEqualGUID(*pguid,*(pAccess->pguid))) )
  84. {
  85. if( (pAccess->mask & pGrantedAccessList[i]) == pAccess->mask )
  86. return TRUE;
  87. }
  88. }
  89. return FALSE;
  90. }
  91. class CEffPage: public CSecurityPage
  92. {
  93. public:
  94. CEffPage(LPSECURITYINFO psi, SI_OBJECT_INFO *psiObjectInfo);
  95. virtual ~CEffPage();
  96. private:
  97. virtual BOOL DlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
  98. BOOL InitDlg(HWND hDlg);
  99. void OnSelect(HWND hDlg);
  100. void InitListBox(HWND hDlg);
  101. HRESULT GetEffectivePerm(PSID pSid, PEFFCACHEITEM *ppCacheItem);
  102. PSID GetSelectedSID(){ return m_pSid; }
  103. private:
  104. PSID m_pSid; //Sid of the security principal for which permissions are displayed
  105. PSI_ACCESS m_pAccess;
  106. ULONG m_cAccesses;
  107. };
  108. HPROPSHEETPAGE
  109. CreateEffectivePermPage(LPSECURITYINFO psi, SI_OBJECT_INFO *psiObjectInfo)
  110. {
  111. HPROPSHEETPAGE hPage = NULL;
  112. CEffPage *pPage;
  113. TraceEnter(TRACE_EFFPERM, "CreateEffectivePermPage");
  114. TraceAssert(psi!=NULL);
  115. TraceAssert(psiObjectInfo);
  116. pPage = new CEffPage(psi, psiObjectInfo);
  117. if (pPage)
  118. {
  119. hPage = pPage->CreatePropSheetPage(MAKEINTRESOURCE(IDD_EFFECTIVE_PERM_PAGE));
  120. if (!hPage)
  121. delete pPage;
  122. }
  123. TraceLeaveValue(hPage);
  124. }
  125. CEffPage::CEffPage(LPSECURITYINFO psi, SI_OBJECT_INFO *psiObjectInfo)
  126. : CSecurityPage(psi, SI_PAGE_OWNER) , m_pSid(NULL),
  127. m_pAccess(NULL), m_cAccesses(0)
  128. {
  129. // Lookup known SIDs asynchronously so the dialog
  130. // will initialize faster
  131. }
  132. CEffPage::~CEffPage()
  133. {
  134. if (m_pSid)
  135. LocalFree(m_pSid);
  136. }
  137. BOOL
  138. CEffPage::DlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  139. {
  140. BOOL bResult = TRUE;
  141. LPPSHNOTIFY lpsn;
  142. switch(uMsg)
  143. {
  144. case WM_INITDIALOG:
  145. InitDlg(hDlg);
  146. break;
  147. case WM_COMMAND:
  148. switch (GET_WM_COMMAND_ID(wParam, lParam))
  149. {
  150. case IDC_EFF_SELECT:
  151. OnSelect(hDlg);
  152. break;
  153. default:
  154. bResult = FALSE;
  155. }
  156. break;
  157. case WM_HELP:
  158. if (IsWindowEnabled(hDlg))
  159. {
  160. WinHelp((HWND)((LPHELPINFO)lParam)->hItemHandle,
  161. c_szAcluiHelpFile,
  162. HELP_WM_HELP,
  163. (DWORD_PTR)aEffHelpIDs);
  164. }
  165. break;
  166. case WM_CONTEXTMENU:
  167. if (IsWindowEnabled(hDlg))
  168. {
  169. WinHelp(hDlg,
  170. c_szAcluiHelpFile,
  171. HELP_CONTEXTMENU,
  172. (DWORD_PTR)aEffHelpIDs);
  173. }
  174. break;
  175. case PSM_QUERYSIBLINGS:
  176. if(GetSelectedSID())
  177. InitListBox(hDlg);
  178. break;
  179. default:
  180. bResult = FALSE;
  181. }
  182. return bResult;
  183. }
  184. BOOL
  185. CEffPage::InitDlg( HWND hDlg )
  186. {
  187. HWND hwndList;
  188. RECT rc;
  189. LV_COLUMN col;
  190. TCHAR szBuffer[MAX_COLUMN_CHARS];
  191. HRESULT hr = S_OK;
  192. ULONG iDefaultAccess;
  193. HCURSOR hcur = SetCursor(LoadCursor(NULL, IDC_WAIT));
  194. TraceEnter(TRACE_EFFPERM, "CEffPage::InitDlg");
  195. TraceAssert(hDlg != NULL);
  196. TraceAssert(m_psi != NULL);
  197. TraceAssert(m_pei != NULL);
  198. hwndList = GetDlgItem(hDlg, IDC_EFF_PERM_LIST);
  199. //
  200. // Create & set the image list for the listview. If there is a
  201. // problem CreateSidImageList will return NULL which won't hurt
  202. // anything. In that case we'll just continue without an image list.
  203. //
  204. ListView_SetImageList(hwndList,
  205. LoadImageList(::hModule, MAKEINTRESOURCE(IDB_CHECKBOX)),
  206. LVSIL_SMALL);
  207. // Set extended LV style for whole line selection with InfoTips
  208. ListView_SetExtendedListViewStyleEx(hwndList,
  209. LVS_EX_FULLROWSELECT | LVS_EX_INFOTIP,
  210. LVS_EX_FULLROWSELECT | LVS_EX_INFOTIP);
  211. IAccPropServices * pAccPropSvc = NULL;
  212. hr = CoCreateInstance( CLSID_AccPropServices, NULL, CLSCTX_SERVER, IID_IAccPropServices, (void **) & pAccPropSvc );
  213. if( hr == S_OK && pAccPropSvc )
  214. {
  215. // Don't have to check HRESULT here, since if they fail we just ignore anyway,
  216. // but may want to log it while debugging.
  217. pAccPropSvc->SetHwndPropStr(hwndList, OBJID_CLIENT, 0, PROPID_ACC_ROLEMAP, g_ListRoleMap );
  218. pAccPropSvc->SetHwndPropStr(hwndList, OBJID_CLIENT, 0, PROPID_ACC_STATEMAP, g_ListStateMap );
  219. pAccPropSvc->Release();
  220. }
  221. //
  222. // Add appropriate listview columns
  223. //
  224. GetClientRect(hwndList, &rc);
  225. LoadString(::hModule, IDS_PERMISSIONS, szBuffer, ARRAYSIZE(szBuffer));
  226. col.mask = LVCF_FMT | LVCF_TEXT | LVCF_SUBITEM | LVCF_WIDTH;
  227. col.fmt = LVCFMT_LEFT;
  228. col.pszText = szBuffer;
  229. col.iSubItem = 0;
  230. col.cx = rc.right - GetSystemMetrics(SM_CXVSCROLL);
  231. ListView_InsertColumn(hwndList, 0, &col);
  232. //Get the access Rights
  233. hr = m_psi->GetAccessRights(&GUID_NULL,
  234. SI_ADVANCED|SI_EDIT_EFFECTIVE,
  235. &m_pAccess,
  236. &m_cAccesses,
  237. &iDefaultAccess);
  238. FailGracefully(hr, "GetAccessRights Failed");
  239. //Initialize the List box
  240. InitListBox(hDlg);
  241. exit_gracefully:
  242. SetCursor(hcur);
  243. if (FAILED(hr))
  244. {
  245. HWND hwnd;
  246. // Hide and disable everything
  247. for (hwnd = GetWindow(hDlg, GW_CHILD);
  248. hwnd != NULL;
  249. hwnd = GetWindow(hwnd, GW_HWNDNEXT))
  250. {
  251. ShowWindow(hwnd, SW_HIDE);
  252. EnableWindow(hwnd, FALSE);
  253. }
  254. // Enable and show the "No Security" message
  255. hwnd = GetDlgItem(hDlg, IDC_NO_EFFECTIVE);
  256. EnableWindow(hwnd, TRUE);
  257. ShowWindow(hwnd, SW_SHOW);
  258. }
  259. TraceLeaveValue(TRUE);
  260. }
  261. VOID
  262. CEffPage::OnSelect(HWND hDlg)
  263. {
  264. PUSER_LIST pUserList = NULL;
  265. LPEFFECTIVEPERMISSION pei;
  266. HRESULT hr = S_OK;
  267. TraceEnter(TRACE_EFFPERM, "CEffPage::OnSelect");
  268. if (S_OK == GetUserGroup(hDlg, FALSE, &pUserList))
  269. {
  270. TraceAssert(NULL != pUserList);
  271. TraceAssert(1 == pUserList->cUsers);
  272. // Free up previous sid
  273. if (m_pSid)
  274. LocalFree(m_pSid);
  275. // Copy the new sid
  276. m_pSid = LocalAllocSid(pUserList->rgUsers[0].pSid);
  277. if (m_pSid)
  278. {
  279. SetDlgItemText(hDlg, IDC_EFF_NAME, pUserList->rgUsers[0].pszName);
  280. }
  281. LocalFree(pUserList);
  282. InitListBox(hDlg);
  283. }
  284. }
  285. VOID
  286. CEffPage::InitListBox(HWND hDlg)
  287. {
  288. HWND hwndList;
  289. BOOL bProperties;
  290. PSI_ACCESS pAccess;
  291. ULONG cAccesses;
  292. DWORD dwType;
  293. TCHAR szName[MAX_PATH];
  294. PSID pSid = NULL;
  295. PEFFCACHEITEM pCacheItem = NULL;
  296. int index;
  297. TraceEnter(TRACE_EFFPERM, "CEffPage::InitListBox");
  298. TraceAssert( m_pAccess != NULL );
  299. TraceAssert(m_cAccesses != 0 );
  300. HRESULT hr = S_OK;
  301. hwndList = GetDlgItem(hDlg, IDC_EFF_PERM_LIST);
  302. if(!IsWindowEnabled(hwndList))
  303. {
  304. //Hide Error Message
  305. HWND hwnd = GetDlgItem(hDlg, IDC_EFF_ERROR);
  306. EnableWindow(hwnd, FALSE);
  307. ShowWindow(hwnd, SW_HIDE);
  308. //Show List box
  309. EnableWindow(hwndList, TRUE);
  310. ShowWindow(hwndList, SW_SHOW);
  311. }
  312. //Clear all items
  313. ListView_DeleteAllItems(hwndList);
  314. pAccess = m_pAccess;
  315. cAccesses = m_cAccesses;
  316. dwType = SI_ACCESS_SPECIFIC | SI_ACCESS_PROPERTY;
  317. //Get the current sid
  318. pSid = GetSelectedSID();
  319. if( pSid )
  320. {
  321. hr = GetEffectivePerm(pSid, &pCacheItem);
  322. FailGracefully(hr,"GetEffectivePermission Failed");
  323. }
  324. index = 0;
  325. // Enumerate the permissions and add to the checklist
  326. ULONG i;
  327. for (i = 0; i < cAccesses; i++, pAccess++)
  328. {
  329. LPCTSTR pszName;
  330. // Only add permissions that have any of the flags specified in dwType
  331. if (!(pAccess->dwFlags & dwType))
  332. continue;
  333. //Don't Add Permission which have inherit only on
  334. if( pAccess->dwFlags & INHERIT_ONLY_ACE )
  335. continue;
  336. pszName = pAccess->pszName;
  337. if (IS_INTRESOURCE(pszName))
  338. {
  339. TraceAssert(m_siObjectInfo.hInstance != NULL);
  340. if (LoadString(m_siObjectInfo.hInstance,
  341. (UINT)((ULONG_PTR)pszName),
  342. szName,
  343. ARRAYSIZE(szName)) == 0)
  344. {
  345. LoadString(::hModule,
  346. IDS_UNKNOWN,
  347. szName,
  348. ARRAYSIZE(szName));
  349. }
  350. pszName = szName;
  351. }
  352. BOOL bChecked = FALSE;
  353. if(pSid)
  354. {
  355. bChecked = IsChecked( pAccess, pCacheItem );
  356. }
  357. index = LV_ADDITEM( hwndList, pszName, index, pAccess, bChecked);
  358. index++;
  359. }
  360. if(index)
  361. {
  362. SelectListViewItem(hwndList, 0);
  363. // Redraw the list
  364. SendMessage(hwndList, WM_SETREDRAW, TRUE, 0);
  365. ListView_RedrawItems(hwndList, 0, -1);
  366. }
  367. exit_gracefully:
  368. if(pCacheItem)
  369. {
  370. if(pCacheItem->pGrantedAccessList)
  371. LocalFree(pCacheItem->pGrantedAccessList);
  372. LocalFree(pCacheItem);
  373. }
  374. if(FAILED(hr))
  375. {
  376. //Hide List box
  377. HWND hwnd = GetDlgItem(hDlg, IDC_EFF_PERM_LIST);
  378. EnableWindow(hwnd, FALSE);
  379. ShowWindow(hwnd, SW_HIDE);
  380. //Format Error Message To Display
  381. WCHAR buffer[MAX_PATH];
  382. LPWSTR pszCaption = NULL;
  383. GetWindowText(GetDlgItem(hDlg, IDC_EFF_NAME),
  384. buffer,
  385. MAX_PATH-1);
  386. FormatStringID(&pszCaption, ::hModule, IDS_EFF_ERROR, buffer);
  387. //Show Error Message
  388. hwnd = GetDlgItem(hDlg, IDC_EFF_ERROR);
  389. EnableWindow(hwnd, TRUE);
  390. SetWindowText(hwnd,pszCaption);
  391. ShowWindow(hwnd, SW_SHOW);
  392. LocalFreeString(&pszCaption);
  393. }
  394. TraceLeaveVoid();
  395. }
  396. //Calling function frees *ppCacheItem->pGrantedAccessList
  397. //and *ppCacheItem
  398. HRESULT
  399. CEffPage::GetEffectivePerm(PSID pSid,
  400. PEFFCACHEITEM *ppCacheItem )
  401. {
  402. PSECURITY_DESCRIPTOR pSD;
  403. HRESULT hr = S_OK;
  404. ULONG cItems = 0;
  405. PEFFCACHEITEM pCacheTemp = NULL;
  406. TraceEnter(TRACE_EFFPERM, "CEffPage::GetEffectivePerm");
  407. TraceAssert(pSid != NULL);
  408. TraceAssert(ppCacheItem != NULL);
  409. pCacheTemp = (PEFFCACHEITEM)LocalAlloc( LPTR, sizeof(EFFCACHEITEM) + GetLengthSid(pSid));
  410. if(!pCacheTemp)
  411. ExitGracefully(hr, E_OUTOFMEMORY, "Lcoal Alloc Failed");
  412. pCacheTemp->pSid = (PSID)(pCacheTemp + 1);
  413. CopySid(GetLengthSid(pSid), pCacheTemp->pSid, pSid);
  414. if(m_psi)
  415. {
  416. hr = m_psi->GetSecurity(OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
  417. &pSD,
  418. FALSE);
  419. FailGracefully(hr, "GetSecurity Failed");
  420. }
  421. if( m_pei)
  422. {
  423. DWORD dwTemp;
  424. hr = m_pei->GetEffectivePermission(&(m_siObjectInfo.guidObjectType),
  425. pCacheTemp->pSid,
  426. m_siObjectInfo.pszServerName,
  427. //NULL,
  428. pSD,
  429. &(pCacheTemp->pObjectTypeList),
  430. &(pCacheTemp->cObjectTypeListLength),
  431. &(pCacheTemp->pGrantedAccessList),
  432. &dwTemp);
  433. if(SUCCEEDED(hr))
  434. {
  435. if(!pCacheTemp->pObjectTypeList || !pCacheTemp->pGrantedAccessList)
  436. hr = E_FAIL;
  437. }
  438. FailGracefully(hr, "GetEffectivePermission Failed");
  439. }
  440. exit_gracefully:
  441. if( !SUCCEEDED(hr) )
  442. {
  443. LocalFree(pCacheTemp);
  444. pCacheTemp = NULL;
  445. }
  446. *ppCacheItem = pCacheTemp;
  447. TraceLeaveResult(hr);
  448. }