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

// MetaExp.cpp : Defines the entry point for the console application.
//
#define _WIN32_DCOM
#include <atlbase.h>
#include <atlconv.h>
#include <initguid.h>
#include <comdef.h>
#include <stdio.h>
#include <iadmw.h> // COM Interface header file.
#include <iiscnfg.h> // MD_ & IIS_MD_ #defines header file.
#include <conio.h>
#include "util.h"
#include "auth.h"
#include "filecopy.h"
#include "mbase.h"
#define DEFAULT_APP_POOL_ID L"ImportedAppPool"
PXCOPYTASKITEM g_pTaskItemList;
void Usage(WCHAR* image)
{
wprintf( L"\nDescription: Utility for moving IIS web sites from server to server\n\n" );
wprintf( L"Usage: %s <source machine name> <metabase path> [/o /d:<root directory> /a:<app pool id> /s /c]\n\n", image );
wprintf( L"\t/d:<path> specify root directory path\n");
wprintf( L"\t/m:<metabase path> specify metabase path for target server\n");
wprintf( L"\t/a:<apppool> specify app pool ID\n");
wprintf( L"\t/b:<serverbinding> serverbindings string\n");
wprintf( L"\t/c copy IIS configuration only\n");
wprintf( L"\t/u:<user> username to connect to source server\n");
wprintf( L"\t/p:<pwd> password to connect to source server\n\n");
wprintf( L"Examples:\n\t%s IIS-01 /lm/w3svc/1\n", image );
wprintf( L"\t%s IIS-01 /lm/w3svc/2 /d:f:\\inetpub\\wwwroot /c\n", image );
wprintf( L"\t%s IIS-01 /lm/w3svc/2 /d:f:\\inetpub\\wwwroot /m:w3svc/3\n", image );
wprintf( L"\t%s IIS-01 /lm/w3svc/2 /d:f:\\inetpub\\wwwroot /a:MyAppPool\n", image );
wprintf( L"\t%s IIS-01 /lm/w3svc/2 /d:f:\\inetpub\\wwwroot /b:192.168.1.1:80:www.mysite.com\n", image );
wprintf( L"\n");
}
int
wmain(int argc, wchar_t* argv[])
{
HRESULT hRes = 0L;
wchar_t** argp;
_bstr_t bstrRootKey = L"/LM";
_bstr_t bstrSourceServer;
_bstr_t bstrSourceNode;
_bstr_t bstrArgz;
_bstr_t bstrTargetNode;
_bstr_t bstrTargetDir;
_bstr_t bstrAppPoolID = DEFAULT_APP_POOL_ID;
_bstr_t bstrRemoteUserName;
_bstr_t bstrRemoteUserPass;
_bstr_t bstrDomainName;
_bstr_t bstrServerBindings;
char userpassword[81];
BOOL bCopyContent = true;
BOOL bCopySubKeys = true;
BOOL bIsLocal = false;
BOOL bUsesImpersonation = false;
COSERVERINFO *pServerInfoSource = NULL;
COSERVERINFO *pServerInfoTarget = NULL;
PXCOPYTASKITEM pListItem = NULL;
g_pTaskItemList = NULL;
hRes = CoInitialize(NULL);
// check for the required command-line arguments
if( argc < 3) {
Usage( argv[0] );
return -1;
}
bstrSourceServer = argv[1];
// cannonicalize the node value
bstrSourceNode = argv[2];
//bstrSourceNode += wcsstr( _wcslwr( argv[2] ), L"w3svc") ;
for (argp = argv + 3; *argp != NULL; argp++ ) {
if( (**argp == '/') || (**argp == '-') )
{
bstrArgz = *argp+1;
if( !_strnicmp( (char*)bstrArgz, "M:", sizeof("M:")-1) )
{
bstrTargetNode = *argp + sizeof("M:") ;
_tprintf(_T("target metabase key: %s\n"),(char *)bstrTargetNode);
continue;
}
if( !_strnicmp( (char*)bstrArgz, "D:", sizeof("D:")-1) )
{
bstrTargetDir = *argp + sizeof("D:");
_tprintf(_T("target dir: %s\n"),(char *)bstrTargetDir);
continue;
}
if( !_strnicmp( (char*)bstrArgz, "C", sizeof("C")-1) )
{
bCopyContent = false;
_tprintf(_T("copy metabase configuration only: true\n"));
continue;
}
if( !_strnicmp( (char*)bstrArgz, "A:", sizeof("A:")-1) )
{
bstrAppPoolID = *argp + sizeof("A:");
_tprintf(_T("app pool ID: %s\n"),(char *)bstrAppPoolID);
continue;
}
if( !_strnicmp( (char*)bstrArgz, "B:", sizeof("B:")-1) )
{
bstrServerBindings = *argp + sizeof("B:");
_tprintf(_T("ServerBindings: %s\n"),(char *)bstrServerBindings);
continue;
}
if( !_strnicmp( (char*)bstrArgz, "U:", sizeof("U:")-1) )
{
bstrRemoteUserName = *argp + sizeof("U:");
bUsesImpersonation = true;
_tprintf(_T("Remote User Name: %s\n"), (char*)bstrRemoteUserName );
continue;
}
if( !_strnicmp( (char*)bstrArgz, "P:", sizeof("P:")-1) )
{
bstrRemoteUserPass = *argp + sizeof("U:");
_tprintf(_T("Remote User Name: *********\n"));
continue;
}
fprintf(stderr, "unknown option '%s'\n", *argp+1);
return 1;
}
else
{
fprintf(stderr, "unknown option '%s'\n", (char *)bstrArgz);
return 1;
}
}
// If the user password is not present, then read from the command line
// echo '*' characters to obfuscate passord
if( (bstrRemoteUserName.length() > 0) && (bstrRemoteUserPass.length() < 1) )
{
_tprintf(_T("Enter the password for %s "), (char*)bstrRemoteUserName);
char ch;
int i;
ch = getch();
for( i = 0;i < 80; i++)
{
if(ch == 13)
break;
userpassword[i] = ch;
putch('*');
ch = getch();
}
userpassword[i] = NULL;
bstrRemoteUserPass = userpassword;
}
// cannonicalize the source metabase node
if( NULL == wcsstr( _wcslwr( bstrSourceNode ), L"w3svc") )
{
fwprintf(stderr,L"source path value %s is invalid format\n", bstrSourceNode.GetBSTR() );
return 1;
}
bstrSourceNode = _bstr_t("/") + _bstr_t(wcsstr( _wcslwr( bstrSourceNode ), L"w3svc") ) ;
_tprintf(_T("Source metabase key: %s\n"), (char*)bstrSourceNode );
// cannonicalize the target metabase node if present, otherwise it is the source
if( bstrTargetNode.length() > 0 )
{
if( NULL == wcsstr( _wcslwr( bstrTargetNode ), L"w3svc") )
{
fwprintf(stderr,L"target path value %s is invalid format\n", bstrTargetNode.GetBSTR() );
return 1;
}
bstrTargetNode = _bstr_t("/") + _bstr_t(wcsstr( _wcslwr( bstrTargetNode ), L"w3svc") ) ;
_tprintf(_T("Target metabase key: %s\n"), (char*)bstrTargetNode );
}
if( IsServerLocal((char*)bstrSourceServer) )
{
bIsLocal = true;
if( bstrSourceNode == bstrTargetNode )
{
fwprintf(stderr,L"cannot import same node for local copy. Program exiting\n");
return 1;
}
if( bCopyContent && !bstrTargetDir)
{
fwprintf(stderr,L"cannot overwrite directory same node for local copy. Program exiting\n");
return 1;
}
}
// Create COSERVERINFO structs used for DCOM connection to source and
// target servers
pServerInfoSource = CreateServerInfoStruct(bstrSourceServer,bstrRemoteUserName,bstrDomainName,
bstrRemoteUserPass,RPC_C_AUTHN_LEVEL_CONNECT);
ATLASSERT( pServerInfoSource );
pServerInfoTarget = CreateServerInfoStruct(L"localhost",NULL,NULL,NULL,0,false);
ATLASSERT( pServerInfoTarget );
// check if user can connect and open a metabase key on the source machine
if( !AUTHUSER(pServerInfoSource) )
{
fwprintf(stderr,L"could not open metabase on server %s. Program exiting\n",
pServerInfoSource->pwszName );
return 1;
}
// check if user can connect and open a metabase key on the target machine
if( !AUTHUSER(pServerInfoTarget) )
{
fwprintf(stderr,L"could not open metabase on server %s. Program exiting\n",
pServerInfoTarget->pwszName );
goto cleanup;
}
// Check to see if the node is of type IIsWebServer
if( !ValidateNode(pServerInfoSource,bstrSourceNode,L"IIsWebServer") )
{
fwprintf(stderr,L"source key %s must be of type IIsWebServer. Program exiting\n",
bstrSourceNode );
goto cleanup;
}
if( bIsLocal && (bstrTargetDir.length() < 1) )
fwprintf(stderr,L"skipping content copy for local copy\n");
else
{
if( bUsesImpersonation ) // use "net use" command to connect to the remote comupter so Admin shares can
// be used
if ( ERROR_SUCCESS != NET(bstrSourceServer,bstrRemoteUserName,bstrRemoteUserPass) )
{
_tprintf( _T("Error encountered in NET USE operation\n") );
goto cleanup;
}
// if bCopyContent parameter is true, then this function will actually copy the content
// otherwise it just builds a TaskItemList of nodes that will need their Path parameter reset
CopyContent(pServerInfoSource,bstrSourceNode + _bstr_t(L"/root"),bstrTargetDir,
&pListItem, bCopyContent );
}
// bstrTarget node will be returned with the target node of the target, if it is passed in as blank.
hRes = CopyIISConfig(pServerInfoSource,pServerInfoTarget,bstrSourceNode,bstrTargetNode);
if( !SUCCEEDED(hRes) )
{
fwprintf(stderr,L"Error encountered with metabase copy. HRESULT = %x\n",hRes);
goto cleanup;
}
hRes = ApplyMBFixUp(pServerInfoTarget,bstrTargetNode,bstrAppPoolID,
pListItem, bstrServerBindings, true );
_tprintf(_T("finished.\n") );
cleanup:
FreeServerInfoStruct(pServerInfoSource);
FreeServerInfoStruct(pServerInfoTarget);
FreeXCOPYTaskList(pListItem);
CoUninitialize();
return 0;
}