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.

576 lines
17 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1998-2002
  6. //
  7. // File: SecurityPropertyPage.cpp
  8. //
  9. //--------------------------------------------------------------------------
  10. /////////////////////////////////////////////////////////////////////
  11. // casec.cpp
  12. //
  13. // ISecurityInformation implementation for CA objects
  14. // and the new acl editor
  15. //
  16. // PURPOSE
  17. //
  18. //
  19. // DYNALOADED LIBRARIES
  20. //
  21. // HISTORY
  22. // 5-Nov-1998 petesk Copied template from privobsi.cpp sample.
  23. // 6-Mar-2000 bryanwal Modified to support cert templates
  24. //
  25. /////////////////////////////////////////////////////////////////////
  26. #include <stdafx.h>
  27. #include <accctrl.h>
  28. //#include <certca.h>
  29. #include <sddl.h>
  30. #include "CertTemplate.h"
  31. // Important, keep enroll GUID in sync with string define in certacl.h
  32. const GUID GUID_ENROLL = { /* 0e10c968-78fb-11d2-90d4-00c04f79dc55 */
  33. 0x0e10c968,
  34. 0x78fb,
  35. 0x11d2,
  36. {0x90, 0xd4, 0x00, 0xc0, 0x4f, 0x79, 0xdc, 0x55} };
  37. const GUID GUID_AUTOENROLL = { /* a05b8cc2-17bc-4802-a710-e7c15ab866a2 */
  38. 0xa05b8cc2,
  39. 0x17bc,
  40. 0x4802,
  41. {0xa7, 0x10, 0xe7, 0xc1, 0x5a, 0xb8, 0x66, 0xa2} };
  42. //
  43. // defined in Security.cpp
  44. //
  45. // // define our generic mapping structure for our private objects //
  46. #define INHERIT_FULL (CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE)
  47. #define ACTRL_CERTSRV_ENROLL (ACTRL_DS_CONTROL_ACCESS)
  48. #define ACTRL_CERTSRV_MANAGE (ACTRL_DS_READ_PROP | \
  49. ACTRL_DS_WRITE_PROP | \
  50. READ_CONTROL | \
  51. DELETE | \
  52. WRITE_DAC | \
  53. WRITE_OWNER | \
  54. ACTRL_DS_CONTROL_ACCESS | \
  55. ACTRL_DS_CREATE_CHILD | \
  56. ACTRL_DS_DELETE_CHILD | \
  57. ACTRL_DS_LIST | \
  58. ACTRL_DS_SELF | \
  59. ACTRL_DS_DELETE_TREE | \
  60. ACTRL_DS_LIST_OBJECT)
  61. #define ACTRL_CERTSRV_READ ( READ_CONTROL | \
  62. ACTRL_DS_READ_PROP | \
  63. ACTRL_DS_LIST )
  64. #define ACTRL_CERTSRV_WRITE ( WRITE_DAC | \
  65. WRITE_OWNER | \
  66. ACTRL_DS_WRITE_PROP )
  67. GENERIC_MAPPING ObjMap =
  68. {
  69. ACTRL_CERTSRV_READ,
  70. DELETE | WRITE_DAC | WRITE_OWNER | ACTRL_DS_WRITE_PROP,
  71. 0,
  72. ACTRL_CERTSRV_MANAGE
  73. };
  74. //
  75. // DESCRIPTION OF ACCESS FLAG AFFECTS
  76. //
  77. // SI_ACCESS_GENERAL shows up on general properties page
  78. // SI_ACCESS_SPECIFIC shows up on advanced page
  79. // SI_ACCESS_CONTAINER shows on general page IF object is a container
  80. //
  81. SI_ACCESS g_siV1ObjAccesses[] =
  82. {
  83. { &GUID_NULL,
  84. ACTRL_CERTSRV_MANAGE,
  85. MAKEINTRESOURCE(IDS_ACTRL_CERTSRV_MANAGE),
  86. SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC },
  87. { &GUID_NULL,
  88. ACTRL_CERTSRV_READ,
  89. MAKEINTRESOURCE(IDS_ACTRL_CERTSRV_READ),
  90. SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC },
  91. { &GUID_NULL,
  92. ACTRL_CERTSRV_WRITE,
  93. MAKEINTRESOURCE(IDS_ACTRL_CERTSRV_WRITE),
  94. SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC },
  95. { &GUID_ENROLL,
  96. ACTRL_CERTSRV_ENROLL,
  97. MAKEINTRESOURCE(IDS_ACTRL_ENROLL),
  98. SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC }
  99. };
  100. SI_ACCESS g_siV2ObjAccesses[] =
  101. {
  102. { &GUID_NULL,
  103. ACTRL_CERTSRV_MANAGE,
  104. MAKEINTRESOURCE(IDS_ACTRL_CERTSRV_MANAGE),
  105. SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC },
  106. { &GUID_NULL,
  107. ACTRL_CERTSRV_READ,
  108. MAKEINTRESOURCE(IDS_ACTRL_CERTSRV_READ),
  109. SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC },
  110. { &GUID_NULL,
  111. ACTRL_CERTSRV_WRITE,
  112. MAKEINTRESOURCE(IDS_ACTRL_CERTSRV_WRITE),
  113. SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC },
  114. { &GUID_ENROLL,
  115. ACTRL_CERTSRV_ENROLL,
  116. MAKEINTRESOURCE(IDS_ACTRL_ENROLL),
  117. SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC },
  118. { &GUID_AUTOENROLL,
  119. ACTRL_CERTSRV_ENROLL,
  120. MAKEINTRESOURCE(IDS_ACTRL_AUTOENROLL),
  121. SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC }
  122. };
  123. #define g_iObjDefAccess 1 // DS_GENERIC_READ
  124. // The following array defines the inheritance types for my containers.
  125. SI_INHERIT_TYPE g_siObjInheritTypes[] =
  126. {
  127. &GUID_NULL, 0, MAKEINTRESOURCE(IDS_INH_NONE),
  128. };
  129. class CCertTemplateSecurityObject : public ISecurityInformation
  130. {
  131. protected:
  132. ULONG m_cRef;
  133. CCertTemplate * m_pCertTemplate;
  134. PSECURITY_DESCRIPTOR m_pSD;
  135. public:
  136. CCertTemplateSecurityObject() : m_cRef(1),
  137. m_pCertTemplate (0),
  138. m_pSD (0)
  139. {
  140. }
  141. virtual ~CCertTemplateSecurityObject();
  142. STDMETHOD(Initialize)(CCertTemplate *pCertTemplate);
  143. // IUnknown methods
  144. STDMETHOD(QueryInterface)(REFIID, LPVOID *);
  145. STDMETHOD_(ULONG, AddRef)();
  146. STDMETHOD_(ULONG, Release)();
  147. // ISecurityInformation methods
  148. STDMETHOD(GetObjectInformation)(PSI_OBJECT_INFO pObjectInfo);
  149. STDMETHOD(GetSecurity)(SECURITY_INFORMATION si,
  150. PSECURITY_DESCRIPTOR *ppSD,
  151. BOOL fDefault);
  152. STDMETHOD(SetSecurity)(SECURITY_INFORMATION si,
  153. PSECURITY_DESCRIPTOR pSD);
  154. STDMETHOD(GetAccessRights)(const GUID* pguidObjectType,
  155. DWORD dwFlags,
  156. PSI_ACCESS *ppAccess,
  157. ULONG *pcAccesses,
  158. ULONG *piDefaultAccess);
  159. STDMETHOD(MapGeneric)(const GUID *pguidObjectType,
  160. UCHAR *pAceFlags,
  161. ACCESS_MASK *pmask);
  162. STDMETHOD(GetInheritTypes)(PSI_INHERIT_TYPE *ppInheritTypes,
  163. ULONG *pcInheritTypes);
  164. STDMETHOD(PropertySheetPageCallback)(HWND hwnd,
  165. UINT uMsg,
  166. SI_PAGE_TYPE uPage);
  167. };
  168. ///////////////////////////////////////////////////////////////////////////////
  169. //
  170. // This is the entry point function called from our code that establishes
  171. // what the ACLUI interface is going to need to know.
  172. //
  173. //
  174. ///////////////////////////////////////////////////////////////////////////////
  175. HRESULT CreateCertTemplateSecurityInfo (
  176. CCertTemplate *pCertTemplate,
  177. LPSECURITYINFO *ppObjSI)
  178. {
  179. _TRACE (1, L"Entering CreateCertTemplateSecurityInfo\n");
  180. ASSERT (pCertTemplate && ppObjSI);
  181. if ( !pCertTemplate || !ppObjSI )
  182. return E_POINTER;
  183. HRESULT hr = S_OK;
  184. CCertTemplateSecurityObject *psi = new CCertTemplateSecurityObject;
  185. if ( psi)
  186. {
  187. *ppObjSI = NULL;
  188. hr = psi->Initialize (pCertTemplate);
  189. if ( SUCCEEDED (hr) )
  190. *ppObjSI = psi;
  191. else
  192. delete psi;
  193. }
  194. else
  195. hr = E_OUTOFMEMORY;;
  196. _TRACE (-1, L"Leaving CreateCertTemplateSecurityInfo: 0x%x\n", hr);
  197. return hr;
  198. }
  199. CCertTemplateSecurityObject::~CCertTemplateSecurityObject()
  200. {
  201. if ( m_pSD )
  202. {
  203. LocalFree (m_pSD);
  204. }
  205. if ( m_pCertTemplate )
  206. m_pCertTemplate->Release ();
  207. }
  208. STDMETHODIMP
  209. CCertTemplateSecurityObject::Initialize(CCertTemplate *pCertTemplate)
  210. {
  211. _TRACE (1, L"Entering CCertTemplateSecurityObject::Initialize\n");
  212. HRESULT hr = S_OK;
  213. if ( pCertTemplate )
  214. {
  215. m_pCertTemplate = pCertTemplate;
  216. m_pCertTemplate->AddRef ();
  217. hr = pCertTemplate->GetSecurity (&m_pSD);
  218. }
  219. else
  220. hr = E_POINTER;
  221. _TRACE (-1, L"Leaving CCertTemplateSecurityObject::Initialize: 0x%x\n", hr);
  222. return hr;
  223. }
  224. ///////////////////////////////////////////////////////////
  225. //
  226. // IUnknown methods
  227. //
  228. ///////////////////////////////////////////////////////////
  229. STDMETHODIMP_(ULONG)
  230. CCertTemplateSecurityObject::AddRef()
  231. {
  232. return ++m_cRef;
  233. }
  234. STDMETHODIMP_(ULONG)
  235. CCertTemplateSecurityObject::Release()
  236. {
  237. if (--m_cRef == 0)
  238. {
  239. delete this;
  240. return 0;
  241. }
  242. return m_cRef;
  243. }
  244. STDMETHODIMP
  245. CCertTemplateSecurityObject::QueryInterface(REFIID riid, LPVOID FAR* ppv)
  246. {
  247. if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_ISecurityInformation))
  248. {
  249. *ppv = (LPSECURITYINFO)this;
  250. m_cRef++;
  251. return S_OK;
  252. }
  253. else
  254. {
  255. *ppv = NULL;
  256. return E_NOINTERFACE;
  257. }
  258. }
  259. ///////////////////////////////////////////////////////////
  260. //
  261. // ISecurityInformation methods
  262. //
  263. ///////////////////////////////////////////////////////////
  264. STDMETHODIMP
  265. CCertTemplateSecurityObject::GetObjectInformation(PSI_OBJECT_INFO pObjectInfo)
  266. {
  267. if ( pObjectInfo == NULL )
  268. {
  269. return E_POINTER;
  270. }
  271. if ( m_pCertTemplate == NULL )
  272. {
  273. return E_POINTER;
  274. }
  275. // security review 2/21/2002 BryanWal ok
  276. ZeroMemory(pObjectInfo, sizeof (SI_OBJECT_INFO));
  277. pObjectInfo->dwFlags = SI_EDIT_ALL | SI_NO_ACL_PROTECT | SI_ADVANCED | SI_NO_ADDITIONAL_PERMISSION;
  278. if ( m_pCertTemplate->ReadOnly () )
  279. pObjectInfo->dwFlags |= SI_READONLY;
  280. AFX_MANAGE_STATE (AfxGetStaticModuleState ());
  281. pObjectInfo->hInstance = AfxGetResourceHandle (); //AfxGetInstanceHandle ();
  282. pObjectInfo->pszObjectName = const_cast<WCHAR *>((LPCTSTR)m_pCertTemplate->GetLDAPPath ());
  283. return S_OK;
  284. }
  285. STDMETHODIMP
  286. CCertTemplateSecurityObject::GetSecurity(SECURITY_INFORMATION si,
  287. PSECURITY_DESCRIPTOR *ppSD,
  288. BOOL fDefault)
  289. {
  290. _TRACE (1, L"Entering CCertTemplateSecurityObject::GetSecurity\n");
  291. HRESULT hr = S_OK;
  292. DWORD dwLength = 0;
  293. SECURITY_DESCRIPTOR_CONTROL Control = SE_DACL_PROTECTED;
  294. DWORD dwRevision = 0;
  295. *ppSD = NULL;
  296. if (fDefault)
  297. return E_NOTIMPL;
  298. //
  299. // Assume that required privileges have already been enabled
  300. //
  301. hr = S_OK;
  302. // find out out much to allocate
  303. if ( !GetPrivateObjectSecurity(m_pSD, si, NULL, 0, &dwLength) )
  304. {
  305. hr = HRESULT_FROM_WIN32 (GetLastError ());
  306. if ( hr == HRESULT_FROM_WIN32 (ERROR_INSUFFICIENT_BUFFER) && dwLength )
  307. {
  308. hr = S_OK;
  309. // allocate and
  310. *ppSD = LocalAlloc(LPTR, dwLength);
  311. if (*ppSD )
  312. {
  313. // retrieve
  314. if ( GetPrivateObjectSecurity (m_pSD, si, *ppSD, dwLength, &dwLength) )
  315. {
  316. if ( GetSecurityDescriptorControl(m_pSD, &Control, &dwRevision))
  317. {
  318. Control &= SE_DACL_PROTECTED | SE_DACL_AUTO_INHERIT_REQ | SE_DACL_AUTO_INHERITED;
  319. // security review 2/21/2002 BryanWal ok - if it ain't broke, don't fix it
  320. SetSecurityDescriptorControl (*ppSD,
  321. SE_DACL_PROTECTED | SE_DACL_AUTO_INHERIT_REQ | SE_DACL_AUTO_INHERITED,
  322. Control);
  323. }
  324. else
  325. {
  326. hr = HRESULT_FROM_WIN32 (GetLastError ());
  327. _TRACE (0, L"GetSecurityDescriptorControl failed: 0x%x\n", hr);
  328. }
  329. }
  330. else
  331. {
  332. _TRACE (0, L"GetPrivateObjectSecurity failed: 0x%x\n", hr);
  333. hr = GetLastError();
  334. LocalFree(*ppSD);
  335. *ppSD = NULL;
  336. }
  337. }
  338. else
  339. hr = E_OUTOFMEMORY;
  340. }
  341. else if ( FAILED (hr) )
  342. {
  343. _TRACE (0, L"GetPrivateObjectSecurity failed: 0x%x\n", hr);
  344. }
  345. }
  346. else
  347. {
  348. hr = HRESULT_FROM_WIN32 (GetLastError ());
  349. }
  350. _TRACE (-1, L"Leaving CCertTemplateSecurityObject::GetSecurity: 0x%x\n", hr);
  351. return hr;
  352. }
  353. STDMETHODIMP
  354. CCertTemplateSecurityObject::SetSecurity(SECURITY_INFORMATION si,
  355. PSECURITY_DESCRIPTOR pSD)
  356. {
  357. HRESULT hr = S_OK;
  358. HANDLE hClientToken = NULL;
  359. HANDLE hHandle = NULL;
  360. SECURITY_DESCRIPTOR_CONTROL Control = SE_DACL_PROTECTED;
  361. DWORD dwRevision = 0;
  362. hHandle = GetCurrentThread();
  363. if (NULL == hHandle)
  364. {
  365. hr = HRESULT_FROM_WIN32 (GetLastError());
  366. }
  367. else
  368. {
  369. if (!OpenThreadToken(hHandle,
  370. TOKEN_QUERY,
  371. TRUE, // open as self
  372. &hClientToken))
  373. {
  374. hr = HRESULT_FROM_WIN32 (GetLastError());
  375. CloseHandle(hHandle);
  376. hHandle = NULL;
  377. }
  378. }
  379. if(hr != S_OK)
  380. {
  381. hHandle = GetCurrentProcess();
  382. if (NULL == hHandle)
  383. {
  384. hr = HRESULT_FROM_WIN32 (GetLastError());
  385. }
  386. else
  387. {
  388. HANDLE hProcessToken = NULL;
  389. hr = S_OK;
  390. if (!OpenProcessToken(hHandle,
  391. TOKEN_DUPLICATE,
  392. &hProcessToken))
  393. {
  394. hr = HRESULT_FROM_WIN32 (GetLastError());
  395. CloseHandle(hHandle);
  396. hHandle = NULL;
  397. }
  398. else
  399. {
  400. // security review 2/21/2002 BryanWal ok
  401. if(!DuplicateToken(hProcessToken,
  402. SecurityImpersonation,
  403. &hClientToken))
  404. {
  405. hr = HRESULT_FROM_WIN32 (GetLastError());
  406. CloseHandle(hHandle);
  407. hHandle = NULL;
  408. }
  409. CloseHandle(hProcessToken);
  410. }
  411. }
  412. }
  413. if ( SUCCEEDED (hr) )
  414. {
  415. //
  416. // Assume that required privileges have already been enabled
  417. //
  418. if ( SetPrivateObjectSecurityEx (si, pSD, &m_pSD, SEF_DACL_AUTO_INHERIT, &ObjMap, hClientToken) )
  419. {
  420. if ( si & DACL_SECURITY_INFORMATION )
  421. {
  422. if ( GetSecurityDescriptorControl (pSD, &Control, &dwRevision) )
  423. {
  424. Control &= SE_DACL_PROTECTED | SE_DACL_AUTO_INHERIT_REQ | SE_DACL_AUTO_INHERITED;
  425. // security review 2/21/2002 BryanWal ok
  426. SetSecurityDescriptorControl(m_pSD,
  427. SE_DACL_PROTECTED | SE_DACL_AUTO_INHERIT_REQ | SE_DACL_AUTO_INHERITED,
  428. Control);
  429. }
  430. }
  431. hr = m_pCertTemplate->SetSecurity (m_pSD);
  432. }
  433. else
  434. {
  435. hr = HRESULT_FROM_WIN32 (GetLastError());
  436. _TRACE (0, L"SetPrivateObjectSecurityEx () failed: 0x%x\n", hr);
  437. }
  438. }
  439. if ( hClientToken )
  440. {
  441. CloseHandle (hClientToken);
  442. }
  443. if ( hHandle )
  444. {
  445. CloseHandle (hHandle);
  446. }
  447. m_pCertTemplate->FailedToSetSecurity (FAILED (hr) ? true : false);
  448. return hr;
  449. }
  450. STDMETHODIMP
  451. CCertTemplateSecurityObject::GetAccessRights(const GUID* /*pguidObjectType*/,
  452. DWORD /*dwFlags*/,
  453. PSI_ACCESS *ppAccesses,
  454. ULONG *pcAccesses,
  455. ULONG *piDefaultAccess)
  456. {
  457. if ( !ppAccesses || !pcAccesses || !piDefaultAccess )
  458. return E_POINTER;
  459. if ( 1 == m_pCertTemplate->GetType () )
  460. {
  461. *ppAccesses = g_siV1ObjAccesses;
  462. *pcAccesses = sizeof(g_siV1ObjAccesses)/sizeof(g_siV1ObjAccesses[0]);
  463. }
  464. else
  465. {
  466. *ppAccesses = g_siV2ObjAccesses;
  467. *pcAccesses = sizeof(g_siV2ObjAccesses)/sizeof(g_siV2ObjAccesses[0]);
  468. }
  469. *piDefaultAccess = g_iObjDefAccess;
  470. return S_OK;
  471. }
  472. STDMETHODIMP
  473. CCertTemplateSecurityObject::MapGeneric(const GUID* /*pguidObjectType*/,
  474. UCHAR * /*pAceFlags*/,
  475. ACCESS_MASK *pmask)
  476. {
  477. MapGenericMask(pmask, &ObjMap);
  478. return S_OK;
  479. }
  480. STDMETHODIMP
  481. CCertTemplateSecurityObject::GetInheritTypes(PSI_INHERIT_TYPE *ppInheritTypes,
  482. ULONG *pcInheritTypes)
  483. {
  484. *ppInheritTypes = g_siObjInheritTypes;
  485. *pcInheritTypes = sizeof(g_siObjInheritTypes)/sizeof(g_siObjInheritTypes[0]);
  486. return S_OK;
  487. }
  488. STDMETHODIMP
  489. CCertTemplateSecurityObject::PropertySheetPageCallback(HWND /*hwnd*/,
  490. UINT uMsg,
  491. SI_PAGE_TYPE /*uPage*/)
  492. {
  493. if ( PSPCB_CREATE == uMsg )
  494. return E_NOTIMPL;
  495. return S_OK;
  496. }