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.

291 lines
8.7 KiB

  1. // MetaExp.cpp : Defines the entry point for the console application.
  2. //
  3. #define _WIN32_DCOM
  4. #include <atlbase.h>
  5. #include <atlconv.h>
  6. #include <initguid.h>
  7. #include <comdef.h>
  8. #include <stdio.h>
  9. #include <iadmw.h> // COM Interface header file.
  10. #include <iiscnfg.h> // MD_ & IIS_MD_ #defines header file.
  11. #include <conio.h>
  12. #include "util.h"
  13. #include "auth.h"
  14. #include "filecopy.h"
  15. #include "mbase.h"
  16. #define DEFAULT_APP_POOL_ID L"ImportedAppPool"
  17. PXCOPYTASKITEM g_pTaskItemList;
  18. void Usage(WCHAR* image)
  19. {
  20. wprintf( L"\nDescription: Utility for moving IIS web sites from server to server\n\n" );
  21. wprintf( L"Usage: %s <source machine name> <metabase path> [/o /d:<root directory> /a:<app pool id> /s /c]\n\n", image );
  22. wprintf( L"\t/d:<path> specify root directory path\n");
  23. wprintf( L"\t/m:<metabase path> specify metabase path for target server\n");
  24. wprintf( L"\t/a:<apppool> specify app pool ID\n");
  25. wprintf( L"\t/b:<serverbinding> serverbindings string\n");
  26. wprintf( L"\t/c copy IIS configuration only\n");
  27. wprintf( L"\t/u:<user> username to connect to source server\n");
  28. wprintf( L"\t/p:<pwd> password to connect to source server\n\n");
  29. wprintf( L"Examples:\n\t%s IIS-01 /lm/w3svc/1\n", image );
  30. wprintf( L"\t%s IIS-01 /lm/w3svc/2 /d:f:\\inetpub\\wwwroot /c\n", image );
  31. wprintf( L"\t%s IIS-01 /lm/w3svc/2 /d:f:\\inetpub\\wwwroot /m:w3svc/3\n", image );
  32. wprintf( L"\t%s IIS-01 /lm/w3svc/2 /d:f:\\inetpub\\wwwroot /a:MyAppPool\n", image );
  33. wprintf( L"\t%s IIS-01 /lm/w3svc/2 /d:f:\\inetpub\\wwwroot /b:192.168.1.1:80:www.mysite.com\n", image );
  34. wprintf( L"\n");
  35. }
  36. int
  37. wmain(int argc, wchar_t* argv[])
  38. {
  39. HRESULT hRes = 0L;
  40. wchar_t** argp;
  41. _bstr_t bstrRootKey = L"/LM";
  42. _bstr_t bstrSourceServer;
  43. _bstr_t bstrSourceNode;
  44. _bstr_t bstrArgz;
  45. _bstr_t bstrTargetNode;
  46. _bstr_t bstrTargetDir;
  47. _bstr_t bstrAppPoolID = DEFAULT_APP_POOL_ID;
  48. _bstr_t bstrRemoteUserName;
  49. _bstr_t bstrRemoteUserPass;
  50. _bstr_t bstrDomainName;
  51. _bstr_t bstrServerBindings;
  52. char userpassword[81];
  53. BOOL bCopyContent = true;
  54. BOOL bCopySubKeys = true;
  55. BOOL bIsLocal = false;
  56. BOOL bUsesImpersonation = false;
  57. COSERVERINFO *pServerInfoSource = NULL;
  58. COSERVERINFO *pServerInfoTarget = NULL;
  59. PXCOPYTASKITEM pListItem = NULL;
  60. g_pTaskItemList = NULL;
  61. hRes = CoInitialize(NULL);
  62. // check for the required command-line arguments
  63. if( argc < 3) {
  64. Usage( argv[0] );
  65. return -1;
  66. }
  67. bstrSourceServer = argv[1];
  68. // cannonicalize the node value
  69. bstrSourceNode = argv[2];
  70. //bstrSourceNode += wcsstr( _wcslwr( argv[2] ), L"w3svc") ;
  71. for (argp = argv + 3; *argp != NULL; argp++ ) {
  72. if( (**argp == '/') || (**argp == '-') )
  73. {
  74. bstrArgz = *argp+1;
  75. if( !_strnicmp( (char*)bstrArgz, "M:", sizeof("M:")-1) )
  76. {
  77. bstrTargetNode = *argp + sizeof("M:") ;
  78. _tprintf(_T("target metabase key: %s\n"),(char *)bstrTargetNode);
  79. continue;
  80. }
  81. if( !_strnicmp( (char*)bstrArgz, "D:", sizeof("D:")-1) )
  82. {
  83. bstrTargetDir = *argp + sizeof("D:");
  84. _tprintf(_T("target dir: %s\n"),(char *)bstrTargetDir);
  85. continue;
  86. }
  87. if( !_strnicmp( (char*)bstrArgz, "C", sizeof("C")-1) )
  88. {
  89. bCopyContent = false;
  90. _tprintf(_T("copy metabase configuration only: true\n"));
  91. continue;
  92. }
  93. if( !_strnicmp( (char*)bstrArgz, "A:", sizeof("A:")-1) )
  94. {
  95. bstrAppPoolID = *argp + sizeof("A:");
  96. _tprintf(_T("app pool ID: %s\n"),(char *)bstrAppPoolID);
  97. continue;
  98. }
  99. if( !_strnicmp( (char*)bstrArgz, "B:", sizeof("B:")-1) )
  100. {
  101. bstrServerBindings = *argp + sizeof("B:");
  102. _tprintf(_T("ServerBindings: %s\n"),(char *)bstrServerBindings);
  103. continue;
  104. }
  105. if( !_strnicmp( (char*)bstrArgz, "U:", sizeof("U:")-1) )
  106. {
  107. bstrRemoteUserName = *argp + sizeof("U:");
  108. bUsesImpersonation = true;
  109. _tprintf(_T("Remote User Name: %s\n"), (char*)bstrRemoteUserName );
  110. continue;
  111. }
  112. if( !_strnicmp( (char*)bstrArgz, "P:", sizeof("P:")-1) )
  113. {
  114. bstrRemoteUserPass = *argp + sizeof("U:");
  115. _tprintf(_T("Remote User Name: *********\n"));
  116. continue;
  117. }
  118. fprintf(stderr, "unknown option '%s'\n", *argp+1);
  119. return 1;
  120. }
  121. else
  122. {
  123. fprintf(stderr, "unknown option '%s'\n", (char *)bstrArgz);
  124. return 1;
  125. }
  126. }
  127. // If the user password is not present, then read from the command line
  128. // echo '*' characters to obfuscate passord
  129. if( (bstrRemoteUserName.length() > 0) && (bstrRemoteUserPass.length() < 1) )
  130. {
  131. _tprintf(_T("Enter the password for %s "), (char*)bstrRemoteUserName);
  132. char ch;
  133. int i;
  134. ch = getch();
  135. for( i = 0;i < 80; i++)
  136. {
  137. if(ch == 13)
  138. break;
  139. userpassword[i] = ch;
  140. putch('*');
  141. ch = getch();
  142. }
  143. userpassword[i] = NULL;
  144. bstrRemoteUserPass = userpassword;
  145. }
  146. // cannonicalize the source metabase node
  147. if( NULL == wcsstr( _wcslwr( bstrSourceNode ), L"w3svc") )
  148. {
  149. fwprintf(stderr,L"source path value %s is invalid format\n", bstrSourceNode.GetBSTR() );
  150. return 1;
  151. }
  152. bstrSourceNode = _bstr_t("/") + _bstr_t(wcsstr( _wcslwr( bstrSourceNode ), L"w3svc") ) ;
  153. _tprintf(_T("Source metabase key: %s\n"), (char*)bstrSourceNode );
  154. // cannonicalize the target metabase node if present, otherwise it is the source
  155. if( bstrTargetNode.length() > 0 )
  156. {
  157. if( NULL == wcsstr( _wcslwr( bstrTargetNode ), L"w3svc") )
  158. {
  159. fwprintf(stderr,L"target path value %s is invalid format\n", bstrTargetNode.GetBSTR() );
  160. return 1;
  161. }
  162. bstrTargetNode = _bstr_t("/") + _bstr_t(wcsstr( _wcslwr( bstrTargetNode ), L"w3svc") ) ;
  163. _tprintf(_T("Target metabase key: %s\n"), (char*)bstrTargetNode );
  164. }
  165. if( IsServerLocal((char*)bstrSourceServer) )
  166. {
  167. bIsLocal = true;
  168. if( bstrSourceNode == bstrTargetNode )
  169. {
  170. fwprintf(stderr,L"cannot import same node for local copy. Program exiting\n");
  171. return 1;
  172. }
  173. if( bCopyContent && !bstrTargetDir)
  174. {
  175. fwprintf(stderr,L"cannot overwrite directory same node for local copy. Program exiting\n");
  176. return 1;
  177. }
  178. }
  179. // Create COSERVERINFO structs used for DCOM connection to source and
  180. // target servers
  181. pServerInfoSource = CreateServerInfoStruct(bstrSourceServer,bstrRemoteUserName,bstrDomainName,
  182. bstrRemoteUserPass,RPC_C_AUTHN_LEVEL_CONNECT);
  183. ATLASSERT( pServerInfoSource );
  184. pServerInfoTarget = CreateServerInfoStruct(L"localhost",NULL,NULL,NULL,0,false);
  185. ATLASSERT( pServerInfoTarget );
  186. // check if user can connect and open a metabase key on the source machine
  187. if( !AUTHUSER(pServerInfoSource) )
  188. {
  189. fwprintf(stderr,L"could not open metabase on server %s. Program exiting\n",
  190. pServerInfoSource->pwszName );
  191. return 1;
  192. }
  193. // check if user can connect and open a metabase key on the target machine
  194. if( !AUTHUSER(pServerInfoTarget) )
  195. {
  196. fwprintf(stderr,L"could not open metabase on server %s. Program exiting\n",
  197. pServerInfoTarget->pwszName );
  198. goto cleanup;
  199. }
  200. // Check to see if the node is of type IIsWebServer
  201. if( !ValidateNode(pServerInfoSource,bstrSourceNode,L"IIsWebServer") )
  202. {
  203. fwprintf(stderr,L"source key %s must be of type IIsWebServer. Program exiting\n",
  204. bstrSourceNode );
  205. goto cleanup;
  206. }
  207. if( bIsLocal && (bstrTargetDir.length() < 1) )
  208. fwprintf(stderr,L"skipping content copy for local copy\n");
  209. else
  210. {
  211. if( bUsesImpersonation ) // use "net use" command to connect to the remote comupter so Admin shares can
  212. // be used
  213. if ( ERROR_SUCCESS != NET(bstrSourceServer,bstrRemoteUserName,bstrRemoteUserPass) )
  214. {
  215. _tprintf( _T("Error encountered in NET USE operation\n") );
  216. goto cleanup;
  217. }
  218. // if bCopyContent parameter is true, then this function will actually copy the content
  219. // otherwise it just builds a TaskItemList of nodes that will need their Path parameter reset
  220. CopyContent(pServerInfoSource,bstrSourceNode + _bstr_t(L"/root"),bstrTargetDir,
  221. &pListItem, bCopyContent );
  222. }
  223. // bstrTarget node will be returned with the target node of the target, if it is passed in as blank.
  224. hRes = CopyIISConfig(pServerInfoSource,pServerInfoTarget,bstrSourceNode,bstrTargetNode);
  225. if( !SUCCEEDED(hRes) )
  226. {
  227. fwprintf(stderr,L"Error encountered with metabase copy. HRESULT = %x\n",hRes);
  228. goto cleanup;
  229. }
  230. hRes = ApplyMBFixUp(pServerInfoTarget,bstrTargetNode,bstrAppPoolID,
  231. pListItem, bstrServerBindings, true );
  232. _tprintf(_T("finished.\n") );
  233. cleanup:
  234. FreeServerInfoStruct(pServerInfoSource);
  235. FreeServerInfoStruct(pServerInfoTarget);
  236. FreeXCOPYTaskList(pListItem);
  237. CoUninitialize();
  238. return 0;
  239. }