Source code of Windows XP (NT5)
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.
 
 
 
 
 
 

1403 lines
32 KiB

//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1997.
//
// File: samlock.c
//
// Contents:
//
// Classes:
//
// Functions:
//
// History: 4-19-97 RichardW Created
//
//----------------------------------------------------------------------------
#include "samlock.h"
#include <stdio.h>
#include <wchar.h>
#if DBG
#define HIDDEN
#else
#define HIDDEN static
#endif
#define MAKE_SAM_CALLS 1
#if MAKE_SAM_CALLS
#define SYSTEM_KEY TEXT("SecureBoot")
#else
#define SYSTEM_KEY TEXT("BootType")
#endif
#define KEYFILE TEXT("A:\\StartKey.Key")
#define KEYFILE_SAVE TEXT("A:\\StartKey.Bak")
HICON hLockIcon ;
HICON KeyDataPwIcon ;
HICON KeyDataDiskIcon ;
SAMPR_BOOT_TYPE SecureBootOption = 0;
SAMPR_BOOT_TYPE OriginalBootOption = 0 ;
SAM_HANDLE SamHandle ;
SAM_HANDLE DomainHandle ;
HKEY LsaKey ;
HCURSOR hcurArrow ;
HCURSOR hcurWait ;
BOOL WaitCursor ;
WCHAR OptionL[ 4 ]; // Unattended, local store
WCHAR OptionQ[ 4 ]; // Question (usage)
BOOL Unattended = FALSE ;
DWORD PwSection[] = { IDD_PW_PW_TEXT, IDD_PW_PW_LABEL, IDD_PW_PASSWORD,
IDD_PW_CONFIRM_LABEL, IDD_PW_CONFIRM };
DWORD GenSection[]= { IDD_PW_FLOPPY, IDD_PW_STORE_LOCAL, IDD_PW_FLOPPY_TEXT,
IDD_PW_LOCAL_TEXT };
typedef WXHASH HASH, *PHASH;
BOOL ObfuscateKey(PHASH H)
{
return(NT_SUCCESS(WxSaveSysKey(sizeof(H->Digest),&H->Digest)));
}
BOOL DeobfuscateKey(PHASH H)
{
ULONG KeyLen = sizeof(H->Digest);
return(NT_SUCCESS(WxReadSysKey(&KeyLen,&H->Digest)));
}
#if MAKE_SAM_CALLS
#define xSamiGetBootKeyInformation SamiGetBootKeyInformation
#define xSamiSetBootKeyInformation SamiSetBootKeyInformation
#else
NTSTATUS
xSamiGetBootKeyInformation(
SAM_HANDLE Domain,
SAMPR_BOOT_TYPE * BootType
)
{
DWORD Type ;
DWORD Length ;
int Result ;
Length = sizeof( SAMPR_BOOT_TYPE );
Result = RegQueryValueEx( LsaKey,
TEXT("SamiSetting"),
0,
&Type,
(PUCHAR) BootType,
&Length );
if ( Result == 0 )
{
NOTHING ;
}
else
{
*BootType = SamBootKeyNone ;
}
return STATUS_SUCCESS ;
}
NTSTATUS
xSamiSetBootKeyInformation(
SAM_HANDLE Domain,
SAMPR_BOOT_TYPE BootType,
PUNICODE_STRING Old,
PUNICODE_STRING New
)
{
DWORD Type ;
DWORD Length ;
HASH Hash ;
int Result ;
Length = 16 ;
Result = RegQueryValueEx( LsaKey,
TEXT("SamiKey"),
0,
&Type,
Hash.Digest,
&Length );
if ( Result == 0 )
{
if (!RtlEqualMemory( Hash.Digest, Old->Buffer, 16 ) )
{
return STATUS_WRONG_PASSWORD ;
}
}
RegSetValueEx( LsaKey,
TEXT("SamiKey"),
0,
REG_BINARY,
(PUCHAR) New->Buffer,
16 );
RegSetValueEx( LsaKey,
TEXT("SamiSetting"),
0,
REG_DWORD,
(PUCHAR) &BootType,
sizeof( DWORD ) );
return STATUS_SUCCESS ;
}
#endif
BOOL
SetupCursor(
BOOL fWait
)
{
BOOL Current ;
if ( hcurArrow == NULL )
{
hcurArrow = LoadCursor( NULL, IDC_ARROW );
}
if ( hcurWait == NULL )
{
hcurWait = LoadCursor( NULL, IDC_WAIT );
}
if ( WaitCursor != fWait )
{
SetCursor( fWait ? hcurWait : hcurArrow );
Current = WaitCursor ;
WaitCursor = fWait ;
}
else
{
Current = fWait ;
}
return Current ;
}
int
MyMessageBox(
HWND hWnd,
int Text,
int Caption,
UINT Flags
)
{
WCHAR String1[ MAX_PATH ];
WCHAR String2[ MAX_PATH ];
int Result ;
BOOL Cursor ;
LoadString( GetModuleHandle(NULL), Caption, String1, MAX_PATH );
LoadString( GetModuleHandle(NULL), Text, String2, MAX_PATH );
Cursor = SetupCursor( FALSE );
Result = MessageBox( hWnd, String2, String1, Flags );
SetupCursor( Cursor );
return Result ;
}
int
DisplayError(
HWND hWnd,
int Description,
int Error
)
{
TCHAR Message[ MAX_PATH ];
TCHAR Caption[ MAX_PATH ];
TCHAR Descr[ MAX_PATH ];
int Result ;
BOOL Cursor ;
FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
Error,
0,
Message,
MAX_PATH,
NULL );
LoadString( GetModuleHandle( NULL ), Description, Caption, MAX_PATH );
wsprintf( Descr, Caption, Message );
LoadString( GetModuleHandle( NULL ), IDS_ERROR_CAPTION, Caption, MAX_PATH );
Cursor = SetupCursor( FALSE );
Result = MessageBox( hWnd, Message, Caption, MB_ICONSTOP | MB_OK );
SetupCursor( Cursor );
return Result ;
}
VOID
DisplayErrorAndExit(
HWND hWnd,
int Description,
int Error
)
{
DisplayError( hWnd, Description, Error );
ExitProcess( Error );
}
VOID
EnableSection(
HWND hDlg,
BOOL Enable,
PDWORD IdList,
DWORD Count
)
{
DWORD i ;
for ( i = 0 ; i < Count ; i++ )
{
EnableWindow( GetDlgItem( hDlg, IdList[ i ]), Enable );
}
}
NTSTATUS
SbLoadKeyFromDisk(
PUCHAR KeyDataBuffer
)
{
HANDLE hFile ;
ULONG Actual ;
ULONG ErrorMode ;
ErrorMode = SetErrorMode( SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX );
SetupCursor( TRUE );
hFile = CreateFileA( "A:\\startkey.key",
GENERIC_READ,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL );
if ( hFile == INVALID_HANDLE_VALUE )
{
SetErrorMode( ErrorMode );
SetupCursor( FALSE );
return STATUS_OBJECT_NAME_NOT_FOUND ;
}
if (!ReadFile( hFile, KeyDataBuffer, 16, &Actual, NULL ) ||
(Actual != 16 ))
{
SetErrorMode( ErrorMode );
CloseHandle( hFile );
SetupCursor( FALSE );
return STATUS_FILE_CORRUPT_ERROR ;
}
SetErrorMode( ErrorMode );
CloseHandle( hFile );
SetupCursor( FALSE );
return STATUS_SUCCESS ;
}
DWORD
SaveKeyToDisk(
HWND hDlg,
PUCHAR Key
)
{
HANDLE hFile ;
ULONG Actual ;
ULONG ErrorMode ;
DWORD Error ;
ErrorMode = SetErrorMode( SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX );
SetupCursor( TRUE );
hFile = CreateFile( KEYFILE,
GENERIC_WRITE,
0,
NULL,
CREATE_NEW,
FILE_ATTRIBUTE_NORMAL,
NULL );
if ( hFile == INVALID_HANDLE_VALUE )
{
Error = GetLastError() ;
if ( Error == ERROR_FILE_EXISTS )
{
//
// This we can handle.
//
(VOID) DeleteFile( KEYFILE_SAVE );
if ( !MoveFile( KEYFILE, KEYFILE_SAVE ) )
{
Error = GetLastError() ;
}
else
{
hFile = CreateFile( KEYFILE,
GENERIC_WRITE,
0,
NULL,
CREATE_NEW,
FILE_ATTRIBUTE_NORMAL,
NULL );
if ( hFile == INVALID_HANDLE_VALUE )
{
Error = GetLastError() ;
}
else
{
MyMessageBox( hDlg, IDS_RENAMED_OLD,
IDS_WARNING_CAPTION,
MB_OK | MB_ICONINFORMATION );
Error = 0 ;
}
}
}
if ( Error )
{
SetErrorMode( ErrorMode );
SetupCursor( FALSE );
return Error ;
}
}
if (!WriteFile( hFile, Key, 16, &Actual, NULL ) ||
(Actual != 16 ))
{
SetErrorMode( ErrorMode );
CloseHandle( hFile );
SetupCursor( FALSE );
return GetLastError() ;
}
SetErrorMode( ErrorMode );
CloseHandle( hFile );
SetupCursor( FALSE );
return 0 ;
}
LRESULT
ValidateDialog(
HWND hDlg,
PSAMPR_BOOT_TYPE Type,
PHASH NewHash
)
{
SAMPR_BOOT_TYPE NewType ;
WCHAR Password[ MAX_PATH ];
WCHAR Confirm[ MAX_PATH ];
PWSTR Scan ;
DWORD PwLen, ConfLen ;
BOOL Match ;
MD5_CTX Md5 ;
if ( IsDlgButtonChecked( hDlg, IDD_PW_PASSWORD_BTN ) == BST_CHECKED )
{
NewType = SamBootKeyPassword ;
}
else if ( IsDlgButtonChecked( hDlg, IDD_PW_FLOPPY ) == BST_CHECKED )
{
NewType = SamBootKeyDisk ;
}
else
{
NewType = SamBootKeyStored ;
}
*Type = NewType ;
switch ( NewType )
{
case SamBootKeyDisk:
case SamBootKeyStored:
STGenerateRandomBits( NewHash->Digest, 16 );
break;
case SamBootKeyPassword:
PwLen = GetDlgItemText( hDlg, IDD_PW_PASSWORD, Password, MAX_PATH );
ConfLen = GetDlgItemText( hDlg, IDD_PW_CONFIRM, Confirm, MAX_PATH );
if ( (PwLen != ConfLen) ||
(wcscmp( Password, Confirm ) ) )
{
Match = FALSE ;
}
else
{
Match = TRUE ;
}
//
// Clear the PW from the dialog:
//
Scan = Confirm ;
while ( *Scan != L'\0' )
{
*Scan++ = ' ';
}
SetDlgItemText( hDlg, IDD_PW_PASSWORD, Confirm );
SetDlgItemText( hDlg, IDD_PW_CONFIRM, Confirm );
SetDlgItemText( hDlg, IDD_PW_PASSWORD, L"" );
SetDlgItemText( hDlg, IDD_PW_CONFIRM, L"" );
if ( !Match )
{
MyMessageBox( hDlg,
IDS_NEW_PW_MATCH,
IDS_ERROR_CAPTION,
MB_OK | MB_ICONSTOP );
SetFocus( GetDlgItem( hDlg, IDD_PW_PASSWORD ) );
return IDCANCEL ;
}
MD5Init( &Md5 );
MD5Update( &Md5, (PUCHAR) Password, PwLen * sizeof( WCHAR ) );
MD5Final( &Md5 );
ZeroMemory( Password, PwLen * sizeof( WCHAR ) );
CopyMemory( NewHash->Digest, Md5.digest, 16 );
break;
}
return IDOK ;
}
LRESULT
CALLBACK
ConfirmPasswordDlg(
HWND hDlg,
UINT Message,
WPARAM wParam,
LPARAM lParam
)
{
WCHAR PW[ 128 ];
MD5_CTX Md5;
int PWLen ;
PUCHAR Hash ;
switch ( Message )
{
case WM_INITDIALOG:
if ( KeyDataPwIcon == NULL )
{
KeyDataPwIcon = LoadImage( GetModuleHandle(NULL),
MAKEINTRESOURCE( IDD_SB_ICON_PW ),
IMAGE_ICON,
64, 72,
LR_DEFAULTCOLOR );
}
SendMessage( GetDlgItem( hDlg, IDD_SB_PW_ICON ),
STM_SETICON,
(WPARAM) KeyDataPwIcon,
0 );
SetWindowLongPtr( hDlg, GWLP_USERDATA, lParam );
return TRUE ;
case WM_COMMAND:
switch ( LOWORD( wParam ) )
{
case IDCANCEL:
EndDialog( hDlg, IDCANCEL );
return TRUE ;
case IDOK:
// Get text
PWLen = GetDlgItemText( hDlg, IDD_SB_PASSWORD, PW, 128 );
// Convert length to bytes
PWLen *= sizeof(WCHAR);
// hash it
MD5Init( &Md5 );
MD5Update( &Md5, (PUCHAR) PW, PWLen );
MD5Final( &Md5 );
// save it
Hash = (PUCHAR) GetWindowLongPtr( hDlg, GWLP_USERDATA );
CopyMemory( Hash, Md5.digest, 16 );
// clean up:
EndDialog( hDlg, IDOK );
FillMemory( PW, PWLen, 0xFF );
ZeroMemory( PW, PWLen );
FillMemory( &Md5, sizeof( Md5 ), 0xFF );
ZeroMemory( &Md5, sizeof( Md5 ) );
return TRUE ;
default:
break;
}
case WM_CLOSE:
break;
}
return FALSE ;
}
LRESULT
CALLBACK
ConfirmDiskDlg(
HWND hDlg,
UINT Message,
WPARAM wParam,
LPARAM lParam
)
{
NTSTATUS Status ;
PUCHAR Hash ;
switch ( Message )
{
case WM_INITDIALOG:
if ( KeyDataDiskIcon == NULL )
{
KeyDataDiskIcon = LoadImage( GetModuleHandle(NULL),
MAKEINTRESOURCE( IDD_SB_ICON_DISK ),
IMAGE_ICON,
64, 72,
LR_DEFAULTCOLOR );
}
SendMessage( GetDlgItem( hDlg, IDD_SB_DISK_ICON ),
STM_SETICON,
(WPARAM) KeyDataDiskIcon,
0 );
SetWindowLongPtr( hDlg, GWLP_USERDATA, lParam );
return TRUE ;
case WM_COMMAND:
switch ( LOWORD( wParam ) )
{
case IDCANCEL:
EndDialog( hDlg, IDCANCEL );
return TRUE ;
case IDOK:
Hash = (PUCHAR) GetWindowLongPtr( hDlg, GWLP_USERDATA );
Status = SbLoadKeyFromDisk( Hash );
if ( !NT_SUCCESS( Status ) )
{
MyMessageBox( hDlg,
IDS_KEYFILE_NOT_FOUND,
IDS_ERROR_CAPTION,
MB_ICONSTOP | MB_OK);
}
else
{
EndDialog( hDlg, IDOK );
}
return TRUE ;
default:
break;
}
case WM_CLOSE:
break;
}
return FALSE ;
}
LRESULT
HandleUpdate(
HWND hDlg
)
{
HASH OldHash ;
HASH NewHash ;
SAMPR_BOOT_TYPE NewType ;
SAMPR_BOOT_TYPE ExtraType ;
LRESULT Result ;
NTSTATUS Status ;
UNICODE_STRING Old ;
UNICODE_STRING New ;
Result = ValidateDialog( hDlg, &NewType, &NewHash );
if ( Result == IDCANCEL )
{
return Result ;
}
switch ( OriginalBootOption )
{
case SamBootKeyNone:
break;
case SamBootKeyStored:
if (!DeobfuscateKey(&OldHash))
{
Result = IDCANCEL ;
}
break;
case SamBootKeyPassword:
Result = DialogBoxParam( GetModuleHandle( NULL ),
MAKEINTRESOURCE( IDD_SECURE_BOOT ),
hDlg,
ConfirmPasswordDlg,
(LPARAM) &OldHash );
if ( Result == IDCANCEL )
{
return Result ;
}
break;
case SamBootKeyDisk:
Result = DialogBoxParam( GetModuleHandle( NULL ),
MAKEINTRESOURCE( IDD_SECURE_BOOT_DISK ),
hDlg,
ConfirmDiskDlg,
(LPARAM) &OldHash );
if ( Result == IDCANCEL )
{
return Result ;
}
break;
}
Old.Buffer = (PWSTR) OldHash.Digest ;
Old.Length = 16 ;
Old.MaximumLength = 16 ;
New.Buffer = (PWSTR) NewHash.Digest ;
New.Length = 16 ;
New.MaximumLength = 16 ;
if ( NewType == SamBootKeyDisk )
{
ExtraType = SamBootKeyDisk ;
NewType = SamBootKeyStored ;
}
else
{
ExtraType = NewType ;
}
Status = xSamiSetBootKeyInformation(
DomainHandle,
NewType,
(OriginalBootOption == SamBootKeyNone ? NULL : &Old),
&New );
if ( !NT_SUCCESS( Status ) )
{
Result = RtlNtStatusToDosError( Status );
DisplayError( hDlg, IDS_SETPASS_FAILED, (int) Result );
return IDCANCEL ;
}
Result = RegSetValueEx( LsaKey,
SYSTEM_KEY,
0,
REG_DWORD,
(PUCHAR) &NewType,
sizeof( NewType ) );
if ( NewType == SamBootKeyStored )
{
ObfuscateKey( &NewHash );
}
MyMessageBox( hDlg, IDS_SETPASS_SUCCESS, IDS_SUCCESS_CAPTION,
MB_OK | MB_ICONINFORMATION );
//
// Switch back to the intended NewType:
//
NewType = ExtraType ;
if ( NewType == SamBootKeyDisk )
{
MyMessageBox( hDlg, IDS_INSERT_FLOPPY, IDS_SAVE_KEY_CAPTION,
MB_OK | MB_ICONQUESTION );
Result = SaveKeyToDisk( hDlg, NewHash.Digest );
while ( Result != 0 )
{
MyMessageBox( hDlg, IDS_SAVE_KEY_FAILED, IDS_SAVE_KEY_CAPTION,
MB_OK | MB_ICONSTOP );
Result = SaveKeyToDisk( hDlg, NewHash.Digest );
}
//
// Once the disk has been written successfully, update SAM and the
// registry with the correct type:
//
Status = xSamiSetBootKeyInformation(
DomainHandle,
NewType,
&New,
&New );
if ( NT_SUCCESS( Status ) )
{
Result = RegSetValueEx( LsaKey,
SYSTEM_KEY,
0,
REG_DWORD,
(PUCHAR) &NewType,
sizeof( NewType ) );
}
MyMessageBox( hDlg, IDS_SAVE_KEY_SUCCESS, IDS_SAVE_KEY_CAPTION,
MB_OK | MB_ICONINFORMATION );
}
//
// Now, if the new type isn't Store-local, write some random stuff in
// there.
//
if ( NewType != SamBootKeyStored )
{
STGenerateRandomBits( NewHash.Digest, 16 );
ObfuscateKey( &NewHash );
}
return IDOK ;
}
LRESULT
CALLBACK
UpdateDlg(
HWND hDlg,
UINT Message,
WPARAM wParam,
LPARAM lParam
)
{
LRESULT Result ;
switch ( Message )
{
case WM_INITDIALOG:
switch ( SecureBootOption )
{
case SamBootKeyPassword:
CheckDlgButton( hDlg, IDD_PW_PASSWORD_BTN, BST_CHECKED );
CheckDlgButton( hDlg, IDD_PW_STORE_LOCAL, BST_CHECKED );
EnableSection( hDlg,
FALSE,
GenSection,
sizeof( GenSection ) /sizeof ( DWORD ) );
SetFocus( GetDlgItem( hDlg, IDD_PW_PASSWORD_BTN ) );
break;
case SamBootKeyStored:
CheckDlgButton( hDlg, IDD_PW_AUTO, BST_CHECKED );
CheckDlgButton( hDlg, IDD_PW_STORE_LOCAL, BST_CHECKED );
EnableSection( hDlg,
FALSE,
PwSection,
sizeof( PwSection ) / sizeof( DWORD ) );
SetFocus( GetDlgItem( hDlg, IDD_PW_STORE_LOCAL ) );
break;
case SamBootKeyDisk:
CheckDlgButton( hDlg, IDD_PW_AUTO, BST_CHECKED );
CheckDlgButton( hDlg, IDD_PW_FLOPPY, BST_CHECKED );
EnableSection( hDlg,
FALSE,
PwSection,
sizeof( PwSection ) / sizeof( DWORD ) );
SetFocus( GetDlgItem( hDlg, IDD_PW_FLOPPY ) );
break;
default:
return FALSE ;
}
return FALSE ;
case WM_COMMAND:
switch ( LOWORD( wParam ) )
{
case IDOK:
Result = HandleUpdate( hDlg );
if ( Result == IDOK )
{
EndDialog( hDlg, IDOK );
}
return TRUE ;
case IDCANCEL:
EndDialog( hDlg, IDCANCEL );
return TRUE ;
case IDD_PW_PASSWORD_BTN:
if ( HIWORD( wParam ) == BN_CLICKED )
{
if ( IsDlgButtonChecked( hDlg, IDD_PW_PASSWORD_BTN )
!= BST_CHECKED )
{
break;
}
EnableSection( hDlg,
TRUE,
PwSection,
sizeof( PwSection ) / sizeof(DWORD) );
EnableSection( hDlg,
FALSE,
GenSection,
sizeof( GenSection ) / sizeof( DWORD ) );
return TRUE ;
}
break;
case IDD_PW_AUTO:
if ( HIWORD( wParam ) == BN_CLICKED )
{
if ( IsDlgButtonChecked( hDlg, IDD_PW_AUTO )
!= BST_CHECKED )
{
break;
}
EnableSection( hDlg,
TRUE,
GenSection,
sizeof( GenSection ) / sizeof( DWORD ) );
EnableSection( hDlg,
FALSE,
PwSection,
sizeof( PwSection ) / sizeof( DWORD ) );
return TRUE ;
}
break;
}
break;
default:
break;
}
return FALSE ;
}
LRESULT
CALLBACK
MainDlg(
HWND hDlg,
UINT Message,
WPARAM wParam,
LPARAM lParam
)
{
LRESULT Result ;
switch ( Message )
{
case WM_INITDIALOG:
if ( hLockIcon == NULL )
{
hLockIcon = LoadImage( GetModuleHandle( NULL ),
MAKEINTRESOURCE( LOCK_ICON ),
IMAGE_ICON,
64, 64,
LR_DEFAULTCOLOR );
}
SendMessage( GetDlgItem( hDlg, IDD_MAIN_ICON ),
STM_SETICON,
(WPARAM) hLockIcon,
0 );
if ( SecureBootOption )
{
EnableWindow( GetDlgItem( hDlg, IDD_MAIN_DISABLED ), FALSE );
CheckDlgButton( hDlg, IDD_MAIN_ENABLED, BST_CHECKED );
}
else
{
EnableWindow( GetDlgItem( hDlg, IDD_MAIN_UPDATE ), FALSE );
CheckDlgButton( hDlg, IDD_MAIN_DISABLED, BST_CHECKED );
}
return TRUE ;
case WM_COMMAND:
switch ( LOWORD( wParam ) )
{
case IDCANCEL:
EndDialog( hDlg, IDOK );
return TRUE ;
case IDOK:
if ( IsDlgButtonChecked( hDlg, IDD_MAIN_DISABLED ) ==
BST_CHECKED )
{
EndDialog( hDlg, IDOK );
return TRUE ;
}
if ( SecureBootOption )
{
EndDialog( hDlg, IDOK );
return TRUE ;
}
//
// Currently disabled, and the user checked enabled, and
// pressed OK. DROP THROUGH to the
// Update case.
//
//
// Set default to Local Store:
//
Result = MyMessageBox( hDlg, IDS_ARE_YOU_SURE,
IDS_ARE_YOU_SURE_CAP,
MB_ICONWARNING | MB_OKCANCEL |
MB_DEFBUTTON2 );
if ( Result == IDCANCEL )
{
return TRUE ;
}
SecureBootOption = SamBootKeyStored ;
case IDD_MAIN_UPDATE:
Result = DialogBox( GetModuleHandle(NULL),
MAKEINTRESOURCE( IDD_PASSWORD_DLG ),
hDlg,
UpdateDlg
);
if ( Result == IDOK )
{
EnableWindow( GetDlgItem( hDlg, IDD_MAIN_DISABLED ), FALSE );
CheckDlgButton( hDlg, IDD_MAIN_ENABLED, BST_CHECKED );
EndDialog( hDlg, IDOK );
}
else
{
SecureBootOption = OriginalBootOption ;
}
return TRUE ;
}
default:
break;
}
return FALSE ;
}
BOOL
UnattendedLocal(
VOID
)
{
HASH OldHash ;
HASH NewHash ;
SAMPR_BOOT_TYPE NewType ;
int Result ;
NTSTATUS Status ;
UNICODE_STRING Old ;
UNICODE_STRING New ;
Result = 0;
if ( OriginalBootOption == SamBootKeyStored )
{
if ( !DeobfuscateKey( &OldHash ) )
{
Result = IDCANCEL ;
}
}
if ( Result == IDCANCEL )
{
return FALSE ;
}
NewType = SamBootKeyStored ;
Old.Buffer = (PWSTR) OldHash.Digest ;
Old.Length = 16 ;
Old.MaximumLength = 16 ;
New.Buffer = (PWSTR) NewHash.Digest ;
New.Length = 16 ;
New.MaximumLength = 16 ;
Status = xSamiSetBootKeyInformation(
DomainHandle,
NewType,
(OriginalBootOption == SamBootKeyNone ? NULL : &Old),
&New );
if ( !NT_SUCCESS( Status ) )
{
Result = RtlNtStatusToDosError( Status );
return FALSE ;
}
Result = RegSetValueEx( LsaKey,
SYSTEM_KEY,
0,
REG_DWORD,
(PUCHAR) &NewType,
sizeof( NewType ) );
ObfuscateKey( &NewHash );
return TRUE ;
}
DWORD
OpenSamAccountDomain(
VOID
)
{
NTSTATUS Status ;
UNICODE_STRING String ;
OBJECT_ATTRIBUTES Obja ;
LSA_HANDLE LsaHandle = NULL;
PPOLICY_ACCOUNT_DOMAIN_INFO DomainInfo = NULL;
CAIROSID DomainSid;
SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
RtlInitUnicodeString( &String, L"" );
InitializeObjectAttributes( &Obja, NULL, 0, NULL, NULL );
Status = SamConnect( &String,
&SamHandle,
MAXIMUM_ALLOWED,
&Obja );
if ( !NT_SUCCESS( Status ) )
{
return RtlNtStatusToDosError( Status );
}
RtlZeroMemory(&Obja, sizeof(OBJECT_ATTRIBUTES));
Status = LsaOpenPolicy(
&String,
&Obja,
POLICY_VIEW_LOCAL_INFORMATION,
&LsaHandle
);
if (!NT_SUCCESS(Status))
{
SamCloseHandle( SamHandle );
return( RtlNtStatusToDosError( Status ) );
}
Status = LsaQueryInformationPolicy(
LsaHandle,
PolicyAccountDomainInformation,
(PVOID *) &DomainInfo
);
if (!NT_SUCCESS(Status))
{
LsaClose( LsaHandle);
SamCloseHandle( SamHandle );
return( RtlNtStatusToDosError( Status ) );
}
RtlCopyMemory(
&DomainSid,
DomainInfo->DomainSid,
RtlLengthSid(DomainInfo->DomainSid)
);
LsaFreeMemory(DomainInfo);
LsaClose( LsaHandle );
Status = SamOpenDomain(
SamHandle,
MAXIMUM_ALLOWED,
(PSID) &DomainSid,
&DomainHandle
);
return RtlNtStatusToDosError( Status );
}
void
__cdecl
wmain (int argc, WCHAR *argv[])
{
HKEY Key ;
int err ;
SAMPR_BOOT_TYPE SystemSetting ;
SAMPR_BOOT_TYPE SamSetting ;
DWORD Type;
DWORD Length ;
NTSTATUS Status ;
WCHAR MsgBuffer[ MAX_PATH ];
STInitializeRNG();
err = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
TEXT("System\\CurrentControlSet\\Control\\Lsa"),
0,
KEY_READ | KEY_WRITE,
& Key );
if ( err )
{
DisplayErrorAndExit( NULL, IDS_SYSTEM_ERROR_OCCURRED, err );
}
LsaKey = Key ;
Length = sizeof( SystemSetting );
err = RegQueryValueEx( Key,
SYSTEM_KEY,
NULL,
&Type,
(PUCHAR) &SystemSetting,
&Length );
if ( err )
{
SystemSetting = SamBootKeyNone ;
}
//
// Now, compare with SAM:
//
err = OpenSamAccountDomain();
if ( err )
{
DisplayErrorAndExit( NULL, IDS_SYSTEM_ERROR_OCCURRED, err );
}
Status = xSamiGetBootKeyInformation( DomainHandle,
&SamSetting );
if ( !NT_SUCCESS( Status ) )
{
DisplayErrorAndExit( NULL,
IDS_SYSTEM_ERROR_OCCURRED,
RtlNtStatusToDosError( Status ) );
}
if ( SamSetting != SystemSetting )
{
SystemSetting = SamSetting ;
err = RegSetValueEx( Key,
SYSTEM_KEY,
0,
REG_DWORD,
(PUCHAR) &SystemSetting,
sizeof( DWORD ) );
MyMessageBox( NULL, IDS_SAM_NOT_SYNC, IDS_WARNING_CAPTION,
MB_ICONHAND | MB_OK );
}
SecureBootOption = SamSetting ;
OriginalBootOption = SamSetting ;
if ( argc > 1 )
{
LoadString( GetModuleHandle( NULL ), IDS_L_OPTION, OptionL, 4 );
LoadString( GetModuleHandle( NULL ), IDS_Q_OPTION, OptionQ, 4 );
//
// Check for unattended:
//
if ( (*argv[1] == L'-') ||
(*argv[1] == L'/') )
{
if ( towupper(argv[1][1]) == OptionL[0] )
{
Unattended = TRUE ;
}
}
}
if ( Unattended )
{
if ( ( OriginalBootOption == SamBootKeyStored ) ||
( OriginalBootOption == SamBootKeyNone ) )
{
UnattendedLocal();
}
else
{
LoadString( GetModuleHandle( NULL ), IDS_NO_UNATTENDED,
MsgBuffer, MAX_PATH );
fprintf( stderr, "%ws\n", MsgBuffer );
}
}
else
{
DialogBox( GetModuleHandle(NULL),
MAKEINTRESOURCE( IDD_MAIN_DIALOG ),
NULL,
MainDlg );
}
RegCloseKey( LsaKey );
}