📄 db.cpp
字号:
// DB.CPP - This module implements the database routines for the authentication filter.
#include "stdafx.h"
#include "AuthFilt.h"
/*
Routine Description:
Looks up the username and confirms the user is allowed access to the
server
Arguments:
pszUserName - The username to validate, will contain the mapped username
on return. Must be at least SF_MAX_USERNAME
pszPassword - The password for this user. Will contain the mapped
password on return. Must be at least SF_MAX_PASSWORD
pfValid - Set to TRUE if the user should be logged on.
Return Value:
TRUE on success, FALSE on failure
*/
BOOL CAuthFilter::ValidateUser(IN OUT CHAR* pszUserName, IN OUT CHAR* pszPassword, OUT BOOL* pfValid)
{
// Assume we're going to fail validation
*pfValid = FALSE;
BOOL fFound;
CHAR achPassword[SF_MAX_PASSWORD];
CHAR achNTUser[SF_MAX_USERNAME];
CHAR achNTUserPassword[SF_MAX_PASSWORD];
// Lookup the user in the cache, if that fails, get the user from the
// database and add the retrieved user to the cache
if ( !LookupUserInCache( pszUserName, &fFound, achPassword, achNTUser, achNTUserPassword ))
return FALSE;
if ( !fFound )
{
if ( !LookupUserInDb( pszUserName, &fFound, achPassword, achNTUser, achNTUserPassword ))
return FALSE;
if ( fFound )
AddUserToCache( pszUserName, achPassword, achNTUser, achNTUserPassword );
}
if ( !fFound )
{
ISAPITRACE1("[ValidateUser] Failed to find user %s\n", pszUserName );
return TRUE;
}
// Do the passwords match?
if ( !strcmp( pszPassword, achPassword ))
{
// We have a match, map to the NT user and password
strcpy( pszUserName, achNTUser );
strcpy( pszPassword, achNTUserPassword );
*pfValid = TRUE;
}
return TRUE;
}
/*
Routine Description:
Retrieves the userlist from the file. If the users were coming from a
database, this routine would connect to the database.
Return Value:
TRUE on success, FALSE on failure
*/
BOOL CAuthFilter::InitializeUserDatabase()
{
DWORD cbRead;
// Open and read the file. The System account must have access to the file.
HANDLE hFile = CreateFile( USER_LIST_FILE, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
if ( hFile == INVALID_HANDLE_VALUE )
{
ISAPITRACE2("[InitializeUserDatabase] Error %d openning %s\n", GetLastError(), USER_LIST_FILE );
return FALSE;
}
DWORD cbFile = GetFileSize( hFile, NULL );
if ( cbFile == (DWORD) -1 )
{
CloseHandle( hFile );
return FALSE;
}
m_pszUserFile = (CHAR *)LocalAlloc( LPTR, cbFile + 1 );
if ( !m_pszUserFile )
{
SetLastError( ERROR_NOT_ENOUGH_MEMORY );
CloseHandle( hFile );
return FALSE;
}
if ( !ReadFile( hFile, m_pszUserFile, cbFile, &cbRead, NULL ))
{
CloseHandle( hFile );
LocalFree( m_pszUserFile );
return FALSE;
}
CloseHandle( hFile );
// Zero terminate the file data
m_pszUserFile[cbRead] = '\0';
return TRUE;
}
/*
Routine Description:
Looks up the username in the database and returns the other attributes
associated with this user
The file data is not sorted to simulate the cost of an external database
lookup.
Arguments:
pszUserName - The username to find in the database (case insensitive)
pfFound - Set to TRUE if the specified user name was found in the
database
pszPassword - The external password for the found user.
pszNTUser - The NT username associated with this user.
pszNTUserPassword - The password for NTUser.
Return Value:
TRUE on success, FALSE on failure
*/
BOOL CAuthFilter::LookupUserInDb(const CHAR* pszUser, OUT BOOL* pfFound, OUT CHAR* pszPassword, OUT CHAR* pszNTUser, OUT CHAR* pszNTUserPassword)
{
*pfFound = FALSE;
// Find the external username. We're expecting one user per line in the form:
// username:password, NTUser:NTUserPassword
CHAR* pch = m_pszUserFile;
DWORD cchUser = strlen( pszUser );
while ( pch && *pch )
{
while ( ISWHITE( *pch ) )
pch++;
if ( toupper( *pch ) == toupper( *pszUser ) &&
!strnicmp( pszUser, pch, cchUser ) &&
pch[cchUser] == ':' )
{
pch += cchUser + 1;
goto Found;
}
pch = strchr( pch+1, '\n' );
}
// Not found
return TRUE;
Found:
// Break out the external username
CHAR* pchEnd = strchr( pch, ',' );
if (!pchEnd)
{
SetLastError( ERROR_INVALID_PASSWORDNAME );
return FALSE;
}
DWORD cch = pchEnd - pch;
if ( cch+1 > SF_MAX_PASSWORD )
{
SetLastError( ERROR_INVALID_PASSWORDNAME );
return FALSE;
}
memcpy( pszPassword, pch, cch );
pszPassword[cch] = '\0';
pch = pchEnd + 1;
// Get the NT username from the file
while ( ISWHITE( *pch ) )
pch++;
if ( !(pchEnd = strchr( pch, ':' )))
{
SetLastError( ERROR_BAD_USERNAME );
return FALSE;
}
cch = pchEnd - pch;
if ( cch+1 > SF_MAX_USERNAME )
{
SetLastError( ERROR_BAD_USERNAME );
return FALSE;
}
memcpy( pszNTUser, pch, cch );
pszNTUser[cch] = '\0';
pch = pchEnd + 1;
// Get the NT password from the file, look for a '\r' or '\n'
pchEnd = pch;
while ( *pchEnd && (*pchEnd!='\r') && (*pchEnd!='\n') )
pchEnd++;
cch = pchEnd - pch;
if ( cch+1 > SF_MAX_PASSWORD )
{
SetLastError( ERROR_INVALID_PASSWORDNAME );
return FALSE;
}
memcpy( pszNTUserPassword, pch, cch );
pszNTUserPassword[cch] = '\0';
*pfFound = TRUE;
return TRUE;
}
/*
Routine Description:
Shutsdown the user database.
*/
VOID CAuthFilter::TerminateUserDatabase()
{
if ( m_pszUserFile )
LocalFree(m_pszUserFile );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -