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.

1409 lines
34 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1997.
  5. //
  6. // File: samlock.c
  7. //
  8. // Contents:
  9. //
  10. // Classes:
  11. //
  12. // Functions:
  13. //
  14. // History: 4-19-97 RichardW Created
  15. //
  16. //----------------------------------------------------------------------------
  17. #include "samlock.h"
  18. #include <stdio.h>
  19. #include <wchar.h>
  20. #if DBG
  21. #define HIDDEN
  22. #else
  23. #define HIDDEN static
  24. #endif
  25. #define MAKE_SAM_CALLS 1
  26. #if MAKE_SAM_CALLS
  27. #define SYSTEM_KEY TEXT("SecureBoot")
  28. #else
  29. #define SYSTEM_KEY TEXT("BootType")
  30. #endif
  31. #define KEYFILE TEXT("A:\\StartKey.Key")
  32. #define KEYFILE_SAVE TEXT("A:\\StartKey.Bak")
  33. HICON hLockIcon ;
  34. HICON KeyDataPwIcon ;
  35. HICON KeyDataDiskIcon ;
  36. SAMPR_BOOT_TYPE SecureBootOption = 0;
  37. SAMPR_BOOT_TYPE OriginalBootOption = 0 ;
  38. SAM_HANDLE SamHandle ;
  39. SAM_HANDLE DomainHandle ;
  40. HKEY LsaKey ;
  41. HCURSOR hcurArrow ;
  42. HCURSOR hcurWait ;
  43. BOOL WaitCursor ;
  44. WCHAR OptionL[ 4 ]; // Unattended, local store
  45. WCHAR OptionQ[ 4 ]; // Question (usage)
  46. BOOL Unattended = FALSE ;
  47. DWORD PwSection[] = { IDD_PW_PW_TEXT, IDD_PW_PW_LABEL, IDD_PW_PASSWORD,
  48. IDD_PW_CONFIRM_LABEL, IDD_PW_CONFIRM };
  49. DWORD GenSection[]= { IDD_PW_FLOPPY, IDD_PW_STORE_LOCAL, IDD_PW_FLOPPY_TEXT,
  50. IDD_PW_LOCAL_TEXT };
  51. typedef WXHASH HASH, *PHASH;
  52. BOOL ObfuscateKey(PHASH H)
  53. {
  54. return(NT_SUCCESS(WxSaveSysKey(sizeof(H->Digest),&H->Digest)));
  55. }
  56. BOOL DeobfuscateKey(PHASH H)
  57. {
  58. ULONG KeyLen = sizeof(H->Digest);
  59. return(NT_SUCCESS(WxReadSysKey(&KeyLen,&H->Digest)));
  60. }
  61. #if MAKE_SAM_CALLS
  62. #define xSamiGetBootKeyInformation SamiGetBootKeyInformation
  63. #define xSamiSetBootKeyInformation SamiSetBootKeyInformation
  64. #else
  65. NTSTATUS
  66. xSamiGetBootKeyInformation(
  67. SAM_HANDLE Domain,
  68. SAMPR_BOOT_TYPE * BootType
  69. )
  70. {
  71. DWORD Type ;
  72. DWORD Length ;
  73. int Result ;
  74. Length = sizeof( SAMPR_BOOT_TYPE );
  75. Result = RegQueryValueEx( LsaKey,
  76. TEXT("SamiSetting"),
  77. 0,
  78. &Type,
  79. (PUCHAR) BootType,
  80. &Length );
  81. if ( Result == 0 )
  82. {
  83. NOTHING ;
  84. }
  85. else
  86. {
  87. *BootType = SamBootKeyNone ;
  88. }
  89. return STATUS_SUCCESS ;
  90. }
  91. NTSTATUS
  92. xSamiSetBootKeyInformation(
  93. SAM_HANDLE Domain,
  94. SAMPR_BOOT_TYPE BootType,
  95. PUNICODE_STRING Old,
  96. PUNICODE_STRING New
  97. )
  98. {
  99. DWORD Type ;
  100. DWORD Length ;
  101. HASH Hash ;
  102. int Result ;
  103. Length = 16 ;
  104. Result = RegQueryValueEx( LsaKey,
  105. TEXT("SamiKey"),
  106. 0,
  107. &Type,
  108. Hash.Digest,
  109. &Length );
  110. if ( Result == 0 )
  111. {
  112. if (!RtlEqualMemory( Hash.Digest, Old->Buffer, 16 ) )
  113. {
  114. return STATUS_WRONG_PASSWORD ;
  115. }
  116. }
  117. RegSetValueEx( LsaKey,
  118. TEXT("SamiKey"),
  119. 0,
  120. REG_BINARY,
  121. (PUCHAR) New->Buffer,
  122. 16 );
  123. RegSetValueEx( LsaKey,
  124. TEXT("SamiSetting"),
  125. 0,
  126. REG_DWORD,
  127. (PUCHAR) &BootType,
  128. sizeof( DWORD ) );
  129. return STATUS_SUCCESS ;
  130. }
  131. #endif
  132. BOOL
  133. SetupCursor(
  134. BOOL fWait
  135. )
  136. {
  137. BOOL Current ;
  138. if ( hcurArrow == NULL )
  139. {
  140. hcurArrow = LoadCursor( NULL, IDC_ARROW );
  141. }
  142. if ( hcurWait == NULL )
  143. {
  144. hcurWait = LoadCursor( NULL, IDC_WAIT );
  145. }
  146. if ( WaitCursor != fWait )
  147. {
  148. SetCursor( fWait ? hcurWait : hcurArrow );
  149. Current = WaitCursor ;
  150. WaitCursor = fWait ;
  151. }
  152. else
  153. {
  154. Current = fWait ;
  155. }
  156. return Current ;
  157. }
  158. int
  159. MyMessageBox(
  160. HWND hWnd,
  161. int Text,
  162. int Caption,
  163. UINT Flags
  164. )
  165. {
  166. WCHAR String1[ MAX_PATH ];
  167. WCHAR String2[ MAX_PATH ];
  168. int Result ;
  169. BOOL Cursor ;
  170. LoadString( GetModuleHandle(NULL), Caption, String1, MAX_PATH );
  171. LoadString( GetModuleHandle(NULL), Text, String2, MAX_PATH );
  172. Cursor = SetupCursor( FALSE );
  173. Result = MessageBox( hWnd, String2, String1, Flags );
  174. SetupCursor( Cursor );
  175. return Result ;
  176. }
  177. int
  178. DisplayError(
  179. HWND hWnd,
  180. int Description,
  181. int Error
  182. )
  183. {
  184. TCHAR Message[ MAX_PATH ];
  185. TCHAR Caption[ MAX_PATH ];
  186. TCHAR Descr[ MAX_PATH ];
  187. int Result ;
  188. BOOL Cursor ;
  189. FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM,
  190. NULL,
  191. Error,
  192. 0,
  193. Message,
  194. MAX_PATH,
  195. NULL );
  196. LoadString( GetModuleHandle( NULL ), Description, Caption, MAX_PATH );
  197. wsprintf( Descr, Caption, Message );
  198. LoadString( GetModuleHandle( NULL ), IDS_ERROR_CAPTION, Caption, MAX_PATH );
  199. Cursor = SetupCursor( FALSE );
  200. Result = MessageBox( hWnd, Message, Caption, MB_ICONSTOP | MB_OK );
  201. SetupCursor( Cursor );
  202. return Result ;
  203. }
  204. VOID
  205. DisplayErrorAndExit(
  206. HWND hWnd,
  207. int Description,
  208. int Error
  209. )
  210. {
  211. DisplayError( hWnd, Description, Error );
  212. ExitProcess( Error );
  213. }
  214. VOID
  215. EnableSection(
  216. HWND hDlg,
  217. BOOL Enable,
  218. PDWORD IdList,
  219. DWORD Count
  220. )
  221. {
  222. DWORD i ;
  223. for ( i = 0 ; i < Count ; i++ )
  224. {
  225. EnableWindow( GetDlgItem( hDlg, IdList[ i ]), Enable );
  226. }
  227. }
  228. NTSTATUS
  229. SbLoadKeyFromDisk(
  230. PUCHAR KeyDataBuffer
  231. )
  232. {
  233. HANDLE hFile ;
  234. ULONG Actual ;
  235. ULONG ErrorMode ;
  236. ErrorMode = SetErrorMode( SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX );
  237. SetupCursor( TRUE );
  238. hFile = CreateFileA( "A:\\startkey.key",
  239. GENERIC_READ,
  240. 0,
  241. NULL,
  242. OPEN_EXISTING,
  243. FILE_ATTRIBUTE_NORMAL,
  244. NULL );
  245. if ( hFile == INVALID_HANDLE_VALUE )
  246. {
  247. SetErrorMode( ErrorMode );
  248. SetupCursor( FALSE );
  249. return STATUS_OBJECT_NAME_NOT_FOUND ;
  250. }
  251. if (!ReadFile( hFile, KeyDataBuffer, 16, &Actual, NULL ) ||
  252. (Actual != 16 ))
  253. {
  254. SetErrorMode( ErrorMode );
  255. CloseHandle( hFile );
  256. SetupCursor( FALSE );
  257. return STATUS_FILE_CORRUPT_ERROR ;
  258. }
  259. SetErrorMode( ErrorMode );
  260. CloseHandle( hFile );
  261. SetupCursor( FALSE );
  262. return STATUS_SUCCESS ;
  263. }
  264. DWORD
  265. SaveKeyToDisk(
  266. HWND hDlg,
  267. PUCHAR Key
  268. )
  269. {
  270. HANDLE hFile ;
  271. ULONG Actual ;
  272. ULONG ErrorMode ;
  273. DWORD Error ;
  274. ErrorMode = SetErrorMode( SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX );
  275. SetupCursor( TRUE );
  276. hFile = CreateFile( KEYFILE,
  277. GENERIC_WRITE,
  278. 0,
  279. NULL,
  280. CREATE_NEW,
  281. FILE_ATTRIBUTE_NORMAL,
  282. NULL );
  283. if ( hFile == INVALID_HANDLE_VALUE )
  284. {
  285. Error = GetLastError() ;
  286. if ( Error == ERROR_FILE_EXISTS )
  287. {
  288. //
  289. // This we can handle.
  290. //
  291. (VOID) DeleteFile( KEYFILE_SAVE );
  292. if ( !MoveFile( KEYFILE, KEYFILE_SAVE ) )
  293. {
  294. Error = GetLastError() ;
  295. }
  296. else
  297. {
  298. hFile = CreateFile( KEYFILE,
  299. GENERIC_WRITE,
  300. 0,
  301. NULL,
  302. CREATE_NEW,
  303. FILE_ATTRIBUTE_NORMAL,
  304. NULL );
  305. if ( hFile == INVALID_HANDLE_VALUE )
  306. {
  307. Error = GetLastError() ;
  308. }
  309. else
  310. {
  311. MyMessageBox( hDlg, IDS_RENAMED_OLD,
  312. IDS_WARNING_CAPTION,
  313. MB_OK | MB_ICONINFORMATION );
  314. Error = 0 ;
  315. }
  316. }
  317. }
  318. if ( Error )
  319. {
  320. SetErrorMode( ErrorMode );
  321. SetupCursor( FALSE );
  322. return Error ;
  323. }
  324. }
  325. if (!WriteFile( hFile, Key, 16, &Actual, NULL ) ||
  326. (Actual != 16 ))
  327. {
  328. SetErrorMode( ErrorMode );
  329. CloseHandle( hFile );
  330. SetupCursor( FALSE );
  331. return GetLastError() ;
  332. }
  333. SetErrorMode( ErrorMode );
  334. CloseHandle( hFile );
  335. SetupCursor( FALSE );
  336. return 0 ;
  337. }
  338. LRESULT
  339. ValidateDialog(
  340. HWND hDlg,
  341. PSAMPR_BOOT_TYPE Type,
  342. PHASH NewHash
  343. )
  344. {
  345. SAMPR_BOOT_TYPE NewType ;
  346. WCHAR Password[ MAX_PATH ];
  347. WCHAR Confirm[ MAX_PATH ];
  348. PWSTR Scan ;
  349. DWORD PwLen, ConfLen ;
  350. BOOL Match ;
  351. MD5_CTX Md5 ;
  352. if ( IsDlgButtonChecked( hDlg, IDD_PW_PASSWORD_BTN ) == BST_CHECKED )
  353. {
  354. NewType = SamBootKeyPassword ;
  355. }
  356. else if ( IsDlgButtonChecked( hDlg, IDD_PW_FLOPPY ) == BST_CHECKED )
  357. {
  358. NewType = SamBootKeyDisk ;
  359. }
  360. else
  361. {
  362. NewType = SamBootKeyStored ;
  363. }
  364. *Type = NewType ;
  365. switch ( NewType )
  366. {
  367. case SamBootKeyDisk:
  368. case SamBootKeyStored:
  369. if (!RtlGenRandom( NewHash->Digest, 16 ))
  370. {
  371. DisplayError( hDlg, IDS_SETPASS_FAILED, ERROR_NOT_ENOUGH_MEMORY);
  372. return IDCANCEL ;
  373. }
  374. break;
  375. case SamBootKeyPassword:
  376. PwLen = GetDlgItemText( hDlg, IDD_PW_PASSWORD, Password, MAX_PATH );
  377. ConfLen = GetDlgItemText( hDlg, IDD_PW_CONFIRM, Confirm, MAX_PATH );
  378. if ( (PwLen != ConfLen) ||
  379. (wcscmp( Password, Confirm ) ) )
  380. {
  381. Match = FALSE ;
  382. }
  383. else
  384. {
  385. Match = TRUE ;
  386. }
  387. //
  388. // Clear the PW from the dialog:
  389. //
  390. Scan = Confirm ;
  391. while ( *Scan != L'\0' )
  392. {
  393. *Scan++ = ' ';
  394. }
  395. SetDlgItemText( hDlg, IDD_PW_PASSWORD, Confirm );
  396. SetDlgItemText( hDlg, IDD_PW_CONFIRM, Confirm );
  397. SetDlgItemText( hDlg, IDD_PW_PASSWORD, L"" );
  398. SetDlgItemText( hDlg, IDD_PW_CONFIRM, L"" );
  399. SecureZeroMemory( Confirm, ConfLen * sizeof( WCHAR ) );
  400. if ( !Match )
  401. {
  402. MyMessageBox( hDlg,
  403. IDS_NEW_PW_MATCH,
  404. IDS_ERROR_CAPTION,
  405. MB_OK | MB_ICONSTOP );
  406. SetFocus( GetDlgItem( hDlg, IDD_PW_PASSWORD ) );
  407. SecureZeroMemory( Password, PwLen * sizeof( WCHAR ) );
  408. return IDCANCEL ;
  409. }
  410. MD5Init( &Md5 );
  411. MD5Update( &Md5, (PUCHAR) Password, PwLen * sizeof( WCHAR ) );
  412. MD5Final( &Md5 );
  413. SecureZeroMemory( Password, PwLen * sizeof( WCHAR ) );
  414. CopyMemory( NewHash->Digest, Md5.digest, 16 );
  415. break;
  416. }
  417. return IDOK ;
  418. }
  419. LRESULT
  420. CALLBACK
  421. ConfirmPasswordDlg(
  422. HWND hDlg,
  423. UINT Message,
  424. WPARAM wParam,
  425. LPARAM lParam
  426. )
  427. {
  428. WCHAR PW[ MAX_PATH ];
  429. MD5_CTX Md5;
  430. int PWLen ;
  431. PUCHAR Hash ;
  432. switch ( Message )
  433. {
  434. case WM_INITDIALOG:
  435. if ( KeyDataPwIcon == NULL )
  436. {
  437. KeyDataPwIcon = LoadImage( GetModuleHandle(NULL),
  438. MAKEINTRESOURCE( IDD_SB_ICON_PW ),
  439. IMAGE_ICON,
  440. 64, 72,
  441. LR_DEFAULTCOLOR );
  442. }
  443. SendMessage( GetDlgItem( hDlg, IDD_SB_PW_ICON ),
  444. STM_SETICON,
  445. (WPARAM) KeyDataPwIcon,
  446. 0 );
  447. SetWindowLongPtr( hDlg, GWLP_USERDATA, lParam );
  448. return TRUE ;
  449. case WM_COMMAND:
  450. switch ( LOWORD( wParam ) )
  451. {
  452. case IDCANCEL:
  453. EndDialog( hDlg, IDCANCEL );
  454. return TRUE ;
  455. case IDOK:
  456. // Get text
  457. PWLen = GetDlgItemText( hDlg, IDD_SB_PASSWORD, PW, RTL_NUMBER_OF(PW) );
  458. // Convert length to bytes
  459. PWLen *= sizeof(WCHAR);
  460. // hash it
  461. MD5Init( &Md5 );
  462. MD5Update( &Md5, (PUCHAR) PW, PWLen );
  463. MD5Final( &Md5 );
  464. // save it
  465. Hash = (PUCHAR) GetWindowLongPtr( hDlg, GWLP_USERDATA );
  466. CopyMemory( Hash, Md5.digest, 16 );
  467. // clean up:
  468. EndDialog( hDlg, IDOK );
  469. RtlSecureZeroMemory( PW, PWLen );
  470. RtlSecureZeroMemory( &Md5, sizeof(Md5) );
  471. return TRUE ;
  472. default:
  473. break;
  474. }
  475. case WM_CLOSE:
  476. break;
  477. }
  478. return FALSE ;
  479. }
  480. LRESULT
  481. CALLBACK
  482. ConfirmDiskDlg(
  483. HWND hDlg,
  484. UINT Message,
  485. WPARAM wParam,
  486. LPARAM lParam
  487. )
  488. {
  489. NTSTATUS Status ;
  490. PUCHAR Hash ;
  491. switch ( Message )
  492. {
  493. case WM_INITDIALOG:
  494. if ( KeyDataDiskIcon == NULL )
  495. {
  496. KeyDataDiskIcon = LoadImage( GetModuleHandle(NULL),
  497. MAKEINTRESOURCE( IDD_SB_ICON_DISK ),
  498. IMAGE_ICON,
  499. 64, 72,
  500. LR_DEFAULTCOLOR );
  501. }
  502. SendMessage( GetDlgItem( hDlg, IDD_SB_DISK_ICON ),
  503. STM_SETICON,
  504. (WPARAM) KeyDataDiskIcon,
  505. 0 );
  506. SetWindowLongPtr( hDlg, GWLP_USERDATA, lParam );
  507. return TRUE ;
  508. case WM_COMMAND:
  509. switch ( LOWORD( wParam ) )
  510. {
  511. case IDCANCEL:
  512. EndDialog( hDlg, IDCANCEL );
  513. return TRUE ;
  514. case IDOK:
  515. Hash = (PUCHAR) GetWindowLongPtr( hDlg, GWLP_USERDATA );
  516. Status = SbLoadKeyFromDisk( Hash );
  517. if ( !NT_SUCCESS( Status ) )
  518. {
  519. MyMessageBox( hDlg,
  520. IDS_KEYFILE_NOT_FOUND,
  521. IDS_ERROR_CAPTION,
  522. MB_ICONSTOP | MB_OK);
  523. }
  524. else
  525. {
  526. EndDialog( hDlg, IDOK );
  527. }
  528. return TRUE ;
  529. default:
  530. break;
  531. }
  532. case WM_CLOSE:
  533. break;
  534. }
  535. return FALSE ;
  536. }
  537. LRESULT
  538. HandleUpdate(
  539. HWND hDlg
  540. )
  541. {
  542. HASH OldHash ;
  543. HASH NewHash ;
  544. SAMPR_BOOT_TYPE NewType ;
  545. SAMPR_BOOT_TYPE ExtraType ;
  546. LRESULT Result ;
  547. NTSTATUS Status ;
  548. UNICODE_STRING Old ;
  549. UNICODE_STRING New ;
  550. Result = ValidateDialog( hDlg, &NewType, &NewHash );
  551. if ( Result == IDCANCEL )
  552. {
  553. return Result ;
  554. }
  555. switch ( OriginalBootOption )
  556. {
  557. case SamBootKeyNone:
  558. break;
  559. case SamBootKeyStored:
  560. if (!DeobfuscateKey(&OldHash))
  561. {
  562. Result = IDCANCEL ;
  563. }
  564. break;
  565. case SamBootKeyPassword:
  566. Result = DialogBoxParam( GetModuleHandle( NULL ),
  567. MAKEINTRESOURCE( IDD_SECURE_BOOT ),
  568. hDlg,
  569. ConfirmPasswordDlg,
  570. (LPARAM) &OldHash );
  571. if ( Result == IDCANCEL )
  572. {
  573. return Result ;
  574. }
  575. break;
  576. case SamBootKeyDisk:
  577. Result = DialogBoxParam( GetModuleHandle( NULL ),
  578. MAKEINTRESOURCE( IDD_SECURE_BOOT_DISK ),
  579. hDlg,
  580. ConfirmDiskDlg,
  581. (LPARAM) &OldHash );
  582. if ( Result == IDCANCEL )
  583. {
  584. return Result ;
  585. }
  586. break;
  587. }
  588. Old.Buffer = (PWSTR) OldHash.Digest ;
  589. Old.Length = 16 ;
  590. Old.MaximumLength = 16 ;
  591. New.Buffer = (PWSTR) NewHash.Digest ;
  592. New.Length = 16 ;
  593. New.MaximumLength = 16 ;
  594. if ( NewType == SamBootKeyDisk )
  595. {
  596. ExtraType = SamBootKeyDisk ;
  597. NewType = SamBootKeyStored ;
  598. }
  599. else
  600. {
  601. ExtraType = NewType ;
  602. }
  603. Status = xSamiSetBootKeyInformation(
  604. DomainHandle,
  605. NewType,
  606. (OriginalBootOption == SamBootKeyNone ? NULL : &Old),
  607. &New );
  608. if ( !NT_SUCCESS( Status ) )
  609. {
  610. Result = RtlNtStatusToDosError( Status );
  611. DisplayError( hDlg, IDS_SETPASS_FAILED, (int) Result );
  612. return IDCANCEL ;
  613. }
  614. Result = RegSetValueEx( LsaKey,
  615. SYSTEM_KEY,
  616. 0,
  617. REG_DWORD,
  618. (PUCHAR) &NewType,
  619. sizeof( NewType ) );
  620. if ( NewType == SamBootKeyStored )
  621. {
  622. ObfuscateKey( &NewHash );
  623. }
  624. MyMessageBox( hDlg, IDS_SETPASS_SUCCESS, IDS_SUCCESS_CAPTION,
  625. MB_OK | MB_ICONINFORMATION );
  626. //
  627. // Switch back to the intended NewType:
  628. //
  629. NewType = ExtraType ;
  630. if ( NewType == SamBootKeyDisk )
  631. {
  632. MyMessageBox( hDlg, IDS_INSERT_FLOPPY, IDS_SAVE_KEY_CAPTION,
  633. MB_OK | MB_ICONQUESTION );
  634. Result = SaveKeyToDisk( hDlg, NewHash.Digest );
  635. while ( Result != 0 )
  636. {
  637. MyMessageBox( hDlg, IDS_SAVE_KEY_FAILED, IDS_SAVE_KEY_CAPTION,
  638. MB_OK | MB_ICONSTOP );
  639. Result = SaveKeyToDisk( hDlg, NewHash.Digest );
  640. }
  641. //
  642. // Once the disk has been written successfully, update SAM and the
  643. // registry with the correct type:
  644. //
  645. Status = xSamiSetBootKeyInformation(
  646. DomainHandle,
  647. NewType,
  648. &New,
  649. &New );
  650. if ( NT_SUCCESS( Status ) )
  651. {
  652. Result = RegSetValueEx( LsaKey,
  653. SYSTEM_KEY,
  654. 0,
  655. REG_DWORD,
  656. (PUCHAR) &NewType,
  657. sizeof( NewType ) );
  658. }
  659. MyMessageBox( hDlg, IDS_SAVE_KEY_SUCCESS, IDS_SAVE_KEY_CAPTION,
  660. MB_OK | MB_ICONINFORMATION );
  661. }
  662. //
  663. // Now, if the new type isn't Store-local, write some random stuff in
  664. // there.
  665. //
  666. if ( NewType != SamBootKeyStored )
  667. {
  668. // no need to check error return since in this case the key is never used
  669. RtlGenRandom( NewHash.Digest, 16 );
  670. ObfuscateKey( &NewHash );
  671. }
  672. return IDOK ;
  673. }
  674. LRESULT
  675. CALLBACK
  676. UpdateDlg(
  677. HWND hDlg,
  678. UINT Message,
  679. WPARAM wParam,
  680. LPARAM lParam
  681. )
  682. {
  683. LRESULT Result ;
  684. switch ( Message )
  685. {
  686. case WM_INITDIALOG:
  687. switch ( SecureBootOption )
  688. {
  689. case SamBootKeyPassword:
  690. CheckDlgButton( hDlg, IDD_PW_PASSWORD_BTN, BST_CHECKED );
  691. CheckDlgButton( hDlg, IDD_PW_STORE_LOCAL, BST_CHECKED );
  692. EnableSection( hDlg,
  693. FALSE,
  694. GenSection,
  695. sizeof( GenSection ) /sizeof ( DWORD ) );
  696. SetFocus( GetDlgItem( hDlg, IDD_PW_PASSWORD_BTN ) );
  697. break;
  698. case SamBootKeyStored:
  699. CheckDlgButton( hDlg, IDD_PW_AUTO, BST_CHECKED );
  700. CheckDlgButton( hDlg, IDD_PW_STORE_LOCAL, BST_CHECKED );
  701. EnableSection( hDlg,
  702. FALSE,
  703. PwSection,
  704. sizeof( PwSection ) / sizeof( DWORD ) );
  705. SetFocus( GetDlgItem( hDlg, IDD_PW_STORE_LOCAL ) );
  706. break;
  707. case SamBootKeyDisk:
  708. CheckDlgButton( hDlg, IDD_PW_AUTO, BST_CHECKED );
  709. CheckDlgButton( hDlg, IDD_PW_FLOPPY, BST_CHECKED );
  710. EnableSection( hDlg,
  711. FALSE,
  712. PwSection,
  713. sizeof( PwSection ) / sizeof( DWORD ) );
  714. SetFocus( GetDlgItem( hDlg, IDD_PW_FLOPPY ) );
  715. break;
  716. default:
  717. return FALSE ;
  718. }
  719. return FALSE ;
  720. case WM_COMMAND:
  721. switch ( LOWORD( wParam ) )
  722. {
  723. case IDOK:
  724. Result = HandleUpdate( hDlg );
  725. if ( Result == IDOK )
  726. {
  727. EndDialog( hDlg, IDOK );
  728. }
  729. return TRUE ;
  730. case IDCANCEL:
  731. EndDialog( hDlg, IDCANCEL );
  732. return TRUE ;
  733. case IDD_PW_PASSWORD_BTN:
  734. if ( HIWORD( wParam ) == BN_CLICKED )
  735. {
  736. if ( IsDlgButtonChecked( hDlg, IDD_PW_PASSWORD_BTN )
  737. != BST_CHECKED )
  738. {
  739. break;
  740. }
  741. EnableSection( hDlg,
  742. TRUE,
  743. PwSection,
  744. sizeof( PwSection ) / sizeof(DWORD) );
  745. EnableSection( hDlg,
  746. FALSE,
  747. GenSection,
  748. sizeof( GenSection ) / sizeof( DWORD ) );
  749. return TRUE ;
  750. }
  751. break;
  752. case IDD_PW_AUTO:
  753. if ( HIWORD( wParam ) == BN_CLICKED )
  754. {
  755. if ( IsDlgButtonChecked( hDlg, IDD_PW_AUTO )
  756. != BST_CHECKED )
  757. {
  758. break;
  759. }
  760. EnableSection( hDlg,
  761. TRUE,
  762. GenSection,
  763. sizeof( GenSection ) / sizeof( DWORD ) );
  764. EnableSection( hDlg,
  765. FALSE,
  766. PwSection,
  767. sizeof( PwSection ) / sizeof( DWORD ) );
  768. return TRUE ;
  769. }
  770. break;
  771. }
  772. break;
  773. default:
  774. break;
  775. }
  776. return FALSE ;
  777. }
  778. LRESULT
  779. CALLBACK
  780. MainDlg(
  781. HWND hDlg,
  782. UINT Message,
  783. WPARAM wParam,
  784. LPARAM lParam
  785. )
  786. {
  787. LRESULT Result ;
  788. switch ( Message )
  789. {
  790. case WM_INITDIALOG:
  791. if ( hLockIcon == NULL )
  792. {
  793. hLockIcon = LoadImage( GetModuleHandle( NULL ),
  794. MAKEINTRESOURCE( LOCK_ICON ),
  795. IMAGE_ICON,
  796. 64, 64,
  797. LR_DEFAULTCOLOR );
  798. }
  799. SendMessage( GetDlgItem( hDlg, IDD_MAIN_ICON ),
  800. STM_SETICON,
  801. (WPARAM) hLockIcon,
  802. 0 );
  803. if ( SecureBootOption )
  804. {
  805. EnableWindow( GetDlgItem( hDlg, IDD_MAIN_DISABLED ), FALSE );
  806. CheckDlgButton( hDlg, IDD_MAIN_ENABLED, BST_CHECKED );
  807. }
  808. else
  809. {
  810. EnableWindow( GetDlgItem( hDlg, IDD_MAIN_UPDATE ), FALSE );
  811. CheckDlgButton( hDlg, IDD_MAIN_DISABLED, BST_CHECKED );
  812. }
  813. return TRUE ;
  814. case WM_COMMAND:
  815. switch ( LOWORD( wParam ) )
  816. {
  817. case IDCANCEL:
  818. EndDialog( hDlg, IDOK );
  819. return TRUE ;
  820. case IDOK:
  821. if ( IsDlgButtonChecked( hDlg, IDD_MAIN_DISABLED ) ==
  822. BST_CHECKED )
  823. {
  824. EndDialog( hDlg, IDOK );
  825. return TRUE ;
  826. }
  827. if ( SecureBootOption )
  828. {
  829. EndDialog( hDlg, IDOK );
  830. return TRUE ;
  831. }
  832. //
  833. // Currently disabled, and the user checked enabled, and
  834. // pressed OK. DROP THROUGH to the
  835. // Update case.
  836. //
  837. //
  838. // Set default to Local Store:
  839. //
  840. Result = MyMessageBox( hDlg, IDS_ARE_YOU_SURE,
  841. IDS_ARE_YOU_SURE_CAP,
  842. MB_ICONWARNING | MB_OKCANCEL |
  843. MB_DEFBUTTON2 );
  844. if ( Result == IDCANCEL )
  845. {
  846. return TRUE ;
  847. }
  848. SecureBootOption = SamBootKeyStored ;
  849. case IDD_MAIN_UPDATE:
  850. Result = DialogBox( GetModuleHandle(NULL),
  851. MAKEINTRESOURCE( IDD_PASSWORD_DLG ),
  852. hDlg,
  853. UpdateDlg
  854. );
  855. if ( Result == IDOK )
  856. {
  857. EnableWindow( GetDlgItem( hDlg, IDD_MAIN_DISABLED ), FALSE );
  858. CheckDlgButton( hDlg, IDD_MAIN_ENABLED, BST_CHECKED );
  859. EndDialog( hDlg, IDOK );
  860. }
  861. else
  862. {
  863. SecureBootOption = OriginalBootOption ;
  864. }
  865. return TRUE ;
  866. }
  867. default:
  868. break;
  869. }
  870. return FALSE ;
  871. }
  872. BOOL
  873. UnattendedLocal(
  874. VOID
  875. )
  876. {
  877. HASH OldHash ;
  878. HASH NewHash ;
  879. SAMPR_BOOT_TYPE NewType ;
  880. int Result ;
  881. NTSTATUS Status ;
  882. UNICODE_STRING Old ;
  883. UNICODE_STRING New ;
  884. Result = 0;
  885. if ( OriginalBootOption == SamBootKeyStored )
  886. {
  887. if ( !DeobfuscateKey( &OldHash ) )
  888. {
  889. Result = IDCANCEL ;
  890. }
  891. }
  892. if ( Result == IDCANCEL )
  893. {
  894. return FALSE ;
  895. }
  896. NewType = SamBootKeyStored ;
  897. Old.Buffer = (PWSTR) OldHash.Digest ;
  898. Old.Length = 16 ;
  899. Old.MaximumLength = 16 ;
  900. New.Buffer = (PWSTR) NewHash.Digest ;
  901. New.Length = 16 ;
  902. New.MaximumLength = 16 ;
  903. Status = xSamiSetBootKeyInformation(
  904. DomainHandle,
  905. NewType,
  906. (OriginalBootOption == SamBootKeyNone ? NULL : &Old),
  907. &New );
  908. if ( !NT_SUCCESS( Status ) )
  909. {
  910. Result = RtlNtStatusToDosError( Status );
  911. return FALSE ;
  912. }
  913. Result = RegSetValueEx( LsaKey,
  914. SYSTEM_KEY,
  915. 0,
  916. REG_DWORD,
  917. (PUCHAR) &NewType,
  918. sizeof( NewType ) );
  919. ObfuscateKey( &NewHash );
  920. return TRUE ;
  921. }
  922. DWORD
  923. OpenSamAccountDomain(
  924. VOID
  925. )
  926. {
  927. NTSTATUS Status ;
  928. UNICODE_STRING String ;
  929. OBJECT_ATTRIBUTES Obja ;
  930. LSA_HANDLE LsaHandle = NULL;
  931. PPOLICY_ACCOUNT_DOMAIN_INFO DomainInfo = NULL;
  932. CAIROSID DomainSid;
  933. SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
  934. RtlInitUnicodeString( &String, L"" );
  935. InitializeObjectAttributes( &Obja, NULL, 0, NULL, NULL );
  936. Status = SamConnect( &String,
  937. &SamHandle,
  938. MAXIMUM_ALLOWED,
  939. &Obja );
  940. if ( !NT_SUCCESS( Status ) )
  941. {
  942. return RtlNtStatusToDosError( Status );
  943. }
  944. RtlZeroMemory(&Obja, sizeof(OBJECT_ATTRIBUTES));
  945. Status = LsaOpenPolicy(
  946. &String,
  947. &Obja,
  948. POLICY_VIEW_LOCAL_INFORMATION,
  949. &LsaHandle
  950. );
  951. if (!NT_SUCCESS(Status))
  952. {
  953. SamCloseHandle( SamHandle );
  954. return( RtlNtStatusToDosError( Status ) );
  955. }
  956. Status = LsaQueryInformationPolicy(
  957. LsaHandle,
  958. PolicyAccountDomainInformation,
  959. (PVOID *) &DomainInfo
  960. );
  961. if (!NT_SUCCESS(Status))
  962. {
  963. LsaClose( LsaHandle);
  964. SamCloseHandle( SamHandle );
  965. return( RtlNtStatusToDosError( Status ) );
  966. }
  967. RtlCopyMemory(
  968. &DomainSid,
  969. DomainInfo->DomainSid,
  970. RtlLengthSid(DomainInfo->DomainSid)
  971. );
  972. LsaFreeMemory(DomainInfo);
  973. LsaClose( LsaHandle );
  974. Status = SamOpenDomain(
  975. SamHandle,
  976. MAXIMUM_ALLOWED,
  977. (PSID) &DomainSid,
  978. &DomainHandle
  979. );
  980. return RtlNtStatusToDosError( Status );
  981. }
  982. void
  983. __cdecl
  984. wmain (int argc, WCHAR *argv[])
  985. {
  986. HKEY Key ;
  987. int err ;
  988. SAMPR_BOOT_TYPE SystemSetting ;
  989. SAMPR_BOOT_TYPE SamSetting ;
  990. DWORD Type;
  991. DWORD Length ;
  992. NTSTATUS Status ;
  993. WCHAR MsgBuffer[ MAX_PATH ];
  994. err = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  995. TEXT("System\\CurrentControlSet\\Control\\Lsa"),
  996. 0,
  997. KEY_READ | KEY_WRITE,
  998. & Key );
  999. if ( err )
  1000. {
  1001. DisplayErrorAndExit( NULL, IDS_SYSTEM_ERROR_OCCURRED, err );
  1002. }
  1003. LsaKey = Key ;
  1004. Length = sizeof( SystemSetting );
  1005. err = RegQueryValueEx( Key,
  1006. SYSTEM_KEY,
  1007. NULL,
  1008. &Type,
  1009. (PUCHAR) &SystemSetting,
  1010. &Length );
  1011. if ( err )
  1012. {
  1013. SystemSetting = SamBootKeyNone ;
  1014. }
  1015. //
  1016. // Now, compare with SAM:
  1017. //
  1018. err = OpenSamAccountDomain();
  1019. if ( err )
  1020. {
  1021. DisplayErrorAndExit( NULL, IDS_SYSTEM_ERROR_OCCURRED, err );
  1022. }
  1023. Status = xSamiGetBootKeyInformation( DomainHandle,
  1024. &SamSetting );
  1025. if ( !NT_SUCCESS( Status ) )
  1026. {
  1027. DisplayErrorAndExit( NULL,
  1028. IDS_SYSTEM_ERROR_OCCURRED,
  1029. RtlNtStatusToDosError( Status ) );
  1030. }
  1031. if ( SamSetting != SystemSetting )
  1032. {
  1033. SystemSetting = SamSetting ;
  1034. err = RegSetValueEx( Key,
  1035. SYSTEM_KEY,
  1036. 0,
  1037. REG_DWORD,
  1038. (PUCHAR) &SystemSetting,
  1039. sizeof( DWORD ) );
  1040. MyMessageBox( NULL, IDS_SAM_NOT_SYNC, IDS_WARNING_CAPTION,
  1041. MB_ICONHAND | MB_OK );
  1042. }
  1043. SecureBootOption = SamSetting ;
  1044. OriginalBootOption = SamSetting ;
  1045. if ( argc > 1 )
  1046. {
  1047. LoadString( GetModuleHandle( NULL ), IDS_L_OPTION, OptionL, 4 );
  1048. LoadString( GetModuleHandle( NULL ), IDS_Q_OPTION, OptionQ, 4 );
  1049. //
  1050. // Check for unattended:
  1051. //
  1052. if ( (*argv[1] == L'-') ||
  1053. (*argv[1] == L'/') )
  1054. {
  1055. if ( towupper(argv[1][1]) == OptionL[0] )
  1056. {
  1057. Unattended = TRUE ;
  1058. }
  1059. }
  1060. }
  1061. if ( Unattended )
  1062. {
  1063. if ( ( OriginalBootOption == SamBootKeyStored ) ||
  1064. ( OriginalBootOption == SamBootKeyNone ) )
  1065. {
  1066. UnattendedLocal();
  1067. }
  1068. else
  1069. {
  1070. LoadString( GetModuleHandle( NULL ), IDS_NO_UNATTENDED,
  1071. MsgBuffer, MAX_PATH );
  1072. fprintf( stderr, "%ws\n", MsgBuffer );
  1073. }
  1074. }
  1075. else
  1076. {
  1077. DialogBox( GetModuleHandle(NULL),
  1078. MAKEINTRESOURCE( IDD_MAIN_DIALOG ),
  1079. NULL,
  1080. MainDlg );
  1081. }
  1082. RegCloseKey( LsaKey );
  1083. }