From 364ed76ca03efcdaa3eb6a480a81d16605dfedef Mon Sep 17 00:00:00 2001 From: Ken Rowland Date: Tue, 21 May 2024 11:02:45 -0400 Subject: [PATCH] Add option to use current caching that only caches access based on first user --- esp/applications/common/ldap/ldap.yaml | 1 + helm/hpcc/values.schema.json | 4 ++ initfiles/componentfiles/configxml/dali.xsl | 3 + initfiles/componentfiles/configxml/esp.xsl | 3 + .../security/LdapSecurity/ldapconnection.cpp | 1 + system/security/LdapSecurity/ldapsecurity.cpp | 1 + system/security/shared/caching.cpp | 62 +++++++++++++++---- system/security/shared/caching.hpp | 11 ++++ 8 files changed, 74 insertions(+), 12 deletions(-) diff --git a/esp/applications/common/ldap/ldap.yaml b/esp/applications/common/ldap/ldap.yaml index 3f87d56f518..b5077d30347 100644 --- a/esp/applications/common/ldap/ldap.yaml +++ b/esp/applications/common/ldap/ldap.yaml @@ -22,3 +22,4 @@ ldap: hpccAdminSecretKey: "" hpccAdminVaultId: "" checkScopeScans: true + useLegacyDefaultFileScopePermissionCache: false diff --git a/helm/hpcc/values.schema.json b/helm/hpcc/values.schema.json index b7d14db9d44..b4b5272cb6d 100644 --- a/helm/hpcc/values.schema.json +++ b/helm/hpcc/values.schema.json @@ -1076,6 +1076,10 @@ "checkScopeScans": { "type": "boolean", "description": "Only return iterated logical file metadata for files that user has scope permission to access" + }, + "useLegacyDefaultFileScopePermissionCache": { + "type": "boolean", + "description": "Use legacy default filescope permissions that cached value for first user" } } }, diff --git a/initfiles/componentfiles/configxml/dali.xsl b/initfiles/componentfiles/configxml/dali.xsl index ffafa3199cc..5983537297d 100644 --- a/initfiles/componentfiles/configxml/dali.xsl +++ b/initfiles/componentfiles/configxml/dali.xsl @@ -308,6 +308,9 @@ + + + diff --git a/initfiles/componentfiles/configxml/esp.xsl b/initfiles/componentfiles/configxml/esp.xsl index c567856f282..8fca1a45b39 100644 --- a/initfiles/componentfiles/configxml/esp.xsl +++ b/initfiles/componentfiles/configxml/esp.xsl @@ -466,6 +466,9 @@ + + + diff --git a/system/security/LdapSecurity/ldapconnection.cpp b/system/security/LdapSecurity/ldapconnection.cpp index 3c55315f9a6..5cdb64452fe 100644 --- a/system/security/LdapSecurity/ldapconnection.cpp +++ b/system/security/LdapSecurity/ldapconnection.cpp @@ -664,6 +664,7 @@ class CLdapConfig : implements ILdapConfig, public CInterface m_sdfieldname.append("aci"); else if(m_serverType == OPEN_LDAP) m_sdfieldname.append("aci"); + #ifdef _DEBUG debugPrintout(); #endif diff --git a/system/security/LdapSecurity/ldapsecurity.cpp b/system/security/LdapSecurity/ldapsecurity.cpp index 7bd62e4e3d0..3cc400c2f54 100644 --- a/system/security/LdapSecurity/ldapsecurity.cpp +++ b/system/security/LdapSecurity/ldapsecurity.cpp @@ -630,6 +630,7 @@ void CLdapSecManager::init(const char *serviceName, IPropertyTree* cfg) m_permissionsCache->setCacheTimeout( 60 * cacheTimeoutMinutes); m_permissionsCache->setTransactionalEnabled(true); m_permissionsCache->setSecManager(this); + m_permissionsCache->setUseLegacyDefaultFileScopePermissionCache(cfg->getPropBool("@useLegacyDefaultFileScopePermissionCache", false)); m_passwordExpirationWarningDays = cfg->getPropInt(".//@passwordExpirationWarningDays", 10); //Default to 10 days m_checkViewPermissions = cfg->getPropBool(".//@checkViewPermissions", false); m_hpccInternalScope.set(queryDfsXmlBranchName(DXB_Internal)).append("::");//HpccInternal:: diff --git a/system/security/shared/caching.cpp b/system/security/shared/caching.cpp index 0d847f738c3..5cc04b18308 100644 --- a/system/security/shared/caching.cpp +++ b/system/security/shared/caching.cpp @@ -572,7 +572,15 @@ bool CPermissionsCache::queryPermsManagedFileScope(ISecUser& sec_user, const cha aindex_t count = m_secMgr->getManagedScopeTree(RT_FILE_SCOPE, nullptr, scopes); if (count) addManagedFileScopes(scopes); - m_userDefaultFileScopePermissions.clear(); + if (m_useLegacyDefaultFileScopePermissionCache) + { + m_defaultPermission = SecAccess_Unknown; + } + else + { + WriteLockBlock defaultScopesWriteLock(m_defaultScopesRWLock); + m_userDefaultFileScopePermissions.clear(); + } time(&m_lastManagedFileScopesRefresh); } } @@ -672,20 +680,42 @@ bool CPermissionsCache::queryPermsManagedFileScope(ISecUser& sec_user, const cha SecAccessFlags CPermissionsCache::queryDefaultPermission(ISecUser& user) { - const char *username = user.getName(); - SecAccessFlags defaultPermission = SecAccess_None; - auto it = m_userDefaultFileScopePermissions.find(username); - if (it == m_userDefaultFileScopePermissions.end()) + if (m_useLegacyDefaultFileScopePermissionCache) { - defaultPermission = m_secMgr->queryDefaultPermission(user); - std::string userName(username); - m_userDefaultFileScopePermissions.insert(std::pair(userName, defaultPermission)); - DBGLOG("Added user '%s' to default file scope permissions with access %s(%d)", username, getSecAccessFlagName(defaultPermission), defaultPermission); + if (m_defaultPermission == SecAccess_Unknown) + { + if (m_secMgr) + m_defaultPermission = m_secMgr->queryDefaultPermission(user); + else + m_defaultPermission = SecAccess_None; + + DBGLOG("Legacy default file scope permission set to %s(%d) for all users, based on User '%s'", getSecAccessFlagName(m_defaultPermission), + m_defaultPermission, user.getName()); + } + return m_defaultPermission; } - else + + const char *username = user.getName(); + SecAccessFlags defaultPermission = SecAccess_None; + if (m_secMgr) { - defaultPermission = it->second; + ReadLockBlock defaultScopesReadLock(m_defaultScopesRWLock); + auto it = m_userDefaultFileScopePermissions.find(username); + if (it == m_userDefaultFileScopePermissions.end()) + { + defaultScopesReadLock.clear(); + WriteLockBlock defaultScopesWriteLock(m_defaultScopesRWLock); + defaultPermission = m_secMgr->queryDefaultPermission(user); + std::string userName(username); + m_userDefaultFileScopePermissions.emplace(userName, defaultPermission); + DBGLOG("Added user '%s' to default file scope permissions with access %s(%d)", username, getSecAccessFlagName(defaultPermission), + defaultPermission); + } + else + { + defaultPermission = it->second; + } } return defaultPermission; @@ -711,8 +741,16 @@ void CPermissionsCache::flush() delete (*ui).second; m_userCache.clear(); } + if (m_useLegacyDefaultFileScopePermissionCache) + { + m_defaultPermission = SecAccess_None; + } + else + { + WriteLockBlock defaultScopesWriteLock(m_defaultScopesRWLock); + m_userDefaultFileScopePermissions.clear(); + } m_lastManagedFileScopesRefresh = 0; - m_userDefaultFileScopePermissions.clear(); } CPermissionsCache* CPermissionsCache::getInstance(const char * _secMgrClass) diff --git a/system/security/shared/caching.hpp b/system/security/shared/caching.hpp index d4a3da0a737..eba76a19311 100644 --- a/system/security/shared/caching.hpp +++ b/system/security/shared/caching.hpp @@ -143,6 +143,7 @@ class CPermissionsCache : public CInterface m_transactionalEnabled = false; m_secMgr = NULL; m_lastManagedFileScopesRefresh = 0; + m_defaultPermission = SecAccess_Unknown; m_secMgrClass.set(_secMgrClass); m_transactionalCacheTimeout = DEFAULT_CACHE_TIMEOUT_SECONDS; } @@ -202,6 +203,12 @@ class CPermissionsCache : public CInterface bool queryPermsManagedFileScope(ISecUser& sec_user, const char * fullScope, StringBuffer& managedScope, SecAccessFlags * accessFlags); void setSecManager(ISecManager * secMgr) { m_secMgr = secMgr; } SecAccessFlags queryDefaultPermission(ISecUser& user); + void setUseLegacyDefaultFileScopePermissionCache(bool useLegacy) + { + if (useLegacy) + DBGLOG("*** Setting default file scope permissions to use legacy mode which uses first retrieved permission for all users."); + m_useLegacyDefaultFileScopePermissionCache = useLegacy; + } private: typedef std::map MapResPermissionsCache; @@ -220,11 +227,15 @@ class CPermissionsCache : public CInterface StringAttr m_secMgrClass; //Managed File Scope support + mutable ReadWriteLock m_defaultScopesRWLock;//guards m_userDefaultFileScopePermissions std::map m_userDefaultFileScopePermissions; + SecAccessFlags m_defaultPermission; map m_managedFileScopesMap; mutable ReadWriteLock m_scopesRWLock;//guards m_managedFileScopesMap ISecManager * m_secMgr; time_t m_lastManagedFileScopesRefresh; + + bool m_useLegacyDefaultFileScopePermissionCache = false; }; time_t getThreadCreateTime();