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.

444 lines
11 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1996.
  5. //
  6. // File: security.cxx
  7. //
  8. // Contents: Security-related helper functions used by the Task Scheduler
  9. // setup program to set security on the job folder.
  10. //
  11. // Classes: None.
  12. //
  13. // Functions:
  14. //
  15. // History: 23-Sep-96 AnirudhS Copied with minor modifications from
  16. // ..\job\security.cxx.
  17. // October 2001 Maxa Updated security.cxx in preparation for addition of auditing.
  18. //
  19. //----------------------------------------------------------------------------
  20. #include <windows.h>
  21. #include "security.hxx"
  22. DWORD
  23. CreateAcl(
  24. OUT PACL* ppAcl,
  25. IN DWORD dwAclAceCount,
  26. IN CONST ACE_DESC* pAclAces
  27. );
  28. //+---------------------------------------------------------------------------
  29. //
  30. // Function: CreateSecurityDescriptor
  31. //
  32. // Synopsis: Create a security descriptor with the ACE information
  33. // specified.
  34. //
  35. // Arguments: [ppSecDesc, out] - pointer to descurity descriptor. Gets filled in if
  36. // the function does not encounter an error.
  37. // [dwDaclAceCount] - number of ACEs for the DACL.
  38. // NOTE: use -1 when you want no DACL, 0 for an empty DACL.
  39. // [pDaclAces] - pointer to ACE specification array.
  40. // [dwSaclAceCount] - number of ACEs for the DACL.
  41. // [pSaclAces] - pointer to ACE specification array.
  42. //
  43. // Returns: win32 error code
  44. //
  45. // Notes: None.
  46. //
  47. //----------------------------------------------------------------------------
  48. DWORD
  49. CreateSecurityDescriptor(
  50. OUT PSECURITY_DESCRIPTOR* ppSecurityDescriptor,
  51. IN DWORD dwDaclAceCount,
  52. IN CONST ACE_DESC* pDaclAces,
  53. IN DWORD dwSaclAceCount,
  54. IN CONST ACE_DESC* pSaclAces
  55. )
  56. {
  57. DWORD dwError = ERROR_SUCCESS;
  58. BOOL bSuccess;
  59. PSECURITY_DESCRIPTOR pSecurityDescriptor = 0;
  60. PACL pDacl = 0;
  61. PACL pSacl = 0;
  62. *ppSecurityDescriptor = 0;
  63. //
  64. // Create the security descriptor.
  65. //
  66. pSecurityDescriptor = LocalAlloc(
  67. LMEM_FIXED,
  68. SECURITY_DESCRIPTOR_MIN_LENGTH);
  69. if (pSecurityDescriptor == NULL)
  70. {
  71. dwError = ERROR_NOT_ENOUGH_MEMORY;
  72. goto ErrorExit;
  73. }
  74. bSuccess = InitializeSecurityDescriptor(
  75. pSecurityDescriptor,
  76. SECURITY_DESCRIPTOR_REVISION);
  77. if (!bSuccess)
  78. {
  79. dwError = GetLastError();
  80. goto ErrorExit;
  81. }
  82. if (dwDaclAceCount != DWORD(-1))
  83. {
  84. dwError = CreateAcl(
  85. &pDacl,
  86. dwDaclAceCount,
  87. pDaclAces);
  88. if (dwError != ERROR_SUCCESS)
  89. {
  90. goto ErrorExit;
  91. }
  92. bSuccess = SetSecurityDescriptorDacl(
  93. pSecurityDescriptor,
  94. TRUE,
  95. pDacl,
  96. FALSE);
  97. if (!bSuccess)
  98. {
  99. dwError = GetLastError();
  100. goto ErrorExit;
  101. }
  102. }
  103. if (dwSaclAceCount)
  104. {
  105. dwError = CreateAcl(
  106. &pSacl,
  107. dwSaclAceCount,
  108. pSaclAces);
  109. if (dwError != ERROR_SUCCESS)
  110. {
  111. goto ErrorExit;
  112. }
  113. bSuccess = SetSecurityDescriptorSacl(
  114. pSecurityDescriptor,
  115. TRUE,
  116. pSacl,
  117. FALSE);
  118. if (!bSuccess)
  119. {
  120. dwError = GetLastError();
  121. goto ErrorExit;
  122. }
  123. }
  124. *ppSecurityDescriptor = pSecurityDescriptor;
  125. return ERROR_SUCCESS;
  126. ErrorExit:
  127. if (pDacl)
  128. {
  129. LocalFree(pDacl);
  130. }
  131. if (pSacl)
  132. {
  133. LocalFree(pSacl);
  134. }
  135. if (pSecurityDescriptor)
  136. {
  137. LocalFree(pSecurityDescriptor);
  138. }
  139. return dwError;
  140. }
  141. //+---------------------------------------------------------------------------
  142. //
  143. // Function: DeleteSecurityDescriptor
  144. //
  145. // Synopsis: Deallocate the security descriptor allocated in
  146. // CreateSecurityDescriptor.
  147. //
  148. // Arguments: [pSecurityDescriptor] -- SD returned from
  149. // CreateSecurityDescriptor.
  150. //
  151. // Returns: None.
  152. //
  153. // Notes: None.
  154. //
  155. //----------------------------------------------------------------------------
  156. void
  157. DeleteSecurityDescriptor(
  158. PSECURITY_DESCRIPTOR pSecurityDescriptor)
  159. {
  160. BOOL bSuccess;
  161. BOOL fPresent;
  162. BOOL fDefaulted;
  163. PACL pAcl;
  164. if (pSecurityDescriptor == 0)
  165. {
  166. return;
  167. }
  168. pAcl = 0;
  169. bSuccess = GetSecurityDescriptorDacl(
  170. pSecurityDescriptor,
  171. &fPresent,
  172. &pAcl,
  173. &fDefaulted);
  174. if (bSuccess)
  175. {
  176. if (fPresent && pAcl != NULL)
  177. {
  178. LocalFree(pAcl);
  179. }
  180. }
  181. pAcl = 0;
  182. bSuccess = GetSecurityDescriptorSacl(
  183. pSecurityDescriptor,
  184. &fPresent,
  185. &pAcl,
  186. &fDefaulted);
  187. if (bSuccess)
  188. {
  189. if (fPresent && pAcl != NULL)
  190. {
  191. LocalFree(pAcl);
  192. }
  193. }
  194. LocalFree(pSecurityDescriptor);
  195. }
  196. //+---------------------------------------------------------------------------
  197. //
  198. // Function: CreateAcl
  199. //
  200. // Synopsis: Creates an access control list.
  201. //
  202. // Arguments: [pAcl] -- pointer to ACL.
  203. // [dwAclAceCount]-- number of ACEs.
  204. // [pAclAces] -- ACE descriptions.
  205. //
  206. // Returns: win32 error code.
  207. //
  208. // Notes: Use LocalFree to delete pAcl once you are done with it.
  209. //
  210. //----------------------------------------------------------------------------
  211. DWORD
  212. CreateAcl(
  213. OUT PACL* ppAcl,
  214. IN DWORD dwAclAceCount,
  215. IN CONST ACE_DESC* pAclAces
  216. )
  217. {
  218. DWORD dwError = ERROR_SUCCESS;
  219. BOOL bSuccess;
  220. DWORD dwAclLength = sizeof(ACL);
  221. PACL pAcl = 0;
  222. CONST ACE_DESC* pAce;
  223. DWORD i;
  224. for (i=0,pAce=pAclAces;i < dwAclAceCount;i++,pAce++)
  225. {
  226. switch (pAce->Type)
  227. {
  228. case ACCESS_ALLOWED_ACE_TYPE:
  229. dwAclLength += sizeof(ACCESS_ALLOWED_ACE);
  230. break;
  231. case ACCESS_DENIED_ACE_TYPE:
  232. dwAclLength += sizeof(ACCESS_DENIED_ACE);
  233. break;
  234. case SYSTEM_AUDIT_ACE_TYPE:
  235. dwAclLength += sizeof(SYSTEM_AUDIT_ACE);
  236. break;
  237. default:
  238. dwError = ERROR_INVALID_PARAMETER;
  239. goto ErrorExit;
  240. }
  241. dwAclLength -= sizeof(DWORD);
  242. dwAclLength += GetLengthSid(pAce->pSid);
  243. }
  244. pAcl = (PACL)LocalAlloc(LMEM_FIXED, dwAclLength);
  245. if (pAcl == 0)
  246. {
  247. dwError = ERROR_NOT_ENOUGH_MEMORY;
  248. goto ErrorExit;
  249. }
  250. bSuccess = InitializeAcl(
  251. pAcl,
  252. dwAclLength,
  253. ACL_REVISION);
  254. if (!bSuccess)
  255. {
  256. dwError = GetLastError();
  257. goto ErrorExit;
  258. }
  259. for (i=0,pAce=pAclAces;i < dwAclAceCount;i++,pAce++)
  260. {
  261. switch (pAce->Type)
  262. {
  263. case ACCESS_ALLOWED_ACE_TYPE:
  264. bSuccess = AddAccessAllowedAceEx(
  265. pAcl,
  266. ACL_REVISION,
  267. pAce->Flags,
  268. pAce->AccessMask,
  269. pAce->pSid);
  270. break;
  271. case ACCESS_DENIED_ACE_TYPE:
  272. bSuccess = AddAccessDeniedAceEx(
  273. pAcl,
  274. ACL_REVISION,
  275. pAce->Flags,
  276. pAce->AccessMask,
  277. pAce->pSid);
  278. break;
  279. case SYSTEM_AUDIT_ACE_TYPE:
  280. bSuccess = AddAuditAccessAceEx(
  281. pAcl,
  282. ACL_REVISION,
  283. pAce->Flags,
  284. pAce->AccessMask,
  285. pAce->pSid,
  286. FALSE,
  287. FALSE);
  288. break;
  289. default:
  290. dwError = ERROR_INVALID_PARAMETER;
  291. goto ErrorExit;
  292. }
  293. if (!bSuccess)
  294. {
  295. dwError = GetLastError();
  296. goto ErrorExit;
  297. }
  298. }
  299. *ppAcl = pAcl;
  300. return ERROR_SUCCESS;
  301. ErrorExit:
  302. if (pAcl)
  303. {
  304. LocalFree(pAcl);
  305. }
  306. return dwError;
  307. }
  308. //+---------------------------------------------------------------------------
  309. //
  310. // Function: EnablePrivilege
  311. //
  312. // Synopsis: Tries to enable / disable a privilege for the current process.
  313. //
  314. // Arguments: [pszPrivName] - name of privilege to enable / disable.
  315. // [bEnable] - enable / disable switch.
  316. // [pbWasEnabled] - optional pointer to receive the previous
  317. // state of the privilege.
  318. //
  319. // Returns: win32 error code.
  320. //
  321. //----------------------------------------------------------------------------
  322. DWORD
  323. EnablePrivilege(
  324. IN PCWSTR pszPrivName,
  325. IN BOOL bEnable,
  326. OUT PBOOL pbWasEnabled OPTIONAL
  327. )
  328. {
  329. DWORD dwError = ERROR_SUCCESS;
  330. BOOL bSuccess;
  331. HANDLE hToken = 0;
  332. DWORD dwSize;
  333. TOKEN_PRIVILEGES privNew;
  334. TOKEN_PRIVILEGES privOld;
  335. bSuccess = OpenProcessToken(
  336. GetCurrentProcess(),
  337. TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
  338. &hToken);
  339. if (!bSuccess)
  340. {
  341. dwError = GetLastError();
  342. goto Cleanup;
  343. }
  344. bSuccess = LookupPrivilegeValue(
  345. 0,
  346. pszPrivName,
  347. &privNew.Privileges[0].Luid);
  348. if (!bSuccess)
  349. {
  350. dwError = GetLastError();
  351. goto Cleanup;
  352. }
  353. privNew.PrivilegeCount = 1;
  354. privNew.Privileges[0].Attributes = bEnable ? SE_PRIVILEGE_ENABLED : 0;
  355. bSuccess = AdjustTokenPrivileges(
  356. hToken,
  357. FALSE,
  358. &privNew,
  359. sizeof(privOld),
  360. &privOld,
  361. &dwSize);
  362. if (!bSuccess)
  363. {
  364. dwError = GetLastError();
  365. goto Cleanup;
  366. }
  367. if (pbWasEnabled)
  368. {
  369. *pbWasEnabled = (privOld.Privileges[0].Attributes & SE_PRIVILEGE_ENABLED)
  370. ? TRUE : FALSE;
  371. }
  372. Cleanup:
  373. if (hToken)
  374. {
  375. CloseHandle(hToken);
  376. }
  377. return dwError;
  378. }