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.

322 lines
7.0 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. CSASSERT(!m_fInitialized);
  113. hr = Init(pwszSanitizedName);
  114. _JumpIfError(hr, error, "CProtectedSecurityDescriptor::Init");
  115. hr = SetSD(pSD);
  116. _JumpIfError(hr, error, "CProtectedSecurityDescriptor::SetSD");
  117. m_fInitialized = true;
  118. error:
  119. return hr;
  120. }
  121. HRESULT
  122. CProtectedSecurityDescriptor::InitializeFromTemplate(
  123. LPCWSTR pcwszTemplate,
  124. LPCWSTR pwszSanitizedName)
  125. {
  126. HRESULT hr = S_OK;
  127. CSASSERT(!m_fInitialized);
  128. hr = Init(pwszSanitizedName);
  129. _JumpIfError(hr, error, "CProtectedSecurityDescriptor::Init");
  130. hr = myGetSDFromTemplate(
  131. pcwszTemplate,
  132. NULL,
  133. &m_pSD);
  134. _JumpIfError(hr, error, "myGetSDFromTemplate");
  135. m_fInitialized = true;
  136. error:
  137. return hr;
  138. }
  139. HRESULT
  140. CProtectedSecurityDescriptor::Load()
  141. {
  142. HRESULT hr = S_OK;
  143. PSECURITY_DESCRIPTOR pSD = NULL;
  144. CSASSERT(m_fInitialized);
  145. hr = myGetCertRegBinaryValue(m_pcwszSanitizedName,
  146. NULL,
  147. NULL,
  148. GetPersistRegistryVal(),
  149. (BYTE**)&pSD);
  150. if(S_OK!=hr)
  151. {
  152. return hr;
  153. }
  154. if(!IsValidSecurityDescriptor(pSD))
  155. {
  156. LocalFree(pSD);
  157. return E_UNEXPECTED;
  158. }
  159. if(m_pSD)
  160. {
  161. LocalFree(m_pSD);
  162. }
  163. m_pSD = pSD;
  164. return S_OK;
  165. }
  166. HRESULT
  167. CProtectedSecurityDescriptor::Save()
  168. {
  169. HRESULT hr = S_OK;
  170. DWORD cbLength = GetSecurityDescriptorLength(m_pSD);
  171. CSASSERT(m_fInitialized);
  172. hr = mySetCertRegValue(
  173. NULL,
  174. m_pcwszSanitizedName,
  175. NULL,
  176. NULL,
  177. GetPersistRegistryVal(),
  178. REG_BINARY,
  179. (BYTE const *) m_pSD,
  180. cbLength,
  181. FALSE);
  182. _JumpIfError(hr, error, "mySetCertRegValue");
  183. error:
  184. return hr;
  185. }
  186. HRESULT
  187. CProtectedSecurityDescriptor::Delete()
  188. {
  189. HRESULT hr = S_OK;
  190. CSASSERT(m_fInitialized);
  191. hr = myDeleteCertRegValue(
  192. m_pcwszSanitizedName,
  193. NULL,
  194. NULL,
  195. GetPersistRegistryVal());
  196. _JumpIfError(hr, error, "myDeleteCertRegValue");
  197. error:
  198. return hr;
  199. }
  200. HRESULT
  201. CProtectedSecurityDescriptor::Set(const PSECURITY_DESCRIPTOR pSD)
  202. {
  203. HRESULT hr = S_OK;
  204. DWORD dwResult;
  205. CSASSERT(m_fInitialized);
  206. if(!IsValidSecurityDescriptor(pSD))
  207. {
  208. hr = E_INVALIDARG;
  209. _JumpError(hr, error, "IsValidSecurityDescriptor");
  210. }
  211. __try
  212. {
  213. EnterCriticalSection(&m_csWrite);
  214. dwResult = WaitForSingleObject(m_hevtNoReaders, INFINITE);
  215. if(WAIT_OBJECT_0 != dwResult)
  216. {
  217. hr = myHLastError();
  218. }
  219. else
  220. {
  221. if(m_pSD)
  222. {
  223. LocalFree(m_pSD);
  224. m_pSD = NULL;
  225. }
  226. hr = SetSD(pSD);
  227. }
  228. LeaveCriticalSection(&m_csWrite);
  229. }
  230. __except(hr = myHEXCEPTIONCODE(), EXCEPTION_EXECUTE_HANDLER)
  231. {
  232. }
  233. error:
  234. return hr;
  235. }
  236. HRESULT
  237. CProtectedSecurityDescriptor::LockGet(PSECURITY_DESCRIPTOR *ppSD)
  238. {
  239. HRESULT hr = S_OK;
  240. CSASSERT(m_fInitialized);
  241. __try
  242. {
  243. EnterCriticalSection(&m_csWrite);
  244. InterlockedIncrement(&m_cReaders);
  245. if(!ResetEvent(m_hevtNoReaders))
  246. {
  247. hr = myHLastError();
  248. }
  249. LeaveCriticalSection(&m_csWrite);
  250. *ppSD = m_pSD;
  251. }
  252. __except(hr = myHEXCEPTIONCODE(), EXCEPTION_EXECUTE_HANDLER)
  253. {
  254. }
  255. return hr;
  256. }
  257. HRESULT
  258. CProtectedSecurityDescriptor::Unlock()
  259. {
  260. HRESULT hr = S_OK;
  261. CSASSERT(m_fInitialized);
  262. if(!InterlockedDecrement(&m_cReaders))
  263. {
  264. if(!SetEvent(m_hevtNoReaders))
  265. {
  266. hr = myHLastError();
  267. }
  268. }
  269. return hr;
  270. }