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.

421 lines
10 KiB

  1. #include "stdafx.h"
  2. #include "common.h"
  3. #include "iisobj.h"
  4. #include "util.h"
  5. #include <activeds.h>
  6. #include <lmerr.h>
  7. #include <Winsock2.h>
  8. #ifdef _DEBUG
  9. #define new DEBUG_NEW
  10. #undef THIS_FILE
  11. static char THIS_FILE[] = __FILE__;
  12. #endif
  13. void DumpFriendlyName(CIISObject * pObj)
  14. {
  15. if (pObj)
  16. {
  17. CString strGUIDName;
  18. GUID * MyGUID = (GUID*) pObj->GetNodeType();
  19. GetFriendlyGuidName(*MyGUID,strGUIDName);
  20. TRACEEOL("CIISObject=" << strGUIDName);
  21. }
  22. }
  23. HRESULT DumpAllScopeItems(CComPtr<IConsoleNameSpace> pConsoleNameSpace, IN HSCOPEITEM hParent, IN int iTreeLevel)
  24. {
  25. HSCOPEITEM hChildItem = NULL;
  26. CIISObject * pItem = NULL;
  27. LONG_PTR cookie = NULL;
  28. if (0 == iTreeLevel)
  29. {
  30. TRACEEOL("==============");
  31. TRACEEOL("[\\]" << hParent);
  32. }
  33. iTreeLevel++;
  34. HRESULT hr = pConsoleNameSpace->GetChildItem(hParent, &hChildItem, &cookie);
  35. while(SUCCEEDED(hr) && hChildItem)
  36. {
  37. //
  38. // The cookie is really the IISObject, which is what we stuff
  39. // in the lparam.
  40. //
  41. pItem = (CIISObject *)cookie;
  42. if (pItem)
  43. {
  44. //
  45. // Recursively dump every object
  46. //
  47. CString strGUIDName;GUID * MyGUID = (GUID*) pItem->GetNodeType();GetFriendlyGuidName(*MyGUID,strGUIDName);
  48. for (int i = 0; i < iTreeLevel; ++i)
  49. {
  50. TRACEOUT("-");
  51. }
  52. TRACEEOL("[" << strGUIDName << "] (parent=" << hParent << " )(" << hChildItem << ")");
  53. // dump all it's children
  54. DumpAllScopeItems(pConsoleNameSpace,hChildItem,iTreeLevel + 1);
  55. }
  56. //
  57. // Advance to next child of same parent
  58. //
  59. hr = pConsoleNameSpace->GetNextItem(hChildItem, &hChildItem, &cookie);
  60. }
  61. return S_OK;
  62. }
  63. HRESULT DumpAllResultItems(IResultData * pResultData)
  64. {
  65. HRESULT hr = S_OK;
  66. RESULTDATAITEM rdi;
  67. CIISObject * pItem = NULL;
  68. ZeroMemory(&rdi, sizeof(rdi));
  69. rdi.mask = RDI_PARAM | RDI_STATE;
  70. rdi.nIndex = -1; // -1 to start at first item
  71. do
  72. {
  73. rdi.lParam = 0;
  74. // this could AV right here if pResultData is invalid
  75. hr = pResultData->GetNextItem(&rdi);
  76. if (hr != S_OK)
  77. {
  78. break;
  79. }
  80. //
  81. // The cookie is really the IISObject, which is what we stuff
  82. // in the lparam.
  83. //
  84. pItem = (CIISObject *)rdi.lParam;
  85. ASSERT_PTR(pItem);
  86. DumpFriendlyName(pItem);
  87. //
  88. // Advance to next child of same parent
  89. //
  90. } while (SUCCEEDED(hr) && -1 != rdi.nIndex);
  91. return hr;
  92. }
  93. //
  94. // IsValidDomainUser
  95. // Check if a domain user like redmond\jonsmith specified in szDomainUser
  96. // is valid or not. returns S_FALSE if it is invalid, S_OK for valid user.
  97. //
  98. // szFullName ---- To return the user's full name
  99. // cch ---- count of characters pointed to by szFullName
  100. //
  101. // if szFullName is NULL or cch is zero, no full name is returned
  102. //
  103. const TCHAR gszUserDNFmt[] = _T("WinNT://%s/%s,user");
  104. HRESULT
  105. IsValidDomainUser(
  106. LPCTSTR szDomainUser,
  107. LPTSTR szFullName,
  108. DWORD cch)
  109. {
  110. HRESULT hr = S_OK;
  111. TCHAR szDN[256];
  112. TCHAR szDomain[256];
  113. LPTSTR szSep;
  114. LPCTSTR szUser;
  115. DWORD dw;
  116. IADsUser * pUser = NULL;
  117. BSTR bstrFullName = NULL;
  118. // Sanity check
  119. if (szDomainUser == NULL || szDomainUser[0] == 0)
  120. {
  121. hr = S_FALSE;
  122. goto ExitHere;
  123. }
  124. //
  125. // Construct the user DN as <WINNT://domain/user,user>
  126. //
  127. szSep = _tcschr (szDomainUser, TEXT('\\'));
  128. if (szSep == NULL)
  129. {
  130. // No '\' is given, assume a local user ,domain is local computer
  131. szUser = szDomainUser;
  132. dw = sizeof(szDomain)/sizeof(TCHAR);
  133. if (GetComputerName (szDomain, &dw) == 0)
  134. {
  135. hr = HRESULT_FROM_WIN32 (GetLastError ());
  136. goto ExitHere;
  137. }
  138. }
  139. else
  140. {
  141. // assume invalid domain name if longer than 255
  142. if (szSep - szDomainUser >= sizeof(szDomain)/sizeof(TCHAR))
  143. {
  144. hr = S_FALSE;
  145. goto ExitHere;
  146. }
  147. _tcsncpy (szDomain, szDomainUser, szSep - szDomainUser);
  148. szDomain[szSep - szDomainUser] = 0;
  149. szUser = szSep + 1;
  150. }
  151. if (_tcslen (gszUserDNFmt) + _tcslen (szDomain) + _tcslen (szUser) >
  152. sizeof(szDN) / sizeof(TCHAR))
  153. {
  154. hr = S_FALSE;
  155. goto ExitHere;
  156. }
  157. wsprintf (szDN, gszUserDNFmt, szDomain, szUser);
  158. //
  159. // Try to bind to the user object
  160. //
  161. hr = ADsGetObject (szDN, IID_IADsUser, (void **)&pUser);
  162. if (FAILED(hr))
  163. {
  164. if (hr == E_ADS_INVALID_USER_OBJECT ||
  165. hr == E_ADS_UNKNOWN_OBJECT ||
  166. hr == E_ADS_BAD_PATHNAME ||
  167. HRESULT_CODE(hr) == NERR_UserNotFound)
  168. {
  169. hr = S_FALSE; // The user does not exist
  170. }
  171. goto ExitHere;
  172. }
  173. //
  174. // If the user exists, get its full name
  175. //
  176. if (cch > 0)
  177. {
  178. hr = pUser->get_FullName (&bstrFullName);
  179. szFullName[0] = 0;
  180. if (hr == S_OK)
  181. {
  182. _tcsncpy (szFullName, bstrFullName, cch);
  183. szFullName[cch - 1] = 0;
  184. }
  185. }
  186. ExitHere:
  187. if (pUser)
  188. {
  189. pUser->Release();
  190. }
  191. if (bstrFullName)
  192. {
  193. SysFreeString (bstrFullName);
  194. }
  195. return hr;
  196. }
  197. #if 0
  198. DWORD VerifyPassword(WCHAR * sUserName, WCHAR * sPassword, WCHAR * sDomain)
  199. {
  200. CWaitCursor wait;
  201. DWORD retVal = 0;
  202. CString strDomainUserName;
  203. CString localIPC;
  204. WCHAR localMachine[MAX_PATH];
  205. WCHAR * computer = NULL;
  206. DWORD len = DIM(localMachine);
  207. NETRESOURCE nr;
  208. CString error=L"no error";
  209. USER_INFO_3 * pInfo = NULL;
  210. NET_API_STATUS rc;
  211. memset(&nr,0,(sizeof nr));
  212. if ( ! gbNeedToVerify )
  213. return 0;
  214. /* see if this domain exists and get a DC name */
  215. //get the domain controller name
  216. if (!GetDomainDCName(sDomain,&computer))
  217. return ERROR_LOGON_FAILURE;
  218. /* see if this user is a member of the given domain */
  219. rc = NetUserGetInfo(computer, sUserName, 3, (LPBYTE *)&pInfo);
  220. NetApiBufferFree(computer);
  221. if (rc != NERR_Success)
  222. return ERROR_LOGON_FAILURE;
  223. NetApiBufferFree(pInfo);
  224. /* see if the password allows us to connect to a local resource */
  225. strDomainUserName.Format(L"%s\\%s",sDomain,sUserName);
  226. // get the name of the local machine
  227. if ( GetComputerName(localMachine,&len) )
  228. {
  229. localIPC.Format(L"\\\\%s",localMachine);
  230. nr.dwType = RESOURCETYPE_ANY;
  231. nr.lpRemoteName = localIPC.GetBuffer(0);
  232. retVal = WNetAddConnection2(&nr,sPassword,strDomainUserName,0);
  233. error.Format(L"WNetAddConnection returned%u",retVal);
  234. if ( ! retVal )
  235. {
  236. error.Format(L"WNetAddConnection2 succeeded");
  237. retVal = WNetCancelConnection2(localIPC.GetBuffer(0),0,TRUE);
  238. if ( retVal )
  239. retVal = 0;
  240. }
  241. else if ( retVal == ERROR_SESSION_CREDENTIAL_CONFLICT )
  242. {
  243. // skip the password check in this case
  244. retVal = 0;
  245. }
  246. }
  247. else
  248. {
  249. retVal = GetLastError();
  250. }
  251. return retVal;
  252. }
  253. #endif
  254. //
  255. // IsConnectingToOwnAddress
  256. // return true if this is an attempt to reconnect to our
  257. // own address.
  258. //
  259. BOOL IsConnectingToOwnAddress(u_long connectAddr)
  260. {
  261. //32-bit form of 127.0.0.1 addr
  262. #define LOOPBACK_ADDR ((u_long)0x0100007f)
  263. //
  264. // First the quick check for localhost/127.0.0.1
  265. //
  266. if( LOOPBACK_ADDR == connectAddr)
  267. {
  268. TRACEEOLID("Connecting to loopback address...");
  269. return TRUE;
  270. }
  271. //
  272. // More extensive check, i.e resolve the local hostname
  273. //
  274. char hostname[(512+1)*sizeof(TCHAR)];
  275. int err;
  276. int j;
  277. struct hostent* phostent;
  278. err=gethostname(hostname, sizeof(hostname));
  279. if (err == 0)
  280. {
  281. if ((phostent = gethostbyname(hostname)) !=NULL)
  282. {
  283. switch (phostent->h_addrtype)
  284. {
  285. case AF_INET:
  286. j=0;
  287. while (phostent->h_addr_list[j] != NULL)
  288. {
  289. if(!memcmp(&connectAddr,
  290. phostent->h_addr_list[j],
  291. sizeof(u_long)))
  292. {
  293. TRACEEOLID("Connecting to same IP as the local machine...");
  294. return TRUE;
  295. }
  296. j++;
  297. }
  298. default:
  299. break;
  300. }
  301. }
  302. }
  303. return FALSE;
  304. }
  305. //-----------------------------------------------------------------------------
  306. // IsLocalHost
  307. //
  308. // Arguments : szHostName (name of computer to check)
  309. // pbIsHost (set to TRUE if host name matches local computer name)
  310. //
  311. // Returns : FALSE on windows socket error
  312. //
  313. // Purpose : check if host name matches this (local) computer name
  314. //-----------------------------------------------------------------------------
  315. #define WS_VERSION_REQD 0x0101
  316. BOOL IsLocalHost(LPCTSTR szHostName,BOOL* pbIsHost)
  317. {
  318. const char * lpszAnsiHostName = NULL;
  319. *pbIsHost = FALSE;
  320. BOOL bSuccess = TRUE;
  321. hostent* phostent = NULL;
  322. // init winsock (reference counted - can init any number of times)
  323. //
  324. WSADATA wsaData;
  325. int err = WSAStartup(WS_VERSION_REQD, &wsaData);
  326. if (err)
  327. {
  328. return FALSE;
  329. }
  330. //
  331. // convert to ansi
  332. //
  333. #ifdef UNICODE
  334. CHAR szAnsi[MAX_PATH];
  335. if (::WideCharToMultiByte(CP_ACP, 0L, szHostName, -1, szAnsi, sizeof(szAnsi), NULL, NULL) > 0)
  336. {
  337. lpszAnsiHostName = szAnsi;
  338. }
  339. #else
  340. lpszAnsiHostName = szHostName;
  341. #endif // UNICODE
  342. if (NULL == lpszAnsiHostName)
  343. {
  344. return FALSE;
  345. }
  346. // get dns name for the given hostname
  347. //
  348. unsigned long addr = inet_addr(lpszAnsiHostName);
  349. if (addr == INADDR_NONE)
  350. phostent = gethostbyname(lpszAnsiHostName);
  351. else
  352. phostent = gethostbyaddr((char*)&addr,4, AF_INET);
  353. if (phostent == NULL)
  354. {
  355. bSuccess = FALSE;
  356. goto cleanup;
  357. }
  358. else
  359. {
  360. IN_ADDR hostaddr;
  361. memcpy(&hostaddr,phostent->h_addr,sizeof(hostaddr));
  362. *pbIsHost = IsConnectingToOwnAddress(hostaddr.s_addr);
  363. bSuccess = TRUE;
  364. goto cleanup;
  365. }
  366. cleanup:
  367. err = WSACleanup();
  368. if (err != 0)
  369. {
  370. bSuccess = FALSE;
  371. }
  372. return bSuccess;
  373. }