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.

311 lines
7.9 KiB

  1. //+--------------------------------------------------------------------------
  2. // File: prvlg.cpp
  3. // Contents: privilege manager implementation
  4. //---------------------------------------------------------------------------
  5. #include <pch.cpp>
  6. #include "prvlg.h"
  7. using namespace CertSrv;
  8. LSA_UNICODE_STRING CPrivilegeManager::m_lsaSecurityPrivilege[] =
  9. {
  10. sizeof(SE_SECURITY_NAME)-2,
  11. sizeof(SE_SECURITY_NAME),
  12. SE_SECURITY_NAME
  13. };
  14. LSA_UNICODE_STRING CPrivilegeManager::m_lsaBackupRestorePrivilege[] =
  15. {
  16. {
  17. sizeof(SE_BACKUP_NAME)-2,
  18. sizeof(SE_BACKUP_NAME),
  19. SE_BACKUP_NAME
  20. },
  21. {
  22. sizeof(SE_RESTORE_NAME)-2,
  23. sizeof(SE_RESTORE_NAME),
  24. SE_RESTORE_NAME
  25. }
  26. };
  27. HRESULT CPrivilegeManager::OpenPolicy()
  28. {
  29. HRESULT hr = S_OK;
  30. LSA_OBJECT_ATTRIBUTES ObjectAttributes;
  31. NTSTATUS NTStatus;
  32. ZeroMemory(&ObjectAttributes, sizeof(ObjectAttributes));
  33. NTStatus = LsaOpenPolicy(
  34. NULL,
  35. &ObjectAttributes,
  36. POLICY_CREATE_ACCOUNT | POLICY_LOOKUP_NAMES,
  37. &m_lsah);
  38. if(STATUS_SUCCESS!=NTStatus)
  39. {
  40. hr = HRESULT_FROM_WIN32(LsaNtStatusToWinError(NTStatus));
  41. _JumpError(hr, error, "LsaOpenPolicy");
  42. }
  43. error:
  44. return hr;
  45. }
  46. HRESULT CPrivilegeManager::ClosePolicy()
  47. {
  48. if(m_lsah)
  49. LsaClose(m_lsah);
  50. return S_OK;
  51. }
  52. void CPrivilegeManager::GetPrivilegeString(
  53. DWORD dwRole,
  54. PLSA_UNICODE_STRING &plsastr,
  55. ULONG &cstr)
  56. {
  57. switch(dwRole)
  58. {
  59. case CA_ACCESS_AUDITOR:
  60. plsastr = m_lsaSecurityPrivilege;
  61. cstr = ARRAYSIZE(m_lsaSecurityPrivilege);
  62. break;
  63. case CA_ACCESS_OPERATOR:
  64. plsastr = m_lsaBackupRestorePrivilege;
  65. cstr = ARRAYSIZE(m_lsaBackupRestorePrivilege);
  66. break;
  67. }
  68. }
  69. HRESULT CPrivilegeManager::AddPrivilege(
  70. const PSID pSid,
  71. DWORD dwRole)
  72. {
  73. HRESULT hr = S_OK;
  74. NTSTATUS NTStatus;
  75. PLSA_UNICODE_STRING plsastr = NULL;
  76. ULONG cstr = 0;
  77. GetPrivilegeString(
  78. dwRole,
  79. plsastr,
  80. cstr);
  81. NTStatus = LsaAddAccountRights(
  82. m_lsah,
  83. pSid,
  84. plsastr,
  85. cstr);
  86. if(STATUS_SUCCESS!=NTStatus)
  87. {
  88. hr = HRESULT_FROM_WIN32(LsaNtStatusToWinError(NTStatus));
  89. _JumpError(hr, error, "LsaAddAcountRights");
  90. }
  91. error:
  92. return hr;
  93. }
  94. HRESULT CPrivilegeManager::RemovePrivilege(
  95. const PSID pSid,
  96. DWORD dwRole)
  97. {
  98. HRESULT hr = S_OK;
  99. NTSTATUS NTStatus;
  100. PLSA_UNICODE_STRING plsastr = NULL;
  101. ULONG cstr = 0;
  102. GetPrivilegeString(
  103. dwRole,
  104. plsastr,
  105. cstr);
  106. NTStatus = LsaRemoveAccountRights(
  107. m_lsah,
  108. pSid,
  109. FALSE,
  110. plsastr,
  111. cstr);
  112. if(STATUS_SUCCESS!=NTStatus && STATUS_OBJECT_NAME_NOT_FOUND!=NTStatus)
  113. {
  114. hr = HRESULT_FROM_WIN32(LsaNtStatusToWinError(NTStatus));
  115. _JumpError(hr, error, "LsaRemoveAcountRights");
  116. }
  117. error:
  118. return hr;
  119. }
  120. HRESULT CPrivilegeManager::InitBuffer(
  121. PACCESS_ALLOWED_ACE **buffer,
  122. DWORD cAce)
  123. {
  124. *buffer = (PACCESS_ALLOWED_ACE *)LocalAlloc(LMEM_FIXED,
  125. cAce*sizeof(PACCESS_ALLOWED_ACE));
  126. if(!*buffer)
  127. {
  128. return E_OUTOFMEMORY;
  129. }
  130. ZeroMemory(*buffer, cAce*sizeof(PACCESS_ALLOWED_ACE));
  131. return S_OK;
  132. }
  133. HRESULT CPrivilegeManager::ComputePrivilegeChanges(
  134. const PSECURITY_DESCRIPTOR pOldSD,
  135. const PSECURITY_DESCRIPTOR pNewSD)
  136. {
  137. HRESULT hr = S_OK;
  138. PACCESS_ALLOWED_ACE pOldAce, pNewAce;
  139. DWORD cOldAce, cNewAce;
  140. PACL pOldAcl, pNewAcl; // no free
  141. hr = myGetSecurityDescriptorDacl(
  142. pOldSD,
  143. &pOldAcl);
  144. _JumpIfError(hr, error, "myGetDaclFromInfoSecurityDescriptor");
  145. hr = myGetSecurityDescriptorDacl(
  146. pNewSD,
  147. &pNewAcl);
  148. _JumpIfError(hr, error, "myGetDaclFromInfoSecurityDescriptor");
  149. m_cOldAce = pOldAcl->AceCount;
  150. m_cNewAce = pNewAcl->AceCount;
  151. hr = InitBuffer(
  152. &m_pAddPrivilegeAudit,
  153. m_cNewAce);
  154. _JumpIfError(hr, error, "InitBuffer");
  155. hr = InitBuffer(
  156. &m_pAddPrivilegeBackup,
  157. m_cNewAce);
  158. _JumpIfError(hr, error, "InitBuffer");
  159. hr = InitBuffer(
  160. &m_pRemovePrivilegeAudit,
  161. m_cOldAce);
  162. _JumpIfError(hr, error, "InitBuffer");
  163. hr = InitBuffer(
  164. &m_pRemovePrivilegeBackup,
  165. m_cOldAce);
  166. _JumpIfError(hr, error, "InitBuffer");
  167. for(cNewAce=0; cNewAce<m_cNewAce; cNewAce++)
  168. {
  169. if(!GetAce(pNewAcl, cNewAce, (PVOID*)&pNewAce))
  170. {
  171. hr = myHLastError();
  172. _JumpError(hr, error, "GetAce");
  173. }
  174. if(pNewAce->Mask&CA_ACCESS_AUDITOR)
  175. m_pAddPrivilegeAudit[cNewAce] = pNewAce;
  176. if(pNewAce->Mask&CA_ACCESS_OPERATOR)
  177. m_pAddPrivilegeBackup[cNewAce] = pNewAce;
  178. }
  179. for(cOldAce=0; cOldAce<m_cOldAce; cOldAce++)
  180. {
  181. if(!GetAce(pOldAcl, cOldAce, (PVOID*)&pOldAce))
  182. {
  183. hr = myHLastError();
  184. _JumpError(hr, error, "GetAce");
  185. }
  186. if(pOldAce->Mask&CA_ACCESS_AUDITOR)
  187. m_pRemovePrivilegeAudit[cOldAce] = pOldAce;
  188. if(pOldAce->Mask&CA_ACCESS_OPERATOR)
  189. m_pRemovePrivilegeBackup[cOldAce] = pOldAce;
  190. for(cNewAce=0; cNewAce<m_cNewAce; cNewAce++)
  191. {
  192. if(!GetAce(pNewAcl, cNewAce, (PVOID*)&pNewAce))
  193. {
  194. hr = myHLastError();
  195. _JumpError(hr, error, "GetAce");
  196. }
  197. if(EqualSid((PSID)&pOldAce->SidStart,
  198. (PSID)&pNewAce->SidStart))
  199. {
  200. if((pOldAce->Mask&CA_ACCESS_AUDITOR)&&
  201. (pNewAce->Mask&CA_ACCESS_AUDITOR))
  202. {
  203. m_pRemovePrivilegeAudit[cOldAce] = NULL;
  204. }
  205. if((pOldAce->Mask&CA_ACCESS_OPERATOR)&&
  206. (pNewAce->Mask&CA_ACCESS_OPERATOR))
  207. {
  208. m_pRemovePrivilegeBackup[cOldAce] = NULL;
  209. }
  210. if((pOldAce->Mask&CA_ACCESS_AUDITOR)&&
  211. (pNewAce->Mask&CA_ACCESS_AUDITOR))
  212. {
  213. m_pAddPrivilegeAudit[cNewAce] = NULL;
  214. }
  215. if((pOldAce->Mask&CA_ACCESS_OPERATOR)&&
  216. (pNewAce->Mask&CA_ACCESS_OPERATOR))
  217. {
  218. m_pAddPrivilegeBackup[cNewAce] = NULL;
  219. }
  220. }
  221. }
  222. }
  223. error:
  224. return hr;
  225. }
  226. HRESULT CPrivilegeManager::UpdatePrivileges()
  227. {
  228. HRESULT hr = S_OK;
  229. DWORD cOldAce, cNewAce;
  230. hr = OpenPolicy();
  231. _JumpIfError(hr, error, "CPrivilegeManager::OpenPolicy");
  232. for(cOldAce=0; cOldAce<m_cOldAce; cOldAce++)
  233. {
  234. if(m_pRemovePrivilegeBackup[cOldAce])
  235. {
  236. hr = RemovePrivilege(
  237. (PSID)&(m_pRemovePrivilegeBackup[cOldAce]->SidStart),
  238. CA_ACCESS_OPERATOR);
  239. _JumpIfError(hr, error, "CPrivilegeManager::RemovePrivilege");
  240. }
  241. if(m_pRemovePrivilegeAudit[cOldAce])
  242. {
  243. hr = RemovePrivilege(
  244. (PSID)&(m_pRemovePrivilegeAudit[cOldAce]->SidStart),
  245. CA_ACCESS_AUDITOR);
  246. _JumpIfError(hr, error, "CPrivilegeManager::RemovePrivilege");
  247. }
  248. }
  249. for(cNewAce=0; cNewAce<m_cNewAce; cNewAce++)
  250. {
  251. if(m_pAddPrivilegeBackup[cNewAce])
  252. {
  253. hr = AddPrivilege(
  254. (PSID)&(m_pAddPrivilegeBackup[cNewAce]->SidStart),
  255. CA_ACCESS_OPERATOR);
  256. _JumpIfError(hr, error, "CPrivilegeManager::AddPrivilege");
  257. }
  258. if(m_pAddPrivilegeAudit[cNewAce])
  259. {
  260. hr = AddPrivilege(
  261. (PSID)&(m_pAddPrivilegeAudit[cNewAce]->SidStart),
  262. CA_ACCESS_AUDITOR);
  263. _JumpIfError(hr, error, "CPrivilegeManager::AddPrivilege");
  264. }
  265. }
  266. error:
  267. ClosePolicy();
  268. return hr;
  269. }