#ifndef MAC #include #endif #include #include #include #include #include #include #include "cache.h" #ifndef MAC #include #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); }