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.

863 lines
16 KiB

  1. /*++
  2. Copyright (c) 1994-95 Microsoft Corporation
  3. Module Name:
  4. domobj.cpp
  5. Abstract:
  6. Domain object implementation.
  7. Author:
  8. Don Ryan (donryan) 04-Jan-1995
  9. Environment:
  10. User Mode - Win32
  11. Revision History:
  12. --*/
  13. #include "stdafx.h"
  14. #include "llsmgr.h"
  15. #include "lmcons.h"
  16. #include "lmapibuf.h"
  17. #include "lmserver.h"
  18. #include "lmaccess.h"
  19. extern "C" {
  20. #include "dsgetdc.h"
  21. }
  22. #include <strsafe.h>
  23. #ifdef _DEBUG
  24. #undef THIS_FILE
  25. static char BASED_CODE THIS_FILE[] = __FILE__;
  26. #endif
  27. IMPLEMENT_DYNCREATE(CDomain, CCmdTarget)
  28. BEGIN_MESSAGE_MAP(CDomain, CCmdTarget)
  29. //{{AFX_MSG_MAP(CDomain)
  30. // NOTE - the ClassWizard will add and remove mapping macros here.
  31. //}}AFX_MSG_MAP
  32. END_MESSAGE_MAP()
  33. BEGIN_DISPATCH_MAP(CDomain, CCmdTarget)
  34. //{{AFX_DISPATCH_MAP(CDomain)
  35. DISP_PROPERTY_EX(CDomain, "Name", GetName, SetNotSupported, VT_BSTR)
  36. DISP_PROPERTY_EX(CDomain, "Parent", GetParent, SetNotSupported, VT_DISPATCH)
  37. DISP_PROPERTY_EX(CDomain, "Primary", GetPrimary, SetNotSupported, VT_BSTR)
  38. DISP_PROPERTY_EX(CDomain, "Application", GetApplication, SetNotSupported, VT_DISPATCH)
  39. DISP_PROPERTY_EX(CDomain, "Controller", GetController, SetNotSupported, VT_BSTR)
  40. DISP_PROPERTY_EX(CDomain, "IsLogging", IsLogging, SetNotSupported, VT_BOOL)
  41. DISP_PROPERTY_PARAM(CDomain, "Servers", GetServers, SetNotSupported, VT_DISPATCH, VTS_VARIANT)
  42. DISP_PROPERTY_PARAM(CDomain, "Users", GetUsers, SetNotSupported, VT_DISPATCH, VTS_VARIANT)
  43. DISP_PROPERTY_PARAM(CDomain, "TrustedDomains", GetTrustedDomains, SetNotSupported, VT_DISPATCH, VTS_VARIANT)
  44. DISP_DEFVALUE(CDomain, "Name")
  45. //}}AFX_DISPATCH_MAP
  46. END_DISPATCH_MAP()
  47. CDomain::CDomain(CCmdTarget* pParent, LPCTSTR pName)
  48. /*++
  49. Routine Description:
  50. Constructor for domain object.
  51. Arguments:
  52. pParent - creator of object.
  53. pName - name of domain.
  54. Return Values:
  55. None.
  56. --*/
  57. {
  58. EnableAutomation();
  59. #ifdef ENABLE_PARENT_CHECK
  60. ASSERT(pParent && pParent->IsKindOf(RUNTIME_CLASS(CApplication)));
  61. #endif // ENABLE_PARENT_CHECK
  62. m_pParent = pParent;
  63. ASSERT(pName && *pName);
  64. m_strName = pName;
  65. m_strPrimary.Empty();
  66. m_strController.Empty();
  67. m_pServers = NULL;
  68. m_pDomains = NULL;
  69. m_pUsers = NULL;
  70. m_serverArray.RemoveAll();
  71. m_domainArray.RemoveAll();
  72. m_userArray.RemoveAll();
  73. m_bServersRefreshed = FALSE;
  74. m_bDomainsRefreshed = FALSE;
  75. m_bUsersRefreshed = FALSE;
  76. }
  77. CDomain::~CDomain()
  78. /*++
  79. Routine Description:
  80. Destructor for domain object.
  81. Arguments:
  82. None.
  83. Return Values:
  84. None.
  85. --*/
  86. {
  87. if (m_pUsers)
  88. m_pUsers->InternalRelease();
  89. if (m_pServers)
  90. m_pServers->InternalRelease();
  91. if (m_pDomains)
  92. m_pDomains->InternalRelease();
  93. }
  94. void CDomain::OnFinalRelease()
  95. /*++
  96. Routine Description:
  97. When the last reference for an automation object is released
  98. OnFinalRelease is called. This implementation deletes object.
  99. Arguments:
  100. None.
  101. Return Values:
  102. None.
  103. --*/
  104. {
  105. ResetUsers();
  106. ResetServers();
  107. ResetDomains();
  108. delete this;
  109. }
  110. LPDISPATCH CDomain::GetApplication()
  111. /*++
  112. Routine Description:
  113. Returns the application object.
  114. Arguments:
  115. None.
  116. Return Values:
  117. VT_DISPATCH.
  118. --*/
  119. {
  120. return theApp.GetAppIDispatch();
  121. }
  122. BSTR CDomain::GetController()
  123. /*++
  124. Routine Description:
  125. Returns license controller for domain.
  126. Arguments:
  127. None.
  128. Return Values:
  129. VT_BSTR.
  130. --*/
  131. {
  132. return NULL; // CODEWORK...
  133. }
  134. BSTR CDomain::GetName()
  135. /*++
  136. Routine Description:
  137. Returns the name of the domain.
  138. Arguments:
  139. None.
  140. Return Values:
  141. None.
  142. --*/
  143. {
  144. return m_strName.AllocSysString();
  145. }
  146. LPDISPATCH CDomain::GetParent()
  147. /*++
  148. Routine Description:
  149. Returns the parent of the object.
  150. Arguments:
  151. None.
  152. Return Values:
  153. VT_DISPATCH.
  154. --*/
  155. {
  156. return m_pParent ? m_pParent->GetIDispatch(TRUE) : NULL;
  157. }
  158. BSTR CDomain::GetPrimary()
  159. /*++
  160. Routine Description:
  161. Returns the name of the ANY domain controller.
  162. Arguments:
  163. None.
  164. Return Values:
  165. VT_BSTR.
  166. --*/
  167. {
  168. if (m_strPrimary.IsEmpty())
  169. {
  170. DWORD NetStatus;
  171. PDOMAIN_CONTROLLER_INFO pDcInfo;
  172. NetStatus = DsGetDcName( NULL,
  173. MKSTR(m_strName),
  174. (GUID *)NULL,
  175. NULL,
  176. DS_IS_FLAT_NAME | DS_RETURN_DNS_NAME,
  177. &pDcInfo );
  178. if (NetStatus == ERROR_SUCCESS)
  179. {
  180. m_strPrimary = pDcInfo->DomainControllerName;
  181. ::NetApiBufferFree((LPBYTE)pDcInfo);
  182. }
  183. LlsSetLastStatus(NetStatus); // called api
  184. }
  185. return m_strPrimary.AllocSysString();
  186. }
  187. LPDISPATCH CDomain::GetServers(const VARIANT FAR& index)
  188. /*++
  189. Routine Description:
  190. Returns a collection object containing all of the
  191. servers in the domain or returns an individual server
  192. described by an index into the collection.
  193. Arguments:
  194. index - optional argument that may be a string (VT_BSTR)
  195. indicating the server name or a number (VT_I4) indicating
  196. the position within collection.
  197. Return Values:
  198. VT_DISPATCH or VT_EMPTY.
  199. --*/
  200. {
  201. LPDISPATCH lpdispatch = NULL;
  202. if (!m_pServers)
  203. {
  204. m_pServers = new CServers(this, &m_serverArray);
  205. }
  206. if (m_pServers)
  207. {
  208. if (V_ISVOID((VARIANT FAR*)&index))
  209. {
  210. if (RefreshServers())
  211. {
  212. lpdispatch = m_pServers->GetIDispatch(TRUE);
  213. }
  214. }
  215. else
  216. {
  217. if (m_bServersRefreshed)
  218. {
  219. lpdispatch = m_pServers->GetItem(index);
  220. }
  221. else if (RefreshServers())
  222. {
  223. lpdispatch = m_pServers->GetItem(index);
  224. }
  225. }
  226. }
  227. else
  228. {
  229. LlsSetLastStatus(STATUS_NO_MEMORY);
  230. }
  231. return lpdispatch;
  232. }
  233. LPDISPATCH CDomain::GetTrustedDomains(const VARIANT FAR& index)
  234. /*++
  235. Routine Description:
  236. Returns a collection object containing all of the
  237. domains trusted bythe domain or returns an individual
  238. trusted domain described by an index into the collection.
  239. Arguments:
  240. index - optional argument that may be a string (VT_BSTR)
  241. indicating the domain name or a number (VT_I4) indicating
  242. the position within collection.
  243. Return Values:
  244. VT_DISPATCH or VT_EMPTY.
  245. --*/
  246. {
  247. LPDISPATCH lpdispatch = NULL;
  248. if (!m_pDomains)
  249. {
  250. m_pDomains = new CDomains(this, &m_domainArray);
  251. }
  252. if (m_pDomains)
  253. {
  254. if (V_ISVOID((VARIANT FAR*)&index))
  255. {
  256. if (RefreshDomains())
  257. {
  258. lpdispatch = m_pDomains->GetIDispatch(TRUE);
  259. }
  260. }
  261. else
  262. {
  263. if (m_bDomainsRefreshed)
  264. {
  265. lpdispatch = m_pDomains->GetItem(index);
  266. }
  267. else if (RefreshDomains())
  268. {
  269. lpdispatch = m_pDomains->GetItem(index);
  270. }
  271. }
  272. }
  273. else
  274. {
  275. LlsSetLastStatus(STATUS_NO_MEMORY);
  276. }
  277. return lpdispatch;
  278. }
  279. LPDISPATCH CDomain::GetUsers(const VARIANT FAR& index)
  280. /*++
  281. Routine Description:
  282. Returns a collection object containing all of the
  283. users in the domain or returns an individual user
  284. described by an index into the collection.
  285. Arguments:
  286. index - optional argument that may be a string (VT_BSTR)
  287. indicating the user name or a number (VT_I4) indicating
  288. the position within collection.
  289. Return Values:
  290. VT_DISPATCH or VT_EMPTY.
  291. --*/
  292. {
  293. LPDISPATCH lpdispatch = NULL;
  294. if (!m_pUsers)
  295. {
  296. m_pUsers = new CUsers(this, &m_userArray);
  297. }
  298. if (m_pUsers)
  299. {
  300. if (V_ISVOID((VARIANT FAR*)&index))
  301. {
  302. if (RefreshUsers())
  303. {
  304. lpdispatch = m_pUsers->GetIDispatch(TRUE);
  305. }
  306. }
  307. else
  308. {
  309. if (m_bUsersRefreshed)
  310. {
  311. lpdispatch = m_pUsers->GetItem(index);
  312. }
  313. else if (RefreshUsers())
  314. {
  315. lpdispatch = m_pUsers->GetItem(index);
  316. }
  317. }
  318. }
  319. else
  320. {
  321. LlsSetLastStatus(STATUS_NO_MEMORY);
  322. }
  323. return lpdispatch;
  324. }
  325. BOOL CDomain::IsLogging()
  326. /*++
  327. Routine Description:
  328. Returns true if primary replicating license information.
  329. Arguments:
  330. None.
  331. Return Values:
  332. VT_BOOL.
  333. --*/
  334. {
  335. return TRUE; // CODEWORK... LlsEnterpriseServerFind??
  336. }
  337. BOOL CDomain::RefreshDomains()
  338. /*++
  339. Routine Description:
  340. Refreshs trusted domain array.
  341. Arguments:
  342. None.
  343. Return Values:
  344. VT_BOOL.
  345. --*/
  346. {
  347. ResetDomains();
  348. ULONG DomainCount = 0;
  349. PDS_DOMAIN_TRUSTS pDomains = NULL;
  350. NET_API_STATUS NetStatus = 0;
  351. OutputDebugString( L"CDomain::RefreshDomains\n" );
  352. NetStatus = DsEnumerateDomainTrusts( NULL,
  353. // DS_DOMAIN_IN_FOREST |
  354. DS_DOMAIN_DIRECT_OUTBOUND, //|
  355. // DS_DOMAIN_PRIMARY,
  356. &pDomains,
  357. &DomainCount );
  358. if (NetStatus == NO_ERROR)
  359. {
  360. CDomain* pDomain;
  361. int DomainsAdded = 0;
  362. for ( ;DomainCount--; pDomains++)
  363. {
  364. if ( (pDomains->Flags
  365. & (DS_DOMAIN_IN_FOREST | DS_DOMAIN_DIRECT_OUTBOUND))
  366. && (pDomains->TrustType
  367. & (TRUST_TYPE_DOWNLEVEL | TRUST_TYPE_UPLEVEL)))
  368. {
  369. #ifdef DBG //this was defined as DBGMSG in stdafx.h
  370. {
  371. TCHAR tchmsg[80];
  372. HRESULT hr;
  373. hr = StringCbPrintf(
  374. tchmsg,
  375. sizeof(tchmsg),
  376. L"\tNetbiosDomainName = %s\n",
  377. pDomains->NetbiosDomainName);
  378. ASSERT(SUCCEEDED(hr));
  379. OutputDebugString( tchmsg );
  380. }
  381. #endif //DBG
  382. pDomain = new CDomain(this, pDomains->NetbiosDomainName);
  383. m_domainArray.SetAtGrow(DomainsAdded, pDomain); // validate later
  384. DomainsAdded++;
  385. }
  386. }
  387. m_domainArray.SetSize(DomainsAdded);
  388. m_bDomainsRefreshed = TRUE;
  389. NetApiBufferFree(pDomains);
  390. }
  391. LlsSetLastStatus(NetStatus); // called api
  392. return m_bDomainsRefreshed;
  393. }
  394. BOOL CDomain::RefreshServers()
  395. /*++
  396. Routine Description:
  397. Refreshs server object array.
  398. Arguments:
  399. None.
  400. Return Values:
  401. VT_BOOL.
  402. --*/
  403. {
  404. ResetServers();
  405. NET_API_STATUS NetStatus;
  406. DWORD ResumeHandle = 0L;
  407. int iServer = 0;
  408. do
  409. {
  410. DWORD EntriesRead;
  411. DWORD TotalEntries;
  412. LPBYTE ReturnBuffer = NULL;
  413. NetStatus = ::NetServerEnum(
  414. NULL, // servername
  415. 100, // level
  416. &ReturnBuffer,
  417. LLS_PREFERRED_LENGTH,
  418. &EntriesRead,
  419. &TotalEntries,
  420. SV_TYPE_NT,
  421. MKSTR(m_strName),
  422. &ResumeHandle
  423. );
  424. if (NetStatus == ERROR_SUCCESS ||
  425. NetStatus == ERROR_MORE_DATA)
  426. {
  427. CServer* pServer;
  428. PSERVER_INFO_100 pServerInfo100;
  429. pServerInfo100 = (PSERVER_INFO_100)ReturnBuffer;
  430. ASSERT(iServer == m_serverArray.GetSize());
  431. m_serverArray.SetSize(m_serverArray.GetSize() + EntriesRead);
  432. while (EntriesRead--)
  433. {
  434. pServer = new CServer(this, pServerInfo100->sv100_name);
  435. m_serverArray.SetAt(iServer++, pServer); // validate later
  436. pServerInfo100++;
  437. }
  438. NetApiBufferFree(ReturnBuffer);
  439. }
  440. } while (NetStatus == ERROR_MORE_DATA);
  441. LlsSetLastStatus(NetStatus); // called api
  442. if (NetStatus == ERROR_SUCCESS)
  443. {
  444. m_bServersRefreshed = TRUE;
  445. }
  446. else
  447. {
  448. ResetServers();
  449. }
  450. return m_bServersRefreshed;
  451. }
  452. BOOL CDomain::RefreshUsers()
  453. /*++
  454. Routine Description:
  455. Refreshs user object array.
  456. Arguments:
  457. None.
  458. Return Values:
  459. VT_BOOL.
  460. --*/
  461. {
  462. ResetUsers();
  463. NET_API_STATUS NetStatus;
  464. DWORD ResumeHandle = 0L;
  465. int iUser = 0;
  466. do
  467. {
  468. DWORD EntriesRead;
  469. DWORD TotalEntries;
  470. LPBYTE ReturnBuffer = NULL;
  471. NetStatus = NetUserEnum(
  472. GetPrimary(), // servername
  473. 0, // level
  474. FILTER_NORMAL_ACCOUNT,
  475. &ReturnBuffer,
  476. LLS_PREFERRED_LENGTH,
  477. &EntriesRead,
  478. &TotalEntries,
  479. &ResumeHandle
  480. );
  481. if (NetStatus == ERROR_SUCCESS ||
  482. NetStatus == ERROR_MORE_DATA)
  483. {
  484. CUser* pUser;
  485. PUSER_INFO_0 pUserInfo0;
  486. pUserInfo0 = (PUSER_INFO_0)ReturnBuffer;
  487. ASSERT(iUser == m_userArray.GetSize());
  488. m_userArray.SetSize(m_userArray.GetSize() + EntriesRead);
  489. while (EntriesRead--)
  490. {
  491. pUser = new CUser(this, pUserInfo0->usri0_name);
  492. m_userArray.SetAt(iUser++, pUser); // validate later
  493. pUserInfo0++;
  494. }
  495. NetApiBufferFree(ReturnBuffer);
  496. }
  497. } while (NetStatus == ERROR_MORE_DATA);
  498. LlsSetLastStatus(NetStatus); // called api
  499. if (NetStatus == ERROR_SUCCESS)
  500. {
  501. m_bUsersRefreshed = TRUE;
  502. }
  503. else
  504. {
  505. ResetUsers();
  506. }
  507. return m_bUsersRefreshed;
  508. }
  509. void CDomain::ResetDomains()
  510. /*++
  511. Routine Description:
  512. Resets domain object array.
  513. Arguments:
  514. None.
  515. Return Values:
  516. None.
  517. --*/
  518. {
  519. CDomain* pDomain;
  520. INT_PTR iDomain = m_domainArray.GetSize();
  521. while (iDomain--)
  522. {
  523. pDomain = (CDomain*)m_domainArray[iDomain];
  524. if (NULL != pDomain)
  525. {
  526. ASSERT(pDomain->IsKindOf(RUNTIME_CLASS(CDomain)));
  527. pDomain->InternalRelease();
  528. }
  529. }
  530. m_domainArray.RemoveAll();
  531. m_bDomainsRefreshed = FALSE;
  532. }
  533. void CDomain::ResetServers()
  534. /*++
  535. Routine Description:
  536. Resets server object array.
  537. Arguments:
  538. None.
  539. Return Values:
  540. None.
  541. --*/
  542. {
  543. CServer* pServer;
  544. INT_PTR iServer = m_serverArray.GetSize();
  545. while (iServer--)
  546. {
  547. pServer = (CServer*)m_serverArray[iServer];
  548. if (NULL != pServer)
  549. {
  550. ASSERT(pServer->IsKindOf(RUNTIME_CLASS(CServer)));
  551. pServer->InternalRelease();
  552. }
  553. }
  554. m_serverArray.RemoveAll();
  555. m_bServersRefreshed = FALSE;
  556. }
  557. void CDomain::ResetUsers()
  558. /*++
  559. Routine Description:
  560. Resets user object array.
  561. Arguments:
  562. None.
  563. Return Values:
  564. None.
  565. --*/
  566. {
  567. CUser* pUser;
  568. INT_PTR iUser = m_userArray.GetSize();
  569. while (iUser--)
  570. {
  571. pUser = (CUser*)m_userArray[iUser];
  572. if (NULL != pUser)
  573. {
  574. ASSERT(pUser->IsKindOf(RUNTIME_CLASS(CUser)));
  575. pUser->InternalRelease();
  576. }
  577. }
  578. m_userArray.RemoveAll();
  579. m_bUsersRefreshed = FALSE;
  580. }