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.

370 lines
9.8 KiB

  1. //
  2. // Copyright (C) 2000, Microsoft Corporation
  3. //
  4. // File: regsecurity.c
  5. //
  6. // Contents: miscellaneous dfs functions.
  7. //
  8. // History: April. 17 2002, Author: rohanp
  9. //
  10. //-----------------------------------------------------------------------------
  11. #include <nt.h>
  12. #include <ntrtl.h>
  13. #include <nturtl.h>
  14. #include <windows.h>
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17. #include <stddef.h>
  18. #include <malloc.h>
  19. #include "rpc.h"
  20. #include "rpcdce.h"
  21. #include <dfsheader.h>
  22. #include "lm.h"
  23. #include "lmdfs.h"
  24. #include <strsafe.h>
  25. #include <dfsmisc.h>
  26. #include <seopaque.h>
  27. #include <sertlp.h>
  28. #define FLAG_ON(x, y) ((y)==((x)&(y)))
  29. //
  30. // Registry generic mapping
  31. //
  32. GENERIC_MAPPING DfsRegGenMapping = {STANDARD_RIGHTS_READ | 0x1,
  33. STANDARD_RIGHTS_WRITE | 0x2,
  34. STANDARD_RIGHTS_EXECUTE | 0x4,
  35. STANDARD_RIGHTS_REQUIRED | 0x3F};
  36. //
  37. // Security open type (used to help determine permissions to use on open)
  38. //
  39. typedef enum _DFS_SECURITY_OPEN_TYPE
  40. {
  41. READ_ACCESS_RIGHTS = 0,
  42. WRITE_ACCESS_RIGHTS,
  43. MODIFY_ACCESS_RIGHTS,
  44. NO_ACCESS_RIGHTS,
  45. RESET_ACCESS_RIGHTS
  46. } DFS_SECURITY_OPEN_TYPE, *PDFS_SECURITY_OPEN_TYPE;
  47. ACCESS_MASK
  48. DfsRegGetDesiredAccess(IN DFS_SECURITY_OPEN_TYPE OpenType,
  49. IN SECURITY_INFORMATION SecurityInfo)
  50. {
  51. ACCESS_MASK DesiredAccess = 0;
  52. if ( (SecurityInfo & OWNER_SECURITY_INFORMATION) ||
  53. (SecurityInfo & GROUP_SECURITY_INFORMATION) )
  54. {
  55. switch (OpenType)
  56. {
  57. case READ_ACCESS_RIGHTS:
  58. DesiredAccess |= READ_CONTROL;
  59. break;
  60. case WRITE_ACCESS_RIGHTS:
  61. DesiredAccess |= WRITE_OWNER;
  62. break;
  63. case MODIFY_ACCESS_RIGHTS:
  64. DesiredAccess |= READ_CONTROL | WRITE_OWNER;
  65. break;
  66. }
  67. }
  68. if (SecurityInfo & DACL_SECURITY_INFORMATION)
  69. {
  70. switch (OpenType)
  71. {
  72. case READ_ACCESS_RIGHTS:
  73. DesiredAccess |= READ_CONTROL;
  74. break;
  75. case WRITE_ACCESS_RIGHTS:
  76. DesiredAccess |= WRITE_DAC;
  77. break;
  78. case MODIFY_ACCESS_RIGHTS:
  79. DesiredAccess |= READ_CONTROL | WRITE_DAC;
  80. break;
  81. }
  82. }
  83. if (SecurityInfo & SACL_SECURITY_INFORMATION)
  84. {
  85. DesiredAccess |= READ_CONTROL | ACCESS_SYSTEM_SECURITY;
  86. }
  87. return DesiredAccess;
  88. }
  89. DFSSTATUS
  90. MakeSDAbsolute(IN PSECURITY_DESCRIPTOR pOriginalSD,
  91. IN SECURITY_INFORMATION SeInfo,
  92. OUT PSECURITY_DESCRIPTOR *ppNewSD,
  93. IN PSID pOwnerToAdd,
  94. IN PSID pGroupToAdd)
  95. {
  96. DFSSTATUS dwErr = ERROR_SUCCESS;
  97. BOOL fDAclPresent = FALSE;
  98. BOOL fSAclPresent = FALSE;
  99. BOOL fDAclDef = FALSE, fSAclDef = FALSE;
  100. BOOL fOwnerDef = FALSE, fGroupDef = FALSE;
  101. PACL pDAcl = NULL, pSAcl = NULL;
  102. PSID pOwner = NULL, pGroup = NULL;
  103. ULONG cSize = 0;
  104. PBYTE pbEndOBuf = NULL;
  105. DWORD cLen = 0;
  106. //
  107. // First, get the info out of the current SD
  108. //
  109. if(FLAG_ON(SeInfo, DACL_SECURITY_INFORMATION))
  110. {
  111. if(GetSecurityDescriptorDacl(pOriginalSD, &fDAclPresent, &pDAcl, &fDAclDef) == FALSE)
  112. {
  113. dwErr = GetLastError();
  114. }
  115. else
  116. {
  117. if(pDAcl != NULL)
  118. {
  119. cSize += pDAcl->AclSize;
  120. }
  121. }
  122. }
  123. if(dwErr == ERROR_SUCCESS && FLAG_ON(SeInfo, SACL_SECURITY_INFORMATION))
  124. {
  125. if(GetSecurityDescriptorSacl(pOriginalSD, &fSAclPresent, &pSAcl, &fSAclDef) == FALSE)
  126. {
  127. dwErr = GetLastError();
  128. }
  129. else
  130. {
  131. if(pSAcl != NULL)
  132. {
  133. cSize += pSAcl->AclSize;
  134. }
  135. }
  136. }
  137. if(pOwnerToAdd != NULL)
  138. {
  139. pOwner = pOwnerToAdd;
  140. }
  141. else
  142. {
  143. if(dwErr == ERROR_SUCCESS && FLAG_ON(SeInfo, OWNER_SECURITY_INFORMATION))
  144. {
  145. if(GetSecurityDescriptorOwner(pOriginalSD, &pOwner, &fOwnerDef) == FALSE)
  146. {
  147. dwErr = GetLastError();
  148. }
  149. }
  150. }
  151. if(pGroupToAdd != NULL)
  152. {
  153. pGroup = pGroupToAdd;
  154. }
  155. else
  156. {
  157. if(dwErr == ERROR_SUCCESS && FLAG_ON(SeInfo, GROUP_SECURITY_INFORMATION))
  158. {
  159. if(GetSecurityDescriptorGroup(pOriginalSD, &pGroup, &fGroupDef) == FALSE)
  160. {
  161. dwErr = GetLastError();
  162. }
  163. }
  164. }
  165. if(pOwner != NULL)
  166. {
  167. cSize += RtlLengthSid(pOwner);
  168. }
  169. if(pGroup != NULL)
  170. {
  171. cSize += RtlLengthSid(pGroup);
  172. }
  173. if(dwErr == ERROR_SUCCESS)
  174. {
  175. //
  176. // Allocate the buffer...
  177. //
  178. PBYTE pBuff = (PBYTE)HeapAlloc(GetProcessHeap(), 0 ,(cSize + sizeof(SECURITY_DESCRIPTOR)));
  179. if(pBuff == NULL)
  180. {
  181. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  182. }
  183. else
  184. {
  185. //
  186. // Start copying in the existing items...
  187. //
  188. pbEndOBuf = pBuff + cSize + sizeof(SECURITY_DESCRIPTOR);
  189. if(pOwner != NULL)
  190. {
  191. cLen = RtlLengthSid(pOwner);
  192. pbEndOBuf -= cLen;
  193. RtlCopyMemory(pbEndOBuf, pOwner, cLen);
  194. pOwner = (PSID)pbEndOBuf;
  195. }
  196. if(pGroup != NULL)
  197. {
  198. cLen = RtlLengthSid(pGroup);
  199. pbEndOBuf -= cLen;
  200. RtlCopyMemory(pbEndOBuf, pGroup, cLen);
  201. pGroup = (PSID)pbEndOBuf;
  202. }
  203. if(pDAcl != NULL)
  204. {
  205. pbEndOBuf -= pDAcl->AclSize;
  206. RtlCopyMemory(pbEndOBuf, pDAcl, pDAcl->AclSize);
  207. pDAcl = (PACL)pbEndOBuf;
  208. }
  209. if(pSAcl != NULL)
  210. {
  211. pbEndOBuf -= pSAcl->AclSize;
  212. RtlCopyMemory(pbEndOBuf, pSAcl, pSAcl->AclSize);
  213. pSAcl = (PACL)pbEndOBuf;
  214. }
  215. //
  216. // Ok, now build it...
  217. //
  218. *ppNewSD = (PSECURITY_DESCRIPTOR)pBuff;
  219. if(InitializeSecurityDescriptor(*ppNewSD, SECURITY_DESCRIPTOR_REVISION) == FALSE)
  220. {
  221. dwErr = GetLastError();
  222. }
  223. if(dwErr == ERROR_SUCCESS && fDAclPresent == TRUE)
  224. {
  225. if(SetSecurityDescriptorDacl(*ppNewSD, TRUE, pDAcl, fDAclDef) == FALSE)
  226. {
  227. dwErr = GetLastError();
  228. }
  229. }
  230. if(dwErr == ERROR_SUCCESS && fSAclPresent == TRUE)
  231. {
  232. if(SetSecurityDescriptorSacl(*ppNewSD, TRUE, pSAcl, fSAclDef) == FALSE)
  233. {
  234. dwErr = GetLastError();
  235. }
  236. }
  237. if(dwErr == ERROR_SUCCESS && pOwner != NULL)
  238. {
  239. if(SetSecurityDescriptorOwner(*ppNewSD, pOwner, fOwnerDef) == FALSE)
  240. {
  241. dwErr = GetLastError();
  242. }
  243. }
  244. if(dwErr == ERROR_SUCCESS && pGroup != NULL)
  245. {
  246. if(SetSecurityDescriptorGroup(*ppNewSD, pGroup, fGroupDef) == FALSE)
  247. {
  248. dwErr = GetLastError();
  249. }
  250. }
  251. //
  252. // Set the new control bits to look like the old ones (minus the selfrel flag, of
  253. // course...
  254. //
  255. if(dwErr == ERROR_SUCCESS)
  256. {
  257. RtlpPropagateControlBits((PISECURITY_DESCRIPTOR)*ppNewSD,
  258. (PISECURITY_DESCRIPTOR)pOriginalSD,
  259. ~SE_SELF_RELATIVE );
  260. }
  261. if(dwErr != ERROR_SUCCESS)
  262. {
  263. HeapFree(GetProcessHeap, 0,(*ppNewSD));
  264. *ppNewSD = NULL;
  265. }
  266. }
  267. }
  268. return(dwErr);
  269. }
  270. DFSSTATUS
  271. DfsReadRegistrySecurityInfo(IN HKEY hRegistry,
  272. IN SECURITY_INFORMATION SeInfo,
  273. OUT PSECURITY_DESCRIPTOR *ppSD)
  274. {
  275. ULONG cSize = 0;
  276. DWORD Status = 0;
  277. PSECURITY_DESCRIPTOR pAbs = NULL;
  278. //
  279. // First, get the size we need
  280. //
  281. Status = RegGetKeySecurity(hRegistry,
  282. SeInfo,
  283. *ppSD,
  284. &cSize);
  285. if(Status == ERROR_INSUFFICIENT_BUFFER)
  286. {
  287. Status = ERROR_SUCCESS;
  288. *ppSD = (PISECURITY_DESCRIPTOR)HeapAlloc(GetProcessHeap(), 0, cSize);
  289. if(*ppSD == NULL)
  290. {
  291. Status = ERROR_NOT_ENOUGH_MEMORY;
  292. }
  293. else
  294. {
  295. Status = RegGetKeySecurity((HKEY)hRegistry,
  296. SeInfo,
  297. *ppSD,
  298. &cSize);
  299. }
  300. }
  301. return Status;
  302. }
  303. DFSSTATUS
  304. DfsSetRegistrySecurityInfo(IN HKEY hRegistry,
  305. IN SECURITY_INFORMATION SeInfo,
  306. IN PSECURITY_DESCRIPTOR pSD)
  307. {
  308. DFSSTATUS Status = 0;
  309. if(FLAG_ON(SeInfo, DACL_SECURITY_INFORMATION))
  310. {
  311. ((PISECURITY_DESCRIPTOR)pSD)->Control |= SE_DACL_AUTO_INHERIT_REQ;
  312. }
  313. if(FLAG_ON(SeInfo, SACL_SECURITY_INFORMATION))
  314. {
  315. ((PISECURITY_DESCRIPTOR)pSD)->Control |= SE_SACL_AUTO_INHERIT_REQ;
  316. }
  317. Status = RegSetKeySecurity(hRegistry,
  318. SeInfo,
  319. pSD);
  320. return Status;
  321. }