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.

767 lines
23 KiB

  1. //+----------------------------------------------------------------------------
  2. //
  3. // Windows 2000 Active Directory Service domain trust verification WMI provider
  4. //
  5. // Microsoft Windows
  6. // Copyright (C) Microsoft Corporation, 1992 - 2000
  7. //
  8. // File: trust.cpp
  9. //
  10. // Contents: Trust class implementation
  11. //
  12. // Classes: CTrustInfo
  13. //
  14. // History: 27-Mar-00 EricB created
  15. //
  16. //-----------------------------------------------------------------------------
  17. #include <stdafx.h>
  18. PCWSTR CSTR_PROP_TRUSTED_DOMAIN = L"TrustedDomain"; // String
  19. PCWSTR CSTR_PROP_FLAT_NAME = L"FlatName"; // String
  20. PCWSTR CSTR_PROP_SID = L"SID"; // String
  21. PCWSTR CSTR_PROP_TRUST_DIRECTION = L"TrustDirection"; // uint32
  22. PCWSTR CSTR_PROP_TRUST_TYPE = L"TrustType"; // uint32
  23. PCWSTR CSTR_PROP_TRUST_ATTRIBUTES = L"TrustAttributes"; // uint32
  24. PCWSTR CSTR_PROP_TRUST_STATUS = L"TrustStatus"; // uint32
  25. PCWSTR CSTR_PROP_TRUST_STATUS_STRING = L"TrustStatusString"; // String
  26. PCWSTR CSTR_PROP_TRUST_IS_OK = L"TrustIsOk"; // Boolean
  27. PCWSTR CSTR_PROP_TRUSTED_DC_NAME = L"TrustedDCName"; // String
  28. // Define NETLOGON_CONTROL_TC_VERIFY if not found so this will build for W2K.
  29. // This constant is in the Whistler version of lmaccess.h
  30. #if !defined(NETLOGON_CONTROL_TC_VERIFY)
  31. # define NETLOGON_CONTROL_TC_VERIFY (10)
  32. #endif
  33. //+----------------------------------------------------------------------------
  34. //
  35. // Class: CTrustInfo
  36. //
  37. //-----------------------------------------------------------------------------
  38. CTrustInfo::CTrustInfo() : m_ulTrustDirection(0),
  39. m_ulTrustType(0),
  40. m_ulTrustAttributes(0),
  41. m_trustStatus(ERROR_SUCCESS),
  42. m_VerifyStatus(VerifyStatusNone),
  43. m_fPwVerifySupported(TRUE)
  44. {
  45. m_liLastVerified.QuadPart = 0;
  46. }
  47. //+----------------------------------------------------------------------------
  48. //
  49. // Method: CTrustInfo::Verify
  50. //
  51. // Synopsis: Verify the status of the trust
  52. //
  53. // Returns: FALSE if the trust was not outbound.
  54. //
  55. //-----------------------------------------------------------------------------
  56. BOOL
  57. CTrustInfo::Verify(TrustCheckLevel CheckLevel)
  58. {
  59. TRACE(L"CTrustInfo::Verify, verify level %d\n", CheckLevel);
  60. NET_API_STATUS netStatus = NERR_Success;
  61. NETLOGON_INFO_2 * pNetlogonInfo2 = NULL;
  62. VerifyStatus Status = VerifyStatusNone;
  63. PCWSTR pwzTrustedDomain = GetTrustedDomain();
  64. CString strDCName, strResetTarget = GetTrustedDomain();
  65. if (DONT_VERIFY == CheckLevel)
  66. {
  67. TRACE(L"\tCheck-Level set to not verify trust.\n");
  68. SetTrustStatus(NERR_Success, VerifyStatusTrustNotChecked);
  69. return TRUE;
  70. }
  71. TRACE(L"\tVerifying trust with %s\n", GetTrustedDomain());
  72. if (TRUST_TYPE_MIT == GetTrustType())
  73. {
  74. // don't verify non-Windows trusts.
  75. //
  76. TRACE(L"\tNot a windows trust, returning.\n");
  77. SetTrustStatus(NERR_Success, VerifyStatusNotWindowsTrust);
  78. SetLastVerifiedTime();
  79. return TRUE;
  80. }
  81. if (!IsTrustOutbound())
  82. {
  83. // don't verify inbound-only trusts.
  84. //
  85. TRACE(L"\tInbound-only trust, returning.\n");
  86. SetTrustStatus(NERR_Success, VerifyStatusNotOutboundTrust);
  87. SetLastVerifiedTime();
  88. return FALSE;
  89. }
  90. //
  91. // NETLOGON_CONTROL_TC_QUERY - get the status (locally) and the name of trusted DC
  92. // Note that the secure channel is set up only on demand, so it is not an error if
  93. // it is not set up. The SC_QUERY will return ERROR_NO_LOGON_SERVERS if this is the
  94. // case.
  95. //
  96. netStatus = I_NetLogonControl2(NULL,
  97. NETLOGON_CONTROL_TC_QUERY,
  98. 2,
  99. (LPBYTE)&pwzTrustedDomain,
  100. (LPBYTE *)&pNetlogonInfo2);
  101. if (NERR_Success == netStatus)
  102. {
  103. ASSERT(pNetlogonInfo2);
  104. netStatus = pNetlogonInfo2->netlog2_tc_connection_status;
  105. if (netStatus == NERR_Success)
  106. {
  107. SetTrustedDCName(pNetlogonInfo2->netlog2_trusted_dc_name);
  108. strDCName = pNetlogonInfo2->netlog2_trusted_dc_name;
  109. #if !defined(NT4_BUILD)
  110. //
  111. // Compose the domain\dc string for the reset command so it will not change
  112. // DCs as a result of the reset. This only works with NT5 or later NetLogon.
  113. //
  114. strResetTarget += L"\\";
  115. strResetTarget += pNetlogonInfo2->netlog2_trusted_dc_name + 2; // skip the UNC double slashes
  116. #endif
  117. }
  118. else
  119. {
  120. if (ERROR_NO_LOGON_SERVERS == netStatus)
  121. {
  122. // This is the error returned when the SC has not yet been set up.
  123. // It is also returned if no DCs are reachable. DsGetDcName is called with the
  124. // force flag to discover if any DCs are reachable on the net.
  125. //
  126. PDOMAIN_CONTROLLER_INFO pDCInfo = NULL;
  127. DWORD dwRet = NO_ERROR;
  128. #if !defined(NT4_BUILD)
  129. dwRet = DsGetDcName(NULL, pwzTrustedDomain, NULL, NULL, DS_FORCE_REDISCOVERY, &pDCInfo);
  130. #endif
  131. if (NO_ERROR == dwRet)
  132. {
  133. // A DC is reachable, so it is safe to assume that the SC has not yet been
  134. // set up. Treat this as success.
  135. //
  136. netStatus = NERR_Success;
  137. TRACE(L"SC_QUERY has returned ERROR_NO_LOGON_SERVERS, SC not yet set up.\n");
  138. #if !defined(NT4_BUILD)
  139. SetTrustedDCName(pDCInfo->DomainControllerName);
  140. NetApiBufferFree(pDCInfo);
  141. #endif
  142. }
  143. else
  144. {
  145. // If there are no DCs, there is nothing to be done except return the error.
  146. //
  147. TRACE(L"DsGetDcName /FORCE has returned %d, DC not found.\n", dwRet);
  148. // Save the error code and fixed by method
  149. SetTrustStatus(dwRet, VerifyStatusBroken);
  150. SetLastVerifiedTime();
  151. return TRUE;
  152. }
  153. }
  154. else
  155. {
  156. TRACE(L"SC_QUERY has returned %d.\n", netStatus);
  157. }
  158. }
  159. NetApiBufferFree(pNetlogonInfo2);
  160. }
  161. else
  162. {
  163. TRACE(L"I_NetLogonControl2 has returned %d.\n", netStatus);
  164. }
  165. //
  166. // Do a trust PW verification if the other domain supports it.
  167. //
  168. if (PW_VERIFY == CheckLevel)
  169. {
  170. if (m_fPwVerifySupported)
  171. {
  172. netStatus = I_NetLogonControl2(NULL,
  173. NETLOGON_CONTROL_TC_VERIFY,
  174. 2,
  175. (LPBYTE)&pwzTrustedDomain,
  176. (LPBYTE *)&pNetlogonInfo2);
  177. if (NERR_Success == netStatus)
  178. {
  179. ASSERT(pNetlogonInfo2);
  180. netStatus = pNetlogonInfo2->netlog2_tc_connection_status;
  181. NetApiBufferFree(pNetlogonInfo2);
  182. }
  183. if (NERR_Success == netStatus)
  184. {
  185. TRACE(L"PW Verify successful on %s\n", pwzTrustedDomain);
  186. Status = VerifyStatusTrustOK;
  187. }
  188. else
  189. {
  190. if (ERROR_INVALID_LEVEL == netStatus ||
  191. ERROR_NOT_SUPPORTED == netStatus ||
  192. RPC_S_PROCNUM_OUT_OF_RANGE == netStatus ||
  193. RPC_NT_PROCNUM_OUT_OF_RANGE == netStatus)
  194. {
  195. TRACE(L"NETLOGON_CONTROL_TC_VERIFY is not supported on %s\n", pwzTrustedDomain);
  196. m_fPwVerifySupported = FALSE;
  197. Status = VerifyStatusPwCheckNotSupported;
  198. netStatus = NERR_Success; // call it success since we don't know the true state
  199. }
  200. else
  201. {
  202. TRACE(L"NETLOGON_CONTROL_TC_VERIFY returned 0x%08x on %s\n", netStatus, pwzTrustedDomain);
  203. Status = VerifyStatusBroken;
  204. }
  205. }
  206. }
  207. else
  208. {
  209. Status = VerifyStatusPwCheckNotSupported;
  210. }
  211. }
  212. //
  213. // Try an SC Reset against the DC returned by the SC query
  214. //
  215. if (SC_RESET == CheckLevel)
  216. {
  217. PCWSTR pwzResetTarget = strResetTarget;
  218. netStatus = I_NetLogonControl2(NULL,
  219. NETLOGON_CONTROL_REDISCOVER,
  220. 2,
  221. (LPBYTE)&pwzResetTarget,
  222. (LPBYTE *)&pNetlogonInfo2);
  223. if (NERR_Success == netStatus)
  224. {
  225. ASSERT(pNetlogonInfo2);
  226. netStatus = pNetlogonInfo2->netlog2_tc_connection_status;
  227. NetApiBufferFree(pNetlogonInfo2);
  228. }
  229. if (NERR_Success == netStatus)
  230. {
  231. TRACE(L"SC_RESET successfull on %s\n", pwzResetTarget);
  232. Status = VerifyStatusRediscover;
  233. }
  234. else
  235. {
  236. TRACE(L"SC_RESET returned 0x%08x on %s\n", netStatus, pwzResetTarget);
  237. }
  238. }
  239. #ifdef NT4_BUILD
  240. //
  241. // Force trust pw replication from PDC to BDCs; only works on pre-W2K.
  242. //
  243. if (netStatus != NERR_Success)
  244. {
  245. // perform only once, ignore the result
  246. ForceReplication();
  247. }
  248. #endif
  249. //
  250. // If still in an error state, do an SC reset against any DC
  251. //
  252. if (netStatus != NERR_Success)
  253. {
  254. netStatus = ForceRediscover(NULL, &strDCName);
  255. if (NERR_Success == netStatus)
  256. {
  257. Status = VerifyStatusRediscover;
  258. SetTrustedDCName(const_cast<PWSTR>((PCWSTR)strDCName));
  259. }
  260. }
  261. //
  262. // Walk through the DCs trying to establish an SC: TRCHK_RETARGET_ON_ERROR
  263. //
  264. if (NERR_Success != netStatus)
  265. {
  266. vector<LPWSTR> dcList;
  267. LPBYTE pbuf = NULL;
  268. TRACE(L"Attempting to retarget...\n");
  269. //
  270. // Enumerate all DCs in the trusted domain
  271. // Attempt reconnecting to another DC.
  272. //
  273. // The returned value is not recorded.
  274. // (if not enumerated, skip this step)
  275. //
  276. if( NERR_Success == GetDCList(strDCName,
  277. dcList,
  278. &pbuf))
  279. {
  280. //
  281. // Try to connect to every DC until success
  282. //
  283. for (vector<LPWSTR>::iterator ppszDCName = dcList.begin();
  284. NERR_Success != netStatus && ppszDCName != dcList.end();
  285. ppszDCName++)
  286. {
  287. netStatus = ForceRediscover(*ppszDCName, &strDCName);
  288. }
  289. }
  290. if (NERR_Success == netStatus)
  291. {
  292. SetTrustedDCName(const_cast<PWSTR>((PCWSTR)strDCName));
  293. Status = VerifyStatusRetarget;
  294. }
  295. //
  296. // Clean up the DC list
  297. //
  298. if (pbuf)
  299. {
  300. VERIFY( NERR_Success == NetApiBufferFree(pbuf));
  301. }
  302. }
  303. // Save the error code and Status
  304. SetTrustStatus(netStatus, Status);
  305. SetLastVerifiedTime();
  306. return TRUE;
  307. }
  308. //+----------------------------------------------------------------------------
  309. //
  310. // Method: CTrustInfo::SetLastVerifiedTime
  311. //
  312. // Synopsis: Record the time of verification.
  313. //
  314. //-----------------------------------------------------------------------------
  315. void
  316. CTrustInfo::SetLastVerifiedTime(void)
  317. {
  318. SYSTEMTIME st;
  319. GetSystemTime(&st);
  320. SystemTimeToFileTime(&st, (LPFILETIME)&m_liLastVerified);
  321. }
  322. //+----------------------------------------------------------------------------
  323. //
  324. // Method: CTrustInfo::IsVerificationStale
  325. //
  326. // Synopsis: Checks to see if the last verification time is older than the
  327. // passed in criteria.
  328. //
  329. // Returns: TRUE if older.
  330. //
  331. // Notes: If the trust hasn't been verified (m_liLastVerified == 0),
  332. // then the verification is defined to be stale.
  333. //
  334. //-----------------------------------------------------------------------------
  335. BOOL
  336. CTrustInfo::IsVerificationStale(LARGE_INTEGER liMaxAge)
  337. {
  338. TRACE(L"CTrustInfo::IsVerificationStale(0x%08x), MaxAge = %d\n",
  339. this, liMaxAge.QuadPart / TRUSTMON_FILETIMES_PER_MINUTE);
  340. BOOL fStale = FALSE;
  341. LARGE_INTEGER liCurrentTime;
  342. SYSTEMTIME st;
  343. GetSystemTime(&st);
  344. SystemTimeToFileTime(&st, (LPFILETIME)&liCurrentTime);
  345. //TRACE(L"\tlast: %I64d, cur: %I64d, max: %I64d\n", m_liLastVerified, liCurrentTime, liMaxAge);
  346. fStale = (m_liLastVerified.QuadPart + liMaxAge.QuadPart) < liCurrentTime.QuadPart;
  347. return fStale;
  348. }
  349. //+----------------------------------------------------------------------------
  350. //
  351. // Method: CTrustInfo::GetDCList
  352. //
  353. // Synopsis: Enumerate all DCs in a domain and return a list in random order.
  354. //
  355. //-----------------------------------------------------------------------------
  356. NET_API_STATUS
  357. CTrustInfo::GetDCList(PCWSTR pszKnownServer, // OPTIONAL The server name to be placed in the end of the list
  358. vector<LPWSTR> & dcList, // Vector of PCWSTRs, pointing to the DC names inside pbufptr
  359. LPBYTE * pbufptr ) // This buffer must be freed with NetApiBufferFree when done.
  360. {
  361. TRACE(L"CTrustInfo::GetDCList\n");
  362. ASSERT( pbufptr );
  363. ASSERT( !(*pbufptr) );
  364. NET_API_STATUS netStatus = NERR_Success;
  365. DWORD dwEntriesRead = 0;
  366. DWORD dwTotalEntries = 0;
  367. DWORD dwResumeHandle = 0;
  368. DWORD dwIndKnownServer = MAXDWORD;
  369. DWORD dwInd = 0;
  370. do
  371. {
  372. // Init
  373. dcList.clear();
  374. //
  375. // Enumerate all the servers belonging to the specified domain
  376. //
  377. netStatus = NetServerEnum( NULL,
  378. 100, // SERVER_INFO_100
  379. pbufptr,
  380. MAX_PREFERRED_LENGTH,
  381. & dwEntriesRead,
  382. & dwTotalEntries,
  383. SV_TYPE_DOMAIN_CTRL | SV_TYPE_DOMAIN_BAKCTRL,
  384. GetTrustedDomain(),
  385. & dwResumeHandle );
  386. TRACE(L"NetServerEnum returned 0x%08x! (%d entries)\n", netStatus, dwEntriesRead);
  387. if( netStatus == ERROR_MORE_DATA )
  388. {
  389. // should never happen (no enum handle)
  390. ASSERT( FALSE );
  391. // process whatever NetServerEnum returned.
  392. netStatus = NERR_Success;
  393. }
  394. if( netStatus != NERR_Success ||
  395. !dwEntriesRead ||
  396. !(*pbufptr) )
  397. {
  398. TRACE(L"Failure, exiting...\n");
  399. dcList.clear();
  400. if( *pbufptr )
  401. {
  402. VERIFY( NERR_Success == NetApiBufferFree( *pbufptr ) );
  403. *pbufptr = NULL;
  404. }
  405. break;
  406. }
  407. // To simplify buffer access...
  408. PSERVER_INFO_100 pServerInfo100 = PSERVER_INFO_100( *pbufptr );
  409. // Reserve enough space for all the entries
  410. dcList.reserve( dwEntriesRead );
  411. //
  412. // Create a list of Servers
  413. //
  414. for( dwInd = 0; dwInd < dwEntriesRead; dwInd++ )
  415. {
  416. if( pszKnownServer &&
  417. !_wcsicmp( pszKnownServer, pServerInfo100[dwInd].sv100_name ) )
  418. {
  419. dwIndKnownServer = dwInd; // postpone until the end
  420. }
  421. else
  422. {
  423. dcList.push_back( pServerInfo100[dwInd].sv100_name );
  424. }
  425. }
  426. ASSERT( dwEntriesRead );
  427. //
  428. // Known server should go to the end of the list
  429. //
  430. if( MAXDWORD != dwIndKnownServer )
  431. {
  432. TRACE(L"Server %s placed @ the end\n", pszKnownServer);
  433. dcList.push_back( pServerInfo100[dwIndKnownServer].sv100_name );
  434. // Shuffling should not include the last entry
  435. dwEntriesRead--;
  436. }
  437. //
  438. // Initialize randomizer
  439. //
  440. srand( (unsigned) time( NULL ) );
  441. //
  442. // Shuffle by replacing each entry with another random entry
  443. //
  444. for( dwInd = 0; dwInd < (int) dwEntriesRead; dwInd++ )
  445. {
  446. DWORD dwRandPos = DWORD( rand() % dwEntriesRead );
  447. if( dwRandPos == dwInd )
  448. continue;
  449. // Swap!
  450. LPWSTR pstrTemp = dcList[ dwRandPos ];
  451. dcList[ dwRandPos ] = dcList[ dwInd ];
  452. dcList[ dwInd ] = pstrTemp;
  453. }
  454. } while( FALSE );
  455. return netStatus;
  456. }
  457. //+----------------------------------------------------------------------------
  458. //
  459. // Method: CTrustInfo::ForceRediscover
  460. //
  461. // Synopsis:
  462. //
  463. //-----------------------------------------------------------------------------
  464. NET_API_STATUS
  465. CTrustInfo::ForceRediscover(PCWSTR pstrDCName, CString * pstrDCNameRet)
  466. {
  467. TRACE(L"CTrustInfo::ForceRediscover\n");
  468. NET_API_STATUS netStatus = NERR_Success;
  469. NETLOGON_INFO_2 * pNetlogonInfo2 = NULL;
  470. CString strTemp;
  471. PCWSTR pstrDomainName = GetTrustedDomain();
  472. if( pstrDCName )
  473. {
  474. //
  475. // Form domain\dc request
  476. //
  477. strTemp = pstrDomainName;
  478. strTemp += L"\\";
  479. strTemp += pstrDCName;
  480. // Retarget pstrDomainName to the new string
  481. pstrDomainName = strTemp;
  482. }
  483. //
  484. // Attempt to re-establish trust
  485. //
  486. netStatus = I_NetLogonControl2( NULL,
  487. NETLOGON_CONTROL_REDISCOVER,
  488. 2,
  489. ( LPBYTE ) &pstrDomainName,
  490. ( LPBYTE *) &pNetlogonInfo2 );
  491. TRACE(L"I_NetLogonControl2:NETLOGON_CONTROL_REDISCOVER to %s returned 0x%08x\n",
  492. pstrDomainName, netStatus);
  493. //
  494. // Clean-up
  495. //
  496. if( pNetlogonInfo2 )
  497. {
  498. *pstrDCNameRet = pNetlogonInfo2->netlog2_trusted_dc_name;
  499. TRACE(L"netlog2_flags=0x%08x, netlog2_pdc_connection_status=0x%08x\n",
  500. pNetlogonInfo2->netlog2_flags,
  501. pNetlogonInfo2->netlog2_pdc_connection_status);
  502. TRACE(L"netlog2_trusted_dc_name=%s, netlog2_tc_connection_status=0x%08x\n",
  503. pNetlogonInfo2->netlog2_trusted_dc_name,
  504. pNetlogonInfo2->netlog2_tc_connection_status);
  505. NetApiBufferFree( pNetlogonInfo2 );
  506. }
  507. return netStatus;
  508. }
  509. //+----------------------------------------------------------------------------
  510. //
  511. // Method: CTrustInfo::SetTrustStatus
  512. //
  513. // Synopsis: Set the status string based on the netStatus value if an error
  514. // else based on the VerifyStatus.
  515. //
  516. //-----------------------------------------------------------------------------
  517. void
  518. CTrustInfo::SetTrustStatus(ULONG netStatus, VerifyStatus Status)
  519. {
  520. WCHAR wzBuf[512];
  521. m_trustStatus = netStatus;
  522. m_VerifyStatus = Status;
  523. if (NERR_Success == netStatus)
  524. {
  525. int nStrID;
  526. switch (Status)
  527. {
  528. case VerifyStatusNone:
  529. //
  530. // This is the default value for the Status parameter.
  531. //
  532. case VerifyStatusTrustOK:
  533. nStrID = IDS_TRUST_STATUS_OK;
  534. break;
  535. case VerifyStatusNotWindowsTrust:
  536. nStrID = IDS_MIT_TRUST_STATUS;
  537. break;
  538. case VerifyStatusNotOutboundTrust:
  539. nStrID = IDS_STATUS_INBOUND_ONLY;
  540. break;
  541. case VerifyStatusTrustNotChecked:
  542. nStrID = IDS_STATUS_NOT_CHECKED;
  543. break;
  544. case VerifyStatusPwCheckNotSupported:
  545. nStrID = IDS_PW_VERIFY_NOT_SUPPORTED;
  546. break;
  547. case VerifyStatusRetarget:
  548. nStrID = IDS_FIXED_BY_RETARGET;
  549. break;
  550. case VerifyStatusRediscover:
  551. nStrID = IDS_STATUS_REDISCOVER;
  552. break;
  553. case VerifyStatusBroken:
  554. ASSERT(FALSE); // shouldn't get here, fall through.
  555. default:
  556. nStrID = IDS_STATUS_UNKNOWN;
  557. }
  558. LoadString(_Module.GetModuleInstance(), nStrID, wzBuf, 512);
  559. m_strTrustStatus = wzBuf;
  560. }
  561. else
  562. {
  563. PWSTR pwzMsg;
  564. if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
  565. FORMAT_MESSAGE_FROM_SYSTEM |
  566. FORMAT_MESSAGE_IGNORE_INSERTS,
  567. NULL,
  568. netStatus,
  569. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  570. (PWSTR)&pwzMsg,
  571. 0,
  572. NULL))
  573. {
  574. PWSTR pwzSuffix = wcsstr(pwzMsg, L"\r\n");
  575. if (pwzSuffix)
  576. {
  577. *pwzSuffix = L'\0';
  578. }
  579. m_strTrustStatus = pwzMsg;
  580. LocalFree(pwzMsg);
  581. }
  582. else
  583. {
  584. LoadString(_Module.GetModuleInstance(), IDS_TRUST_STATUS_FAILED, wzBuf, 512);
  585. m_strTrustStatus = wzBuf;
  586. }
  587. }
  588. }
  589. //+----------------------------------------------------------------------------
  590. //
  591. // Method: CTrustInfo::SetTrustDirectionFromFlags
  592. //
  593. //-----------------------------------------------------------------------------
  594. void
  595. CTrustInfo::SetTrustDirectionFromFlags(ULONG ulFlags)
  596. {
  597. m_ulTrustDirection = 0;
  598. if (DS_DOMAIN_DIRECT_OUTBOUND & ulFlags)
  599. {
  600. m_ulTrustDirection = TRUST_DIRECTION_OUTBOUND;
  601. }
  602. if (DS_DOMAIN_DIRECT_INBOUND & ulFlags)
  603. {
  604. m_ulTrustDirection |= TRUST_DIRECTION_INBOUND;
  605. }
  606. }
  607. //+----------------------------------------------------------------------------
  608. //
  609. // Method: CTrustInfo::SetSid
  610. //
  611. //-----------------------------------------------------------------------------
  612. BOOL
  613. CTrustInfo::SetSid(PSID pSid)
  614. {
  615. if (!pSid)
  616. {
  617. return TRUE;
  618. }
  619. #if !defined(NT4_BUILD)
  620. PWSTR buffer;
  621. BOOL fRet = ConvertSidToStringSid(pSid, &buffer);
  622. if (fRet)
  623. {
  624. m_strSid = buffer;
  625. LocalFree(buffer);
  626. }
  627. return fRet;
  628. #else
  629. // TODO: Code for NT4 ??
  630. #pragma message("need ConvertSidToStringSid for NT4");
  631. #endif
  632. }
  633. #ifdef NT4_BUILD
  634. //+----------------------------------------------------------------------------
  635. //
  636. // Function: ForceReplication
  637. //
  638. // Synopsis: Force local Domain Replication -- works only for NT4 domains
  639. //
  640. //-----------------------------------------------------------------------------
  641. NET_API_STATUS ForceReplication(void)
  642. {
  643. TRACE(L"ForceReplication\n");
  644. NET_API_STATUS netStatus = NERR_Success;
  645. LPBYTE pbInputDataPtr = NULL;
  646. PNETLOGON_INFO_1 pNetlogonInfo1 = NULL;
  647. netStatus = I_NetLogonControl2( NULL,
  648. NETLOGON_CONTROL_REPLICATE,
  649. 1,
  650. (LPBYTE ) &pbInputDataPtr,
  651. (LPBYTE *) &pNetlogonInfo1 );
  652. TRACE(L"I_NetLogonControl2:NETLOGON_CONTROL_REPLICATE returned 0x%08x\n", netStatus);
  653. if( pNetlogonInfo1 )
  654. {
  655. TRACE(L"netlog1_flags=0x%08x, netlog1_pdc_connection_status=0x%08x\n",
  656. pNetlogonInfo1->netlog1_flags,
  657. pNetlogonInfo1->netlog1_pdc_connection_status);
  658. NetApiBufferFree( pNetlogonInfo1 );
  659. }
  660. return netStatus;
  661. }
  662. #endif //NT4_BUILD