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.

1401 lines
45 KiB

  1. /*++
  2. Copyright (c) 1998 Microsoft Corporation
  3. Module Name:
  4. upgrade.c
  5. Abstract:
  6. Implements the server side of the routines to upgrade NT4 (downlevel) servers
  7. Author:
  8. Mac McLain (MacM) 24 January, 1998
  9. Environment:
  10. User Mode
  11. Revision History:
  12. --*/
  13. #include <setpch.h>
  14. #include <dssetp.h>
  15. #include <loadfn.h>
  16. #include <ntlsa.h>
  17. #include <lsarpc.h>
  18. #include <lsaisrv.h>
  19. #include <samrpc.h>
  20. #include <samisrv.h>
  21. #include <db.h>
  22. #define DSROLEP_UPGRADE_KEY L"Security\\"
  23. #define DSROLEP_UPGRADE_VALUE L"Upgrade"
  24. #define DSROLEP_UPGRADE_WINLOGON \
  25. L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon\\"
  26. #define DSROLEP_UPGRADE_SAVE_PREFIX L"DcpromoOld_"
  27. #define DSROLEP_UPGRADE_AUTOADMIN L"AutoAdminLogon"
  28. #define DSROLEP_UPGRADE_AUTOPASSWD L"DefaultPassword"
  29. #define DSROLEP_UPGRADE_DEFDOMAIN L"DefaultDomainName"
  30. #define DSROLEP_UPGRADE_DEFUSER L"DefaultUserName"
  31. #define DSROLEP_UPGRADE_AUTOUSERINIT L"Userinit"
  32. #define DSROLEP_UPGRADE_DCPROMO L",dcpromo /upgrade"
  33. #define DSROLEP_UPGRADE_ANSWERFILE L"/answer:"
  34. DWORD
  35. DsRolepSetLogonDomain(
  36. IN LPWSTR Domain,
  37. IN BOOLEAN FailureAllowed
  38. )
  39. /*++
  40. Routine Description:
  41. This function sets the default logon domain for winlogon
  42. Arguments:
  43. Domain -- Default logon domain
  44. FailureAllowed -- If true, a failure is not considered catastrophic
  45. Return Values:
  46. ERROR_SUCCESS - Success
  47. --*/
  48. {
  49. DWORD Win32Err = ERROR_SUCCESS;
  50. HKEY WinlogonHandle = NULL;
  51. //
  52. // Open the key
  53. //
  54. Win32Err = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  55. DSROLEP_UPGRADE_WINLOGON,
  56. 0,
  57. KEY_READ | KEY_WRITE,
  58. &WinlogonHandle );
  59. if ( Win32Err == ERROR_SUCCESS ) {
  60. //
  61. // Default logon domain
  62. //
  63. Win32Err = RegSetValueEx( WinlogonHandle,
  64. DSROLEP_UPGRADE_DEFDOMAIN,
  65. 0,
  66. REG_SZ,
  67. ( CONST PBYTE )Domain,
  68. ( wcslen( Domain ) + 1 ) * sizeof( WCHAR ) );
  69. RegCloseKey( WinlogonHandle );
  70. }
  71. if ( Win32Err != ERROR_SUCCESS && FailureAllowed ) {
  72. //
  73. // Raise an event
  74. //
  75. SpmpReportEvent( TRUE,
  76. EVENTLOG_WARNING_TYPE,
  77. DSROLERES_FAIL_LOGON_DOMAIN,
  78. 0,
  79. sizeof( ULONG ),
  80. &Win32Err,
  81. 1,
  82. Domain );
  83. DSROLEP_SET_NON_FATAL_ERROR( Win32Err );
  84. Win32Err = ERROR_SUCCESS;
  85. }
  86. return( Win32Err );
  87. }
  88. #pragma warning(push)
  89. #pragma warning(disable:4701)
  90. DWORD
  91. DsRolepSaveUpgradeState(
  92. IN LPWSTR AnswerFile
  93. )
  94. /*++
  95. Routine Description:
  96. This function is to be invoked during setup and saves the required server state to
  97. complete the promotion following the reboot. Following the successful completion
  98. of this API call, the server will be demoted to a member server in the same domain.
  99. Arguments:
  100. AnswerFile -- Optional path to an answer file to be used by DCPROMO during the subsequent
  101. invocation
  102. Return Values:
  103. ERROR_SUCCESS - Success
  104. ERROR_NOT_ENOUGH_MEMORY - A memory allocation failed
  105. --*/
  106. {
  107. DWORD Win32Err = ERROR_SUCCESS;
  108. NTSTATUS Status;
  109. LSAPR_HANDLE PolicyHandle = NULL;
  110. POLICY_ACCOUNT_DOMAIN_INFO AccountDomainInfo;
  111. PPOLICY_LSA_SERVER_ROLE_INFO ServerRoleInfo;
  112. OBJECT_ATTRIBUTES ObjectAttributes;
  113. HANDLE Handle = NULL;
  114. HKEY WinlogonHandle, UpgradeKey;
  115. ULONG Disp, Length;
  116. UNICODE_STRING KeyName;
  117. UNICODE_STRING ValueName;
  118. WCHAR ComputerName[ MAX_COMPUTERNAME_LENGTH + 1 ];
  119. PBYTE UserInitBuffer, TempBuffer;
  120. DWORD Type;
  121. LPWSTR NewAdminPassword = NULL;
  122. WCHAR Buffer[MAX_PATH];
  123. LPWSTR AdminName = Buffer;
  124. LPWSTR DefaultAdminName = L"Administrator";
  125. //
  126. // Get the localized Admin
  127. //
  128. Length = sizeof(Buffer)/sizeof(Buffer[0]);
  129. Status = SamIGetDefaultAdministratorName( AdminName,
  130. &Length );
  131. if ( !NT_SUCCESS(Status) ) {
  132. DsRolepLogOnFailure( ERROR_GEN_FAILURE,
  133. DsRolepLogPrint(( DEB_TRACE,
  134. "SamIGetDefaultAdministratorName failed with 0x%x\n",
  135. Status )) );
  136. AdminName = DefaultAdminName;
  137. Status = STATUS_SUCCESS;
  138. }
  139. //
  140. // Steps involved: Set new SAM hives
  141. // Save LSA state
  142. // Set auto admin logon
  143. //
  144. // Invoke the SAM save code. It returns the new account domain sid
  145. //
  146. DSROLEP_CURRENT_OP0( DSROLEEVT_UPGRADE_SAM );
  147. Win32Err = NtdsPrepareForDsUpgrade( &AccountDomainInfo,
  148. &NewAdminPassword );
  149. DsRolepLogOnFailure( Win32Err,
  150. DsRolepLogPrint(( DEB_TRACE,
  151. "NtdsPrepareForDsUpgrade failed with %lu\n",
  152. Win32Err )) );
  153. //
  154. // Set the new lsa account domain sid
  155. //
  156. if ( Win32Err == ERROR_SUCCESS ) {
  157. RtlZeroMemory( &ObjectAttributes, sizeof( ObjectAttributes ) );
  158. Status = LsaOpenPolicy( NULL,
  159. &ObjectAttributes,
  160. POLICY_READ | POLICY_WRITE |
  161. POLICY_VIEW_LOCAL_INFORMATION | POLICY_TRUST_ADMIN,
  162. &PolicyHandle );
  163. if ( NT_SUCCESS( Status ) ) {
  164. //
  165. // Set the new policy info
  166. //
  167. Status = LsaSetInformationPolicy( PolicyHandle,
  168. PolicyAccountDomainInformation,
  169. ( PVOID ) &AccountDomainInfo );
  170. }
  171. Win32Err = RtlNtStatusToDosError( Status );
  172. RtlFreeHeap( RtlProcessHeap(), 0, AccountDomainInfo.DomainSid );
  173. RtlFreeHeap( RtlProcessHeap(), 0, AccountDomainInfo.DomainName.Buffer );
  174. }
  175. //
  176. // Set the LSA registry keys that let the server know on the next reboot that this
  177. // is an upgrade
  178. //
  179. if ( Win32Err == ERROR_SUCCESS ) {
  180. //
  181. // Get the current server role
  182. //
  183. Status = LsaQueryInformationPolicy( PolicyHandle,
  184. PolicyLsaServerRoleInformation,
  185. ( PVOID )&ServerRoleInfo );
  186. Win32Err = RtlNtStatusToDosError( Status );
  187. if ( Win32Err == ERROR_SUCCESS ) {
  188. //
  189. // Open the key
  190. //
  191. if ( Win32Err == ERROR_SUCCESS ) {
  192. Win32Err = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  193. DSROLEP_UPGRADE_KEY,
  194. 0,
  195. KEY_READ | KEY_WRITE,
  196. &UpgradeKey );
  197. }
  198. if ( Win32Err == ERROR_SUCCESS ) {
  199. //
  200. // Set the server role
  201. //
  202. Win32Err = RegSetValueEx( UpgradeKey,
  203. DSROLEP_UPGRADE_VALUE,
  204. 0,
  205. REG_DWORD,
  206. ( CONST PBYTE )&ServerRoleInfo->LsaServerRole,
  207. sizeof( DWORD ) );
  208. RegCloseKey( UpgradeKey );
  209. }
  210. LsaFreeMemory( ServerRoleInfo );
  211. }
  212. }
  213. //
  214. // Set the machine to do auto admin logon
  215. //
  216. if ( Win32Err == ERROR_SUCCESS ) {
  217. //
  218. // Get the computer name. That will be used for the default logon domain
  219. //
  220. Length = MAX_COMPUTERNAME_LENGTH + 1;
  221. if ( GetComputerName( ComputerName, &Length ) == FALSE ) {
  222. Win32Err = GetLastError();
  223. } else {
  224. //
  225. // Open the root key
  226. //
  227. Win32Err = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  228. DSROLEP_UPGRADE_WINLOGON,
  229. 0,
  230. KEY_READ | KEY_WRITE,
  231. &WinlogonHandle );
  232. if ( Win32Err == ERROR_SUCCESS ) {
  233. //
  234. // Auto logon
  235. //
  236. //
  237. // First, see if the value currently exists...
  238. //
  239. Length = 0;
  240. Win32Err = RegQueryValueEx( WinlogonHandle,
  241. DSROLEP_UPGRADE_AUTOADMIN,
  242. 0,
  243. &Type,
  244. 0,
  245. &Length );
  246. if ( Win32Err == ERROR_SUCCESS ) {
  247. TempBuffer = RtlAllocateHeap( RtlProcessHeap(), 0, Length );
  248. if ( TempBuffer == NULL ) {
  249. Win32Err = ERROR_NOT_ENOUGH_MEMORY;
  250. } else {
  251. Win32Err = RegQueryValueEx( WinlogonHandle,
  252. DSROLEP_UPGRADE_AUTOADMIN,
  253. 0,
  254. &Type,
  255. TempBuffer,
  256. &Length );
  257. if ( Win32Err == ERROR_SUCCESS ) {
  258. Win32Err = RegSetValueEx( WinlogonHandle,
  259. DSROLEP_UPGRADE_SAVE_PREFIX
  260. DSROLEP_UPGRADE_AUTOADMIN,
  261. 0,
  262. Type,
  263. TempBuffer,
  264. Length );
  265. }
  266. RtlFreeHeap( RtlProcessHeap(), 0, TempBuffer );
  267. }
  268. } else if ( Win32Err == ERROR_FILE_NOT_FOUND ) {
  269. Win32Err = ERROR_SUCCESS;
  270. }
  271. if ( Win32Err == ERROR_SUCCESS ) {
  272. Win32Err = RegSetValueEx( WinlogonHandle,
  273. DSROLEP_UPGRADE_AUTOADMIN,
  274. 0,
  275. REG_SZ,
  276. ( CONST PBYTE )L"1",
  277. 2 * sizeof ( WCHAR ) );
  278. }
  279. }
  280. if ( Win32Err == ERROR_SUCCESS ) {
  281. //
  282. // Set the account password
  283. //
  284. //
  285. // First, see if the value currently exists...
  286. //
  287. Length = 0;
  288. Win32Err = RegQueryValueEx( WinlogonHandle,
  289. DSROLEP_UPGRADE_AUTOPASSWD,
  290. 0,
  291. &Type,
  292. 0,
  293. &Length );
  294. if ( Win32Err == ERROR_SUCCESS ) {
  295. TempBuffer = RtlAllocateHeap( RtlProcessHeap(), 0, Length );
  296. if ( TempBuffer == NULL ) {
  297. Win32Err = ERROR_NOT_ENOUGH_MEMORY;
  298. } else {
  299. Win32Err = RegQueryValueEx( WinlogonHandle,
  300. DSROLEP_UPGRADE_AUTOPASSWD,
  301. 0,
  302. &Type,
  303. TempBuffer,
  304. &Length );
  305. if ( Win32Err == ERROR_SUCCESS ) {
  306. Win32Err = RegSetValueEx( WinlogonHandle,
  307. DSROLEP_UPGRADE_SAVE_PREFIX
  308. DSROLEP_UPGRADE_AUTOPASSWD,
  309. 0,
  310. Type,
  311. TempBuffer,
  312. Length );
  313. }
  314. RtlFreeHeap( RtlProcessHeap(), 0, TempBuffer );
  315. }
  316. } else if ( Win32Err == ERROR_FILE_NOT_FOUND ) {
  317. Win32Err = ERROR_SUCCESS;
  318. }
  319. if ( Win32Err == ERROR_SUCCESS ) {
  320. Win32Err = RegSetValueEx( WinlogonHandle,
  321. DSROLEP_UPGRADE_AUTOPASSWD,
  322. 0,
  323. REG_SZ,
  324. (BYTE*)NewAdminPassword,
  325. NewAdminPassword ? (wcslen(NewAdminPassword)+1)*sizeof(WCHAR) : 0 );
  326. }
  327. }
  328. if ( Win32Err == ERROR_SUCCESS ) {
  329. //
  330. // Set the user name to be administrator
  331. //
  332. //
  333. // First, see if the value currently exists...
  334. //
  335. Length = 0;
  336. Win32Err = RegQueryValueEx( WinlogonHandle,
  337. DSROLEP_UPGRADE_DEFUSER,
  338. 0,
  339. &Type,
  340. 0,
  341. &Length );
  342. if ( Win32Err == ERROR_SUCCESS ) {
  343. TempBuffer = RtlAllocateHeap( RtlProcessHeap(), 0, Length );
  344. if ( TempBuffer == NULL ) {
  345. Win32Err = ERROR_NOT_ENOUGH_MEMORY;
  346. } else {
  347. Win32Err = RegQueryValueEx( WinlogonHandle,
  348. DSROLEP_UPGRADE_DEFUSER,
  349. 0,
  350. &Type,
  351. TempBuffer,
  352. &Length );
  353. if ( Win32Err == ERROR_SUCCESS ) {
  354. Win32Err = RegSetValueEx( WinlogonHandle,
  355. DSROLEP_UPGRADE_SAVE_PREFIX
  356. DSROLEP_UPGRADE_DEFUSER,
  357. 0,
  358. Type,
  359. TempBuffer,
  360. Length );
  361. }
  362. RtlFreeHeap( RtlProcessHeap(), 0, TempBuffer );
  363. }
  364. } else if ( Win32Err == ERROR_FILE_NOT_FOUND ) {
  365. Win32Err = ERROR_SUCCESS;
  366. }
  367. if ( Win32Err == ERROR_SUCCESS ) {
  368. Win32Err = RegSetValueEx( WinlogonHandle,
  369. DSROLEP_UPGRADE_DEFUSER,
  370. 0,
  371. REG_SZ,
  372. ( CONST PBYTE )AdminName,
  373. ( wcslen( AdminName ) + 1 ) * sizeof( WCHAR ) );
  374. }
  375. }
  376. if ( Win32Err == ERROR_SUCCESS ) {
  377. //
  378. // Set the logon domain to the machine
  379. //
  380. //
  381. // First, see if the value currently exists...
  382. //
  383. Length = 0;
  384. Win32Err = RegQueryValueEx( WinlogonHandle,
  385. DSROLEP_UPGRADE_DEFDOMAIN,
  386. 0,
  387. &Type,
  388. 0,
  389. &Length );
  390. if ( Win32Err == ERROR_SUCCESS ) {
  391. TempBuffer = RtlAllocateHeap( RtlProcessHeap(), 0, Length );
  392. if ( TempBuffer == NULL ) {
  393. Win32Err = ERROR_NOT_ENOUGH_MEMORY;
  394. } else {
  395. Win32Err = RegQueryValueEx( WinlogonHandle,
  396. DSROLEP_UPGRADE_DEFDOMAIN,
  397. 0,
  398. &Type,
  399. TempBuffer,
  400. &Length );
  401. if ( Win32Err == ERROR_SUCCESS ) {
  402. Win32Err = RegSetValueEx( WinlogonHandle,
  403. DSROLEP_UPGRADE_SAVE_PREFIX
  404. DSROLEP_UPGRADE_DEFDOMAIN,
  405. 0,
  406. Type,
  407. TempBuffer,
  408. Length );
  409. }
  410. RtlFreeHeap( RtlProcessHeap(), 0, TempBuffer );
  411. }
  412. } else if ( Win32Err == ERROR_FILE_NOT_FOUND ) {
  413. Win32Err = ERROR_SUCCESS;
  414. }
  415. if ( Win32Err == ERROR_SUCCESS ) {
  416. Win32Err = RegSetValueEx( WinlogonHandle,
  417. DSROLEP_UPGRADE_DEFDOMAIN,
  418. 0,
  419. REG_SZ,
  420. ( CONST PBYTE )ComputerName,
  421. ( wcslen( ComputerName ) + 1 ) * sizeof( WCHAR ) );
  422. }
  423. }
  424. if ( Win32Err == ERROR_SUCCESS ) {
  425. //
  426. // Finally, set dcpromo to autostart
  427. //
  428. Length = 0;
  429. Win32Err = RegQueryValueEx( WinlogonHandle,
  430. DSROLEP_UPGRADE_AUTOUSERINIT,
  431. 0, // reserved
  432. &Type,
  433. 0,
  434. &Length );
  435. if ( Win32Err == ERROR_SUCCESS ) {
  436. Length += sizeof( DSROLEP_UPGRADE_DCPROMO );
  437. if ( AnswerFile ) {
  438. Length += sizeof( DSROLEP_UPGRADE_ANSWERFILE ) +
  439. ( wcslen( AnswerFile ) * sizeof( WCHAR ) );
  440. }
  441. UserInitBuffer = RtlAllocateHeap( RtlProcessHeap(), 0,
  442. Length );
  443. if ( UserInitBuffer == NULL ) {
  444. Win32Err = ERROR_NOT_ENOUGH_MEMORY;
  445. } else {
  446. Win32Err = RegQueryValueEx( WinlogonHandle,
  447. DSROLEP_UPGRADE_AUTOUSERINIT,
  448. 0,
  449. &Type,
  450. UserInitBuffer,
  451. &Length );
  452. if ( Win32Err == ERROR_SUCCESS ) {
  453. wcscat( ( PWSTR )UserInitBuffer, DSROLEP_UPGRADE_DCPROMO );
  454. if ( AnswerFile ) {
  455. wcscat( ( PWSTR )UserInitBuffer, DSROLEP_UPGRADE_ANSWERFILE );
  456. wcscat( ( PWSTR )UserInitBuffer, AnswerFile );
  457. }
  458. Status = RegSetValueEx( WinlogonHandle,
  459. DSROLEP_UPGRADE_AUTOUSERINIT,
  460. 0,
  461. Type,
  462. UserInitBuffer,
  463. ( wcslen( ( PWSTR )UserInitBuffer ) + 1 ) *
  464. sizeof( WCHAR ) );
  465. }
  466. }
  467. RtlFreeHeap( RtlProcessHeap(), 0, UserInitBuffer );
  468. }
  469. RegCloseKey( WinlogonHandle );
  470. }
  471. }
  472. }
  473. if ( PolicyHandle ) {
  474. LsaClose( PolicyHandle );
  475. }
  476. //
  477. // Set the product types
  478. //
  479. if ( Win32Err == ERROR_SUCCESS ) {
  480. Win32Err = DsRolepSetProductType( DSROLEP_MT_STANDALONE );
  481. }
  482. if ( NewAdminPassword ) {
  483. RtlFreeHeap( RtlProcessHeap(), 0, NewAdminPassword );
  484. }
  485. return( Win32Err );
  486. }
  487. #pragma warning(pop)
  488. DWORD
  489. DsRolepDeleteUpgradeInfo(
  490. VOID
  491. )
  492. /*++
  493. Routine Description:
  494. This function deletes the saved information
  495. Arguments:
  496. VOID
  497. Return Values:
  498. ERROR_SUCCESS - Success
  499. ERROR_NOT_ENOUGH_MEMORY - A memory allocation failed
  500. --*/
  501. {
  502. DWORD Win32Err = ERROR_SUCCESS, RestoreError = Win32Err;
  503. NTSTATUS Status;
  504. OBJECT_ATTRIBUTES ObjectAttributes;
  505. HKEY WinlogonHandle, UpgradeKey;
  506. PWSTR Remove, Next, DeletePath;
  507. PBYTE UserInitBuffer, TempBuffer;
  508. DWORD Type, Length = 0;
  509. //
  510. // Remove autostarting dcpromo
  511. //
  512. //
  513. // Open the root key
  514. //
  515. Win32Err = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  516. DSROLEP_UPGRADE_WINLOGON,
  517. 0,
  518. KEY_READ | KEY_WRITE,
  519. &WinlogonHandle );
  520. #if DBG
  521. DsRolepLogOnFailure( Win32Err,
  522. DsRolepLogPrint(( DEB_TRACE,
  523. "RegOpenKeyEx on %ws failed with %lu\n",
  524. DSROLEP_UPGRADE_WINLOGON,
  525. Win32Err )) );
  526. #endif
  527. if ( Win32Err == ERROR_SUCCESS ) {
  528. //
  529. // Stop dcpromo from autostarting...
  530. //
  531. Win32Err = RegQueryValueEx( WinlogonHandle,
  532. DSROLEP_UPGRADE_AUTOUSERINIT,
  533. 0, // reserved
  534. &Type,
  535. 0,
  536. &Length );
  537. #if DBG
  538. DsRolepLogOnFailure( Win32Err,
  539. DsRolepLogPrint(( DEB_TRACE,
  540. "RegQueryValyueEx on %ws failed with %lu\n",
  541. DSROLEP_UPGRADE_AUTOUSERINIT,
  542. Win32Err )) );
  543. #endif
  544. if ( Win32Err == ERROR_SUCCESS ) {
  545. UserInitBuffer = RtlAllocateHeap( RtlProcessHeap(), 0,
  546. Length );
  547. if ( UserInitBuffer == NULL ) {
  548. Win32Err = ERROR_NOT_ENOUGH_MEMORY;
  549. } else {
  550. Win32Err = RegQueryValueEx( WinlogonHandle,
  551. DSROLEP_UPGRADE_AUTOUSERINIT,
  552. 0,
  553. &Type,
  554. UserInitBuffer,
  555. &Length );
  556. #if DBG
  557. DsRolepLogOnFailure( Win32Err,
  558. DsRolepLogPrint(( DEB_TRACE,
  559. "RegQueryValyueEx on %ws failed with %lu\n",
  560. DSROLEP_UPGRADE_AUTOUSERINIT,
  561. Win32Err )) );
  562. #endif
  563. if ( Win32Err == ERROR_SUCCESS ) {
  564. Remove = wcsstr ( ( PWSTR )UserInitBuffer, DSROLEP_UPGRADE_DCPROMO );
  565. if ( Remove ) {
  566. Next = Remove + ( ( sizeof( DSROLEP_UPGRADE_DCPROMO ) - sizeof( WCHAR ) ) /
  567. sizeof( WCHAR ) );
  568. while ( *Next ) {
  569. *Remove++ = *Next++;
  570. }
  571. *Remove = UNICODE_NULL;
  572. Status = RegSetValueEx( WinlogonHandle,
  573. DSROLEP_UPGRADE_AUTOUSERINIT,
  574. 0,
  575. Type,
  576. UserInitBuffer,
  577. ( wcslen( ( PWSTR )UserInitBuffer ) + 1 ) *
  578. sizeof( WCHAR ) );
  579. #if DBG
  580. DsRolepLogOnFailure( Win32Err,
  581. DsRolepLogPrint(( DEB_TRACE,
  582. "RegQSetValyueEx on %ws failed with %lu\n",
  583. DSROLEP_UPGRADE_AUTOUSERINIT,
  584. Win32Err )) );
  585. #endif
  586. }
  587. }
  588. }
  589. RtlFreeHeap( RtlProcessHeap(), 0, UserInitBuffer );
  590. }
  591. if ( Win32Err == ERROR_SUCCESS ) {
  592. //
  593. // Auto logon
  594. //
  595. //
  596. // Restore the old values, if they exist
  597. //
  598. DeletePath = DSROLEP_UPGRADE_AUTOADMIN;
  599. Length = 0;
  600. Win32Err = RegQueryValueEx( WinlogonHandle,
  601. DSROLEP_UPGRADE_SAVE_PREFIX DSROLEP_UPGRADE_AUTOADMIN,
  602. 0,
  603. &Type,
  604. 0,
  605. &Length );
  606. if ( Win32Err == ERROR_SUCCESS ) {
  607. TempBuffer = RtlAllocateHeap( RtlProcessHeap(), 0, Length );
  608. if ( TempBuffer == NULL ) {
  609. Win32Err = ERROR_NOT_ENOUGH_MEMORY;
  610. } else {
  611. Win32Err = RegQueryValueEx( WinlogonHandle,
  612. DSROLEP_UPGRADE_SAVE_PREFIX
  613. DSROLEP_UPGRADE_AUTOADMIN,
  614. 0,
  615. &Type,
  616. TempBuffer,
  617. &Length );
  618. if ( Win32Err == ERROR_SUCCESS ) {
  619. Win32Err = RegSetValueEx( WinlogonHandle,
  620. DSROLEP_UPGRADE_AUTOADMIN,
  621. 0,
  622. Type,
  623. TempBuffer,
  624. Length );
  625. RegDeleteValue( WinlogonHandle,
  626. DSROLEP_UPGRADE_SAVE_PREFIX DSROLEP_UPGRADE_AUTOADMIN );
  627. }
  628. RtlFreeHeap( RtlProcessHeap(), 0, TempBuffer );
  629. }
  630. } else if ( Win32Err == ERROR_FILE_NOT_FOUND ) {
  631. Win32Err = RegDeleteValue( WinlogonHandle, DeletePath );
  632. DsRolepLogOnFailure( Win32Err,
  633. DsRolepLogPrint(( DEB_TRACE,
  634. "RegDeleteKey on %ws failed with %lu\n",
  635. DeletePath,
  636. Win32Err )) );
  637. //
  638. // An error here is not considered fatal...
  639. //
  640. Win32Err = ERROR_SUCCESS;
  641. }
  642. //
  643. // Restore the default user logon name
  644. //
  645. DeletePath = DSROLEP_UPGRADE_DEFUSER;
  646. Length = 0;
  647. Win32Err = RegQueryValueEx( WinlogonHandle,
  648. DSROLEP_UPGRADE_SAVE_PREFIX DSROLEP_UPGRADE_DEFUSER,
  649. 0,
  650. &Type,
  651. 0,
  652. &Length );
  653. if ( Win32Err == ERROR_SUCCESS ) {
  654. TempBuffer = RtlAllocateHeap( RtlProcessHeap(), 0, Length );
  655. if ( TempBuffer == NULL ) {
  656. Win32Err = ERROR_NOT_ENOUGH_MEMORY;
  657. } else {
  658. Win32Err = RegQueryValueEx( WinlogonHandle,
  659. DSROLEP_UPGRADE_SAVE_PREFIX
  660. DSROLEP_UPGRADE_DEFUSER,
  661. 0,
  662. &Type,
  663. TempBuffer,
  664. &Length );
  665. if ( Win32Err == ERROR_SUCCESS ) {
  666. Win32Err = RegSetValueEx( WinlogonHandle,
  667. DSROLEP_UPGRADE_DEFUSER,
  668. 0,
  669. Type,
  670. TempBuffer,
  671. Length );
  672. RegDeleteValue( WinlogonHandle,
  673. DSROLEP_UPGRADE_SAVE_PREFIX DSROLEP_UPGRADE_DEFUSER );
  674. }
  675. RtlFreeHeap( RtlProcessHeap(), 0, TempBuffer );
  676. }
  677. } else if ( Win32Err == ERROR_FILE_NOT_FOUND ) {
  678. Win32Err = RegDeleteValue( WinlogonHandle, DeletePath );
  679. DsRolepLogOnFailure( Win32Err,
  680. DsRolepLogPrint(( DEB_TRACE,
  681. "RegDeleteKey on %ws failed with %lu\n",
  682. DeletePath,
  683. Win32Err )) );
  684. //
  685. // An error here is not considered fatal...
  686. //
  687. Win32Err = ERROR_SUCCESS;
  688. }
  689. //
  690. // Restore the default domain name
  691. //
  692. DeletePath = DSROLEP_UPGRADE_DEFDOMAIN;
  693. Length = 0;
  694. Win32Err = RegQueryValueEx( WinlogonHandle,
  695. DSROLEP_UPGRADE_SAVE_PREFIX DSROLEP_UPGRADE_DEFDOMAIN,
  696. 0,
  697. &Type,
  698. 0,
  699. &Length );
  700. if ( Win32Err == ERROR_SUCCESS ) {
  701. TempBuffer = RtlAllocateHeap( RtlProcessHeap(), 0, Length );
  702. if ( TempBuffer == NULL ) {
  703. Win32Err = ERROR_NOT_ENOUGH_MEMORY;
  704. } else {
  705. Win32Err = RegQueryValueEx( WinlogonHandle,
  706. DSROLEP_UPGRADE_SAVE_PREFIX
  707. DSROLEP_UPGRADE_DEFDOMAIN,
  708. 0,
  709. &Type,
  710. TempBuffer,
  711. &Length );
  712. if ( Win32Err == ERROR_SUCCESS ) {
  713. Win32Err = RegSetValueEx( WinlogonHandle,
  714. DSROLEP_UPGRADE_DEFDOMAIN,
  715. 0,
  716. Type,
  717. TempBuffer,
  718. Length );
  719. RegDeleteValue( WinlogonHandle,
  720. DSROLEP_UPGRADE_SAVE_PREFIX DSROLEP_UPGRADE_DEFDOMAIN );
  721. }
  722. RtlFreeHeap( RtlProcessHeap(), 0, TempBuffer );
  723. }
  724. } else if ( Win32Err == ERROR_FILE_NOT_FOUND ) {
  725. Win32Err = RegDeleteValue( WinlogonHandle, DeletePath );
  726. DsRolepLogOnFailure( Win32Err,
  727. DsRolepLogPrint(( DEB_TRACE,
  728. "RegDeleteKey on %ws failed with %lu\n",
  729. DeletePath,
  730. Win32Err )) );
  731. //
  732. // An error here is not considered fatal...
  733. //
  734. Win32Err = ERROR_SUCCESS;
  735. }
  736. if ( Win32Err == ERROR_SUCCESS ) {
  737. //
  738. // Delete the account password
  739. //
  740. Length = 0;
  741. Win32Err = RegQueryValueEx( WinlogonHandle,
  742. DSROLEP_UPGRADE_SAVE_PREFIX
  743. DSROLEP_UPGRADE_AUTOPASSWD,
  744. 0,
  745. &Type,
  746. 0,
  747. &Length );
  748. if ( Win32Err == ERROR_SUCCESS ) {
  749. TempBuffer = RtlAllocateHeap( RtlProcessHeap(), 0, Length );
  750. if ( TempBuffer == NULL ) {
  751. Win32Err = ERROR_NOT_ENOUGH_MEMORY;
  752. } else {
  753. Win32Err = RegQueryValueEx( WinlogonHandle,
  754. DSROLEP_UPGRADE_SAVE_PREFIX
  755. DSROLEP_UPGRADE_AUTOPASSWD,
  756. 0,
  757. &Type,
  758. TempBuffer,
  759. &Length );
  760. if ( Win32Err == ERROR_SUCCESS ) {
  761. Win32Err = RegSetValueEx( WinlogonHandle,
  762. DSROLEP_UPGRADE_AUTOPASSWD,
  763. 0,
  764. Type,
  765. TempBuffer,
  766. Length );
  767. RegDeleteValue( WinlogonHandle,
  768. DSROLEP_UPGRADE_SAVE_PREFIX
  769. DSROLEP_UPGRADE_AUTOPASSWD );
  770. }
  771. RtlFreeHeap( RtlProcessHeap(), 0, TempBuffer );
  772. }
  773. } else if ( Win32Err == ERROR_FILE_NOT_FOUND ) {
  774. DeletePath = DSROLEP_UPGRADE_AUTOPASSWD;
  775. Win32Err = RegDeleteValue( WinlogonHandle, DeletePath );
  776. DsRolepLogOnFailure( Win32Err,
  777. DsRolepLogPrint(( DEB_TRACE,
  778. "RegDeleteKey on %ws failed with %lu\n",
  779. DeletePath,
  780. Win32Err )) );
  781. //
  782. // An error here is not considered fatal...
  783. //
  784. Win32Err = ERROR_SUCCESS;
  785. }
  786. }
  787. if ( Win32Err != ERROR_SUCCESS ) {
  788. //
  789. // Raise an event
  790. //
  791. SpmpReportEvent( TRUE,
  792. EVENTLOG_WARNING_TYPE,
  793. DSROLERES_FAIL_DISABLE_AUTO_LOGON,
  794. 0,
  795. sizeof( ULONG ),
  796. &Win32Err,
  797. 1,
  798. DeletePath );
  799. DSROLEP_SET_NON_FATAL_ERROR( Win32Err );
  800. Win32Err = ERROR_SUCCESS;
  801. }
  802. }
  803. RegCloseKey( WinlogonHandle );
  804. }
  805. //
  806. // Delete the registry key that LSA uses to determine if this is an upgrade
  807. //
  808. //
  809. // Open the key
  810. //
  811. if ( Win32Err == ERROR_SUCCESS ) {
  812. Win32Err = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  813. DSROLEP_UPGRADE_KEY,
  814. 0,
  815. DELETE | KEY_SET_VALUE,
  816. &UpgradeKey );
  817. #if DBG
  818. DsRolepLogOnFailure( Win32Err,
  819. DsRolepLogPrint(( DEB_TRACE,
  820. "RegOpenKey on %ws failed with %lu\n",
  821. DSROLEP_UPGRADE_KEY,
  822. Win32Err )) );
  823. #endif
  824. if ( Win32Err == ERROR_SUCCESS ) {
  825. Win32Err = RegDeleteValue( UpgradeKey, DSROLEP_UPGRADE_VALUE );
  826. if ( ERROR_FILE_NOT_FOUND == Win32Err ) {
  827. // This is ok.
  828. Win32Err = ERROR_SUCCESS;
  829. }
  830. #if DBG
  831. DsRolepLogOnFailure( Win32Err,
  832. DsRolepLogPrint(( DEB_TRACE,
  833. "RegDeleteKey on %ws failed with %lu\n",
  834. DSROLEP_UPGRADE_KEY,
  835. Win32Err )) );
  836. #endif
  837. RegCloseKey( UpgradeKey );
  838. }
  839. }
  840. //
  841. // Finally remove the nt4 LSA information
  842. //
  843. //
  844. // Remove the nt4 LSA stuff that has been put into the registry
  845. //
  846. LsapDsUnitializeDsStateInfo();
  847. Status = LsaIUpgradeRegistryToDs( TRUE );
  848. RestoreError = RtlNtStatusToDosError( Status );
  849. DsRolepLogOnFailure( RestoreError,
  850. DsRolepLogPrint(( DEB_WARN,
  851. "Failed to cleanup NT4 LSA (%d)\n",
  852. RestoreError )) );
  853. if ( ERROR_SUCCESS != RestoreError
  854. && ERROR_SUCCESS == Win32Err ) {
  855. Win32Err = RestoreError;
  856. }
  857. return( Win32Err );
  858. }
  859. DWORD
  860. DsRolepQueryUpgradeInfo(
  861. OUT PBOOLEAN IsUpgrade,
  862. OUT PULONG ServerRole
  863. )
  864. /*++
  865. Routine Description:
  866. This function queries the current update information.
  867. Arguments:
  868. IsUpgrade - A pointer to a BOOLEAN to hold a value of TRUE if there is upgrade information
  869. saved away, or a FALSE if not
  870. ServerRole - If this is an upgrade, the previous server role is returned here.
  871. Return Values:
  872. ERROR_SUCCESS - Success
  873. --*/
  874. {
  875. DWORD Win32Err = ERROR_SUCCESS;
  876. HKEY UpgradeKey;
  877. ULONG Type, Length = sizeof( ULONG );
  878. //
  879. // Open the upgrade key
  880. //
  881. Win32Err = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  882. DSROLEP_UPGRADE_KEY,
  883. 0,
  884. KEY_READ | KEY_WRITE,
  885. &UpgradeKey );
  886. if ( Win32Err == ERROR_SUCCESS ) {
  887. //
  888. // Finally, set dcpromo to autostart
  889. //
  890. Win32Err = RegQueryValueEx( UpgradeKey,
  891. DSROLEP_UPGRADE_VALUE,
  892. 0, // reserved
  893. &Type,
  894. ( PBYTE )ServerRole,
  895. &Length );
  896. if ( Win32Err == ERROR_SUCCESS ) {
  897. *IsUpgrade = TRUE;
  898. }
  899. RegCloseKey( UpgradeKey );
  900. }
  901. if ( Win32Err == ERROR_FILE_NOT_FOUND ) {
  902. Win32Err = ERROR_SUCCESS;
  903. *IsUpgrade = FALSE;
  904. }
  905. return( Win32Err );
  906. }
  907. DWORD
  908. DsRolepGetBuiltinAdminAccountName(
  909. OUT LPWSTR *BuiltinAdmin
  910. )
  911. /*++
  912. Routine Description:
  913. This routine finds the alias name for the builtin user account ADMINISTRATOR
  914. Arguments:
  915. BuiltinAdmin - Where the admin name is returned
  916. Return Values:
  917. ERROR_SUCCESS - Success
  918. ERROR_NOT_ENOUGH_MEMORY - A memory allocation failed
  919. --*/
  920. {
  921. DWORD Win32Err = ERROR_SUCCESS;
  922. SID_IDENTIFIER_AUTHORITY UaspNtAuthority = SECURITY_NT_AUTHORITY;
  923. DWORD SidBuff[ sizeof( SID ) / sizeof( DWORD ) + 5];
  924. PSID Sid = ( PSID )SidBuff;
  925. SID_NAME_USE SNE;
  926. LPWSTR Domain = NULL;
  927. LPWSTR Name = NULL;
  928. ULONG NameLen = 0, DomainLen = 0;
  929. //
  930. // Build the sid
  931. //
  932. RtlInitializeSid( Sid, &UaspNtAuthority, 2 );
  933. *( RtlSubAuthoritySid( Sid, 0 ) ) = SECURITY_BUILTIN_DOMAIN_RID;
  934. *( RtlSubAuthoritySid( Sid, 1 ) ) = DOMAIN_USER_RID_ADMIN;
  935. if ( LookupAccountSid( NULL,
  936. Sid,
  937. NULL,
  938. &NameLen,
  939. NULL,
  940. &DomainLen,
  941. &SNE ) == FALSE ) {
  942. Win32Err = GetLastError();
  943. if ( Win32Err == ERROR_INSUFFICIENT_BUFFER ) {
  944. Win32Err = ERROR_SUCCESS;
  945. Name = RtlAllocateHeap( RtlProcessHeap(), 0, NameLen * sizeof( WCHAR ) );
  946. Domain = RtlAllocateHeap( RtlProcessHeap(), 0, DomainLen * sizeof( WCHAR ) );
  947. if ( !Name || !Domain ) {
  948. Win32Err = ERROR_NOT_ENOUGH_MEMORY;
  949. } else {
  950. if ( LookupAccountSid( NULL,
  951. Sid,
  952. Name,
  953. &NameLen,
  954. Domain,
  955. &DomainLen,
  956. &SNE ) == FALSE ) {
  957. Win32Err = GetLastError();
  958. }
  959. }
  960. }
  961. }
  962. if ( Win32Err != ERROR_SUCCESS ) {
  963. RtlFreeHeap( RtlProcessHeap(), 0, Domain );
  964. RtlFreeHeap( RtlProcessHeap(), 0, Name );
  965. }
  966. return( Win32Err );
  967. }
  968. DWORD
  969. DsRolepSetBuiltinAdminAccountPassword(
  970. IN LPWSTR Password
  971. )
  972. /*++
  973. Routine Description:
  974. This routine will change the password on the builtin administrator account to the one
  975. specified
  976. Arguments:
  977. Password - Password to set
  978. Return Values:
  979. ERROR_SUCCESS - Success
  980. --*/
  981. {
  982. NTSTATUS Status = STATUS_SUCCESS;
  983. SAM_HANDLE SamHandle, SamDomainHandle, SamAdministrator;
  984. PPOLICY_ACCOUNT_DOMAIN_INFO AccountDomainInfo;
  985. LSA_HANDLE PolicyHandle;
  986. USER_ALL_INFORMATION UserAllInfo;
  987. OBJECT_ATTRIBUTES ObjectAttributes;
  988. UNICODE_STRING UserPassword;
  989. RtlZeroMemory( &ObjectAttributes, sizeof( ObjectAttributes ) );
  990. Status = LsaOpenPolicy( NULL,
  991. &ObjectAttributes,
  992. POLICY_VIEW_LOCAL_INFORMATION,
  993. &PolicyHandle );
  994. if ( NT_SUCCESS( Status ) ) {
  995. Status = LsaQueryInformationPolicy( PolicyHandle,
  996. PolicyAccountDomainInformation,
  997. ( PVOID * )&AccountDomainInfo );
  998. LsaClose( PolicyHandle );
  999. }
  1000. if ( NT_SUCCESS( Status ) ) {
  1001. Status = SamConnect( NULL,
  1002. &SamHandle,
  1003. MAXIMUM_ALLOWED,
  1004. &ObjectAttributes );
  1005. if ( NT_SUCCESS( Status ) ) {
  1006. //
  1007. // Open the builtin domain
  1008. //
  1009. Status = SamOpenDomain( SamHandle,
  1010. MAXIMUM_ALLOWED,
  1011. AccountDomainInfo->DomainSid,
  1012. &SamDomainHandle );
  1013. if ( NT_SUCCESS( Status ) ) {
  1014. Status = SamOpenUser( SamDomainHandle,
  1015. MAXIMUM_ALLOWED,
  1016. DOMAIN_USER_RID_ADMIN,
  1017. &SamAdministrator );
  1018. if ( NT_SUCCESS( Status ) ) {
  1019. RtlZeroMemory( &UserAllInfo, sizeof( USER_ALL_INFORMATION ) );
  1020. RtlInitUnicodeString( &UserPassword, Password );
  1021. UserAllInfo.NtPassword = UserPassword;
  1022. UserAllInfo.NtPasswordPresent = TRUE;
  1023. UserAllInfo.WhichFields = USER_ALL_NTPASSWORDPRESENT;
  1024. Status = SamSetInformationUser( SamAdministrator,
  1025. UserAllInformation,
  1026. ( PSAMPR_USER_INFO_BUFFER )&UserAllInfo );
  1027. SamCloseHandle( SamAdministrator );
  1028. }
  1029. SamCloseHandle( SamDomainHandle );
  1030. }
  1031. SamCloseHandle( SamHandle );
  1032. }
  1033. LsaFreeMemory( AccountDomainInfo );
  1034. }
  1035. return( RtlNtStatusToDosError( Status ) );
  1036. }