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.

378 lines
8.4 KiB

  1. /*****************************************************************************/
  2. /* Copyright (c) 2000-2001 Microsoft Corporation, All Rights Reserved /
  3. /*****************************************************************************/
  4. /*
  5. * SecurityDescriptor.cpp - implementation file for CSecureKernelObj class.
  6. *
  7. * Created: 11-27-00 by Kevin Hughes
  8. */
  9. #include "precomp.h"
  10. #include "AccessEntry.h" // CAccessEntry class
  11. #include "AccessEntryList.h"
  12. #include "aclapi.h"
  13. #include "DACL.h" // CDACL class
  14. #include "SACL.h" // CSACL class
  15. #include "SecurityDescriptor.h"
  16. #include "securefile.h"
  17. #include "tokenprivilege.h"
  18. #include "ImpLogonUser.h"
  19. #include "AdvApi32Api.h"
  20. #include "smartptr.h"
  21. #include "SecureKernelObj.h"
  22. ///////////////////////////////////////////////////////////////////
  23. //
  24. // Function: CSecureKernelObj::CSecureKernelObj
  25. //
  26. // Default class constructor.
  27. //
  28. // Inputs:
  29. // None.
  30. //
  31. // Outputs:
  32. // None.
  33. //
  34. // Returns:
  35. // None.
  36. //
  37. // Comments:
  38. //
  39. ///////////////////////////////////////////////////////////////////
  40. CSecureKernelObj::CSecureKernelObj()
  41. : CSecurityDescriptor()
  42. {
  43. }
  44. ///////////////////////////////////////////////////////////////////
  45. //
  46. // Function: CSecureKernelObj::CSecureKernelObj
  47. //
  48. // Alternate Class CTOR
  49. //
  50. // Inputs:
  51. // LPCWSTR wszObjName - The kernel object to handle
  52. // security for.
  53. // BOOL fGetSACL - Should we get the SACL?
  54. //
  55. // Outputs:
  56. // None.
  57. //
  58. // Returns:
  59. // None.
  60. //
  61. // Comments:
  62. //
  63. ///////////////////////////////////////////////////////////////////
  64. CSecureKernelObj::CSecureKernelObj(
  65. HANDLE hObject,
  66. BOOL fGetSACL /*= TRUE*/ )
  67. : CSecurityDescriptor()
  68. {
  69. SetObject(hObject, fGetSACL);
  70. }
  71. ///////////////////////////////////////////////////////////////////
  72. //
  73. // Function: CSecureKernelObj::CSecureKernelObj
  74. //
  75. // Alternate Class CTOR
  76. //
  77. // Inputs:
  78. // LPCWSTR wszObjName - The object name to handle
  79. // security for.
  80. //
  81. // PSECURITY_DESCRIPTOR pSD - The Security Descriptor to associate with this object
  82. //
  83. // Outputs:
  84. // None.
  85. //
  86. // Returns:
  87. // None.
  88. //
  89. // Comments:
  90. //
  91. ///////////////////////////////////////////////////////////////////
  92. CSecureKernelObj::CSecureKernelObj(
  93. HANDLE hObject,
  94. PSECURITY_DESCRIPTOR pSD)
  95. : CSecurityDescriptor()
  96. {
  97. if(InitSecurity(pSD))
  98. {
  99. // we just get a copy - we don't take ownership.
  100. m_hObject = hObject;
  101. }
  102. }
  103. ///////////////////////////////////////////////////////////////////
  104. //
  105. // Function: CSecureKernelObj::~CSecureKernelObj
  106. //
  107. // Class Destructor.
  108. //
  109. // Inputs:
  110. // None.
  111. //
  112. // Outputs:
  113. // None.
  114. //
  115. // Returns:
  116. // None.
  117. //
  118. // Comments:
  119. //
  120. ///////////////////////////////////////////////////////////////////
  121. CSecureKernelObj::~CSecureKernelObj(void)
  122. {
  123. }
  124. ///////////////////////////////////////////////////////////////////
  125. //
  126. // Function: CSecureKernelObj::SetObject
  127. //
  128. // Public Entry point to set which object this instance
  129. // of the class is to supply security for.
  130. //
  131. // Inputs:
  132. // HANDLE hObject - The object to handle
  133. // security for.
  134. // BOOL fGetSACL - Should we get the SACL?
  135. //
  136. // Outputs:
  137. // None.
  138. //
  139. // Returns:
  140. // DWORD ERROR_SUCCESS if successful
  141. //
  142. // Comments:
  143. //
  144. // This will clear any previously set filenames and/or security
  145. // information.
  146. //
  147. ///////////////////////////////////////////////////////////////////
  148. DWORD CSecureKernelObj::SetObject(
  149. HANDLE hObject,
  150. BOOL fGetSACL /*= TRUE*/ )
  151. {
  152. DWORD dwError = ERROR_SUCCESS;
  153. SECURITY_INFORMATION siFlags = OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION;
  154. // We must have the security privilege enabled in order to access the object's SACL
  155. CTokenPrivilege securityPrivilege( SE_SECURITY_NAME );
  156. BOOL fDisablePrivilege = FALSE;
  157. if ( fGetSACL )
  158. {
  159. fDisablePrivilege = (securityPrivilege.Enable() == ERROR_SUCCESS);
  160. siFlags |= SACL_SECURITY_INFORMATION;
  161. }
  162. // Determine the length needed for self-relative SD
  163. DWORD dwLengthNeeded = 0;
  164. BOOL fSuccess = ::GetKernelObjectSecurity(
  165. hObject,
  166. siFlags,
  167. NULL,
  168. 0,
  169. &dwLengthNeeded);
  170. dwError = ::GetLastError();
  171. // It is possible that the user lacked the permissions required to obtain the SACL,
  172. // even though we set the token's SE_SECURITY_NAME privilege. So if we obtained an
  173. // access denied error, try it again, this time without requesting the SACL.
  174. if(dwError == ERROR_ACCESS_DENIED || dwError == ERROR_PRIVILEGE_NOT_HELD)
  175. {
  176. siFlags = OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION;
  177. fSuccess = ::GetKernelObjectSecurity(
  178. hObject,
  179. siFlags,
  180. NULL,
  181. 0,
  182. &dwLengthNeeded);
  183. dwError = ::GetLastError();
  184. }
  185. // The only expected error at this point is insuficient buffer
  186. if(!fSuccess && ERROR_INSUFFICIENT_BUFFER == dwError)
  187. {
  188. PSECURITY_DESCRIPTOR pSD = NULL;
  189. try
  190. {
  191. pSD = new BYTE[dwLengthNeeded];
  192. if(pSD)
  193. {
  194. // Now obtain security descriptor
  195. if(::GetKernelObjectSecurity(
  196. hObject,
  197. siFlags,
  198. pSD,
  199. dwLengthNeeded,
  200. &dwLengthNeeded))
  201. {
  202. dwError = ERROR_SUCCESS;
  203. if(InitSecurity(pSD))
  204. {
  205. m_hObject = hObject;
  206. }
  207. else
  208. {
  209. dwError = ERROR_INVALID_PARAMETER;
  210. }
  211. }
  212. else
  213. {
  214. dwError = ::GetLastError();
  215. }
  216. // free up the security descriptor
  217. delete pSD;
  218. }
  219. }
  220. catch(...)
  221. {
  222. delete pSD;
  223. throw;
  224. }
  225. }
  226. // Cleanup the Name Privilege as necessary.
  227. if(fDisablePrivilege)
  228. {
  229. securityPrivilege.Enable(FALSE);
  230. }
  231. return dwError;
  232. }
  233. ///////////////////////////////////////////////////////////////////
  234. //
  235. // Function: CSecureKernelObj::WriteAcls
  236. //
  237. // Protected entry point called by CSecurityDescriptor when
  238. // a user Applies Security and wants to apply security for
  239. // the DACL and/or SACL.
  240. //
  241. // Inputs:
  242. // PSECURITY_DESCRIPTOR pAbsoluteSD - Security
  243. // descriptor to apply to
  244. // the object.
  245. // SECURITY_INFORMATION securityinfo - Flags
  246. // indicating which ACL(s)
  247. // to set.
  248. //
  249. // Outputs:
  250. // None.
  251. //
  252. // Returns:
  253. // DWORD ERROR_SUCCESS if successful
  254. //
  255. // Comments:
  256. //
  257. ///////////////////////////////////////////////////////////////////
  258. DWORD CSecureKernelObj::WriteAcls(
  259. PSECURITY_DESCRIPTOR pAbsoluteSD,
  260. SECURITY_INFORMATION securityinfo)
  261. {
  262. DWORD dwError = ERROR_SUCCESS;
  263. // We must have the security privilege enabled in order to access the object's SACL
  264. CTokenPrivilege securityPrivilege( SE_SECURITY_NAME );
  265. BOOL fDisablePrivilege = FALSE;
  266. if(securityinfo & SACL_SECURITY_INFORMATION ||
  267. securityinfo & PROTECTED_SACL_SECURITY_INFORMATION ||
  268. securityinfo & UNPROTECTED_SACL_SECURITY_INFORMATION)
  269. {
  270. fDisablePrivilege = (securityPrivilege.Enable() == ERROR_SUCCESS);
  271. }
  272. if(!::SetKernelObjectSecurity(
  273. m_hObject,
  274. securityinfo,
  275. pAbsoluteSD))
  276. {
  277. dwError = ::GetLastError();
  278. }
  279. // Cleanup the Name Privilege as necessary.
  280. if(fDisablePrivilege)
  281. {
  282. securityPrivilege.Enable(FALSE);
  283. }
  284. return dwError;
  285. }
  286. ///////////////////////////////////////////////////////////////////
  287. //
  288. // Function: CSecureKernelObj::WriteOwner
  289. //
  290. // Protected entry point called by CSecurityDescriptor when
  291. // a user Applies Security and wants to apply security for
  292. // the owner.
  293. //
  294. // Inputs:
  295. // PSECURITY_DESCRIPTOR pAbsoluteSD - Security
  296. // descriptor to apply to
  297. // the object.
  298. //
  299. // Outputs:
  300. // None.
  301. //
  302. // Returns:
  303. // DWORD ERROR_SUCCESS if successful
  304. //
  305. // Comments:
  306. //
  307. ///////////////////////////////////////////////////////////////////
  308. DWORD CSecureKernelObj::WriteOwner(PSECURITY_DESCRIPTOR pAbsoluteSD)
  309. {
  310. DWORD dwError = ERROR_SUCCESS;
  311. // Open with the appropriate access, set the security and leave
  312. if(!::SetKernelObjectSecurity(
  313. m_hObject,
  314. OWNER_SECURITY_INFORMATION,
  315. pAbsoluteSD))
  316. {
  317. dwError = ::GetLastError();
  318. }
  319. return dwError;
  320. }
  321. DWORD CSecureKernelObj::AllAccessMask(void)
  322. {
  323. // File specific All Access Mask
  324. return TOKEN_ALL_ACCESS;
  325. }