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.
 
 
 
 
 
 

305 lines
8.1 KiB

#ifndef MAC
#include <security.h>
#endif
#include <bootdefs.h>
#include <sspi.h>
#include <ntlmsspi.h>
#include <crypt.h>
#include <cred.h>
#include <winerror.h>
#include "cache.h"
#ifndef MAC
#include <rpc.h>
#endif
#define toupper(_c) ( ((_c) >= 'a' && (_c) <= 'z') ? ( (_c)-'a'+'A' ) : (_c) )
BOOL
SspGetWorkstation(
PSSP_CREDENTIAL Credential
);
static PSSP_CREDENTIAL Cache = NULL;
void
CacheInitializeCache(
)
{
}
BOOL
CacheGetPassword(
PSSP_CREDENTIAL Credential
)
{
if (Cache == NULL) {
return (FALSE);
}
#ifdef BL_USE_LM_PASSWORD
Credential->LmPassword = SspAlloc (sizeof(LM_OWF_PASSWORD));
if (Credential->LmPassword == NULL) {
return (FALSE);
}
#endif
Credential->NtPassword = (LM_OWF_PASSWORD*)SspAlloc (sizeof(NT_OWF_PASSWORD));
if (Credential->NtPassword == NULL) {
return (FALSE);
}
#ifdef BL_USE_LM_PASSWORD
_fmemcpy((PCHAR)Credential->LmPassword, (PCHAR)Cache->LmPassword, sizeof(LM_OWF_PASSWORD));
#endif
_fmemcpy((PCHAR)Credential->NtPassword, (PCHAR)Cache->NtPassword, sizeof(NT_OWF_PASSWORD));
return (TRUE);
}
SECURITY_STATUS
CacheSetCredentials(
IN PVOID AuthData,
PSSP_CREDENTIAL Credential
)
{
SEC_WINNT_AUTH_IDENTITY *Identity = (SEC_WINNT_AUTH_IDENTITY*)AuthData;
char TmpText[CLEAR_BLOCK_LENGTH*2];
NT_PASSWORD TmpNtPassword;
WCHAR TmpUnicodeText[CLEAR_BLOCK_LENGTH*2];
int Length = 0;
int i = 0;
if (Identity->Domain == NULL)
return SEC_E_UNKNOWN_CREDENTIALS;
Credential->Username = NULL;
Credential->Domain = NULL;
#ifdef BL_USE_LM_PASSWORD
Credential->LmPassword = NULL;
#endif
Credential->NtPassword = NULL;
Credential->Workstation = NULL;
// If no identity is passed and there is no cached identity, give up.
if (AuthData == NULL)
{
if (Cache == NULL)
return SEC_E_UNKNOWN_CREDENTIALS;
}
// Save the latest authentication information.
else
{
// If an old cache entry exists, release its strings.
if (Cache != NULL)
{
if (Cache->Username != NULL)
SspFree(Cache->Username);
if (Cache->Domain != NULL)
SspFree(Cache->Domain);
if (Cache->Workstation != NULL)
SspFree(Cache->Workstation);
#ifdef BL_USE_LM_PASSWORD
if (Cache->LmPassword != NULL)
SspFree(Cache->LmPassword);
#endif
if (Cache->NtPassword != NULL)
SspFree(Cache->NtPassword);
}
// Otherwise, allocate a cache entry
else
{
Cache = (PSSP_CREDENTIAL) SspAlloc (sizeof(SSP_CREDENTIAL));
if (Cache == NULL) {
return (SEC_E_INSUFFICIENT_MEMORY);
}
}
Cache->Username = NULL;
Cache->Domain = NULL;
#ifdef BL_USE_LM_PASSWORD
Cache->LmPassword = NULL;
#endif
Cache->NtPassword = NULL;
Cache->Workstation = NULL;
Cache->Username = (PCHAR)SspAlloc(_fstrlen((const char*)Identity->User) + 1);
if (Cache->Username == NULL) {
goto cache_failure;
}
_fstrcpy(Cache->Username, (const char*)Identity->User);
Cache->Domain = (PCHAR)SspAlloc(_fstrlen((const char*)Identity->Domain) + 1);
if (Cache->Domain == NULL) {
goto cache_failure;
}
_fstrcpy(Cache->Domain, (const char*)Identity->Domain);
// If netbios won't tell us the workstation name, make one up.
if (!SspGetWorkstation(Cache))
{
Cache->Workstation = (PCHAR)SspAlloc(_fstrlen("none") + 1);
if (Cache->Workstation == NULL) {
goto cache_failure;
}
_fstrcpy(Cache->Workstation, "none");
}
#ifdef BL_USE_LM_PASSWORD
Cache->LmPassword = SspAlloc (sizeof(LM_OWF_PASSWORD));
if (Cache->LmPassword == NULL) {
goto cache_failure;
}
#endif
Cache->NtPassword = (LM_OWF_PASSWORD*)SspAlloc (sizeof(NT_OWF_PASSWORD));
if (Cache->NtPassword == NULL) {
goto cache_failure;
}
#ifdef ALLOW_NON_OWF_PASSWORD
if ( (Credential->CredentialUseFlags & SECPKG_CRED_OWF_PASSWORD) == 0 ) {
if (Identity->Password == NULL)
Length = 0;
else
Length = _fstrlen(Identity->Password);
if (Length > CLEAR_BLOCK_LENGTH * 2)
goto cache_failure;
// Allow NULL and "\0" passwords by prefilling TmpText with and
// empty string.
if (Length == 0)
TmpText[0] = 0;
else
for (i = 0; i <= Length; i++) {
TmpText[i] = toupper(Identity->Password[i]);
TmpUnicodeText[i] = (WCHAR)(Identity->Password[i]);
}
#ifdef BL_USE_LM_PASSWORD
CalculateLmOwfPassword((PLM_PASSWORD)TmpText, Cache->LmPassword);
#endif
TmpNtPassword.Buffer = TmpUnicodeText;
TmpNtPassword.Length = Length * sizeof(WCHAR);
TmpNtPassword.MaximumLength = sizeof(TmpUnicodeText);
CalculateNtOwfPassword(&TmpNtPassword, Cache->NtPassword);
} else
#endif
{
//
// In this case the passed-in password is the LM and NT OWF
// passwords concatenated together.
//
#ifdef BL_USE_LM_PASSWORD
_fmemcpy(Cache->LmPassword, Identity->Password, sizeof(LM_OWF_PASSWORD));
#endif
_fmemcpy(Cache->NtPassword, Identity->Password + sizeof(LM_OWF_PASSWORD), sizeof(NT_OWF_PASSWORD));
}
}
// Copy the credentials for the caller.
Credential->Username = (PCHAR)SspAlloc(_fstrlen(Cache->Username) + 1);
if (Credential->Username == NULL) {
goto out_failure;
}
_fstrcpy(Credential->Username, Cache->Username);
if (_fstrcmp(Cache->Domain, "WORKGROUP") != 0) {
Credential->Domain = (PCHAR)SspAlloc(_fstrlen(Cache->Domain) + 1);
if (Credential->Domain == NULL) {
goto out_failure;
}
_fstrcpy(Credential->Domain, Cache->Domain);
}
Credential->Workstation = (PCHAR)SspAlloc(_fstrlen(Cache->Workstation) + 1);
if (Credential->Workstation == NULL) {
goto out_failure;
}
_fstrcpy(Credential->Workstation, Cache->Workstation);
#ifdef BL_USE_LM_PASSWORD
Credential->LmPassword = SspAlloc(sizeof(LM_OWF_PASSWORD));
if (Credential->LmPassword == NULL) {
goto out_failure;
}
_fmemcpy(Credential->LmPassword, Cache->LmPassword, sizeof(LM_OWF_PASSWORD));
#endif
Credential->NtPassword = (LM_OWF_PASSWORD*)SspAlloc(sizeof(NT_OWF_PASSWORD));
if (Credential->NtPassword == NULL) {
goto out_failure;
}
_fmemcpy(Credential->NtPassword, Cache->NtPassword, sizeof(NT_OWF_PASSWORD));
return (SEC_E_OK);
cache_failure:
if (Cache->Username != NULL) {
SspFree(Cache->Username);
}
if (Cache->Domain != NULL) {
SspFree(Cache->Domain);
}
if (Cache->Workstation != NULL) {
SspFree(Cache->Workstation);
}
#ifdef BL_USE_LM_PASSWORD
if (Cache->LmPassword != NULL) {
SspFree(Cache->LmPassword);
}
#endif
if (Cache->NtPassword != NULL) {
SspFree(Cache->NtPassword);
}
SspFree(Cache);
Cache = NULL;
out_failure:
if (Credential->Username != NULL) {
SspFree(Credential->Username);
Credential->Username = NULL;
}
if (Credential->Domain != NULL) {
SspFree(Credential->Domain);
Credential->Domain = NULL;
}
if (Credential->Workstation != NULL) {
SspFree(Credential->Workstation);
Credential->Workstation = NULL;
}
#ifdef BL_USE_LM_PASSWORD
if (Credential->LmPassword != NULL) {
SspFree(Credential->LmPassword);
Credential->LmPassword = NULL;
}
#endif
if (Credential->NtPassword != NULL) {
SspFree(Credential->NtPassword);
Credential->NtPassword = NULL;
}
return (SEC_E_INSUFFICIENT_MEMORY);
}