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.

426 lines
9.6 KiB

  1. /*++
  2. Copyright (c) 1998-2002 Microsoft Corporation
  3. Module Name:
  4. Misc.c
  5. Abstract:
  6. User-mode interface to HTTP.SYS: Miscellaneous functions.
  7. Author:
  8. Keith Moore (keithmo) 15-Dec-1998
  9. Revision History:
  10. --*/
  11. #include "precomp.h"
  12. //
  13. // Private macros.
  14. //
  15. //
  16. // Private prototypes.
  17. //
  18. //
  19. // Public functions.
  20. //
  21. /***************************************************************************++
  22. Routine Description:
  23. Wait for a demand start notification.
  24. Arguments:
  25. AppPoolHandle - Supplies a handle to a application pool.
  26. pBuffer - Unused, must be NULL.
  27. BufferLength - Unused, must be zero.
  28. pBytesReceived - Unused, must be NULL.
  29. pOverlapped - Supplies an OVERLAPPED structure.
  30. Return Value:
  31. ULONG - Completion status.
  32. --***************************************************************************/
  33. ULONG
  34. WINAPI
  35. HttpWaitForDemandStart(
  36. IN HANDLE AppPoolHandle,
  37. IN OUT PVOID pBuffer OPTIONAL,
  38. IN ULONG BufferLength OPTIONAL,
  39. IN PULONG pBytesReceived OPTIONAL,
  40. IN LPOVERLAPPED pOverlapped OPTIONAL
  41. )
  42. {
  43. // ASSERT(HttpIsInitialized(HTTP_INITIALIZE_SERVER));
  44. //
  45. // Make the request.
  46. //
  47. return HttpApiDeviceControl(
  48. AppPoolHandle, // FileHandle
  49. pOverlapped, // pOverlapped
  50. IOCTL_HTTP_WAIT_FOR_DEMAND_START, // IoControlCode
  51. pBuffer, // pInputBuffer
  52. BufferLength, // InputBufferLength
  53. pBuffer, // pOutputBuffer
  54. BufferLength, // OutputBufferLength
  55. pBytesReceived // pBytesTransferred
  56. );
  57. } // HttpWaitForDemandStart
  58. //
  59. // Private functions.
  60. //
  61. /***************************************************************************++
  62. Routine Description:
  63. Given a set of Security Attributes, create a security descriptor. If
  64. no Security Attributes given, create the best guess at a "default"
  65. Security Descriptor.
  66. Arguments:
  67. pSA - Set of security attributes.
  68. ppSD - Security Descriptor created. Caller must free using
  69. FreeSecurityDescriptor.
  70. --***************************************************************************/
  71. ULONG
  72. CreateSecurityDescriptor(
  73. OUT PSECURITY_DESCRIPTOR * ppSD
  74. )
  75. {
  76. ULONG result;
  77. ULONG daclSize;
  78. PSECURITY_DESCRIPTOR pSecurityDescriptor = NULL;
  79. PACL pDacl = NULL;
  80. PSID pMySid;
  81. BOOL success;
  82. HANDLE hProc;
  83. HANDLE hToken = NULL;
  84. TOKEN_USER * ptuInfo;
  85. TOKEN_DEFAULT_DACL * ptddInfo;
  86. char * rgcBuffer = NULL;
  87. DWORD cbLen = 0;
  88. //
  89. // Build default security descriptor from Process Token.
  90. //
  91. hProc = GetCurrentProcess(); // Gets pseudo-handle; no need to call CloseHandle
  92. success = OpenProcessToken(hProc, TOKEN_READ, &hToken);
  93. if (!success)
  94. {
  95. result = GetLastError();
  96. goto cleanup;
  97. }
  98. //
  99. // See if there's a default DACL we can just copy
  100. //
  101. success = GetTokenInformation(
  102. hToken,
  103. TokenDefaultDacl,
  104. NULL,
  105. 0,
  106. &cbLen
  107. );
  108. // We know this will fail (we didn't provide a buffer)
  109. ASSERT(!success);
  110. result = GetLastError();
  111. if (ERROR_INSUFFICIENT_BUFFER != result)
  112. goto cleanup;
  113. if ( sizeof(TOKEN_DEFAULT_DACL) == cbLen )
  114. {
  115. //
  116. // No DACL present on token; must create DACL based on TokenUser
  117. //
  118. success = GetTokenInformation(
  119. hToken,
  120. TokenUser,
  121. NULL,
  122. 0,
  123. &cbLen
  124. );
  125. // We know this will fail (we didn't provide a buffer)
  126. ASSERT(!success);
  127. result = GetLastError();
  128. if (ERROR_INSUFFICIENT_BUFFER != result)
  129. goto cleanup;
  130. if ( 0 == cbLen )
  131. {
  132. goto cleanup;
  133. }
  134. rgcBuffer = ALLOC_MEM( cbLen );
  135. if ( rgcBuffer == NULL ) {
  136. result = ERROR_NOT_ENOUGH_MEMORY;
  137. goto cleanup;
  138. }
  139. success = GetTokenInformation(
  140. hToken,
  141. TokenUser,
  142. rgcBuffer,
  143. cbLen,
  144. &cbLen
  145. );
  146. if (!success)
  147. {
  148. result = GetLastError();
  149. goto cleanup;
  150. }
  151. ptuInfo = (TOKEN_USER *) rgcBuffer;
  152. pMySid = ptuInfo->User.Sid;
  153. //
  154. // Verify that we've got a good SID
  155. //
  156. if( !IsValidSid(pMySid) )
  157. {
  158. HttpTrace( "Bogus SID\n" );
  159. result = ERROR_INVALID_SID;
  160. goto cleanup;
  161. }
  162. //
  163. // Alloc & init dacl entries
  164. //
  165. daclSize = sizeof(ACL) +
  166. sizeof(ACCESS_ALLOWED_ACE) +
  167. GetLengthSid(pMySid);
  168. pDacl = ALLOC_MEM(daclSize);
  169. if ( pDacl == NULL ) {
  170. result = ERROR_NOT_ENOUGH_MEMORY;
  171. goto cleanup;
  172. }
  173. success = InitializeAcl(pDacl, daclSize, ACL_REVISION);
  174. if (!success)
  175. {
  176. result = GetLastError();
  177. goto cleanup;
  178. }
  179. //
  180. // And add MySid ACE to DACL
  181. // NOTE: we need FILE_ALL_ACCESS because adding sub-items under
  182. // the current item requires write access, and removing requires
  183. // delete access. This is enforced inside HTTP.SYS
  184. //
  185. success = AddAccessAllowedAce(
  186. pDacl,
  187. ACL_REVISION,
  188. FILE_ALL_ACCESS,
  189. pMySid
  190. );
  191. if (!success)
  192. {
  193. result = GetLastError();
  194. goto cleanup;
  195. }
  196. } else
  197. {
  198. //
  199. // DACL present; Alloc space for DACL & fetch
  200. //
  201. ASSERT( 0 != cbLen );
  202. rgcBuffer = ALLOC_MEM( cbLen );
  203. if ( !rgcBuffer )
  204. {
  205. result = ERROR_NOT_ENOUGH_MEMORY;
  206. goto cleanup;
  207. }
  208. success = GetTokenInformation(
  209. hToken,
  210. TokenDefaultDacl,
  211. rgcBuffer,
  212. cbLen,
  213. &cbLen
  214. );
  215. if (!success)
  216. {
  217. result = GetLastError();
  218. goto cleanup;
  219. }
  220. ptddInfo = (TOKEN_DEFAULT_DACL *) rgcBuffer;
  221. daclSize = cbLen - sizeof(TOKEN_DEFAULT_DACL);
  222. pDacl = ALLOC_MEM( daclSize );
  223. if ( !pDacl )
  224. {
  225. result = ERROR_NOT_ENOUGH_MEMORY;
  226. goto cleanup;
  227. }
  228. CopyMemory( pDacl, ptddInfo->DefaultDacl, daclSize );
  229. }
  230. ASSERT( NULL != pDacl );
  231. //
  232. // allocate the security descriptor
  233. //
  234. pSecurityDescriptor = ALLOC_MEM( sizeof(SECURITY_DESCRIPTOR) );
  235. if (pSecurityDescriptor == NULL)
  236. {
  237. result = ERROR_NOT_ENOUGH_MEMORY;
  238. goto cleanup;
  239. }
  240. success = InitializeSecurityDescriptor(
  241. pSecurityDescriptor,
  242. SECURITY_DESCRIPTOR_REVISION
  243. );
  244. if (!success)
  245. {
  246. result = GetLastError();
  247. goto cleanup;
  248. }
  249. //
  250. // Set the DACL into the security descriptor
  251. //
  252. success = SetSecurityDescriptorDacl(
  253. pSecurityDescriptor,
  254. TRUE, // DaclPresent
  255. pDacl, // pDacl
  256. FALSE // DaclDefaulted
  257. );
  258. if (!success)
  259. {
  260. result = GetLastError();
  261. HttpTrace1( "SetSecurityDescriptorDacl failed. result = %d\n", result );
  262. goto cleanup;
  263. }
  264. *ppSD = pSecurityDescriptor;
  265. result = NO_ERROR;
  266. cleanup:
  267. if (result != NO_ERROR)
  268. {
  269. if (pSecurityDescriptor)
  270. {
  271. FREE_MEM(pSecurityDescriptor);
  272. }
  273. if (pDacl)
  274. {
  275. FREE_MEM(pDacl);
  276. }
  277. }
  278. if ( hToken )
  279. {
  280. CloseHandle( hToken );
  281. }
  282. if ( rgcBuffer )
  283. {
  284. FREE_MEM( rgcBuffer );
  285. }
  286. return result;
  287. } // CreateSecurityDescriptor
  288. /***************************************************************************++
  289. Routine Description:
  290. Clean up a Security Descriptor created by InitSecurityDescriptor.
  291. Arguments:
  292. pSD - Security Descriptor to clean up.
  293. --***************************************************************************/
  294. VOID
  295. FreeSecurityDescriptor(
  296. IN PSECURITY_DESCRIPTOR pSD
  297. )
  298. {
  299. BOOL success;
  300. BOOL DaclPresent;
  301. PACL pDacl;
  302. BOOL DaclDefaulted;
  303. if (pSD)
  304. {
  305. success = GetSecurityDescriptorDacl(
  306. pSD,
  307. &DaclPresent,
  308. &pDacl,
  309. &DaclDefaulted
  310. );
  311. if (success && DaclPresent && !DaclDefaulted) {
  312. FREE_MEM(pDacl);
  313. }
  314. FREE_MEM(pSD);
  315. }
  316. } // FreeSecurityDescriptor