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.

316 lines
6.6 KiB

  1. //+--------------------------------------------------------------------------
  2. // File: certsd.cpp
  3. // Contents: CA's security descriptor class implementation
  4. //---------------------------------------------------------------------------
  5. #include <pch.cpp>
  6. #pragma hdrstop
  7. #include "certsd.h"
  8. #include "certacl.h"
  9. #define __dwFILE__ __dwFILE_CERTLIB_CERTSD_CPP__
  10. using namespace CertSrv;
  11. HRESULT
  12. CProtectedSecurityDescriptor::Init(LPCWSTR pwszSanitizedName)
  13. {
  14. HRESULT hr = S_OK;
  15. CSASSERT(!m_fInitialized);
  16. __try
  17. {
  18. InitializeCriticalSection(&m_csWrite);
  19. }
  20. __except(hr = myHEXCEPTIONCODE(), EXCEPTION_EXECUTE_HANDLER)
  21. {
  22. }
  23. _JumpIfError(hr, error, "InitializeCriticalSection");
  24. m_hevtNoReaders = CreateEvent(
  25. NULL,
  26. TRUE,
  27. TRUE,
  28. NULL);
  29. if(NULL==m_hevtNoReaders)
  30. {
  31. hr = myHLastError();
  32. _JumpError(hr, error, "CreateEvent");
  33. }
  34. m_pcwszSanitizedName = pwszSanitizedName;
  35. error:
  36. return hr;
  37. }
  38. HRESULT
  39. CProtectedSecurityDescriptor::SetSD(const PSECURITY_DESCRIPTOR pSD)
  40. {
  41. HRESULT hr = S_OK;
  42. DWORD dwSize = 0;
  43. SECURITY_DESCRIPTOR_CONTROL SDCtrl;
  44. DWORD dwRev;
  45. CSASSERT(NULL==m_pSD);
  46. if(pSD)
  47. {
  48. if(!IsValidSecurityDescriptor(pSD))
  49. {
  50. hr = E_INVALIDARG;
  51. _JumpError(hr, error, "IsValidSecurityDescriptor");
  52. }
  53. if(!GetSecurityDescriptorControl(pSD, &SDCtrl, &dwRev))
  54. {
  55. hr = myHLastError();
  56. _JumpError(hr, error, "GetSecurityDescriptorControl");
  57. }
  58. // always keep the SD in self relative form
  59. if(!(SDCtrl&SE_SELF_RELATIVE))
  60. {
  61. if(!MakeSelfRelativeSD(pSD, NULL, &dwSize))
  62. {
  63. m_pSD = (PSECURITY_DESCRIPTOR)LocalAlloc(LMEM_FIXED, dwSize);
  64. if(NULL == m_pSD)
  65. {
  66. hr = E_OUTOFMEMORY;
  67. _JumpError(hr, error, "LocalAlloc");
  68. }
  69. if(!MakeSelfRelativeSD(pSD, m_pSD, &dwSize))
  70. {
  71. hr = myHLastError();
  72. _JumpError(hr, error, "LocalAlloc");
  73. }
  74. }
  75. }
  76. else
  77. {
  78. dwSize = GetSecurityDescriptorLength(pSD);
  79. m_pSD = (PSECURITY_DESCRIPTOR)LocalAlloc(LMEM_FIXED, dwSize);
  80. if(NULL == m_pSD)
  81. {
  82. hr = E_OUTOFMEMORY;
  83. _JumpError(hr, error, "LocalAlloc");
  84. }
  85. CopyMemory(m_pSD, pSD, dwSize);
  86. }
  87. }
  88. error:
  89. return hr;
  90. }
  91. HRESULT
  92. CProtectedSecurityDescriptor::Initialize(LPCWSTR pwszSanitizedName)
  93. {
  94. HRESULT hr = S_OK;
  95. CSASSERT(!m_fInitialized);
  96. hr = Init(pwszSanitizedName);
  97. _JumpIfError(hr, error, "CProtectedSecurityDescriptor::Init");
  98. m_fInitialized = true;
  99. hr = Load();
  100. if(HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)==hr)
  101. hr = S_OK;
  102. _JumpIfError(hr, error, "CProtectedSecurityDescriptor::Load");
  103. error:
  104. return hr;
  105. }
  106. HRESULT
  107. CProtectedSecurityDescriptor::Initialize(
  108. PSECURITY_DESCRIPTOR pSD,
  109. LPCWSTR pwszSanitizedName)
  110. {
  111. HRESULT hr = S_OK;
  112. DWORD dwSDLen;
  113. CSASSERT(!m_fInitialized);
  114. hr = Init(pwszSanitizedName);
  115. _JumpIfError(hr, error, "CProtectedSecurityDescriptor::Init");
  116. hr = SetSD(pSD);
  117. _JumpIfError(hr, error, "CProtectedSecurityDescriptor::SetSD");
  118. m_fInitialized = true;
  119. error:
  120. return hr;
  121. }
  122. HRESULT
  123. CProtectedSecurityDescriptor::InitializeFromTemplate(
  124. LPCWSTR pcwszTemplate,
  125. LPCWSTR pwszSanitizedName)
  126. {
  127. HRESULT hr = S_OK;
  128. DWORD dwSDLen;
  129. CSASSERT(!m_fInitialized);
  130. hr = Init(pwszSanitizedName);
  131. _JumpIfError(hr, error, "CProtectedSecurityDescriptor::Init");
  132. hr = myGetSDFromTemplate(
  133. pcwszTemplate,
  134. NULL,
  135. &m_pSD);
  136. _JumpIfError(hr, error, "myGetSDFromTemplate");
  137. m_fInitialized = true;
  138. error:
  139. return hr;
  140. }
  141. HRESULT
  142. CProtectedSecurityDescriptor::Load()
  143. {
  144. HRESULT hr = S_OK;
  145. PSECURITY_DESCRIPTOR pSD = NULL;
  146. CSASSERT(m_fInitialized);
  147. hr = myGetCertRegBinaryValue(m_pcwszSanitizedName,
  148. NULL,
  149. NULL,
  150. GetPersistRegistryVal(),
  151. (BYTE**)&pSD);
  152. if(S_OK!=hr)
  153. {
  154. return hr;
  155. }
  156. if(!IsValidSecurityDescriptor(pSD))
  157. {
  158. LocalFree(pSD);
  159. return E_UNEXPECTED;
  160. }
  161. if(m_pSD)
  162. {
  163. LocalFree(m_pSD);
  164. }
  165. m_pSD = pSD;
  166. return S_OK;
  167. }
  168. HRESULT
  169. CProtectedSecurityDescriptor::Save()
  170. {
  171. HRESULT hr = S_OK;
  172. DWORD cbLength = GetSecurityDescriptorLength(m_pSD);
  173. CSASSERT(m_fInitialized);
  174. hr = mySetCertRegValue(
  175. NULL,
  176. m_pcwszSanitizedName,
  177. NULL,
  178. NULL,
  179. GetPersistRegistryVal(),
  180. REG_BINARY,
  181. (BYTE const *) m_pSD,
  182. cbLength,
  183. FALSE);
  184. _JumpIfError(hr, error, "mySetCertRegValue");
  185. error:
  186. return hr;
  187. }
  188. HRESULT
  189. CProtectedSecurityDescriptor::Delete()
  190. {
  191. HRESULT hr = S_OK;
  192. CSASSERT(m_fInitialized);
  193. hr = myDeleteCertRegValue(
  194. m_pcwszSanitizedName,
  195. NULL,
  196. NULL,
  197. GetPersistRegistryVal());
  198. _JumpIfError(hr, error, "myDeleteCertRegValue");
  199. error:
  200. return hr;
  201. }
  202. HRESULT
  203. CProtectedSecurityDescriptor::Set(const PSECURITY_DESCRIPTOR pSD)
  204. {
  205. HRESULT hr = S_OK;
  206. CSASSERT(m_fInitialized);
  207. if(!IsValidSecurityDescriptor(pSD))
  208. {
  209. hr = E_INVALIDARG;
  210. _JumpError(hr, error, "IsValidSecurityDescriptor");
  211. }
  212. __try
  213. {
  214. EnterCriticalSection(&m_csWrite);
  215. WaitForSingleObject(&m_hevtNoReaders, INFINITE);
  216. if(m_pSD)
  217. {
  218. LocalFree(m_pSD);
  219. m_pSD = NULL;
  220. }
  221. hr = SetSD(pSD);
  222. LeaveCriticalSection(&m_csWrite);
  223. }
  224. __except(hr = myHEXCEPTIONCODE(), EXCEPTION_EXECUTE_HANDLER)
  225. {
  226. }
  227. error:
  228. return hr;
  229. }
  230. HRESULT
  231. CProtectedSecurityDescriptor::LockGet(PSECURITY_DESCRIPTOR *ppSD)
  232. {
  233. HRESULT hr = S_OK;
  234. CSASSERT(m_fInitialized);
  235. __try
  236. {
  237. EnterCriticalSection(&m_csWrite);
  238. InterlockedIncrement(&m_cReaders);
  239. if(!ResetEvent(m_hevtNoReaders))
  240. {
  241. hr = myHLastError();
  242. }
  243. LeaveCriticalSection(&m_csWrite);
  244. *ppSD = m_pSD;
  245. }
  246. __except(hr = myHEXCEPTIONCODE(), EXCEPTION_EXECUTE_HANDLER)
  247. {
  248. }
  249. return hr;
  250. }
  251. HRESULT
  252. CProtectedSecurityDescriptor::Unlock()
  253. {
  254. HRESULT hr = S_OK;
  255. CSASSERT(m_fInitialized);
  256. if(!InterlockedDecrement(&m_cReaders))
  257. {
  258. if(!SetEvent(m_hevtNoReaders))
  259. {
  260. hr = myHLastError();
  261. }
  262. }
  263. return hr;
  264. }