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.

356 lines
8.3 KiB

  1. //+--------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1996 - 1999
  5. //
  6. // File: certsrvd.cpp
  7. //
  8. // Contents: Implementation of DCOM object for RPC services
  9. //
  10. // History: July-97 xtan created
  11. //
  12. //---------------------------------------------------------------------------
  13. #include <pch.cpp>
  14. #pragma hdrstop
  15. #define SECURITY_WIN32
  16. #include <security.h>
  17. #include <lmcons.h>
  18. #include <accctrl.h>
  19. #include "certsrvd.h"
  20. #include "admin.h"
  21. #include "request.h"
  22. #include "certacl.h"
  23. //temporary
  24. #include <msaudite.h>
  25. #define __dwFILE__ __dwFILE_CERTSRV_CERTSRVD_CPP__
  26. using namespace CertSrv;
  27. // Global Access List
  28. CCertificateAuthoritySD g_CASD;
  29. AUTHZ_RESOURCE_MANAGER_HANDLE g_AuthzCertSrvRM;
  30. DWORD g_dwAuditFilter;
  31. COfficerRightsSD g_OfficerRightsSD;
  32. CConfigStorage g_ConfigStorage;
  33. GENERIC_MAPPING g_CertGenericMapping = {
  34. READ_CONTROL | ACTRL_DS_READ_PROP,
  35. WRITE_DAC | WRITE_OWNER | ACTRL_DS_WRITE_PROP,
  36. 0,
  37. ACTRL_DS_READ_PROP |
  38. ACTRL_DS_WRITE_PROP |
  39. READ_CONTROL |
  40. WRITE_DAC |
  41. WRITE_OWNER
  42. };
  43. // GetClientUserName() impersonates the client
  44. HRESULT
  45. GetClientUserName(
  46. IN handle_t hRpc,
  47. OPTIONAL OUT WCHAR **ppwszUserSamName,
  48. OPTIONAL OUT WCHAR **ppwszUserDN)
  49. {
  50. HRESULT hr;
  51. IServerSecurity *pISS = NULL;
  52. bool fImpersonating = false;
  53. WCHAR *pwszUserSamName = NULL;
  54. if (NULL != ppwszUserSamName)
  55. {
  56. *ppwszUserSamName = NULL;
  57. }
  58. if (NULL != ppwszUserDN)
  59. {
  60. *ppwszUserDN = NULL;
  61. }
  62. if (NULL == hRpc)
  63. {
  64. // dcom impersonate
  65. // get client info and impersonate client
  66. hr = CoGetCallContext(IID_IServerSecurity, (void**)&pISS);
  67. _JumpIfError(hr, error, "CoGetCallContext");
  68. hr = pISS->ImpersonateClient();
  69. _JumpIfError(hr, error, "ImpersonateClient");
  70. }
  71. else
  72. {
  73. // rpc impersonate
  74. hr = RpcImpersonateClient((RPC_BINDING_HANDLE) hRpc);
  75. _JumpIfError(hr, error, "RpcImpersonateClient");
  76. }
  77. fImpersonating = true;
  78. if (NULL != ppwszUserSamName)
  79. {
  80. hr = myGetUserNameEx(NameSamCompatible, &pwszUserSamName);
  81. _JumpIfError(hr, error, "myGetUserNameEx");
  82. }
  83. if (NULL != ppwszUserDN)
  84. {
  85. hr = myGetUserNameEx(NameFullyQualifiedDN, ppwszUserDN);
  86. _JumpIfError(hr, error, "myGetUserNameEx");
  87. }
  88. if (NULL != ppwszUserSamName)
  89. {
  90. *ppwszUserSamName = pwszUserSamName;
  91. pwszUserSamName = NULL;
  92. }
  93. hr = S_OK;
  94. error:
  95. if (fImpersonating)
  96. {
  97. if (NULL != hRpc)
  98. {
  99. HRESULT hr2 = RpcRevertToSelf();
  100. _PrintIfError(hr2, "RpcRevertToSelf");
  101. if (S_OK == hr)
  102. {
  103. hr = hr2;
  104. }
  105. }
  106. else // dcom
  107. {
  108. pISS->RevertToSelf();
  109. }
  110. }
  111. if (NULL != pISS)
  112. {
  113. pISS->Release();
  114. }
  115. if (NULL != pwszUserSamName)
  116. {
  117. LocalFree(pwszUserSamName);
  118. }
  119. return(hr);
  120. }
  121. STDMETHODIMP
  122. CheckCertSrvAccess(
  123. OPTIONAL IN LPCWSTR pwszAuthority,
  124. IN handle_t hRpc,
  125. IN ACCESS_MASK Mask,
  126. OUT BOOL *pfAccessAllowed,
  127. OPTIONAL OUT HANDLE *phToken)
  128. {
  129. HRESULT hr = S_OK;
  130. HANDLE hClientToken = NULL;
  131. HANDLE hThread = NULL;
  132. IServerSecurity *pISS = NULL;
  133. PRIVILEGE_SET ps;
  134. DWORD dwPSSize = sizeof(PRIVILEGE_SET);
  135. DWORD grantAccess;
  136. PSECURITY_DESCRIPTOR pCASD = NULL;
  137. bool fImpersonating = false;
  138. *pfAccessAllowed = FALSE;
  139. CSASSERT(hRpc);
  140. // If, for some reason, a certsrv call is made after we've shut down
  141. // security, we need to fail.
  142. if (!g_CASD.IsInitialized())
  143. {
  144. hr = HRESULT_FROM_WIN32(ERROR_NOT_READY);
  145. _JumpError(hr, error, "Security not enabled");
  146. }
  147. if (NULL != pwszAuthority)
  148. {
  149. if (0 != mylstrcmpiL(pwszAuthority, g_wszCommonName))
  150. {
  151. if (0 != mylstrcmpiL(pwszAuthority, g_wszSanitizedName) &&
  152. 0 != mylstrcmpiL(pwszAuthority, g_pwszSanitizedDSName))
  153. {
  154. hr = E_INVALIDARG;
  155. _PrintErrorStr(
  156. hr,
  157. "CheckCertSrvAccess: invalid authority name",
  158. pwszAuthority);
  159. _JumpErrorStr(hr, error, "expected CA name", g_wszCommonName);
  160. }
  161. #ifdef DBG_CERTSRV_DEBUG_PRINT
  162. if (0 == mylstrcmpiL(pwszAuthority, g_wszSanitizedName))
  163. {
  164. DBGPRINT((
  165. DBG_SS_CERTSRV,
  166. "'%ws' called with Sanitized Name: '%ws'\n",
  167. g_wszCommonName,
  168. pwszAuthority));
  169. }
  170. else
  171. if (0 == mylstrcmpiL(pwszAuthority, g_pwszSanitizedDSName))
  172. {
  173. DBGPRINT((
  174. DBG_SS_CERTSRV,
  175. "'%ws' called with Sanitized DS Name: '%ws'\n",
  176. g_wszCommonName,
  177. pwszAuthority));
  178. }
  179. #endif
  180. }
  181. }
  182. // enforce encryption if enabled
  183. if(IF_ENFORCEENCRYPTICERTREQUEST & g_InterfaceFlags)
  184. {
  185. unsigned long ulAuthLevel;
  186. hr = RpcBindingInqAuthClient(
  187. hRpc,
  188. NULL, NULL,
  189. &ulAuthLevel,
  190. NULL, NULL);
  191. _JumpIfError(hr, error, "RpcBindingInqAuthClient");
  192. if(RPC_C_AUTHN_LEVEL_PKT_PRIVACY != ulAuthLevel)
  193. {
  194. hr = E_ACCESSDENIED;
  195. _JumpError(hr, error, "call not encrypted");
  196. }
  197. }
  198. // rpc impersonate
  199. hr = RpcImpersonateClient((RPC_BINDING_HANDLE) hRpc);
  200. if (S_OK != hr)
  201. {
  202. hr = myHError(hr);
  203. _JumpError(hr, error, "RpcImpersonateClient");
  204. }
  205. fImpersonating = true;
  206. hThread = GetCurrentThread();
  207. if (NULL == hThread)
  208. {
  209. hr = myHLastError();
  210. _JumpIfError(hr, error, "GetCurrentThread");
  211. }
  212. if (!OpenThreadToken(hThread,
  213. TOKEN_QUERY | TOKEN_DUPLICATE,
  214. FALSE, // client impersonation
  215. &hClientToken))
  216. {
  217. hr = myHLastError();
  218. _JumpIfError(hr, error, "OpenThreadToken");
  219. }
  220. hr = g_CASD.LockGet(&pCASD);
  221. _JumpIfError(hr, error, "CProtectedSecurityDescriptor::LockGet");
  222. if (!AccessCheck(
  223. pCASD, // security descriptor
  224. hClientToken, // handle to client access token
  225. Mask, // requested access rights
  226. &g_CertGenericMapping, // map generic to specific rights
  227. &ps, // receives privileges used
  228. &dwPSSize, // size of privilege-set buffer
  229. &grantAccess, // retrieves mask of granted rights
  230. pfAccessAllowed)) // retrieves results of access check
  231. {
  232. hr = myHLastError();
  233. _JumpError(hr, error, "AccessCheckByType");
  234. }
  235. hr = S_OK;
  236. if(phToken)
  237. {
  238. *phToken = hClientToken;
  239. hClientToken = NULL;
  240. }
  241. error:
  242. if(pCASD)
  243. {
  244. HRESULT hr2 = g_CASD.Unlock();
  245. _PrintIfError(hr2, "g_CASD.Unlock");
  246. if (S_OK == hr)
  247. {
  248. hr = hr2;
  249. }
  250. }
  251. if(fImpersonating)
  252. {
  253. if (NULL != hRpc) // rpc
  254. {
  255. HRESULT hr2 = RpcRevertToSelf();
  256. _PrintIfError(hr2, "RpcRevertToSelf");
  257. if (S_OK == hr)
  258. {
  259. hr = hr2;
  260. }
  261. }
  262. else // dcom
  263. {
  264. if (NULL != pISS)
  265. {
  266. pISS->RevertToSelf();
  267. pISS->Release();
  268. }
  269. }
  270. }
  271. if (NULL != hThread)
  272. {
  273. CloseHandle(hThread);
  274. }
  275. if (NULL != hClientToken)
  276. {
  277. CloseHandle(hClientToken);
  278. }
  279. return(hr);
  280. }
  281. HRESULT
  282. CertStartClassFactories()
  283. {
  284. HRESULT hr;
  285. if (0 == (IF_NOREMOTEICERTREQUEST & g_InterfaceFlags) ||
  286. 0 == (IF_NOLOCALICERTREQUEST & g_InterfaceFlags))
  287. {
  288. hr = CRequestFactory::StartFactory();
  289. _JumpIfError(hr, error, "CRequestFactory::StartFactory");
  290. }
  291. if (0 == (IF_NOREMOTEICERTADMIN & g_InterfaceFlags) ||
  292. 0 == (IF_NOLOCALICERTADMIN & g_InterfaceFlags))
  293. {
  294. hr = CAdminFactory::StartFactory();
  295. _JumpIfError(hr, error, "CAdminFactory::StartFactory");
  296. }
  297. hr = S_OK;
  298. error:
  299. if (S_OK != hr)
  300. {
  301. CRequestFactory::StopFactory();
  302. }
  303. CSASSERT(S_OK == hr || FAILED(hr));
  304. return(hr);
  305. }
  306. VOID
  307. CertStopClassFactories()
  308. {
  309. CRequestFactory::StopFactory();
  310. CAdminFactory::StopFactory();
  311. }