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.

413 lines
11 KiB

  1. #define _WIN32_DCOM
  2. #include "util.h"
  3. #include <atlbase.h>
  4. #include <initguid.h>
  5. #include <comdef.h>
  6. #include <stdlib.h>
  7. #include <stdio.h>
  8. #include <wchar.h>
  9. #include <iiscnfg.h> // MD_ & IIS_MD_ #defines header file.
  10. #include "common.h" // log file routines
  11. #include "filecopy.h"
  12. #define BUFFER_SIZE 255
  13. #define CHUNK_SIZE 4098
  14. DWORD GetKeyNameFromPath(const WCHAR *pMBPath, WCHAR *pName, DWORD dwSize)
  15. {
  16. ATLASSERT(pMBPath);
  17. ATLASSERT(pName);
  18. DWORD dwLen = wcslen(pMBPath);
  19. DWORD pos = 0;
  20. ZeroMemory(pName,dwSize);
  21. for(DWORD i = dwLen-1; i >= 0; i--)
  22. {
  23. if( pMBPath[i] == '/' )
  24. break;
  25. }
  26. for( i = i+1; i < dwLen; i++ )
  27. pName[pos++] = pMBPath[i];
  28. return ERROR_SUCCESS;
  29. }
  30. long GetAvailableSiteID(IMSAdminBase* pIMeta, METADATA_HANDLE hRootKey)
  31. {
  32. DWORD indx = 0;
  33. WCHAR SubKeyName[MAX_PATH*2];
  34. HRESULT hRes = 0;
  35. WCHAR KeyType[256];
  36. long siteID = -1;
  37. while (SUCCEEDED(hRes)){
  38. hRes = pIMeta->EnumKeys(hRootKey, L"/W3SVC", SubKeyName, indx);
  39. if(SUCCEEDED(hRes)) {
  40. GetKeyTypeProperty(pIMeta,hRootKey,_bstr_t(L"/W3SVC/") + _bstr_t(SubKeyName),KeyType,256);
  41. if( _wcsicmp(KeyType,L"IIsWebServer") == 0 )
  42. {
  43. siteID = _wtol(SubKeyName);
  44. //wprintf(L"%s %s\n",SubKeyName,KeyType);
  45. }
  46. // Increment the index.
  47. }
  48. indx++;
  49. }
  50. siteID++;
  51. //wprintf(L"new site ID %d\n", siteID);
  52. return siteID;
  53. }
  54. BOOL IsKeyType(IMSAdminBase* pIMeta, METADATA_HANDLE hKey, wchar_t * pwszPath, wchar_t * key)
  55. {
  56. HRESULT hRes = 0;
  57. WCHAR KeyType[256];
  58. hRes = GetKeyTypeProperty(pIMeta,hKey,pwszPath,KeyType,256);
  59. if( _wcsicmp(KeyType,key) == 0 )
  60. {
  61. return true;
  62. }
  63. return false;
  64. }
  65. // Function to return the key type property of an hKey
  66. // 1002 is metabase ID code for KeyType property
  67. HRESULT GetKeyTypeProperty(IMSAdminBase* pIMeta, METADATA_HANDLE hKey, wchar_t * pwszPath, wchar_t *pwszBuffer, DWORD dwMDDataLen )
  68. {
  69. HRESULT hRes;
  70. METADATA_RECORD mRec;
  71. DWORD dwReqBufLen = 0;
  72. DWORD dwBufLen = BUFFER_SIZE;
  73. PBYTE pbBuffer = new BYTE[dwBufLen];
  74. if( !pIMeta || !hKey || !pwszPath)
  75. return E_UNEXPECTED;
  76. // this is the property for keytype
  77. mRec.dwMDIdentifier = 1002;
  78. mRec.dwMDAttributes = METADATA_INSERT_PATH;
  79. mRec.dwMDUserType = ALL_METADATA; //IIS_MD_UT_FILE ;
  80. mRec.dwMDDataType = ALL_METADATA;
  81. mRec.dwMDDataLen = dwBufLen;
  82. mRec.pbMDData = pbBuffer;
  83. // Open the key, if the key fails return false
  84. hRes = pIMeta->GetData(hKey, pwszPath, &mRec, &dwReqBufLen);
  85. if( !SUCCEEDED(hRes) )
  86. return hRes;
  87. wcscpy(pwszBuffer,(WCHAR *)mRec.pbMDData);
  88. //wprintf(L"The keytype property is: %s\n", pwszBuffer);
  89. return hRes;
  90. }
  91. // Generic wrapper to read property data
  92. HRESULT GetPropertyData(IMSAdminBase* pIMeta, METADATA_HANDLE hKey, wchar_t *pwszMDPath,
  93. DWORD dwMDIdentifier, DWORD dwMDAttributes, DWORD dwMDUserType, DWORD dwMDDataType,
  94. VOID * pData, DWORD *dwReqBufLen)
  95. {
  96. METADATA_RECORD mRec;
  97. ATLASSERT(pIMeta);
  98. if( !pIMeta )
  99. return E_UNEXPECTED;
  100. mRec.dwMDIdentifier = dwMDIdentifier;
  101. mRec.dwMDAttributes = dwMDAttributes;
  102. mRec.dwMDUserType = dwMDUserType;
  103. mRec.dwMDDataType = dwMDDataType;
  104. mRec.dwMDDataLen = *dwReqBufLen;
  105. mRec.pbMDData = (PBYTE)pData;
  106. return pIMeta->GetData(hKey, pwszMDPath, &mRec, dwReqBufLen);
  107. }
  108. // Generic wrapper to write property data
  109. HRESULT SetPropertyData(IMSAdminBase* pIMeta, METADATA_HANDLE hKey, wchar_t *pwszMDPath,
  110. DWORD dwMDIdentifier, DWORD dwMDAttributes, DWORD dwMDUserType,
  111. DWORD dwMDDataType, VOID * pData, DWORD dwDataLen)
  112. {
  113. HRESULT hRes = S_OK;
  114. METADATA_RECORD mRec;
  115. ATLASSERT( pIMeta );
  116. mRec.dwMDIdentifier = dwMDIdentifier;
  117. mRec.dwMDAttributes = dwMDAttributes;
  118. mRec.dwMDUserType = dwMDUserType;
  119. mRec.dwMDDataType = dwMDDataType;
  120. mRec.pbMDData = (PBYTE)pData;
  121. mRec.dwMDDataLen = dwDataLen;
  122. return pIMeta->SetData(hKey, pwszMDPath, &mRec);
  123. }
  124. DWORD MyCreateProcess( LPTSTR appName, LPTSTR cmdLine, DWORD dwCreationFlags, DWORD dwTimeOut )
  125. {
  126. STARTUPINFO si = {0};
  127. si.cb = sizeof( si );
  128. PROCESS_INFORMATION pi = {0};
  129. bstr_t cApplicationName( appName );
  130. bstr_t cCommandLine( cApplicationName);
  131. //cCommandLine += ( TEXT(" ") );
  132. cCommandLine = cmdLine;
  133. Log( TEXT("executing: %s"), (char*)cCommandLine );
  134. BOOL bOK = CreateProcess(
  135. (char*)cApplicationName, // LPCTSTR lpApplicationName, // name of executable module
  136. (char*) cCommandLine, // LPTSTR lpCommandLine, // command line string
  137. NULL, // LPSECURITY_ATTRIBUTES lpProcessAttributes, // SD
  138. NULL, // LPSECURITY_ATTRIBUTES lpThreadAttributes, // SD
  139. NULL, // BOOL bInheritHandles, // handle inheritance option
  140. dwCreationFlags, // DWORD dwCreationFlags, // creation flags
  141. NULL, // LPVOID lpEnvironment, // new environment block
  142. NULL, // LPCTSTR lpCurrentDirectory, // current directory name
  143. &si, // LPSTARTUPINFO lpStartupInfo, // startup information
  144. &pi ); // LPPROCESS_INFORMATION lpProcessInformation // process information
  145. if( !bOK )
  146. {
  147. Log( TEXT( "FAIL: CreateProcess() failed, error code=%d" ), GetLastError() );
  148. return GetLastError();
  149. }
  150. DWORD dwRet = WaitForSingleObject( pi.hProcess, dwTimeOut );
  151. if( dwRet == WAIT_TIMEOUT )
  152. {
  153. Log( TEXT( "FAIL: CreateProcess() timed out" ) );
  154. return ERROR_SEM_TIMEOUT;
  155. }
  156. else if( dwRet == WAIT_ABANDONED )
  157. {
  158. Log( TEXT( "FAIL: WaitForSingleObject() failed on WAIT_ABANDONED" ) );
  159. return ERROR_SEM_TIMEOUT;
  160. }
  161. else if( dwRet == WAIT_FAILED )
  162. {
  163. LogError( TEXT( "FAIL: WaitForSingleObject() failed" ), GetLastError() );
  164. return GetLastError();
  165. }
  166. DWORD dwExitCode = 0;
  167. if( GetExitCodeProcess( pi.hProcess, &dwExitCode ) )
  168. {
  169. if( dwExitCode )
  170. {
  171. Log( TEXT( "FAIL: net.exe() threw an error=%d" ), dwExitCode );
  172. return dwExitCode;
  173. }
  174. else
  175. {
  176. Log( TEXT( "CreateProcess() succeeded" ) );
  177. }
  178. }
  179. else
  180. {
  181. LogError( TEXT( "GetExitCodeProcess()" ), GetLastError() );
  182. return GetLastError();
  183. }
  184. return ERROR_SUCCESS;
  185. }
  186. DWORD NET(WCHAR* device, WCHAR* user, WCHAR* password)
  187. {
  188. STARTUPINFO si = {0};
  189. si.cb = sizeof( si );
  190. PROCESS_INFORMATION pi = {0};
  191. TCHAR szSystemFolder[ MAX_PATH ];
  192. if( 0 == GetSystemDirectory( szSystemFolder, MAX_PATH ) )
  193. {
  194. return GetLastError();
  195. }
  196. bstr_t cApplicationName( szSystemFolder );
  197. cApplicationName += ( TEXT( "\\net.exe" ) );
  198. bstr_t cCommandLine( cApplicationName);
  199. cCommandLine += ( TEXT(" use \\\\") );
  200. cCommandLine += device;
  201. cCommandLine += ( TEXT(" /user:") );
  202. cCommandLine += user;
  203. cCommandLine += ( TEXT(" ") );
  204. cCommandLine += password;
  205. Log( TEXT("executing: %s"), (char*)cCommandLine );
  206. BOOL bOK = CreateProcess(
  207. (char*)cApplicationName, // LPCTSTR lpApplicationName, // name of executable module
  208. (char*) cCommandLine, // LPTSTR lpCommandLine, // command line string
  209. NULL, // LPSECURITY_ATTRIBUTES lpProcessAttributes, // SD
  210. NULL, // LPSECURITY_ATTRIBUTES lpThreadAttributes, // SD
  211. NULL, // BOOL bInheritHandles, // handle inheritance option
  212. CREATE_NEW_PROCESS_GROUP, // DWORD dwCreationFlags, // creation flags
  213. NULL, // LPVOID lpEnvironment, // new environment block
  214. NULL, // LPCTSTR lpCurrentDirectory, // current directory name
  215. &si, // LPSTARTUPINFO lpStartupInfo, // startup information
  216. &pi ); // LPPROCESS_INFORMATION lpProcessInformation // process information
  217. if( !bOK )
  218. {
  219. Log( TEXT( "FAIL: CreateProcess() failed, error code=%d" ), GetLastError() );
  220. return GetLastError();
  221. }
  222. DWORD dwRet = WaitForSingleObject( pi.hProcess, 15000 );
  223. if( dwRet == WAIT_TIMEOUT )
  224. {
  225. Log( TEXT( "FAIL: CreateProcess() timed out" ) );
  226. return ERROR_SEM_TIMEOUT;
  227. }
  228. else if( dwRet == WAIT_ABANDONED )
  229. {
  230. Log( TEXT( "FAIL: WaitForSingleObject() failed on WAIT_ABANDONED" ) );
  231. return ERROR_SEM_TIMEOUT;
  232. }
  233. else if( dwRet == WAIT_FAILED )
  234. {
  235. LogError( TEXT( "FAIL: WaitForSingleObject() failed" ), GetLastError() );
  236. return GetLastError();
  237. }
  238. DWORD dwExitCode = 0;
  239. if( GetExitCodeProcess( pi.hProcess, &dwExitCode ) )
  240. {
  241. if( dwExitCode )
  242. {
  243. Log( TEXT( "FAIL: net.exe() threw an error=%d" ), dwExitCode );
  244. return dwExitCode;
  245. }
  246. else
  247. {
  248. Log( TEXT( "CreateProcess() succeeded" ) );
  249. }
  250. }
  251. else
  252. {
  253. LogError( TEXT( "GetExitCodeProcess()" ), GetLastError() );
  254. return GetLastError();
  255. }
  256. return ERROR_SUCCESS;
  257. }
  258. BOOL
  259. IsServerLocal(
  260. IN LPCTSTR lpszServer
  261. )
  262. /*++
  263. Routine Description:
  264. Check to see if the given name refers to the local machine
  265. Arguments:
  266. LPCTSTR lpszServer : Server name
  267. Return Value:
  268. TRUE if the given name refers to the local computer, FALSE otherwise
  269. Note:
  270. Doesn't work if the server is an ip address
  271. --*/
  272. {
  273. TCHAR szComputerName[MAX_COMPUTERNAME_LENGTH + 1];
  274. DWORD dwSize = sizeof(szComputerName);
  275. //
  276. // CODEWORK(?): we're not checking for all the ip addresses
  277. // on the local box or full dns names.
  278. //
  279. // Try GetComputerNameEx when we're building with NT5
  280. // settings.
  281. //
  282. return (!_tcsicmp(_T("localhost"), PURE_COMPUTER_NAME(lpszServer))
  283. || !_tcscmp( _T("127.0.0.1"), PURE_COMPUTER_NAME(lpszServer)))
  284. || (GetComputerName(szComputerName, &dwSize)
  285. && !_tcsicmp(szComputerName, PURE_COMPUTER_NAME(lpszServer)));
  286. }
  287. HRESULT SetBlanket(LPUNKNOWN pIUnk, WCHAR* user, WCHAR* domain, WCHAR* password)
  288. {
  289. SEC_WINNT_AUTH_IDENTITY_W* pAuthIdentity =
  290. new SEC_WINNT_AUTH_IDENTITY_W;
  291. ZeroMemory(pAuthIdentity, sizeof(SEC_WINNT_AUTH_IDENTITY_W) );
  292. if( !pIUnk || !user )
  293. return E_UNEXPECTED;
  294. pAuthIdentity->User = new WCHAR[32];
  295. wcscpy(pAuthIdentity->User , user);
  296. pAuthIdentity->UserLength = wcslen(pAuthIdentity->User );
  297. if( domain )
  298. {
  299. pAuthIdentity-> Domain = new WCHAR[32];
  300. wcscpy(pAuthIdentity->Domain, domain );
  301. pAuthIdentity->DomainLength = wcslen( pAuthIdentity->Domain);
  302. }
  303. if( password )
  304. {
  305. pAuthIdentity-> Password = new WCHAR[32];
  306. pAuthIdentity->Password = password;
  307. pAuthIdentity->PasswordLength = wcslen( pAuthIdentity->Password );
  308. }
  309. pAuthIdentity->Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
  310. return CoSetProxyBlanket( pIUnk,
  311. RPC_C_AUTHN_WINNT, // NTLM authentication service
  312. RPC_C_AUTHZ_NONE, // default authorization service...
  313. NULL, // no mutual authentication
  314. RPC_C_AUTHN_LEVEL_DEFAULT, // authentication level
  315. RPC_C_IMP_LEVEL_IMPERSONATE, // impersonation level
  316. pAuthIdentity, // use current token
  317. EOAC_NONE ); // no special capabilities
  318. }