/*++ Copyright (c) 1998-2002 Microsoft Corporation Module Name: Misc.c Abstract: User-mode interface to HTTP.SYS: Miscellaneous functions. Author: Keith Moore (keithmo) 15-Dec-1998 Revision History: --*/ #include "precomp.h" // // Private macros. // // // Private prototypes. // // // Public functions. // /***************************************************************************++ Routine Description: Wait for a demand start notification. Arguments: AppPoolHandle - Supplies a handle to a application pool. pBuffer - Unused, must be NULL. BufferLength - Unused, must be zero. pBytesReceived - Unused, must be NULL. pOverlapped - Supplies an OVERLAPPED structure. Return Value: ULONG - Completion status. --***************************************************************************/ ULONG WINAPI HttpWaitForDemandStart( IN HANDLE AppPoolHandle, IN OUT PVOID pBuffer OPTIONAL, IN ULONG BufferLength OPTIONAL, IN PULONG pBytesReceived OPTIONAL, IN LPOVERLAPPED pOverlapped OPTIONAL ) { // ASSERT(HttpIsInitialized(HTTP_INITIALIZE_SERVER)); // // Make the request. // return HttpApiDeviceControl( AppPoolHandle, // FileHandle pOverlapped, // pOverlapped IOCTL_HTTP_WAIT_FOR_DEMAND_START, // IoControlCode pBuffer, // pInputBuffer BufferLength, // InputBufferLength pBuffer, // pOutputBuffer BufferLength, // OutputBufferLength pBytesReceived // pBytesTransferred ); } // HttpWaitForDemandStart // // Private functions. // /***************************************************************************++ Routine Description: Given a set of Security Attributes, create a security descriptor. If no Security Attributes given, create the best guess at a "default" Security Descriptor. Arguments: pSA - Set of security attributes. ppSD - Security Descriptor created. Caller must free using FreeSecurityDescriptor. --***************************************************************************/ ULONG CreateSecurityDescriptor( OUT PSECURITY_DESCRIPTOR * ppSD ) { ULONG result; ULONG daclSize; PSECURITY_DESCRIPTOR pSecurityDescriptor = NULL; PACL pDacl = NULL; PSID pMySid; BOOL success; HANDLE hProc; HANDLE hToken = NULL; TOKEN_USER * ptuInfo; TOKEN_DEFAULT_DACL * ptddInfo; char * rgcBuffer = NULL; DWORD cbLen = 0; // // Build default security descriptor from Process Token. // hProc = GetCurrentProcess(); // Gets pseudo-handle; no need to call CloseHandle success = OpenProcessToken(hProc, TOKEN_READ, &hToken); if (!success) { result = GetLastError(); goto cleanup; } // // See if there's a default DACL we can just copy // success = GetTokenInformation( hToken, TokenDefaultDacl, NULL, 0, &cbLen ); // We know this will fail (we didn't provide a buffer) ASSERT(!success); result = GetLastError(); if (ERROR_INSUFFICIENT_BUFFER != result) goto cleanup; if ( sizeof(TOKEN_DEFAULT_DACL) == cbLen ) { // // No DACL present on token; must create DACL based on TokenUser // success = GetTokenInformation( hToken, TokenUser, NULL, 0, &cbLen ); // We know this will fail (we didn't provide a buffer) ASSERT(!success); result = GetLastError(); if (ERROR_INSUFFICIENT_BUFFER != result) goto cleanup; if ( 0 == cbLen ) { goto cleanup; } rgcBuffer = ALLOC_MEM( cbLen ); if ( rgcBuffer == NULL ) { result = ERROR_NOT_ENOUGH_MEMORY; goto cleanup; } success = GetTokenInformation( hToken, TokenUser, rgcBuffer, cbLen, &cbLen ); if (!success) { result = GetLastError(); goto cleanup; } ptuInfo = (TOKEN_USER *) rgcBuffer; pMySid = ptuInfo->User.Sid; // // Verify that we've got a good SID // if( !IsValidSid(pMySid) ) { HttpTrace( "Bogus SID\n" ); result = ERROR_INVALID_SID; goto cleanup; } // // Alloc & init dacl entries // daclSize = sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(pMySid); pDacl = ALLOC_MEM(daclSize); if ( pDacl == NULL ) { result = ERROR_NOT_ENOUGH_MEMORY; goto cleanup; } success = InitializeAcl(pDacl, daclSize, ACL_REVISION); if (!success) { result = GetLastError(); goto cleanup; } // // And add MySid ACE to DACL // NOTE: we need FILE_ALL_ACCESS because adding sub-items under // the current item requires write access, and removing requires // delete access. This is enforced inside HTTP.SYS // success = AddAccessAllowedAce( pDacl, ACL_REVISION, FILE_ALL_ACCESS, pMySid ); if (!success) { result = GetLastError(); goto cleanup; } } else { // // DACL present; Alloc space for DACL & fetch // ASSERT( 0 != cbLen ); rgcBuffer = ALLOC_MEM( cbLen ); if ( !rgcBuffer ) { result = ERROR_NOT_ENOUGH_MEMORY; goto cleanup; } success = GetTokenInformation( hToken, TokenDefaultDacl, rgcBuffer, cbLen, &cbLen ); if (!success) { result = GetLastError(); goto cleanup; } ptddInfo = (TOKEN_DEFAULT_DACL *) rgcBuffer; daclSize = cbLen - sizeof(TOKEN_DEFAULT_DACL); pDacl = ALLOC_MEM( daclSize ); if ( !pDacl ) { result = ERROR_NOT_ENOUGH_MEMORY; goto cleanup; } CopyMemory( pDacl, ptddInfo->DefaultDacl, daclSize ); } ASSERT( NULL != pDacl ); // // allocate the security descriptor // pSecurityDescriptor = ALLOC_MEM( sizeof(SECURITY_DESCRIPTOR) ); if (pSecurityDescriptor == NULL) { result = ERROR_NOT_ENOUGH_MEMORY; goto cleanup; } success = InitializeSecurityDescriptor( pSecurityDescriptor, SECURITY_DESCRIPTOR_REVISION ); if (!success) { result = GetLastError(); goto cleanup; } // // Set the DACL into the security descriptor // success = SetSecurityDescriptorDacl( pSecurityDescriptor, TRUE, // DaclPresent pDacl, // pDacl FALSE // DaclDefaulted ); if (!success) { result = GetLastError(); HttpTrace1( "SetSecurityDescriptorDacl failed. result = %d\n", result ); goto cleanup; } *ppSD = pSecurityDescriptor; result = NO_ERROR; cleanup: if (result != NO_ERROR) { if (pSecurityDescriptor) { FREE_MEM(pSecurityDescriptor); } if (pDacl) { FREE_MEM(pDacl); } } if ( hToken ) { CloseHandle( hToken ); } if ( rgcBuffer ) { FREE_MEM( rgcBuffer ); } return result; } // CreateSecurityDescriptor /***************************************************************************++ Routine Description: Clean up a Security Descriptor created by InitSecurityDescriptor. Arguments: pSD - Security Descriptor to clean up. --***************************************************************************/ VOID FreeSecurityDescriptor( IN PSECURITY_DESCRIPTOR pSD ) { BOOL success; BOOL DaclPresent; PACL pDacl; BOOL DaclDefaulted; if (pSD) { success = GetSecurityDescriptorDacl( pSD, &DaclPresent, &pDacl, &DaclDefaulted ); if (success && DaclPresent && !DaclDefaulted) { FREE_MEM(pDacl); } FREE_MEM(pSD); } } // FreeSecurityDescriptor