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.

587 lines
15 KiB

  1. //
  2. // Copyright (C) 2000, Microsoft Corporation
  3. //
  4. // File: DfsADBlobCache.hxx
  5. //
  6. // Contents: the ADBlob DFS Store class, this contains the
  7. // old AD blob store specific functionality.
  8. //
  9. // Classes: DfsADBlobStore.
  10. //
  11. // History: April. 9 2001, Author: Rohanp
  12. //
  13. //-----------------------------------------------------------------------------
  14. #ifndef __DFS_ADBLOB_CACHE__
  15. #define __DFS_ADBLOB_CACHE__
  16. #include <dfsgeneric.hxx>
  17. #include <dfsstore.hxx>
  18. #include <shellapi.h>
  19. #include <ole2.h>
  20. #include <activeds.h>
  21. #include "dfsadsiapi.hxx"
  22. #include <WinLdap.h>
  23. #include <NtLdap.h>
  24. #include <shash.h>
  25. class DfsRootFolder;
  26. #define ADBlobAttribute L"pKT"
  27. #define ADBlobPktGuidAttribute L"pKTGuid"
  28. //
  29. // It appears that siteroot is case sensitive on downlevel DFS.
  30. // dont change case.
  31. //
  32. #define ADBlobSiteRoot L"\\siteroot"
  33. //
  34. // domainroot is case-sensitive along some paths of downlevel DFS as well.
  35. // Leave this lowercase also.
  36. //
  37. #define ADBlobMetaDataNamePrefix L"\\domainroot"
  38. #define ADBlobDefaultBlobPackSize 1* 1024 * 1024
  39. #define ADBlobMaximumBlobPackSize 32 * 1024 * 1024
  40. #define PKT_ENTRY_TYPE_CAIRO 0x0001 // Entry refers to Cairo srv
  41. #define PKT_ENTRY_TYPE_MACHINE 0x0002 // Entry is a machine volume
  42. #define PKT_ENTRY_TYPE_INSITE_ONLY 0x0020 // Only give insite referrals.
  43. #define PKT_ENTRY_TYPE_COST_BASED_SITE_SELECTION 0x0040 // get inter-site costs from DS.
  44. #define PKT_ENTRY_TYPE_REFERRAL_SVC 0x0080 // Entry refers to a DC
  45. #define PKT_ENTRY_TYPE_PERMANENT 0x0100 // Entry cannot be scavenged
  46. #define PKT_ENTRY_TYPE_LOCAL 0x0400 // Entry refers to local vol
  47. #define DFS_USE_LDAP 1
  48. #define DFS_ROOTSCALABILTY_FORCED_REFRESH_INTERVAL 20
  49. typedef struct _BLOB_DATA
  50. {
  51. SHASH_HEADER Header;
  52. UNICODE_STRING BlobName;
  53. ULONG Size;
  54. PBYTE pBlob;
  55. LONG SequenceNumber;
  56. } DFSBLOB_DATA, *PDFSBLOB_DATA;
  57. typedef struct _BLOB_ITERATOR
  58. {
  59. BOOLEAN Started;
  60. PDFSBLOB_DATA RootReferenced;
  61. SHASH_ITERATOR Iter;
  62. }DFSBOB_ITER, *PDFSBLOB_ITER;
  63. void *
  64. AllocateShashData(ULONG Size );
  65. void
  66. DeallocateShashData(void *pPointer );
  67. #define ADSBLOB_DEFAULT_BUFFER_SIZE 8192
  68. #define DFS_DS_NOERROR 1
  69. #define DFS_DS_ERROR 0
  70. class DfsADBlobCache : public DfsGeneric
  71. {
  72. private:
  73. PSHASH_TABLE m_pTable;
  74. PDFSBLOB_DATA m_pBlob;
  75. PDFSBLOB_DATA m_pRootBlob;
  76. ULONG m_BlobSize;
  77. DfsRootFolder *m_pRootFolder;
  78. BOOL m_fCritInit;
  79. GUID m_BlobAttributePktGuid;
  80. LONG m_CurrentSequenceNumber;
  81. LONG m_ErrorOccured;
  82. PVOID m_pAdHandle;
  83. ULONG m_AdReferenceCount;
  84. LONG m_RefreshCount;
  85. UNICODE_STRING m_LogicalShare;
  86. UNICODE_STRING m_ObjectDN;
  87. CRITICAL_SECTION m_Lock;
  88. public:
  89. DfsADBlobCache(DFSSTATUS *pStatus,
  90. PUNICODE_STRING pShareName,
  91. DfsRootFolder * pRootFolder);
  92. ~DfsADBlobCache();
  93. //
  94. // Note: This is protected by the critical section of the
  95. // root object. Any changed intentions of using this should
  96. // protect this code under a critical section.
  97. //
  98. #ifndef DFS_USE_LDAP
  99. DFSSTATUS
  100. SetObjectPktGuid(
  101. IADs *pADs,
  102. GUID *pGuid );
  103. DFSSTATUS
  104. GetADObject( PVOID *ppHandle )
  105. {
  106. DFSSTATUS Status;
  107. Status = DfsAcquireWriteLock(&m_Lock);
  108. if (Status != ERROR_SUCCESS)
  109. {
  110. return Status;
  111. }
  112. if (m_pAdHandle == NULL)
  113. {
  114. Status = DfsGetDfsRootADObject( NULL,
  115. m_LogicalShare.Buffer,
  116. (IADs **)&m_pAdHandle );
  117. if (Status == ERROR_SUCCESS)
  118. {
  119. m_AdReferenceCount = 1;
  120. *ppHandle = m_pAdHandle;
  121. }
  122. }
  123. else
  124. {
  125. m_AdReferenceCount++;
  126. *ppHandle = m_pAdHandle;
  127. }
  128. DfsReleaseLock(&m_Lock);
  129. return Status;
  130. }
  131. VOID
  132. ReleaseADObject( PVOID pObject )
  133. {
  134. DFSSTATUS Status;
  135. if (pObject != NULL)
  136. {
  137. // make sure the object is the one we have cached?
  138. }
  139. Status = DfsAcquireWriteLock(&m_Lock);
  140. if (Status != ERROR_SUCCESS)
  141. {
  142. return;
  143. }
  144. if (--m_AdReferenceCount == 0)
  145. {
  146. ((IADs *)m_pAdHandle)->Release();
  147. m_pAdHandle = NULL;
  148. }
  149. DfsReleaseLock(&m_Lock);
  150. return NOTHING;
  151. }
  152. #else
  153. DFSSTATUS DfsLdapConnect(LPWSTR DcName, LDAP **ppLdap );
  154. VOID DfsLdapDisconnect(LDAP *pLdap );
  155. DFSSTATUS DfsGetPktBlob( LDAP *pLdap,
  156. LPWSTR ObjectDN,
  157. PVOID *ppBlob,
  158. PULONG pBlobSize,
  159. PVOID *ppHandle,
  160. PVOID *ppHandle1 );
  161. VOID DfsReleasePktBlob( PVOID pHandle,
  162. PVOID pHandle1 );
  163. DFSSTATUS DfsSetPktBlobAndPktGuid ( LDAP *pLdap,
  164. LPWSTR ObjectDN,
  165. PVOID pBlob,
  166. ULONG BlobSize,
  167. GUID *pGuid );
  168. DFSSTATUS
  169. GetADObject( PVOID *ppHandle,
  170. LPWSTR DCName )
  171. {
  172. DFSSTATUS Status = ERROR_SUCCESS;
  173. Status = DfsAcquireWriteLock(&m_Lock);
  174. if (Status != ERROR_SUCCESS)
  175. {
  176. return Status;
  177. }
  178. if (m_pAdHandle == NULL)
  179. {
  180. Status = DfsLdapConnect( DCName, (LDAP **)&m_pAdHandle );
  181. if (Status == ERROR_SUCCESS)
  182. {
  183. m_AdReferenceCount = 1;
  184. *ppHandle = m_pAdHandle;
  185. }
  186. }
  187. else
  188. {
  189. m_AdReferenceCount++;
  190. *ppHandle = m_pAdHandle;
  191. }
  192. DfsReleaseLock(&m_Lock);
  193. return Status;
  194. }
  195. DFSSTATUS
  196. GetCachedADObject( PVOID *ppHandle )
  197. {
  198. DFSSTATUS Status = ERROR_SUCCESS;
  199. Status = DfsAcquireWriteLock(&m_Lock);
  200. if (Status != ERROR_SUCCESS)
  201. {
  202. return Status;
  203. }
  204. if (m_pAdHandle == NULL)
  205. {
  206. Status = ERROR_NOT_FOUND;
  207. }
  208. else
  209. {
  210. m_AdReferenceCount++;
  211. *ppHandle = m_pAdHandle;
  212. }
  213. DfsReleaseLock(&m_Lock);
  214. return Status;
  215. }
  216. VOID
  217. ReleaseADObject( PVOID pObject )
  218. {
  219. DFSSTATUS Status;
  220. if (pObject != NULL)
  221. {
  222. // make sure the object is the one we have cached?
  223. }
  224. Status = DfsAcquireWriteLock(&m_Lock);
  225. if (Status != ERROR_SUCCESS)
  226. {
  227. return;
  228. }
  229. if (--m_AdReferenceCount == 0)
  230. {
  231. DfsLdapDisconnect( (LDAP *)m_pAdHandle );
  232. m_pAdHandle = NULL;
  233. }
  234. DfsReleaseLock(&m_Lock);
  235. return NOTHING;
  236. }
  237. #endif
  238. DFSSTATUS
  239. CacheRefresh(BOOLEAN fForceSync,
  240. BOOLEAN fFromPDC);
  241. DFSSTATUS
  242. CacheFlush(PVOID pObject) ;
  243. DFSSTATUS
  244. GetObjectPktGuid(
  245. PVOID pHandle,
  246. GUID *pGuid );
  247. DFSSTATUS
  248. UpdateDSBlobFromCache(
  249. PVOID pHandle,
  250. GUID *pGuid );
  251. DFSSTATUS
  252. UpdateCacheWithDSBlob(
  253. PVOID pHandle );
  254. BOOLEAN
  255. IsStaleBlob( PDFSBLOB_DATA pBlob)
  256. {
  257. return (pBlob->SequenceNumber != m_CurrentSequenceNumber);
  258. }
  259. void InvalidateCache();
  260. DFSSTATUS
  261. UnpackBlob (BYTE *pBuffer,
  262. PULONG pLength,
  263. PDFSBLOB_DATA * pRetBlob);
  264. DFSSTATUS
  265. StoreBlobInCache(PUNICODE_STRING BlobName,
  266. PBYTE pBlobBuffer,
  267. ULONG BlobSize);
  268. DFSSTATUS
  269. GetSubBlob(
  270. PUNICODE_STRING pName,
  271. BYTE **ppBlobBuffer,
  272. PULONG pBlobSize,
  273. BYTE **ppBuffer,
  274. PULONG pSize );
  275. DFSSTATUS
  276. GetNamedBlob (PUNICODE_STRING pBlobName,
  277. PDFSBLOB_DATA *pBlobStructure);
  278. DFSSTATUS
  279. SetNamedBlob (PDFSBLOB_DATA pBlob);
  280. DFSSTATUS
  281. RemoveNamedBlob(PUNICODE_STRING pBlobName );
  282. DFSSTATUS
  283. PutBinaryIntoVariant(VARIANT * ovData,
  284. BYTE * pBuf,
  285. unsigned long cBufLen);
  286. DFSSTATUS
  287. GetBinaryFromVariant(VARIANT *ovData,
  288. BYTE ** ppBuf,
  289. unsigned long * pcBufLen);
  290. DFSSTATUS
  291. PackBlob(BYTE *pBuffer,
  292. PULONG pLength,
  293. PULONG TotalBlobBytes );
  294. DFSSTATUS
  295. CreateBlob(PUNICODE_STRING BlobName,
  296. PBYTE pBlobBuffer,
  297. ULONG BlobSize,
  298. PDFSBLOB_DATA *pNewBlob
  299. );
  300. PDFSBLOB_DATA AcquireRootBlob()
  301. {
  302. if (m_pRootBlob != NULL)
  303. {
  304. AcquireBlobReference(m_pRootBlob);
  305. }
  306. return m_pRootBlob;
  307. }
  308. VOID
  309. ReleaseRootBlob()
  310. {
  311. if (m_pRootBlob != NULL)
  312. {
  313. ReleaseBlobReference(m_pRootBlob);
  314. }
  315. m_pRootBlob = NULL;
  316. }
  317. VOID
  318. AcquireBlobReference(
  319. PDFSBLOB_DATA pBlobData)
  320. {
  321. PSHASH_HEADER pData = (PSHASH_HEADER)pBlobData;
  322. InterlockedIncrement(&pData->RefCount);
  323. }
  324. VOID
  325. ReleaseBlobReference(
  326. PDFSBLOB_DATA pBlobData)
  327. {
  328. PSHASH_HEADER pData = (PSHASH_HEADER)pBlobData;
  329. if(InterlockedDecrement(&pData->RefCount) == 0)
  330. {
  331. DeallocateShashData(pData);
  332. }
  333. }
  334. void
  335. ReleaseBlobCacheReference(PDFSBLOB_DATA pBlobStructure)
  336. {
  337. NTSTATUS Status = STATUS_SUCCESS;
  338. if (IsEmptyString(pBlobStructure->BlobName.Buffer))
  339. {
  340. ReleaseBlobReference(pBlobStructure);
  341. }
  342. else
  343. {
  344. Status = SHashReleaseReference(m_pTable, (PSHASH_HEADER) pBlobStructure);
  345. }
  346. }
  347. PDFSBLOB_DATA
  348. FindFirstBlob(PDFSBLOB_ITER pIter);
  349. PDFSBLOB_DATA
  350. FindNextBlob(PDFSBLOB_ITER pIter);
  351. void
  352. FindCloseBlob(PDFSBLOB_ITER pIter);
  353. DFSSTATUS
  354. WriteBlobToAd(
  355. BOOLEAN ForceFlush = FALSE);
  356. DFSSTATUS
  357. SetupObjectDN()
  358. {
  359. DFSSTATUS Status = ERROR_SUCCESS;
  360. LPWSTR DNBuffer;
  361. LPWSTR RemainingDN;
  362. RemainingDN = DfsGetDfsAdNameContextString();
  363. if (RemainingDN == NULL)
  364. {
  365. Status = ERROR_NOT_READY;
  366. }
  367. if (Status == ERROR_SUCCESS)
  368. {
  369. ULONG DNSize = 3 +
  370. wcslen(m_LogicalShare.Buffer) +
  371. 1 +
  372. wcslen(DFS_AD_CONFIG_DATA) +
  373. 1 +
  374. wcslen(RemainingDN) + 1;
  375. DNBuffer = new WCHAR[DNSize];
  376. if (DNBuffer != NULL)
  377. {
  378. wcscpy(DNBuffer, L"CN=");
  379. wcscat(DNBuffer, m_LogicalShare.Buffer);
  380. wcscat(DNBuffer, L",");
  381. wcscat(DNBuffer, DFS_AD_CONFIG_DATA);
  382. wcscat(DNBuffer, L",");
  383. wcscat(DNBuffer, RemainingDN);
  384. Status = DfsRtlInitUnicodeStringEx( &m_ObjectDN, DNBuffer );
  385. if(Status != ERROR_SUCCESS)
  386. {
  387. delete [] DNBuffer;
  388. }
  389. }
  390. else
  391. {
  392. Status = ERROR_NOT_ENOUGH_MEMORY;
  393. }
  394. }
  395. return Status;
  396. }
  397. DFSSTATUS
  398. GetObjectDN(
  399. PUNICODE_STRING pObjectDN)
  400. {
  401. DFSSTATUS Status = ERROR_SUCCESS;
  402. if (m_ObjectDN.Buffer == NULL)
  403. {
  404. Status = SetupObjectDN();
  405. }
  406. *pObjectDN = m_ObjectDN;
  407. return Status;
  408. }
  409. ULONG
  410. GetBlobSize();
  411. DFSSTATUS
  412. DfsDoesUserHaveAccess(DWORD DesiredAccess);
  413. DFSSTATUS
  414. CreateSiteBlobIfNecessary(void);
  415. DFSSTATUS
  416. UpdateSiteBlob(PVOID pBuffer, ULONG Size);
  417. DFSSTATUS
  418. GetSiteBlob(PVOID *ppBuffer, PULONG pSize)
  419. {
  420. DFSSTATUS Status = ERROR_SUCCESS;
  421. if (m_pBlob != NULL)
  422. {
  423. *ppBuffer = m_pBlob->pBlob;
  424. *pSize = m_pBlob->Size;
  425. }
  426. else
  427. {
  428. Status = ERROR_NOT_FOUND;
  429. }
  430. return Status;
  431. }
  432. DFSSTATUS
  433. SetSiteBlob(PVOID pBuffer, ULONG Size)
  434. {
  435. DFSSTATUS Status;
  436. Status = UpdateSiteBlob(pBuffer, Size);
  437. return Status;
  438. }
  439. };
  440. DWORD PackBlobEnumerator( void* pvkey,
  441. void* pvData,
  442. void * pContext ) ;
  443. DFSSTATUS
  444. AddStreamToBlob(PUNICODE_STRING BlobName,
  445. BYTE *pBlobBuffer,
  446. ULONG BlobSize,
  447. BYTE ** pUseBuffer,
  448. ULONG *BufferSize );
  449. typedef struct _PACKBLOB_ENUMCTX
  450. {
  451. DFSSTATUS Status;
  452. ULONG Size;
  453. ULONG NumItems;
  454. ULONG CurrentSize;
  455. LONG SequenceNumber;
  456. BYTE * pBuffer;
  457. } PACKBLOB_ENUMCTX, *PPACKBLOB_ENUMCTX;
  458. #endif // __DFS_ADBLOB_CACHE__