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.

1542 lines
40 KiB

  1. //+--------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1999 - 2000
  5. //
  6. // File: event.cpp
  7. //
  8. // Contents: Cert CAuditEvent class implementation
  9. //
  10. //---------------------------------------------------------------------------
  11. #include <pch.cpp>
  12. #pragma hdrstop
  13. #include <sid.h>
  14. #include <authzi.h>
  15. #define __dwFILE__ __dwFILE_CERTSRV_EVENT_CPP__
  16. using namespace CertSrv;
  17. CAuditEvent::AUDIT_CATEGORIES cat[] =
  18. { // event ID // event category no of check role separation
  19. //args for this event
  20. {SE_AUDITID_CERTSRV_SHUTDOWN, AUDIT_FILTER_STARTSTOP, 0, TRUE},
  21. {SE_AUDITID_CERTSRV_SERVICESTART, AUDIT_FILTER_STARTSTOP, 4, FALSE},
  22. {SE_AUDITID_CERTSRV_SERVICESTOP, AUDIT_FILTER_STARTSTOP, 4, FALSE},
  23. {SE_AUDITID_CERTSRV_BACKUPSTART, AUDIT_FILTER_BACKUPRESTORE,1, TRUE},
  24. {SE_AUDITID_CERTSRV_BACKUPEND, AUDIT_FILTER_BACKUPRESTORE,0, TRUE},
  25. {SE_AUDITID_CERTSRV_RESTORESTART, AUDIT_FILTER_BACKUPRESTORE,0, FALSE},
  26. {SE_AUDITID_CERTSRV_RESTOREEND, AUDIT_FILTER_BACKUPRESTORE,0, FALSE},
  27. {SE_AUDITID_CERTSRV_DENYREQUEST, AUDIT_FILTER_CERTIFICATE, 1, TRUE},
  28. {SE_AUDITID_CERTSRV_RESUBMITREQUEST, AUDIT_FILTER_CERTIFICATE, 1, TRUE},
  29. {SE_AUDITID_CERTSRV_SETEXTENSION, AUDIT_FILTER_CERTIFICATE, 5, TRUE},
  30. {SE_AUDITID_CERTSRV_SETATTRIBUTES, AUDIT_FILTER_CERTIFICATE, 2, TRUE},
  31. {SE_AUDITID_CERTSRV_IMPORTCERT, AUDIT_FILTER_CERTIFICATE, 2, TRUE},
  32. {SE_AUDITID_CERTSRV_NEWREQUEST, AUDIT_FILTER_CERTIFICATE, 3, FALSE},
  33. {SE_AUDITID_CERTSRV_REQUESTAPPROVED, AUDIT_FILTER_CERTIFICATE, 6, FALSE},
  34. {SE_AUDITID_CERTSRV_REQUESTDENIED, AUDIT_FILTER_CERTIFICATE, 6, FALSE},
  35. {SE_AUDITID_CERTSRV_REQUESTPENDING, AUDIT_FILTER_CERTIFICATE, 6, FALSE},
  36. {SE_AUDITID_CERTSRV_DELETEROW, AUDIT_FILTER_CERTIFICATE, 3, TRUE},
  37. {SE_AUDITID_CERTSRV_PUBLISHCACERT, AUDIT_FILTER_CERTIFICATE, 3, FALSE},
  38. {SE_AUDITID_CERTSRV_REVOKECERT, AUDIT_FILTER_CERTREVOCATION, 2, TRUE},
  39. {SE_AUDITID_CERTSRV_PUBLISHCRL, AUDIT_FILTER_CERTREVOCATION, 3, TRUE},
  40. {SE_AUDITID_CERTSRV_AUTOPUBLISHCRL, AUDIT_FILTER_CERTREVOCATION, 5, FALSE},
  41. {SE_AUDITID_CERTSRV_SETSECURITY, AUDIT_FILTER_CASECURITY, 1, TRUE},
  42. {SE_AUDITID_CERTSRV_SETAUDITFILTER, AUDIT_FILTER_CASECURITY, 1, TRUE},
  43. {SE_AUDITID_CERTSRV_SETOFFICERRIGHTS, AUDIT_FILTER_CASECURITY, 2, TRUE},
  44. {SE_AUDITID_CERTSRV_ROLESEPARATIONSTATE,AUDIT_FILTER_CASECURITY, 1, FALSE},
  45. {SE_AUDITID_CERTSRV_GETARCHIVEDKEY, AUDIT_FILTER_KEYAARCHIVAL, 1, TRUE},
  46. {SE_AUDITID_CERTSRV_KEYARCHIVED, AUDIT_FILTER_KEYAARCHIVAL, 3, FALSE},
  47. {SE_AUDITID_CERTSRV_IMPORTKEY, AUDIT_FILTER_KEYAARCHIVAL, 1, TRUE},
  48. {SE_AUDITID_CERTSRV_SETCONFIGENTRY, AUDIT_FILTER_CACONFIG, 3, TRUE},
  49. {SE_AUDITID_CERTSRV_SETCAPROPERTY, AUDIT_FILTER_CACONFIG, 4, TRUE},
  50. };
  51. CAuditEvent::AUDIT_CATEGORIES *CAuditEvent::m_gAuditCategories = cat;
  52. DWORD CAuditEvent::m_gdwAuditCategoriesSize = sizeof(cat)/sizeof(cat[0]);
  53. bool CAuditEvent::m_gfRoleSeparationEnabled = false;
  54. CAuditEvent::CAuditEvent(ULONG ulEventID, DWORD dwFilter) :
  55. m_cEventData(0),
  56. m_cRequiredEventData(0),
  57. m_dwFilter(dwFilter),
  58. m_fRoleSeparationEnabled(false),
  59. m_pISS(NULL),
  60. m_hClientToken(NULL),
  61. m_pCASD(NULL),
  62. m_ClientContext(NULL),
  63. m_pSDPrivileges(NULL),
  64. m_pDaclPrivileges(NULL),
  65. m_hRpc(NULL),
  66. m_Error(0),
  67. m_MaskAllowed(0),
  68. m_crtGUID(0),
  69. m_pUserSid(NULL),
  70. m_hAuditEventType(NULL)
  71. {
  72. m_AuthzHandle = NULL;
  73. m_Request.ObjectTypeList = NULL;
  74. m_Request.PrincipalSelfSid = NULL;
  75. m_Request.ObjectTypeListLength = 0;
  76. m_Request.OptionalArguments = NULL;
  77. m_Reply.ResultListLength = 1;
  78. m_Reply.GrantedAccessMask = &m_MaskAllowed;
  79. m_Reply.Error = &m_Error;
  80. m_Reply.SaclEvaluationResults = &m_SaclEval;
  81. SetEventID(ulEventID);
  82. };
  83. // initializes internal data associated with a particular audit event
  84. void CAuditEvent::SetEventID(ULONG ulEventID)
  85. {
  86. m_ulEventID = ulEventID;
  87. for(DWORD c=0; c<m_gdwAuditCategoriesSize; c++)
  88. {
  89. if(((DWORD)m_ulEventID)==((DWORD)m_gAuditCategories[c].ulAuditID))
  90. {
  91. m_fRoleSeparationEnabled =
  92. m_gAuditCategories[c].fRoleSeparationEnabled;
  93. m_cRequiredEventData = m_gAuditCategories[c].dwParamCount;
  94. CSASSERT(m_EventDataMaxSize>=m_cRequiredEventData);
  95. if(!m_gAuditCategories[c].hAuditEventType)
  96. {
  97. AuthziInitializeAuditEventType(
  98. 0,
  99. SE_CATEGID_OBJECT_ACCESS,
  100. (USHORT)m_ulEventID,
  101. (USHORT)m_gAuditCategories[c].dwParamCount,
  102. &m_gAuditCategories[c].hAuditEventType);
  103. }
  104. m_hAuditEventType = m_gAuditCategories[c].hAuditEventType;
  105. break;
  106. }
  107. }
  108. }
  109. CAuditEvent::~CAuditEvent()
  110. {
  111. for(DWORD cData=0;cData<m_cEventData;cData++)
  112. delete m_pEventDataList[cData];
  113. FreeCachedHandles();
  114. }
  115. void CAuditEvent::CleanupAuditEventTypeHandles()
  116. {
  117. for(DWORD c=0; c<m_gdwAuditCategoriesSize; c++)
  118. {
  119. if(m_gAuditCategories[c].hAuditEventType)
  120. {
  121. AuthziFreeAuditEventType(m_gAuditCategories[c].hAuditEventType);
  122. }
  123. }
  124. }
  125. bool CAuditEvent::IsEventValid()
  126. {
  127. for(DWORD c=0; c<m_gdwAuditCategoriesSize; c++)
  128. {
  129. if(m_ulEventID==m_gAuditCategories[c].ulAuditID)
  130. return true;
  131. }
  132. return false;
  133. }
  134. bool CAuditEvent::IsEventEnabled()
  135. {
  136. if(0==m_ulEventID) // event is used for access check only
  137. return false;
  138. for(DWORD c=0; c<m_gdwAuditCategoriesSize; c++)
  139. {
  140. if(((DWORD)m_ulEventID)==((DWORD)m_gAuditCategories[c].ulAuditID))
  141. {
  142. return (m_dwFilter&m_gAuditCategories[c].dwFilter)?true:false;
  143. }
  144. }
  145. // if get here the event has an unknown ID
  146. CSASSERT(CSExpr(!L"Invalid event found"));
  147. return false;
  148. }
  149. inline bool CAuditEvent::IsEventRoleSeparationEnabled()
  150. {
  151. return RoleSeparationIsEnabled() && m_fRoleSeparationEnabled;
  152. }
  153. HRESULT CAuditEvent::AddData(DWORD dwValue)
  154. {
  155. PROPVARIANT *pvtData = CreateNewEventData();
  156. if(!pvtData)
  157. {
  158. return E_OUTOFMEMORY;
  159. }
  160. V_VT(pvtData) = VT_UI4;
  161. V_UI4(pvtData) = dwValue;
  162. return S_OK;
  163. }
  164. HRESULT CAuditEvent::AddData(PBYTE pData, DWORD dwDataLen)
  165. {
  166. CSASSERT(pData && dwDataLen);
  167. PROPVARIANT *pvtData = CreateNewEventData();
  168. if(!pvtData)
  169. {
  170. return E_OUTOFMEMORY;
  171. }
  172. V_VT(pvtData) = VT_BLOB;
  173. pvtData->blob.cbSize = dwDataLen;
  174. pvtData->blob.pBlobData = (BYTE*)CoTaskMemAlloc(dwDataLen);
  175. if(!pvtData->blob.pBlobData)
  176. {
  177. return E_OUTOFMEMORY;
  178. }
  179. memcpy(pvtData->blob.pBlobData, pData, dwDataLen);
  180. return S_OK;
  181. }
  182. HRESULT CAuditEvent::AddData(bool fData)
  183. {
  184. PROPVARIANT *pvtData = CreateNewEventData();
  185. if(!pvtData)
  186. {
  187. return E_OUTOFMEMORY;
  188. }
  189. V_VT(pvtData) = VT_BOOL;
  190. V_BOOL(pvtData) = fData?VARIANT_TRUE:VARIANT_FALSE;
  191. return S_OK;
  192. }
  193. HRESULT CAuditEvent::AddData(LPCWSTR pcwszData)
  194. {
  195. if(!pcwszData)
  196. pcwszData = L"";
  197. PROPVARIANT *pvtData = CreateNewEventData();
  198. if(!pvtData)
  199. {
  200. return E_OUTOFMEMORY;
  201. }
  202. V_VT(pvtData) = VT_LPWSTR;
  203. pvtData->pwszVal =
  204. (LPWSTR)CoTaskMemAlloc((wcslen(pcwszData)+1)*sizeof(WCHAR));
  205. if(!pvtData->pwszVal)
  206. {
  207. return E_OUTOFMEMORY;
  208. }
  209. wcscpy(pvtData->pwszVal, pcwszData);
  210. return S_OK;
  211. }
  212. HRESULT CAuditEvent::AddData(LPCWSTR *ppcwszData)
  213. {
  214. CSASSERT(ppcwszData);
  215. PROPVARIANT *pvtData = CreateNewEventData();
  216. if(!pvtData)
  217. {
  218. return E_OUTOFMEMORY;
  219. }
  220. V_VT(pvtData) = VT_LPWSTR;
  221. DWORD dwTextLen = 1;
  222. for(LPCWSTR *ppcwszStr=ppcwszData; *ppcwszStr; ppcwszStr++)
  223. {
  224. dwTextLen += wcslen(*ppcwszStr)+2;
  225. }
  226. pvtData->pwszVal =
  227. (LPWSTR)CoTaskMemAlloc(dwTextLen*sizeof(WCHAR));
  228. if(!pvtData->pwszVal)
  229. {
  230. return E_OUTOFMEMORY;
  231. }
  232. wcscpy(pvtData->pwszVal, L"");
  233. for(ppcwszStr=ppcwszData; *ppcwszStr; ppcwszStr++)
  234. {
  235. wcscat(pvtData->pwszVal, *ppcwszStr);
  236. wcscat(pvtData->pwszVal, L"; ");
  237. }
  238. return S_OK;
  239. }
  240. HRESULT CAuditEvent::AddData(FILETIME time)
  241. {
  242. PROPVARIANT *pvtData = CreateNewEventData();
  243. if(!pvtData)
  244. {
  245. return E_OUTOFMEMORY;
  246. }
  247. FILETIME ftZero = {0,0};
  248. #define wszTIMEZERO L"0"
  249. if(0 == CompareFileTime(&time, &ftZero))
  250. {
  251. V_VT(pvtData) = VT_LPWSTR;
  252. pvtData->pwszVal = (LPWSTR) CoTaskMemAlloc(sizeof(wszTIMEZERO));
  253. if (NULL == pvtData->pwszVal)
  254. {
  255. return E_OUTOFMEMORY;
  256. }
  257. wcscpy(pvtData->pwszVal, wszTIMEZERO);
  258. }
  259. else
  260. {
  261. V_VT(pvtData) = VT_FILETIME;
  262. pvtData->filetime = time;
  263. }
  264. return S_OK;
  265. }
  266. HRESULT CAuditEvent::AddData(const VARIANT *pvar, bool fDoublePercentInStrings=false)
  267. {
  268. CSASSERT(pvar);
  269. EventData *pData = CreateNewEventData1();
  270. if(!pData)
  271. {
  272. return E_OUTOFMEMORY;
  273. }
  274. pData->m_fDoublePercentsInStrings = fDoublePercentInStrings;
  275. HRESULT hr = VariantCopy((VARIANT*)&pData->m_vtData, (VARIANT*)pvar);
  276. myRegisterMemAlloc((VARIANT *) &pData->m_vtData, 0, CSM_VARIANT);
  277. return hr;
  278. }
  279. HRESULT CAuditEvent::AddData(ULARGE_INTEGER *puliValue)
  280. {
  281. PROPVARIANT *pvtData = CreateNewEventData();
  282. DWORD dwDataLen = sizeof(*puliValue);
  283. if(!pvtData)
  284. {
  285. return E_OUTOFMEMORY;
  286. }
  287. V_VT(pvtData) = VT_UI8;
  288. memcpy(&pvtData->uhVal, puliValue, dwDataLen);
  289. return S_OK;
  290. }
  291. PROPVARIANT *CAuditEvent::CreateNewEventData()
  292. {
  293. EventData *pData = CreateNewEventData1();
  294. return &pData->m_vtData;
  295. }
  296. CAuditEvent::EventData *CAuditEvent::CreateNewEventData1()
  297. {
  298. EventData *pData = new EventData;
  299. if(!pData)
  300. {
  301. return NULL;
  302. }
  303. m_pEventDataList[m_cEventData++] = pData;
  304. return pData;
  305. }
  306. HRESULT ConvertToStringBOOL(
  307. BOOL fVal,
  308. LPWSTR *ppwszOut)
  309. {
  310. LPCWSTR pwszBoolVal =
  311. fVal==VARIANT_TRUE?
  312. g_pwszYes:
  313. g_pwszNo;
  314. *ppwszOut = (LPWSTR) LocalAlloc(
  315. LMEM_FIXED,
  316. sizeof(WCHAR)*(wcslen(pwszBoolVal)+1));
  317. if(!*ppwszOut)
  318. {
  319. return E_OUTOFMEMORY;
  320. }
  321. wcscpy(*ppwszOut, pwszBoolVal);
  322. return S_OK;
  323. }
  324. HRESULT CAuditEvent::EventData::ConvertToString(LPWSTR *ppwszValue)
  325. {
  326. HRESULT hr = S_OK;
  327. switch(V_VT(&m_vtData))
  328. {
  329. case VT_I2:
  330. hr = ConvertToStringI2I4(V_I2(&m_vtData), ppwszValue);
  331. break;
  332. case VT_BYREF|VT_I2:
  333. hr = ConvertToStringI2I4(*V_I2REF(&m_vtData), ppwszValue);
  334. break;
  335. case VT_I4:
  336. hr = ConvertToStringI2I4(V_I4(&m_vtData), ppwszValue);
  337. break;
  338. case VT_BYREF|VT_I4:
  339. hr = ConvertToStringI2I4(*V_I4REF(&m_vtData), ppwszValue);
  340. break;
  341. case VT_UI2:
  342. hr = ConvertToStringUI2UI4(V_UI2(&m_vtData), ppwszValue);
  343. break;
  344. case VT_BYREF|VT_UI2:
  345. hr = ConvertToStringUI2UI4(*V_UI2REF(&m_vtData), ppwszValue);
  346. break;
  347. case VT_UI4:
  348. hr = ConvertToStringUI2UI4(V_UI4(&m_vtData), ppwszValue);
  349. break;
  350. case VT_BYREF|VT_UI4:
  351. hr = ConvertToStringUI2UI4(*V_UI4REF(&m_vtData), ppwszValue);
  352. break;
  353. case VT_BLOB:
  354. // We don't call CryptBinaryToString directly anywhere in the CA tree.
  355. // This avoids errors when linking in the CryptBinaryToString code
  356. // for NT 4 reskit builds.
  357. hr = myCryptBinaryToString(
  358. m_vtData.blob.pBlobData,
  359. m_vtData.blob.cbSize,
  360. CRYPT_STRING_BASE64,
  361. ppwszValue);
  362. break;
  363. case VT_BOOL:
  364. hr = ConvertToStringBOOL(V_BOOL(&m_vtData), ppwszValue);
  365. break;
  366. case VT_BOOL|VT_BYREF:
  367. hr = ConvertToStringBOOL(*V_BOOLREF(&m_vtData), ppwszValue);
  368. break;
  369. case VT_LPWSTR:
  370. hr = ConvertToStringWSZ(
  371. m_vtData.pwszVal,
  372. ppwszValue,
  373. m_fDoublePercentsInStrings);
  374. break;
  375. case VT_BSTR:
  376. hr = ConvertToStringWSZ(
  377. V_BSTR(&m_vtData),
  378. ppwszValue,
  379. m_fDoublePercentsInStrings);
  380. break;
  381. case VT_BSTR|VT_BYREF:
  382. hr = ConvertToStringWSZ(
  383. *V_BSTRREF(&m_vtData),
  384. ppwszValue,
  385. m_fDoublePercentsInStrings);
  386. break;
  387. case VT_FILETIME:
  388. hr = myFileTimeToWszTime(
  389. &m_vtData.filetime,
  390. TRUE,
  391. ppwszValue);
  392. break;
  393. case VT_ARRAY|VT_UI1:
  394. hr = ConvertToStringArrayUI1(V_ARRAY(&m_vtData), ppwszValue);
  395. break;
  396. case VT_ARRAY|VT_UI1|VT_BYREF:
  397. hr = ConvertToStringArrayUI1(*V_ARRAYREF(&m_vtData), ppwszValue);
  398. break;
  399. case VT_ARRAY|VT_BSTR:
  400. hr = ConvertToStringArrayBSTR(
  401. V_ARRAY(&m_vtData),
  402. ppwszValue,
  403. m_fDoublePercentsInStrings);
  404. break;
  405. case VT_ARRAY|VT_BSTR|VT_BYREF:
  406. hr = ConvertToStringArrayBSTR(
  407. *V_ARRAYREF(&m_vtData),
  408. ppwszValue,
  409. m_fDoublePercentsInStrings);
  410. break;
  411. default:
  412. {
  413. LPCWSTR pwszValOut = cAuditString_UnknownDataType;
  414. VARIANT varOut;
  415. VariantInit(&varOut);
  416. hr = VariantChangeType(&varOut, (VARIANT*)&m_vtData, 0, VT_BSTR);
  417. if(S_OK==hr)
  418. {
  419. pwszValOut = V_BSTR(&varOut);
  420. }
  421. *ppwszValue = (LPWSTR) LocalAlloc(
  422. LMEM_FIXED,
  423. sizeof(WCHAR)*(wcslen(pwszValOut)+1));
  424. if(!*ppwszValue)
  425. {
  426. return E_OUTOFMEMORY;
  427. }
  428. wcscpy(*ppwszValue, pwszValOut);
  429. VariantClear(&varOut);
  430. hr = S_OK;
  431. }
  432. break;
  433. }
  434. return hr;
  435. }
  436. HRESULT CAuditEvent::Report(bool fSuccess /* = true */)
  437. {
  438. HRESULT hr;
  439. AUTHZ_AUDIT_EVENT_HANDLE AuthzAIH = NULL;
  440. PAUDIT_PARAMS pAuditParams = NULL;
  441. PAUDIT_PARAM pParamArray = NULL;
  442. if(!IsEventEnabled())
  443. {
  444. return S_OK;
  445. }
  446. hr = BuildAuditParamArray(pParamArray);
  447. _JumpIfError(hr, error, "GetAuditText");
  448. if(!AuthziAllocateAuditParams(
  449. &pAuditParams,
  450. (USHORT)(m_cEventData+2))) // authz adds 2
  451. { // extra params
  452. hr = myHLastError(); // internally
  453. _JumpError(hr, error, "AuthziAllocateAuditParams");
  454. }
  455. #ifndef _DISABLE_AUTHZ_
  456. if(!AuthziInitializeAuditParamsFromArray(
  457. fSuccess?APF_AuditSuccess:APF_AuditFailure,
  458. g_AuthzCertSrvRM,
  459. (USHORT)m_cEventData,
  460. pParamArray,
  461. pAuditParams))
  462. #else
  463. SetLastError(E_INVALIDARG);
  464. #endif
  465. {
  466. hr = myHLastError();
  467. _JumpError(hr, error, "AuthziInitializeAuditParamsFromArray");
  468. }
  469. if (!AuthziInitializeAuditEvent(0,
  470. g_AuthzCertSrvRM,
  471. m_hAuditEventType,
  472. pAuditParams,
  473. NULL,
  474. INFINITE,
  475. L"",
  476. L"",
  477. L"",
  478. L"",
  479. &AuthzAIH))
  480. {
  481. hr = myHLastError();
  482. _JumpIfError(hr, error, "AuthzInitializeAuditInfo");
  483. }
  484. if(!AuthziLogAuditEvent( 0, AuthzAIH, NULL ))
  485. {
  486. hr = myHLastError();
  487. _JumpIfError(hr, error, "AuthzGenAuditEvent");
  488. }
  489. DBGPRINT((
  490. DBG_SS_AUDIT,
  491. "Audit event ID=%d\n",
  492. m_ulEventID));
  493. error:
  494. if(AuthzAIH)
  495. {
  496. AuthzFreeAuditEvent(AuthzAIH);
  497. }
  498. if(pAuditParams)
  499. {
  500. AuthziFreeAuditParams(pAuditParams);
  501. }
  502. FreeAuditParamArray(pParamArray);
  503. return hr;
  504. }
  505. HRESULT CAuditEvent::SaveFilter(LPCWSTR pcwszSanitizedName)
  506. {
  507. return mySetCertRegDWValue(
  508. pcwszSanitizedName,
  509. NULL,
  510. NULL,
  511. wszREGAUDITFILTER,
  512. m_dwFilter);
  513. }
  514. HRESULT CAuditEvent::LoadFilter(LPCWSTR pcwszSanitizedName)
  515. {
  516. return myGetCertRegDWValue(
  517. pcwszSanitizedName,
  518. NULL,
  519. NULL,
  520. wszREGAUDITFILTER,
  521. &m_dwFilter);
  522. }
  523. HRESULT CAuditEvent::Impersonate()
  524. {
  525. HRESULT hr;
  526. HANDLE hThread = NULL;
  527. CSASSERT(NULL==m_pISS);
  528. CSASSERT(NULL==m_hClientToken);
  529. if (NULL == m_hRpc)
  530. {
  531. // dcom impersonate
  532. hr = CoGetCallContext(IID_IServerSecurity, (void**)&m_pISS);
  533. _JumpIfError(hr, error, "CoGetCallContext");
  534. hr = m_pISS->ImpersonateClient();
  535. _JumpIfError(hr, error, "ImpersonateClient");
  536. }
  537. else
  538. {
  539. // rpc impersonate
  540. hr = RpcImpersonateClient((RPC_BINDING_HANDLE) m_hRpc);
  541. if (S_OK != hr)
  542. {
  543. hr = myHError(hr);
  544. _JumpError(hr, error, "RpcImpersonateClient");
  545. }
  546. }
  547. hThread = GetCurrentThread();
  548. if (NULL == hThread)
  549. {
  550. hr = myHLastError();
  551. _JumpIfError(hr, error, "GetCurrentThread");
  552. }
  553. if (!OpenThreadToken(hThread,
  554. TOKEN_QUERY | TOKEN_DUPLICATE,
  555. FALSE, // client impersonation
  556. &m_hClientToken))
  557. {
  558. hr = myHLastError();
  559. _JumpIfError(hr, error, "OpenThreadToken");
  560. }
  561. error:
  562. if(S_OK!=hr)
  563. {
  564. if(NULL!=m_pISS)
  565. {
  566. m_pISS->Release();
  567. m_pISS = NULL;
  568. }
  569. }
  570. if (NULL != hThread)
  571. {
  572. CloseHandle(hThread);
  573. }
  574. return hr;
  575. }
  576. HRESULT CAuditEvent::RevertToSelf()
  577. {
  578. HRESULT hr = S_OK;
  579. // CSASSERT(m_pISS||m_hRpc);
  580. if (NULL != m_hRpc) // rpc
  581. {
  582. hr = RpcRevertToSelf();
  583. if (S_OK != hr)
  584. {
  585. hr = myHError(hr);
  586. _JumpError(hr, error, "RpcRevertToSelf");
  587. }
  588. m_hRpc = NULL;
  589. }
  590. else if(m_pISS) // dcom
  591. {
  592. hr = m_pISS->RevertToSelf();
  593. _JumpIfError(hr, error, "IServerSecurity::RpcRevertToSelf");
  594. m_pISS->Release();
  595. m_pISS = NULL;
  596. }
  597. error:
  598. return hr;
  599. }
  600. HANDLE CAuditEvent::GetClientToken()
  601. {
  602. CSASSERT(m_hClientToken);
  603. HANDLE hSave = m_hClientToken;
  604. m_hClientToken = NULL;
  605. return hSave;
  606. }
  607. // dwAuditFlags - not asking for both success and failure implicitely
  608. // means the handles will be cached for future audit
  609. HRESULT
  610. CAuditEvent::AccessCheck(
  611. ACCESS_MASK Mask,
  612. DWORD dwAuditFlags,
  613. handle_t hRpc,
  614. HANDLE *phToken)
  615. {
  616. HRESULT hr = S_OK;
  617. LUID luid = {0,0};
  618. bool fAccessAllowed = false;
  619. DWORD dwRoles = 0;
  620. bool fImpersonating = false;
  621. FreeCachedHandles();
  622. m_hRpc = hRpc;
  623. if (!g_CASD.IsInitialized())
  624. {
  625. hr = HRESULT_FROM_WIN32(ERROR_NOT_READY);
  626. _JumpError(hr, error, "Security not enabled");
  627. }
  628. hr = g_CASD.LockGet(&m_pCASD);
  629. _JumpIfError(hr, error, "CProtectedSecurityDescriptor::LockGet");
  630. hr = Impersonate();
  631. _JumpIfError(hr, error, "CAuditEvent::Impersonate");
  632. fImpersonating = true;
  633. // fail if RPC/COM encryption is required but client auth level is not
  634. // "privacy"
  635. hr = EnforceEncryption(CA_ACCESS_ENROLL==Mask);
  636. _JumpIfError(hr, error, "EnforceEncryption");
  637. hr = EnforceLocalVsRemote(Mask);
  638. _JumpIfError(hr, error, "EnforceLocalVsRemote");
  639. if(!AuthzInitializeContextFromToken(
  640. 0,
  641. m_hClientToken,
  642. g_AuthzCertSrvRM,
  643. NULL,
  644. luid,
  645. NULL,
  646. &m_ClientContext))
  647. {
  648. hr = myHLastError();
  649. _PrintError(hr, "AuthzInitializeContextFromToken");
  650. if (E_INVALIDARG == hr && (!IsWhistler() || 2 <= g_fAdvancedServer))
  651. {
  652. hr = S_OK;
  653. fAccessAllowed = TRUE;
  654. }
  655. goto error;
  656. }
  657. if(Mask & CA_ACCESS_LOCALADMIN)
  658. {
  659. bool fLocalAdmin;
  660. hr = myIsCurrentUserBuiltinAdmin(&fLocalAdmin);
  661. _JumpIfError(hr, error, "myIsCurrentUserBuiltinAdmin");
  662. if(fLocalAdmin)
  663. {
  664. dwRoles |= CA_ACCESS_LOCALADMIN;
  665. }
  666. }
  667. RevertToSelf();
  668. fImpersonating = false;
  669. // Get privilege based roles if checking access on a privilege role
  670. // or if role separation is enabled when we have to know all roles
  671. if(IsEventRoleSeparationEnabled() ||
  672. Mask & (CA_ACCESS_OPERATOR|CA_ACCESS_AUDITOR|CA_ACCESS_LOCALADMIN))
  673. {
  674. hr = GetPrivilegeRoles(&dwRoles);
  675. _JumpIfError(hr, error, "CAuditEvent::GetPrivilegeRolesCount");
  676. hr = BuildPrivilegeSecurityDescriptor(dwRoles);
  677. _JumpIfError(hr, error, "CAuditEvent::BuildPrivilegeSecurityDescriptor");
  678. }
  679. // Get security descriptor based roles
  680. m_Request.DesiredAccess = MAXIMUM_ALLOWED;
  681. CSASSERT(!m_AuthzHandle);
  682. if(!AuthzAccessCheck(
  683. 0,
  684. m_ClientContext,
  685. &m_Request,
  686. NULL, //no audit
  687. m_pCASD,
  688. m_pSDPrivileges?(&m_pSDPrivileges):NULL,
  689. m_pSDPrivileges?1:0,
  690. &m_Reply,
  691. IsEventEnabled()?&m_AuthzHandle:NULL)) // no caching if no audit
  692. // event will be generated
  693. {
  694. hr = myHLastError();
  695. _JumpError(hr, error, "AuthzAccessCheck");
  696. }
  697. dwRoles |= m_Reply.GrantedAccessMask[0];
  698. if(m_Reply.Error[0]==ERROR_SUCCESS &&
  699. m_Reply.GrantedAccessMask[0]&Mask)
  700. {
  701. fAccessAllowed = true;
  702. }
  703. if(IsEventRoleSeparationEnabled() &&
  704. GetBitCount(dwRoles&CA_ACCESS_MASKROLES)>1)
  705. {
  706. hr = CERTSRV_E_ROLECONFLICT;
  707. fAccessAllowed = false;
  708. // don't return yet, we need to generate an audit
  709. }
  710. // Next is a fake access check to generate an audit.
  711. // Access is denied if:
  712. // - role separation is enabled and user has more than one role
  713. // - none of the roles requested is allowed
  714. // Generate audit if event is enabled and
  715. if(IsEventEnabled() &&
  716. (!fAccessAllowed && !(dwAuditFlags&m_gcNoAuditFailure) ||
  717. fAccessAllowed && !(dwAuditFlags&m_gcNoAuditSuccess)))
  718. {
  719. m_Request.DesiredAccess =
  720. fAccessAllowed?
  721. m_Reply.GrantedAccessMask[0]&Mask:
  722. Mask;
  723. if(CERTSRV_E_ROLECONFLICT==hr)
  724. m_Request.DesiredAccess = 0x0000ffff; //force a failure audit
  725. HRESULT hr2 = CachedGenerateAudit();
  726. if(S_OK != hr2)
  727. {
  728. hr = hr2;
  729. _JumpIfError(hr, error, "CAuditEvent::CachedGenerateAudit");
  730. }
  731. }
  732. if(phToken)
  733. {
  734. *phToken = GetClientToken();
  735. }
  736. error:
  737. if(fImpersonating)
  738. {
  739. RevertToSelf();
  740. }
  741. if(!IsEventEnabled())
  742. {
  743. FreeCachedHandles();
  744. }
  745. if(S_OK==hr)
  746. {
  747. hr = fAccessAllowed?S_OK:E_ACCESSDENIED;
  748. }
  749. return(hr);
  750. }
  751. HRESULT
  752. CAuditEvent::CachedGenerateAudit()
  753. {
  754. HRESULT hr = S_OK;
  755. AUTHZ_AUDIT_EVENT_HANDLE AuditInfo = NULL;
  756. PAUDIT_PARAMS pAuditParams = NULL;
  757. PAUDIT_PARAM pParamArray = NULL;
  758. if(!IsEventEnabled())
  759. {
  760. FreeCachedHandles();
  761. return S_OK;
  762. }
  763. CSASSERT(m_AuthzHandle);
  764. hr = BuildAuditParamArray(pParamArray);
  765. _JumpIfError(hr, error, "GetAuditText");
  766. if(!AuthziAllocateAuditParams(
  767. &pAuditParams,
  768. (USHORT)(m_cEventData+2))) // authz adds 2
  769. { // extra params
  770. hr = myHLastError(); // internally
  771. _JumpError(hr, error, "AuthziAllocateAuditParams");
  772. }
  773. #ifndef _DISABLE_AUTHZ_
  774. if(!AuthziInitializeAuditParamsFromArray(
  775. APF_AuditSuccess|APF_AuditFailure,
  776. g_AuthzCertSrvRM,
  777. (USHORT)m_cEventData,
  778. pParamArray,
  779. pAuditParams))
  780. #else
  781. SetLastError(E_INVALIDARG);
  782. #endif
  783. {
  784. hr = myHLastError();
  785. _JumpError(hr, error, "AuthzInitAuditParams");
  786. }
  787. if(!AuthziInitializeAuditEvent(
  788. 0,
  789. g_AuthzCertSrvRM,
  790. m_hAuditEventType,
  791. pAuditParams,
  792. NULL,
  793. INFINITE,
  794. L"",
  795. L"",
  796. L"",
  797. L"",
  798. &AuditInfo))
  799. {
  800. hr = myHLastError();
  801. _JumpError(hr, error, "AuthzInitAuditInfoHandle");
  802. }
  803. if(!AuthzCachedAccessCheck(
  804. 0,
  805. m_AuthzHandle,
  806. &m_Request,
  807. AuditInfo,
  808. &m_Reply))
  809. {
  810. hr = myHLastError();
  811. _JumpError(hr, error, "AuthzCachedAccessCheck");
  812. }
  813. error:
  814. if(AuditInfo)
  815. {
  816. AuthzFreeAuditEvent(AuditInfo);
  817. }
  818. if(pAuditParams)
  819. {
  820. AuthziFreeAuditParams(pAuditParams);
  821. }
  822. FreeCachedHandles();
  823. FreeAuditParamArray(pParamArray);
  824. return hr;
  825. }
  826. void CAuditEvent::FreeCachedHandles()
  827. {
  828. if(m_hClientToken)
  829. {
  830. CloseHandle(m_hClientToken);
  831. m_hClientToken = NULL;
  832. }
  833. if(m_AuthzHandle)
  834. {
  835. AuthzFreeHandle(m_AuthzHandle);
  836. m_AuthzHandle = NULL;
  837. }
  838. if(m_pCASD)
  839. {
  840. g_CASD.Unlock();
  841. m_pCASD = NULL;
  842. }
  843. if(m_ClientContext)
  844. {
  845. AuthzFreeContext(m_ClientContext);
  846. m_ClientContext = NULL;
  847. }
  848. if(m_pUserSid)
  849. {
  850. LocalFree(m_pUserSid);
  851. m_pUserSid = NULL;
  852. }
  853. if(m_pSDPrivileges)
  854. {
  855. LocalFree(m_pSDPrivileges);
  856. m_pSDPrivileges = NULL;
  857. }
  858. if(m_pDaclPrivileges)
  859. {
  860. LocalFree(m_pDaclPrivileges);
  861. m_pDaclPrivileges = NULL;
  862. }
  863. }
  864. HRESULT CAuditEvent::RoleSeparationFlagSave(LPCWSTR pcwszSanitizedName)
  865. {
  866. return mySetCertRegDWValue(
  867. pcwszSanitizedName,
  868. NULL,
  869. NULL,
  870. wszREGROLESEPARATIONENABLED,
  871. RoleSeparationIsEnabled()?1:0);
  872. }
  873. HRESULT CAuditEvent::RoleSeparationFlagLoad(LPCWSTR pcwszSanitizedName)
  874. {
  875. DWORD dwFlags = 0;
  876. HRESULT hr = myGetCertRegDWValue(
  877. pcwszSanitizedName,
  878. NULL,
  879. NULL,
  880. wszREGROLESEPARATIONENABLED,
  881. &dwFlags);
  882. if(S_OK==hr)
  883. {
  884. RoleSeparationEnable(dwFlags?true:false);
  885. }
  886. return hr;
  887. }
  888. HRESULT CAuditEvent::GetPrivilegeRoles(PDWORD pdwRoles)
  889. {
  890. HRESULT hr = S_OK;
  891. PTOKEN_USER pTokenUser = NULL;
  892. DWORD cbTokenUser = 0;
  893. PTOKEN_GROUPS pTokenGroups = NULL;
  894. DWORD cbTokenGroups = 0;
  895. DWORD dwRoles = 0;
  896. LSA_HANDLE lsahPolicyHandle = NULL;
  897. LSA_OBJECT_ATTRIBUTES ObjectAttributes;
  898. NTSTATUS NTStatus;
  899. // first get roles for the user itself
  900. AuthzGetInformationFromContext(
  901. m_ClientContext,
  902. AuthzContextInfoUserSid,
  903. 0,
  904. &cbTokenUser,
  905. NULL);
  906. if(GetLastError()!=ERROR_INSUFFICIENT_BUFFER)
  907. {
  908. hr = myHLastError();
  909. _JumpError(hr, error, "AuthzGetContextInformation");
  910. }
  911. pTokenUser = (PTOKEN_USER)LocalAlloc(LMEM_FIXED, cbTokenUser);
  912. _JumpIfAllocFailed(pTokenUser, error);
  913. if(!AuthzGetInformationFromContext(
  914. m_ClientContext,
  915. AuthzContextInfoUserSid,
  916. cbTokenUser,
  917. &cbTokenUser,
  918. pTokenUser))
  919. {
  920. hr = myHLastError();
  921. _JumpError(hr, error, "AuthzGetContextInformation");
  922. }
  923. // Object attributes are reserved, so initalize to zeroes.
  924. ZeroMemory(&ObjectAttributes, sizeof(ObjectAttributes));
  925. NTStatus = LsaOpenPolicy(
  926. NULL,
  927. &ObjectAttributes,
  928. POLICY_LOOKUP_NAMES,
  929. &lsahPolicyHandle);
  930. if(STATUS_SUCCESS!=NTStatus)
  931. {
  932. hr = myHError(LsaNtStatusToWinError(NTStatus));
  933. _JumpError(hr, error, "LsaOpenPolicy");
  934. }
  935. CSASSERT(!m_pUserSid);
  936. m_pUserSid = (PSID)LocalAlloc(LMEM_FIXED, GetLengthSid(pTokenUser->User.Sid));
  937. _JumpIfAllocFailed(m_pUserSid, error);
  938. CopySid(
  939. GetLengthSid(pTokenUser->User.Sid),
  940. m_pUserSid,
  941. pTokenUser->User.Sid);
  942. hr = GetUserPrivilegeRoles(lsahPolicyHandle, &pTokenUser->User, &dwRoles);
  943. if(HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)==hr)
  944. {
  945. hr =S_OK;
  946. }
  947. _JumpIfError(hr, error, "CAuditEvent::GetUserPrivilegeRoles");
  948. *pdwRoles |= dwRoles;
  949. // then find the roles assigned to the groups the user is member of
  950. AuthzGetInformationFromContext(
  951. m_ClientContext,
  952. AuthzContextInfoGroupsSids,
  953. 0,
  954. &cbTokenGroups,
  955. NULL);
  956. if(GetLastError()!=ERROR_INSUFFICIENT_BUFFER)
  957. {
  958. hr = myHLastError();
  959. _JumpError(hr, error, "AuthzGetContextInformation");
  960. }
  961. pTokenGroups = (PTOKEN_GROUPS)LocalAlloc(LMEM_FIXED, cbTokenGroups);
  962. _JumpIfAllocFailed(pTokenGroups, error);
  963. if(!AuthzGetInformationFromContext(
  964. m_ClientContext,
  965. AuthzContextInfoGroupsSids,
  966. cbTokenGroups,
  967. &cbTokenGroups,
  968. pTokenGroups))
  969. {
  970. hr = myHLastError();
  971. _JumpError(hr, error, "AuthzGetContextInformation");
  972. }
  973. for(DWORD cGroups = 0; cGroups<pTokenGroups->GroupCount; cGroups++)
  974. {
  975. dwRoles = 0;
  976. hr = GetUserPrivilegeRoles(
  977. lsahPolicyHandle,
  978. &pTokenGroups->Groups[cGroups],
  979. &dwRoles);
  980. if(HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)==hr)
  981. {
  982. hr =S_OK;
  983. }
  984. _JumpIfError(hr, error, "CAuditEvent::GetUserPrivilegeRoles");
  985. *pdwRoles |= dwRoles;
  986. }
  987. error:
  988. if(pTokenUser)
  989. {
  990. LocalFree(pTokenUser);
  991. }
  992. if(pTokenGroups)
  993. {
  994. LocalFree(pTokenGroups);
  995. }
  996. if(lsahPolicyHandle)
  997. {
  998. LsaClose(lsahPolicyHandle);
  999. }
  1000. return hr;
  1001. }
  1002. HRESULT CAuditEvent::GetUserPrivilegeRoles(
  1003. LSA_HANDLE lsah,
  1004. PSID_AND_ATTRIBUTES pSA,
  1005. PDWORD pdwRoles)
  1006. {
  1007. NTSTATUS NTStatus;
  1008. PLSA_UNICODE_STRING pLSAString = NULL;
  1009. ULONG cRights, c;
  1010. NTStatus = LsaEnumerateAccountRights(
  1011. lsah,
  1012. pSA->Sid,
  1013. &pLSAString,
  1014. &cRights);
  1015. if(STATUS_SUCCESS!=NTStatus)
  1016. {
  1017. return(myHError(LsaNtStatusToWinError(NTStatus)));
  1018. }
  1019. for(c=0; c<cRights; c++)
  1020. {
  1021. if(0==_wcsicmp(SE_SECURITY_NAME, pLSAString[c].Buffer))
  1022. {
  1023. *pdwRoles |= CA_ACCESS_AUDITOR;
  1024. }
  1025. else if(0==_wcsicmp(SE_BACKUP_NAME, pLSAString[c].Buffer))
  1026. {
  1027. *pdwRoles |= CA_ACCESS_OPERATOR;
  1028. }
  1029. }
  1030. if(pLSAString)
  1031. {
  1032. LsaFreeMemory(pLSAString);
  1033. }
  1034. return S_OK;
  1035. }
  1036. HRESULT
  1037. CAuditEvent::GetMyRoles(
  1038. DWORD *pdwRoles)
  1039. {
  1040. HRESULT hr = S_OK;
  1041. LUID luid = {0,0};
  1042. DWORD dwRoles = 0;
  1043. bool fImpersonating = false;
  1044. if (!g_CASD.IsInitialized())
  1045. {
  1046. hr = HRESULT_FROM_WIN32(ERROR_NOT_READY);
  1047. _JumpError(hr, error, "Security not enabled");
  1048. }
  1049. hr = g_CASD.LockGet(&m_pCASD);
  1050. _JumpIfError(hr, error, "CProtectedSecurityDescriptor::LockGet");
  1051. hr = Impersonate();
  1052. _JumpIfError(hr, error, "CAuditEvent::Impersonate");
  1053. // fail if RPC/COM encryption is required but client auth level is not
  1054. // "privacy"
  1055. hr = EnforceEncryption(false); // false == admin interface
  1056. _JumpIfError(hr, error, "EnforceEncryption");
  1057. fImpersonating = true;
  1058. if(!AuthzInitializeContextFromToken(
  1059. 0,
  1060. m_hClientToken,
  1061. g_AuthzCertSrvRM,
  1062. NULL,
  1063. luid,
  1064. NULL,
  1065. &m_ClientContext))
  1066. {
  1067. hr = myHLastError();
  1068. _JumpError(hr, error, "AuthzInitializeContextFromToken");
  1069. }
  1070. RevertToSelf();
  1071. fImpersonating = false;
  1072. hr = GetPrivilegeRoles(&dwRoles);
  1073. _JumpIfError(hr, error, "CAuditEvent::GetPrivilegeRoles");
  1074. m_Request.DesiredAccess = MAXIMUM_ALLOWED;
  1075. m_Reply.GrantedAccessMask[0] = 0;
  1076. if(!AuthzAccessCheck(
  1077. 0,
  1078. m_ClientContext,
  1079. &m_Request,
  1080. NULL, //no audit
  1081. m_pCASD,
  1082. NULL,
  1083. 0,
  1084. &m_Reply,
  1085. NULL))
  1086. {
  1087. hr = myHLastError();
  1088. _JumpError(hr, error, "AuthzAccessCheck");
  1089. }
  1090. dwRoles |= (m_Reply.GrantedAccessMask[0] &
  1091. (CA_ACCESS_MASKROLES | // returned mask could also
  1092. CA_ACCESS_READ | // include generic rights (like
  1093. CA_ACCESS_ENROLL)); // read and write DACL) which
  1094. // we are not interested in
  1095. *pdwRoles = dwRoles;
  1096. error:
  1097. if(fImpersonating)
  1098. {
  1099. RevertToSelf();
  1100. }
  1101. FreeCachedHandles();
  1102. return(hr);
  1103. }
  1104. // Build a one ace DACL security descriptor with the roles
  1105. // passed in
  1106. HRESULT CAuditEvent::BuildPrivilegeSecurityDescriptor(DWORD dwRoles)
  1107. {
  1108. HRESULT hr = S_OK;
  1109. DWORD dwDaclSize;
  1110. PSID pOwnerSid = NULL; // no free
  1111. PSID pGroupSid = NULL; // no free
  1112. BOOL fDefaulted;
  1113. CSASSERT(NULL == m_pSDPrivileges);
  1114. CSASSERT(NULL == m_pDaclPrivileges);
  1115. m_pSDPrivileges = (PSECURITY_DESCRIPTOR)LocalAlloc(
  1116. LMEM_FIXED,
  1117. SECURITY_DESCRIPTOR_MIN_LENGTH);
  1118. _JumpIfAllocFailed(m_pSDPrivileges, error);
  1119. if (!InitializeSecurityDescriptor(
  1120. m_pSDPrivileges,
  1121. SECURITY_DESCRIPTOR_REVISION))
  1122. {
  1123. hr = myHLastError();
  1124. _JumpError(hr, error, "InitializeSecurityDescriptor");
  1125. }
  1126. CSASSERT(m_pUserSid && IsValidSid(m_pUserSid));
  1127. dwDaclSize = sizeof(ACL) +
  1128. sizeof(ACCESS_ALLOWED_ACE)-sizeof(DWORD)+
  1129. GetLengthSid(m_pUserSid);
  1130. m_pDaclPrivileges = (PACL)LocalAlloc(LMEM_FIXED|LMEM_ZEROINIT, dwDaclSize);
  1131. _JumpIfAllocFailed(m_pDaclPrivileges, error);
  1132. if(!InitializeAcl(m_pDaclPrivileges, dwDaclSize, ACL_REVISION))
  1133. {
  1134. hr = myHLastError();
  1135. _JumpError(hr, error, "InitializeAcl");
  1136. }
  1137. if(!AddAccessAllowedAce(
  1138. m_pDaclPrivileges,
  1139. ACL_REVISION,
  1140. dwRoles,
  1141. m_pUserSid))
  1142. {
  1143. hr = myHLastError();
  1144. _JumpError(hr, error, "AddAccessAllowedAce");
  1145. }
  1146. if(!GetSecurityDescriptorOwner(m_pCASD,
  1147. &pOwnerSid,
  1148. &fDefaulted))
  1149. {
  1150. hr = myHLastError();
  1151. _JumpError(hr, error, "GetSecurityDescriptorOwner");
  1152. }
  1153. if(!SetSecurityDescriptorOwner(m_pSDPrivileges,
  1154. pOwnerSid,
  1155. fDefaulted))
  1156. {
  1157. hr = myHLastError();
  1158. _JumpError(hr, error, "SetSecurityDescriptorOwner");
  1159. }
  1160. if(!GetSecurityDescriptorGroup(m_pCASD,
  1161. &pGroupSid,
  1162. &fDefaulted))
  1163. {
  1164. hr = myHLastError();
  1165. _JumpError(hr, error, "GetSecurityDescriptorGroup");
  1166. }
  1167. if(!SetSecurityDescriptorGroup(m_pSDPrivileges,
  1168. pGroupSid,
  1169. fDefaulted))
  1170. {
  1171. hr = myHLastError();
  1172. _JumpError(hr, error, "SetSecurityDescriptorGroup");
  1173. }
  1174. if(!SetSecurityDescriptorDacl(m_pSDPrivileges,
  1175. TRUE,
  1176. m_pDaclPrivileges,
  1177. FALSE))
  1178. {
  1179. hr = myHLastError();
  1180. _JumpError(hr, error, "SetSecurityDescriptorDacl");
  1181. }
  1182. CSASSERT(IsValidSecurityDescriptor(m_pSDPrivileges));
  1183. error:
  1184. if(S_OK != hr)
  1185. {
  1186. if(m_pDaclPrivileges)
  1187. {
  1188. LocalFree(m_pDaclPrivileges);
  1189. m_pDaclPrivileges = NULL;
  1190. }
  1191. if(m_pSDPrivileges)
  1192. {
  1193. LocalFree(m_pSDPrivileges);
  1194. m_pSDPrivileges = NULL;
  1195. }
  1196. }
  1197. return hr;
  1198. }
  1199. HRESULT CAuditEvent::BuildAuditParamArray(PAUDIT_PARAM& rpParamArray)
  1200. {
  1201. HRESULT hr = S_OK;
  1202. // number of parameters added should be the same as the number of
  1203. // params defined in the audit format string in msaudite.dll
  1204. CSASSERT(m_cEventData == m_cRequiredEventData);
  1205. rpParamArray = (PAUDIT_PARAM) LocalAlloc(
  1206. LMEM_FIXED | LMEM_ZEROINIT,
  1207. sizeof(AUDIT_PARAM)*m_cEventData);
  1208. _JumpIfAllocFailed(rpParamArray, error);
  1209. for(USHORT c=0;c<m_cEventData;c++)
  1210. {
  1211. rpParamArray[c].Type = APT_String;
  1212. hr = m_pEventDataList[c]->ConvertToString(
  1213. &rpParamArray[c].String);
  1214. _JumpIfError(hr, error, "ConvertToString");
  1215. }
  1216. error:
  1217. return hr;
  1218. }
  1219. void CAuditEvent::FreeAuditParamArray(PAUDIT_PARAM pParamArray)
  1220. {
  1221. if(pParamArray)
  1222. {
  1223. for(USHORT c=0;c<m_cEventData;c++)
  1224. {
  1225. if(pParamArray[c].String)
  1226. LocalFree(pParamArray[c].String);
  1227. }
  1228. LocalFree(pParamArray);
  1229. }
  1230. }
  1231. HRESULT CAuditEvent::EnforceEncryption(bool fRequestInterface)
  1232. {
  1233. HRESULT hr = S_OK;
  1234. if((fRequestInterface?
  1235. IF_ENFORCEENCRYPTICERTREQUEST:
  1236. IF_ENFORCEENCRYPTICERTADMIN) &
  1237. g_InterfaceFlags)
  1238. {
  1239. if(m_pISS) // DCOM
  1240. {
  1241. DWORD dwAuthLevel;
  1242. hr = m_pISS->QueryBlanket(
  1243. NULL, NULL, NULL,
  1244. &dwAuthLevel,
  1245. NULL, NULL, NULL);
  1246. _JumpIfError(hr, error, "IServerSecurity::QueryBlanket");
  1247. if(RPC_C_AUTHN_LEVEL_PKT_PRIVACY != dwAuthLevel)
  1248. {
  1249. hr = E_ACCESSDENIED;
  1250. _JumpError(hr, error, "call not encrypted");
  1251. }
  1252. }
  1253. else // RPC
  1254. {
  1255. CSASSERT(m_hRpc);
  1256. unsigned long ulAuthLevel;
  1257. hr = RpcBindingInqAuthClient(
  1258. m_hRpc,
  1259. NULL, NULL,
  1260. &ulAuthLevel,
  1261. NULL, NULL);
  1262. _JumpIfError(hr, error, "RpcBindingInqAuthClient");
  1263. if(RPC_C_AUTHN_LEVEL_PKT_PRIVACY != ulAuthLevel)
  1264. {
  1265. hr = E_ACCESSDENIED;
  1266. _JumpError(hr, error, "call not encrypted");
  1267. }
  1268. }
  1269. }
  1270. error:
  1271. return hr;
  1272. }
  1273. HRESULT CAuditEvent::EnforceLocalVsRemote(ACCESS_MASK Mask)
  1274. {
  1275. HRESULT hr = S_OK;
  1276. DWORD dwEnforceNoLocalFlag, dwEnforceNoRemoteFlag;
  1277. PSID psidNetwork = NULL;
  1278. BOOL fIsRemote;
  1279. hr = GetNetworkSID(&psidNetwork);
  1280. _JumpIfError(hr, error, "GetLocalSid");
  1281. if(!CheckTokenMembership(m_hClientToken, psidNetwork, &fIsRemote))
  1282. {
  1283. hr = myHLastError();
  1284. _JumpError(hr, error, "CheckTokenMembership");
  1285. }
  1286. switch(Mask)
  1287. {
  1288. case CA_ACCESS_OPERATOR:
  1289. dwEnforceNoRemoteFlag = IF_NOREMOTEICERTADMINBACKUP;
  1290. dwEnforceNoLocalFlag = IF_NOLOCALICERTADMINBACKUP;
  1291. break;
  1292. case CA_ACCESS_ENROLL:
  1293. dwEnforceNoRemoteFlag = IF_NOREMOTEICERTREQUEST;
  1294. dwEnforceNoLocalFlag = IF_NOLOCALICERTREQUEST;
  1295. break;
  1296. default:
  1297. dwEnforceNoRemoteFlag = IF_NOREMOTEICERTADMIN;
  1298. dwEnforceNoLocalFlag = IF_NOLOCALICERTADMIN;
  1299. break;
  1300. }
  1301. if((fIsRemote && (g_InterfaceFlags & dwEnforceNoRemoteFlag)) ||
  1302. (!fIsRemote && (g_InterfaceFlags & dwEnforceNoLocalFlag)))
  1303. {
  1304. hr = E_ACCESSDENIED;
  1305. }
  1306. error:
  1307. if (NULL != psidNetwork)
  1308. {
  1309. FreeSid(psidNetwork);
  1310. }
  1311. return hr;
  1312. }