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.

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