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.

436 lines
13 KiB

  1. #define _WIN32_DCOM
  2. #include <atlbase.h>
  3. #include <atlconv.h>
  4. #include <initguid.h>
  5. #include <comdef.h>
  6. #include <stdio.h>
  7. #include <iadmw.h> // COM Interface header file.
  8. #include <iiscnfg.h> // MD_ & IIS_MD_ #defines header file.
  9. #include <conio.h>
  10. #include <shlobj.h>
  11. #include <Shlwapi.h>
  12. #include "util.h"
  13. #include "auth.h"
  14. #include "filecopy.h"
  15. #include "mbase.h"
  16. #define ORIGINAL_BUFFER_SIZE 256
  17. #define KEYTYPE_NAME_BUFFER 32
  18. #pragma comment(lib,"Shlwapi.lib")
  19. HRESULT CreateAndCopyKey(
  20. IMSAdminBase* pIMetaSource,
  21. METADATA_HANDLE hMDSourceHandle, //metabase handle to the source key.
  22. wchar_t* pszMDSourcePath, //path of the source relative to hMDSourceHandle.
  23. IMSAdminBase* pIMetaTarget,
  24. METADATA_HANDLE hMDDestHandle, //metabase handle to the destination.
  25. wchar_t* pszMDDestPath, //path of the destination, relative to hMDDestHandle.
  26. BOOL bMDCopySubKeys //whether to copy all subkey data
  27. )
  28. {
  29. HRESULT hRes = S_OK;
  30. DWORD indx = 0;
  31. WCHAR SubKeyName[MAX_PATH*2];
  32. _bstr_t bstrTargetSubKeyPath;
  33. _bstr_t bstrSourceSubKeyPath;
  34. ATLASSERT(pIMetaSource != NULL);
  35. ATLASSERT(pIMetaTarget != NULL);
  36. ATLASSERT(pszMDSourcePath);
  37. ATLASSERT(pszMDDestPath);
  38. // first this will create the destination key.
  39. pIMetaTarget->AddKey(hMDDestHandle,pszMDDestPath);
  40. while (SUCCEEDED(hRes))
  41. {
  42. hRes = pIMetaSource->EnumKeys(hMDSourceHandle, pszMDSourcePath, SubKeyName, indx);
  43. if(SUCCEEDED(hRes)) {
  44. bstrTargetSubKeyPath = pszMDDestPath;
  45. bstrTargetSubKeyPath += L"/";
  46. bstrTargetSubKeyPath += SubKeyName;
  47. bstrSourceSubKeyPath = pszMDSourcePath;
  48. bstrSourceSubKeyPath += L"/";
  49. bstrSourceSubKeyPath += SubKeyName;
  50. //wprintf(L"%s %s\n",SubKeyName,KeyType);
  51. CreateAndCopyKey (pIMetaSource,hMDSourceHandle,bstrSourceSubKeyPath,pIMetaTarget,
  52. hMDDestHandle,bstrTargetSubKeyPath, bMDCopySubKeys);
  53. }
  54. indx++;
  55. } //while (SUCCEEDED(hRes))
  56. hRes = EnumProperties(pIMetaSource,hMDSourceHandle,pszMDSourcePath,pIMetaTarget,hMDDestHandle,pszMDDestPath);
  57. return hRes;
  58. }
  59. HRESULT EnumProperties(IMSAdminBase* pIMetaSource, METADATA_HANDLE hKeySource, wchar_t* SourceMDPath,
  60. IMSAdminBase* pIMetaTarget, METADATA_HANDLE hKeyTarget, wchar_t* TargetMDPath )
  61. {
  62. HRESULT hRes = 0;
  63. METADATA_RECORD mRec;
  64. DWORD indx = 0;
  65. DWORD dwReqBufLen = 0;
  66. DWORD dwBufLen = ORIGINAL_BUFFER_SIZE;
  67. PBYTE pbBuffer = new BYTE[dwBufLen];
  68. wchar_t *ptemp = 0;
  69. while (SUCCEEDED(hRes)){
  70. mRec.dwMDAttributes = METADATA_ISINHERITED;
  71. mRec.dwMDUserType = ALL_METADATA; //IIS_MD_UT_FILE ;
  72. mRec.dwMDDataType = ALL_METADATA;
  73. mRec.dwMDDataLen = dwBufLen;
  74. mRec.pbMDData = pbBuffer;
  75. hRes = pIMetaSource->EnumData(hKeySource, SourceMDPath, &mRec, indx, &dwReqBufLen);
  76. if (hRes == RETURNCODETOHRESULT(ERROR_INSUFFICIENT_BUFFER)) {
  77. delete [] (pbBuffer);
  78. pbBuffer = new BYTE[dwReqBufLen];
  79. dwBufLen = dwReqBufLen;
  80. mRec.dwMDDataLen = dwReqBufLen;
  81. mRec.pbMDData = pbBuffer;
  82. hRes = pIMetaSource->EnumData(hKeySource, SourceMDPath, &mRec, indx, &dwReqBufLen);
  83. }
  84. if ( SUCCEEDED(hRes) )
  85. {
  86. // write the property to the target
  87. if( mRec.dwMDIdentifier == MD_APP_ROOT )
  88. {
  89. // mRec.pbMDData = new WCHAR[MAX_PATH];
  90. wcscpy((LPWSTR)mRec.pbMDData, _bstr_t(L"/LM") + _bstr_t(TargetMDPath) );
  91. mRec.dwMDDataLen = (DWORD)(wcslen((LPWSTR)mRec.pbMDData)+1)*2;
  92. }
  93. hRes = pIMetaTarget->SetData(hKeyTarget,TargetMDPath,&mRec);
  94. if( !SUCCEEDED(hRes) )
  95. return hRes;
  96. }
  97. // Increment the index.
  98. indx++;
  99. } // End while.
  100. delete pbBuffer;
  101. //wprintf(L"Done numerating properties set at: %s ...\n",SourceMDPath);
  102. return S_OK;
  103. }
  104. // INPUT canonicalized source path node in relation to the root key "/LM" ex: /w3svc/1
  105. HRESULT CopyIISConfig(COSERVERINFO *pCoServerInfoSource, COSERVERINFO *pCoServerInfoTarget,
  106. WCHAR *pwszSourceKey, _bstr_t &bstrTargetKey)
  107. {
  108. HRESULT hRes;
  109. METADATA_HANDLE hKeySource;
  110. METADATA_HANDLE hKeyTarget;
  111. CComPtr <IMSAdminBase> pIMetaSource = 0L;
  112. CComPtr <IMSAdminBase> pIMetaTarget = 0L;
  113. BOOL bIsLocal;
  114. _bstr_t bstrRootKey = L"/LM";
  115. _bstr_t bstrTargetNode;
  116. long lTargetSiteID;
  117. // Declare a MULTI_QI for remote usage
  118. MULTI_QI rgmqi[1] = { &IID_IMSAdminBase,0,0 };
  119. ATLASSERT(pCoServerInfoSource);
  120. ATLASSERT(pCoServerInfoTarget);
  121. bIsLocal = IsServerLocal( (char*)_bstr_t(pCoServerInfoSource->pwszName) );
  122. hRes = CoCreateInstanceEx(CLSID_MSAdminBase,NULL, CLSCTX_ALL, pCoServerInfoSource,
  123. 1, rgmqi);
  124. if(SUCCEEDED(hRes))
  125. pIMetaSource = reinterpret_cast<IMSAdminBase*>(rgmqi[0].pItf);
  126. else
  127. {
  128. wprintf( L"error creating IMSAdminbase on machine: %s. HRESULT=%x\n", pCoServerInfoSource->pwszName, hRes);
  129. return hRes;
  130. }
  131. if( pCoServerInfoSource->pAuthInfo->pAuthIdentityData->User )
  132. {
  133. //hRes = SetBlanket(pIMetaSource);
  134. if (!SUCCEEDED(SetBlanket(pIMetaSource,pCoServerInfoSource->pAuthInfo->pAuthIdentityData->User,
  135. pCoServerInfoSource->pAuthInfo->pAuthIdentityData->Domain,
  136. pCoServerInfoSource->pAuthInfo->pAuthIdentityData->Password) ) )
  137. {
  138. _tprintf(_T("error setting COM impersonation: HRESULT=%x\n"), hRes);
  139. return hRes;
  140. }
  141. }
  142. if(bIsLocal)
  143. //hRes = pIMetaSource->QueryInterface(IID_IMSAdminBase,(void**)&pIMetaTarget);
  144. pIMetaTarget = pIMetaSource;
  145. else
  146. {
  147. // Create the IMSAdminBase object on the target server
  148. rgmqi[0].pItf = 0L;
  149. rgmqi[0].hr = 0L;
  150. hRes = CoCreateInstanceEx(CLSID_MSAdminBase,NULL, CLSCTX_ALL, pCoServerInfoTarget,
  151. 1, rgmqi);
  152. if(SUCCEEDED(hRes))
  153. pIMetaTarget = reinterpret_cast<IMSAdminBase*>(rgmqi[0].pItf);
  154. else
  155. {
  156. _tprintf(_T("error creating IMSAdminbase on this machine: %s. HRESULT=%x\n"),
  157. (char*)_bstr_t(pCoServerInfoTarget->pwszName), hRes);
  158. return hRes;
  159. }
  160. }
  161. // Open the metabase on the source and target
  162. if( bIsLocal )
  163. {
  164. if( !SUCCEEDED( hRes = pIMetaSource->OpenKey(METADATA_MASTER_ROOT_HANDLE, bstrRootKey,
  165. METADATA_PERMISSION_READ | METADATA_PERMISSION_WRITE, 10000, &hKeySource) ) )
  166. {
  167. _tprintf( _T("OpenKey() failed on the root key %s on server: %s, hr = %x\n"),
  168. (char*)bstrRootKey, (char*)_bstr_t(pCoServerInfoSource->pwszName), hRes );
  169. return hRes;
  170. }
  171. hKeyTarget = hKeySource;
  172. }
  173. else
  174. {
  175. // Get a handle to the Root key of the Source machine
  176. if( !SUCCEEDED( hRes = pIMetaSource->OpenKey(METADATA_MASTER_ROOT_HANDLE, bstrRootKey,
  177. METADATA_PERMISSION_READ , 10000, &hKeySource) ))
  178. {
  179. _tprintf( _T("OpenKey() failed on the root key %s on server: %s, hr = %x\n"),
  180. (char*)bstrRootKey, (char*)_bstr_t(pCoServerInfoSource->pwszName), hRes );
  181. return hRes;
  182. }
  183. // Get a handle to the Root key of the Target machine
  184. if( !SUCCEEDED( hRes = pIMetaTarget->OpenKey(METADATA_MASTER_ROOT_HANDLE, bstrRootKey,
  185. METADATA_PERMISSION_READ | METADATA_PERMISSION_WRITE, 10000, &hKeyTarget) ))
  186. {
  187. _tprintf( _T("OpenKey() failed on the root key %s on server: %s, hr = %x\n"),
  188. (char*)bstrRootKey, (char*)_bstr_t(pCoServerInfoTarget->pwszName), hRes );
  189. pIMetaSource->CloseKey(hKeySource);
  190. return hRes;
  191. }
  192. }
  193. if( bstrTargetKey.length() == 0 )
  194. {
  195. lTargetSiteID = GetAvailableSiteID(pIMetaTarget,hKeyTarget);
  196. bstrTargetNode = L"/W3SVC/";
  197. bstrTargetNode += _bstr_t(lTargetSiteID);
  198. bstrTargetKey = bstrTargetNode;
  199. }
  200. else
  201. bstrTargetNode = bstrTargetKey;
  202. // replicate the metabase node
  203. fwprintf(stderr, L"replicating IIS metabase properties set at: %s ...\n",pwszSourceKey);
  204. hRes = CreateAndCopyKey(pIMetaSource,hKeySource, pwszSourceKey,
  205. pIMetaTarget, hKeyTarget,bstrTargetNode, true );
  206. if( !SUCCEEDED(hRes) )
  207. {
  208. _tprintf( _T("Error encountered in metabase copy operation\n") );
  209. }
  210. pIMetaSource->CloseKey(hKeySource);
  211. if( !bIsLocal )
  212. pIMetaTarget->CloseKey( hKeyTarget );
  213. pIMetaSource = 0;
  214. pIMetaTarget = 0;
  215. return hRes;
  216. }
  217. HRESULT ApplyMBFixUp(COSERVERINFO *pCoServerInfo, WCHAR * pwszKey, WCHAR * pwszAppPoolID,
  218. PXCOPYTASKITEM pXCOPYList, WCHAR * pwszServerBinding, BOOL bApplyFPSE)
  219. {
  220. HRESULT hRes;
  221. METADATA_HANDLE hKey;
  222. CComPtr <IMSAdminBase> pIMeta = 0L;
  223. MULTI_QI rgmqi[1] = { &IID_IMSAdminBase,0,0 };
  224. WCHAR DataBuf[MAX_PATH];
  225. memset (DataBuf,0,sizeof(DataBuf) );
  226. PXCOPYTASKITEM pList = pXCOPYList;
  227. bstr_t bstrRealTargetPath;
  228. WCHAR *pTemp = NULL;
  229. DWORD dwFPSEBOOL;
  230. DWORD dwSize = sizeof(DWORD);
  231. _bstr_t bstrCommandline;
  232. TCHAR szOwsAdmPath[MAX_PATH];
  233. ZeroMemory(szOwsAdmPath,sizeof(szOwsAdmPath));
  234. ATLASSERT(pwszKey);
  235. if( !pCoServerInfo )
  236. return E_UNEXPECTED;
  237. if( SUCCEEDED(hRes = CoCreateInstanceEx(CLSID_MSAdminBase,NULL,
  238. CLSCTX_ALL, pCoServerInfo,1, rgmqi) ) )
  239. pIMeta = reinterpret_cast<IMSAdminBase*>(rgmqi[0].pItf);
  240. else
  241. {
  242. fwprintf( stderr, L"error creating IMSAdminbase on machine: %s. HRESULT=%x\n",
  243. pCoServerInfo->pwszName, hRes);
  244. return hRes;
  245. }
  246. if( UsesImpersonation(pCoServerInfo) )
  247. {
  248. if (!SUCCEEDED(hRes = SetBlanket(pIMeta,pCoServerInfo->pAuthInfo->pAuthIdentityData->User,
  249. pCoServerInfo->pAuthInfo->pAuthIdentityData->Domain,
  250. pCoServerInfo->pAuthInfo->pAuthIdentityData->Password) ) )
  251. {
  252. fwprintf( stderr, L"error setting CoSetProxyBlanket on machine: %s for user: %s HRESULT=%x\n",
  253. pCoServerInfo->pwszName,pCoServerInfo->pAuthInfo->pAuthIdentityData->User, hRes);
  254. pIMeta = 0;
  255. return hRes;
  256. }
  257. }
  258. if( !SUCCEEDED( hRes = pIMeta->OpenKey(METADATA_MASTER_ROOT_HANDLE, L"/LM",
  259. METADATA_PERMISSION_READ | METADATA_PERMISSION_WRITE , 10000, &hKey) ) )
  260. {
  261. fwprintf( stderr, L"Error opening key: %s on computer: %s. HRESULT=%x\n",
  262. L"/LM", pCoServerInfo->pwszName, hRes);
  263. pIMeta = 0;
  264. return hRes;
  265. }
  266. if( !SUCCEEDED( hRes = CreateAppPool(pIMeta,hKey,pwszAppPoolID) ) )
  267. {
  268. return hRes;
  269. }
  270. // Now set the AppPoolID property of the Key
  271. // wcscpy((LPWSTR)DataBuf, pwszAppPoolID);
  272. hRes = SetPropertyData(pIMeta,hKey,_bstr_t(pwszKey) + _bstr_t(L"/root"), MD_APP_APPPOOL_ID, METADATA_INHERIT,
  273. IIS_MD_UT_SERVER,STRING_METADATA, (PBYTE)pwszAppPoolID, (wcslen(pwszAppPoolID) + 1) * sizeof(WCHAR) );
  274. // Loope thought the list and reset any Path direcrories
  275. if( pList )
  276. {
  277. ATLASSERT(pList->pwszMBPath);
  278. ATLASSERT(pList->pwszDestPath);
  279. pTemp = wcsstr(_wcslwr(pList->pwszMBPath),L"/root");
  280. bstrRealTargetPath = _bstr_t(pwszKey) + _bstr_t(pTemp);
  281. hRes = SetPropertyData(pIMeta,hKey,bstrRealTargetPath, MD_VR_PATH, METADATA_INHERIT,
  282. IIS_MD_UT_FILE,STRING_METADATA, pList->pwszDestPath, (wcslen(pList->pwszDestPath) + 1) * sizeof(WCHAR) );
  283. while( pList->pNextItem )
  284. {
  285. pList = pList->pNextItem;
  286. pTemp = wcsstr(_wcslwr(pList->pwszMBPath),L"/root");
  287. bstrRealTargetPath = _bstr_t(pwszKey) + _bstr_t(pTemp);
  288. hRes = SetPropertyData(pIMeta,hKey,bstrRealTargetPath, MD_VR_PATH, METADATA_INHERIT,
  289. IIS_MD_UT_FILE,STRING_METADATA, pList->pwszDestPath, (wcslen(pList->pwszDestPath) + 1) * sizeof(WCHAR) );
  290. }
  291. }
  292. // Set the serverbinding string if present
  293. if( pwszServerBinding )
  294. {
  295. hRes = SetPropertyData(pIMeta,hKey,pwszKey, MD_SERVER_BINDINGS, METADATA_NO_ATTRIBUTES,
  296. IIS_MD_UT_SERVER,MULTISZ_METADATA, pwszServerBinding, (wcslen(pwszServerBinding) + 1) * sizeof(WCHAR) + 1 * sizeof(WCHAR));
  297. }
  298. if (bApplyFPSE)
  299. {
  300. // Check to see if the web is front page extended
  301. bstrCommandline = "-o install -p /lm";
  302. bstrCommandline += _bstr_t(pwszKey);
  303. hRes = GetPropertyData(pIMeta,hKey,pwszKey,MD_FRONTPAGE_WEB,METADATA_NO_ATTRIBUTES,
  304. IIS_MD_UT_SERVER, DWORD_METADATA, &dwFPSEBOOL, &dwSize );
  305. if( SUCCEEDED(hRes) )
  306. {
  307. if(SUCCEEDED(SHGetFolderPath(NULL, CSIDL_PROGRAM_FILES_COMMON , NULL, SHGFP_TYPE_CURRENT, szOwsAdmPath)) )
  308. {
  309. PathAppend(szOwsAdmPath, TEXT("Microsoft Shared\\Web Server Extensions\\50\\bin\\owsadm.exe") );
  310. }
  311. }
  312. }
  313. if( !SUCCEEDED(hRes = pIMeta->CloseKey(hKey) ) )
  314. {
  315. fwprintf( stderr, L"Error closing key: /LM/W3SVC on computer: %s. HRESULT=%x\n",
  316. pCoServerInfo->pwszName, hRes);
  317. }
  318. pIMeta = 0;
  319. if( bApplyFPSE )
  320. {
  321. fwprintf(stderr,L"reconfiguring FPSE settings...\n" );
  322. MyCreateProcess(szOwsAdmPath,bstrCommandline,CREATE_NEW_PROCESS_GROUP,360000);
  323. }
  324. return hRes;
  325. }
  326. HRESULT CreateAppPool(IMSAdminBase* pIMeta,METADATA_HANDLE hKey,WCHAR *pAppPoolID)
  327. {
  328. HRESULT hRes;
  329. _bstr_t bstrAppPoolPath(L"/w3svc/AppPools/");
  330. WCHAR DataBuf[MAX_PATH];
  331. memset (DataBuf,0,sizeof(DataBuf) );
  332. bstrAppPoolPath += pAppPoolID;
  333. hRes = pIMeta->AddKey(hKey,bstrAppPoolPath);
  334. // Set the KeyType property of the AppPool
  335. // hRes = SetKeyType( pIMeta, hKey, bstrAppPoolPath, L"IIsApplicationPool" );
  336. hRes = SetPropertyData(pIMeta,hKey,bstrAppPoolPath,MD_KEY_TYPE,METADATA_NO_ATTRIBUTES,
  337. IIS_MD_UT_SERVER,STRING_METADATA,L"IIsApplicationPool",(wcslen(L"IIsApplicationPool") + 1) * sizeof(WCHAR) );
  338. return hRes;
  339. }