bool CAccessControlListManager::CanObjectUseRight ( const char* szObjectName, CAccessControlListGroupObject::EObjectType eObjectType, const char* szRightName, CAccessControlListRight::ERightType eRightType, bool bDefaultAccessRight ) { // Clear cache if required if ( m_bReadCacheDirty ) ClearReadCache (); // If object is resource, try cache if ( eObjectType == CAccessControlListGroupObject::OBJECT_TYPE_RESOURCE ) { // Make unique key for this query SString strKey ( "%s %s %d %d", szObjectName, szRightName, eRightType, bDefaultAccessRight ); // Check if this query has been done before bool* pResult = MapFind( m_ReadCacheMap, strKey ); if ( !pResult ) { // If not, do query now and add result to the cache bool bResult = InternalCanObjectUseRight ( szObjectName, eObjectType, szRightName, eRightType, bDefaultAccessRight ); MapSet ( m_ReadCacheMap, strKey, bResult ); pResult = MapFind( m_ReadCacheMap, strKey ); } // Return cached result return *pResult; } return InternalCanObjectUseRight ( szObjectName, eObjectType, szRightName, eRightType, bDefaultAccessRight ); }
void CAccessControlListManager::DoPulse ( void ) { // Clear cache every 12 hours or if dirty if ( m_bReadCacheDirty || GetTickCount64_ () - m_llLastTimeReadCacheCleared > 1000 * 60 * 60 * 12 ) ClearReadCache (); // Save when needed, but no more than once every 10 seconds if ( m_AutoSaveTimer.Get () > 10000 && m_bNeedsSave ) Save (); }
bool CAccessControlListManager::Load ( void ) { m_bAllowSave = true; // Eventually destroy the previously loaded xml if ( m_pXML ) { delete m_pXML; } // Load the XML m_pXML = g_pServerInterface->GetXML ()->CreateXML ( GetFileName ().c_str () ); if ( !m_pXML ) { CLogger::ErrorPrintf ( "Error loading Access Control List file\n" ); return false; } // Parse it if ( !m_pXML->Parse () ) { SString strParseErrorDesc; m_pXML->GetLastError( strParseErrorDesc ); CLogger::ErrorPrintf ( "Error parsing %s - %s\n", *ExtractFilename( GetFileName() ), *strParseErrorDesc ); return false; } // Grab the XML root node m_pRootNode = m_pXML->GetRootNode (); if ( !m_pRootNode ) { CLogger::ErrorPrintf ( "Missing root node ('ACL')\n" ); return false; } // Clear previous ACL stuff ClearACLs (); ClearGroups (); ClearReadCache (); // load the acl's CXMLNode* pSubNode = NULL; unsigned int uiSubNodesCount = m_pRootNode->GetSubNodeCount (); for ( unsigned int i = 0 ; i < uiSubNodesCount ; i++ ) { pSubNode = m_pRootNode->GetSubNode ( i ); if ( !pSubNode ) continue; if ( pSubNode->GetTagName ().compare ( "acl" ) == 0 ) { CXMLAttribute* pAttribute = pSubNode->GetAttributes ().Find ( "name" ); if ( pAttribute ) { CAccessControlList* pACL = AddACL ( pAttribute->GetValue ().c_str () ); CXMLNode* pSubSubNode = NULL; unsigned int uiSubSubNodesCount = pSubNode->GetSubNodeCount (); for ( unsigned int j = 0 ; j < uiSubSubNodesCount ; j++ ) { // If this subnode doesn't exist, return to the for loop and continue it pSubSubNode = pSubNode->GetSubNode ( j ); if ( !pSubSubNode ) continue; // Check that this subsub node is named "right" if ( pSubSubNode->GetTagName ().compare ( "right" ) == 0 ) { // Grab the name and the access attributes CXMLAttribute* pNameAttribute = pSubSubNode->GetAttributes ().Find ( "name" ); CXMLAttribute* pAccessAttribute = pSubSubNode->GetAttributes ().Find ( "access" ); if ( pNameAttribute && pAccessAttribute ) { // See if the access attribute is true or false bool bAccess = false; std::string strAccess = pAccessAttribute->GetValue (); if ( stricmp ( strAccess.c_str (), "true" ) == 0 || stricmp ( strAccess.c_str (), "yes" ) == 0 || strcmp ( strAccess.c_str (), "1" ) == 0 ) { bAccess = true; } // Grab the name of the 'right' name const char *szRightName = pNameAttribute->GetValue ().c_str (); // Create the rights control list CAccessControlListRight* pRight = NULL; if ( StringBeginsWith ( szRightName, "command." ) ) { pRight = pACL->AddRight ( &szRightName[8], CAccessControlListRight::RIGHT_TYPE_COMMAND, bAccess ); } else if ( StringBeginsWith ( szRightName, "function." ) ) { pRight = pACL->AddRight ( &szRightName[9], CAccessControlListRight::RIGHT_TYPE_FUNCTION, bAccess ); } else if ( StringBeginsWith ( szRightName, "resource." ) ) { pRight = pACL->AddRight ( &szRightName[9], CAccessControlListRight::RIGHT_TYPE_RESOURCE, bAccess ); } else if ( StringBeginsWith ( szRightName, "general." ) ) { pRight = pACL->AddRight ( &szRightName[8], CAccessControlListRight::RIGHT_TYPE_GENERAL, bAccess ); } else continue; // Set all the extra attributes for ( uint i = 0 ; i < pSubSubNode->GetAttributes ().Count () ; i++ ) { CXMLAttribute* pAttribute = pSubSubNode->GetAttributes ().Get ( i ); pRight->SetAttributeValue ( pAttribute->GetName (), pAttribute->GetValue () ); } } } } } } } // Load the groups pSubNode = NULL; uiSubNodesCount = m_pRootNode->GetSubNodeCount (); for ( unsigned int i = 0 ; i < uiSubNodesCount ; i++ ) { pSubNode = m_pRootNode->GetSubNode ( i ); if ( !pSubNode ) continue; if ( pSubNode->GetTagName ().compare ( "group" ) == 0 ) { CXMLAttribute* pAttribute = pSubNode->GetAttributes ().Find ( "name" ); if ( pAttribute ) { CAccessControlListGroup* pGroup = AddGroup ( pAttribute->GetValue ().c_str () ); CXMLNode* pSubSubNode = NULL; unsigned int uiSubSubNodesCount = pSubNode->GetSubNodeCount (); for ( unsigned int j = 0 ; j < uiSubSubNodesCount ; j++ ) { pSubSubNode = pSubNode->GetSubNode ( j ); if ( !pSubSubNode ) continue; if ( pSubSubNode->GetTagName ().compare ( "object" ) == 0 ) { CXMLAttribute* pSubAttribute = pSubSubNode->GetAttributes ().Find ( "name" ); if ( pSubAttribute ) { const char *szAccountName = pSubAttribute->GetValue ().c_str (); if ( StringBeginsWith ( szAccountName, "user." ) ) { pGroup->AddObject ( &szAccountName[5], CAccessControlListGroupObject::OBJECT_TYPE_USER ); } else if ( StringBeginsWith ( szAccountName, "resource." ) ) { pGroup->AddObject ( &szAccountName[9], CAccessControlListGroupObject::OBJECT_TYPE_RESOURCE ); } } } else if ( pSubSubNode->GetTagName ().compare ( "acl" ) == 0 ) { CXMLAttribute* pSubAttribute = pSubSubNode->GetAttributes ().Find ( "name" ); if ( pSubAttribute ) { CAccessControlList* pACL = GetACL ( pSubAttribute->GetValue ().c_str () ); if ( pACL ) { pGroup->AddACL ( pACL ); } } } } } } } m_bNeedsSave = false; return true; }