Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

442 lines
9.0 KiB

#ifndef _TOKENCACHE_HXX_
#define _TOKENCACHE_HXX_
#include <wincrypt.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include "usercache.hxx"
#include "stringa.hxx"
//
// Special logon types to indicate local system and passport
//
#define IIS_LOGON_METHOD_LOCAL_SYSTEM (-2)
#define IIS_LOGON_METHOD_PASSPORT (-3)
#define DEFAULT_MD5_HASH_SIZE 16
class TOKEN_CACHE_KEY : public CACHE_KEY
{
public:
TOKEN_CACHE_KEY()
: m_strHashKey( m_achHashKey, sizeof( m_achHashKey ) )
{
}
BOOL
QueryIsEqual(
const CACHE_KEY * pCompareKey
) const
{
TOKEN_CACHE_KEY * pTokenKey = (TOKEN_CACHE_KEY*) pCompareKey;
DBG_ASSERT( pTokenKey != NULL );
//
// If lengths are not equal, this is easy
//
if ( m_strHashKey.QueryCB() != pTokenKey->m_strHashKey.QueryCB() )
{
return FALSE;
}
//
// Do memcmp
//
return memcmp( m_strHashKey.QueryStr(),
pTokenKey->m_strHashKey.QueryStr(),
m_strHashKey.QueryCB() ) == 0;
}
DWORD
QueryKeyHash(
VOID
) const
{
return HashString( m_strHashKey.QueryStr() );
}
HRESULT
SetKey(
TOKEN_CACHE_KEY * pCacheKey
)
{
return m_strHashKey.Copy( pCacheKey->m_strHashKey.QueryStr() );
}
HRESULT
CreateCacheKey(
WCHAR * pszUserName,
WCHAR * pszDomainName,
DWORD dwLogonMethod
);
private:
WCHAR m_achHashKey[ 64 ];
STRU m_strHashKey;
};
//
// The check period for how long a token can be in the cache.
// Tokens can be in the cache for up to two times this value
// (in seconds)
//
#define DEFAULT_CACHED_TOKEN_TTL ( 15 * 60 )
#define SID_DEFAULT_SIZE 64
#define TOKEN_CACHE_ENTRY_SIGNATURE 'TC3W'
#define TOKEN_CACHE_ENTRY_FREE_SIGNATURE 'fC3W'
class TOKEN_CACHE_ENTRY : public CACHE_ENTRY
{
public:
TOKEN_CACHE_ENTRY( OBJECT_CACHE * pObjectCache )
: CACHE_ENTRY( pObjectCache ),
m_strMD5Password( m_achMD5Password, sizeof( m_achMD5Password ) ),
m_lOOPToken( 0 ),
m_lDisBackupPriToken( 0 ),
m_hImpersonationToken( NULL ),
m_hPrimaryToken( NULL ),
m_pSid( NULL )
{
m_liPwdExpiry.HighPart = 0x7fffffff;
m_liPwdExpiry.LowPart = 0xffffffff;
m_dwSignature = TOKEN_CACHE_ENTRY_SIGNATURE;
}
virtual ~TOKEN_CACHE_ENTRY()
{
DBG_ASSERT( CheckSignature() );
m_dwSignature = TOKEN_CACHE_ENTRY_FREE_SIGNATURE;
if ( m_hImpersonationToken != NULL )
{
CloseHandle( m_hImpersonationToken );
m_hImpersonationToken = NULL;
}
if ( m_hPrimaryToken != NULL )
{
CloseHandle( m_hPrimaryToken );
m_hPrimaryToken = NULL;
}
}
CACHE_KEY *
QueryCacheKey(
VOID
) const
{
return (CACHE_KEY*) &m_cacheKey;
}
HRESULT
SetCacheKey(
TOKEN_CACHE_KEY * pCacheKey
)
{
return m_cacheKey.SetKey( pCacheKey );
}
BOOL
CheckSignature(
VOID
) const
{
return m_dwSignature == TOKEN_CACHE_ENTRY_SIGNATURE;
}
VOID *
operator new(
#if DBG
size_t size
#else
size_t
#endif
)
{
DBG_ASSERT( size == sizeof( TOKEN_CACHE_ENTRY ) );
DBG_ASSERT( sm_pachTokenCacheEntry != NULL );
return sm_pachTokenCacheEntry->Alloc();
}
VOID
operator delete(
VOID * pTokenCacheEntry
)
{
DBG_ASSERT( pTokenCacheEntry != NULL );
DBG_ASSERT( sm_pachTokenCacheEntry != NULL );
DBG_REQUIRE( sm_pachTokenCacheEntry->Free( pTokenCacheEntry ) );
}
HANDLE
QueryImpersonationToken(
VOID
);
HANDLE
QueryPrimaryToken(
VOID
);
PSID
QuerySid(
VOID
);
LARGE_INTEGER *
QueryExpiry(
VOID
)
{
return &m_liPwdExpiry;
}
LONG
QueryOOPToken(
VOID
)
{
if( m_lOOPToken )
{
return m_lOOPToken;
}
return InterlockedExchange( &m_lOOPToken, 1 );
}
LONG
QueryDisBackupPriToken(
VOID
)
{
if( m_lDisBackupPriToken )
{
return m_lDisBackupPriToken;
}
return InterlockedExchange( &m_lDisBackupPriToken, 1 );
}
HRESULT
GenMD5Password(
IN WCHAR * pszPassword,
OUT STRA * pstrMD5Password
);
HRESULT
EqualMD5Password(
IN WCHAR * pszPassword,
OUT BOOL * fEqual
);
HRESULT
Create(
IN HANDLE hToken,
IN WCHAR * pszPassword,
IN LARGE_INTEGER * pliPwdExpiry,
IN BOOL fImpersonation
);
static
HRESULT
Initialize(
VOID
);
static
VOID
Terminate(
VOID
);
private:
TOKEN_CACHE_ENTRY(const TOKEN_CACHE_ENTRY &);
void operator=(const TOKEN_CACHE_ENTRY &);
DWORD m_dwSignature;
//
// Cache key
//
TOKEN_CACHE_KEY m_cacheKey;
//
// Hashed password. The hashed binary data will be converted to
// ASCII hex representation, so the size would be twice as big
// as the original one
//
CHAR m_achMD5Password[ 2 * DEFAULT_MD5_HASH_SIZE + 1 ];
STRA m_strMD5Password;
//
// The actual tokens
//
HANDLE m_hImpersonationToken;
HANDLE m_hPrimaryToken;
//
// Have we modified the token for OOP isapi
//
LONG m_lOOPToken;
//
// Have we disabled the backup privilege for the token
//
LONG m_lDisBackupPriToken;
//
// Time to expire for the token
//
LARGE_INTEGER m_liPwdExpiry;
//
// Keep the sid for file cache purposes
//
PSID m_pSid;
BYTE m_abSid[ SID_DEFAULT_SIZE ];
//
// Allocation cache for TOKEN_CACHE_ENTRY's
//
static ALLOC_CACHE_HANDLER * sm_pachTokenCacheEntry;
//
// Handle of a cryptographic service provider
//
static HCRYPTPROV sm_hCryptProv;
};
class TOKEN_CACHE : public OBJECT_CACHE
{
public:
TOKEN_CACHE()
: m_dwLastPriorityUPNLogon ( 0 ),
m_hKey ( NULL ),
m_hEvent ( NULL ),
m_hWaitObject ( NULL ),
m_fInitializedThreadPool ( FALSE )
{}
~TOKEN_CACHE()
{}
HRESULT
GetCachedToken(
IN LPWSTR pszUserName,
IN LPWSTR pszDomain,
IN LPWSTR pszPassword,
IN DWORD dwLogonMethod,
IN BOOL fUseSubAuth,
IN BOOL fPossibleUPNLogon,
IN PSOCKADDR pSockAddr,
OUT TOKEN_CACHE_ENTRY ** ppCachedToken,
OUT DWORD * pdwLogonError
);
WCHAR *
QueryName(
VOID
) const
{
return L"TOKEN_CACHE";
}
HKEY
QueryRegKey(
VOID
) const
{
return m_hKey;
}
HANDLE
QueryEventHandle(
VOID
) const
{
return m_hEvent;
}
HRESULT
Initialize(
VOID
);
VOID
Terminate(
VOID
);
static
VOID
WINAPI
FlushTokenCacheWaitCallback(
PVOID pParam,
BOOL fWaitFired
);
private:
TOKEN_CACHE(const TOKEN_CACHE &);
void operator=(const TOKEN_CACHE &);
DWORD m_dwLastPriorityUPNLogon;
//
// Handle to the "UserTokenTTL" registry key
//
HKEY m_hKey;
//
// Handle to the event waiting for the notification
//
HANDLE m_hEvent;
//
// Wait handle
//
HANDLE m_hWaitObject;
//
// Has the threadpool been successfully initialized
//
BOOL m_fInitializedThreadPool;
};
HRESULT
ToHex(
IN BUFFER & buffSrc,
OUT STRA & strDst
);
#endif