caching.cpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697
  1. /*##############################################################################
  2. HPCC SYSTEMS software Copyright (C) 2012 HPCC Systems®.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. ############################################################################## */
  13. #include "caching.hpp"
  14. #include "jtime.hpp"
  15. //define a container for multiple instances of a security manager cache
  16. typedef map<string, CPermissionsCache*> MapCache;
  17. static CriticalSection mapCacheCS;//guards modifications to the cache map
  18. static MapCache g_mapCache;
  19. /**********************************************************
  20. * CResPermissionsCache *
  21. * (used by CPermissionsCache defined below) *
  22. **********************************************************/
  23. time_t getThreadCreateTime()
  24. {
  25. time_t t;
  26. void* tslval = getThreadLocalVal();
  27. if(tslval == NULL)
  28. return 0;
  29. memcpy(&t, tslval, sizeof(t));
  30. return t;
  31. }
  32. CResPermissionsCache::~CResPermissionsCache()
  33. {
  34. MapResAccess::const_iterator i;
  35. MapResAccess::const_iterator iEnd = m_resAccessMap.end();
  36. for (i = m_resAccessMap.begin(); i != iEnd; i++)
  37. {
  38. ISecResource* ptr = ((*i).second).second;
  39. if(ptr)
  40. {
  41. ptr->Release();
  42. }
  43. }
  44. }
  45. //called from within a ReadLockBlock
  46. int CResPermissionsCache::lookup( IArrayOf<ISecResource>& resources, bool* pFound )
  47. {
  48. time_t tstamp;
  49. time(&tstamp);
  50. int nresources = resources.ordinality();
  51. int nFound = 0;
  52. for (int i = 0; i < nresources; i++)
  53. {
  54. ISecResource& secResource = resources.item(i);
  55. const char* resource = secResource.getName();
  56. if(resource == NULL)
  57. {
  58. *pFound++ = false;
  59. continue;
  60. }
  61. #ifdef _DEBUG
  62. DBGLOG("CACHE: CResPermissionsCache Looking up resource(%d of %d) %s:%s", i, nresources, m_user.c_str(), resource);
  63. #endif
  64. MapResAccess::iterator it = m_resAccessMap.find(SecCacheKeyEntry(resource, secResource.getResourceType()));
  65. if (it != m_resAccessMap.end())//exists in cache
  66. {
  67. ResPermCacheEntry& resParamCacheEntry = (*it).second;
  68. const time_t timestamp = resParamCacheEntry.first;
  69. if (timestamp < tstamp)//entry was not stale during last cleanup but is stale now
  70. *pFound++ = false;
  71. else if(!m_pParentCache->isCacheEnabled() && m_pParentCache->isTransactionalEnabled())//m_pParentCache->getOriginalTimeout() == 0)
  72. {
  73. time_t tctime = getThreadCreateTime();
  74. if(tctime <= 0 || timestamp < tctime)
  75. {
  76. *pFound++ = false;
  77. }
  78. else
  79. {
  80. secResource.copy(resParamCacheEntry.second);
  81. #ifdef _DEBUG
  82. DBGLOG("CACHE: CResPermissionsCache FoundA %s:%s=>%d", m_user.c_str(), resource, ((ISecResource*)resParamCacheEntry.second)->getAccessFlags());
  83. #endif
  84. *pFound++ = true;
  85. nFound++;
  86. }
  87. }
  88. else
  89. {
  90. secResource.copy(resParamCacheEntry.second);
  91. #ifdef _DEBUG
  92. DBGLOG("CACHE: CResPermissionsCache FoundB %s:%s=>%d", m_user.c_str(), resource, ((ISecResource*)resParamCacheEntry.second)->getAccessFlags());
  93. #endif
  94. *pFound++ = true;
  95. nFound++;
  96. }
  97. }
  98. else
  99. *pFound++ = false;
  100. }
  101. return nFound;
  102. }
  103. //called from within a WriteLockBlock
  104. void CResPermissionsCache::add( IArrayOf<ISecResource>& resources )
  105. {
  106. time_t tstamp;
  107. time(&tstamp);
  108. int nresources = resources.ordinality();
  109. for (int i = 0; i < nresources; i++)
  110. {
  111. ISecResource* secResource = &resources.item(i);
  112. if(!secResource)
  113. continue;
  114. const char* resource = secResource->getName();
  115. SecResourceType resourcetype = secResource->getResourceType();
  116. if(resource == NULL)
  117. continue;
  118. int permissions = secResource->getAccessFlags();
  119. if(permissions == SecAccess_Unavailable)
  120. continue;
  121. MapResAccess::iterator it = m_resAccessMap.find(SecCacheKeyEntry(resource, resourcetype));
  122. if (it != m_resAccessMap.end())//already exists so overwrite it but first remove existing timestamp info
  123. {
  124. ResPermCacheEntry& resParamCacheEntry = (*it).second;
  125. time_t oldtstamp = resParamCacheEntry.first;
  126. //there may be multiple resources associated with the same timestamp
  127. //in the multimap so find this entry
  128. //
  129. MapTimeStamp::iterator itL = m_timestampMap.lower_bound( oldtstamp );
  130. MapTimeStamp::iterator itU = m_timestampMap.upper_bound( oldtstamp );
  131. MapTimeStamp::iterator its;
  132. for ( its = itL; its != itU; its++)
  133. {
  134. SecCacheKeyEntry& cachekey = (*its).second;
  135. if (cachekey.first == resource && cachekey.second == resourcetype)
  136. {
  137. m_timestampMap.erase(its);
  138. break;
  139. }
  140. }
  141. m_resAccessMap.erase(SecCacheKeyEntry(resource, resourcetype));
  142. }
  143. #ifdef _DEBUG
  144. DBGLOG("CACHE: CResPermissionsCache Adding %s:%s(%d)", m_user.c_str(), resource, permissions);
  145. #endif
  146. m_resAccessMap.insert( pair<SecCacheKeyEntry, ResPermCacheEntry>(SecCacheKeyEntry(resource, resourcetype), ResPermCacheEntry(tstamp, secResource->clone())));
  147. m_timestampMap.insert( pair<time_t, SecCacheKeyEntry>(tstamp, SecCacheKeyEntry(resource, resourcetype)));
  148. }
  149. }
  150. //called from within a WriteLockBlock
  151. void CResPermissionsCache::removeStaleEntries(time_t tstamp)
  152. {
  153. if (needsCleanup(tstamp, m_pParentCache->getCacheTimeout()))
  154. {
  155. MapTimeStamp::iterator i;
  156. MapTimeStamp::iterator itL = m_timestampMap.lower_bound(tstamp);
  157. MapTimeStamp::iterator iBegin = m_timestampMap.begin();
  158. for (i = iBegin; i != itL; i++)
  159. {
  160. SecCacheKeyEntry& cachekey = (*i).second;
  161. MapResAccess::iterator it = m_resAccessMap.find(cachekey);
  162. if (it != m_resAccessMap.end())//exists in cache
  163. {
  164. ResPermCacheEntry& entry = (*it).second;
  165. if(entry.second)
  166. entry.second->Release();
  167. }
  168. m_resAccessMap.erase(cachekey);
  169. }
  170. m_timestampMap.erase(iBegin, itL);
  171. m_tLastCleanup = tstamp;
  172. }
  173. }
  174. //called from within a WriteLockBlock
  175. void CResPermissionsCache::remove(SecResourceType rtype, const char* resourcename)
  176. {
  177. SecCacheKeyEntry key(resourcename, rtype);
  178. MapResAccess::iterator it = m_resAccessMap.find(key);
  179. if (it != m_resAccessMap.end())//exists in cache
  180. {
  181. ResPermCacheEntry& entry = (*it).second;
  182. if(entry.second)
  183. entry.second->Release();
  184. }
  185. m_resAccessMap.erase(key);
  186. }
  187. /**********************************************************
  188. * CPermissionsCache *
  189. **********************************************************/
  190. CPermissionsCache::~CPermissionsCache()
  191. {
  192. if (!m_secMgrClass.isEmpty())
  193. {
  194. CriticalBlock block(mapCacheCS);
  195. g_mapCache.erase(m_secMgrClass.str());
  196. }
  197. flush();
  198. }
  199. int CPermissionsCache::lookup( ISecUser& sec_user, IArrayOf<ISecResource>& resources, bool* pFound)
  200. {
  201. time_t tstamp;
  202. time(&tstamp);
  203. const char* userId = sec_user.getName();
  204. //First check if matching cache entry is stale
  205. bool needsCleanup = false;
  206. {
  207. ReadLockBlock readLock(m_resPermCacheRWLock);
  208. MapResPermissionsCache::const_iterator i = m_resPermissionsMap.find( userId );
  209. if (i != m_resPermissionsMap.end())
  210. {
  211. CResPermissionsCache* pResPermissionsCache = (*i).second;
  212. needsCleanup = pResPermissionsCache->needsCleanup(tstamp, getCacheTimeout());
  213. }
  214. }
  215. //clear stale cache entries for this CResPermissionsCache entry
  216. if (needsCleanup)
  217. {
  218. WriteLockBlock writeLock(m_resPermCacheRWLock);
  219. MapResPermissionsCache::const_iterator i = m_resPermissionsMap.find( userId );
  220. if (i != m_resPermissionsMap.end())//Entry could have been deleted by another thread
  221. {
  222. CResPermissionsCache* pResPermissionsCache = (*i).second;
  223. pResPermissionsCache->removeStaleEntries(tstamp);
  224. }
  225. }
  226. //Lookup all user/resources
  227. int nFound;
  228. ReadLockBlock readLock(m_resPermCacheRWLock);
  229. MapResPermissionsCache::const_iterator i = m_resPermissionsMap.find( userId );
  230. if (i != m_resPermissionsMap.end())
  231. {
  232. CResPermissionsCache* pResPermissionsCache = (*i).second;
  233. nFound = pResPermissionsCache->lookup( resources, pFound );
  234. }
  235. else
  236. {
  237. nFound = 0;
  238. memset(pFound, 0, sizeof(bool)*resources.ordinality());
  239. }
  240. #ifdef _DEBUG
  241. DBGLOG("CACHE: CPermissionsCache Looked up resources for %s:*, found %d of %d matches", userId, nFound, resources.ordinality());
  242. #endif
  243. return nFound;
  244. }
  245. void CPermissionsCache::add( ISecUser& sec_user, IArrayOf<ISecResource>& resources )
  246. {
  247. const char* user = sec_user.getName();
  248. WriteLockBlock writeLock(m_resPermCacheRWLock);
  249. MapResPermissionsCache::const_iterator i = m_resPermissionsMap.find( user );
  250. CResPermissionsCache* pResPermissionsCache;
  251. if (i == m_resPermissionsMap.end())
  252. {
  253. #ifdef _DEBUG
  254. DBGLOG("CACHE: CPermissionsCache Adding resources to cache for new user %s", user);
  255. #endif
  256. pResPermissionsCache = new CResPermissionsCache(this, user);
  257. m_resPermissionsMap.insert(pair<string, CResPermissionsCache*>(user, pResPermissionsCache));
  258. }
  259. else
  260. {
  261. #ifdef _DEBUG
  262. DBGLOG("CACHE: CPermissionsCache Adding resources to cache for existing user %s", user);
  263. #endif
  264. pResPermissionsCache = (*i).second;
  265. }
  266. pResPermissionsCache->add( resources );
  267. }
  268. void CPermissionsCache::removePermissions( ISecUser& sec_user)
  269. {
  270. const char* user = sec_user.getName();
  271. if(user != NULL && *user != '\0')
  272. {
  273. #ifdef _DEBUG
  274. DBGLOG("CACHE: CPermissionsCache Removing permissions for user %s", user);
  275. #endif
  276. WriteLockBlock writeLock(m_resPermCacheRWLock);
  277. m_resPermissionsMap.erase(user);
  278. }
  279. }
  280. void CPermissionsCache::remove(SecResourceType rtype, const char* resourcename)
  281. {
  282. MapResPermissionsCache::const_iterator i;
  283. WriteLockBlock writeLock(m_resPermCacheRWLock);
  284. MapResPermissionsCache::const_iterator iEnd = m_resPermissionsMap.end();
  285. for (i = m_resPermissionsMap.begin(); i != iEnd; i++)
  286. {
  287. i->second->remove(rtype, resourcename);
  288. }
  289. }
  290. bool CPermissionsCache::lookup(ISecUser& sec_user)
  291. {
  292. if(!isCacheEnabled())
  293. return false;
  294. const char* username = sec_user.getName();
  295. if(!username || !*username)
  296. return false;
  297. bool deleteEntry = false;
  298. {
  299. ReadLockBlock readLock(m_userCacheRWLock );
  300. MapUserCache::iterator it = m_userCache.find(username);
  301. if (it == m_userCache.end())
  302. return false;
  303. CachedUser* user = (CachedUser*)(it->second);
  304. time_t now;
  305. time(&now);
  306. if(user->getTimestamp() < (now - m_cacheTimeout))
  307. {
  308. deleteEntry = true;
  309. }
  310. else
  311. {
  312. const char* cachedpw = user->queryUser()->credentials().getPassword();
  313. const char * pw = sec_user.credentials().getPassword();
  314. if(cachedpw && pw && *pw != '\0')
  315. {
  316. StringBuffer md5pbuf;
  317. md5_string2(pw, md5pbuf);
  318. if(strcmp(cachedpw, md5pbuf.str()) == 0)
  319. {
  320. #ifdef _DEBUG
  321. DBGLOG("CACHE: CPermissionsCache Found validated user %s", username);
  322. #endif
  323. // Copy cached user to the sec_user structure, but still keep the original clear text password.
  324. StringAttr originalPW(pw);
  325. user->queryUser()->copyTo(sec_user);
  326. sec_user.credentials().setPassword(originalPW.get());
  327. return true;
  328. }
  329. else
  330. {
  331. deleteEntry = true;
  332. }
  333. }
  334. }
  335. }
  336. if (deleteEntry)
  337. {
  338. WriteLockBlock writeLock(m_userCacheRWLock);
  339. MapUserCache::iterator it = m_userCache.find(username);
  340. if (it != m_userCache.end())
  341. {
  342. CachedUser* user = (CachedUser*)(it->second);
  343. m_userCache.erase(username);
  344. delete user;
  345. }
  346. }
  347. return false;
  348. }
  349. ISecUser* CPermissionsCache::getCachedUser( ISecUser& sec_user)
  350. {
  351. if(!isCacheEnabled())
  352. return NULL;
  353. const char* username = sec_user.getName();
  354. if(!username || !*username)
  355. return NULL;
  356. ReadLockBlock readLock(m_userCacheRWLock );
  357. MapUserCache::iterator it = m_userCache.find(username);
  358. if (it == m_userCache.end())
  359. return NULL;
  360. CachedUser* user = (CachedUser*)(it->second);
  361. return LINK(user->queryUser());
  362. }
  363. void CPermissionsCache::add(ISecUser& sec_user)
  364. {
  365. if(!isCacheEnabled())
  366. return;
  367. const char* username = sec_user.getName();
  368. if(!username || !*username)
  369. return;
  370. WriteLockBlock writeLock(m_userCacheRWLock );
  371. MapUserCache::iterator it = m_userCache.find(username);
  372. CachedUser* user = NULL;
  373. if (it != m_userCache.end())
  374. {
  375. user = (CachedUser*)(it->second);
  376. m_userCache.erase(username);
  377. delete user;
  378. }
  379. #ifdef _DEBUG
  380. DBGLOG("CACHE: CPermissionsCache Adding cached user %s", username);
  381. #endif
  382. m_userCache[username] = new CachedUser(LINK(&sec_user));
  383. }
  384. void CPermissionsCache::removeFromUserCache(ISecUser& sec_user)
  385. {
  386. const char* username = sec_user.getName();
  387. if(username && *username)
  388. {
  389. WriteLockBlock writeLock(m_userCacheRWLock );
  390. MapUserCache::iterator it = m_userCache.find(username);
  391. if (it != m_userCache.end())
  392. {
  393. CachedUser* user = (CachedUser*)(it->second);
  394. m_userCache.erase(username);
  395. delete user;
  396. #ifdef _DEBUG
  397. DBGLOG("CACHE: CPermissionsCache Removing cached user %s", username);
  398. #endif
  399. }
  400. }
  401. }
  402. bool CPermissionsCache::addManagedFileScopes(IArrayOf<ISecResource>& scopes)
  403. {
  404. WriteLockBlock writeLock(m_scopesRWLock);
  405. ForEachItemIn(x, scopes)
  406. {
  407. ISecResource* scope = &scopes.item(x);
  408. if(!scope)
  409. continue;
  410. const char* cachekey = scope->getName();
  411. if(cachekey == NULL)
  412. continue;
  413. map<string, ISecResource*>::iterator it = m_managedFileScopesMap.find(cachekey);
  414. if (it != m_managedFileScopesMap.end())
  415. {
  416. ISecResource *res = (*it).second;
  417. res->Release();
  418. m_managedFileScopesMap.erase(it);
  419. }
  420. #ifdef _DEBUG
  421. DBGLOG("Caching Managed File Scope %s",cachekey);
  422. #endif
  423. m_managedFileScopesMap.insert( pair<string, ISecResource*>(cachekey, LINK(scope)));
  424. }
  425. return true;
  426. }
  427. inline void CPermissionsCache::removeManagedFileScopes(IArrayOf<ISecResource>& scopes)
  428. {
  429. WriteLockBlock writeLock(m_scopesRWLock);
  430. ForEachItemIn(x, scopes)
  431. {
  432. ISecResource* scope = &scopes.item(x);
  433. if(!scope)
  434. continue;
  435. const char* cachekey = scope->getName();
  436. if(cachekey == NULL)
  437. continue;
  438. map<string, ISecResource*>::iterator it = m_managedFileScopesMap.find(cachekey);
  439. if (it != m_managedFileScopesMap.end())
  440. {
  441. ISecResource *res = (*it).second;
  442. res->Release();
  443. m_managedFileScopesMap.erase(it);
  444. }
  445. }
  446. }
  447. inline void CPermissionsCache::removeAllManagedFileScopes()
  448. {
  449. WriteLockBlock writeLock(m_scopesRWLock);
  450. map<string, ISecResource*>::const_iterator cit;
  451. map<string, ISecResource*>::const_iterator iEnd = m_managedFileScopesMap.end();
  452. for (cit = m_managedFileScopesMap.begin(); cit != iEnd; cit++)
  453. {
  454. ISecResource *res = (*cit).second;
  455. res->Release();
  456. }
  457. m_managedFileScopesMap.clear();
  458. }
  459. /*
  460. if perms set on 'scopeA::scopeB' only and lookup of 'scopeA::scopeB::scopeC::scopeD'
  461. need to lookup:
  462. 'scopeA'
  463. no match=>continue
  464. match=>continue if read permissions (if no read, implies can't "see" child scopes)
  465. 'scopeA::scopeB'
  466. no match=>continue
  467. match=>continue if read permissions (if no read, implies can't "see" child scopes)
  468. etc. Until full scope path checked, or no read permissions hit on ancestor scope.
  469. */
  470. bool CPermissionsCache::queryPermsManagedFileScope(ISecUser& sec_user, const char * fullScope, StringBuffer& managedScope, SecAccessFlags * accessFlags)
  471. {
  472. if (!fullScope || !*fullScope)
  473. {
  474. *accessFlags = queryDefaultPermission(sec_user);
  475. return true;
  476. }
  477. time_t now;
  478. time(&now);
  479. if (m_secMgr && (0 == m_lastManagedFileScopesRefresh || m_lastManagedFileScopesRefresh < (now - m_cacheTimeout)))
  480. {
  481. removeAllManagedFileScopes();
  482. IArrayOf<ISecResource> scopes;
  483. aindex_t count = m_secMgr->getManagedFileScopes(scopes);
  484. if (count)
  485. addManagedFileScopes(scopes);
  486. m_defaultPermission = SecAccess_Unknown;//trigger refresh
  487. m_lastManagedFileScopesRefresh = now;
  488. }
  489. if (m_managedFileScopesMap.empty())
  490. {
  491. *accessFlags = queryDefaultPermission(sec_user);
  492. return true;
  493. }
  494. StringArray scopes;
  495. {
  496. StringBuffer scope;
  497. const char * p = fullScope;
  498. while (*p)
  499. {
  500. if (*p == ':')
  501. {
  502. if (*(p+1) != ':')
  503. return false;//Malformed scope string, let LDAP figure it out
  504. scopes.append(scope.str());
  505. scope.append(*(p++));
  506. }
  507. scope.append(*(p++));
  508. }
  509. scopes.append(scope.str());
  510. }
  511. ISecResource *matchedRes = NULL;
  512. ISecResource *res = NULL;
  513. bool isManaged = false;
  514. ReadLockBlock readLock(m_scopesRWLock);
  515. for(unsigned i = 0; i < scopes.length(); i++)
  516. {
  517. const char* scope = scopes.item(i);
  518. map<string, ISecResource*>::const_iterator it = m_managedFileScopesMap.find(scope);
  519. if (it != m_managedFileScopesMap.end())
  520. {
  521. isManaged = true;
  522. res = (*it).second;
  523. res->setResourceType(RT_FILE_SCOPE);
  524. LINK(res);
  525. IArrayOf<ISecResource> secResArr;
  526. secResArr.append(*res);
  527. bool found;
  528. int nFound = lookup(sec_user, secResArr, &found);
  529. if (nFound && found)
  530. {
  531. if (0 == (res->getAccessFlags() & SecAccess_Read))
  532. {
  533. *accessFlags = res->getAccessFlags();
  534. managedScope.append(const_cast<char *>(res->getName()));
  535. #ifdef _DEBUG
  536. DBGLOG("FileScope %s for %s(%s) access denied %d",fullScope, sec_user.getName(), res->getName(), *accessFlags);
  537. #endif
  538. return true;
  539. }
  540. else
  541. matchedRes = res;//allowed at this scope, but must also look at child scopes
  542. }
  543. }
  544. }
  545. bool rc;
  546. if (isManaged)
  547. {
  548. if (matchedRes)
  549. {
  550. *accessFlags = matchedRes->getAccessFlags();
  551. managedScope.append(const_cast<char *>(matchedRes->getName()));
  552. #ifdef _DEBUG
  553. DBGLOG("FileScope %s for %s(%s) access granted %d", fullScope, sec_user.getName(), matchedRes->getName(), *accessFlags);
  554. #endif
  555. rc = true;
  556. }
  557. else
  558. {
  559. managedScope.append(const_cast<char *>(res->getName()));
  560. #ifdef _DEBUG
  561. DBGLOG("FileScope %s for %s(%s) managed but not cached", fullScope, sec_user.getName(), res->getName());
  562. #endif
  563. rc = false;//need to go to LDAP to check
  564. }
  565. }
  566. else
  567. {
  568. *accessFlags = queryDefaultPermission(sec_user);
  569. #ifdef _DEBUG
  570. DBGLOG("FileScope %s for %s not managed, using default %d", fullScope, sec_user.getName(),*accessFlags);
  571. #endif
  572. rc = true;
  573. }
  574. return rc;
  575. }
  576. SecAccessFlags CPermissionsCache::queryDefaultPermission(ISecUser& user)
  577. {
  578. if (m_defaultPermission == SecAccess_Unknown)
  579. {
  580. if (m_secMgr)
  581. m_defaultPermission = m_secMgr->queryDefaultPermission(user);
  582. else
  583. m_defaultPermission = SecAccess_None;
  584. }
  585. return m_defaultPermission;
  586. }
  587. void CPermissionsCache::flush()
  588. {
  589. // MORE - is this safe? m_defaultPermossion and m_lastManagedFileScopesRefresh are unprotected,
  590. // and entries could be added to the first cache while the second is being cleared - does that matter?
  591. {
  592. WriteLockBlock writeLock(m_resPermCacheRWLock);
  593. MapResPermissionsCache::const_iterator i;
  594. MapResPermissionsCache::const_iterator iEnd = m_resPermissionsMap.end();
  595. for (i = m_resPermissionsMap.begin(); i != iEnd; i++)
  596. delete (*i).second;
  597. m_resPermissionsMap.clear();
  598. }
  599. {
  600. WriteLockBlock writeLock(m_userCacheRWLock );
  601. MapUserCache::const_iterator ui;
  602. MapUserCache::const_iterator uiEnd = m_userCache.end();
  603. for (ui = m_userCache.begin(); ui != uiEnd; ui++)
  604. delete (*ui).second;
  605. m_userCache.clear();
  606. }
  607. m_lastManagedFileScopesRefresh = 0;
  608. m_defaultPermission = SecAccess_Unknown;//trigger refresh
  609. }
  610. CPermissionsCache* CPermissionsCache::getInstance(const char * _secMgrClass)
  611. {
  612. const char * secMgrClass = (_secMgrClass != nullptr && *_secMgrClass) ? _secMgrClass : "genericSecMgrClass";
  613. CriticalBlock block(mapCacheCS);
  614. MapCache::iterator it = g_mapCache.find(secMgrClass);
  615. if (it != g_mapCache.end())//exists in cache
  616. {
  617. LINK((*it).second);
  618. return (*it).second;
  619. }
  620. else
  621. {
  622. CPermissionsCache * instance = new CPermissionsCache(_secMgrClass);
  623. g_mapCache.insert(pair<string, CPermissionsCache*>(secMgrClass, instance));
  624. return instance;
  625. }
  626. }