home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 1998 February
/
CHIP_2_98.iso
/
software
/
pelne
/
optionp
/
iis4_07.cab
/
authfilt.c
< prev
next >
Wrap
Text File
|
1997-10-25
|
7KB
|
281 lines
/*++
Copyright (c) 1996 Microsoft Corporation
This program is released into the public domain for any purpose.
Module Name:
authfilt.c
Abstract:
This module is an example of an ISAPI Authentication Filter.
It demonstrates how to do an authentication filter based on an external
datasource. Though this sample uses a flat file, access to a database
could easily be plugged in.
--*/
#include <windows.h>
#include <httpfilt.h>
#include "authfilt.h"
//
// Functions
//
BOOL
WINAPI
DllMain(
IN HINSTANCE hinstDll,
IN DWORD fdwReason,
IN LPVOID lpvContext OPTIONAL
)
/*++
Routine Description:
This function DllLibMain() is the main initialization function for
this DLL. It initializes local variables and prepares it to be invoked
subsequently.
Arguments:
hinstDll Instance Handle of the DLL
fdwReason Reason why NT called this DLL
lpvReserved Reserved parameter for future use.
Return Value:
Returns TRUE is successful; otherwise FALSE is returned.
--*/
{
BOOL fReturn = TRUE;
switch (fdwReason )
{
case DLL_PROCESS_ATTACH:
if ( !InitializeUserDatabase() ||
!InitializeCache() )
{
DbgWrite(( DEST,
"[GetFilterVersion] Database or cache failed, error %d\n",
GetLastError() ))
return FALSE;
}
//
// We don't care about thread attach/detach notifications
//
DisableThreadLibraryCalls( hinstDll );
break;
case DLL_PROCESS_DETACH:
{
if ( lpvContext != NULL)
{
TerminateCache();
TerminateUserDatabase();
}
break;
} /* case DLL_PROCESS_DETACH */
default:
break;
} /* switch */
return ( fReturn);
} /* DllLibMain() */
BOOL
WINAPI
GetFilterVersion(
HTTP_FILTER_VERSION * pVer
)
{
DbgWrite(( DEST,
"[GetFilterVersion] Server filter version is %d.%d\n",
HIWORD( pVer->dwServerFilterVersion ),
LOWORD( pVer->dwServerFilterVersion ) ));
pVer->dwFilterVersion = HTTP_FILTER_REVISION;
//
// Specify the types and order of notification
//
pVer->dwFlags = (SF_NOTIFY_SECURE_PORT |
SF_NOTIFY_NONSECURE_PORT |
SF_NOTIFY_AUTHENTICATION |
SF_NOTIFY_LOG |
SF_NOTIFY_ORDER_DEFAULT);
strcpy( pVer->lpszFilterDesc, "Sample Authentication Filter, version 1.0" );
return TRUE;
}
DWORD
WINAPI
HttpFilterProc(
HTTP_FILTER_CONTEXT * pfc,
DWORD NotificationType,
VOID * pvData
)
/*++
Routine Description:
Filter notification entry point
Arguments:
pfc - Filter context
NotificationType - Type of notification
pvData - Notification specific data
Return Value:
One of the SF_STATUS response codes
--*/
{
BOOL fAllowed;
CHAR achUser[SF_MAX_USERNAME];
HTTP_FILTER_AUTHENT * pAuth;
HTTP_FILTER_LOG * pLog;
CHAR * pch;
//
// Handle this notification
//
switch ( NotificationType )
{
case SF_NOTIFY_AUTHENTICATION:
pAuth = (HTTP_FILTER_AUTHENT *) pvData;
//
// Ignore the anonymous user
//
if ( !*pAuth->pszUser )
{
//
// Tell the server to notify any subsequent notifications in the
// chain
//
return SF_STATUS_REQ_NEXT_NOTIFICATION;
}
//
// Save the unmapped username so we can log it later
//
strcpy( achUser, pAuth->pszUser );
//
// Make sure this user is a valid user and map to the appropriate
// Windows NT user
//
if ( !ValidateUser( pAuth->pszUser,
pAuth->pszPassword,
&fAllowed ))
{
DbgWrite(( DEST,
"[OnAuthentication] Error %d validating user %s\n",
GetLastError(),
pAuth->pszUser ));
return SF_STATUS_REQ_ERROR;
}
if ( !fAllowed )
{
//
// This user isn't allowed access. Indicate this to the server
//
SetLastError( ERROR_ACCESS_DENIED );
return SF_STATUS_REQ_ERROR;
}
//
// Save the unmapped user name so we can log it later on. We allocate
// enough space for two usernames so we can use this memory block
// for logging. Note we may have already allocated it from a previous
// request on this TCP session
//
if ( !pfc->pFilterContext )
{
pfc->pFilterContext = pfc->AllocMem( pfc, 2 * SF_MAX_USERNAME + 4, 0 );
if ( !pfc->pFilterContext )
{
SetLastError( ERROR_NOT_ENOUGH_MEMORY );
return SF_STATUS_REQ_ERROR;
}
}
strcpy( (CHAR *) pfc->pFilterContext, achUser );
return SF_STATUS_REQ_HANDLED_NOTIFICATION;
case SF_NOTIFY_LOG:
//
// The unmapped username is in pFilterContext if this filter
// authenticated this user
//
if ( pfc->pFilterContext )
{
pch = pfc->pFilterContext;
pLog = (HTTP_FILTER_LOG *) pvData;
//
// Put both the original username and the NT mapped username
// into the log in the form "Original User (NT User)"
//
strcat( pch, " (" );
strcat( pch, pLog->pszClientUserName );
strcat( pch, ")" );
pLog->pszClientUserName = pch;
}
return SF_STATUS_REQ_NEXT_NOTIFICATION;
default:
DbgWrite(( DEST,
"[HttpFilterProc] Unknown notification type, %d\n",
NotificationType ));
break;
}
return SF_STATUS_REQ_NEXT_NOTIFICATION;
}