/*++
Copyright (c) 2000 Microsoft Corporation
Module Name:
tcgsec.c
Abstract:
Config Group security test. See also ttrans.c.
Author:
Michael Courage (mcourage) 15-Jan-2000
Revision History:
--*/
#include "precomp.h"
UCHAR CannedResponseEntityBody[] =
"
Hello!"
"This section of the namespace is owned by tcgsec.";
DEFINE_COMMON_GLOBALS();
ULONG
InitTransientNameSpace(
IN HANDLE ControlChannel,
IN HANDLE AppPool,
OUT PHTTP_CONFIG_GROUP_ID pConfigId
);
ULONG
InitSecurityDescriptor(
OUT PSECURITY_DESCRIPTOR * ppSD
);
VOID
FreeSecurityDescriptor(
IN PSECURITY_DESCRIPTOR pSD
);
INT
__cdecl
wmain(
INT argc,
PWSTR argv[]
)
{
ULONG result;
HANDLE controlChannel;
HANDLE appPool;
HTTP_CONFIG_GROUP_ID configId;
HTTP_CONFIG_GROUP_ID transConfigId;
HTTP_CONFIG_GROUP_APP_POOL configAppPool;
HTTP_CONFIG_GROUP_STATE configState;
HTTP_ENABLED_STATE controlState;
HTTP_REQUEST_ID requestId;
DWORD bytesRead;
DWORD bytesSent;
PHTTP_REQUEST request;
HTTP_RESPONSE response;
HTTP_DATA_CHUNK dataChunk;
ULONG i;
BOOL initDone;
HTTP_REQUEST_ALIGNMENT UCHAR requestBuffer[REQUEST_LENGTH];
//
// Initialize.
//
result = CommonInit();
if (result != NO_ERROR)
{
wprintf( L"CommonInit() failed, error %lu\n", result );
return 1;
}
if (!ParseCommandLine( argc, argv ))
{
return 1;
}
//
// Setup locals so we know how to cleanup on exit.
//
initDone = FALSE;
controlChannel = NULL;
appPool = NULL;
HTTP_SET_NULL_ID( &configId );
//
// Get UL started.
//
result = InitUlStuff(
&controlChannel,
&appPool,
NULL, // FilterChannel
&configId,
TRUE, // AllowSystem
TRUE, // AllowAdmin
FALSE, // AllowCurrentUser
FALSE, // AllowWorld
0,
FALSE, // EnableSsl
FALSE // EnableRawFilters
);
if (result != NO_ERROR)
{
wprintf( L"InitUlStuff() failed, error %lu\n", result );
goto cleanup;
}
result = InitTransientNameSpace(controlChannel, appPool, &transConfigId);
if (result != NO_ERROR)
{
wprintf( L"InitTransientNamespace() failed, error %lu\n", result);
goto cleanup;
}
initDone = TRUE;
//
// Build our canned response.
//
INIT_RESPONSE( &response, 200, "OK" );
INIT_HEADER( &response, HttpHeaderContentType, "text/html" );
INIT_HEADER( &response, HttpHeaderContentLength, "109" );
dataChunk.DataChunkType = HttpDataChunkFromMemory;
dataChunk.FromMemory.pBuffer = CannedResponseEntityBody;
dataChunk.FromMemory.BufferLength = sizeof(CannedResponseEntityBody) - 1;
//
// Loop forever...
//
request = (PHTTP_REQUEST)requestBuffer;
HTTP_SET_NULL_ID( &requestId );
for( ; ; )
{
//
// Wait for a request.
//
//DEBUG_BREAK();
result = HttpReceiveHttpRequest(
appPool,
requestId,
0,
(PHTTP_REQUEST)requestBuffer,
sizeof(requestBuffer),
&bytesRead,
NULL
);
if (result != NO_ERROR)
{
wprintf( L"HttpReceiveHttpRequest() failed, error %lu\n", result );
break;
}
//
// Dump it.
//
if (TEST_OPTION(Verbose))
{
DumpHttpRequest( request );
}
//
// Send the canned response.
//
DEBUG_BREAK();
response.EntityChunkCount = 1;
response.pEntityChunks = &dataChunk;
result = HttpSendHttpResponse(
appPool,
request->RequestId,
0,
&response,
NULL,
&bytesSent,
NULL,
NULL
);
if (result != NO_ERROR)
{
wprintf( L"HttpSendHttpResponse() failed, error %lu\n", result );
break;
}
}
cleanup:
if (!HTTP_IS_NULL_ID( &configId ))
{
result = HttpDeleteConfigGroup(
controlChannel,
configId
);
if (result != NO_ERROR)
{
wprintf( L"HttpDeleteConfigGroup(1) failed, error %lu\n", result );
}
}
if (!HTTP_IS_NULL_ID( &transConfigId ))
{
result = HttpDeleteConfigGroup(
controlChannel,
transConfigId
);
if (result != NO_ERROR)
{
wprintf( L"HttpDeleteConfigGroup(2) failed, error %lu\n", result );
}
}
if (appPool != NULL)
{
CloseHandle( appPool );
}
if (controlChannel != NULL)
{
CloseHandle( controlChannel );
}
if (initDone)
{
HttpTerminate();
}
return 0;
} // wmain
ULONG
InitTransientNameSpace(
IN HANDLE ControlChannel,
IN HANDLE AppPool,
OUT PHTTP_CONFIG_GROUP_ID pConfigId
)
{
ULONG result;
HTTP_CONFIG_GROUP_ID configId = HTTP_NULL_ID;
HTTP_CONFIG_GROUP_APP_POOL configAppPool;
HTTP_CONFIG_GROUP_STATE configState;
HTTP_CONFIG_GROUP_SECURITY configSecurity;
PSECURITY_DESCRIPTOR pSecurityDescriptor = NULL;
//
// Create a configuration group.
//
result = HttpCreateConfigGroup(
ControlChannel,
&configId
);
if (result != NO_ERROR)
{
wprintf( L"HttpCreateConfigGroup() failed, error %lu\n", result );
goto cleanup;
}
//
// Add a URL to the configuration group.
//
result = HttpAddUrlToConfigGroup(
ControlChannel,
configId,
TRANS_URL_NAME,
0
);
if (result != NO_ERROR)
{
wprintf( L"HttpAddUrlToConfigGroup() failed, error %lu\n", result );
goto cleanup;
}
//
// Associate the configuration group with the application pool.
//
configAppPool.Flags.Present = 1;
configAppPool.AppPoolHandle = AppPool;
result = HttpSetConfigGroupInformation(
ControlChannel,
configId,
HttpConfigGroupAppPoolInformation,
&configAppPool,
sizeof(configAppPool)
);
if (result != NO_ERROR)
{
wprintf( L"HttpSetConfigGroupInformation(1) failed, error %lu\n", result );
goto cleanup;
}
//
// Set the config group state.
//
configState.Flags.Present = 1;
configState.State = HttpEnabledStateActive; // not really necessary
result = HttpSetConfigGroupInformation(
ControlChannel,
configId,
HttpConfigGroupStateInformation,
&configState,
sizeof(configState)
);
if (result != NO_ERROR)
{
wprintf( L"HttpSetConfigGroupInformation(2) failed, error %lu\n", result );
goto cleanup;
}
//
// Set security
//
result = InitSecurityDescriptor(&pSecurityDescriptor);
if (result != NO_ERROR)
{
wprintf( L"InitSecurityDescriptor() failed, error %lu\n", result );
goto cleanup;
}
//
// Set the security descriptor into the config group
//
configSecurity.Flags.Present = 1;
configSecurity.pSecurityDescriptor = pSecurityDescriptor;
result = HttpSetConfigGroupInformation(
ControlChannel,
configId,
HttpConfigGroupSecurityInformation,
&configSecurity,
sizeof(configSecurity)
);
FreeSecurityDescriptor(pSecurityDescriptor);
if (result != NO_ERROR)
{
wprintf( L"HttpSetConfigGroupInformation(3) failed, error %lu\n", result );
goto cleanup;
}
//
// Done!
//
*pConfigId = configId;
return NO_ERROR;
cleanup:
if (!HTTP_IS_NULL_ID( &configId ))
{
result = HttpDeleteConfigGroup(
ControlChannel,
configId
);
if (result != NO_ERROR)
{
wprintf( L"HttpDeleteConfigGroup() failed, error %lu\n", result );
}
}
return result;
}
ULONG
InitSecurityDescriptor(
OUT PSECURITY_DESCRIPTOR * ppSD
)
{
ULONG result;
SID_IDENTIFIER_AUTHORITY worldAuthority = SECURITY_WORLD_SID_AUTHORITY;
ULONG daclSize;
PSECURITY_DESCRIPTOR pSecurityDescriptor = NULL;
PACL pAcl = NULL;
PSID pSid = NULL;
BOOL success;
//
// Create the world sid
//
success = AllocateAndInitializeSid(
&worldAuthority,
1,
SECURITY_WORLD_RID,
0,
0,
0,
0,
0,
0,
0,
&pSid
);
if (!success) {
result = GetLastError();
goto cleanup;
}
//
// allocate the security descriptor
//
pSecurityDescriptor = ALLOC( 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;
}
//
// allocate and initialize the dacl
//
daclSize = sizeof(ACL) +
sizeof(ACCESS_ALLOWED_ACE) +
GetLengthSid(pSid);
pAcl = ALLOC(daclSize);
if (pAcl == NULL) {
result = ERROR_NOT_ENOUGH_MEMORY;
goto cleanup;
}
success = InitializeAcl(pAcl, daclSize, ACL_REVISION);
if (!success)
{
result = GetLastError();
goto cleanup;
}
//
// Add the ACE.
//
success = AddAccessAllowedAce(
pAcl,
ACL_REVISION,
FILE_ALL_ACCESS,
pSid
);
if (!success)
{
result = GetLastError();
goto cleanup;
}
//
// Set the DACL into the security descriptor
//
success = SetSecurityDescriptorDacl(
pSecurityDescriptor,
TRUE, // DaclPresent
pAcl, // pDacl
FALSE // DaclDefaulted
);
if (!success)
{
result = GetLastError();
goto cleanup;
}
*ppSD = pSecurityDescriptor;
result = NO_ERROR;
cleanup:
if (pSid) {
FreeSid(pSid);
}
if (result != NO_ERROR) {
if (pSecurityDescriptor) {
FREE(pSecurityDescriptor);
}
if (pAcl) {
FREE(pAcl);
}
}
return result;
}
VOID
FreeSecurityDescriptor(
IN PSECURITY_DESCRIPTOR pSD
)
{
BOOL success;
BOOL DaclPresent;
PACL pDacl;
BOOL DaclDefaulted;
success = GetSecurityDescriptorDacl(
pSD,
&DaclPresent,
&pDacl,
&DaclDefaulted
);
if (success && DaclPresent && !DaclDefaulted) {
FREE(pDacl);
}
FREE(pSD);
}