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.

363 lines
11 KiB

  1. //+----------------------------------------------------------------------------
  2. //
  3. // File: allowaccess.cpp
  4. //
  5. // Module: Common Code
  6. //
  7. // Synopsis: Implements the function AllowAccessToWorld.
  8. //
  9. // Copyright (c) 1999 Microsoft Corporation
  10. //
  11. // Author: quintinb Created 12/04/01
  12. //
  13. //+----------------------------------------------------------------------------
  14. LPCSTR apszAdvapi32[] = {
  15. "GetSidLengthRequired",
  16. "InitializeSid",
  17. "GetSidSubAuthority",
  18. "InitializeAcl",
  19. "AddAccessAllowedAceEx",
  20. "InitializeSecurityDescriptor",
  21. "SetSecurityDescriptorDacl",
  22. "SetSecurityDescriptorOwner",
  23. "SetSecurityDescriptorGroup",
  24. "GetSecurityDescriptorDacl",
  25. #ifdef UNICODE
  26. "SetNamedSecurityInfoW",
  27. #else
  28. "SetNamedSecurityInfoA",
  29. #endif
  30. NULL
  31. };
  32. //+----------------------------------------------------------------------------
  33. //
  34. // Function: LinkToAdavapi32
  35. //
  36. // Synopsis: This function links to advapi32.dll and loads the entry points
  37. // specified in the above array of function name strings. If it returns
  38. // success (TRUE) then the array has all of the requested function
  39. // pointers in it. If it returns failure (FALSE), it zeros the structure.
  40. //
  41. // Arguments: AdvapiLinkageStruct* pAdvapiLink - Pointer struct to fill in
  42. //
  43. // Returns: BOOL - returns TRUE if successfull
  44. //
  45. // History: 12/05/01 quintinb created
  46. //
  47. //+----------------------------------------------------------------------------
  48. BOOL LinkToAdavapi32(AdvapiLinkageStruct* pAdvapiLink)
  49. {
  50. BOOL bReturn = FALSE;
  51. if (pAdvapiLink)
  52. {
  53. ZeroMemory(pAdvapiLink, sizeof(*pAdvapiLink));
  54. //
  55. // Do the link, but make it obvious if it fails
  56. //
  57. if (LinkToDll(&(pAdvapiLink->hAdvapi32), "advapi32.dll", apszAdvapi32, pAdvapiLink->apvPfnAdvapi32))
  58. {
  59. bReturn = TRUE;
  60. }
  61. else
  62. {
  63. if (pAdvapiLink->hAdvapi32)
  64. {
  65. FreeLibrary(pAdvapiLink->hAdvapi32);
  66. }
  67. ZeroMemory(pAdvapiLink, sizeof(*pAdvapiLink));
  68. }
  69. }
  70. return bReturn;
  71. }
  72. //+----------------------------------------------------------------------------
  73. //
  74. // Function: UnlinkFromAdvapi32
  75. //
  76. // Synopsis: This function frees the link to advapi32.dll and zeros the passed
  77. // in linkage struct.
  78. //
  79. // Arguments: AdvapiLinkageStruct* pAdvapiLink - Pointer struct to free
  80. //
  81. // Returns: Nothing
  82. //
  83. // History: 12/05/01 quintinb created
  84. //
  85. //+----------------------------------------------------------------------------
  86. void UnlinkFromAdvapi32(AdvapiLinkageStruct* pAdvapiLink)
  87. {
  88. if (pAdvapiLink)
  89. {
  90. if (pAdvapiLink->hAdvapi32)
  91. {
  92. FreeLibrary(pAdvapiLink->hAdvapi32);
  93. }
  94. ZeroMemory(pAdvapiLink, sizeof(*pAdvapiLink));
  95. }
  96. }
  97. //+----------------------------------------------------------------------------
  98. //
  99. // Function: AllocateSecurityDescriptorAllowAccessToWorld
  100. //
  101. // Synopsis: This function allocates a security descriptor for all users.
  102. // This function was taken directly from RAS when they create their
  103. // phonebook. This has to be before GetPhoneBookPath otherwise it
  104. // causes compile errors in other components since we don't have a
  105. // function prototype anywhere and cmcfg just includes this (getpbk.cpp)
  106. // file. This function is also in common\source\getpbk.cpp
  107. //
  108. // Arguments: PSECURITY_DESCRIPTOR *ppSd - Pointer to a pointer to the SD struct
  109. //
  110. // Returns: DWORD - returns ERROR_SUCCESS if successfull
  111. //
  112. // History: 06/27/2001 tomkel Taken from RAS ui\common\pbk\file.c
  113. //
  114. //+----------------------------------------------------------------------------
  115. #define SIZE_ALIGNED_FOR_TYPE(_size, _type) \
  116. (((_size) + sizeof(_type)-1) & ~(sizeof(_type)-1))
  117. DWORD AllocateSecurityDescriptorAllowAccessToWorld(PSECURITY_DESCRIPTOR *ppSd, AdvapiLinkageStruct* pAdvapiLink)
  118. {
  119. PSECURITY_DESCRIPTOR pSd;
  120. PSID pSid;
  121. PACL pDacl;
  122. DWORD dwErr = ERROR_SUCCESS;
  123. DWORD dwAlignSdSize;
  124. DWORD dwAlignDaclSize;
  125. DWORD dwSidSize;
  126. PVOID pvBuffer;
  127. DWORD dwAcls = 0;
  128. // Here is the buffer we are building.
  129. //
  130. // |<- a ->|<- b ->|<- c ->|
  131. // +-------+--------+------+
  132. // | p| p| |
  133. // | SD a| DACL a| SID |
  134. // | d| d| |
  135. // +-------+-------+-------+
  136. // ^ ^ ^
  137. // | | |
  138. // | | +--pSid
  139. // | |
  140. // | +--pDacl
  141. // |
  142. // +--pSd (this is returned via *ppSd)
  143. //
  144. // pad is so that pDacl and pSid are aligned properly.
  145. //
  146. // a = dwAlignSdSize
  147. // b = dwAlignDaclSize
  148. // c = dwSidSize
  149. //
  150. if (NULL == ppSd)
  151. {
  152. return ERROR_INVALID_PARAMETER;
  153. }
  154. // Initialize output parameter.
  155. //
  156. *ppSd = NULL;
  157. // Compute the size of the SID. The SID is the well-known SID for World
  158. // (S-1-1-0).
  159. //
  160. dwSidSize = pAdvapiLink->pfnGetSidLengthRequired(1);
  161. // Compute the size of the DACL. It has an inherent copy of SID within
  162. // it so add enough room for it. It also must sized properly so that
  163. // a pointer to a SID structure can come after it. Hence, we use
  164. // SIZE_ALIGNED_FOR_TYPE.
  165. //
  166. dwAlignDaclSize = SIZE_ALIGNED_FOR_TYPE(
  167. sizeof(ACCESS_ALLOWED_ACE) + sizeof(ACL) + dwSidSize,
  168. PSID);
  169. // Compute the size of the SD. It must be sized propertly so that a
  170. // pointer to a DACL structure can come after it. Hence, we use
  171. // SIZE_ALIGNED_FOR_TYPE.
  172. //
  173. dwAlignSdSize = SIZE_ALIGNED_FOR_TYPE(
  174. sizeof(SECURITY_DESCRIPTOR),
  175. PACL);
  176. // Allocate the buffer big enough for all.
  177. //
  178. dwErr = ERROR_OUTOFMEMORY;
  179. pvBuffer = CmMalloc(dwSidSize + dwAlignDaclSize + dwAlignSdSize);
  180. if (pvBuffer)
  181. {
  182. SID_IDENTIFIER_AUTHORITY SidIdentifierWorldAuth
  183. = SECURITY_WORLD_SID_AUTHORITY;
  184. PULONG pSubAuthority;
  185. dwErr = NOERROR;
  186. // Setup the pointers into the buffer.
  187. //
  188. pSd = pvBuffer;
  189. pDacl = (PACL)((PBYTE)pvBuffer + dwAlignSdSize);
  190. pSid = (PSID)((PBYTE)pDacl + dwAlignDaclSize);
  191. // Initialize pSid as S-1-1-0.
  192. //
  193. if (!pAdvapiLink->pfnInitializeSid(
  194. pSid,
  195. &SidIdentifierWorldAuth,
  196. 1)) // 1 sub-authority
  197. {
  198. dwErr = GetLastError();
  199. goto finish;
  200. }
  201. pSubAuthority = pAdvapiLink->pfnGetSidSubAuthority(pSid, 0);
  202. *pSubAuthority = SECURITY_WORLD_RID;
  203. // Initialize pDacl.
  204. //
  205. if (!pAdvapiLink->pfnInitializeAcl(
  206. pDacl,
  207. dwAlignDaclSize,
  208. ACL_REVISION))
  209. {
  210. dwErr = GetLastError();
  211. goto finish;
  212. }
  213. dwAcls = SPECIFIC_RIGHTS_ALL | STANDARD_RIGHTS_ALL;
  214. dwAcls &= ~(WRITE_DAC | WRITE_OWNER);
  215. if(!pAdvapiLink->pfnAddAccessAllowedAceEx(
  216. pDacl,
  217. ACL_REVISION,
  218. CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE,
  219. dwAcls,
  220. pSid))
  221. {
  222. dwErr = GetLastError();
  223. goto finish;
  224. }
  225. // Initialize pSd.
  226. //
  227. if (!pAdvapiLink->pfnInitializeSecurityDescriptor(
  228. pSd,
  229. SECURITY_DESCRIPTOR_REVISION))
  230. {
  231. dwErr = GetLastError();
  232. goto finish;
  233. }
  234. // Set pSd to use pDacl.
  235. //
  236. if (!pAdvapiLink->pfnSetSecurityDescriptorDacl(
  237. pSd,
  238. TRUE,
  239. pDacl,
  240. FALSE))
  241. {
  242. dwErr = GetLastError();
  243. goto finish;
  244. }
  245. // Set the owner for pSd.
  246. //
  247. if (!pAdvapiLink->pfnSetSecurityDescriptorOwner(
  248. pSd,
  249. NULL,
  250. TRUE))
  251. {
  252. dwErr = GetLastError();
  253. goto finish;
  254. }
  255. // Set the group for pSd.
  256. //
  257. if (!pAdvapiLink->pfnSetSecurityDescriptorGroup(
  258. pSd,
  259. NULL,
  260. FALSE))
  261. {
  262. dwErr = GetLastError();
  263. goto finish;
  264. }
  265. finish:
  266. if (!dwErr)
  267. {
  268. *ppSd = pSd;
  269. }
  270. else
  271. {
  272. CmFree(pvBuffer);
  273. }
  274. }
  275. return dwErr;
  276. }
  277. //+----------------------------------------------------------------------------
  278. //
  279. // Function: AllowAccessToWorld
  280. //
  281. // Synopsis: Assigns world access to the directory or filename passed in.
  282. //
  283. // Arguments: LPCTSTR pszDirOrFile - Directory or file to assign AllowAccessToWorld permissions
  284. //
  285. // Returns: BOOL - FALSE on Falure, non-zero on Success.
  286. //
  287. // History: koryg Created 12/03/2001
  288. //
  289. //+----------------------------------------------------------------------------
  290. BOOL AllowAccessToWorld(LPTSTR pszDirOrFile)
  291. {
  292. AdvapiLinkageStruct AdvapiLink;
  293. BOOL bReturn = FALSE;
  294. if (pszDirOrFile && pszDirOrFile[0])
  295. {
  296. if (LinkToAdavapi32(&AdvapiLink))
  297. {
  298. PSECURITY_DESCRIPTOR pSd = NULL;
  299. DWORD dwErr = AllocateSecurityDescriptorAllowAccessToWorld(&pSd, &AdvapiLink);
  300. if ((ERROR_SUCCESS == dwErr) && (NULL != pSd))
  301. {
  302. BOOL fDaclPresent;
  303. BOOL fDaclDefaulted;
  304. PACL pDacl = NULL;
  305. if (AdvapiLink.pfnGetSecurityDescriptorDacl(pSd, &fDaclPresent, &pDacl, &fDaclDefaulted))
  306. {
  307. dwErr = AdvapiLink.pfnSetNamedSecurityInfo(pszDirOrFile,
  308. SE_FILE_OBJECT,
  309. DACL_SECURITY_INFORMATION,
  310. NULL, // psidOwner
  311. NULL, // psidGroup
  312. pDacl, // pDacl
  313. NULL); // pSacl
  314. if (ERROR_SUCCESS == dwErr)
  315. {
  316. bReturn = TRUE;
  317. }
  318. }
  319. }
  320. CmFree(pSd);
  321. UnlinkFromAdvapi32(&AdvapiLink);
  322. }
  323. }
  324. return bReturn;
  325. }