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.

1920 lines
58 KiB

  1. #include "stdafx.h"
  2. #include <ole2.h>
  3. #include "iadm.h"
  4. #include "iiscnfgp.h"
  5. #include "mdkey.h"
  6. #include "mdacl.h"
  7. #include "inetinfo.h"
  8. #include "log.h"
  9. #include "svc.h"
  10. #include "dcomperm.h"
  11. #include "setpass.h"
  12. #include "comncomp.hxx"
  13. #include <comadmin.h> // CLSID_COMAdminCatalog
  14. #include <Sddl.h>
  15. #include <acl.hxx>
  16. #include "webcomp.hxx"
  17. typedef TCHAR USERNAME_STRING_TYPE[MAX_PATH];
  18. typedef TCHAR PASSWORD_STRING_TYPE[LM20_PWLEN+1];
  19. typedef enum {
  20. GUFM_SUCCESS,
  21. GUFM_NO_PATH,
  22. GUFM_NO_PASSWORD,
  23. GUFM_NO_USER_ID
  24. } GUFM_RETURN;
  25. #define OPEN_TIMEOUT_VALUE 30000
  26. #define MD_SET_DATA_RECORD_EXT(PMDR, ID, ATTR, UTYPE, DTYPE, DLEN, PD) \
  27. { \
  28. (PMDR)->dwMDIdentifier=ID; \
  29. (PMDR)->dwMDAttributes=ATTR; \
  30. (PMDR)->dwMDUserType=UTYPE; \
  31. (PMDR)->dwMDDataType=DTYPE; \
  32. (PMDR)->dwMDDataLen=DLEN; \
  33. (PMDR)->pbMDData=(PBYTE)PD; \
  34. }
  35. #define SYSPREP_TEMPFILE_NAME _T("IISSysPr.tmp")
  36. #define SYSPREP_KNOWN_SECTION_NAME _T("paths")
  37. #define SYSPREP_KNOWN_REGISTRY_KEY _T("SysPrepIISInfo")
  38. #define SYSPREP_KNOWN_REGISTRY_KEY2 _T("SysPrepIISInfoStage")
  39. #define SYSPREP_TEMP_PASSWORD_LENGTH 256
  40. #define SYSPREP_USE_SECRETS
  41. #define REG_ENABLEPASSSYNC_KEY _T("SOFTWARE\\Microsoft\\InetStp")
  42. #define REG_ENABLEPASSSYNC_VALUE _T("EnableUserAccountRestorePassSync")
  43. DWORD AddUserToMetabaseACL2( CSecurityDescriptor *pSD, LPTSTR szUserToAdd, LPTSTR szSidString, ACCESS_ALLOWED_ACE * MyACEInfo);
  44. HRESULT RemoveMetabaseACL( LPCTSTR szPath );
  45. #ifndef _CHICAGO_
  46. HRESULT
  47. UpdateComApplications(
  48. IMSAdminBase2 * pcCom,
  49. LPCTSTR szWamUserName,
  50. LPCTSTR szWamUserPass
  51. )
  52. /*++
  53. Routine Description:
  54. If the IWAM account has been modified, it is necessary to update the
  55. the out of process com+ applications with the correct account
  56. information. This routine will collect all the com+ applications and
  57. reset the activation information.
  58. Arguments:
  59. pcCom - metabase object
  60. szWamUserName - the new user name
  61. szWamUserPass - the new user password
  62. Note:
  63. This routine is a royal pain in the butt. I take back
  64. all the good things I may have said about com automation.
  65. Return Value:
  66. HRESULT - Return value from failed API call
  67. - E_OUTOFMEMORY
  68. - S_OK - everything worked
  69. - S_FALSE - encountered a non-fatal error, unable
  70. to reset at least one application.
  71. --*/
  72. {
  73. HRESULT hr = NOERROR;
  74. BOOL fNoErrors = TRUE;
  75. METADATA_HANDLE hMetabase = NULL;
  76. WCHAR * pwszDataPaths = NULL;
  77. DWORD cchDataPaths = 0;
  78. BOOL fTryAgain;
  79. DWORD cMaxApplications;
  80. WCHAR * pwszCurrentPath;
  81. SAFEARRAY * psaApplications = NULL;
  82. SAFEARRAYBOUND rgsaBound[1];
  83. DWORD cApplications;
  84. VARIANT varAppKey;
  85. LONG rgIndices[1];
  86. METADATA_RECORD mdrAppIsolated;
  87. METADATA_RECORD mdrAppPackageId;
  88. DWORD dwAppIsolated;
  89. WCHAR wszAppPackageId[ 40 ];
  90. DWORD dwMDGetDataLen = 0;
  91. ICOMAdminCatalog * pComCatalog = NULL;
  92. ICatalogCollection * pComAppCollection = NULL;
  93. ICatalogObject * pComApp = NULL;
  94. BSTR bstrAppCollectionName = NULL;
  95. LONG nAppsInCollection;
  96. LONG iCurrentApp;
  97. LONG nChanges;
  98. VARIANT varOldAppIdentity;
  99. VARIANT varNewAppIdentity;
  100. VARIANT varNewAppPassword;
  101. // This is built unicode right now. Since all the com apis I need
  102. // are unicode only I'm using wide characters here. I should get
  103. // plenty of compiler errors if _UNICODE isn't defined, but just
  104. // in case....
  105. DBG_ASSERT( sizeof(TCHAR) == sizeof(WCHAR) );
  106. iisDebugOut((LOG_TYPE_TRACE, _T("UpdateComApplications():start\n")));
  107. // Init variants
  108. VariantInit( &varAppKey );
  109. VariantInit( &varOldAppIdentity );
  110. VariantInit( &varNewAppIdentity );
  111. VariantInit( &varNewAppPassword );
  112. //
  113. // Get the applications to be reset by querying the metabase paths
  114. //
  115. hr = pcCom->OpenKey( METADATA_MASTER_ROOT_HANDLE,
  116. L"LM/W3SVC",
  117. METADATA_PERMISSION_READ,
  118. OPEN_TIMEOUT_VALUE,
  119. &hMetabase
  120. );
  121. if( FAILED(hr) )
  122. {
  123. iisDebugOut((LOG_TYPE_ERROR, _T("Failed to open metabase (%08x)\n"),hr));
  124. goto cleanup;
  125. }
  126. // Get the data paths string
  127. fTryAgain = TRUE;
  128. do
  129. {
  130. hr = pcCom->GetDataPaths( hMetabase,
  131. NULL,
  132. MD_APP_PACKAGE_ID,
  133. STRING_METADATA,
  134. cchDataPaths,
  135. pwszDataPaths,
  136. &cchDataPaths
  137. );
  138. if( HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER) == hr )
  139. {
  140. delete[] pwszDataPaths;
  141. pwszDataPaths = NULL;
  142. pwszDataPaths = new WCHAR[cchDataPaths];
  143. if( !pwszDataPaths )
  144. {
  145. hr = E_OUTOFMEMORY;
  146. goto cleanup;
  147. }
  148. }
  149. else
  150. {
  151. fTryAgain = FALSE;
  152. }
  153. }
  154. while( fTryAgain );
  155. if( FAILED(hr) )
  156. {
  157. iisDebugOut((LOG_TYPE_ERROR, _T("Failed to find metadata (%08x) Data(%d)\n"),hr,MD_APP_PACKAGE_ID));
  158. goto cleanup;
  159. }
  160. else if (pwszDataPaths == NULL)
  161. {
  162. //
  163. // If we found no isolated apps, make the path list an empty multisz
  164. //
  165. cchDataPaths = 1;
  166. pwszDataPaths = new WCHAR[cchDataPaths];
  167. if( !pwszDataPaths )
  168. {
  169. hr = E_OUTOFMEMORY;
  170. goto cleanup;
  171. }
  172. pwszDataPaths[0] = L'\0';
  173. }
  174. // Determine the maximum number of applications
  175. cMaxApplications = 1; // The pooled application
  176. for( pwszCurrentPath = pwszDataPaths;
  177. *pwszCurrentPath != L'\0';
  178. pwszCurrentPath += wcslen(pwszCurrentPath) + 1
  179. )
  180. {
  181. cMaxApplications++;
  182. }
  183. //
  184. // Build a key array and load the com applications.
  185. //
  186. // Create an array to hold the keys
  187. rgsaBound[0].cElements = cMaxApplications;
  188. rgsaBound[0].lLbound = 0;
  189. psaApplications = SafeArrayCreate( VT_VARIANT, 1, rgsaBound );
  190. if( psaApplications == NULL )
  191. {
  192. hr = E_OUTOFMEMORY;
  193. goto cleanup;
  194. }
  195. // Set the out of process pool application key
  196. varAppKey.vt = VT_BSTR;
  197. varAppKey.bstrVal = SysAllocString( W3_OOP_POOL_PACKAGE_ID );
  198. if( !varAppKey.bstrVal )
  199. {
  200. hr = E_OUTOFMEMORY;
  201. goto cleanup;
  202. }
  203. rgIndices[0] = 0;
  204. hr = SafeArrayPutElement( psaApplications, rgIndices, &varAppKey );
  205. if( FAILED(hr) )
  206. {
  207. iisDebugOut((LOG_TYPE_ERROR, _T("Failed setting an element in a safe array (%08x)\n"),hr));
  208. goto cleanup;
  209. }
  210. // For each of the application paths determine if an out of process
  211. // application is defined there and set the appropriate key into
  212. // our array
  213. MD_SET_DATA_RECORD_EXT( &mdrAppIsolated,
  214. MD_APP_ISOLATED,
  215. METADATA_NO_ATTRIBUTES,
  216. ALL_METADATA,
  217. DWORD_METADATA,
  218. sizeof(DWORD),
  219. (PBYTE)&dwAppIsolated
  220. );
  221. MD_SET_DATA_RECORD_EXT( &mdrAppPackageId,
  222. MD_APP_PACKAGE_ID,
  223. METADATA_NO_ATTRIBUTES,
  224. ALL_METADATA,
  225. STRING_METADATA,
  226. sizeof(wszAppPackageId),
  227. (PBYTE)wszAppPackageId
  228. );
  229. wszAppPackageId[0] = L'\0';
  230. // Go through each data path and set it into our array if
  231. // it is an isolated application
  232. cApplications = 1; // Actual # of applications - 1 for pool
  233. for( pwszCurrentPath = pwszDataPaths;
  234. *pwszCurrentPath != L'\0';
  235. pwszCurrentPath += wcslen(pwszCurrentPath) + 1
  236. )
  237. {
  238. hr = pcCom->GetData( hMetabase,
  239. pwszCurrentPath,
  240. &mdrAppIsolated,
  241. &dwMDGetDataLen
  242. );
  243. if( FAILED(hr) )
  244. {
  245. iisDebugOut(( LOG_TYPE_ERROR,
  246. _T("Failed to get data from the metabase (%08x) Path(%S) Data(%d)\n"),
  247. hr,
  248. pwszCurrentPath,
  249. mdrAppIsolated.dwMDIdentifier
  250. ));
  251. fNoErrors = FALSE;
  252. continue;
  253. }
  254. // Is the application out of process
  255. if( dwAppIsolated == 1 )
  256. {
  257. // Get the application id
  258. hr = pcCom->GetData( hMetabase,
  259. pwszCurrentPath,
  260. &mdrAppPackageId,
  261. &dwMDGetDataLen
  262. );
  263. if( FAILED(hr) )
  264. {
  265. iisDebugOut(( LOG_TYPE_ERROR,
  266. _T("Failed to get data from the metabase (%08x) Path(%S) Data(%d)\n"),
  267. hr,
  268. pwszCurrentPath,
  269. mdrAppPackageId.dwMDIdentifier
  270. ));
  271. fNoErrors = FALSE;
  272. continue;
  273. }
  274. // Add the application id to the array
  275. VariantClear( &varAppKey );
  276. varAppKey.vt = VT_BSTR;
  277. varAppKey.bstrVal = SysAllocString( wszAppPackageId );
  278. if( !varAppKey.bstrVal )
  279. {
  280. hr = E_OUTOFMEMORY;
  281. goto cleanup;
  282. }
  283. rgIndices[0]++;
  284. hr = SafeArrayPutElement( psaApplications,
  285. rgIndices,
  286. &varAppKey
  287. );
  288. if( FAILED(hr) )
  289. {
  290. iisDebugOut(( LOG_TYPE_ERROR,
  291. _T("Failed to set safe array element (%08x)\n"),
  292. hr
  293. ));
  294. VariantClear( &varAppKey );
  295. rgIndices[0]--;
  296. fNoErrors = FALSE;
  297. continue;
  298. }
  299. cApplications++;
  300. }
  301. }
  302. // Done with the metabase
  303. pcCom->CloseKey(hMetabase);
  304. hMetabase = NULL;
  305. // Shrink the size of the safe-array if necessary
  306. if( cApplications < cMaxApplications )
  307. {
  308. rgsaBound[0].cElements = cApplications;
  309. hr = SafeArrayRedim( psaApplications, rgsaBound );
  310. if( FAILED(hr) )
  311. {
  312. iisDebugOut(( LOG_TYPE_ERROR,
  313. _T("Failed to redim safe array (%08x)\n"),
  314. hr
  315. ));
  316. goto cleanup;
  317. }
  318. }
  319. //
  320. // For each application reset the activation identity
  321. //
  322. // Use our key array to get the application collection
  323. hr = CoCreateInstance( CLSID_COMAdminCatalog,
  324. NULL,
  325. CLSCTX_SERVER,
  326. IID_ICOMAdminCatalog,
  327. (void**)&pComCatalog
  328. );
  329. if( FAILED(hr) )
  330. {
  331. iisDebugOut(( LOG_TYPE_ERROR,
  332. _T("Failed to create COM catalog (%08x)\n"),
  333. hr
  334. ));
  335. goto cleanup;
  336. }
  337. hr = pComCatalog->GetCollection( L"Applications",
  338. (IDispatch **)&pComAppCollection
  339. );
  340. if( FAILED(hr) )
  341. {
  342. iisDebugOut(( LOG_TYPE_ERROR,
  343. _T("Failed to get Applications collection (%08x)\n"),
  344. hr
  345. ));
  346. goto cleanup;
  347. }
  348. hr = pComAppCollection->PopulateByKey( psaApplications );
  349. if( FAILED(hr) )
  350. {
  351. iisDebugOut(( LOG_TYPE_ERROR,
  352. _T("Failed to populate Applications collection (%08x)\n"),
  353. hr
  354. ));
  355. goto cleanup;
  356. }
  357. // Iterate over the application collection and update all the
  358. // applications that use IWAM.
  359. hr = pComAppCollection->get_Count( &nAppsInCollection );
  360. if( FAILED(hr) )
  361. {
  362. iisDebugOut(( LOG_TYPE_ERROR,
  363. _T("Failed to get Applications count (%08x)\n"),
  364. hr
  365. ));
  366. goto cleanup;
  367. }
  368. // Init our new app identity and password.
  369. varNewAppIdentity.vt = VT_BSTR;
  370. varNewAppIdentity.bstrVal = SysAllocString( szWamUserName );
  371. if( !varNewAppIdentity.bstrVal )
  372. {
  373. hr = E_OUTOFMEMORY;
  374. goto cleanup;
  375. }
  376. varNewAppPassword.vt = VT_BSTR;
  377. varNewAppPassword.bstrVal = SysAllocString( szWamUserPass );
  378. if( !varNewAppPassword.bstrVal )
  379. {
  380. hr = E_OUTOFMEMORY;
  381. goto cleanup;
  382. }
  383. for( iCurrentApp = 0; iCurrentApp < nAppsInCollection; ++iCurrentApp )
  384. {
  385. if( pComApp )
  386. {
  387. pComApp->Release();
  388. pComApp = NULL;
  389. }
  390. if( varOldAppIdentity.vt != VT_EMPTY )
  391. {
  392. VariantClear( &varOldAppIdentity );
  393. }
  394. hr = pComAppCollection->get_Item( iCurrentApp,
  395. (IDispatch **)&pComApp );
  396. if( FAILED(hr) )
  397. {
  398. iisDebugOut(( LOG_TYPE_ERROR,
  399. _T("Failed to get item from Applications collection (%08x)\n"),
  400. hr
  401. ));
  402. fNoErrors = FALSE;
  403. continue;
  404. }
  405. // If the user has set this to something other than the IWAM_
  406. // user, then we will respect that and not reset the identiy.
  407. hr = pComApp->get_Value( L"Identity", &varOldAppIdentity );
  408. if( FAILED(hr) )
  409. {
  410. iisDebugOut(( LOG_TYPE_ERROR,
  411. _T("Failed to get Identify from Application (%08x)\n"),
  412. hr
  413. ));
  414. fNoErrors = FALSE;
  415. continue;
  416. }
  417. DBG_ASSERT( varOldAppIdentity.vt == VT_BSTR );
  418. if( varOldAppIdentity.vt == VT_BSTR )
  419. {
  420. if( memcmp( L"IWAM_", varOldAppIdentity.bstrVal, 10 ) == 0 )
  421. {
  422. hr = pComApp->put_Value( L"Identity", varNewAppIdentity );
  423. if( FAILED(hr) )
  424. {
  425. iisDebugOut(( LOG_TYPE_ERROR,
  426. _T("Failed to set new Identify (%08x)\n"),
  427. hr
  428. ));
  429. fNoErrors = FALSE;
  430. continue;
  431. }
  432. hr = pComApp->put_Value( L"Password", varNewAppPassword );
  433. if( FAILED(hr) )
  434. {
  435. iisDebugOut(( LOG_TYPE_ERROR,
  436. _T("Failed to set new Password (%08x)\n"),
  437. hr
  438. ));
  439. fNoErrors = FALSE;
  440. continue;
  441. }
  442. }
  443. else
  444. {
  445. DBGINFO(( DBG_CONTEXT,
  446. "Unrecognized application identity (%S)\n",
  447. varOldAppIdentity.bstrVal
  448. ));
  449. }
  450. }
  451. }
  452. hr = pComAppCollection->SaveChanges( &nChanges );
  453. if( FAILED(hr) )
  454. {
  455. iisDebugOut(( LOG_TYPE_ERROR,
  456. _T("Failed to save changes (%08x)\n"),
  457. hr
  458. ));
  459. goto cleanup;
  460. }
  461. goto cleanup;
  462. cleanup:
  463. if( hMetabase != NULL )
  464. {
  465. pcCom->CloseKey(hMetabase);
  466. }
  467. if( psaApplications != NULL )
  468. {
  469. SafeArrayDestroy( psaApplications );
  470. }
  471. if( pComCatalog != NULL )
  472. {
  473. pComCatalog->Release();
  474. }
  475. if( pComAppCollection != NULL )
  476. {
  477. pComAppCollection->Release();
  478. }
  479. if( pComApp != NULL )
  480. {
  481. pComApp->Release();
  482. }
  483. if( varAppKey.vt != VT_EMPTY )
  484. {
  485. VariantClear( &varAppKey );
  486. }
  487. if( varOldAppIdentity.vt != VT_EMPTY )
  488. {
  489. VariantClear( &varOldAppIdentity );
  490. }
  491. if( varNewAppIdentity.vt != VT_EMPTY )
  492. {
  493. VariantClear( &varNewAppIdentity );
  494. }
  495. if( varNewAppPassword.vt != VT_EMPTY )
  496. {
  497. VariantClear( &varNewAppPassword );
  498. }
  499. delete [] pwszDataPaths;
  500. iisDebugOut((LOG_TYPE_TRACE, _T("UpdateComApplications():end\n")));
  501. // return
  502. if( FAILED(hr) )
  503. {
  504. return hr;
  505. }
  506. else if( fNoErrors == FALSE )
  507. {
  508. return S_FALSE;
  509. }
  510. else
  511. {
  512. return S_OK;
  513. }
  514. }
  515. GUFM_RETURN GetUserFromMetabase(IMSAdminBase2 *pcCom,
  516. LPWSTR pszPath,
  517. DWORD dwUserMetaId,
  518. DWORD dwPasswordMetaId,
  519. USERNAME_STRING_TYPE ustUserBuf,
  520. PASSWORD_STRING_TYPE pstPasswordBuf)
  521. {
  522. HRESULT hresTemp;
  523. GUFM_RETURN gufmReturn = GUFM_SUCCESS;
  524. METADATA_RECORD mdrData;
  525. DWORD dwRequiredDataLen;
  526. METADATA_HANDLE mhOpenHandle;
  527. hresTemp = pcCom->OpenKey(METADATA_MASTER_ROOT_HANDLE,
  528. pszPath,
  529. METADATA_PERMISSION_READ,
  530. OPEN_TIMEOUT_VALUE,
  531. &mhOpenHandle);
  532. if (FAILED(hresTemp)) {
  533. gufmReturn = GUFM_NO_PATH;
  534. }
  535. else {
  536. MD_SET_DATA_RECORD_EXT(&mdrData,
  537. dwUserMetaId,
  538. METADATA_NO_ATTRIBUTES,
  539. ALL_METADATA,
  540. STRING_METADATA,
  541. MAX_PATH * sizeof(TCHAR),
  542. (PBYTE)ustUserBuf)
  543. hresTemp = pcCom->GetData(mhOpenHandle,
  544. NULL,
  545. &mdrData,
  546. &dwRequiredDataLen);
  547. if (FAILED(hresTemp) || (ustUserBuf[0] == (TCHAR)'\0')) {
  548. gufmReturn = GUFM_NO_USER_ID;
  549. }
  550. else {
  551. MD_SET_DATA_RECORD_EXT(&mdrData,
  552. dwPasswordMetaId,
  553. METADATA_NO_ATTRIBUTES,
  554. ALL_METADATA,
  555. STRING_METADATA,
  556. MAX_PATH * sizeof(TCHAR),
  557. (PBYTE)pstPasswordBuf)
  558. hresTemp = pcCom->GetData(mhOpenHandle,
  559. NULL,
  560. &mdrData,
  561. &dwRequiredDataLen);
  562. if (FAILED(hresTemp)) {
  563. gufmReturn = GUFM_NO_PASSWORD;
  564. }
  565. }
  566. pcCom->CloseKey(mhOpenHandle);
  567. }
  568. return gufmReturn;
  569. }
  570. #endif
  571. // ReRegisterDav
  572. //
  573. // This will re-register Dav. This is need after sysprep, so that the sids in the
  574. // registry are correct.
  575. //
  576. BOOL
  577. ReregisterDav()
  578. {
  579. TSTR_PATH strDavExe;
  580. TSTR strCmdLine;
  581. if ( !strDavExe.RetrieveSystemDir() ||
  582. !strDavExe.PathAppend( _T("inetsrv") ) ||
  583. !strDavExe.PathAppend( _T("davcdata.exe") ) ||
  584. !strCmdLine.Copy( strDavExe ) ||
  585. !strCmdLine.Append( _T(" /RegServer") ) )
  586. {
  587. // Failed to construct strings
  588. return FALSE;
  589. }
  590. return RunProgram( strDavExe.QueryStr(), // Exe
  591. strCmdLine.QueryStr(), // Parameters
  592. TRUE, // Minimized
  593. 90, // Timeout, in seconds
  594. FALSE ); // Do not create new console
  595. }
  596. HRESULT WINAPI SysPrepAclSyncIWam(void)
  597. {
  598. HRESULT hr = S_OK;
  599. IMSAdminBase2 * pcCom;
  600. iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("start\n")));
  601. hr = CoCreateInstance(CLSID_MSAdminBase,NULL,CLSCTX_ALL,IID_IMSAdminBase2,(void **) & pcCom);
  602. if (SUCCEEDED(hr))
  603. {
  604. #ifndef _CHICAGO_
  605. GUFM_RETURN gufmTemp;
  606. PASSWORD_STRING_TYPE pstAnonyPass;
  607. USERNAME_STRING_TYPE ustAnonyName;
  608. pstAnonyPass[0] = (TCHAR)'\0';
  609. ustAnonyName[0] = (TCHAR)'\0';
  610. //
  611. // Get the WAM username and password
  612. //
  613. gufmTemp = GetUserFromMetabase(pcCom,
  614. TEXT("LM/W3SVC"),
  615. MD_WAM_USER_NAME,
  616. MD_WAM_PWD,
  617. ustAnonyName,
  618. pstAnonyPass);
  619. UpdateComApplications(pcCom,ustAnonyName,pstAnonyPass);
  620. #endif
  621. pcCom->Release();
  622. }
  623. // Loop thru all the acl's
  624. // and get the values, store it somewhere
  625. iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("end,ret=0x%x\n"),hr));
  626. return hr;
  627. }
  628. // function: ChangeIUsrPasswords
  629. //
  630. // Change the IUsr Passwords after you have been sysprepped
  631. //
  632. // This is three steps:
  633. // 1) Get the IUSR account name
  634. // 2) Create a new password for it
  635. // 3) Change the password at all locations with the username
  636. //
  637. BOOL ChangeIUsrPasswords()
  638. {
  639. CMDKey cmdKey;
  640. TSTR strAnonymousPrefix;
  641. CMDValue cmdAnonymousUserName;
  642. CMDValue cmdCurrentUser;
  643. LPTSTR pszNewPassword;
  644. CString csPath;
  645. LPTSTR szPath;
  646. CStringList cslpathList;
  647. POSITION pos;
  648. BOOL bRet = TRUE;
  649. if ( !strAnonymousPrefix.LoadString( IDS_GUEST_NAME ) ||
  650. FAILED( cmdKey.OpenNode(TEXT("LM")) ) )
  651. {
  652. // Either of these is fatal
  653. return FALSE;
  654. }
  655. // Find the anonymous username
  656. if ( !cmdKey.GetData( cmdAnonymousUserName,
  657. MD_ANONYMOUS_USER_NAME,
  658. L"W3SVC" ) ||
  659. ( _tcsnicmp( strAnonymousPrefix.QueryStr(),
  660. (LPTSTR) cmdAnonymousUserName.GetData(),
  661. strAnonymousPrefix.QueryLen() ) != 0 ) )
  662. {
  663. // Either there was no anynmous user there, or they replace the IUSR_ username
  664. return TRUE;
  665. }
  666. // Now update in all location
  667. if (FAILED( cmdKey.GetDataPaths( MD_ANONYMOUS_USER_NAME,
  668. STRING_METADATA,
  669. cslpathList) ))
  670. {
  671. // Could not GetDataPaths for this value
  672. return FALSE;
  673. }
  674. // Create new password
  675. pszNewPassword = CreatePassword(LM20_PWLEN+1);
  676. if ( !pszNewPassword )
  677. {
  678. // Could not create new password
  679. return FALSE;
  680. }
  681. pos = cslpathList.GetHeadPosition();
  682. while ( NULL != pos )
  683. {
  684. csPath = cslpathList.GetNext( pos );
  685. szPath = csPath.GetBuffer(0);
  686. if ( cmdKey.GetData( cmdCurrentUser, MD_ANONYMOUS_USER_NAME, szPath ),
  687. ( _tcsicmp( (LPTSTR) cmdAnonymousUserName.GetData(),
  688. (LPTSTR) cmdCurrentUser.GetData() ) == 0 ) )
  689. {
  690. // We found a location with the username set
  691. if ( FAILED( cmdKey.SetData( MD_ANONYMOUS_PWD,
  692. METADATA_INHERIT | METADATA_SECURE,
  693. IIS_MD_UT_FILE,
  694. STRING_METADATA,
  695. ( _tcslen( pszNewPassword ) + 1 )*sizeof( TCHAR ),
  696. (LPBYTE) pszNewPassword,
  697. szPath ) ) )
  698. {
  699. // Failed to set correctly
  700. bRet = FALSE;
  701. }
  702. }
  703. }
  704. if ( pszNewPassword )
  705. {
  706. GlobalFree(pszNewPassword);
  707. }
  708. return bRet;
  709. }
  710. // function: ReSetIWamIUsrPasswds
  711. //
  712. // This function Changes the IWAM and IUSR passwords the
  713. // metabase. Then sets a reg entry, and stops and starts
  714. // iisadmin. This causes iisadmin to reset the password in NT,
  715. // and re sync the com objects.
  716. //
  717. // Return:
  718. // TRUE - Succeeded
  719. // FALSE - Failed
  720. //
  721. BOOL ReSetIWamIUsrPasswds(void)
  722. {
  723. DWORD dwType;
  724. DWORD dwValue;
  725. DWORD dwSize;
  726. DWORD dwOldRegValue;
  727. BOOL fOldRegWasSet = FALSE;
  728. CMDKey cmdKey;
  729. LPTSTR pszNewPassword = NULL;
  730. HKEY hKey;
  731. iisDebugOut((LOG_TYPE_TRACE, _T("ReSetIWamIUsrPasswds:start\n")));
  732. if ( RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  733. REG_ENABLEPASSSYNC_KEY,
  734. 0,
  735. KEY_READ | KEY_WRITE,
  736. &hKey) != ERROR_SUCCESS)
  737. {
  738. // If we can not open the registry to set the flag,
  739. // there is not hope in resetting the password
  740. return FALSE;
  741. }
  742. if ( !ChangeIUsrPasswords() )
  743. {
  744. return FALSE;
  745. }
  746. cmdKey.OpenNode(TEXT("LM/W3SVC"));
  747. // Set New IWAM Password
  748. pszNewPassword = CreatePassword(LM20_PWLEN+1);
  749. if ( pszNewPassword )
  750. {
  751. cmdKey.SetData(MD_WAM_PWD,METADATA_INHERIT | METADATA_SECURE,IIS_MD_UT_FILE,STRING_METADATA,(_tcslen(pszNewPassword)+1)*sizeof(TCHAR),(LPBYTE) pszNewPassword);
  752. GlobalFree(pszNewPassword);
  753. }
  754. cmdKey.Close();
  755. // Retrieve Old Value for REG_ENABLEPASSSYNC
  756. dwSize = sizeof(DWORD);
  757. if ( (RegQueryValueEx(hKey,REG_ENABLEPASSSYNC_VALUE,NULL,&dwType,(LPBYTE) &dwValue,&dwSize) == ERROR_SUCCESS) &&
  758. (dwType == REG_DWORD)
  759. )
  760. {
  761. fOldRegWasSet = TRUE;
  762. dwOldRegValue = dwValue;
  763. }
  764. // Set New Value
  765. dwSize = sizeof(DWORD);
  766. dwType = REG_DWORD;
  767. dwValue = 1;
  768. if (RegSetValueEx(hKey,REG_ENABLEPASSSYNC_VALUE,0,dwType,(LPBYTE) &dwValue,dwSize) == ERROR_SUCCESS)
  769. {
  770. // Stop IISAdmin Service
  771. StopServiceAndDependencies(TEXT("IISADMIN"), FALSE);
  772. // Start IISAdmin Service (this will resync the passwords)
  773. InetStartService(TEXT("IISADMIN"));
  774. // We are going to reboot after installing, so don't
  775. // worry about starting the services that we cascadingly
  776. // stopped
  777. // Reset the Key to the old value
  778. if (fOldRegWasSet)
  779. {
  780. dwSize = sizeof(DWORD);
  781. dwType = REG_DWORD;
  782. RegSetValueEx(hKey,REG_ENABLEPASSSYNC_VALUE,0,dwType,(LPBYTE) &dwOldRegValue,dwSize);
  783. }
  784. else
  785. {
  786. RegDeleteValue(hKey,REG_ENABLEPASSSYNC_VALUE);
  787. }
  788. }
  789. else
  790. {
  791. RegCloseKey(hKey);
  792. return FALSE;
  793. }
  794. RegCloseKey(hKey);
  795. return TRUE;
  796. }
  797. DWORD SysPrepTempfileWriteAclInfo(HANDLE hFile,CString csKeyPath)
  798. {
  799. DWORD dwReturn = ERROR_ACCESS_DENIED;
  800. BOOL bFound = FALSE;
  801. DWORD attr, uType, dType, cbLen;
  802. CMDKey cmdKey;
  803. BUFFER bufData;
  804. PBYTE pData;
  805. int BufSize;
  806. PSECURITY_DESCRIPTOR pOldSd = NULL;
  807. if (hFile == NULL || hFile == INVALID_HANDLE_VALUE)
  808. {
  809. return S_OK;
  810. }
  811. cmdKey.OpenNode(csKeyPath);
  812. if ( (METADATA_HANDLE) cmdKey )
  813. {
  814. pData = (PBYTE)(bufData.QueryPtr());
  815. BufSize = bufData.QuerySize();
  816. cbLen = 0;
  817. bFound = cmdKey.GetData(MD_ADMIN_ACL, &attr, &uType, &dType, &cbLen, pData, BufSize);
  818. if (!bFound)
  819. {
  820. if (cbLen > 0)
  821. {
  822. if ( ! (bufData.Resize(cbLen)) )
  823. {
  824. iisDebugOut((LOG_TYPE_ERROR, _T("MDDumpAdminACL(): cmdKey.GetData. failed to resize to %d.!\n"), cbLen));
  825. }
  826. else
  827. {
  828. pData = (PBYTE)(bufData.QueryPtr());
  829. BufSize = cbLen;
  830. cbLen = 0;
  831. bFound = cmdKey.GetData(MD_ADMIN_ACL, &attr, &uType, &dType, &cbLen, pData, BufSize);
  832. }
  833. }
  834. }
  835. cmdKey.Close();
  836. if (bFound)
  837. {
  838. // dump out the info
  839. // We've got the acl
  840. pOldSd = (PSECURITY_DESCRIPTOR) pData;
  841. if (IsValidSecurityDescriptor(pOldSd))
  842. {
  843. #ifndef _CHICAGO_
  844. DumpAdminACL(hFile,pOldSd);
  845. dwReturn = ERROR_SUCCESS;
  846. #endif
  847. }
  848. }
  849. else
  850. {
  851. dwReturn = ERROR_PATH_NOT_FOUND;
  852. }
  853. }
  854. return dwReturn;
  855. }
  856. void SysPrepTempfileWrite(HANDLE hFile,TCHAR * szBuf)
  857. {
  858. DWORD dwBytesWritten = 0;
  859. if (hFile != NULL && hFile != INVALID_HANDLE_VALUE)
  860. {
  861. if (WriteFile(hFile, szBuf, _tcslen(szBuf) * sizeof(TCHAR), &dwBytesWritten, NULL ) == FALSE )
  862. {iisDebugOut((LOG_TYPE_WARN, _T("WriteFile Failed=0x%x.\n"), GetLastError()));}
  863. }
  864. return;
  865. }
  866. // Loop thru all the acl's
  867. // and get the values, store it somewhere
  868. HRESULT WINAPI SysPrepAclBackup(void)
  869. {
  870. HRESULT hRes = S_OK;
  871. CMDKey cmdKey;
  872. CStringList cslpathList;
  873. POSITION pos;
  874. CString csPath;
  875. HANDLE hFile = INVALID_HANDLE_VALUE;
  876. DWORD dwBytesWritten = 0;
  877. TCHAR buf[256];
  878. TCHAR szTempFileNameFull[_MAX_PATH];
  879. iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("start\n")));
  880. hRes = cmdKey.OpenNode(_T("/"));
  881. if ( FAILED(hRes) )
  882. {
  883. iisDebugOut((LOG_TYPE_ERROR, _T("OpenNode failed. err=0x%x.\n"), hRes));
  884. goto SysPrepAclBackup_Exit;
  885. }
  886. // get the sub-paths that have the data on them
  887. hRes = cmdKey.GetDataPaths( MD_ADMIN_ACL, BINARY_METADATA, cslpathList);
  888. if ( FAILED(hRes) )
  889. {
  890. iisDebugOut((LOG_TYPE_ERROR, _T("Update()-GetDataPaths failed. err=0x%x.\n"), hRes));
  891. goto SysPrepAclBackup_Exit;
  892. }
  893. // we now have the cstringlist of paths that need to be updated. Loop through the
  894. // list and update them all.
  895. // get the list's head position
  896. pos = cslpathList.GetHeadPosition();
  897. if ( NULL == pos )
  898. {
  899. goto SysPrepAclBackup_Exit;
  900. }
  901. // Create the tempfile
  902. if (!GetWindowsDirectory(szTempFileNameFull,_MAX_PATH))
  903. {
  904. goto SysPrepAclBackup_Exit;
  905. }
  906. AddPath(szTempFileNameFull, SYSPREP_TEMPFILE_NAME);
  907. if (GetFileAttributes(szTempFileNameFull) != 0xFFFFFFFF)
  908. {
  909. // if file already exists, then delete it
  910. SetFileAttributes(szTempFileNameFull, FILE_ATTRIBUTE_NORMAL);
  911. DeleteFile(szTempFileNameFull);
  912. }
  913. // create the file
  914. hFile = CreateFile(szTempFileNameFull,GENERIC_READ | GENERIC_WRITE,FILE_SHARE_READ | FILE_SHARE_WRITE,NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
  915. if (hFile == INVALID_HANDLE_VALUE)
  916. {
  917. hFile = NULL;
  918. goto SysPrepAclBackup_Exit;
  919. }
  920. SetFilePointer( hFile, NULL, NULL, FILE_END );
  921. // write a couple of bytes to the beginning of the file say that it's "unicode"
  922. WriteFile(hFile, (LPCVOID) 0xFF, 1, &dwBytesWritten, NULL);
  923. WriteFile(hFile, (LPCVOID) 0xFE, 1, &dwBytesWritten, NULL);
  924. // write a section so that setupapi api's can read it
  925. //
  926. //[version]
  927. //signature="$Windows NT$"
  928. memset(buf, 0, _tcslen(buf) * sizeof(TCHAR));
  929. _tcscpy(buf, _T("[version]\r\n"));SysPrepTempfileWrite(hFile, buf);
  930. _tcscpy(buf, _T("signature=\"$Windows NT$\"\r\n"));SysPrepTempfileWrite(hFile, buf);
  931. // Write in known section
  932. _stprintf(buf, _T("[%s]\r\n"),SYSPREP_KNOWN_SECTION_NAME);SysPrepTempfileWrite(hFile, buf);
  933. // Add entries for the [paths] section
  934. // [paths]
  935. // /
  936. // /w3svc/info
  937. // etc...
  938. //
  939. while ( NULL != pos )
  940. {
  941. // get the next path in question
  942. csPath = cslpathList.GetNext( pos );
  943. // Write to [paths] section
  944. _stprintf(buf, _T("%s\r\n"),csPath);
  945. SysPrepTempfileWrite(hFile, buf);
  946. // Save this whole list to the tempfile....
  947. //iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("[%s]\n"),csPath));
  948. }
  949. // close the metabase
  950. if ( (METADATA_HANDLE)cmdKey )
  951. {cmdKey.Close();}
  952. // go to the top of the list again
  953. pos = cslpathList.GetHeadPosition();
  954. while ( NULL != pos )
  955. {
  956. // get the next path in question
  957. csPath = cslpathList.GetNext( pos );
  958. // Write to [paths] section
  959. _stprintf(buf, _T("[%s]\r\n"),csPath);
  960. SysPrepTempfileWrite(hFile, buf);
  961. // Get the info that we will add to this section from looking up the metabase...
  962. // open up the metabase item for each of them.
  963. // Grab the AdminACL data, convert it to username/permissions
  964. // save the username/permission data into text format
  965. SysPrepTempfileWriteAclInfo(hFile,csPath);
  966. }
  967. SysPrepAclBackup_Exit:
  968. if ( (METADATA_HANDLE)cmdKey )
  969. {cmdKey.Close();}
  970. if (hFile)
  971. {CloseHandle(hFile);}
  972. iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("end,ret=0x%x\n"),hRes));
  973. return hRes;
  974. }
  975. void SysPrepRestoreAclSection(IN HINF hFile, IN LPCTSTR szSection)
  976. {
  977. LPTSTR szLine = NULL;
  978. DWORD dwRequiredSize;
  979. BOOL bRet = FALSE;
  980. INFCONTEXT Context;
  981. CSecurityDescriptor SD;
  982. DWORD dwSize;
  983. BUFFER buffNewSD;
  984. TSTR strSid;
  985. // go to the beginning of the section in the INF file
  986. bRet = SetupFindFirstLine_Wrapped(hFile, szSection, NULL, &Context);
  987. if (!bRet)
  988. {
  989. goto SysPrepRestoreAclSection_Exit;
  990. }
  991. // Start off by deleting the old ACL, since we do not want to add
  992. // to it, we want to replace it
  993. if ( FAILED( RemoveMetabaseACL( szSection ) ) )
  994. {
  995. iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("RemoveMetabaseACL failed!!\n")));
  996. }
  997. // Set Group and Owner of SD
  998. if ( !SD.SetOwnerbyWellKnownID( CSecurityDescriptor::GROUP_ADMINISTRATORS ) ||
  999. !SD.SetGroupbyWellKnownID( CSecurityDescriptor::GROUP_ADMINISTRATORS ) )
  1000. {
  1001. iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("Failed to initialize SD with owner and group, GLE=%8x\n"),GetLastError()));
  1002. goto SysPrepRestoreAclSection_Exit;
  1003. }
  1004. // loop through the items in the section.
  1005. while (bRet)
  1006. {
  1007. // get the size of the memory we need for this
  1008. bRet = SetupGetLineText(&Context, NULL, NULL, NULL, NULL, 0, &dwRequiredSize);
  1009. // prepare the buffer to receive the line
  1010. szLine = (LPTSTR)GlobalAlloc( GPTR, dwRequiredSize * sizeof(TCHAR) );
  1011. if ( !szLine )
  1012. {
  1013. goto SysPrepRestoreAclSection_Exit;
  1014. }
  1015. // get the line from the inf file1
  1016. if (SetupGetLineText(&Context, NULL, NULL, NULL, szLine, dwRequiredSize, NULL) == FALSE)
  1017. {
  1018. goto SysPrepRestoreAclSection_Exit;
  1019. }
  1020. // The line we get should look something like this:
  1021. //
  1022. //[/]
  1023. //IIS_WPG,0x0,0x0,0x24,0x400ab
  1024. //Administrators,0x0,0x0,0x18,0x400ab
  1025. //Everyone,0x0,0x0,0x14,0x8
  1026. // Get everything to the left of the "=" sign
  1027. // this should be the username
  1028. TCHAR szUserName[UNLEN + 1];
  1029. ACCESS_ALLOWED_ACE MyNewACE;
  1030. TCHAR *token = NULL;
  1031. token = _tcstok(szLine, _T(","));
  1032. if (token == NULL)
  1033. {
  1034. goto SysPrepRestoreAclSection_Exit;
  1035. }
  1036. // Get the username
  1037. _tcscpy(szUserName,token);
  1038. // Copy the String Sid
  1039. token = _tcstok(NULL, _T(","));
  1040. if ( (NULL == token) ||
  1041. !strSid.Copy( token ) )
  1042. {
  1043. goto SysPrepRestoreAclSection_Exit;
  1044. }
  1045. // Get the next 4 values...
  1046. token = _tcstok(NULL, _T(","));
  1047. if (NULL == token){goto SysPrepRestoreAclSection_Exit;}
  1048. MyNewACE.Header.AceType = (UCHAR) atodw(token);
  1049. token = _tcstok(NULL, _T(","));
  1050. if (NULL == token){goto SysPrepRestoreAclSection_Exit;}
  1051. MyNewACE.Header.AceFlags = (UCHAR) atodw(token);
  1052. token = _tcstok(NULL, _T(","));
  1053. if (NULL == token){goto SysPrepRestoreAclSection_Exit;}
  1054. MyNewACE.Header.AceSize = (USHORT) atodw(token);
  1055. token = _tcstok(NULL, _T(","));
  1056. if (NULL == token){goto SysPrepRestoreAclSection_Exit;}
  1057. MyNewACE.Mask = atodw(token);
  1058. //iisDebugOut((LOG_TYPE_TRACE, _T("NewACLinfo:%s,0x%x,0x%x,0x%x,0x%x\n"),szUserName,MyNewACE.Header.AceType,MyNewACE.Header.AceFlags,MyNewACE.Header.AceSize,MyNewACE.Mask));
  1059. // Grab this info and create an ACL for it.
  1060. if ( AddUserToMetabaseACL2( &SD, szUserName, strSid.QueryStr(), &MyNewACE) != ERROR_SUCCESS )
  1061. {
  1062. iisDebugOut((LOG_TYPE_ERROR, _T("Failed to restore metabase acl by adding '%s' to ACL at '%s', GLE=%8x)\n"),szUserName,szSection,GetLastError()));
  1063. return;
  1064. }
  1065. // find the next line in the section. If there is no next line it should return false
  1066. bRet = SetupFindNextLine(&Context, &Context);
  1067. // free the temporary buffer
  1068. GlobalFree( szLine );szLine=NULL;
  1069. szLine = NULL;
  1070. }
  1071. if ( !SD.CreateSelfRelativeSD( &buffNewSD, &dwSize ) )
  1072. {
  1073. // Failed to make selfrelative
  1074. iisDebugOut((LOG_TYPE_ERROR, _T("Failed to create SelfRelative SD at '%s', GLE=%8x)\n"),szSection,GetLastError()));
  1075. return;
  1076. }
  1077. WriteSDtoMetaBase( (PSECURITY_DESCRIPTOR) buffNewSD.QueryPtr(), szSection);
  1078. SysPrepRestoreAclSection_Exit:
  1079. if (szLine) {GlobalFree(szLine);szLine=NULL;}
  1080. return;
  1081. }
  1082. // Function: RemoveMetabaseACL
  1083. //
  1084. // Delete the Metabase ACL from the node specified
  1085. //
  1086. // Parameters:
  1087. // szPath - The node to delete it from
  1088. //
  1089. HRESULT RemoveMetabaseACL( LPCTSTR szPath )
  1090. {
  1091. DWORD hr;
  1092. CMDKey cmdKey;
  1093. iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("RemoveMetabaseACL:start\n")));
  1094. hr = cmdKey.OpenNode( szPath );
  1095. if ( FAILED( hr ) )
  1096. {
  1097. // Failed to open Node
  1098. iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("RemoveMetabaseACL: Open failed, hr = %8x\n"), hr));
  1099. return hr;
  1100. }
  1101. hr = cmdKey.DeleteData( MD_ADMIN_ACL, ALL_METADATA );
  1102. if ( FAILED( hr ) &&
  1103. ( hr == MD_ERROR_DATA_NOT_FOUND ) )
  1104. {
  1105. iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("RemoveMetabaseACL: Delete failed, hr = %8x\n"), hr));
  1106. // If the value did not exist, that is fine,
  1107. // we will just create a new one
  1108. hr = S_OK;
  1109. }
  1110. iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("RemoveMetabaseACL: end\n")));
  1111. // Successfully removed
  1112. return hr;
  1113. }
  1114. DWORD AddUserToMetabaseACL2( CSecurityDescriptor *pSD, LPTSTR szUserToAdd, LPTSTR szSidString, ACCESS_ALLOWED_ACE * MyACEInfo)
  1115. {
  1116. DWORD dwReturn;
  1117. iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("AddUserToMetabaseACL2():start. MyACEInfo->Mask=0x%x.\n"), MyACEInfo->Mask));
  1118. if ( !pSD->AddAccessAcebyName( szUserToAdd,
  1119. MyACEInfo->Mask,
  1120. MyACEInfo->Header.AceType == ACCESS_ALLOWED_ACE_TYPE ) )
  1121. {
  1122. // If we can not add by Username, then lets try to add by the old Sid
  1123. // since it might be a domain account we just can not get to
  1124. if ( !pSD->AddAccessAcebyStringSid( szSidString,
  1125. MyACEInfo->Mask,
  1126. MyACEInfo->Header.AceType == ACCESS_ALLOWED_ACE_TYPE ) )
  1127. {
  1128. // Failed to add user
  1129. dwReturn = GetLastError();
  1130. }
  1131. }
  1132. iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("AddUserToMetabaseACL2():End. Return=0x%x.\n"), dwReturn ));
  1133. return ERROR_SUCCESS;
  1134. }
  1135. HRESULT WINAPI SysPrepAclRestore(void)
  1136. {
  1137. HRESULT hr = S_OK;
  1138. HINF InfHandle;
  1139. TCHAR szTempFileNameFull[_MAX_PATH];
  1140. CStringList strList;
  1141. CString csTheSection = SYSPREP_KNOWN_SECTION_NAME;
  1142. iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("start\n")));
  1143. //MDDumpAdminACL(_T("/"));
  1144. // Loop thru our data file
  1145. // Create the tempfile
  1146. if (!GetWindowsDirectory(szTempFileNameFull,_MAX_PATH))
  1147. {
  1148. goto SysPrepAclRestore_Exit;
  1149. }
  1150. AddPath(szTempFileNameFull, SYSPREP_TEMPFILE_NAME);
  1151. // Get a handle to it.
  1152. InfHandle = SetupOpenInfFile(szTempFileNameFull, NULL, INF_STYLE_WIN4, NULL);
  1153. if(InfHandle == INVALID_HANDLE_VALUE)
  1154. {
  1155. goto SysPrepAclRestore_Exit;
  1156. }
  1157. if (ERROR_SUCCESS == FillStrListWithListOfSections(InfHandle, strList, csTheSection))
  1158. {
  1159. // loop thru the list returned back
  1160. if (strList.IsEmpty() == FALSE)
  1161. {
  1162. POSITION pos;
  1163. CString csEntry;
  1164. pos = strList.GetHeadPosition();
  1165. while (pos)
  1166. {
  1167. csEntry = strList.GetAt(pos);
  1168. // go get this section and read thru it's info
  1169. SysPrepRestoreAclSection(InfHandle, csEntry);
  1170. strList.GetNext(pos);
  1171. }
  1172. }
  1173. }
  1174. //MDDumpAdminACL(_T("/"));
  1175. if (GetFileAttributes(szTempFileNameFull) != 0xFFFFFFFF)
  1176. {
  1177. // if file already exists, then delete it
  1178. SetFileAttributes(szTempFileNameFull, FILE_ATTRIBUTE_NORMAL);
  1179. DeleteFile(szTempFileNameFull);
  1180. }
  1181. SysPrepAclRestore_Exit:
  1182. iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("end,ret=0x%x\n"),hr));
  1183. return hr;
  1184. }
  1185. //
  1186. // DO NOT REMOVE THIS ENTRY POINT
  1187. //
  1188. // Entry point used by SysPrep in Whistler
  1189. //
  1190. // When sysprep runs, it is going to reset the machine sid
  1191. // so when that happens all the crypto stuff is broken.
  1192. // we had to implement this stuff so that before sysprep
  1193. // changes the sid (and thus breaking crypto) we can save our
  1194. // working metabase off somewhere (without crypto key encryption)
  1195. //
  1196. // At some point after sysprep has changed the machine sid
  1197. // it will call us into SysPrepRestore() and we wil restore
  1198. // our metabase using the new crypto keys on the machine.
  1199. //
  1200. HRESULT WINAPI SysPrepBackup(void)
  1201. {
  1202. HRESULT hr = S_OK;
  1203. WCHAR lpwszBackupLocation[_MAX_PATH];
  1204. DWORD dwMDVersion;
  1205. DWORD dwMDFlags;
  1206. WCHAR * pwszPassword = NULL;
  1207. BOOL bThingsAreGood = FALSE;
  1208. IMSAdminBase2 * pIMSAdminBase2 = NULL;
  1209. _tcscpy(g_MyLogFile.m_szLogPreLineInfo, _T("SysPrepBackup:"));
  1210. _tcscpy(g_MyLogFile.m_szLogPreLineInfo2, _T(""));
  1211. iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("start\n")));
  1212. #ifndef _CHICAGO_
  1213. #ifdef SYSPREP_USE_SECRETS
  1214. #else
  1215. CRegKey regBigString(HKEY_LOCAL_MACHINE, REG_INETSTP, KEY_ALL_ACCESS);
  1216. #endif
  1217. #endif
  1218. // Check if the user who loaded this dll
  1219. // and is calling this entry point has the right priv to do this!
  1220. if (FALSE == RunningAsAdministrator())
  1221. {
  1222. hr = E_ABORT;
  1223. iisDebugOut((LOG_TYPE_ERROR, _T("No admin priv, aborting\n")));
  1224. goto SysPrepBackup_Exit2;
  1225. }
  1226. // if the service doesn't exist, then we don't have to do anyting
  1227. if (CheckifServiceExist(_T("IISADMIN")) != 0 )
  1228. {
  1229. iisDebugOut((LOG_TYPE_TRACE, _T("IIS not installed. do nothing.\n")));
  1230. hr = S_OK;
  1231. goto SysPrepBackup_Exit2;
  1232. }
  1233. // start the iisadmin service before calling backup.
  1234. // this is because if the backup function is called and the metabase is not
  1235. // running, then the metabase must startup while backup is trying to lock the
  1236. // metabase for backup. a race condition will happen and sometimes backup will
  1237. // fail since the metabase may take a while before starting up.
  1238. // this function will wait till the service is fully started before returning
  1239. InetStartService(_T("IISADMIN"));
  1240. #ifndef _CHICAGO_
  1241. pwszPassword = CreatePassword(SYSPREP_TEMP_PASSWORD_LENGTH);
  1242. if (pwszPassword)
  1243. {
  1244. #ifdef SYSPREP_USE_SECRETS
  1245. // calling set
  1246. if (ERROR_SUCCESS == SetSecret(SYSPREP_KNOWN_REGISTRY_KEY,pwszPassword))
  1247. {
  1248. bThingsAreGood = TRUE;
  1249. }
  1250. #else
  1251. if ((HKEY) regBigString)
  1252. {
  1253. regBigString.SetValue(SYSPREP_KNOWN_REGISTRY_KEY, pwszPassword);
  1254. bThingsAreGood = TRUE;
  1255. }
  1256. #endif
  1257. }
  1258. //iisDebugOut((LOG_TYPE_TRACE, _T("PASSWORD=%s,len=%d\n"),pwszPassword,wcslen(pwszPassword)));
  1259. #endif
  1260. // Tell the metabase where it should backup to.
  1261. wcscpy(lpwszBackupLocation,L"");
  1262. dwMDFlags = MD_BACKUP_OVERWRITE | MD_BACKUP_SAVE_FIRST | MD_BACKUP_FORCE_BACKUP;
  1263. dwMDVersion = MD_BACKUP_MAX_VERSION;
  1264. #ifndef _CHICAGO_
  1265. hr = CoInitializeEx( NULL, COINIT_MULTITHREADED );
  1266. #else
  1267. hr = CoInitialize(NULL);
  1268. #endif
  1269. // no need to call uninit
  1270. if( FAILED (hr))
  1271. {
  1272. iisDebugOut((LOG_TYPE_ERROR, _T("CoInitializeEx failed\n")));
  1273. goto SysPrepBackup_Exit2;
  1274. }
  1275. hr = ::CoCreateInstance(CLSID_MSAdminBase,NULL,CLSCTX_ALL,IID_IMSAdminBase2,(void **) & pIMSAdminBase2);
  1276. if(FAILED (hr))
  1277. {
  1278. iisDebugOut((LOG_TYPE_ERROR, _T("CoCreateInstance on IID_IMSAdminBase2 failed\n")));
  1279. goto SysPrepBackup_Exit;
  1280. }
  1281. // Call the metabase function
  1282. if (SUCCEEDED(hr))
  1283. {
  1284. iisDebugOut((LOG_TYPE_TRACE, _T("BackupWithPasswd calling...\n")));
  1285. if (bThingsAreGood)
  1286. {
  1287. //iisDebugOut((LOG_TYPE_TRACE, _T("using org\n")));
  1288. hr = pIMSAdminBase2->BackupWithPasswd(lpwszBackupLocation, dwMDVersion, dwMDFlags, pwszPassword);
  1289. }
  1290. else
  1291. {
  1292. //iisDebugOut((LOG_TYPE_TRACE, _T("using backup\n")));
  1293. hr = pIMSAdminBase2->BackupWithPasswd(lpwszBackupLocation, dwMDVersion, dwMDFlags, L"null");
  1294. }
  1295. if (pIMSAdminBase2)
  1296. {
  1297. pIMSAdminBase2->Release();
  1298. pIMSAdminBase2 = NULL;
  1299. }
  1300. if (SUCCEEDED(hr))
  1301. {
  1302. iisDebugOut((LOG_TYPE_TRACE, _T("BackupWithPasswd SUCCEEDED\n")));
  1303. }
  1304. else
  1305. {
  1306. iisDebugOut((LOG_TYPE_ERROR, _T("BackupWithPasswd failed\n")));
  1307. }
  1308. // Save all the acl info somewhere.
  1309. _tcscpy(g_MyLogFile.m_szLogPreLineInfo2, _T("SysPrepAclBackup"));
  1310. SysPrepAclBackup();
  1311. _tcscpy(g_MyLogFile.m_szLogPreLineInfo2, _T(""));
  1312. // set a flag to say that we called backup...
  1313. CRegKey regStageString(HKEY_LOCAL_MACHINE, REG_INETSTP, KEY_ALL_ACCESS);
  1314. if ((HKEY) regStageString)
  1315. {
  1316. regStageString.SetValue(SYSPREP_KNOWN_REGISTRY_KEY2, _T("1"));
  1317. }
  1318. }
  1319. SysPrepBackup_Exit:
  1320. CoUninitialize();
  1321. SysPrepBackup_Exit2:
  1322. if (pwszPassword) {GlobalFree(pwszPassword);pwszPassword=NULL;}
  1323. iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("end,ret=0x%x\n"),hr));
  1324. _tcscpy(g_MyLogFile.m_szLogPreLineInfo, _T(""));
  1325. _tcscpy(g_MyLogFile.m_szLogPreLineInfo2, _T(""));
  1326. return hr;
  1327. }
  1328. //
  1329. // DO NOT REMOVE THIS ENTRY POINT
  1330. //
  1331. // Entry point used by SysPrep in Whistler
  1332. //
  1333. // When sysprep runs, it is going to reset the machine sid
  1334. // so when that happens all the crypto stuff is broken.
  1335. // we had to implement this stuff so that before sysprep
  1336. // changes the sid (and thus breaking crypto) we can save our
  1337. // working metabase off somewhere (without crypto key encryption)
  1338. //
  1339. // At some point after sysprep has changed the machine sid
  1340. // it will call us into SysPrepRestore() and we wil restore
  1341. // our metabase using the new crypto keys on the machine.
  1342. //
  1343. HRESULT WINAPI SysPrepRestore(void)
  1344. {
  1345. HRESULT hr = S_OK;
  1346. WCHAR lpwszBackupLocation[_MAX_PATH];
  1347. TCHAR szTempDir[_MAX_PATH];
  1348. TCHAR szSystemDir[_MAX_PATH];
  1349. DWORD dwMDVersion;
  1350. DWORD dwMDFlags;
  1351. TSTR strPassword;
  1352. IMSAdminBase2 * pIMSAdminBase2 = NULL;
  1353. BOOL bThingsAreGood = FALSE;
  1354. _tcscpy(g_MyLogFile.m_szLogPreLineInfo, _T("SysPrepRestore:"));
  1355. _tcscpy(g_MyLogFile.m_szLogPreLineInfo2, _T(""));
  1356. iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("start\n")));
  1357. strPassword.MarkSensitiveData(TRUE);
  1358. #ifndef _CHICAGO_
  1359. #ifdef SYSPREP_USE_SECRETS
  1360. #else
  1361. CRegKey regBigString(HKEY_LOCAL_MACHINE, REG_INETSTP, KEY_ALL_ACCESS);
  1362. #endif
  1363. #endif
  1364. CRegKey regStageString(HKEY_LOCAL_MACHINE, REG_INETSTP, KEY_ALL_ACCESS);
  1365. iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("SysPrepRestore start\n")));
  1366. // Check if the user who loaded this dll
  1367. // and is calling this entry point has the right priv to do this!
  1368. if (FALSE == RunningAsAdministrator())
  1369. {
  1370. hr = E_ABORT;
  1371. iisDebugOut((LOG_TYPE_ERROR, _T("No admin priv, aborting\n")));
  1372. goto SysPrepRestore_Exit2;
  1373. }
  1374. // Only do this restore stuff if backup was called...
  1375. if ((HKEY) regStageString)
  1376. {
  1377. CString csTheData;
  1378. regStageString.m_iDisplayWarnings = FALSE;
  1379. if ( regStageString.QueryValue(SYSPREP_KNOWN_REGISTRY_KEY2, csTheData) == ERROR_SUCCESS )
  1380. {
  1381. if (_tcsicmp(csTheData,_T("1")) == 0)
  1382. {
  1383. // Backup was run!
  1384. bThingsAreGood = TRUE;
  1385. }
  1386. else
  1387. {
  1388. bThingsAreGood = FALSE;
  1389. }
  1390. }
  1391. }
  1392. if (FALSE == bThingsAreGood)
  1393. {
  1394. // Lets get out.
  1395. iisDebugOut((LOG_TYPE_TRACE, _T("SysPrepBackup not called, so not doing SysPrepRestore. do nothing.\n")));
  1396. hr = S_OK;
  1397. goto SysPrepRestore_Exit2;
  1398. }
  1399. if ( !SetInstallStateInRegistry( INSTALLSTATE_CURRENTLYINSTALLING ) )
  1400. {
  1401. hr = E_ABORT;
  1402. iisDebugOut((LOG_TYPE_ERROR, _T("Could not set setup install state in registry, aborting\n")));
  1403. goto SysPrepRestore_Exit2;
  1404. }
  1405. // if the service doesn't exist, then we don't have to do anyting
  1406. if (CheckifServiceExist(_T("IISADMIN")) != 0 )
  1407. {
  1408. iisDebugOut((LOG_TYPE_TRACE, _T("SysPrepRestore IIS not installed. do nothing.\n")));
  1409. hr = S_OK;
  1410. goto SysPrepRestore_Exit2;
  1411. }
  1412. // make sure the iisadmin service is stopped.
  1413. StopServiceAndDependencies(_T("IISADMIN"), TRUE);
  1414. #ifndef _CHICAGO_
  1415. #ifdef SYSPREP_USE_SECRETS
  1416. if (GetSecret(SYSPREP_KNOWN_REGISTRY_KEY, &strPassword))
  1417. {
  1418. bThingsAreGood = TRUE;
  1419. }
  1420. #else
  1421. if ((HKEY) regBigString)
  1422. {
  1423. CString csTheData;
  1424. regBigString.m_iDisplayWarnings = FALSE;
  1425. if ( regBigString.QueryValue(SYSPREP_KNOWN_REGISTRY_KEY, csTheData) == ERROR_SUCCESS )
  1426. {
  1427. pwszPassword = (WCHAR *) GlobalAlloc (GPTR, (csTheData.GetLength() + 1) * sizeof(TCHAR) );
  1428. if (pwszPassword)
  1429. {
  1430. wcscpy(pwszPassword,csTheData);
  1431. bThingsAreGood = TRUE;
  1432. }
  1433. }
  1434. }
  1435. #endif
  1436. #endif
  1437. //iisDebugOut((LOG_TYPE_TRACE, _T("PASSWORD=%s,len=%d\n"),pwszPassword,wcslen(pwszPassword)));
  1438. // Tell the metabase where it should backup to.
  1439. wcscpy(lpwszBackupLocation,L"");
  1440. dwMDFlags = 0;
  1441. dwMDVersion = MD_BACKUP_MAX_VERSION;
  1442. //
  1443. // IISAdmin won't start up if the metabase.xml,mbschema.xml files are corrupted (bad signature)
  1444. // so delete them before restoring....
  1445. if (0 == GetSystemDirectory(szSystemDir, _MAX_PATH))
  1446. {
  1447. goto SysPrepRestore_Exit2;
  1448. }
  1449. // delete existing metabase files
  1450. // we can't have this file hanging around --> the metabase won't start if it is here!
  1451. // iis6 files -- for whistler server skus
  1452. _stprintf(szTempDir, _T("%s\\inetsrv\\Metabase.xml"),szSystemDir);
  1453. InetDeleteFile(szTempDir);
  1454. _stprintf(szTempDir, _T("%s\\inetsrv\\MBSchema.xml"),szSystemDir);
  1455. InetDeleteFile(szTempDir);
  1456. // iis51 files -- for whistler pro sku
  1457. _stprintf(szTempDir, _T("%s\\inetsrv\\metabase.bin"),szSystemDir);
  1458. InetDeleteFile(szTempDir);
  1459. #ifndef _CHICAGO_
  1460. hr = CoInitializeEx( NULL, COINIT_MULTITHREADED );
  1461. #else
  1462. hr = CoInitialize(NULL);
  1463. #endif
  1464. // no need to call uninit
  1465. if( FAILED (hr))
  1466. {
  1467. iisDebugOut((LOG_TYPE_ERROR, _T("CoInitializeEx failed\n")));
  1468. goto SysPrepRestore_Exit2;
  1469. }
  1470. hr = ::CoCreateInstance(CLSID_MSAdminBase,NULL,CLSCTX_ALL,IID_IMSAdminBase2,(void **) & pIMSAdminBase2);
  1471. if(FAILED (hr))
  1472. {
  1473. iisDebugOut((LOG_TYPE_ERROR, _T("CoCreateInstance on IID_IMSAdminBase2 failed\n")));
  1474. goto SysPrepRestore_Exit;
  1475. }
  1476. // Call the metabase function
  1477. if (SUCCEEDED(hr))
  1478. {
  1479. iisDebugOut((LOG_TYPE_TRACE, _T("RestoreWithPasswd calling...\n")));
  1480. if (bThingsAreGood)
  1481. {
  1482. //iisDebugOut((LOG_TYPE_TRACE, _T("using org\n")));
  1483. hr = pIMSAdminBase2->RestoreWithPasswd(lpwszBackupLocation, dwMDVersion, dwMDFlags, strPassword.QueryStr() );
  1484. }
  1485. else
  1486. {
  1487. //iisDebugOut((LOG_TYPE_TRACE, _T("using backup\n")));
  1488. hr = pIMSAdminBase2->RestoreWithPasswd(lpwszBackupLocation, dwMDVersion, dwMDFlags, L"null");
  1489. }
  1490. if (pIMSAdminBase2)
  1491. {
  1492. pIMSAdminBase2->Release();
  1493. pIMSAdminBase2 = NULL;
  1494. }
  1495. if (SUCCEEDED(hr))
  1496. {
  1497. // Delete the backup file that we used!
  1498. //MD_DEFAULT_BACKUP_LOCATION + ".md" + MD_BACKUP_MAX_VERSION
  1499. _stprintf(szTempDir, _T("%s\\inetsrv\\MetaBack\\%s.md%d"),szSystemDir,MD_DEFAULT_BACKUP_LOCATION,MD_BACKUP_MAX_VERSION);
  1500. InetDeleteFile(szTempDir);
  1501. _stprintf(szTempDir, _T("%s\\inetsrv\\MetaBack\\%s.sc%d"),szSystemDir,MD_DEFAULT_BACKUP_LOCATION,MD_BACKUP_MAX_VERSION);
  1502. InetDeleteFile(szTempDir);
  1503. iisDebugOut((LOG_TYPE_TRACE, _T("RestoreWithPasswd SUCCEEDED\n")));
  1504. #ifndef _CHICAGO_
  1505. #ifdef SYSPREP_USE_SECRETS
  1506. // we need to delete the Secret that we used here!
  1507. SetSecret(SYSPREP_KNOWN_REGISTRY_KEY,L" ");
  1508. #else
  1509. if ((HKEY) regBigString)
  1510. {
  1511. regBigString.DeleteValue(SYSPREP_KNOWN_REGISTRY_KEY);
  1512. }
  1513. #endif
  1514. #endif
  1515. // Do extra stuff
  1516. // like Re-applying the acl for the iis_wpg group to the "/" node
  1517. _tcscpy(g_MyLogFile.m_szLogPreLineInfo2, _T("SysPrepAclRestore"));
  1518. SysPrepAclRestore();
  1519. _tcscpy(g_MyLogFile.m_szLogPreLineInfo2, _T(""));
  1520. // syncronize wam with new iwam user
  1521. //_tcscpy(g_MyLogFile.m_szLogPreLineInfo2, _T("SysPrepAclSyncIWam"));
  1522. //SysPrepAclSyncIWam();
  1523. //_tcscpy(g_MyLogFile.m_szLogPreLineInfo2, _T(""));
  1524. // only delete this if restore ws success
  1525. if ((HKEY) regStageString)
  1526. {
  1527. regStageString.DeleteValue(SYSPREP_KNOWN_REGISTRY_KEY2);
  1528. }
  1529. }
  1530. else
  1531. {
  1532. iisDebugOut((LOG_TYPE_ERROR, _T("RestoreWithPasswd failed, with hr=0x%8x\n"),hr));
  1533. }
  1534. }
  1535. // Reset the passwords, and allow iisadmin to fix the com information
  1536. if (!ReSetIWamIUsrPasswds())
  1537. {
  1538. iisDebugOut((LOG_TYPE_WARN, _T("ReSetIWamIUsrPasswds was unable to reset IUSR and IWAM passwords\n")));
  1539. }
  1540. if ( !ReregisterDav() )
  1541. {
  1542. iisDebugOut((LOG_TYPE_WARN, _T("Failed to update DAV COM ACL's\n")));
  1543. }
  1544. SysPrepRestore_Exit:
  1545. CoUninitialize();
  1546. SysPrepRestore_Exit2:
  1547. SetInstallStateInRegistry( INSTALLSTATE_DONE );
  1548. iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("end,ret=0x%x\n"),hr));
  1549. _tcscpy(g_MyLogFile.m_szLogPreLineInfo, _T(""));
  1550. _tcscpy(g_MyLogFile.m_szLogPreLineInfo2, _T(""));
  1551. return hr;
  1552. }
  1553. // ValidateWebRootDir
  1554. //
  1555. // Update the g_pTheApp->m_csPathWWWRoot
  1556. BOOL ValidateWebRootDir()
  1557. {
  1558. TSTR strWWWRootDir;
  1559. if ( !strWWWRootDir.Resize( MAX_PATH ) )
  1560. {
  1561. // Could not allocate space for this
  1562. return FALSE;
  1563. }
  1564. if ( GetDataFromMetabase(METABASEPATH_DEFAULTSITE, MD_VR_PATH, (PBYTE)strWWWRootDir.QueryStr(), strWWWRootDir.QuerySize()))
  1565. {
  1566. g_pTheApp->m_csPathWWWRoot = strWWWRootDir.QueryStr();
  1567. }
  1568. return TRUE;
  1569. }
  1570. // IsInstalled
  1571. //
  1572. // Check if the component is installed
  1573. //
  1574. BOOL
  1575. IsInstalled( LPTSTR szServiceName, LPBOOL pbIsInstalled )
  1576. {
  1577. DWORD dwRet;
  1578. dwRet = CheckifServiceExist( szServiceName );
  1579. if ( ( dwRet != ERROR_SUCCESS ) &&
  1580. ( dwRet != ERROR_SERVICE_DOES_NOT_EXIST ) )
  1581. {
  1582. SetLastError( dwRet );
  1583. return FALSE;
  1584. }
  1585. *pbIsInstalled = ( dwRet == ERROR_SUCCESS );
  1586. return TRUE;
  1587. }
  1588. // ApplyIISAcl
  1589. //
  1590. // Apply the IIS Acl's to the machine, or remove them
  1591. //
  1592. BOOL
  1593. ApplyIISAcl( WCHAR cDriveLetter, BOOL bAdd )
  1594. {
  1595. BOOL bRet = TRUE;
  1596. BOOL bW3SVCIsInstalled;
  1597. BOOL bIISAdminIsInstalled;
  1598. TSTR_PATH strSystemDrive;
  1599. if ( !IsInstalled( _T("W3SVC"), &bW3SVCIsInstalled ) ||
  1600. !IsInstalled( _T("IISAdmin"), &bIISAdminIsInstalled ) )
  1601. {
  1602. // Failed to query if service was installed
  1603. return FALSE;
  1604. }
  1605. if ( !bIISAdminIsInstalled )
  1606. {
  1607. // Since nothing is installed, lets just exit now
  1608. return TRUE;
  1609. }
  1610. if ( !g_pTheApp->InitApplicationforSysPrep() ||
  1611. !ValidateWebRootDir() ||
  1612. !UpdateAnonymousUsers( NULL ) ||
  1613. !strSystemDrive.RetrieveWindowsDir() )
  1614. {
  1615. return FALSE;
  1616. }
  1617. // Reset this now, since we do not want it to interfere with the ACLing
  1618. g_pTheApp->m_eUpgradeType = UT_NONE;
  1619. if ( bAdd )
  1620. {
  1621. if ( bIISAdminIsInstalled &&
  1622. ( ( cDriveLetter == L'*' ) ||
  1623. ( tolower( cDriveLetter ) == tolower( *( strSystemDrive.QueryStr() ) ) )
  1624. )
  1625. )
  1626. {
  1627. // Update ACL's for IISAdmin if we are acling system drive
  1628. bRet = bRet && CCommonInstallComponent::SetMetabaseFileAcls();
  1629. }
  1630. if ( bW3SVCIsInstalled )
  1631. {
  1632. // Update ACL's for W3SVC
  1633. bRet = bRet && CWebServiceInstallComponent::SetAppropriateFileAclsforDrive( cDriveLetter );
  1634. if ( ( cDriveLetter == L'*' ) ||
  1635. ( tolower( cDriveLetter ) == tolower( *( strSystemDrive.QueryStr() ) ) ) )
  1636. {
  1637. bRet = bRet && CWebServiceInstallComponent::SetAspTemporaryDirAcl( TRUE );
  1638. }
  1639. }
  1640. }
  1641. else
  1642. {
  1643. // Not implemented yet, because it is not used
  1644. bRet = FALSE;
  1645. }
  1646. return bRet;
  1647. }