home *** CD-ROM | disk | FTP | other *** search
- /*++
-
- 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;
- }
-
-
-