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.

1335 lines
46 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation 1996-2001.
  5. //
  6. // File: servperm.cpp
  7. //
  8. // Contents: implementation of CSecurityInfo
  9. //
  10. //----------------------------------------------------------------------------
  11. #include "stdafx.h"
  12. extern "C"
  13. {
  14. #include <seopaque.h> // RtlObjectAceSid, etc.
  15. }
  16. #include "resource.h"
  17. #include "initguid.h"
  18. #include "ServPerm.h"
  19. #include "util.h"
  20. #include "uithread.h"
  21. #ifdef _DEBUG
  22. #define new DEBUG_NEW
  23. #undef THIS_FILE
  24. static char THIS_FILE[] = __FILE__;
  25. #endif
  26. //extern "C"
  27. //STDAPI
  28. //DSCreateISecurityInfoObject(LPCWSTR pwszObjectPath,
  29. // LPCWSTR pwszObjectClass,
  30. // DWORD dwFlags,
  31. // LPSECURITYINFO *ppSI,
  32. // PFNREADOBJECTSECURITY pfnReadSD,
  33. // PFNWRITEOBJECTSECURITY pfnWriteSD,
  34. // LPARAM lpContext);
  35. //
  36. /*
  37. HPROPSHEETPAGE ACLUIAPI CreateSecurityPage( LPSECURITYINFO psi );
  38. */
  39. static HINSTANCE g_hAclUiDll = NULL;
  40. typedef HPROPSHEETPAGE (WINAPI *PFNCSECPAGE)(LPSECURITYINFO);
  41. #ifndef PERM_HEADER_DEFINED
  42. #define PERM_HEADER_DEFINED
  43. #define INHERIT_FULL (CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE)
  44. //For ntfs
  45. //
  46. // Treat SYNCHRONIZE specially. In particular, always allow SYNCHRONIZE and
  47. // never Deny SYNCHRONIZE. Do this by removing it from the Generic Mapping,
  48. // turning it off in all ACEs and SI_ACCESS entries, and then adding it to
  49. // all Allow ACEs before saving a new ACL.
  50. //Keep this in sync with ISecurityInfromation impl for FileSystem
  51. #define FILE_GENERIC_READ_ (FILE_GENERIC_READ & ~SYNCHRONIZE)
  52. #define FILE_GENERIC_WRITE_ (FILE_GENERIC_WRITE & ~(SYNCHRONIZE | READ_CONTROL))
  53. #define FILE_GENERIC_EXECUTE_ (FILE_GENERIC_EXECUTE & ~SYNCHRONIZE)
  54. #define FILE_GENERIC_ALL_ (FILE_ALL_ACCESS & ~SYNCHRONIZE)
  55. #define FILE_GENERAL_MODIFY (FILE_GENERIC_READ_ | FILE_GENERIC_WRITE_ | FILE_GENERIC_EXECUTE_ | DELETE)
  56. #define FILE_GENERAL_PUBLISH (FILE_GENERIC_READ_ | FILE_GENERIC_WRITE_ | FILE_GENERIC_EXECUTE_)
  57. #define FILE_GENERAL_DEPOSIT (FILE_GENERIC_WRITE_ | FILE_GENERIC_EXECUTE_)
  58. #define FILE_GENERAL_READ_EX (FILE_GENERIC_READ_ | FILE_GENERIC_EXECUTE_)
  59. #define iFileDefAccess 2 // FILE_GEN_READ
  60. #define iKeyDefAccess 2 // KEY_READ
  61. #endif
  62. #include <initguid.h>
  63. DEFINE_GUID(GUID_A_NT_GROUP_MEMBERS, 0xbf9679df,0x0de6,0x11d0,0xa2,0x85,0x00,0xaa,0x00,0x30,0x49,0xe2);
  64. //
  65. // define all access rights for files on general page and/or specific page
  66. //
  67. static SI_ACCESS siFileAccesses[] =
  68. {
  69. { &GUID_NULL, FILE_GENERIC_ALL_, MAKEINTRESOURCE(IDS_FILE_GEN_ALL), SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC | INHERIT_FULL },
  70. { &GUID_NULL, FILE_GENERAL_MODIFY, MAKEINTRESOURCE(IDS_FILE_GEN_MODIFY), SI_ACCESS_GENERAL | INHERIT_FULL },
  71. { &GUID_NULL, FILE_GENERAL_READ_EX, MAKEINTRESOURCE(IDS_FILE_GEN_READ), SI_ACCESS_GENERAL | INHERIT_FULL },
  72. { &GUID_NULL, FILE_GENERAL_READ_EX, MAKEINTRESOURCE(IDS_FILE_GEN_LIST), SI_ACCESS_CONTAINER | CONTAINER_INHERIT_ACE },
  73. { &GUID_NULL, FILE_GENERIC_READ_, MAKEINTRESOURCE(IDS_FILE_GENERIC_READ), SI_ACCESS_GENERAL | INHERIT_FULL },
  74. { &GUID_NULL, FILE_GENERIC_WRITE_, MAKEINTRESOURCE(IDS_FILE_GENERIC_WRITE), SI_ACCESS_GENERAL | INHERIT_FULL },
  75. { &GUID_NULL, FILE_EXECUTE, MAKEINTRESOURCE(IDS_FILE_SPEC_EXECUTE), SI_ACCESS_SPECIFIC },
  76. { &GUID_NULL, FILE_READ_DATA, MAKEINTRESOURCE(IDS_FILE_SPEC_READ_DATA), SI_ACCESS_SPECIFIC },
  77. { &GUID_NULL, FILE_READ_ATTRIBUTES, MAKEINTRESOURCE(IDS_FILE_SPEC_READ_ATTR), SI_ACCESS_SPECIFIC },
  78. { &GUID_NULL, FILE_READ_EA, MAKEINTRESOURCE(IDS_FILE_SPEC_READ_EA), SI_ACCESS_SPECIFIC },
  79. { &GUID_NULL, FILE_WRITE_DATA, MAKEINTRESOURCE(IDS_FILE_SPEC_WRITE_DATA), SI_ACCESS_SPECIFIC },
  80. { &GUID_NULL, FILE_APPEND_DATA, MAKEINTRESOURCE(IDS_FILE_SPEC_APPEND_DATA), SI_ACCESS_SPECIFIC },
  81. { &GUID_NULL, FILE_WRITE_ATTRIBUTES, MAKEINTRESOURCE(IDS_FILE_SPEC_WRITE_ATTR), SI_ACCESS_SPECIFIC },
  82. { &GUID_NULL, FILE_WRITE_EA, MAKEINTRESOURCE(IDS_FILE_SPEC_WRITE_EA), SI_ACCESS_SPECIFIC },
  83. { &GUID_NULL, FILE_DELETE_CHILD, MAKEINTRESOURCE(IDS_FILE_SPEC_DELETE_CHILD),SI_ACCESS_SPECIFIC },
  84. { &GUID_NULL, DELETE, MAKEINTRESOURCE(IDS_STD_DELETE), SI_ACCESS_SPECIFIC },
  85. { &GUID_NULL, READ_CONTROL, MAKEINTRESOURCE(IDS_STD_READ_CONTROL), SI_ACCESS_SPECIFIC },
  86. { &GUID_NULL, WRITE_DAC, MAKEINTRESOURCE(IDS_STD_WRITE_DAC), SI_ACCESS_SPECIFIC },
  87. { &GUID_NULL, WRITE_OWNER, MAKEINTRESOURCE(IDS_STD_WRITE_OWNER), SI_ACCESS_SPECIFIC },
  88. // { &GUID_NULL, SYNCHRONIZE, MAKEINTRESOURCE(IDS_STD_SYNCHRONIZE), SI_ACCESS_SPECIFIC },
  89. { &GUID_NULL, 0, MAKEINTRESOURCE(IDS_NONE), 0 },
  90. { &GUID_NULL, FILE_GENERIC_EXECUTE_, MAKEINTRESOURCE(IDS_FILE_GENERIC_EXECUTE), 0 },
  91. { &GUID_NULL, FILE_GENERAL_DEPOSIT, MAKEINTRESOURCE(IDS_FILE_GENERAL_DEPOSIT), 0 },
  92. { &GUID_NULL, FILE_GENERAL_PUBLISH, MAKEINTRESOURCE(IDS_FILE_GENERAL_PUBLISH), 0 },
  93. };
  94. //
  95. // define all access rights for keys on general page and/or specific page
  96. //
  97. static SI_ACCESS siKeyAccesses[] =
  98. {
  99. { &GUID_NULL, KEY_ALL_ACCESS, MAKEINTRESOURCE(IDS_KEY_ALL_ACCESS), SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC | CONTAINER_INHERIT_ACE},
  100. { &GUID_NULL, KEY_READ, MAKEINTRESOURCE(IDS_KEY_READ), SI_ACCESS_GENERAL | CONTAINER_INHERIT_ACE},
  101. { &GUID_NULL, KEY_QUERY_VALUE, MAKEINTRESOURCE(IDS_KEY_QUERY_VALUE), SI_ACCESS_SPECIFIC},
  102. { &GUID_NULL, KEY_SET_VALUE, MAKEINTRESOURCE(IDS_KEY_SET_VALUE), SI_ACCESS_SPECIFIC},
  103. { &GUID_NULL, KEY_CREATE_SUB_KEY, MAKEINTRESOURCE(IDS_KEY_CREATE_SUB_KEY), SI_ACCESS_SPECIFIC},
  104. { &GUID_NULL, KEY_ENUMERATE_SUB_KEYS,MAKEINTRESOURCE(IDS_KEY_ENUMERATE_SUB_KEYS),SI_ACCESS_SPECIFIC},
  105. { &GUID_NULL, KEY_NOTIFY, MAKEINTRESOURCE(IDS_KEY_NOTIFY), SI_ACCESS_SPECIFIC},
  106. { &GUID_NULL, KEY_CREATE_LINK, MAKEINTRESOURCE(IDS_KEY_CREATE_LINK), SI_ACCESS_SPECIFIC},
  107. { &GUID_NULL, DELETE, MAKEINTRESOURCE(IDS_STD_DELETE), SI_ACCESS_SPECIFIC | CONTAINER_INHERIT_ACE},
  108. { &GUID_NULL, READ_CONTROL, MAKEINTRESOURCE(IDS_STD_READ_CONTROL), SI_ACCESS_SPECIFIC },
  109. { &GUID_NULL, WRITE_DAC, MAKEINTRESOURCE(IDS_STD_WRITE_DAC), SI_ACCESS_SPECIFIC },
  110. { &GUID_NULL, WRITE_OWNER, MAKEINTRESOURCE(IDS_STD_WRITE_OWNER), SI_ACCESS_SPECIFIC },
  111. { &GUID_NULL, 0, MAKEINTRESOURCE(IDS_NONE), 0}
  112. };
  113. //
  114. // define generic mapping for files
  115. // This is consistent with the NETUI code
  116. //
  117. static GENERIC_MAPPING FileMap =
  118. {
  119. FILE_GENERIC_READ_,
  120. FILE_GENERIC_WRITE_,
  121. FILE_GENERIC_EXECUTE_,
  122. FILE_GENERIC_ALL_
  123. };
  124. //
  125. // define generic mapping for keys
  126. //
  127. static GENERIC_MAPPING KeyMap =
  128. {
  129. // STANDARD_RIGHTS_READ | 0x1,
  130. // STANDARD_RIGHTS_WRITE | 0x2,
  131. // STANDARD_RIGHTS_EXECUTE | 0x4,
  132. // STANDARD_RIGHTS_REQUIRED | 0x7F
  133. KEY_READ,
  134. KEY_WRITE,
  135. KEY_EXECUTE,
  136. KEY_ALL_ACCESS
  137. };
  138. //
  139. // The following array defines the inheritance types for NTFS.
  140. //
  141. static SI_INHERIT_TYPE siFileInheritTypes[] =
  142. {
  143. &GUID_NULL, 0, MAKEINTRESOURCE(IDS_FILE_FOLDER),
  144. &GUID_NULL, CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE, MAKEINTRESOURCE(IDS_FILE_FOLDER_SUBITEMS),
  145. &GUID_NULL, CONTAINER_INHERIT_ACE, MAKEINTRESOURCE(IDS_FILE_FOLDER_SUBFOLDER),
  146. &GUID_NULL, OBJECT_INHERIT_ACE, MAKEINTRESOURCE(IDS_FILE_FOLDER_FILE),
  147. &GUID_NULL, INHERIT_ONLY_ACE | CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE, MAKEINTRESOURCE(IDS_FILE_SUBITEMS_ONLY),
  148. &GUID_NULL, INHERIT_ONLY_ACE | CONTAINER_INHERIT_ACE, MAKEINTRESOURCE(IDS_FILE_SUBFOLDER_ONLY),
  149. &GUID_NULL, INHERIT_ONLY_ACE | OBJECT_INHERIT_ACE, MAKEINTRESOURCE(IDS_FILE_FILE_ONLY)
  150. };
  151. //
  152. // The following array defines the inheritance types for Registry.
  153. //
  154. //
  155. // For Keys, objects and containers are the same, so no need for OBJECT_INHERIT_ACE
  156. //
  157. static SI_INHERIT_TYPE siKeyInheritTypes[] =
  158. {
  159. &GUID_NULL, 0, MAKEINTRESOURCE(IDS_KEY_FOLDER),
  160. // &GUID_NULL, CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE, MAKEINTRESOURCE(IDS_KEY_FOLDER_SUBITEMS),
  161. &GUID_NULL, CONTAINER_INHERIT_ACE, MAKEINTRESOURCE(IDS_KEY_FOLDER_SUBFOLDER),
  162. // &GUID_NULL, INHERIT_ONLY_ACE | CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE, MAKEINTRESOURCE(IDS_KEY_SUBITEMS_ONLY),
  163. &GUID_NULL, INHERIT_ONLY_ACE | CONTAINER_INHERIT_ACE, MAKEINTRESOURCE(IDS_KEY_SUBFOLDER_ONLY)
  164. };
  165. //
  166. // constants for services
  167. //
  168. #define SERVICE_GENERIC_READ (STANDARD_RIGHTS_READ |\
  169. SERVICE_QUERY_CONFIG |\
  170. SERVICE_QUERY_STATUS |\
  171. SERVICE_ENUMERATE_DEPENDENTS |\
  172. SERVICE_INTERROGATE |\
  173. SERVICE_USER_DEFINED_CONTROL)
  174. #define SERVICE_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE |\
  175. SERVICE_START |\
  176. SERVICE_STOP |\
  177. SERVICE_PAUSE_CONTINUE)
  178. // SERVICE_INTERROGATE |\
  179. // SERVICE_USER_DEFINED_CONTROL)
  180. #define SERVICE_GENERIC_WRITE (STANDARD_RIGHTS_WRITE |\
  181. SERVICE_CHANGE_CONFIG )
  182. //
  183. // access rights for services
  184. //
  185. static SI_ACCESS siServiceAccesses[] =
  186. {
  187. { &GUID_NULL, SERVICE_ALL_ACCESS, MAKEINTRESOURCE(IDS_SERVICE_ALL), SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC },
  188. { &GUID_NULL, SERVICE_GENERIC_READ, MAKEINTRESOURCE(IDS_SERVICE_READ), SI_ACCESS_GENERAL },
  189. { &GUID_NULL, SERVICE_GENERIC_EXECUTE, MAKEINTRESOURCE(IDS_SERVICE_EXECUTE), SI_ACCESS_GENERAL },
  190. { &GUID_NULL, SERVICE_GENERIC_WRITE, MAKEINTRESOURCE(IDS_SERVICE_WRITE), SI_ACCESS_GENERAL },
  191. { &GUID_NULL, SERVICE_QUERY_CONFIG, MAKEINTRESOURCE(IDS_SERVICE_QUERY_CONFIG), SI_ACCESS_SPECIFIC },
  192. { &GUID_NULL, SERVICE_CHANGE_CONFIG, MAKEINTRESOURCE(IDS_SERVICE_CHANGE_CONFIG),SI_ACCESS_SPECIFIC },
  193. { &GUID_NULL, SERVICE_QUERY_STATUS, MAKEINTRESOURCE(IDS_SERVICE_QUERY_STATUS), SI_ACCESS_SPECIFIC },
  194. { &GUID_NULL, SERVICE_ENUMERATE_DEPENDENTS,MAKEINTRESOURCE(IDS_SERVICE_ENUMERATE), SI_ACCESS_SPECIFIC },
  195. { &GUID_NULL, SERVICE_START, MAKEINTRESOURCE(IDS_SERVICE_START), SI_ACCESS_SPECIFIC },
  196. { &GUID_NULL, SERVICE_STOP, MAKEINTRESOURCE(IDS_SERVICE_STOP), SI_ACCESS_SPECIFIC },
  197. { &GUID_NULL, SERVICE_PAUSE_CONTINUE, MAKEINTRESOURCE(IDS_SERVICE_PAUSE), SI_ACCESS_SPECIFIC },
  198. { &GUID_NULL, SERVICE_INTERROGATE, MAKEINTRESOURCE(IDS_SERVICE_INTERROGATE), SI_ACCESS_SPECIFIC },
  199. { &GUID_NULL, SERVICE_USER_DEFINED_CONTROL,MAKEINTRESOURCE(IDS_SERVICE_USER_CONTROL),SI_ACCESS_SPECIFIC },
  200. { &GUID_NULL, DELETE, MAKEINTRESOURCE(IDS_STD_DELETE), SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC },
  201. { &GUID_NULL, READ_CONTROL, MAKEINTRESOURCE(IDS_STD_READ_CONTROL), SI_ACCESS_SPECIFIC },
  202. { &GUID_NULL, WRITE_DAC, MAKEINTRESOURCE(IDS_STD_WRITE_DAC), SI_ACCESS_SPECIFIC },
  203. { &GUID_NULL, WRITE_OWNER, MAKEINTRESOURCE(IDS_STD_WRITE_OWNER), SI_ACCESS_SPECIFIC },
  204. { &GUID_NULL, 0, MAKEINTRESOURCE(IDS_NONE), 0 },
  205. };
  206. #define iServiceDefAccess 2 // SERVICE_GEN_EXECUTE
  207. //
  208. // generic mapping for services
  209. //
  210. static GENERIC_MAPPING ServiceMap =
  211. {
  212. SERVICE_GENERIC_READ,
  213. SERVICE_GENERIC_WRITE,
  214. SERVICE_GENERIC_EXECUTE,
  215. SERVICE_ALL_ACCESS
  216. };
  217. /*
  218. // No need to define inherit type for service because there is no subfolders/items
  219. #define DS_ACC_READ (STANDARD_RIGHTS_READ |\
  220. ACTRL_DS_LIST |\
  221. ACTRL_DS_READ_PROP )
  222. #define DS_ACC_WRITE (STANDARD_RIGHTS_WRITE |\
  223. ACTRL_DS_WRITE_PROP |\
  224. ACTRL_DS_SELF)
  225. #define DS_ACC_EXECUTE (STANDARD_RIGHTS_EXECUTE |\
  226. ACTRL_DS_LIST )
  227. // generic all
  228. #define DS_ACC_ALL ((STANDARD_RIGHTS_REQUIRED) |\
  229. (ACTRL_DS_CREATE_CHILD) |\
  230. (ACTRL_DS_DELETE_CHILD) |\
  231. (ACTRL_DS_READ_PROP) |\
  232. (ACTRL_DS_WRITE_PROP) |\
  233. (ACTRL_DS_LIST) |\
  234. (ACTRL_DS_SELF))
  235. static SI_ACCESS siDsAccesses[] =
  236. {
  237. { &GUID_NULL, DS_ACC_ALL, MAKEINTRESOURCE(IDS_DS_ALL), SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC },
  238. { &GUID_NULL, DS_ACC_READ, MAKEINTRESOURCE(IDS_DS_READ), SI_ACCESS_GENERAL },
  239. { &GUID_NULL, DS_ACC_WRITE, MAKEINTRESOURCE(IDS_DS_WRITE), SI_ACCESS_GENERAL },
  240. { &GUID_NULL, ACTRL_DS_LIST, MAKEINTRESOURCE(IDS_DS_ACTRL_LIST), SI_ACCESS_SPECIFIC },
  241. { &GUID_NULL, ACTRL_DS_READ_PROP, MAKEINTRESOURCE(IDS_DS_ACTRL_READ_PROP), SI_ACCESS_SPECIFIC | SI_ACCESS_PROPERTY },
  242. { &GUID_NULL, ACTRL_DS_WRITE_PROP, MAKEINTRESOURCE(IDS_DS_ACTRL_WRITE_PROP), SI_ACCESS_SPECIFIC | SI_ACCESS_PROPERTY },
  243. { &GUID_A_NT_GROUP_MEMBERS,ACTRL_DS_SELF,MAKEINTRESOURCE(IDS_DS_ACTRL_SELF), SI_ACCESS_SPECIFIC },
  244. { &GUID_NULL, DELETE, MAKEINTRESOURCE(IDS_STD_DELETE), SI_ACCESS_SPECIFIC },
  245. { &GUID_NULL, READ_CONTROL, MAKEINTRESOURCE(IDS_STD_READ_CONTROL), SI_ACCESS_SPECIFIC },
  246. { &GUID_NULL, WRITE_DAC, MAKEINTRESOURCE(IDS_STD_WRITE_DAC), SI_ACCESS_SPECIFIC },
  247. { &GUID_NULL, WRITE_OWNER, MAKEINTRESOURCE(IDS_STD_WRITE_OWNER), SI_ACCESS_SPECIFIC },
  248. { &GUID_NULL, ACTRL_DS_CREATE_CHILD, MAKEINTRESOURCE(IDS_DS_ACTRL_CREATE), SI_ACCESS_CONTAINER | SI_ACCESS_SPECIFIC },
  249. { &GUID_NULL, ACTRL_DS_DELETE_CHILD, MAKEINTRESOURCE(IDS_DS_ACTRL_DELETE), SI_ACCESS_CONTAINER | SI_ACCESS_SPECIFIC },
  250. { &GUID_NULL, 0, MAKEINTRESOURCE(IDS_NONE), 0 },
  251. };
  252. #define iDsDefAccess 1 // DS_ACC_READ
  253. #define iDSProperties 4 // Read/Write properties
  254. //
  255. // Standard DS generic access rights mapping
  256. //
  257. static GENERIC_MAPPING DsMap =
  258. {
  259. DS_ACC_READ,
  260. DS_ACC_WRITE,
  261. DS_ACC_EXECUTE,
  262. DS_ACC_ALL
  263. };
  264. // The following array defines the inheritance types common to all DS containers.
  265. SI_INHERIT_TYPE siDsInheritTypes[] =
  266. {
  267. { &GUID_NULL, 0, MAKEINTRESOURCE(IDS_DS_FOLDER) },
  268. { &GUID_NULL, CONTAINER_INHERIT_ACE, MAKEINTRESOURCE(IDS_DS_FOLDER_SUBFOLDER) },
  269. { &GUID_NULL, CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE, MAKEINTRESOURCE(IDS_DS_SUBFOLDER_ONLY) },
  270. };
  271. */
  272. #ifndef ARRAYSIZE
  273. #define ARRAYSIZE(x) (sizeof(x)/sizeof(x[0]))
  274. #endif
  275. void CSecurityInfo::SetMachineName( LPCTSTR pszMachineName )
  276. {
  277. if ( pszMachineName == NULL )
  278. m_strMachineName.Empty();
  279. else
  280. m_strMachineName = pszMachineName;
  281. }
  282. STDMETHODIMP
  283. CSecurityInfo::GetAccessRights (
  284. IN const GUID* pguidObjectType,
  285. IN DWORD dwFlags,
  286. OUT PSI_ACCESS *ppAccess,
  287. OUT ULONG *pcAccesses,
  288. OUT ULONG *piDefaultAccess )
  289. /*
  290. Retrieve access rights array and the default element
  291. */
  292. {
  293. ASSERT(ppAccess != NULL);
  294. ASSERT(pcAccesses != NULL);
  295. ASSERT(piDefaultAccess != NULL);
  296. if ( ppAccess == NULL || pcAccesses == NULL || piDefaultAccess == NULL ) {
  297. return E_FAIL;
  298. }
  299. switch (m_SeType ) {
  300. case SE_FILE_OBJECT:
  301. *ppAccess = siFileAccesses;
  302. *pcAccesses = ARRAYSIZE(siFileAccesses);
  303. *piDefaultAccess = iFileDefAccess;
  304. break;
  305. case SE_REGISTRY_KEY:
  306. *ppAccess = siKeyAccesses;
  307. *pcAccesses = ARRAYSIZE(siKeyAccesses);
  308. *piDefaultAccess = iKeyDefAccess;
  309. break;
  310. case SE_SERVICE:
  311. *ppAccess = siServiceAccesses;
  312. *pcAccesses = ARRAYSIZE(siServiceAccesses);
  313. *piDefaultAccess = iServiceDefAccess;
  314. break;
  315. // case SE_DS_OBJECT:
  316. // *ppAccess = siDsAccesses;
  317. // *pcAccesses = ARRAYSIZE(siDsAccesses);
  318. // *piDefaultAccess = iDsDefAccess;
  319. break;
  320. }
  321. /*
  322. if (dwFlags & SI_EDIT_AUDITS) {
  323. } else {
  324. }
  325. */
  326. return S_OK;
  327. }
  328. STDMETHODIMP
  329. CSecurityInfo::MapGeneric (
  330. IN const GUID *pguidObjectType,
  331. OUT UCHAR *pAceFlags,
  332. OUT ACCESS_MASK *pMask)
  333. /*
  334. Map generic rights to specific rights based on object type
  335. */
  336. {
  337. ASSERT(pMask != NULL);
  338. if ( pMask == NULL ) {
  339. return E_FAIL;
  340. }
  341. switch(m_SeType) {
  342. case SE_FILE_OBJECT:
  343. MapGenericMask(pMask, &FileMap);
  344. *pMask = *pMask & (~SYNCHRONIZE); //Raid #340750, 4/12/2001
  345. break;
  346. case SE_REGISTRY_KEY:
  347. MapGenericMask(pMask, &KeyMap);
  348. break;
  349. case SE_SERVICE:
  350. MapGenericMask(pMask, &ServiceMap);
  351. break;
  352. // case SE_DS_OBJECT:
  353. // MapGenericMask(pMask, &DsMap);
  354. break;
  355. }
  356. return S_OK;
  357. }
  358. STDMETHODIMP
  359. CSecurityInfo::GetInheritTypes (
  360. OUT PSI_INHERIT_TYPE *ppInheritTypes,
  361. OUT ULONG *pcInheritTypes )
  362. /*
  363. Retrieve inherit type array based on the object type
  364. */
  365. {
  366. ASSERT(ppInheritTypes != NULL);
  367. ASSERT(pcInheritTypes != NULL);
  368. if ( !ppInheritTypes || !pcInheritTypes ) {
  369. return E_FAIL;
  370. }
  371. switch (m_SeType ) {
  372. case SE_FILE_OBJECT:
  373. *ppInheritTypes = siFileInheritTypes;
  374. *pcInheritTypes = ARRAYSIZE(siFileInheritTypes);
  375. break;
  376. case SE_REGISTRY_KEY:
  377. *ppInheritTypes = siKeyInheritTypes;
  378. *pcInheritTypes = ARRAYSIZE(siKeyInheritTypes);
  379. break;
  380. // case SE_DS_OBJECT:
  381. // *ppInheritTypes = siDsInheritTypes;
  382. // *pcInheritTypes = ARRAYSIZE(siDsInheritTypes);
  383. // break;
  384. case SE_SERVICE:
  385. *ppInheritTypes = NULL;
  386. *pcInheritTypes = NULL;
  387. break;
  388. }
  389. return S_OK;
  390. }
  391. STDMETHODIMP
  392. CSecurityInfo::PropertySheetPageCallback(
  393. HWND hwnd,
  394. UINT uMsg,
  395. SI_PAGE_TYPE uPage )
  396. {
  397. return S_OK;
  398. }
  399. /*
  400. JeffreyS 1/24/97:
  401. If you don't set the SI_RESET flag in
  402. ISecurityInformation::GetObjectInformation, then fDefault should never be TRUE
  403. so you can ignore it. Returning E_NOTIMPL in this case is OK too.
  404. If you want the user to be able to reset the ACL to some default state
  405. (defined by you) then turn on SI_RESET and return your default ACL
  406. when fDefault is TRUE. This happens if/when the user pushes a button
  407. that is only visible when SI_RESET is on.
  408. */
  409. STDMETHODIMP
  410. CSecurityInfo::GetObjectInformation (
  411. IN OUT PSI_OBJECT_INFO pObjectInfo )
  412. /*
  413. Retrieve information for the object to display
  414. */
  415. {
  416. ASSERT(pObjectInfo != NULL &&
  417. !IsBadWritePtr(pObjectInfo, sizeof(*pObjectInfo))); // Check the expression.
  418. if ( pObjectInfo == NULL || IsBadWritePtr(pObjectInfo, sizeof(*pObjectInfo))) { //Raid #550912, yanggao.
  419. return E_FAIL;
  420. }
  421. //
  422. // query the edit flag dwFlags
  423. //
  424. pObjectInfo->dwFlags = SI_ADVANCED;
  425. switch ( m_SeType ) {
  426. case SE_FILE_OBJECT:
  427. // if ( m_pData->GetID() &&
  428. // ((PSCE_OBJECT_SECURITY)(m_pData->GetID()))->IsContainer )
  429. // pObjectInfo->dwFlags |= SI_CONTAINER;
  430. if ( m_bIsContainer ) {
  431. pObjectInfo->dwFlags |= SI_CONTAINER;
  432. }
  433. break;
  434. case SE_SERVICE:
  435. break;
  436. default:
  437. pObjectInfo->dwFlags |= SI_CONTAINER;
  438. break;
  439. }
  440. switch ( m_flag ) {
  441. case SECURITY_PAGE_READ_ONLY:
  442. case ANALYSIS_SECURITY_PAGE_READ_ONLY:
  443. case CONFIG_SECURITY_PAGE_READ_ONLY:
  444. pObjectInfo->dwFlags |= SI_READONLY;
  445. break;
  446. case SECURITY_PAGE_RO_NP:
  447. case CONFIG_SECURITY_PAGE_RO_NP:
  448. case ANALYSIS_SECURITY_PAGE_RO_NP:
  449. pObjectInfo->dwFlags |= (SI_READONLY | SI_NO_ACL_PROTECT);
  450. break;
  451. case CONFIG_SECURITY_PAGE_NO_PROTECT:
  452. case ANALYSIS_SECURITY_PAGE_NO_PROTECT:
  453. case SECURITY_PAGE_NO_PROTECT:
  454. if ( SE_SERVICE == m_SeType ) {
  455. // pObjectInfo->dwFlags |= (SI_EDIT_PERMS | SI_NO_ACL_PROTECT );
  456. pObjectInfo->dwFlags |= (SI_EDIT_PERMS | SI_EDIT_AUDITS | SI_NO_ACL_PROTECT );
  457. } else {
  458. pObjectInfo->dwFlags |= (SI_EDIT_ALL | SI_NO_ACL_PROTECT);
  459. }
  460. break;
  461. default:
  462. if ( SE_SERVICE == m_SeType ) {
  463. pObjectInfo->dwFlags |= (SI_EDIT_PERMS | SI_EDIT_AUDITS );
  464. } else {
  465. pObjectInfo->dwFlags |= SI_EDIT_ALL;
  466. }
  467. }
  468. pObjectInfo->hInstance = m_hInstance;
  469. pObjectInfo->pszServerName = QueryMachineName();
  470. pObjectInfo->pszObjectName = QueryObjectName();
  471. return S_OK;
  472. }
  473. STDMETHODIMP
  474. CSecurityInfo::GetSecurity(
  475. IN SECURITY_INFORMATION RequestedInformation,
  476. OUT PSECURITY_DESCRIPTOR *ppSecurityDescriptor,
  477. IN BOOL fDefault )
  478. /*
  479. Retrieve security descriptor for the requested security information to display
  480. */
  481. {
  482. if (0 == RequestedInformation )
  483. {
  484. ASSERT(FALSE);
  485. return E_INVALIDARG;
  486. }
  487. if (fDefault)
  488. return E_NOTIMPL;
  489. if ( NULL == ppSecurityDescriptor )
  490. {
  491. ASSERT(FALSE);
  492. return E_INVALIDARG;
  493. }
  494. // should also check for SeInfo
  495. if ( m_ppSD != NULL && *m_ppSD != NULL )
  496. {
  497. // Added check for SECURITY_PAGE_RO_NP (read-only) because it was
  498. // preventing viewing of security information in RSOP
  499. if ( m_pSeInfo && SECURITY_PAGE_RO_NP != m_flag &&
  500. ( 0 == (RequestedInformation & (*m_pSeInfo)) ) )
  501. {
  502. *ppSecurityDescriptor = NULL;
  503. }
  504. else
  505. {
  506. if ( !IsValidSecurityDescriptor(*m_ppSD))
  507. {
  508. ASSERT(FALSE);
  509. return E_INVALIDARG;
  510. }
  511. MyMakeSelfRelativeSD(*m_ppSD,ppSecurityDescriptor);
  512. }
  513. }
  514. else
  515. {
  516. *ppSecurityDescriptor = NULL;
  517. }
  518. return S_OK;
  519. }
  520. void
  521. FixSynchronizeAccess(SECURITY_INFORMATION si, PSECURITY_DESCRIPTOR pSD)
  522. {
  523. if (NULL != pSD && 0 != (si & DACL_SECURITY_INFORMATION))
  524. {
  525. BOOL bPresent;
  526. BOOL bDefault;
  527. PACL pDacl = NULL;
  528. GetSecurityDescriptorDacl(pSD, &bPresent, &pDacl, &bDefault);
  529. if (pDacl)
  530. {
  531. PACE_HEADER pAce;
  532. int i;
  533. for (i = 0, pAce = (PACE_HEADER)FirstAce(pDacl);
  534. i < pDacl->AceCount;
  535. i++, pAce = (PACE_HEADER)NextAce(pAce))
  536. {
  537. if (ACCESS_ALLOWED_ACE_TYPE == pAce->AceType)
  538. ((PKNOWN_ACE)pAce)->Mask |= SYNCHRONIZE;
  539. }
  540. }
  541. }
  542. }
  543. STDMETHODIMP CSecurityInfo::SetSecurity (
  544. IN SECURITY_INFORMATION SecurityInformation,
  545. IN PSECURITY_DESCRIPTOR pSecurityDescriptor )
  546. /*
  547. Save security descriptor for the SecurityInformation to your own storage
  548. This method can be called multiple times for different security inforamtion.
  549. Since SCE is saving the final security descriptor (combined) in m_ppSD,
  550. this method must handle each component (Owner, Dacl, and Sacl) without overwritting
  551. other components.
  552. */
  553. {
  554. if ( pSecurityDescriptor == NULL || SecurityInformation == 0 )
  555. return S_OK;
  556. if ( m_flag == CONFIG_SECURITY_PAGE_READ_ONLY ||
  557. m_flag == ANALYSIS_SECURITY_PAGE_READ_ONLY ||
  558. m_flag == SECURITY_PAGE_READ_ONLY )
  559. return S_OK;
  560. if ( m_ppSD != NULL ) {
  561. //
  562. // only replace "SecurityInformation" part in m_ppSD
  563. //
  564. if ( m_pSeInfo && (SecurityInformation == *m_pSeInfo) ) {
  565. //
  566. // exactly same component
  567. //
  568. if ( *m_ppSD != NULL )
  569. LocalFree(*m_ppSD);
  570. MyMakeSelfRelativeSD(pSecurityDescriptor, m_ppSD);
  571. } else {
  572. SECURITY_INFORMATION TempSeInfo;
  573. SECURITY_DESCRIPTOR_CONTROL sdcControl = 0;
  574. if ( m_pSeInfo )
  575. TempSeInfo = (*m_pSeInfo) & ~SecurityInformation;
  576. else
  577. TempSeInfo = 0x0F & ~SecurityInformation;
  578. PSID pOwner=NULL, pOwnerNew=NULL;
  579. PACL pDacl=NULL, pDaclNew=NULL;
  580. PACL pSacl=NULL, pSaclNew=NULL;
  581. BOOL bDefault, bPresent;
  582. //
  583. // save the other components first
  584. //
  585. SECURITY_DESCRIPTOR_CONTROL sdc = 0;
  586. DWORD dwRevision = 0;
  587. if ( *m_ppSD ) {
  588. GetSecurityDescriptorControl( *m_ppSD, &sdc, &dwRevision );
  589. if ( TempSeInfo & OWNER_SECURITY_INFORMATION ) {
  590. bDefault = FALSE;
  591. if ( !GetSecurityDescriptorOwner (
  592. *m_ppSD,
  593. &pOwner,
  594. &bDefault
  595. ) || bDefault )
  596. pOwner = NULL;
  597. sdcControl |= (sdc & SE_OWNER_DEFAULTED);
  598. }
  599. if ( TempSeInfo & DACL_SECURITY_INFORMATION ) {
  600. bDefault = FALSE;
  601. bPresent = FALSE;
  602. if ( !GetSecurityDescriptorDacl (
  603. *m_ppSD,
  604. &bPresent,
  605. &pDacl,
  606. &bDefault
  607. ) || !bPresent || bDefault )
  608. pDacl = NULL;
  609. sdcControl |= (sdc & (SE_DACL_AUTO_INHERIT_REQ |
  610. SE_DACL_AUTO_INHERITED |
  611. SE_DACL_PROTECTED
  612. ));
  613. }
  614. if ( TempSeInfo & SACL_SECURITY_INFORMATION ) {
  615. bDefault = FALSE;
  616. bPresent = FALSE;
  617. if ( !GetSecurityDescriptorSacl (
  618. *m_ppSD,
  619. &bPresent,
  620. &pSacl,
  621. &bDefault
  622. ) || !bPresent || bDefault )
  623. pSacl = NULL;
  624. sdcControl |= (sdc & (SE_SACL_AUTO_INHERIT_REQ |
  625. SE_SACL_AUTO_INHERITED |
  626. SE_SACL_PROTECTED
  627. ));
  628. }
  629. }
  630. //
  631. // check the new components
  632. //
  633. sdc = 0;
  634. dwRevision = 0;
  635. GetSecurityDescriptorControl( pSecurityDescriptor, &sdc, &dwRevision );
  636. if ( SecurityInformation & OWNER_SECURITY_INFORMATION ) {
  637. bDefault = FALSE;
  638. if ( !GetSecurityDescriptorOwner (
  639. pSecurityDescriptor,
  640. &pOwnerNew,
  641. &bDefault
  642. ) || bDefault )
  643. pOwnerNew = NULL;
  644. pOwner = pOwnerNew;
  645. sdcControl |= (sdc & SE_OWNER_DEFAULTED);
  646. }
  647. if ( SecurityInformation & DACL_SECURITY_INFORMATION ) {
  648. bDefault = FALSE;
  649. bPresent = FALSE;
  650. if ( !GetSecurityDescriptorDacl (
  651. pSecurityDescriptor,
  652. &bPresent,
  653. &pDaclNew,
  654. &bDefault
  655. ) || !bPresent || bDefault )
  656. pDaclNew = NULL;
  657. pDacl = pDaclNew;
  658. sdcControl |= (sdc & (SE_DACL_AUTO_INHERIT_REQ |
  659. SE_DACL_AUTO_INHERITED |
  660. SE_DACL_PROTECTED
  661. ));
  662. }
  663. if ( SecurityInformation & SACL_SECURITY_INFORMATION ) {
  664. bDefault = FALSE;
  665. bPresent = FALSE;
  666. if ( !GetSecurityDescriptorSacl (
  667. pSecurityDescriptor,
  668. &bPresent,
  669. &pSaclNew,
  670. &bDefault
  671. ) || !bPresent || bDefault )
  672. pSaclNew = NULL;
  673. pSacl = pSaclNew;
  674. sdcControl |= (sdc & (SE_SACL_AUTO_INHERIT_REQ |
  675. SE_SACL_AUTO_INHERITED |
  676. SE_SACL_PROTECTED
  677. ));
  678. }
  679. if ( m_pSeInfo )
  680. *m_pSeInfo |= SecurityInformation;
  681. //
  682. // build a temp security descriptor
  683. //
  684. SECURITY_DESCRIPTOR sd;
  685. //This is a safe usage.
  686. InitializeSecurityDescriptor (&sd, SECURITY_DESCRIPTOR_REVISION);
  687. //This is a safe usage.
  688. if ( pOwner )
  689. SetSecurityDescriptorOwner (&sd, pOwner, FALSE);
  690. //This is a safe usage.
  691. if ( pDacl )
  692. SetSecurityDescriptorDacl (&sd, TRUE, pDacl, FALSE);
  693. //This is a safe usage.
  694. if ( pSacl )
  695. SetSecurityDescriptorSacl (&sd, TRUE, pSacl, FALSE);
  696. sd.Control |= sdcControl;
  697. //
  698. // re-create the final security descriptor
  699. //
  700. PSECURITY_DESCRIPTOR pTempSD=NULL;
  701. MyMakeSelfRelativeSD(&sd, &pTempSD);
  702. //
  703. // must free this after pTempSD is made, because sd is in absolute format
  704. //
  705. if ( *m_ppSD != NULL )
  706. LocalFree(*m_ppSD);
  707. *m_ppSD = pTempSD;
  708. }
  709. //Treat Synchronize Specially
  710. if( m_SeType == SE_FILE_OBJECT )
  711. {
  712. FixSynchronizeAccess(SecurityInformation,*m_ppSD);
  713. }
  714. } else {
  715. return E_INVALIDARG;
  716. }
  717. return S_OK;
  718. }
  719. //
  720. // original code from \\marsslm\backup\src\ncpmgr\ncpmgr\shareacl.cxx
  721. // ACL-wrangling templated from \net\ui\common\src\lmobj\lmobj\security.cxx
  722. //
  723. // caller must free using "release"
  724. //
  725. HRESULT CSecurityInfo::NewDefaultDescriptor(
  726. PSECURITY_DESCRIPTOR* ppsd,
  727. SECURITY_INFORMATION RequestedInformation
  728. )
  729. {
  730. *ppsd = NULL;
  731. PSID psidWorld = NULL;
  732. PSID psidAdmins = NULL;
  733. ACCESS_ALLOWED_ACE* pace = NULL;
  734. ACL* pacl = NULL;
  735. SECURITY_DESCRIPTOR sd;
  736. HRESULT hr = S_OK;
  737. do { // false loop
  738. // build World SID
  739. SID_IDENTIFIER_AUTHORITY IDAuthorityWorld = SECURITY_WORLD_SID_AUTHORITY;
  740. if ( !::AllocateAndInitializeSid(
  741. &IDAuthorityWorld,
  742. 1,
  743. SECURITY_WORLD_RID,
  744. 0,0,0,0,0,0,0,
  745. &psidWorld ) )
  746. {
  747. ASSERT( FALSE );
  748. break;
  749. }
  750. // build Admins SID
  751. SID_IDENTIFIER_AUTHORITY IDAuthorityNT = SECURITY_NT_AUTHORITY;
  752. if ( !::AllocateAndInitializeSid(
  753. &IDAuthorityNT,
  754. 2,
  755. SECURITY_BUILTIN_DOMAIN_RID,
  756. DOMAIN_ALIAS_RID_ADMINS,
  757. 0,0,0,0,0,0,
  758. &psidAdmins ) )
  759. {
  760. ASSERT( FALSE );
  761. break;
  762. }
  763. // build ACE
  764. DWORD cbSid = ::GetLengthSid(psidWorld);
  765. if ( 0 == cbSid )
  766. {
  767. ASSERT( FALSE );
  768. hr = E_UNEXPECTED;
  769. break;
  770. }
  771. INT cbAce = sizeof(ACCESS_ALLOWED_ACE) + cbSid;
  772. pace = reinterpret_cast<ACCESS_ALLOWED_ACE*>(new BYTE[ cbAce+10 ]);
  773. if ( pace ) {
  774. ::memset((BYTE*)pace,0,cbAce+10);
  775. pace->Header.AceType = ACCESS_ALLOWED_ACE_TYPE; // SetType()
  776. pace->Header.AceFlags = 0; // SetInheritFlags()
  777. pace->Header.AceSize = (WORD)cbAce; // SetSize() (in SetSID())
  778. pace->Mask = GENERIC_ALL; // SetAccessMask()
  779. //This is a safe usage.
  780. ::memcpy( &(pace->SidStart), psidWorld, cbSid ); // SetSID()
  781. } else {
  782. ASSERT ( FALSE );
  783. hr = E_OUTOFMEMORY;
  784. break;
  785. }
  786. // build ACL
  787. DWORD cbAcl = sizeof(ACL) + cbAce + 10;
  788. pacl = reinterpret_cast<ACL*>(new BYTE[ cbAcl ]);
  789. if ( pacl ) {
  790. //This is a safe usage. yanggao.
  791. ::memset((BYTE*)pacl,0,cbAcl);
  792. if ( !::InitializeAcl( pacl, cbAcl, ACL_REVISION2 ) )
  793. {
  794. ASSERT( FALSE );
  795. hr = E_UNEXPECTED;
  796. break;
  797. }
  798. if ( !::AddAce( pacl, ACL_REVISION2, 0, pace, cbAce ) )
  799. {
  800. ASSERT( FALSE );
  801. hr = E_UNEXPECTED;
  802. break;
  803. }
  804. // build security descriptor in absolute format
  805. if ( !::InitializeSecurityDescriptor(
  806. &sd,
  807. SECURITY_DESCRIPTOR_REVISION ) )
  808. {
  809. ASSERT( FALSE );
  810. hr = E_UNEXPECTED;
  811. break;
  812. }
  813. if ( !::SetSecurityDescriptorOwner( &sd, psidAdmins, FALSE )
  814. || !::SetSecurityDescriptorGroup( &sd, psidAdmins, FALSE )
  815. || !::SetSecurityDescriptorDacl( &sd, TRUE, pacl, FALSE )
  816. )
  817. {
  818. ASSERT( FALSE );
  819. hr = E_UNEXPECTED;
  820. break;
  821. }
  822. // convert security descriptor to self-relative format
  823. DWORD cbSD = 0;
  824. // this call should fail and set cbSD to the correct size
  825. if ( ::MakeSelfRelativeSD( &sd, NULL, &cbSD ) || 0 == cbSD )
  826. {
  827. ASSERT( FALSE );
  828. hr = E_UNEXPECTED;
  829. break;
  830. }
  831. *ppsd = reinterpret_cast<PSECURITY_DESCRIPTOR>(new BYTE[ cbSD + 20 ]);
  832. if ( *ppsd ) {
  833. //This is a safe usage. yanggao.
  834. ::memset( (BYTE*)*ppsd, 0, cbSD + 20 );
  835. if ( !::MakeSelfRelativeSD( &sd, *ppsd, &cbSD ) )
  836. {
  837. ASSERT( FALSE );
  838. hr = E_UNEXPECTED;
  839. break;
  840. }
  841. } else {
  842. ASSERT ( FALSE );
  843. hr = E_OUTOFMEMORY;
  844. break;
  845. }
  846. } else {
  847. ASSERT ( FALSE );
  848. hr = E_OUTOFMEMORY;
  849. break;
  850. }
  851. } while (FALSE); // false loop
  852. // clean up
  853. if ( NULL != psidWorld ) {
  854. (void)::FreeSid( psidWorld );
  855. }
  856. if ( NULL != psidAdmins ) {
  857. (void)::FreeSid( psidAdmins );
  858. }
  859. if ( pace )
  860. delete []pace;//Raid #Prefast
  861. if ( pacl )
  862. delete []pacl;//Raid #Prefast
  863. if ( FAILED(hr) && *ppsd ) {
  864. delete *ppsd;
  865. *ppsd = NULL;
  866. }
  867. return hr;
  868. }
  869. void CSecurityInfo::Initialize(BOOL bIsContainer, //CResult *pData,
  870. PSECURITY_DESCRIPTOR *ppSeDescriptor,
  871. SECURITY_INFORMATION *pSeInfo,
  872. int flag)
  873. {
  874. // m_pData = pData;
  875. m_bIsContainer = bIsContainer;
  876. m_ppSD = ppSeDescriptor;
  877. m_pSeInfo = pSeInfo;
  878. m_flag = flag;
  879. }
  880. STDMETHODIMP CDsSecInfo::GetSecurity(
  881. SECURITY_INFORMATION RequestedInformation,
  882. PSECURITY_DESCRIPTOR *ppSecurityDescriptor,
  883. BOOL fDefault )
  884. {
  885. if ( NULL == ppSecurityDescriptor ) {
  886. ASSERT(FALSE);
  887. return E_INVALIDARG;
  888. }
  889. *ppSecurityDescriptor = NULL;
  890. if (0 == RequestedInformation ) {
  891. ASSERT(FALSE);
  892. return E_INVALIDARG;
  893. }
  894. if (fDefault)
  895. return E_NOTIMPL;
  896. HRESULT hr = S_OK;
  897. if ( m_ppSD != NULL && *m_ppSD != NULL ) {
  898. if ( !IsValidSecurityDescriptor(*m_ppSD)) {
  899. ASSERT(FALSE);
  900. hr = E_INVALIDARG;
  901. }
  902. else
  903. hr = MyMakeSelfRelativeSD(*m_ppSD,ppSecurityDescriptor);
  904. } else {
  905. hr = E_UNEXPECTED;
  906. }
  907. return hr;
  908. }
  909. STDMETHODIMP CDsSecInfo::SetSecurity (
  910. SECURITY_INFORMATION SecurityInformation,
  911. PSECURITY_DESCRIPTOR pSecurityDescriptor )
  912. {
  913. if ( pSecurityDescriptor == NULL || SecurityInformation == 0 )
  914. return S_OK;
  915. if ( m_flag == CONFIG_SECURITY_PAGE_READ_ONLY ||
  916. m_flag == ANALYSIS_SECURITY_PAGE_READ_ONLY ||
  917. m_flag == SECURITY_PAGE_READ_ONLY )
  918. return S_OK;
  919. HRESULT hr = S_OK;
  920. if ( m_ppSD != NULL ) {
  921. if ( *m_ppSD != NULL )
  922. LocalFree(*m_ppSD);
  923. hr = MyMakeSelfRelativeSD(pSecurityDescriptor, m_ppSD);
  924. if (SUCCEEDED(hr) && m_pSeInfo )
  925. *m_pSeInfo = SecurityInformation;
  926. } else {
  927. hr = E_INVALIDARG;
  928. }
  929. return hr;
  930. }
  931. HRESULT CDsSecInfo::Initialize(
  932. LPTSTR LdapName,
  933. PFNDSCREATEISECINFO pfnCreateDsPage,
  934. PSECURITY_DESCRIPTOR *ppSeDescriptor,
  935. SECURITY_INFORMATION *pSeInfo,
  936. int flag)
  937. {
  938. if ( !LdapName || !pfnCreateDsPage ) {
  939. return E_INVALIDARG;
  940. }
  941. m_ppSD = ppSeDescriptor;
  942. m_pSeInfo = pSeInfo;
  943. m_flag = flag;
  944. BOOL bReadOnly;
  945. switch (flag ) {
  946. case SECURITY_PAGE_RO_NP:
  947. case SECURITY_PAGE_READ_ONLY:
  948. case CONFIG_SECURITY_PAGE_READ_ONLY:
  949. case CONFIG_SECURITY_PAGE_RO_NP:
  950. case ANALYSIS_SECURITY_PAGE_READ_ONLY:
  951. case ANALYSIS_SECURITY_PAGE_RO_NP:
  952. bReadOnly = TRUE;
  953. break;
  954. default:
  955. bReadOnly = FALSE;
  956. break;
  957. }
  958. HRESULT hr=(*pfnCreateDsPage)(
  959. LdapName, //ObjectName,
  960. NULL,
  961. bReadOnly,
  962. &m_pISecInfo,
  963. NULL,
  964. NULL,
  965. 0);
  966. return hr;
  967. }
  968. //-----------------------------------------------------------------------
  969. // this function creates a SCE editor property page. If a modeless
  970. // property sheet is desired, make sure that the creation code originates
  971. // from your own thread. Search for usage of the function for sample.
  972. //-----------------------------------------------------------------------
  973. INT_PTR
  974. MyCreateSecurityPage2(BOOL bIsContainer, //CResult *pData,
  975. PSECURITY_DESCRIPTOR *ppSeDescriptor,
  976. SECURITY_INFORMATION *pSeInfo,
  977. LPCTSTR ObjectName,
  978. SE_OBJECT_TYPE SeType,
  979. int flag,
  980. HWND hwndParent,
  981. BOOL bModeless)
  982. {
  983. INT_PTR nRet=-1;
  984. HRESULT hr;
  985. if (!g_hAclUiDll) {
  986. // This is a safe usage.
  987. g_hAclUiDll = LoadLibrary(TEXT("aclui.dll"));
  988. }
  989. if (!*ppSeDescriptor) {
  990. DWORD SDSize;
  991. if (SE_REGISTRY_KEY == SeType) {
  992. hr = GetDefaultRegKeySecurity(ppSeDescriptor,pSeInfo);
  993. } else {
  994. hr = GetDefaultFileSecurity(ppSeDescriptor,pSeInfo);
  995. }
  996. if (FAILED(hr)) // if access denied, return the invalid handle
  997. return nRet;
  998. }
  999. PFNCSECPAGE pfnCSecPage=NULL;
  1000. if ( g_hAclUiDll) {
  1001. pfnCSecPage = (PFNCSECPAGE)GetProcAddress(g_hAclUiDll,
  1002. "CreateSecurityPage");
  1003. if ( pfnCSecPage ) {
  1004. CComObject<CSecurityInfo>* psi = NULL;
  1005. HPROPSHEETPAGE hPage=NULL;
  1006. hr = CComObject<CSecurityInfo>::CreateInstance(&psi);
  1007. if ( SUCCEEDED(hr) ) {
  1008. psi->AddRef();
  1009. psi->SetMachineName( NULL );
  1010. psi->SetObjectName( ObjectName );
  1011. psi->SetTypeInstance(SeType, AfxGetInstanceHandle() );
  1012. psi->Initialize(bIsContainer, ppSeDescriptor, pSeInfo, flag);
  1013. psi->AddRef();
  1014. hPage = (*pfnCSecPage)((LPSECURITYINFO)psi); // in aclui.h. Raid #prefast
  1015. psi->Release();
  1016. if ( hPage ) {
  1017. // display this one
  1018. PROPSHEETHEADER psh;
  1019. HPROPSHEETPAGE hpsp[1];
  1020. hpsp[0] = hPage;
  1021. ZeroMemory(&psh,sizeof(psh));
  1022. psh.dwSize = sizeof(psh);
  1023. psh.dwFlags = PSH_DEFAULT;
  1024. if (bModeless) {
  1025. psh.dwFlags |= PSH_MODELESS;
  1026. }
  1027. psh.nPages = 1;
  1028. psh.phpage = hpsp;
  1029. CString str=_T("");
  1030. switch (flag) {
  1031. case CONFIG_SECURITY_PAGE_READ_ONLY:
  1032. case CONFIG_SECURITY_PAGE_NO_PROTECT:
  1033. case CONFIG_SECURITY_PAGE:
  1034. case CONFIG_SECURITY_PAGE_RO_NP:
  1035. str.LoadString(IDS_CONFIG_SECURITY_PAGE);
  1036. break;
  1037. case ANALYSIS_SECURITY_PAGE_READ_ONLY:
  1038. case ANALYSIS_SECURITY_PAGE_NO_PROTECT:
  1039. case ANALYSIS_SECURITY_PAGE:
  1040. case ANALYSIS_SECURITY_PAGE_RO_NP:
  1041. str.LoadString(IDS_ANALYSIS_SECURITY_PAGE);
  1042. break;
  1043. default:
  1044. str.LoadString(IDS_SECURITY_PAGE);
  1045. break;
  1046. }
  1047. str+= ObjectName;
  1048. psh.pszCaption = (LPCTSTR)str;
  1049. psh.hwndParent = hwndParent;
  1050. if (bModeless) {
  1051. nRet = PropertySheet(&psh);
  1052. } else {
  1053. nRet = PropertySheet(&psh);
  1054. if (-1 == nRet) {
  1055. ErrorHandler();
  1056. }
  1057. }
  1058. }
  1059. psi->Release();
  1060. }
  1061. }
  1062. }
  1063. return nRet;
  1064. }
  1065. INT_PTR
  1066. MyCreateDsSecurityPage(
  1067. LPDSSECINFO *ppSI,
  1068. PFNDSCREATEISECINFO pfnCreateDsPage,
  1069. PSECURITY_DESCRIPTOR *ppSeDescriptor,
  1070. SECURITY_INFORMATION *pSeInfo,
  1071. LPCTSTR ObjectName,
  1072. int flag,
  1073. HWND hwndParent)
  1074. {
  1075. if ( !ObjectName || !ppSeDescriptor || !pfnCreateDsPage || !ppSI ) {
  1076. // invalid parameter
  1077. return -1;
  1078. }
  1079. INT_PTR nRet=-1;
  1080. if (!g_hAclUiDll)
  1081. //This is a safe usage.
  1082. g_hAclUiDll = LoadLibrary(TEXT("aclui.dll"));
  1083. PFNCSECPAGE pfnCSecPage=NULL;
  1084. if ( g_hAclUiDll) {
  1085. pfnCSecPage = (PFNCSECPAGE)GetProcAddress(g_hAclUiDll,
  1086. "CreateSecurityPage");
  1087. if ( pfnCSecPage ) {
  1088. //
  1089. // get the address of CreateSecurityPage
  1090. //
  1091. HRESULT hr=S_OK;
  1092. LPTSTR LdapName=NULL;
  1093. if ( NULL == *ppSI ) {
  1094. DWORD nLen = 8+wcslen(ObjectName);
  1095. LdapName = (LPTSTR)LocalAlloc(0, nLen*sizeof(WCHAR));
  1096. if ( LdapName ) {
  1097. //This is a safe usage.
  1098. swprintf(LdapName, L"LDAP://%s", ObjectName);
  1099. } else
  1100. return -1;
  1101. hr = CComObject<CDsSecInfo>::CreateInstance((CComObject<CDsSecInfo>**)ppSI);
  1102. if ( SUCCEEDED(hr) ) {
  1103. (*ppSI)->AddRef();
  1104. hr = (*ppSI)->Initialize(LdapName, pfnCreateDsPage, ppSeDescriptor, pSeInfo, flag);
  1105. }
  1106. }
  1107. if ( SUCCEEDED(hr) ) {
  1108. (*ppSI)->AddRef();
  1109. HPROPSHEETPAGE hPage = (*pfnCSecPage)((LPSECURITYINFO)(*ppSI)); // in aclui.h
  1110. (*ppSI)->Release();
  1111. if ( hPage ) {
  1112. // display this one
  1113. PROPSHEETHEADER psh;
  1114. HPROPSHEETPAGE hpsp[1];
  1115. hpsp[0] = hPage;
  1116. ZeroMemory(&psh,sizeof(psh));
  1117. psh.dwSize = sizeof(psh);
  1118. psh.dwFlags = PSH_DEFAULT;
  1119. psh.nPages = 1;
  1120. psh.phpage = hpsp;
  1121. CString str=_T("");
  1122. switch (flag) {
  1123. case CONFIG_SECURITY_PAGE_READ_ONLY:
  1124. case CONFIG_SECURITY_PAGE_NO_PROTECT:
  1125. case CONFIG_SECURITY_PAGE:
  1126. str.LoadString(IDS_CONFIG_SECURITY_PAGE);
  1127. break;
  1128. case ANALYSIS_SECURITY_PAGE_READ_ONLY:
  1129. case ANALYSIS_SECURITY_PAGE_NO_PROTECT:
  1130. case ANALYSIS_SECURITY_PAGE:
  1131. str.LoadString(IDS_ANALYSIS_SECURITY_PAGE);
  1132. break;
  1133. default:
  1134. str.LoadString(IDS_SECURITY_PAGE);
  1135. break;
  1136. }
  1137. str+= ObjectName;
  1138. psh.pszCaption = (LPCTSTR)str;
  1139. psh.hwndParent = hwndParent;
  1140. nRet = PropertySheet(&psh);
  1141. if (-1 == nRet) {
  1142. ErrorHandler();
  1143. }
  1144. } else
  1145. hr = E_FAIL;
  1146. }
  1147. if ( LdapName )
  1148. LocalFree(LdapName);
  1149. }
  1150. }
  1151. return nRet;
  1152. }