Source code of Windows XP (NT5)
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.

779 lines
24 KiB

  1. #include <pch.cxx>
  2. #pragma hdrstop
  3. #include <ole2.h>
  4. #include "trkwks.hxx"
  5. #include "trksvr.hxx"
  6. #include "dltadmin.hxx"
  7. void
  8. CDomainRelativeObjId::FillLdapIdtKeyBuffer(TCHAR * const pchCN,
  9. DWORD cch) const
  10. {
  11. TCHAR *pchBuf = pchCN;
  12. _tcscpy(pchBuf, TEXT("CN="));
  13. pchBuf = pchBuf + 3;
  14. _volume.Stringize(pchBuf);
  15. _object.Stringize(pchBuf);
  16. TrkAssert(pchBuf <= pchCN+cch);
  17. }
  18. void
  19. ShowMoveCounter( const TCHAR *ptszHostName )
  20. {
  21. CDbConnection dbc;
  22. dbc.Initialize( NULL, ptszHostName );
  23. CTrkSvrConfiguration
  24. configSvr;
  25. configSvr.Initialize();
  26. BOOL fSuccess = FALSE;
  27. struct berval** ppbvCounter = NULL;
  28. TCHAR* rgtszAttrs[2];
  29. LDAPMessage* pRes = NULL;
  30. int ldapRV;
  31. int cEntries = 0;
  32. LDAPMessage* pEntry = NULL;
  33. CLdapQuotaCounterKeyDn dnKeyCounter(dbc.GetBaseDn());
  34. DWORD dwCounter = 0;
  35. __try
  36. {
  37. rgtszAttrs[0] = const_cast<TCHAR*>(s_volumeSecret);
  38. rgtszAttrs[1] = NULL;
  39. ldapRV = ldap_search_s(dbc.Ldap(),
  40. dnKeyCounter,
  41. LDAP_SCOPE_BASE,
  42. TEXT("(ObjectClass=*)"),
  43. rgtszAttrs,
  44. 0,
  45. &pRes);
  46. if( LDAP_NO_SUCH_OBJECT == ldapRV )
  47. {
  48. printf( "Move table counter doesn't exist\n" );
  49. __leave;
  50. }
  51. else if( LDAP_SUCCESS != ldapRV )
  52. {
  53. printf( "Couldn't read move table counter (%d)\n", ldapRV );
  54. __leave;
  55. }
  56. cEntries = ldap_count_entries(dbc.Ldap(), pRes);
  57. if( 0 == cEntries )
  58. {
  59. printf( "Move table counter didn't exist or couldn't be read\n" );
  60. __leave;
  61. }
  62. else if( 1 != cEntries )
  63. {
  64. printf( "Too many move table counters (%d)!\n", cEntries );
  65. __leave;
  66. }
  67. pEntry = ldap_first_entry(dbc.Ldap(), pRes);
  68. if(NULL == pEntry)
  69. {
  70. printf( "Entries couldn't be read from result\n" );
  71. __leave;
  72. }
  73. ppbvCounter = ldap_get_values_len(dbc.Ldap(), pEntry, const_cast<TCHAR*>(s_volumeSecret) );
  74. if (ppbvCounter == NULL)
  75. {
  76. _tprintf( TEXT("Move table counter is corrupt, missing %s attribute\n"),
  77. s_volumeSecret );
  78. __leave;
  79. }
  80. if ((*ppbvCounter)->bv_len < sizeof(DWORD))
  81. {
  82. _tprintf( TEXT("Move table counter attribute %s has wrong type (%d)\n"),
  83. s_volumeSecret, (*ppbvCounter)->bv_len );
  84. __leave;
  85. }
  86. memcpy( (PCHAR)&dwCounter, (*ppbvCounter)->bv_val, sizeof(DWORD) );
  87. printf( "Move table counter (in DS) %lu\n", dwCounter );
  88. }
  89. __finally
  90. {
  91. if(NULL != pRes)
  92. {
  93. ldap_msgfree(pRes);
  94. }
  95. if (ppbvCounter != NULL)
  96. {
  97. ldap_value_free_len(ppbvCounter);
  98. }
  99. }
  100. }
  101. /*
  102. ShowDcEntries( const TCHAR *ptszHostName )
  103. {
  104. TCHAR* rgptszAttrs[4];
  105. LDAPMessage* pRes = NULL;
  106. int ldapRV;
  107. HRESULT hr = E_FAIL;
  108. CDbConnection dbc;
  109. dbc.Initialize( NULL, ptszHostName );
  110. CLdapVolumeKeyDn dnKey(dbc.GetBaseDn());
  111. LONGLONG llCreationTime, llLastAliveTime;
  112. CFILETIME cftNow;
  113. CTrkSvrConfiguration
  114. configSvr;
  115. configSvr.Initialize();
  116. struct berval ** ppbvMachineId = NULL;
  117. TCHAR** pptszCreationTime = NULL;
  118. TCHAR** pptszLastAliveTime = NULL;
  119. LDAPMessage * pEntry = NULL;
  120. struct SDcEntries
  121. {
  122. CMachineId mcid;
  123. BOOL fSuspended;
  124. CFILETIME cftCreation;
  125. CFILETIME cftLastAlive;
  126. };
  127. SDcEntries rgsDcEntries[ 100 ];
  128. ULONG cDcEntries = 0;
  129. CMachineId mcidDesignated;
  130. ULONG cEntries = 0;
  131. __try
  132. {
  133. rgptszAttrs[0] = const_cast<TCHAR*>(s_Cn);
  134. rgptszAttrs[1] = const_cast<TCHAR*>(s_timeVolChange);
  135. rgptszAttrs[2] = const_cast<TCHAR*>(s_timeRefresh);
  136. rgptszAttrs[3] = NULL;
  137. ldapRV = ldap_search_s( dbc.Ldap(),
  138. dnKey,
  139. LDAP_SCOPE_ONELEVEL,
  140. TEXT("(cn=QTDC_*)"),
  141. rgptszAttrs,
  142. 0,
  143. &pRes);
  144. if(LDAP_SUCCESS != ldapRV)
  145. {
  146. printf( "Failed ldap_search_s (%lu)\n", LdapMapErrorToWin32(ldapRV) );
  147. hr = HRESULT_FROM_WIN32(LdapMapErrorToWin32(ldapRV) );
  148. __leave;
  149. }
  150. cEntries = ldap_count_entries( dbc.Ldap(), pRes );
  151. if(cEntries < 1)
  152. __leave;
  153. pEntry = ldap_first_entry( dbc.Ldap(), pRes );
  154. if(NULL == pEntry)
  155. {
  156. printf( "Invalid ldap_first_entry\n" );
  157. __leave;
  158. }
  159. // Loop through the results.
  160. while(TRUE)
  161. {
  162. // Get the machine id.
  163. ppbvMachineId = ldap_get_values_len( dbc.Ldap(), pEntry, const_cast<TCHAR*>(s_Cn) );
  164. if(NULL == ppbvMachineId)
  165. {
  166. printf( "Couldn't get machine ID\n" );
  167. hr = TRK_E_CORRUPT_VOLTAB;
  168. __leave;
  169. }
  170. if((*ppbvMachineId)->bv_val == NULL)
  171. {
  172. printf( "Couldn't get machine ID\n" );
  173. hr = TRK_E_CORRUPT_VOLTAB;
  174. __leave;
  175. }
  176. memcpy( &rgsDcEntries[cDcEntries].mcid,
  177. (*ppbvMachineId)->bv_val + 5,
  178. strlen((*ppbvMachineId)->bv_val+5));
  179. // Get the creation time.
  180. pptszCreationTime = ldap_get_values(dbc.Ldap(), pEntry, const_cast<TCHAR*>(s_timeVolChange) );
  181. if(NULL == pptszCreationTime)
  182. {
  183. printf( "Couldn't get the creation time\n" );
  184. hr = TRK_E_CORRUPT_VOLTAB;
  185. __leave;
  186. }
  187. _stscanf(*pptszCreationTime, TEXT("%I64u"), &llCreationTime);
  188. rgsDcEntries[cDcEntries].cftCreation = CFILETIME(llCreationTime);
  189. // Get the last alive time.
  190. pptszLastAliveTime = ldap_get_values(dbc.Ldap(), pEntry, const_cast<TCHAR*>(s_timeRefresh) );
  191. if(NULL == pptszLastAliveTime)
  192. {
  193. printf( "Couldn't get last alive time\n" );
  194. hr = TRK_E_CORRUPT_VOLTAB;
  195. __leave;
  196. }
  197. _stscanf(*pptszLastAliveTime, TEXT("%I64u"), &llLastAliveTime);
  198. rgsDcEntries[cDcEntries].cftLastAlive = CFILETIME(llLastAliveTime);
  199. rgsDcEntries[cDcEntries].fSuspended = FALSE;
  200. if(((LONGLONG)cftNow - (LONGLONG)rgsDcEntries[cDcEntries].cftCreation) / 10000000 < configSvr.GetDcSuspensionPeriod()
  201. ||
  202. ((LONGLONG)cftNow - (LONGLONG)rgsDcEntries[cDcEntries].cftLastAlive) / 10000000 > configSvr.GetDcSuspensionPeriod()
  203. )
  204. {
  205. rgsDcEntries[cDcEntries].fSuspended = TRUE;
  206. }
  207. else if( rgsDcEntries[cDcEntries].mcid > mcidDesignated )
  208. {
  209. mcidDesignated = rgsDcEntries[cDcEntries].mcid;
  210. }
  211. if (ppbvMachineId != NULL)
  212. {
  213. ldap_value_free_len(ppbvMachineId);
  214. ppbvMachineId = NULL;
  215. }
  216. if (pptszCreationTime != NULL)
  217. {
  218. ldap_value_free(pptszCreationTime);
  219. pptszCreationTime = NULL;
  220. }
  221. if (pptszLastAliveTime != NULL)
  222. {
  223. ldap_value_free(pptszLastAliveTime);
  224. pptszLastAliveTime = NULL;
  225. }
  226. cDcEntries++;
  227. pEntry = ldap_next_entry(dbc.Ldap(), pEntry);
  228. if(!pEntry)
  229. {
  230. break;
  231. }
  232. } // while( TRUE )
  233. for( int iEntry = 0; iEntry < cDcEntries; iEntry++ )
  234. {
  235. CFILETIME cftLocal;
  236. TCHAR tszTime[ 80 ];
  237. printf( " %-16s ", &rgsDcEntries[iEntry].mcid );
  238. if( rgsDcEntries[iEntry].mcid == mcidDesignated )
  239. printf( " (** Designated **)\n" );
  240. else if( rgsDcEntries[iEntry].fSuspended )
  241. printf(" (suspended)\n" );
  242. else
  243. printf(" (not suspended)\n" );
  244. cftLocal = rgsDcEntries[iEntry].cftCreation.ConvertUtcToLocal();
  245. cftLocal.Stringize( ELEMENTS(tszTime), tszTime );
  246. _tprintf( TEXT(" Create = %s\n"), tszTime );
  247. cftLocal = rgsDcEntries[iEntry].cftLastAlive.ConvertUtcToLocal();
  248. cftLocal.Stringize( ELEMENTS(tszTime), tszTime );
  249. _tprintf( TEXT(" Alive = %s\n"), tszTime );
  250. }
  251. }
  252. __finally
  253. {
  254. if (ppbvMachineId != NULL)
  255. {
  256. ldap_value_free_len(ppbvMachineId);
  257. }
  258. if (pptszCreationTime != NULL)
  259. {
  260. ldap_value_free(pptszCreationTime);
  261. }
  262. if (pptszLastAliveTime != NULL)
  263. {
  264. ldap_value_free(pptszLastAliveTime);
  265. }
  266. if( NULL != pRes )
  267. ldap_msgfree(pRes);
  268. }
  269. return hr;
  270. }
  271. */
  272. BOOL
  273. DltAdminSvrStat( ULONG cArgs, const TCHAR * const rgptszArgs[], ULONG *pcEaten )
  274. {
  275. NTSTATUS status;
  276. HRESULT hr = S_OK;;
  277. RPC_BINDING_HANDLE BindingHandle;
  278. BOOL fBound = FALSE;
  279. BOOL fShowDsInfo = FALSE;
  280. ULONG iDcName = 0;
  281. if( 1 <= cArgs && IsHelpArgument( rgptszArgs[0] ))
  282. {
  283. printf( "\nOption SvrStat\n"
  284. " Purpose: Query a DC for TrkSvr statistics\n"
  285. " Usage: -svrstat [options] <DC name>\n"
  286. " E.g.: -svrstat ntdsdc0\n"
  287. " Note: To find a DC name for a domain, use the nltest tool\n" );
  288. *pcEaten = 1;
  289. return( TRUE );
  290. }
  291. _tprintf( TEXT("Checking for TrkSvr statistics\n"), rgptszArgs[0] );
  292. if( 1 > cArgs )
  293. {
  294. printf( "Invalid parameters. Use -? for usage info\n" );
  295. *pcEaten = 0;
  296. return( FALSE );
  297. }
  298. *pcEaten = 1;
  299. if( 2 <= cArgs && TEXT('-') == rgptszArgs[0][0] )
  300. {
  301. if( TEXT('d') == rgptszArgs[0][1]
  302. ||
  303. TEXT('D') == rgptszArgs[0][1] )
  304. {
  305. fShowDsInfo = TRUE;
  306. }
  307. else
  308. {
  309. printf( "Invalid option. Use -? for help\n" );
  310. return( FALSE );
  311. }
  312. iDcName = 1;
  313. (*pcEaten)++;
  314. }
  315. __try
  316. {
  317. CFILETIME cftLocal(0);
  318. TCHAR tszLocalFileTime[ 80 ];
  319. WCHAR wszAuthName[ 80 ];
  320. WCHAR wszUser[ 80 ];
  321. WCHAR wszDomain[ 80 ];
  322. RPC_STATUS rpcstatus = RPC_S_OK;
  323. RPC_TCHAR * ptszStringBinding = NULL;
  324. TRKSVR_MESSAGE_UNION Msg;
  325. memset( &Msg, 0, sizeof(Msg) );
  326. Msg.MessageType = STATISTICS;
  327. Msg.Priority = PRI_0;
  328. // Create a binding string
  329. rpcstatus = RpcStringBindingCompose(NULL,
  330. L"ncacn_np",
  331. const_cast<TCHAR*>(rgptszArgs[iDcName]),
  332. L"\\pipe\\trksvr",
  333. NULL,
  334. &ptszStringBinding);
  335. if( RPC_S_OK != rpcstatus )
  336. {
  337. hr = HRESULT_FROM_WIN32( rpcstatus );
  338. _tprintf( TEXT("Failed RpcStringBindingCompose (%d)\n"), rpcstatus );
  339. goto Exit;
  340. }
  341. _tprintf( TEXT("String binding = %s\n"), ptszStringBinding );
  342. // Get a client binding handle.
  343. rpcstatus = RpcBindingFromStringBinding(ptszStringBinding, &BindingHandle);
  344. RpcStringFree(&ptszStringBinding);
  345. if( RPC_S_OK != rpcstatus )
  346. {
  347. _tprintf( TEXT("Failed RpcBindingFromStringBinding (%d)\n"), rpcstatus );
  348. hr = HRESULT_FROM_WIN32( rpcstatus );
  349. goto Exit;
  350. }
  351. fBound = TRUE;
  352. // Call up to TrkSvr
  353. __try
  354. {
  355. hr = LnkSvrMessage(BindingHandle, &Msg);
  356. }
  357. __except( EXCEPTION_EXECUTE_HANDLER )
  358. {
  359. hr = HRESULT_FROM_WIN32( GetExceptionCode() );
  360. }
  361. if( FAILED(hr) )
  362. {
  363. _tprintf( TEXT("Failed LnkSvrMessage RPC (%08x)\n"), hr );
  364. goto Exit;
  365. }
  366. // Dump the results
  367. _tprintf( TEXT("\n") );
  368. _tprintf( TEXT("%-35s\t%d.%d (Build %d)\n"), TEXT("Version"),
  369. Msg.Statistics.Version.dwMajor, Msg.Statistics.Version.dwMinor,
  370. Msg.Statistics.Version.dwBuildNumber );
  371. _tprintf( TEXT("\n") );
  372. _tprintf( TEXT("%-35s\t%d\t%d\t%d\n"), TEXT("SyncVolume Requests/Errors/Threads"),
  373. Msg.Statistics.cSyncVolumeRequests, Msg.Statistics.cSyncVolumeErrors, Msg.Statistics.cSyncVolumeThreads );
  374. _tprintf( TEXT("%-35s\t%d\t%d\n"), TEXT(" CreateVolume Requests/Errors"),
  375. Msg.Statistics.cCreateVolumeRequests, Msg.Statistics.cCreateVolumeErrors );
  376. _tprintf( TEXT("%-35s\t%d\t%d\n"), TEXT(" ClaimVolume Requests/Errors"),
  377. Msg.Statistics.cClaimVolumeRequests, Msg.Statistics.cClaimVolumeErrors );
  378. _tprintf( TEXT("%-35s\t%d\t%d\n"), TEXT(" QueryVolume Requests/Errors"),
  379. Msg.Statistics.cQueryVolumeRequests, Msg.Statistics.cQueryVolumeErrors );
  380. _tprintf( TEXT("%-35s\t%d\t%d\n"), TEXT(" FindVolume Requests/Errors"),
  381. Msg.Statistics.cFindVolumeRequests, Msg.Statistics.cFindVolumeErrors );
  382. _tprintf( TEXT("%-35s\t%d\t%d\n"), TEXT(" TestVolume Requests/Errors"),
  383. Msg.Statistics.cTestVolumeRequests, Msg.Statistics.cTestVolumeErrors );
  384. _tprintf( TEXT("%-35s\t%d\t%d\t%d\n"), TEXT("Search Requests/Errors/Threads"),
  385. Msg.Statistics.cSearchRequests, Msg.Statistics.cSearchErrors, Msg.Statistics.cSearchThreads );
  386. _tprintf( TEXT("%-35s\t%d\t%d\t%d\n"), TEXT("MoveNotify Requests/Errors/Threads"),
  387. Msg.Statistics.cMoveNotifyRequests, Msg.Statistics.cMoveNotifyErrors, Msg.Statistics.cMoveNotifyThreads );
  388. _tprintf( TEXT("%-35s\t%d\t%d\t%d\n"), TEXT("Refresh Requests/Errors/Threads"),
  389. Msg.Statistics.cRefreshRequests, Msg.Statistics.cRefreshErrors, Msg.Statistics.cRefreshThreads );
  390. _tprintf( TEXT("%-35s\t%d\t%d\t%d\n"), TEXT("DeleteNotify Requests/Errors/Threads"),
  391. Msg.Statistics.cDeleteNotifyRequests, Msg.Statistics.cDeleteNotifyErrors, Msg.Statistics.cDeleteNotifyThreads );
  392. _tprintf( TEXT("\n") );
  393. cftLocal = static_cast<CFILETIME>(Msg.Statistics.ftServiceStart).ConvertUtcToLocal();
  394. cftLocal.Stringize( ELEMENTS(tszLocalFileTime), tszLocalFileTime );
  395. _tprintf( TEXT("%-35s\t%08x:%08x\n%35s\t(%s local time)\n"), TEXT("Service start"),
  396. Msg.Statistics.ftServiceStart.dwHighDateTime, Msg.Statistics.ftServiceStart.dwLowDateTime,
  397. TEXT(""), tszLocalFileTime );
  398. cftLocal = static_cast<CFILETIME>(Msg.Statistics.ftLastSuccessfulRequest).ConvertUtcToLocal();
  399. cftLocal.Stringize( ELEMENTS(tszLocalFileTime), tszLocalFileTime );
  400. _tprintf( TEXT("%-35s\t%08x:%08x\n%35s\t(%s local time)\n"), TEXT("Last successful request"),
  401. Msg.Statistics.ftLastSuccessfulRequest.dwHighDateTime, Msg.Statistics.ftLastSuccessfulRequest.dwLowDateTime,
  402. TEXT(""), tszLocalFileTime );
  403. _tprintf( TEXT("%-35s\t%08x\n"), TEXT("Last Error"), Msg.Statistics.hrLastError );
  404. _tprintf( TEXT("\nQuota Information:\n") );
  405. _tprintf( TEXT(" %-32s\t%d\n"), TEXT("Move Limit"), Msg.Statistics.dwMoveLimit );
  406. _tprintf( TEXT(" %-32s\t%d\n"), TEXT("Volume table cached count"), Msg.Statistics.dwCachedVolumeTableCount );
  407. _tprintf( TEXT(" %-32s\t%d\n"), TEXT("Move table cached count"), Msg.Statistics.dwCachedMoveTableCount );
  408. cftLocal = static_cast<CFILETIME>(Msg.Statistics.ftCacheLastUpdated).ConvertUtcToLocal();
  409. cftLocal.Stringize( ELEMENTS(tszLocalFileTime), tszLocalFileTime );
  410. _tprintf( TEXT(" %-32s\t%08x:%08x\n%35s\t(%s local time)\n"), TEXT("Cache counts last updated"),
  411. Msg.Statistics.ftCacheLastUpdated.dwHighDateTime, Msg.Statistics.ftCacheLastUpdated.dwLowDateTime,
  412. TEXT(""), tszLocalFileTime );
  413. _tprintf( TEXT(" %-32s\t%s\n"), TEXT("Is designated DC"),
  414. Msg.Statistics.fIsDesignatedDc ? TEXT("Yes") : TEXT("No") );
  415. _tprintf( TEXT("\n") );
  416. cftLocal = static_cast<CFILETIME>(Msg.Statistics.ftNextGC).ConvertUtcToLocal();
  417. cftLocal.Stringize( ELEMENTS(tszLocalFileTime), tszLocalFileTime );
  418. _tprintf( TEXT("%-35s\t%08x:%08x\n%35s\t(%s local time)\n"), TEXT("Next GC"),
  419. Msg.Statistics.ftNextGC.dwHighDateTime, Msg.Statistics.ftNextGC.dwLowDateTime,
  420. TEXT(""), tszLocalFileTime );
  421. _tprintf( TEXT("%-35s\t%d\n"), TEXT("Entries GC-ed"), Msg.Statistics.cEntriesGCed);
  422. _tprintf( TEXT("%-35s\t%d\n"), TEXT("Max DS write events"), Msg.Statistics.cMaxDsWriteEvents);
  423. _tprintf( TEXT("%-35s\t%d\n"), TEXT("Current failed writes"), Msg.Statistics.cCurrentFailedWrites);
  424. _tprintf( TEXT("\n") );
  425. _tprintf( TEXT("%-35s\t%d\n"), TEXT("Refresh counter"), Msg.Statistics.lRefreshCounter );
  426. _tprintf( TEXT("%-35s\t%d/%d/%d\n"), TEXT("Available/least/max RPC server threads"),
  427. Msg.Statistics.cAvailableRpcThreads, Msg.Statistics.cLowestAvailableRpcThreads, Msg.Statistics.cMaxRpcThreads );
  428. _tprintf( TEXT("%-35s\t%d/%d\n"), TEXT("Current/most thread pool threads"),
  429. Msg.Statistics.cNumThreadPoolThreads, Msg.Statistics.cMostThreadPoolThreads );
  430. /*
  431. _tprintf( TEXT("%-35s\t%s\n"), TEXT("Service controller state"),
  432. CDebugString( static_cast<SServiceState>(Msg.Statistics.SvcCtrlState))._tsz );
  433. */
  434. //ShowMoveCounter( rgptszArgs[iDcName] );
  435. }
  436. __except( EXCEPTION_EXECUTE_HANDLER )
  437. {
  438. hr = GetExceptionCode();
  439. }
  440. Exit:
  441. if( fBound )
  442. RpcBindingFree( &BindingHandle );
  443. return( SUCCEEDED(hr) );
  444. }
  445. BOOL
  446. SetRefreshCounter( CDbConnection &dbc,
  447. CLdapVolumeKeyDn dnKey,
  448. const SequenceNumber seq )
  449. {
  450. int ldapRV;
  451. HRESULT hr = E_FAIL;
  452. CTrkSvrConfiguration
  453. configSvr;
  454. configSvr.Initialize();
  455. LDAPMod * mods[2];
  456. __try
  457. {
  458. CLdapSeqNum lsn(seq);
  459. CLdapStringMod lsmSequence(s_timeRefresh, lsn, LDAP_MOD_REPLACE );
  460. mods[0] = &lsmSequence._mod;
  461. mods[1] = 0;
  462. ldapRV = ldap_modify_s(dbc.Ldap(), dnKey, mods);
  463. if(LDAP_SUCCESS != ldapRV)
  464. {
  465. printf( "Failed ldap_modify_s(%lu)\n", LdapMapErrorToWin32(ldapRV) );
  466. hr = HRESULT_FROM_WIN32(LdapMapErrorToWin32(ldapRV) );
  467. __leave;
  468. }
  469. }
  470. __finally
  471. {
  472. }
  473. return SUCCEEDED(hr);
  474. }
  475. class CLdapSecret
  476. {
  477. public:
  478. CLdapSecret()
  479. {
  480. memset(_abPad,0,sizeof(_abPad));
  481. }
  482. CLdapSecret(const CVolumeSecret &secret)
  483. {
  484. _secret = secret;
  485. memset(_abPad,0,sizeof(_abPad));
  486. }
  487. CVolumeSecret _secret;
  488. BYTE _abPad[sizeof(GUID) - sizeof(CVolumeSecret)];
  489. };
  490. BOOL
  491. DltAdminSetVolumeSeqNumber( ULONG cArgs, const TCHAR * const rgptszArgs[], ULONG *pcEaten )
  492. {
  493. NTSTATUS status;
  494. HRESULT hr = S_OK;;
  495. SequenceNumber seq;
  496. CVolumeId volid;
  497. CStringize stringize;
  498. if( 1 <= cArgs && IsHelpArgument( rgptszArgs[0] ))
  499. {
  500. printf( "\nOption SetVolSeq\n"
  501. " Purpose: Set the sequence number in a volume table entry\n"
  502. " Usage: -setvolseq <DC name> <seq> <volid>\n"
  503. " E.g.: -setvolseq ntdsdc0 90 {d763433c-73a3-48c7-88a5-d6f3552835c6}\n"
  504. " Note: Requires write access to volume table in DS.\n" );
  505. *pcEaten = 1;
  506. return( TRUE );
  507. }
  508. _tprintf( TEXT("Setting sequence number in volume table\n"), rgptszArgs[0] );
  509. if( 3 > cArgs )
  510. {
  511. printf( "Invalid parameters. Use -? for usage info\n" );
  512. *pcEaten = 0;
  513. return( FALSE );
  514. }
  515. *pcEaten = 1;
  516. // Get the sequence number
  517. if( 1 != _stscanf( rgptszArgs[1], TEXT("%d"), &seq ))
  518. {
  519. printf( "Invalid sequence number. Use -? for usage info\n" );
  520. return FALSE;
  521. }
  522. // Get the volid
  523. // mikehill_test
  524. DebugBreak();
  525. stringize.Use( rgptszArgs[2] );
  526. volid = stringize;
  527. /*
  528. {
  529. RPC_STATUS rpc_status = RPC_S_INVALID_STRING_UUID;
  530. TCHAR tszTemp[ MAX_PATH ];
  531. TCHAR *ptszTemp = NULL;
  532. if( TEXT('{') == rgptszArgs[2][0] )
  533. {
  534. _tcscpy( tszTemp, &rgptszArgs[2][1] );
  535. ptszTemp = _tcschr( tszTemp, TEXT('}') );
  536. if( NULL != ptszTemp )
  537. {
  538. *ptszTemp = TEXT('\0');
  539. rpc_status = UuidFromString( tszTemp, (GUID*)&volid );
  540. }
  541. }
  542. if( RPC_S_OK != rpc_status )
  543. {
  544. _tprintf( TEXT("Error: Invalid volume ID\n") );
  545. return FALSE;
  546. }
  547. }
  548. */
  549. // Set the sequence
  550. CDbConnection dbc;
  551. dbc.Initialize( NULL, rgptszArgs[0] );
  552. CLdapVolumeKeyDn dnKey(dbc.GetBaseDn(), volid);
  553. return SetRefreshCounter( dbc, dnKey, seq );
  554. }
  555. BOOL
  556. SetRefreshCounter2( CDbConnection &dbc,
  557. CLdapIdtKeyDn dnKey,
  558. const SequenceNumber seq )
  559. {
  560. int ldapRV;
  561. HRESULT hr = E_FAIL;
  562. CTrkSvrConfiguration
  563. configSvr;
  564. configSvr.Initialize();
  565. LDAPMod * mods[2];
  566. __try
  567. {
  568. CLdapSeqNum lsn(seq);
  569. CLdapStringMod lsmSequence(s_timeRefresh, lsn, LDAP_MOD_REPLACE );
  570. mods[0] = &lsmSequence._mod;
  571. mods[1] = 0;
  572. ldapRV = ldap_modify_s(dbc.Ldap(), dnKey, mods);
  573. if(LDAP_SUCCESS != ldapRV)
  574. {
  575. printf( "Failed ldap_modify_s(%lu)\n", LdapMapErrorToWin32(ldapRV) );
  576. hr = HRESULT_FROM_WIN32(LdapMapErrorToWin32(ldapRV) );
  577. __leave;
  578. }
  579. }
  580. __finally
  581. {
  582. }
  583. return SUCCEEDED(hr);
  584. }
  585. BOOL
  586. DltAdminSetDroidSeqNumber( ULONG cArgs, const TCHAR * const rgptszArgs[], ULONG *pcEaten )
  587. {
  588. NTSTATUS status;
  589. HRESULT hr = S_OK;;
  590. SequenceNumber seq;
  591. CDomainRelativeObjId droid;
  592. CStringize stringize;
  593. if( 1 <= cArgs && IsHelpArgument( rgptszArgs[0] ))
  594. {
  595. printf( "\nOption SetDroidSeq\n"
  596. " Purpose: Set the sequence number in a move table entry\n"
  597. " Usage: -setdroidseq <DC name> <seq> <volid>\n"
  598. " E.g.: -setdroidseq ntdsdc0 90 {d763433c-73a3-48c7-88a5-d6f3552835c6}{183c8367-a392-c784-88a5-d6f3552835c6}\n"
  599. " Note: Requires write access to volume table in DS.\n" );
  600. *pcEaten = 1;
  601. return( TRUE );
  602. }
  603. _tprintf( TEXT("Setting sequence number in move table\n"), rgptszArgs[0] );
  604. if( 3 > cArgs )
  605. {
  606. printf( "Invalid parameters. Use -? for usage info\n" );
  607. *pcEaten = 0;
  608. return( FALSE );
  609. }
  610. *pcEaten = 1;
  611. // Get the sequence number
  612. if( 1 != _stscanf( rgptszArgs[1], TEXT("%d"), &seq ))
  613. {
  614. printf( "Invalid sequence number. Use -? for usage info\n" );
  615. return FALSE;
  616. }
  617. // Get the droid
  618. stringize.Use( rgptszArgs[2] );
  619. droid = stringize;
  620. if( CDomainRelativeObjId() == droid )
  621. {
  622. _tprintf( TEXT("Error: Invalid DROID\n") );
  623. return FALSE;
  624. }
  625. // Set the sequence
  626. CDbConnection dbc;
  627. dbc.Initialize( NULL, rgptszArgs[0] );
  628. CLdapIdtKeyDn dnKey(dbc.GetBaseDn(), droid);
  629. return SetRefreshCounter2( dbc, dnKey, seq );
  630. }