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.

1741 lines
56 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. DWORD
  89. DsRolepClearLsaSecretAutoLogonPassword()
  90. /*++
  91. Routine Description:
  92. This function is to be invoked during setup and deletes the
  93. auto logon password that was save in a lsa secret.
  94. Arguments:
  95. Return Values:
  96. ERROR_SUCCESS - Success
  97. ERROR_NOT_ENOUGH_MEMORY - A memory allocation failed
  98. --*/
  99. {
  100. LSAPR_OBJECT_ATTRIBUTES ObjectAttributes;
  101. LSAPR_HANDLE LsaPolicyHandle = NULL;
  102. LSAPR_UNICODE_STRING lusSecretName, lusSecretNameOld;
  103. PLSAPR_CR_CIPHER_VALUE plusSecretData = NULL;
  104. USHORT SecretNameLength, SecretNameOldLength;
  105. NTSTATUS status = STATUS_SUCCESS;
  106. DWORD Win32Err = ERROR_SUCCESS;
  107. ZeroMemory(&ObjectAttributes, sizeof(ObjectAttributes));
  108. // Get a handle to the Policy object.
  109. status = LsarOpenPolicy(NULL, //local machine
  110. &ObjectAttributes,
  111. POLICY_CREATE_SECRET |
  112. POLICY_READ,
  113. &LsaPolicyHandle);
  114. if (!NT_SUCCESS(status)) {
  115. Win32Err = LsaNtStatusToWinError(status);
  116. goto Cleanup;
  117. }
  118. //Initialize an LSA_UNICODE_STRING
  119. SecretNameLength = (USHORT)wcslen(DSROLEP_UPGRADE_AUTOPASSWD);
  120. lusSecretName.Buffer = DSROLEP_UPGRADE_AUTOPASSWD;
  121. lusSecretName.Length = SecretNameLength * sizeof(WCHAR);
  122. lusSecretName.MaximumLength = (SecretNameLength+1) * sizeof(WCHAR);
  123. //Initialize an LSA_UNICODE_STRING
  124. SecretNameOldLength = (USHORT)wcslen(DSROLEP_UPGRADE_SAVE_PREFIX
  125. DSROLEP_UPGRADE_AUTOPASSWD);
  126. lusSecretNameOld.Buffer = DSROLEP_UPGRADE_SAVE_PREFIX
  127. DSROLEP_UPGRADE_AUTOPASSWD;
  128. lusSecretNameOld.Length = SecretNameOldLength * sizeof(WCHAR);
  129. lusSecretNameOld.MaximumLength = (SecretNameOldLength+1) * sizeof(WCHAR);
  130. //erase the autologon password
  131. status = LsarStorePrivateData(LsaPolicyHandle,
  132. &lusSecretName,
  133. NULL);
  134. if (!NT_SUCCESS(status)) {
  135. Win32Err = LsaNtStatusToWinError(status);
  136. goto Cleanup;
  137. }
  138. //get the value of any secret that may currently be stored there
  139. //and save it off to a different location
  140. status = LsarRetrievePrivateData(LsaPolicyHandle,
  141. &lusSecretNameOld,
  142. &plusSecretData);
  143. if ( status != STATUS_OBJECT_NAME_NOT_FOUND ) {
  144. if ( !NT_SUCCESS(status) ) {
  145. Win32Err = LsaNtStatusToWinError(status);
  146. goto Cleanup;
  147. } else {
  148. //store the value else where
  149. status = LsarStorePrivateData(LsaPolicyHandle,
  150. &lusSecretName,
  151. plusSecretData);
  152. RtlSecureZeroMemory(plusSecretData->Buffer,plusSecretData->Length);
  153. if (!NT_SUCCESS(status)) {
  154. Win32Err = LsaNtStatusToWinError(status);
  155. goto Cleanup;
  156. }
  157. //erase the value
  158. status = LsarStorePrivateData(LsaPolicyHandle,
  159. &lusSecretNameOld,
  160. NULL);
  161. if (!NT_SUCCESS(status)) {
  162. Win32Err = LsaNtStatusToWinError(status);
  163. goto Cleanup;
  164. }
  165. }
  166. }
  167. Cleanup:
  168. if( NULL != LsaPolicyHandle )
  169. {
  170. LsaClose(LsaPolicyHandle);
  171. }
  172. if ( plusSecretData ) {
  173. LsaFreeMemory(plusSecretData);
  174. }
  175. return Win32Err;
  176. }
  177. DWORD
  178. DsRolepSaveUpgradePasswordForAutoLogonAsLsaSecret(
  179. IN LPWSTR NewAdminPassword)
  180. /*++
  181. Routine Description:
  182. This function is to be invoked during setup and saves the admin password for
  183. autologon as a lsa secret.
  184. Arguments:
  185. NewAdminPassword -- Password to save as a LSASECRET
  186. Return Values:
  187. ERROR_SUCCESS - Success
  188. ERROR_NOT_ENOUGH_MEMORY - A memory allocation failed
  189. --*/
  190. {
  191. LSAPR_OBJECT_ATTRIBUTES ObjectAttributes;
  192. LSAPR_HANDLE LsaPolicyHandle;
  193. LSAPR_UNICODE_STRING lusSecretName, lusSecretNameOld;
  194. PLSAPR_CR_CIPHER_VALUE plusSecretData = NULL;
  195. PLSAPR_CR_CIPHER_VALUE plusSecretDataNew = NULL;
  196. USHORT SecretNameLength, SecretNameOldLength, SecretDataLength;
  197. NTSTATUS status = STATUS_SUCCESS;
  198. DWORD Win32Err = ERROR_SUCCESS;
  199. LSAP_CR_CIPHER_KEY *SessionKey = NULL;
  200. LSAP_CR_CLEAR_VALUE lusSecretDataClear;
  201. // Object attributes are reserved, so initialize to zeroes.
  202. ZeroMemory(&ObjectAttributes, sizeof(ObjectAttributes));
  203. // Get a handle to the Policy object.
  204. status = LsarOpenPolicy(NULL, //local machine
  205. &ObjectAttributes,
  206. POLICY_CREATE_SECRET |
  207. POLICY_READ,
  208. &LsaPolicyHandle);
  209. if (!NT_SUCCESS(status)) {
  210. Win32Err = LsaNtStatusToWinError(status);
  211. goto Cleanup;
  212. }
  213. //Initialize an LSA_UNICODE_STRING
  214. SecretNameLength = (USHORT)wcslen(DSROLEP_UPGRADE_AUTOPASSWD);
  215. lusSecretName.Buffer = DSROLEP_UPGRADE_AUTOPASSWD;
  216. lusSecretName.Length = SecretNameLength * sizeof(WCHAR);
  217. lusSecretName.MaximumLength = (SecretNameLength+1) * sizeof(WCHAR);
  218. //Initialize an LSA_UNICODE_STRING
  219. SecretNameOldLength = (USHORT)wcslen(DSROLEP_UPGRADE_SAVE_PREFIX
  220. DSROLEP_UPGRADE_AUTOPASSWD);
  221. lusSecretNameOld.Buffer = DSROLEP_UPGRADE_SAVE_PREFIX
  222. DSROLEP_UPGRADE_AUTOPASSWD;
  223. lusSecretNameOld.Length = SecretNameOldLength * sizeof(WCHAR);
  224. lusSecretNameOld.MaximumLength = (SecretNameOldLength+1) * sizeof(WCHAR);
  225. //get the value of any secret that may currently be stored there
  226. //and save it off to a different location
  227. status = LsarRetrievePrivateData(LsaPolicyHandle,
  228. &lusSecretName,
  229. &plusSecretData);
  230. if ( status != STATUS_OBJECT_NAME_NOT_FOUND ) {
  231. if ( !NT_SUCCESS(status) ) {
  232. Win32Err = LsaNtStatusToWinError(status);
  233. goto Cleanup;
  234. } else {
  235. //store the value else where
  236. status = LsarStorePrivateData(LsaPolicyHandle,
  237. &lusSecretNameOld,
  238. plusSecretData);
  239. RtlSecureZeroMemory(plusSecretData->Buffer,plusSecretData->Length);
  240. if (!NT_SUCCESS(status)) {
  241. Win32Err = LsaNtStatusToWinError(status);
  242. goto Cleanup;
  243. }
  244. //erase the value
  245. status = LsarStorePrivateData(LsaPolicyHandle,
  246. &lusSecretName,
  247. NULL);
  248. if (!NT_SUCCESS(status)) {
  249. Win32Err = LsaNtStatusToWinError(status);
  250. goto Cleanup;
  251. }
  252. }
  253. }
  254. //Save the admin password
  255. //Initialize the Password LSA_UNICODE_STRING
  256. SecretDataLength = (USHORT)wcslen(NewAdminPassword);
  257. lusSecretDataClear.Buffer = (PUCHAR)NewAdminPassword;
  258. lusSecretDataClear.Length = SecretDataLength * sizeof(WCHAR);
  259. lusSecretDataClear.MaximumLength = (SecretDataLength+1) * sizeof(WCHAR);
  260. //
  261. // Obtain the Session Key to be used to two-way encrypt the
  262. // Current Value.
  263. //
  264. status = LsapCrServerGetSessionKey( LsaPolicyHandle, &SessionKey);
  265. if (!NT_SUCCESS(status)) {
  266. Win32Err = LsaNtStatusToWinError(status);
  267. goto Cleanup;
  268. }
  269. //
  270. // Encrypt the Current Value if specified and not too long.
  271. //
  272. status = LsapCrEncryptValue(
  273. &lusSecretDataClear,
  274. SessionKey,
  275. (PLSAP_CR_CIPHER_VALUE*)&plusSecretDataNew
  276. );
  277. if (!NT_SUCCESS(status)) {
  278. goto Cleanup;
  279. }
  280. status = LsarStorePrivateData(LsaPolicyHandle,
  281. &lusSecretName,
  282. plusSecretDataNew);
  283. RtlSecureZeroMemory(plusSecretDataNew->Buffer,plusSecretDataNew->Length);
  284. LsapCrFreeMemoryValue(plusSecretDataNew);
  285. if (!NT_SUCCESS(status)) {
  286. Win32Err = LsaNtStatusToWinError(status);
  287. goto Cleanup;
  288. }
  289. Cleanup:
  290. if( NULL != LsaPolicyHandle )
  291. {
  292. LsaClose(LsaPolicyHandle);
  293. }
  294. if ( SessionKey ) {
  295. MIDL_user_free(SessionKey);
  296. }
  297. if ( plusSecretData ) {
  298. LsaFreeMemory(plusSecretData);
  299. }
  300. if (plusSecretDataNew) {
  301. LsapCrFreeMemoryValue(plusSecretDataNew);
  302. }
  303. return Win32Err;
  304. }
  305. #pragma warning(push)
  306. #pragma warning(disable:4701)
  307. DWORD
  308. DsRolepSaveUpgradeState(
  309. IN LPWSTR AnswerFile
  310. )
  311. /*++
  312. Routine Description:
  313. This function is to be invoked during setup and saves the required server state to
  314. complete the promotion following the reboot. Following the successful completion
  315. of this API call, the server will be demoted to a member server in the same domain.
  316. Arguments:
  317. AnswerFile -- Optional path to an answer file to be used by DCPROMO during the subsequent
  318. invocation
  319. Return Values:
  320. ERROR_SUCCESS - Success
  321. ERROR_NOT_ENOUGH_MEMORY - A memory allocation failed
  322. --*/
  323. {
  324. DWORD Win32Err = ERROR_SUCCESS;
  325. NTSTATUS Status;
  326. LSAPR_HANDLE PolicyHandle = NULL;
  327. POLICY_ACCOUNT_DOMAIN_INFO AccountDomainInfo;
  328. PPOLICY_LSA_SERVER_ROLE_INFO ServerRoleInfo;
  329. OBJECT_ATTRIBUTES ObjectAttributes;
  330. HANDLE Handle = NULL;
  331. HKEY WinlogonHandle, UpgradeKey;
  332. ULONG Disp, Length;
  333. UNICODE_STRING KeyName;
  334. UNICODE_STRING ValueName;
  335. WCHAR ComputerName[ MAX_COMPUTERNAME_LENGTH + 1 ];
  336. PBYTE UserInitBuffer, TempBuffer;
  337. DWORD Type;
  338. LPWSTR NewAdminPassword = NULL;
  339. WCHAR Buffer[MAX_PATH];
  340. LPWSTR AdminName = Buffer;
  341. LPWSTR DefaultAdminName = L"Administrator";
  342. //
  343. // Get the localized Admin
  344. //
  345. Length = sizeof(Buffer)/sizeof(Buffer[0]);
  346. Status = SamIGetDefaultAdministratorName( AdminName,
  347. &Length );
  348. if ( !NT_SUCCESS(Status) ) {
  349. DsRolepLogOnFailure( ERROR_GEN_FAILURE,
  350. DsRolepLogPrint(( DEB_TRACE,
  351. "SamIGetDefaultAdministratorName failed with 0x%x\n",
  352. Status )) );
  353. AdminName = DefaultAdminName;
  354. Status = STATUS_SUCCESS;
  355. }
  356. DsRolepInitializeOperationHandle();
  357. //
  358. // Steps involved: Set new SAM hives
  359. // Save LSA state
  360. // Set auto admin logon
  361. //
  362. // Invoke the SAM save code. It returns the new account domain sid
  363. //
  364. DSROLEP_CURRENT_OP0( DSROLEEVT_UPGRADE_SAM );
  365. Win32Err = NtdsPrepareForDsUpgrade( &AccountDomainInfo,
  366. &NewAdminPassword );
  367. DsRolepLogOnFailure( Win32Err,
  368. DsRolepLogPrint(( DEB_TRACE,
  369. "NtdsPrepareForDsUpgrade failed with %lu\n",
  370. Win32Err )) );
  371. //
  372. // Set the new lsa account domain sid
  373. //
  374. if ( Win32Err == ERROR_SUCCESS ) {
  375. RtlZeroMemory( &ObjectAttributes, sizeof( ObjectAttributes ) );
  376. Status = LsaOpenPolicy( NULL,
  377. &ObjectAttributes,
  378. POLICY_READ | POLICY_WRITE |
  379. POLICY_VIEW_LOCAL_INFORMATION | POLICY_TRUST_ADMIN,
  380. &PolicyHandle );
  381. if ( NT_SUCCESS( Status ) ) {
  382. //
  383. // Set the new policy info
  384. //
  385. Status = LsaSetInformationPolicy( PolicyHandle,
  386. PolicyAccountDomainInformation,
  387. ( PVOID ) &AccountDomainInfo );
  388. }
  389. Win32Err = RtlNtStatusToDosError( Status );
  390. RtlFreeHeap( RtlProcessHeap(), 0, AccountDomainInfo.DomainSid );
  391. RtlFreeHeap( RtlProcessHeap(), 0, AccountDomainInfo.DomainName.Buffer );
  392. }
  393. //
  394. // Set the LSA registry keys that let the server know on the next reboot that this
  395. // is an upgrade
  396. //
  397. if ( Win32Err == ERROR_SUCCESS ) {
  398. //
  399. // Get the current server role
  400. //
  401. Status = LsaQueryInformationPolicy( PolicyHandle,
  402. PolicyLsaServerRoleInformation,
  403. ( PVOID )&ServerRoleInfo );
  404. Win32Err = RtlNtStatusToDosError( Status );
  405. if ( Win32Err == ERROR_SUCCESS ) {
  406. //
  407. // Open the key
  408. //
  409. if ( Win32Err == ERROR_SUCCESS ) {
  410. Win32Err = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  411. DSROLEP_UPGRADE_KEY,
  412. 0,
  413. KEY_READ | KEY_WRITE,
  414. &UpgradeKey );
  415. }
  416. if ( Win32Err == ERROR_SUCCESS ) {
  417. //
  418. // Set the server role
  419. //
  420. Win32Err = RegSetValueEx( UpgradeKey,
  421. DSROLEP_UPGRADE_VALUE,
  422. 0,
  423. REG_DWORD,
  424. ( CONST PBYTE )&ServerRoleInfo->LsaServerRole,
  425. sizeof( DWORD ) );
  426. RegCloseKey( UpgradeKey );
  427. }
  428. LsaFreeMemory( ServerRoleInfo );
  429. }
  430. }
  431. //
  432. // Set the machine to do auto admin logon
  433. //
  434. if ( Win32Err == ERROR_SUCCESS ) {
  435. //
  436. // Get the computer name. That will be used for the default logon domain
  437. //
  438. Length = MAX_COMPUTERNAME_LENGTH + 1;
  439. if ( GetComputerName( ComputerName, &Length ) == FALSE ) {
  440. Win32Err = GetLastError();
  441. } else {
  442. //
  443. // Open the root key
  444. //
  445. Win32Err = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  446. DSROLEP_UPGRADE_WINLOGON,
  447. 0,
  448. KEY_READ | KEY_WRITE,
  449. &WinlogonHandle );
  450. if ( Win32Err == ERROR_SUCCESS ) {
  451. //
  452. // Auto logon
  453. //
  454. //
  455. // First, see if the value currently exists...
  456. //
  457. Length = 0;
  458. Win32Err = RegQueryValueEx( WinlogonHandle,
  459. DSROLEP_UPGRADE_AUTOADMIN,
  460. 0,
  461. &Type,
  462. 0,
  463. &Length );
  464. if ( Win32Err == ERROR_SUCCESS ) {
  465. TempBuffer = RtlAllocateHeap( RtlProcessHeap(), 0, Length );
  466. if ( TempBuffer == NULL ) {
  467. Win32Err = ERROR_NOT_ENOUGH_MEMORY;
  468. } else {
  469. Win32Err = RegQueryValueEx( WinlogonHandle,
  470. DSROLEP_UPGRADE_AUTOADMIN,
  471. 0,
  472. &Type,
  473. TempBuffer,
  474. &Length );
  475. if ( Win32Err == ERROR_SUCCESS ) {
  476. Win32Err = RegSetValueEx( WinlogonHandle,
  477. DSROLEP_UPGRADE_SAVE_PREFIX
  478. DSROLEP_UPGRADE_AUTOADMIN,
  479. 0,
  480. Type,
  481. TempBuffer,
  482. Length );
  483. }
  484. RtlFreeHeap( RtlProcessHeap(), 0, TempBuffer );
  485. }
  486. } else if ( Win32Err == ERROR_FILE_NOT_FOUND ) {
  487. Win32Err = ERROR_SUCCESS;
  488. }
  489. if ( Win32Err == ERROR_SUCCESS ) {
  490. Win32Err = RegSetValueEx( WinlogonHandle,
  491. DSROLEP_UPGRADE_AUTOADMIN,
  492. 0,
  493. REG_SZ,
  494. ( CONST PBYTE )L"1",
  495. 2 * sizeof ( WCHAR ) );
  496. }
  497. }
  498. if ( Win32Err == ERROR_SUCCESS ) {
  499. //
  500. // Set the account password
  501. //
  502. //
  503. // First, see if the value currently exists...
  504. //
  505. Length = 0;
  506. Win32Err = RegQueryValueEx( WinlogonHandle,
  507. DSROLEP_UPGRADE_AUTOPASSWD,
  508. 0,
  509. &Type,
  510. 0,
  511. &Length );
  512. if ( Win32Err == ERROR_SUCCESS ) {
  513. TempBuffer = RtlAllocateHeap( RtlProcessHeap(), 0, Length );
  514. if ( TempBuffer == NULL ) {
  515. Win32Err = ERROR_NOT_ENOUGH_MEMORY;
  516. } else {
  517. Win32Err = RegQueryValueEx( WinlogonHandle,
  518. DSROLEP_UPGRADE_AUTOPASSWD,
  519. 0,
  520. &Type,
  521. TempBuffer,
  522. &Length );
  523. if ( Win32Err == ERROR_SUCCESS ) {
  524. Win32Err = RegSetValueEx( WinlogonHandle,
  525. DSROLEP_UPGRADE_SAVE_PREFIX
  526. DSROLEP_UPGRADE_AUTOPASSWD,
  527. 0,
  528. Type,
  529. TempBuffer,
  530. Length );
  531. }
  532. RtlSecureZeroMemory( TempBuffer, Length );
  533. RtlFreeHeap( RtlProcessHeap(), 0, TempBuffer );
  534. }
  535. } else if ( Win32Err == ERROR_FILE_NOT_FOUND ) {
  536. Win32Err = ERROR_SUCCESS;
  537. }
  538. if ( Win32Err == ERROR_SUCCESS ) {
  539. Win32Err = DsRolepSaveUpgradePasswordForAutoLogonAsLsaSecret(NewAdminPassword);
  540. RtlSecureZeroMemory(NewAdminPassword,
  541. NewAdminPassword ? wcslen(NewAdminPassword)*sizeof(WCHAR) : 0);
  542. if ( Win32Err == ERROR_SUCCESS ) {
  543. Win32Err = RegDeleteValue( WinlogonHandle,
  544. DSROLEP_UPGRADE_AUTOPASSWD );
  545. }
  546. //If there is no autologon password value then RegDeleteValue will return
  547. // ERROR_FILE_NOT_FOUND. We shouldn't fail due to this.
  548. if ( Win32Err == ERROR_FILE_NOT_FOUND ) {
  549. Win32Err = ERROR_SUCCESS;
  550. }
  551. }
  552. }
  553. if ( Win32Err == ERROR_SUCCESS ) {
  554. //
  555. // Set the user name to be administrator
  556. //
  557. //
  558. // First, see if the value currently exists...
  559. //
  560. Length = 0;
  561. Win32Err = RegQueryValueEx( WinlogonHandle,
  562. DSROLEP_UPGRADE_DEFUSER,
  563. 0,
  564. &Type,
  565. 0,
  566. &Length );
  567. if ( Win32Err == ERROR_SUCCESS ) {
  568. TempBuffer = RtlAllocateHeap( RtlProcessHeap(), 0, Length );
  569. if ( TempBuffer == NULL ) {
  570. Win32Err = ERROR_NOT_ENOUGH_MEMORY;
  571. } else {
  572. Win32Err = RegQueryValueEx( WinlogonHandle,
  573. DSROLEP_UPGRADE_DEFUSER,
  574. 0,
  575. &Type,
  576. TempBuffer,
  577. &Length );
  578. if ( Win32Err == ERROR_SUCCESS ) {
  579. Win32Err = RegSetValueEx( WinlogonHandle,
  580. DSROLEP_UPGRADE_SAVE_PREFIX
  581. DSROLEP_UPGRADE_DEFUSER,
  582. 0,
  583. Type,
  584. TempBuffer,
  585. Length );
  586. }
  587. RtlFreeHeap( RtlProcessHeap(), 0, TempBuffer );
  588. }
  589. } else if ( Win32Err == ERROR_FILE_NOT_FOUND ) {
  590. Win32Err = ERROR_SUCCESS;
  591. }
  592. if ( Win32Err == ERROR_SUCCESS ) {
  593. Win32Err = RegSetValueEx( WinlogonHandle,
  594. DSROLEP_UPGRADE_DEFUSER,
  595. 0,
  596. REG_SZ,
  597. ( CONST PBYTE )AdminName,
  598. ( wcslen( AdminName ) + 1 ) * sizeof( WCHAR ) );
  599. }
  600. }
  601. if ( Win32Err == ERROR_SUCCESS ) {
  602. //
  603. // Set the logon domain to the machine
  604. //
  605. //
  606. // First, see if the value currently exists...
  607. //
  608. Length = 0;
  609. Win32Err = RegQueryValueEx( WinlogonHandle,
  610. DSROLEP_UPGRADE_DEFDOMAIN,
  611. 0,
  612. &Type,
  613. 0,
  614. &Length );
  615. if ( Win32Err == ERROR_SUCCESS ) {
  616. TempBuffer = RtlAllocateHeap( RtlProcessHeap(), 0, Length );
  617. if ( TempBuffer == NULL ) {
  618. Win32Err = ERROR_NOT_ENOUGH_MEMORY;
  619. } else {
  620. Win32Err = RegQueryValueEx( WinlogonHandle,
  621. DSROLEP_UPGRADE_DEFDOMAIN,
  622. 0,
  623. &Type,
  624. TempBuffer,
  625. &Length );
  626. if ( Win32Err == ERROR_SUCCESS ) {
  627. Win32Err = RegSetValueEx( WinlogonHandle,
  628. DSROLEP_UPGRADE_SAVE_PREFIX
  629. DSROLEP_UPGRADE_DEFDOMAIN,
  630. 0,
  631. Type,
  632. TempBuffer,
  633. Length );
  634. }
  635. RtlFreeHeap( RtlProcessHeap(), 0, TempBuffer );
  636. }
  637. } else if ( Win32Err == ERROR_FILE_NOT_FOUND ) {
  638. Win32Err = ERROR_SUCCESS;
  639. }
  640. if ( Win32Err == ERROR_SUCCESS ) {
  641. Win32Err = RegSetValueEx( WinlogonHandle,
  642. DSROLEP_UPGRADE_DEFDOMAIN,
  643. 0,
  644. REG_SZ,
  645. ( CONST PBYTE )ComputerName,
  646. ( wcslen( ComputerName ) + 1 ) * sizeof( WCHAR ) );
  647. }
  648. }
  649. if ( Win32Err == ERROR_SUCCESS ) {
  650. //
  651. // Finally, set dcpromo to autostart
  652. //
  653. Length = 0;
  654. Win32Err = RegQueryValueEx( WinlogonHandle,
  655. DSROLEP_UPGRADE_AUTOUSERINIT,
  656. 0, // reserved
  657. &Type,
  658. 0,
  659. &Length );
  660. if ( Win32Err == ERROR_SUCCESS ) {
  661. Length += sizeof( DSROLEP_UPGRADE_DCPROMO );
  662. if ( AnswerFile ) {
  663. Length += sizeof( DSROLEP_UPGRADE_ANSWERFILE ) +
  664. ( wcslen( AnswerFile ) * sizeof( WCHAR ) );
  665. }
  666. UserInitBuffer = RtlAllocateHeap( RtlProcessHeap(), 0,
  667. Length );
  668. if ( UserInitBuffer == NULL ) {
  669. Win32Err = ERROR_NOT_ENOUGH_MEMORY;
  670. } else {
  671. Win32Err = RegQueryValueEx( WinlogonHandle,
  672. DSROLEP_UPGRADE_AUTOUSERINIT,
  673. 0,
  674. &Type,
  675. UserInitBuffer,
  676. &Length );
  677. if ( Win32Err == ERROR_SUCCESS ) {
  678. wcscat( ( PWSTR )UserInitBuffer, DSROLEP_UPGRADE_DCPROMO );
  679. if ( AnswerFile ) {
  680. wcscat( ( PWSTR )UserInitBuffer, DSROLEP_UPGRADE_ANSWERFILE );
  681. wcscat( ( PWSTR )UserInitBuffer, AnswerFile );
  682. }
  683. Status = RegSetValueEx( WinlogonHandle,
  684. DSROLEP_UPGRADE_AUTOUSERINIT,
  685. 0,
  686. Type,
  687. UserInitBuffer,
  688. ( wcslen( ( PWSTR )UserInitBuffer ) + 1 ) *
  689. sizeof( WCHAR ) );
  690. }
  691. }
  692. RtlFreeHeap( RtlProcessHeap(), 0, UserInitBuffer );
  693. }
  694. RegCloseKey( WinlogonHandle );
  695. }
  696. }
  697. }
  698. if ( PolicyHandle ) {
  699. LsaClose( PolicyHandle );
  700. }
  701. //
  702. // Set the product types
  703. //
  704. if ( Win32Err == ERROR_SUCCESS ) {
  705. Win32Err = DsRolepSetProductType( DSROLEP_MT_STANDALONE );
  706. }
  707. if ( NewAdminPassword ) {
  708. RtlSecureZeroMemory(NewAdminPassword, (wcslen(NewAdminPassword)+1)*sizeof(WCHAR) );
  709. RtlFreeHeap( RtlProcessHeap(), 0, NewAdminPassword );
  710. }
  711. return( Win32Err );
  712. }
  713. #pragma warning(pop)
  714. DWORD
  715. DsRolepDeleteUpgradeInfo(
  716. VOID
  717. )
  718. /*++
  719. Routine Description:
  720. This function deletes the saved information
  721. Arguments:
  722. VOID
  723. Return Values:
  724. ERROR_SUCCESS - Success
  725. ERROR_NOT_ENOUGH_MEMORY - A memory allocation failed
  726. --*/
  727. {
  728. DWORD Win32Err = ERROR_SUCCESS, RestoreError = Win32Err;
  729. NTSTATUS Status;
  730. OBJECT_ATTRIBUTES ObjectAttributes;
  731. HKEY WinlogonHandle, UpgradeKey;
  732. PWSTR Remove, Next, DeletePath;
  733. PBYTE UserInitBuffer, TempBuffer;
  734. DWORD Type, Length = 0;
  735. //
  736. // Remove autostarting dcpromo
  737. //
  738. //
  739. // Open the root key
  740. //
  741. Win32Err = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  742. DSROLEP_UPGRADE_WINLOGON,
  743. 0,
  744. KEY_READ | KEY_WRITE,
  745. &WinlogonHandle );
  746. #if DBG
  747. DsRolepLogOnFailure( Win32Err,
  748. DsRolepLogPrint(( DEB_TRACE,
  749. "RegOpenKeyEx on %ws failed with %lu\n",
  750. DSROLEP_UPGRADE_WINLOGON,
  751. Win32Err )) );
  752. #endif
  753. if ( Win32Err == ERROR_SUCCESS ) {
  754. //
  755. // Stop dcpromo from autostarting...
  756. //
  757. Win32Err = RegQueryValueEx( WinlogonHandle,
  758. DSROLEP_UPGRADE_AUTOUSERINIT,
  759. 0, // reserved
  760. &Type,
  761. 0,
  762. &Length );
  763. #if DBG
  764. DsRolepLogOnFailure( Win32Err,
  765. DsRolepLogPrint(( DEB_TRACE,
  766. "RegQueryValyueEx on %ws failed with %lu\n",
  767. DSROLEP_UPGRADE_AUTOUSERINIT,
  768. Win32Err )) );
  769. #endif
  770. if ( Win32Err == ERROR_SUCCESS ) {
  771. UserInitBuffer = RtlAllocateHeap( RtlProcessHeap(), 0,
  772. Length );
  773. if ( UserInitBuffer == NULL ) {
  774. Win32Err = ERROR_NOT_ENOUGH_MEMORY;
  775. } else {
  776. Win32Err = RegQueryValueEx( WinlogonHandle,
  777. DSROLEP_UPGRADE_AUTOUSERINIT,
  778. 0,
  779. &Type,
  780. UserInitBuffer,
  781. &Length );
  782. #if DBG
  783. DsRolepLogOnFailure( Win32Err,
  784. DsRolepLogPrint(( DEB_TRACE,
  785. "RegQueryValyueEx on %ws failed with %lu\n",
  786. DSROLEP_UPGRADE_AUTOUSERINIT,
  787. Win32Err )) );
  788. #endif
  789. if ( Win32Err == ERROR_SUCCESS ) {
  790. Remove = wcsstr ( ( PWSTR )UserInitBuffer, DSROLEP_UPGRADE_DCPROMO );
  791. if ( Remove ) {
  792. Next = Remove + ( ( sizeof( DSROLEP_UPGRADE_DCPROMO ) - sizeof( WCHAR ) ) /
  793. sizeof( WCHAR ) );
  794. while ( *Next ) {
  795. *Remove++ = *Next++;
  796. }
  797. *Remove = UNICODE_NULL;
  798. Status = RegSetValueEx( WinlogonHandle,
  799. DSROLEP_UPGRADE_AUTOUSERINIT,
  800. 0,
  801. Type,
  802. UserInitBuffer,
  803. ( wcslen( ( PWSTR )UserInitBuffer ) + 1 ) *
  804. sizeof( WCHAR ) );
  805. #if DBG
  806. DsRolepLogOnFailure( Win32Err,
  807. DsRolepLogPrint(( DEB_TRACE,
  808. "RegQSetValyueEx on %ws failed with %lu\n",
  809. DSROLEP_UPGRADE_AUTOUSERINIT,
  810. Win32Err )) );
  811. #endif
  812. }
  813. }
  814. }
  815. RtlFreeHeap( RtlProcessHeap(), 0, UserInitBuffer );
  816. }
  817. if ( Win32Err == ERROR_SUCCESS ) {
  818. //
  819. // Auto logon
  820. //
  821. //
  822. // Restore the old values, if they exist
  823. //
  824. DeletePath = DSROLEP_UPGRADE_AUTOADMIN;
  825. Length = 0;
  826. Win32Err = RegQueryValueEx( WinlogonHandle,
  827. DSROLEP_UPGRADE_SAVE_PREFIX DSROLEP_UPGRADE_AUTOADMIN,
  828. 0,
  829. &Type,
  830. 0,
  831. &Length );
  832. if ( Win32Err == ERROR_SUCCESS ) {
  833. TempBuffer = RtlAllocateHeap( RtlProcessHeap(), 0, Length );
  834. if ( TempBuffer == NULL ) {
  835. Win32Err = ERROR_NOT_ENOUGH_MEMORY;
  836. } else {
  837. Win32Err = RegQueryValueEx( WinlogonHandle,
  838. DSROLEP_UPGRADE_SAVE_PREFIX
  839. DSROLEP_UPGRADE_AUTOADMIN,
  840. 0,
  841. &Type,
  842. TempBuffer,
  843. &Length );
  844. if ( Win32Err == ERROR_SUCCESS ) {
  845. Win32Err = RegSetValueEx( WinlogonHandle,
  846. DSROLEP_UPGRADE_AUTOADMIN,
  847. 0,
  848. Type,
  849. TempBuffer,
  850. Length );
  851. RegDeleteValue( WinlogonHandle,
  852. DSROLEP_UPGRADE_SAVE_PREFIX DSROLEP_UPGRADE_AUTOADMIN );
  853. }
  854. RtlFreeHeap( RtlProcessHeap(), 0, TempBuffer );
  855. }
  856. } else if ( Win32Err == ERROR_FILE_NOT_FOUND ) {
  857. Win32Err = RegDeleteValue( WinlogonHandle, DeletePath );
  858. DsRolepLogOnFailure( Win32Err,
  859. DsRolepLogPrint(( DEB_TRACE,
  860. "RegDeleteKey on %ws failed with %lu\n",
  861. DeletePath,
  862. Win32Err )) );
  863. //
  864. // An error here is not considered fatal...
  865. //
  866. Win32Err = ERROR_SUCCESS;
  867. }
  868. //
  869. // Restore the default user logon name
  870. //
  871. DeletePath = DSROLEP_UPGRADE_DEFUSER;
  872. Length = 0;
  873. Win32Err = RegQueryValueEx( WinlogonHandle,
  874. DSROLEP_UPGRADE_SAVE_PREFIX DSROLEP_UPGRADE_DEFUSER,
  875. 0,
  876. &Type,
  877. 0,
  878. &Length );
  879. if ( Win32Err == ERROR_SUCCESS ) {
  880. TempBuffer = RtlAllocateHeap( RtlProcessHeap(), 0, Length );
  881. if ( TempBuffer == NULL ) {
  882. Win32Err = ERROR_NOT_ENOUGH_MEMORY;
  883. } else {
  884. Win32Err = RegQueryValueEx( WinlogonHandle,
  885. DSROLEP_UPGRADE_SAVE_PREFIX
  886. DSROLEP_UPGRADE_DEFUSER,
  887. 0,
  888. &Type,
  889. TempBuffer,
  890. &Length );
  891. if ( Win32Err == ERROR_SUCCESS ) {
  892. Win32Err = RegSetValueEx( WinlogonHandle,
  893. DSROLEP_UPGRADE_DEFUSER,
  894. 0,
  895. Type,
  896. TempBuffer,
  897. Length );
  898. RegDeleteValue( WinlogonHandle,
  899. DSROLEP_UPGRADE_SAVE_PREFIX DSROLEP_UPGRADE_DEFUSER );
  900. }
  901. RtlFreeHeap( RtlProcessHeap(), 0, TempBuffer );
  902. }
  903. } else if ( Win32Err == ERROR_FILE_NOT_FOUND ) {
  904. Win32Err = RegDeleteValue( WinlogonHandle, DeletePath );
  905. DsRolepLogOnFailure( Win32Err,
  906. DsRolepLogPrint(( DEB_TRACE,
  907. "RegDeleteKey on %ws failed with %lu\n",
  908. DeletePath,
  909. Win32Err )) );
  910. //
  911. // An error here is not considered fatal...
  912. //
  913. Win32Err = ERROR_SUCCESS;
  914. }
  915. //
  916. // Restore the default domain name
  917. //
  918. DeletePath = DSROLEP_UPGRADE_DEFDOMAIN;
  919. Length = 0;
  920. Win32Err = RegQueryValueEx( WinlogonHandle,
  921. DSROLEP_UPGRADE_SAVE_PREFIX DSROLEP_UPGRADE_DEFDOMAIN,
  922. 0,
  923. &Type,
  924. 0,
  925. &Length );
  926. if ( Win32Err == ERROR_SUCCESS ) {
  927. TempBuffer = RtlAllocateHeap( RtlProcessHeap(), 0, Length );
  928. if ( TempBuffer == NULL ) {
  929. Win32Err = ERROR_NOT_ENOUGH_MEMORY;
  930. } else {
  931. Win32Err = RegQueryValueEx( WinlogonHandle,
  932. DSROLEP_UPGRADE_SAVE_PREFIX
  933. DSROLEP_UPGRADE_DEFDOMAIN,
  934. 0,
  935. &Type,
  936. TempBuffer,
  937. &Length );
  938. if ( Win32Err == ERROR_SUCCESS ) {
  939. Win32Err = RegSetValueEx( WinlogonHandle,
  940. DSROLEP_UPGRADE_DEFDOMAIN,
  941. 0,
  942. Type,
  943. TempBuffer,
  944. Length );
  945. RegDeleteValue( WinlogonHandle,
  946. DSROLEP_UPGRADE_SAVE_PREFIX DSROLEP_UPGRADE_DEFDOMAIN );
  947. }
  948. RtlFreeHeap( RtlProcessHeap(), 0, TempBuffer );
  949. }
  950. } else if ( Win32Err == ERROR_FILE_NOT_FOUND ) {
  951. Win32Err = RegDeleteValue( WinlogonHandle, DeletePath );
  952. DsRolepLogOnFailure( Win32Err,
  953. DsRolepLogPrint(( DEB_TRACE,
  954. "RegDeleteKey on %ws failed with %lu\n",
  955. DeletePath,
  956. Win32Err )) );
  957. //
  958. // An error here is not considered fatal...
  959. //
  960. Win32Err = ERROR_SUCCESS;
  961. }
  962. if ( Win32Err == ERROR_SUCCESS ) {
  963. //
  964. // Delete the account password
  965. //
  966. Win32Err = DsRolepClearLsaSecretAutoLogonPassword();
  967. Length = 0;
  968. Win32Err = RegQueryValueEx( WinlogonHandle,
  969. DSROLEP_UPGRADE_SAVE_PREFIX
  970. DSROLEP_UPGRADE_AUTOPASSWD,
  971. 0,
  972. &Type,
  973. 0,
  974. &Length );
  975. if ( Win32Err == ERROR_SUCCESS ) {
  976. TempBuffer = RtlAllocateHeap( RtlProcessHeap(), 0, Length );
  977. if ( TempBuffer == NULL ) {
  978. Win32Err = ERROR_NOT_ENOUGH_MEMORY;
  979. } else {
  980. Win32Err = RegQueryValueEx( WinlogonHandle,
  981. DSROLEP_UPGRADE_SAVE_PREFIX
  982. DSROLEP_UPGRADE_AUTOPASSWD,
  983. 0,
  984. &Type,
  985. TempBuffer,
  986. &Length );
  987. if ( Win32Err == ERROR_SUCCESS ) {
  988. Win32Err = RegSetValueEx( WinlogonHandle,
  989. DSROLEP_UPGRADE_AUTOPASSWD,
  990. 0,
  991. Type,
  992. TempBuffer,
  993. Length );
  994. RegDeleteValue( WinlogonHandle,
  995. DSROLEP_UPGRADE_SAVE_PREFIX
  996. DSROLEP_UPGRADE_AUTOPASSWD );
  997. }
  998. RtlFreeHeap( RtlProcessHeap(), 0, TempBuffer );
  999. }
  1000. } else if ( Win32Err == ERROR_FILE_NOT_FOUND ) {
  1001. DeletePath = DSROLEP_UPGRADE_AUTOPASSWD;
  1002. Win32Err = RegDeleteValue( WinlogonHandle, DeletePath );
  1003. DsRolepLogOnFailure( Win32Err,
  1004. DsRolepLogPrint(( DEB_TRACE,
  1005. "RegDeleteKey on %ws failed with %lu\n",
  1006. DeletePath,
  1007. Win32Err )) );
  1008. //
  1009. // An error here is not considered fatal...
  1010. //
  1011. Win32Err = ERROR_SUCCESS;
  1012. }
  1013. }
  1014. if ( Win32Err != ERROR_SUCCESS ) {
  1015. //
  1016. // Raise an event
  1017. //
  1018. SpmpReportEvent( TRUE,
  1019. EVENTLOG_WARNING_TYPE,
  1020. DSROLERES_FAIL_DISABLE_AUTO_LOGON,
  1021. 0,
  1022. sizeof( ULONG ),
  1023. &Win32Err,
  1024. 1,
  1025. DeletePath );
  1026. DSROLEP_SET_NON_FATAL_ERROR( Win32Err );
  1027. Win32Err = ERROR_SUCCESS;
  1028. }
  1029. }
  1030. RegCloseKey( WinlogonHandle );
  1031. }
  1032. //
  1033. // Delete the registry key that LSA uses to determine if this is an upgrade
  1034. //
  1035. //
  1036. // Open the key
  1037. //
  1038. if ( Win32Err == ERROR_SUCCESS ) {
  1039. Win32Err = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  1040. DSROLEP_UPGRADE_KEY,
  1041. 0,
  1042. DELETE | KEY_SET_VALUE,
  1043. &UpgradeKey );
  1044. #if DBG
  1045. DsRolepLogOnFailure( Win32Err,
  1046. DsRolepLogPrint(( DEB_TRACE,
  1047. "RegOpenKey on %ws failed with %lu\n",
  1048. DSROLEP_UPGRADE_KEY,
  1049. Win32Err )) );
  1050. #endif
  1051. if ( Win32Err == ERROR_SUCCESS ) {
  1052. Win32Err = RegDeleteValue( UpgradeKey, DSROLEP_UPGRADE_VALUE );
  1053. if ( ERROR_FILE_NOT_FOUND == Win32Err ) {
  1054. // This is ok.
  1055. Win32Err = ERROR_SUCCESS;
  1056. }
  1057. #if DBG
  1058. DsRolepLogOnFailure( Win32Err,
  1059. DsRolepLogPrint(( DEB_TRACE,
  1060. "RegDeleteKey on %ws failed with %lu\n",
  1061. DSROLEP_UPGRADE_KEY,
  1062. Win32Err )) );
  1063. #endif
  1064. RegCloseKey( UpgradeKey );
  1065. }
  1066. }
  1067. //
  1068. // Finally remove the nt4 LSA information
  1069. //
  1070. //
  1071. // Remove the nt4 LSA stuff that has been put into the registry
  1072. //
  1073. LsapDsUnitializeDsStateInfo();
  1074. Status = LsaIUpgradeRegistryToDs( TRUE );
  1075. RestoreError = RtlNtStatusToDosError( Status );
  1076. DsRolepLogOnFailure( RestoreError,
  1077. DsRolepLogPrint(( DEB_WARN,
  1078. "Failed to cleanup NT4 LSA (%d)\n",
  1079. RestoreError )) );
  1080. if ( ERROR_SUCCESS != RestoreError
  1081. && ERROR_SUCCESS == Win32Err ) {
  1082. Win32Err = RestoreError;
  1083. }
  1084. return( Win32Err );
  1085. }
  1086. DWORD
  1087. DsRolepQueryUpgradeInfo(
  1088. OUT PBOOLEAN IsUpgrade,
  1089. OUT PULONG ServerRole
  1090. )
  1091. /*++
  1092. Routine Description:
  1093. This function queries the current update information.
  1094. Arguments:
  1095. IsUpgrade - A pointer to a BOOLEAN to hold a value of TRUE if there is upgrade information
  1096. saved away, or a FALSE if not
  1097. ServerRole - If this is an upgrade, the previous server role is returned here.
  1098. Return Values:
  1099. ERROR_SUCCESS - Success
  1100. --*/
  1101. {
  1102. DWORD Win32Err = ERROR_SUCCESS;
  1103. HKEY UpgradeKey;
  1104. ULONG Type, Length = sizeof( ULONG );
  1105. //
  1106. // Open the upgrade key
  1107. //
  1108. Win32Err = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  1109. DSROLEP_UPGRADE_KEY,
  1110. 0,
  1111. KEY_READ | KEY_WRITE,
  1112. &UpgradeKey );
  1113. if ( Win32Err == ERROR_SUCCESS ) {
  1114. //
  1115. // Finally, set dcpromo to autostart
  1116. //
  1117. Win32Err = RegQueryValueEx( UpgradeKey,
  1118. DSROLEP_UPGRADE_VALUE,
  1119. 0, // reserved
  1120. &Type,
  1121. ( PBYTE )ServerRole,
  1122. &Length );
  1123. if ( Win32Err == ERROR_SUCCESS ) {
  1124. *IsUpgrade = TRUE;
  1125. }
  1126. RegCloseKey( UpgradeKey );
  1127. }
  1128. if ( Win32Err == ERROR_FILE_NOT_FOUND ) {
  1129. Win32Err = ERROR_SUCCESS;
  1130. *IsUpgrade = FALSE;
  1131. }
  1132. return( Win32Err );
  1133. }
  1134. DWORD
  1135. DsRolepGetBuiltinAdminAccountName(
  1136. OUT LPWSTR *BuiltinAdmin
  1137. )
  1138. /*++
  1139. Routine Description:
  1140. This routine finds the alias name for the builtin user account ADMINISTRATOR
  1141. Arguments:
  1142. BuiltinAdmin - Where the admin name is returned
  1143. Return Values:
  1144. ERROR_SUCCESS - Success
  1145. ERROR_NOT_ENOUGH_MEMORY - A memory allocation failed
  1146. --*/
  1147. {
  1148. DWORD Win32Err = ERROR_SUCCESS;
  1149. SID_IDENTIFIER_AUTHORITY UaspNtAuthority = SECURITY_NT_AUTHORITY;
  1150. DWORD SidBuff[ sizeof( SID ) / sizeof( DWORD ) + 5];
  1151. PSID Sid = ( PSID )SidBuff;
  1152. SID_NAME_USE SNE;
  1153. LPWSTR Domain = NULL;
  1154. LPWSTR Name = NULL;
  1155. ULONG NameLen = 0, DomainLen = 0;
  1156. //
  1157. // Build the sid
  1158. //
  1159. RtlInitializeSid( Sid, &UaspNtAuthority, 2 );
  1160. *( RtlSubAuthoritySid( Sid, 0 ) ) = SECURITY_BUILTIN_DOMAIN_RID;
  1161. *( RtlSubAuthoritySid( Sid, 1 ) ) = DOMAIN_USER_RID_ADMIN;
  1162. if ( LookupAccountSid( NULL,
  1163. Sid,
  1164. NULL,
  1165. &NameLen,
  1166. NULL,
  1167. &DomainLen,
  1168. &SNE ) == FALSE ) {
  1169. Win32Err = GetLastError();
  1170. if ( Win32Err == ERROR_INSUFFICIENT_BUFFER ) {
  1171. Win32Err = ERROR_SUCCESS;
  1172. Name = RtlAllocateHeap( RtlProcessHeap(), 0, NameLen * sizeof( WCHAR ) );
  1173. Domain = RtlAllocateHeap( RtlProcessHeap(), 0, DomainLen * sizeof( WCHAR ) );
  1174. if ( !Name || !Domain ) {
  1175. Win32Err = ERROR_NOT_ENOUGH_MEMORY;
  1176. } else {
  1177. if ( LookupAccountSid( NULL,
  1178. Sid,
  1179. Name,
  1180. &NameLen,
  1181. Domain,
  1182. &DomainLen,
  1183. &SNE ) == FALSE ) {
  1184. Win32Err = GetLastError();
  1185. }
  1186. }
  1187. }
  1188. }
  1189. if ( Win32Err != ERROR_SUCCESS ) {
  1190. RtlFreeHeap( RtlProcessHeap(), 0, Domain );
  1191. RtlFreeHeap( RtlProcessHeap(), 0, Name );
  1192. }
  1193. return( Win32Err );
  1194. }
  1195. DWORD
  1196. DsRolepSetBuiltinAdminAccountPassword(
  1197. IN LPWSTR Password
  1198. )
  1199. /*++
  1200. Routine Description:
  1201. This routine will change the password on the builtin administrator account to the one
  1202. specified
  1203. Arguments:
  1204. Password - Password to set
  1205. Return Values:
  1206. ERROR_SUCCESS - Success
  1207. --*/
  1208. {
  1209. NTSTATUS Status = STATUS_SUCCESS;
  1210. SAM_HANDLE SamHandle, SamDomainHandle, SamAdministrator;
  1211. PPOLICY_ACCOUNT_DOMAIN_INFO AccountDomainInfo;
  1212. LSA_HANDLE PolicyHandle;
  1213. USER_ALL_INFORMATION UserAllInfo;
  1214. OBJECT_ATTRIBUTES ObjectAttributes;
  1215. UNICODE_STRING UserPassword;
  1216. RtlZeroMemory( &ObjectAttributes, sizeof( ObjectAttributes ) );
  1217. Status = LsaOpenPolicy( NULL,
  1218. &ObjectAttributes,
  1219. POLICY_VIEW_LOCAL_INFORMATION,
  1220. &PolicyHandle );
  1221. if ( NT_SUCCESS( Status ) ) {
  1222. Status = LsaQueryInformationPolicy( PolicyHandle,
  1223. PolicyAccountDomainInformation,
  1224. ( PVOID * )&AccountDomainInfo );
  1225. LsaClose( PolicyHandle );
  1226. }
  1227. if ( NT_SUCCESS( Status ) ) {
  1228. Status = SamConnect( NULL,
  1229. &SamHandle,
  1230. MAXIMUM_ALLOWED,
  1231. &ObjectAttributes );
  1232. if ( NT_SUCCESS( Status ) ) {
  1233. //
  1234. // Open the builtin domain
  1235. //
  1236. Status = SamOpenDomain( SamHandle,
  1237. MAXIMUM_ALLOWED,
  1238. AccountDomainInfo->DomainSid,
  1239. &SamDomainHandle );
  1240. if ( NT_SUCCESS( Status ) ) {
  1241. Status = SamOpenUser( SamDomainHandle,
  1242. MAXIMUM_ALLOWED,
  1243. DOMAIN_USER_RID_ADMIN,
  1244. &SamAdministrator );
  1245. if ( NT_SUCCESS( Status ) ) {
  1246. RtlZeroMemory( &UserAllInfo, sizeof( USER_ALL_INFORMATION ) );
  1247. RtlInitUnicodeString( &UserPassword, Password );
  1248. UserAllInfo.NtPassword = UserPassword;
  1249. UserAllInfo.NtPasswordPresent = TRUE;
  1250. UserAllInfo.WhichFields = USER_ALL_NTPASSWORDPRESENT;
  1251. Status = SamSetInformationUser( SamAdministrator,
  1252. UserAllInformation,
  1253. ( PSAMPR_USER_INFO_BUFFER )&UserAllInfo );
  1254. SamCloseHandle( SamAdministrator );
  1255. }
  1256. SamCloseHandle( SamDomainHandle );
  1257. }
  1258. SamCloseHandle( SamHandle );
  1259. }
  1260. LsaFreeMemory( AccountDomainInfo );
  1261. }
  1262. return( RtlNtStatusToDosError( Status ) );
  1263. }