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.

524 lines
14 KiB

  1. /**********************************************************************/
  2. /** Microsoft Windows/NT **/
  3. /** Copyright(c) Microsoft Corporation, 1997 - 1999 **/
  4. /**********************************************************************/
  5. /*
  6. rtrcomn.cpp
  7. FILE HISTORY:
  8. */
  9. #include "stdafx.h"
  10. #include "tfschar.h"
  11. #include "info.h"
  12. #include "rtrstr.h"
  13. #include "rtrcomn.h"
  14. #include "rtrguid.h"
  15. #include "mprapi.h"
  16. #include "rtrutil.h"
  17. #include "lsa.h"
  18. #include "tregkey.h"
  19. #include "reg.h"
  20. /*---------------------------------------------------------------------------
  21. Function: IfInterfaceIdHasIpxExtensions
  22. Checks the string to see if it has the following extensions
  23. EthernetSNAP
  24. EthernetII
  25. Ethernet802.2
  26. Ethernet802.3
  27. ---------------------------------------------------------------------------*/
  28. int IfInterfaceIdHasIpxExtensions(LPCTSTR pszIfId)
  29. {
  30. CString stIfEnd;
  31. CString stIf = pszIfId;
  32. BOOL bFound = TRUE;
  33. int iPos = 0;
  34. do
  35. {
  36. stIfEnd = stIf.Right(lstrlen(c_szEthernetII));
  37. if (stIfEnd == c_szEthernetII)
  38. break;
  39. stIfEnd = stIf.Right(lstrlen(c_szEthernetSNAP));
  40. if (stIfEnd == c_szEthernetSNAP)
  41. break;
  42. stIfEnd = stIf.Right(lstrlen(c_szEthernet8022));
  43. if (stIfEnd == c_szEthernet8022)
  44. break;
  45. stIfEnd = stIf.Right(lstrlen(c_szEthernet8023));
  46. if (stIfEnd == c_szEthernet8023)
  47. break;
  48. bFound = FALSE;
  49. }
  50. while (FALSE);
  51. if (bFound)
  52. iPos = stIf.GetLength() - stIfEnd.GetLength();
  53. return iPos;
  54. }
  55. extern const GUID CLSID_RemoteRouterConfig;
  56. HRESULT CoCreateRouterConfig(LPCTSTR pszMachine,
  57. IRouterInfo *pRouter,
  58. COSERVERINFO *pcsi,
  59. const GUID& riid,
  60. IUnknown **ppUnk)
  61. {
  62. HRESULT hr = hrOK;
  63. MULTI_QI qi;
  64. Assert(ppUnk);
  65. *ppUnk = NULL;
  66. if (IsLocalMachine(pszMachine))
  67. {
  68. hr = CoCreateInstance(CLSID_RemoteRouterConfig,
  69. NULL,
  70. CLSCTX_SERVER | CLSCTX_ENABLE_CODE_DOWNLOAD,
  71. riid,
  72. (LPVOID *) &(qi.pItf));
  73. }
  74. else
  75. {
  76. SPIRouterAdminAccess spAdmin;
  77. BOOL fAdminInfoSet = FALSE;
  78. COSERVERINFO csi;
  79. Assert(pcsi);
  80. qi.pIID = &riid;
  81. qi.pItf = NULL;
  82. qi.hr = 0;
  83. pcsi->dwReserved1 = 0;
  84. pcsi->dwReserved2 = 0;
  85. pcsi->pwszName = (LPWSTR) (LPCTSTR) pszMachine;
  86. if (pRouter)
  87. {
  88. spAdmin.HrQuery(pRouter);
  89. if (spAdmin && spAdmin->IsAdminInfoSet())
  90. {
  91. int cPassword;
  92. int cchPassword;
  93. WCHAR * pszPassword = NULL;
  94. UCHAR ucSeed = 0x83;
  95. pcsi->pAuthInfo->dwAuthnSvc = RPC_C_AUTHN_WINNT;
  96. pcsi->pAuthInfo->dwAuthzSvc = RPC_C_AUTHZ_NONE;
  97. pcsi->pAuthInfo->pwszServerPrincName = NULL;
  98. pcsi->pAuthInfo->dwAuthnLevel = RPC_C_AUTHN_LEVEL_DEFAULT;
  99. pcsi->pAuthInfo->dwImpersonationLevel = RPC_C_IMP_LEVEL_IMPERSONATE;
  100. // pcsi->pAuthInfo->pAuthIdentityData = &caid;
  101. pcsi->pAuthInfo->dwCapabilities = EOAC_NONE;
  102. if (spAdmin->GetUserName())
  103. {
  104. pcsi->pAuthInfo->pAuthIdentityData->User = (LPTSTR) spAdmin->GetUserName();
  105. pcsi->pAuthInfo->pAuthIdentityData->UserLength = StrLenW(spAdmin->GetUserName());
  106. }
  107. if (spAdmin->GetDomainName())
  108. {
  109. pcsi->pAuthInfo->pAuthIdentityData->Domain = (LPTSTR) spAdmin->GetDomainName();
  110. pcsi->pAuthInfo->pAuthIdentityData->DomainLength = StrLenW(spAdmin->GetDomainName());
  111. }
  112. spAdmin->GetUserPassword(NULL, &cPassword);
  113. // Assume that the password is Unicode
  114. cchPassword = cPassword / sizeof(WCHAR);
  115. pszPassword = (WCHAR *) new BYTE[cPassword + sizeof(WCHAR)];
  116. spAdmin->GetUserPassword((PBYTE) pszPassword, &cPassword);
  117. pszPassword[cchPassword] = 0;
  118. RtlDecodeW(ucSeed, pszPassword);
  119. delete pcsi->pAuthInfo->pAuthIdentityData->Password;
  120. pcsi->pAuthInfo->pAuthIdentityData->Password = pszPassword;
  121. pcsi->pAuthInfo->pAuthIdentityData->PasswordLength = cchPassword;
  122. pcsi->pAuthInfo->pAuthIdentityData->Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
  123. fAdminInfoSet = TRUE;
  124. }
  125. else
  126. {
  127. pcsi->pAuthInfo = NULL;
  128. }
  129. }
  130. hr = CoCreateInstanceEx(CLSID_RemoteRouterConfig,
  131. NULL,
  132. CLSCTX_SERVER | CLSCTX_ENABLE_CODE_DOWNLOAD,
  133. pcsi,
  134. 1,
  135. &qi);
  136. if (FHrOK(hr) && fAdminInfoSet)
  137. {
  138. DWORD dwAuthnSvc, dwAuthzSvc, dwAuthnLevel, dwImpLevel;
  139. DWORD dwCaps;
  140. OLECHAR * pszServerPrincipal = NULL;
  141. CComPtr<IUnknown> spIUnk;
  142. qi.pItf->QueryInterface(IID_IUnknown, (void**)&spIUnk);
  143. CoQueryProxyBlanket(spIUnk,
  144. &dwAuthnSvc,
  145. &dwAuthzSvc,
  146. &pszServerPrincipal,
  147. &dwAuthnLevel,
  148. &dwImpLevel,
  149. NULL,
  150. &dwCaps);
  151. hr = CoSetProxyBlanket(spIUnk,
  152. dwAuthnSvc,
  153. dwAuthzSvc,
  154. pszServerPrincipal,
  155. dwAuthnLevel,
  156. dwImpLevel,
  157. (RPC_AUTH_IDENTITY_HANDLE) pcsi->pAuthInfo->pAuthIdentityData,
  158. dwCaps);
  159. CoTaskMemFree(pszServerPrincipal);
  160. pszServerPrincipal = NULL;
  161. CoQueryProxyBlanket(qi.pItf,
  162. &dwAuthnSvc,
  163. &dwAuthzSvc,
  164. &pszServerPrincipal,
  165. &dwAuthnLevel,
  166. &dwImpLevel,
  167. NULL,
  168. &dwCaps);
  169. hr = CoSetProxyBlanket(qi.pItf,
  170. dwAuthnSvc,
  171. dwAuthzSvc,
  172. pszServerPrincipal,
  173. dwAuthnLevel,
  174. dwImpLevel,
  175. (RPC_AUTH_IDENTITY_HANDLE) pcsi->pAuthInfo->pAuthIdentityData,
  176. dwCaps);
  177. CoTaskMemFree(pszServerPrincipal);
  178. }
  179. }
  180. if (FHrSucceeded(hr))
  181. {
  182. *ppUnk = qi.pItf;
  183. qi.pItf = NULL;
  184. }
  185. return hr;
  186. }
  187. /*!--------------------------------------------------------------------------
  188. CoCreateProtocolConfig
  189. -
  190. Author: KennT
  191. ---------------------------------------------------------------------------*/
  192. HRESULT CoCreateProtocolConfig(const GUID& iid,
  193. IRouterInfo *pRouter,
  194. DWORD dwTransportId,
  195. DWORD dwProtocolId,
  196. IRouterProtocolConfig **ppConfig)
  197. {
  198. HRESULT hr = hrOK;
  199. GUID guidConfig;
  200. guidConfig = iid;
  201. if (((iid == GUID_RouterNull) ||
  202. (iid == GUID_RouterError)) &&
  203. pRouter)
  204. {
  205. RouterVersionInfo routerVersion;
  206. pRouter->GetRouterVersionInfo(&routerVersion);
  207. // If we don't have a configuration GUID and this is an NT4
  208. // router, then we create the default configuration object
  209. // and use that to add/remove a protocol
  210. // ------------------------------------------------------------
  211. if ((routerVersion.dwRouterVersion <= 4) &&
  212. (dwTransportId == PID_IP))
  213. {
  214. // For NT4, we have to create our own object
  215. // --------------------------------------------------------
  216. guidConfig = CLSID_IPRouterConfiguration;
  217. }
  218. }
  219. if (guidConfig == GUID_RouterNull)
  220. {
  221. // Skip the rest of the creation, we didn't supply a GUID
  222. // ------------------------------------------------------------
  223. goto Error;
  224. }
  225. if (guidConfig == GUID_RouterError)
  226. {
  227. // We don't have a valid GUID
  228. // ------------------------------------------------------------
  229. CWRg( ERROR_BADKEY );
  230. }
  231. hr = CoCreateInstance(guidConfig,
  232. NULL,
  233. CLSCTX_INPROC_SERVER | CLSCTX_ENABLE_CODE_DOWNLOAD,
  234. IID_IRouterProtocolConfig,
  235. (LPVOID *) ppConfig);
  236. CORg( hr );
  237. Error:
  238. return hr;
  239. }
  240. //----------------------------------------------------------------------------
  241. // Function: QueryIpAddressList(
  242. //
  243. // Loads a list of strings with the IP addresses configured
  244. // for a given LAN interface, if any.
  245. //----------------------------------------------------------------------------
  246. HRESULT
  247. QueryIpAddressList(
  248. IN LPCTSTR pszMachine,
  249. IN HKEY hkeyMachine,
  250. IN LPCTSTR pszInterface,
  251. OUT CStringList* pAddressList,
  252. OUT CStringList* pNetmaskList,
  253. OUT BOOL * pfDhcpObtained,
  254. OUT BOOL * pfDns,
  255. OUT CString * pDhcpServer
  256. ) {
  257. DWORD dwErr = NO_ERROR;
  258. BOOL bDisconnect = FALSE;
  259. RegKey regkeyMachine;
  260. RegKey regkeyInterface;
  261. DWORD dwType, dwSize, dwEnableDHCP;
  262. SPBYTE spValue;
  263. HRESULT hr = hrOK;
  264. HKEY hkeyInterface;
  265. INT i;
  266. TCHAR* psz;
  267. LPCTSTR aszSources[2];
  268. CStringList* alistDestinations[2] = { pAddressList, pNetmaskList };
  269. CString stNameServer;
  270. LPCTSTR pszNameServer = NULL;
  271. if (!pszInterface || !lstrlen(pszInterface) ||
  272. !pAddressList || !pNetmaskList)
  273. CORg(E_INVALIDARG);
  274. //
  275. // If no HKEY_LOCAL_MACHINE key was given, get one
  276. //
  277. if (hkeyMachine == NULL)
  278. {
  279. CWRg( ConnectRegistry(pszMachine, &hkeyMachine) );
  280. regkeyMachine.Attach(hkeyMachine);
  281. }
  282. //
  283. // Connect to the LAN card's registry key
  284. //
  285. CWRg( OpenTcpipInterfaceParametersKey(pszMachine, pszInterface,
  286. hkeyMachine, &hkeyInterface) );
  287. regkeyInterface.Attach(hkeyInterface);
  288. //
  289. // Read the 'EnableDHCP' flag to see whether to read
  290. // the 'DhcpIPAddress' or the 'IPAddress'.
  291. //
  292. dwErr = regkeyInterface.QueryValue( c_szEnableDHCP, dwEnableDHCP );
  293. if (dwErr == ERROR_SUCCESS)
  294. {
  295. if (pfDhcpObtained)
  296. *pfDhcpObtained = dwEnableDHCP;
  297. }
  298. else
  299. dwEnableDHCP = FALSE;
  300. //
  301. // If the flag isn't found, we look for the IP address;
  302. // otherwise, we look for the setting indicated by the flag
  303. //
  304. if (dwErr == ERROR_SUCCESS && dwEnableDHCP)
  305. {
  306. //
  307. // Read the 'DhcpIpAddress' and 'DhcpSubnetMask'
  308. //
  309. aszSources[0] = c_szDhcpIpAddress;
  310. aszSources[1] = c_szDhcpSubnetMask;
  311. pszNameServer = c_szRegValDhcpNameServer;
  312. }
  313. else
  314. {
  315. //
  316. // Read the 'IPAddress' and 'SubnetMask'
  317. //
  318. aszSources[0] = c_szIPAddress;
  319. aszSources[1] = c_szSubnetMask;
  320. pszNameServer= c_szRegValNameServer;
  321. }
  322. if (pDhcpServer)
  323. {
  324. pDhcpServer->Empty();
  325. regkeyInterface.QueryValue(c_szRegValDhcpServer, *pDhcpServer);
  326. }
  327. // Check the DhcpNameServer/NameServer to find the existence
  328. // of DNS servers
  329. if (pfDns)
  330. {
  331. regkeyInterface.QueryValue(pszNameServer, stNameServer);
  332. stNameServer.TrimLeft();
  333. stNameServer.TrimRight();
  334. *pfDns = !stNameServer.IsEmpty();
  335. }
  336. //
  337. // Read the address list and the netmask list
  338. //
  339. for (i = 0; i < 2 && dwErr == NO_ERROR; i++)
  340. {
  341. //
  342. // Get the size of the multi-string-list
  343. //
  344. dwErr = regkeyInterface.QueryTypeAndSize(aszSources[i],
  345. &dwType, &dwSize);
  346. // CheckRegQueryValueError(dwErr, (LPCTSTR) c_szTcpip, aszSources[i], _T("QueryIpAddressList"));
  347. CWRg( dwErr );
  348. //
  349. // Allocate space for the list
  350. //
  351. spValue = new BYTE[dwSize + sizeof(TCHAR)];
  352. Assert(spValue);
  353. ::ZeroMemory(spValue, dwSize + sizeof(TCHAR));
  354. //
  355. // Read the list
  356. //
  357. dwErr = regkeyInterface.QueryValue(aszSources[i], (LPTSTR) (BYTE *)spValue, dwSize,
  358. FALSE /* fExpandSz */);
  359. // CheckRegQueryValueError(dwErr, (LPCTSTR) c_szTcpip, aszSources[i], _T("QueryIpAddressList"));
  360. CWRg( dwErr );
  361. //
  362. // Fill the CString list with items
  363. //
  364. for (psz = (TCHAR*)(BYTE *)spValue; *psz; psz += lstrlen(psz) + 1)
  365. {
  366. alistDestinations[i]->AddTail(psz);
  367. }
  368. spValue.Free();
  369. dwErr = NO_ERROR;
  370. }
  371. Error:
  372. return hr;
  373. }
  374. /*!--------------------------------------------------------------------------
  375. OpenTcpipInterfaceParametersKey
  376. -
  377. Author: KennT
  378. ---------------------------------------------------------------------------*/
  379. DWORD OpenTcpipInterfaceParametersKey(LPCTSTR pszMachine,
  380. LPCTSTR pszInterface,
  381. HKEY hkeyMachine,
  382. HKEY *phkeyParams)
  383. {
  384. DWORD dwErr;
  385. BOOL fNt4;
  386. CString skey;
  387. dwErr = IsNT4Machine(hkeyMachine, &fNt4);
  388. if (dwErr != ERROR_SUCCESS)
  389. return dwErr;
  390. //$NT5 : kennt, the tcpip key is stored separately. What they
  391. // have done is to reverse the hierarchy, instead of a tcpip key
  392. // under interfaces, there are now interfaces under tcpip
  393. // the key location is
  394. // HKLM\System\CCS\Services\Tcpip\Parameters\Interfaces\{interface}
  395. // In NT4, this was
  396. // HKLM\System\CCS\Services\{interface}\Parameters\Tcpip
  397. // Need to determine if the target machine is running NT5 or not
  398. if (fNt4)
  399. {
  400. skey = c_szSystemCCSServices;
  401. skey += TEXT('\\');
  402. skey += pszInterface;
  403. skey += TEXT('\\');
  404. skey += c_szParameters;
  405. skey += TEXT('\\');
  406. skey += c_szTcpip;
  407. }
  408. else
  409. {
  410. skey = c_szSystemCCSServices;
  411. skey += TEXT('\\');
  412. skey += c_szTcpip;
  413. skey += TEXT('\\');
  414. skey += c_szParameters;
  415. skey += TEXT('\\');
  416. skey += c_szInterfaces;
  417. skey += TEXT('\\');
  418. skey += pszInterface;
  419. }
  420. if (dwErr == ERROR_SUCCESS)
  421. {
  422. dwErr = ::RegOpenKeyEx(
  423. hkeyMachine, skey, 0, KEY_ALL_ACCESS, phkeyParams);
  424. // CheckRegOpenError(dwErr, (LPCTSTR) skey, _T("OpenTcpInterfaceParametersKey"));
  425. }
  426. return dwErr;
  427. }