Microsoft KB Archive/239738

= PRB: ISAPI Filter AuthFilt Sample Causes Access Violation =

Article ID: 239738

Article Last Modified on 11/21/2006

-

APPLIES TO


 * Microsoft Internet Information Server 4.0
 * Microsoft Internet Information Services 5.0
 * Microsoft Internet Information Services 5.1

-



This article was previously published under Q239738



SYMPTOMS
The Microsoft Internet Information Server SDK contains an Internet Server Application Programming Interface (ISAPI) AuthFilt filter sample in the \InterPub\Iissamples\Sdk\Isapi\Filters\AuthFilt folder. When you use the AuthFilt sample directly, an access violation occurs.



CAUSE
The AuthFilt sample allocates a buffer on the SF_NOTIFY_AUTHENTICATION notification with AllocMem: pfc->pFilterContext = pfc->AllocMem( pfc, 2 * SF_MAX_USERNAME + 4, 0 ); Then, the AuthFilt sample has string concatenations within the SF_NOTIFY_LOG event: pch = pfc->pFilterContext; pLog = (HTTP_FILTER_LOG *) pvData;

strcat( pch, " (" ); strcat( pch, pLog->pszClientUserName ); strcat( pch, ")" ); NOTE: Multiple requests occur on the same network session if the connection is keep-alive (authentication occurs only once per session). The filter is called multiple times in the SF_NOTIFY_LOG event within the same session. Because the pFilterContext buffer is maintained for the entire session, having a fixed size of 2 * SF_MAX_USERNAME + 4, an access violation occurs.



RESOLUTION
To work around this behavior, perform the following:   Define a struct: typedef struct {   int iLength; CHAR szUsername[ 2 * SF_MAX_USERNAME + 4 ]; } USERID;   Define a new pointer at the beginning of the HttpFilterProc function: USERID *  pUser;   Allocate a buffer to store the unmapped username and its length in SF_NOTIFY_AUTHENTICATION: if ( !pfc->pFilterContext ) {  pfc->pFilterContext = pfc->AllocMem( pfc, sizeof ( USERID ), 0 ); if ( !pfc->pFilterContext ) {     SetLastError( ERROR_NOT_ENOUGH_MEMORY ); return SF_STATUS_REQ_ERROR; } } pUser = pfc->pFilterContext; strcpy(pUser->szUsername, achUser ); pUser->iLength = strlen ( achUser );

return SF_STATUS_REQ_HANDLED_NOTIFICATION;   In the SF_NOTIFY_LOG event, set a NULL char at the end of the unmapped username. (This allows the strcat to append the mapped username to the unmapped username.) if ( pfc->pFilterContext ) {  pUser = pfc->pFilterContext; pUser->szUsername [ pUser->iLength ] = 0;

pch =  pUser->szUsername; pLog = ( HTTP_FILTER_LOG* ) pvData;

strcat( pch, " (" );  strcat( pch, pLog->pszClientUserName );   strcat( pch, ")" );

pLog->pszClientUserName = pch; }                   



MORE INFORMATION
There is an unrelated problem in the AuthFilt sample. The AuthFilt sample is called with a non-NULL lpvContext to terminate the cache and the user database on the case of DLL_PROCESS_DETACH in the DllMain. Because ISAPI is unloaded with the FreeLibrary, lpvContext is a non-NULL for ISAPI and the cache and the user database are not cleaned up at all. BOOL WINAPI DllMain(    IN HINSTANCE hinstDll,     IN DWORD     fdwReason,     IN LPVOID    lpvContext OPTIONAL     ) {   BOOL fReturn = TRUE;

switch (fdwReason ) {   case DLL_PROCESS_ATTACH: ...   break;

case DLL_PROCESS_DETACH: {           if ( lpvContext != NULL) {                TerminateCache; TerminateUserDatabase; }

break; } /* case DLL_PROCESS_DETACH */

default: break; }  /* switch */

return ( fReturn ); } /* DllLibMain */ Remove the "if ( lpvContext != NULL)" statement on the case of DLL_PROCESS_DETACH in DllMain so that the cache and the user database terminate when the filter is unloaded.

Keywords: kbfilter kbprb KB239738

-

[mailto:TECHNET@MICROSOFT.COM Send feedback to Microsoft]

© Microsoft Corporation. All rights reserved.