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.

287 lines
7.0 KiB

  1. /*++
  2. Copyright (c) 1995-96 Microsoft Corporation
  3. Module Name:
  4. ssets.hxx
  5. Abstract:
  6. CServerSet objects represent sets of CServerOids which are owned by
  7. a particular client. The same CServerOids may appear in a large
  8. number of sets.
  9. CServerSets are mangaged by an instance of the CServerSetTable
  10. class. This object (pServerSets) can be used to allocate (exclusive lock)
  11. and lookup (shared lock) sets. It can also be used (shared lock) by
  12. the worker thread to rundowns old CServerSet's.
  13. Author:
  14. Mario Goertzel [MarioGo]
  15. Revision History:
  16. MarioGo 02-27-95 Bits 'n pieces
  17. MarioGo 04-04-95 Split client and server.
  18. MarioGo 01-06-96 Locally unique Ids, added new management class
  19. --*/
  20. #ifndef __SSET_HXX
  21. #define __SSET_HXX
  22. class CServerSet
  23. /*++
  24. Class Description:
  25. Each instance for this class represtents a set of oids which are being
  26. used by a particular client. This client may or may not be making secure
  27. calls to this objext resolver. If the calls are secure, the SID of the
  28. client is remembered and compared during any operation changing the
  29. contents of the set.
  30. Members:
  31. _timeout - The time at which this set should rundown.
  32. _blistOids - List of pointers to all the CServerOids in this set.
  33. _psid - Security ID of the client. NULL for non-secure set.
  34. _sequence - The sequence number of the last good ping. Used to
  35. avoid problems with multiple execution since pings are idempotent.
  36. _period - Power of two multipler for timeout period. Not implemented.
  37. _psid - Pointer to the sid of the client or NULL.
  38. _fLocal - (need 1 bit) non-zero if the client is on this machine.
  39. --*/
  40. {
  41. private:
  42. CTime _timeout;
  43. PSID _psid;
  44. CBList _blistOids;
  45. USHORT _sequence;
  46. USHORT _pings;
  47. USHORT _fLocal:8; // free bits
  48. // Free USHORT
  49. BOOL ValidateObjects(BOOL fShared);
  50. public:
  51. CServerSet(USHORT sequence,
  52. PSID psid,
  53. BOOL fLocal) :
  54. _blistOids(8),
  55. _sequence(sequence - 1),
  56. _psid(psid),
  57. _fLocal((USHORT) fLocal)
  58. {
  59. _timeout += BaseTimeoutInterval; // * factor
  60. }
  61. ~CServerSet()
  62. {
  63. #if DBG
  64. CTime now;
  65. ASSERT(now > _timeout);
  66. #endif
  67. if (!_fLocal)
  68. {
  69. ASSERT(gpPingSetQuotaManager);
  70. gpPingSetQuotaManager->ManageQuotaForUser(_psid, FALSE);
  71. }
  72. delete _psid;
  73. }
  74. BOOL
  75. Ping(BOOL fShared)
  76. {
  77. _timeout.SetNow();
  78. _timeout += BaseTimeoutInterval; // * factor
  79. _pings++;
  80. if (_pings % BaseNumberOfPings == 0)
  81. {
  82. return(ValidateObjects(fShared));
  83. }
  84. return(fShared);
  85. }
  86. BOOL
  87. CheckAndUpdateSequenceNumber(USHORT sequence)
  88. {
  89. // note: this handles overflow cases, too.
  90. USHORT diff = sequence - _sequence;
  91. if (diff && diff <= BaseNumberOfPings)
  92. {
  93. _sequence = sequence;
  94. return(TRUE);
  95. }
  96. return(FALSE);
  97. }
  98. BOOL
  99. CheckSecurity(HANDLE hRpc)
  100. {
  101. // Local calls are secure
  102. if (0 == hRpc)
  103. {
  104. ASSERT(0 == _psid );
  105. return(TRUE);
  106. }
  107. // No security on the set
  108. if (0 == _psid)
  109. {
  110. return(TRUE);
  111. }
  112. BOOL f;
  113. RPC_STATUS status;
  114. HANDLE hT;
  115. status = RpcImpersonateClient(hRpc);
  116. if (status == RPC_S_OK)
  117. {
  118. f = OpenThreadToken(GetCurrentThread(),
  119. TOKEN_IMPERSONATE | TOKEN_QUERY,
  120. TRUE,
  121. &hT);
  122. if (!f)
  123. {
  124. return(FALSE);
  125. }
  126. }
  127. else
  128. {
  129. #if DBG
  130. SetLastError(status);
  131. #endif
  132. return(FALSE);
  133. }
  134. ULONG needed = DEBUG_MIN(1, 24);
  135. PTOKEN_USER ptu;
  136. do
  137. {
  138. ptu = (PTOKEN_USER)alloca(needed);
  139. ASSERT(ptu);
  140. f = GetTokenInformation(hT,
  141. TokenUser,
  142. (PBYTE)ptu,
  143. needed,
  144. &needed);
  145. }
  146. while( FALSE == f && GetLastError() == ERROR_INSUFFICIENT_BUFFER);
  147. CloseHandle(hT);
  148. if (FALSE != f)
  149. {
  150. ASSERT(needed > sizeof(SID));
  151. f = EqualSid(_psid, ptu->User.Sid);
  152. return(f);
  153. }
  154. return(FALSE);
  155. }
  156. ORSTATUS AddObject(OID &oid);
  157. void RemoveObject(OID &oid);
  158. BOOL ShouldRundown() { CTime now; return(now > _timeout); }
  159. BOOL Rundown();
  160. };
  161. class CServerSetTable
  162. /*++
  163. Class Description:
  164. Management class for allocating and looking up CServerSets.
  165. Each set is associated with an ID which is made up of an index
  166. and a sequence number. The index is used to index into _pElements
  167. and the sequence number is used to avoid problems with old set ID
  168. and a new server.
  169. Members:
  170. _pElements - An array (size _cMax) of IndexElement structures
  171. IndexElement-
  172. _sequence - A sequence number used to detect invalid
  173. referneces to a slot which has rundown and been realloc'd.
  174. _pSet - A pointer to the actual CServerSet. If the
  175. slot is free it is 0x80000000 & index of next free slot.
  176. _cMax - The number of slots in _pElements.
  177. _cAllocated - The number of slots in use.
  178. _iFirstFree - (Hint) A starting place of where to look when trying
  179. to insert. No elements < _iFirstFree are free.
  180. _iRundown - Index of the rundown checker. It is written
  181. to with a shared lock held. This is okay.
  182. --*/
  183. {
  184. struct IndexElement {
  185. DWORD _sequence;
  186. CServerSet *_pSet;
  187. };
  188. public:
  189. CServerSetTable(ORSTATUS &status) :
  190. _cMax(DEBUG_MIN(16,4)),
  191. _cAllocated(0),
  192. _iFirstFree(0),
  193. _iRundown(0)
  194. {
  195. _pElements = new IndexElement[_cMax];
  196. if (!_pElements)
  197. {
  198. status = OR_NOMEM;
  199. }
  200. else
  201. {
  202. OrMemorySet(_pElements, 0, sizeof(IndexElement) * _cMax);
  203. status = OR_OK;
  204. }
  205. }
  206. CServerSet *Allocate(IN USHORT sequence,
  207. IN PSID psid,
  208. IN BOOL fLocal,
  209. OUT ID &setid);
  210. CServerSet *Lookup(IN ID setid);
  211. DWORD Size() {
  212. return(_cAllocated);
  213. }
  214. // Used for set cleanup by worker and SimplePing.
  215. ID CheckForRundowns();
  216. BOOL RundownSetIfNeeded(SETID id);
  217. void PingAllSets();
  218. private:
  219. IndexElement *_pElements;
  220. DWORD _cMax;
  221. DWORD _cAllocated;
  222. DWORD _iFirstFree;
  223. DWORD _iRundown;
  224. };
  225. #endif // __SSET_HXX