Looks OK. /Bertil
-----Original Message----- From: Ingvar Bergström Sent: den 7 mars 2014 10:09 To: Bertil Engelholm Cc: [email protected] Subject: [PATCH 1 of 1] smfd: deletion of objects owned by SMF possible regadless of DN [#752] osaf/services/saf/smfsv/smfd/SmfUtils.cc | 22 + osaf/services/saf/smfsv/smfd/SmfUtils.hh | 8 + osaf/services/saf/smfsv/smfd/smfd_campaign_oi.cc | 380 ++++++++++++---------- 3 files changed, 244 insertions(+), 166 deletions(-) SMF allows objects to be created and deleted regardless of DN. Without this patch the deletion of objects needed specific RDN to be accepted. diff --git a/osaf/services/saf/smfsv/smfd/SmfUtils.cc b/osaf/services/saf/smfsv/smfd/SmfUtils.cc --- a/osaf/services/saf/smfsv/smfd/SmfUtils.cc +++ b/osaf/services/saf/smfsv/smfd/SmfUtils.cc @@ -238,6 +238,28 @@ SmfImmUtils::classDescriptionMemoryFree( } // ------------------------------------------------------------------------------ +// getClassNameForObject() +// +----------------------------------------------------------------------- +------- +bool +SmfImmUtils::getClassNameForObject(const std::string& i_dn, +std::string& o_className) { + SaImmAttrValuesT_2 **attributes; + if (this->getObject(i_dn, &attributes) == false) { + LOG_NO("Failed to get object %s", i_dn.c_str()); + return false; + } + + o_className = immutil_getStringAttr((const SaImmAttrValuesT_2 **)attributes, + SA_IMM_ATTR_CLASS_NAME, 0); + if (o_className.empty()) { + LOG_NO("Failed to get class name for object %s", i_dn.c_str()); + return false; + } + + return true; +} + +// +----------------------------------------------------------------------- +------- // getObject() // ------------------------------------------------------------------------------ bool diff --git a/osaf/services/saf/smfsv/smfd/SmfUtils.hh b/osaf/services/saf/smfsv/smfd/SmfUtils.hh --- a/osaf/services/saf/smfsv/smfd/SmfUtils.hh +++ b/osaf/services/saf/smfsv/smfd/SmfUtils.hh @@ -109,6 +109,14 @@ class SmfImmUtils { bool classDescriptionMemoryFree(SaImmAttrDefinitionT_2 ** i_attributeDefs); /// +/// Purpose: Get the class name for an IMM object. +/// @param i_dn DN of the object to read the class name from. +/// @param o_className Resulting class name +/// @return True if successful, otherwise false /// + bool getClassNameForObject(const std::string& i_dn, +std::string& o_className); + +/// /// Purpose: Get all attributes for an IMM object. /// @param i_dn DN of the object to get. /// @param o_attributes Resulting attribute values diff --git a/osaf/services/saf/smfsv/smfd/smfd_campaign_oi.cc b/osaf/services/saf/smfsv/smfd/smfd_campaign_oi.cc --- a/osaf/services/saf/smfsv/smfd/smfd_campaign_oi.cc +++ b/osaf/services/saf/smfsv/smfd/smfd_campaign_oi.cc @@ -49,6 +49,13 @@ static const SaImmClassNameT campaignCla static const SaImmClassNameT smfConfigClassName = (SaImmClassNameT) "OpenSafSmfConfig"; static const SaImmClassNameT smfSwBundleClassName = (SaImmClassNameT) "SaSmfSwBundle"; +typedef enum { + SMF_CLASS_UNKNOWN = 0, + SMF_CLASS_CAMPAIGN = 1, + SMF_CLASS_BUNDLE = 2, + SMF_CLASS_CONFIG = 3 +} smf_classes_t; + /** * Campaign Admin operation handling. This function is executed as an * IMM callback. @@ -184,187 +191,227 @@ static SaAisErrorT saImmOiCcbCompletedCa } /* - ** "check that the sequence of change requests contained in the CCB is - ** valid and that no errors will be generated when these changes - ** are applied." - */ + ** "check that the sequence of change requests contained in the CCB is + ** valid and that no errors will be generated when these changes + ** are applied." + */ ccbUtilOperationData = ccbUtilCcbData->operationListHead; while (ccbUtilOperationData != NULL) { - switch (ccbUtilOperationData->operationType) { - case CCBUTIL_CREATE: - { - //Handle the campaign object - if (strcmp(ccbUtilOperationData->param.create.className, campaignClassName) == 0) { - SmfCampaign test(ccbUtilOperationData->param.create.parentName, - ccbUtilOperationData->param.create.attrValues); + switch (ccbUtilOperationData->operationType) { + case CCBUTIL_CREATE: + { + //Handle the campaign object + if (strcmp(ccbUtilOperationData->param.create.className, campaignClassName) == 0) { + SmfCampaign test(ccbUtilOperationData->param.create.parentName, + ccbUtilOperationData->param.create.attrValues); + //Save the class name enum for use in later phases + ccbUtilOperationData->userData = (void*)SMF_CLASS_CAMPAIGN; + TRACE("Create campaign %s", + test.getDn().c_str()); /* Creation always allowed */ - TRACE("Create campaign %s", test.getDn().c_str()); /* Creation always allowed */ - //Handle the SaSmfSwBundle object - } else if (strcmp(ccbUtilOperationData->param.create.className, smfSwBundleClassName) == 0) { - TRACE("Create a software bundle"); /* Creation always allowed */ - //Handle the OpenSAFSmfConfig object - } else if (strcmp(ccbUtilOperationData->param.create.className, smfConfigClassName) == 0) { - LOG_NO("OpenSafSmfConfig object must be initially created"); - rc = SA_AIS_ERR_BAD_OPERATION; - goto done; - } else { - LOG_NO("Unknown class name %s, can't be created", - ccbUtilOperationData->param.create.className); - rc = SA_AIS_ERR_BAD_OPERATION; - goto done; - } - break; - } + //Handle the SaSmfSwBundle object + } else if (strcmp(ccbUtilOperationData->param.create.className, smfSwBundleClassName) == 0) { + //Save the class name enum for use in later phases + ccbUtilOperationData->userData = (void*)SMF_CLASS_BUNDLE; + TRACE("Create a software bundle"); /* + Creation always allowed */ - case CCBUTIL_DELETE: - { - //Handle the campaign object - if (strncmp((char *)ccbUtilOperationData->param.deleteOp.objectName->value, "safSmfCampaign=", 15) == 0) { - TRACE("Delete campaign %s", ccbUtilOperationData->param.deleteOp.objectName->value); + //Handle the OpenSAFSmfConfig object + } else if (strcmp(ccbUtilOperationData->param.create.className, smfConfigClassName) == 0) { + //Save the class name enum for use in later phases + ccbUtilOperationData->userData = (void*)SMF_CLASS_CONFIG; + LOG_NO("OpenSafSmfConfig object must be initially created"); + rc = SA_AIS_ERR_BAD_OPERATION; + goto done; - SmfCampaign *campaign = - SmfCampaignList::instance()->get(ccbUtilOperationData->param.deleteOp.objectName); - if (campaign == NULL) { - LOG_NO("Campaign %s doesn't exists, can't be deleted", - ccbUtilOperationData->param.deleteOp.objectName->value); - rc = SA_AIS_ERR_BAD_OPERATION; - goto done; - } + //Handle unknown + } else { + //Save the class name enum for use in later phases + ccbUtilOperationData->userData = (void*)SMF_CLASS_UNKNOWN; + LOG_NO("Unknown class name %s, can't be created", + ccbUtilOperationData->param.create.className); + rc = SA_AIS_ERR_BAD_OPERATION; + goto done; + } + break; + } - if (campaign->executing() == true) { - LOG_NO("Campaign %s in state %u, can't be deleted", - ccbUtilOperationData->param.deleteOp.objectName->value, - campaign->getState()); - rc = SA_AIS_ERR_BAD_OPERATION; - goto done; - } - else if ((SmfCampaignThread::instance() != NULL) && - (SmfCampaignThread::instance()->campaign() == campaign)) { - /* Campaign is executing prereq tests (in state INITIAL) */ - LOG_NO("Campaign %s is executing, can't be deleted", - ccbUtilOperationData->param.deleteOp.objectName->value); - rc = SA_AIS_ERR_BAD_OPERATION; - goto done; + case CCBUTIL_DELETE: + { + //Get the DN to the object to delete and read the class name + const std::string objToDelete = (char + *)ccbUtilOperationData->param.deleteOp.objectName->value; + + std::string className; + if (immUtil.getClassNameForObject(objToDelete, className) == false) { + LOG_NO("Failed to get class name for object to delete %s", objToDelete.c_str()); + rc = SA_AIS_ERR_BAD_OPERATION; + goto done; + } + + //Handle the campaign object + if (className == campaignClassName ) { + TRACE("Delete campaign %s", objToDelete.c_str()); + //Save the class name enum for use in later phases + ccbUtilOperationData->userData = + (void*)SMF_CLASS_CAMPAIGN; + + //Find Campaign object + SmfCampaign *campaign = + SmfCampaignList::instance()->get(ccbUtilOperationData->param.deleteOp.objectName); //objToDelete + if (campaign == NULL) { + LOG_NO("Campaign %s doesn't exists, can't be deleted", objToDelete.c_str()); + rc = SA_AIS_ERR_BAD_OPERATION; + goto done; } - //Handle the OpenSAFSmfConfig object - }else if (strncmp((char*)ccbUtilOperationData->param.deleteOp.objectName->value, "smfConfig=", 10) == 0) { - LOG_NO("Deletion of SMF configuration object %s, not allowed", - ccbUtilOperationData->param.deleteOp.objectName->value); - rc = SA_AIS_ERR_BAD_OPERATION; - goto done; - //Handle the SaSmfSwBundle object - }else if (strncmp((char*)ccbUtilOperationData->param.deleteOp.objectName->value, "safSmfBundle=", 13) == 0) { - TRACE("Delete software bundle %s", ccbUtilOperationData->param.deleteOp.objectName->value); - //Check if the bundle is in use. - //Search for installed bundles - std::list < std::string > objectList; - std::list < std::string >::const_iterator objit; - if(immUtil.getChildren("", objectList, SA_IMM_SUBTREE, "SaAmfNodeSwBundle") == false){ - LOG_NO("Fail to search for SaAmfNodeSwBundle instances."); - rc = SA_AIS_ERR_BAD_OPERATION; - goto done; - } - //Match the names of the installed bundles with the bundle requested to be removed - std::string swBundleToRemove = (const char*)ccbUtilOperationData->param.deleteOp.objectName->value; - std::string::size_type pos1 = sizeof("safInstalledSwBundle=") - 1; + if (campaign->executing() == true) { + LOG_NO("Campaign %s in state %u, can't be deleted", objToDelete.c_str(), campaign->getState()); + rc = SA_AIS_ERR_BAD_OPERATION; + goto done; + } else if ((SmfCampaignThread::instance() != NULL) && + (SmfCampaignThread::instance()->campaign() == campaign)) { + //Campaign is executing prereq tests (in state INITIAL) + LOG_NO("Campaign %s is executing, can't be deleted", objToDelete.c_str()); + rc = SA_AIS_ERR_BAD_OPERATION; + goto done; + } - for (objit = objectList.begin(); objit != objectList.end(); ++objit) { - std::string::size_type pos2 = (*objit).find(","); - if (pos2 == std::string::npos) { - LOG_NO("saImmOiCcbCompletedCallback:: Could not find separator \",\" in %s", (*objit).c_str()); - rc = SA_AIS_ERR_BAD_OPERATION; - goto done; - } - std::string swBundleInstalled = (*objit).substr(pos1, pos2 - pos1); - if (swBundleInstalled.size() == 0) { - LOG_NO("saImmOiCcbCompletedCallback:: Could not find installed bundle from %s", (*objit).c_str()); - rc = SA_AIS_ERR_BAD_OPERATION; - goto done; - } + //Handle the OpenSAFSmfConfig object + } else if (className == smfConfigClassName){ + //Save the class name enum for use in later phases + ccbUtilOperationData->userData = (void*)SMF_CLASS_CONFIG; + LOG_NO("Deletion of SMF configuration object %s, not allowed", objToDelete.c_str()); + rc = SA_AIS_ERR_BAD_OPERATION; + goto done; - if (swBundleInstalled == swBundleToRemove){ - LOG_NO("SwBundle %s is in use, can not be removed", swBundleToRemove.c_str()); - rc = SA_AIS_ERR_BAD_OPERATION; - goto done; - } - } + //Handle the SaSmfSwBundle object + } else if (className == smfSwBundleClassName){ + TRACE("Delete software bundle %s", objToDelete.c_str()); + //Save the class name enum for use in later phases + ccbUtilOperationData->userData = + (void*)SMF_CLASS_BUNDLE; - goto done; - //Handle any unknown object - } else { - LOG_NO("Unknown object %s, can't be deleted", - ccbUtilOperationData->param.deleteOp.objectName->value); - rc = SA_AIS_ERR_BAD_OPERATION; - goto done; - } - break; - } + //Check if the bundle is in use. + //Search for installed bundles + std::list < std::string > objectList; + std::list < std::string >::const_iterator objit; + if(immUtil.getChildren("", objectList, SA_IMM_SUBTREE, "SaAmfNodeSwBundle") == false){ + LOG_NO("Fail to search for SaAmfNodeSwBundle instances."); + rc = SA_AIS_ERR_BAD_OPERATION; + goto done; + } + //Match the names of the installed bundles with the bundle requested to be removed + std::string swBundleToRemove = objToDelete; + std::string::size_type pos1 = + sizeof("safInstalledSwBundle=") - 1; - case CCBUTIL_MODIFY: - { - //Handle the campaign object - if (strncmp((char *)ccbUtilOperationData->param.modify.objectName->value, "safSmfCampaign=", 15) == 0) { - TRACE("Modify campaign %s", ccbUtilOperationData->param.modify.objectName->value); - - /* Find Campaign object */ - SmfCampaign *campaign = - SmfCampaignList::instance()->get(ccbUtilOperationData->param.modify.objectName); - if (campaign == NULL) { - LOG_NO("Campaign %s not found, can't be modified", - ccbUtilOperationData->param.modify.objectName->value); - rc = SA_AIS_ERR_BAD_OPERATION; - goto done; - } - - if (campaign->executing() == true) { - LOG_NO("Campaign %s in state %u, can't be modified", - ccbUtilOperationData->param.modify.objectName->value, - campaign->getState()); + for (objit = objectList.begin(); objit != objectList.end(); ++objit) { + std::string::size_type pos2 = (*objit).find(","); + if (pos2 == std::string::npos) { + + LOG_NO("saImmOiCcbCompletedCallback:: Could not find separator \",\" + in %s", (*objit).c_str()); rc = SA_AIS_ERR_BAD_OPERATION; goto done; } - else if ((SmfCampaignThread::instance() != NULL) && - (SmfCampaignThread::instance()->campaign() == campaign)) { - /* Campaign is executing prereq tests (in state INITIAL) */ - LOG_NO("Campaign %s is executing, can't be modified", - ccbUtilOperationData->param.modify.objectName->value); + std::string swBundleInstalled = (*objit).substr(pos1, pos2 - pos1); + if (swBundleInstalled.size() == 0) { + + LOG_NO("saImmOiCcbCompletedCallback:: Could not find installed bundle + from %s", (*objit).c_str()); rc = SA_AIS_ERR_BAD_OPERATION; goto done; } - rc = campaign->verify(ccbUtilOperationData->param.modify.attrMods); - if (rc != SA_AIS_OK) { - LOG_NO("Campaign %s attribute modification fail, wrong parameter content", - ccbUtilOperationData->param.modify.objectName->value); - goto done; - } - //Handle the OpenSAFSmfConfig object - } else if (strncmp((char*)ccbUtilOperationData->param.modify.objectName->value, "smfConfig=", 10) == 0) { - //Modification of OpenSAFSmfConfig object is always allowed. - //The SMF control block structure is re-read at saImmOiCcbApplyCallback - TRACE("Modification of object %s", ccbUtilOperationData->param.modify.objectName->value); + if (swBundleInstalled == swBundleToRemove){ + LOG_NO("SwBundle %s is in use, can not be removed", swBundleToRemove.c_str()); + rc = SA_AIS_ERR_BAD_OPERATION; + goto done; + } + } + + goto done; + //Handle any unknown object + } else { + LOG_NO("Unknown object %s, can't be deleted", objToDelete.c_str()); + //Save the class name enum for use in later phases + ccbUtilOperationData->userData = + (void*)SMF_CLASS_UNKNOWN; + + rc = SA_AIS_ERR_BAD_OPERATION; + goto done; + } + break; + } + + case CCBUTIL_MODIFY: + { + //Get the DN to the object to modify and read the class name + std::string objToModify = (char + *)ccbUtilOperationData->param.modify.objectName->value; - //Handle the SaSmfSwBundle object - } else if (strncmp((char *)ccbUtilOperationData->param.modify.objectName->value, "safSmfBundle=", 13) == 0) { - //Always allow modification - TRACE("Modification of object %s", ccbUtilOperationData->param.modify.objectName->value); + std::string className; + if (immUtil.getClassNameForObject(objToModify, className) == false) { + LOG_NO("Failed to get class name for object to modify %s", objToModify.c_str()); + rc = SA_AIS_ERR_BAD_OPERATION; + goto done; + } - //Handle any unknown object - } else { - LOG_NO("Unknown object %s, can't be modified", - ccbUtilOperationData->param.modify.objectName->value); - rc = SA_AIS_ERR_BAD_OPERATION; - goto done; - } + //Handle the campaign object + if (className == campaignClassName) { + TRACE("Modify campaign %s", objToModify.c_str()); + //Save the class name enum for use in later phases + ccbUtilOperationData->userData = + (void*)SMF_CLASS_CAMPAIGN; - break; - } - } - ccbUtilOperationData = ccbUtilOperationData->next; + //Find Campaign object + SmfCampaign *campaign = + SmfCampaignList::instance()->get(ccbUtilOperationData->param.modify.objectName); //objToModify + if (campaign == NULL) { + LOG_NO("Campaign %s not found, can't be modified", objToModify.c_str()); + rc = SA_AIS_ERR_BAD_OPERATION; + goto done; + } + + if (campaign->executing() == true) { + LOG_NO("Campaign %s in state %u, can't be modified", + objToModify.c_str(), + campaign->getState()); + rc = SA_AIS_ERR_BAD_OPERATION; + goto done; + } else if ((SmfCampaignThread::instance() != NULL) && + (SmfCampaignThread::instance()->campaign() == campaign)) { + //Campaign is executing prereq tests (in state INITIAL) + LOG_NO("Campaign %s is executing, can't be modified", objToModify.c_str()); + rc = SA_AIS_ERR_BAD_OPERATION; + goto done; + } + + rc = campaign->verify(ccbUtilOperationData->param.modify.attrMods); + if (rc != SA_AIS_OK) { + LOG_NO("Campaign %s attribute modification fail, wrong parameter content", objToModify.c_str()); + goto done; + } + + //Handle the OpenSAFSmfConfig object + } else if (className == smfConfigClassName){ + //Modification of OpenSAFSmfConfig object is always allowed. + //The SMF control block structure is re-read at saImmOiCcbApplyCallback + TRACE("Modification of object %s", objToModify.c_str()); + //Save the class name enum for use in later phases + ccbUtilOperationData->userData = + (void*)SMF_CLASS_CONFIG; + + //Handle the SaSmfSwBundle object + } else if (className == smfSwBundleClassName){ + //Always allow modification + TRACE("Modification of object %s", objToModify.c_str()); + //Save the class name enum for use in later phases + ccbUtilOperationData->userData = + (void*)SMF_CLASS_BUNDLE; + + //Handle any unknown object + } else { + LOG_NO("Unknown object %s, can't be modified" ,objToModify.c_str()); + //Save the class name enum for use in later phases + ccbUtilOperationData->userData = (void*)SMF_CLASS_UNKNOWN; + rc = SA_AIS_ERR_BAD_OPERATION; + goto done; + } + + break; + } + } + ccbUtilOperationData = ccbUtilOperationData->next; } - done: +done: TRACE_LEAVE(); return rc; } @@ -374,6 +421,7 @@ static void saImmOiCcbApplyCallback(SaIm struct CcbUtilCcbData *ccbUtilCcbData; struct CcbUtilOperationData *ccbUtilOperationData; bool openSAFSmfConfigApply = false; + SmfImmUtils immUtil; TRACE_ENTER(); @@ -388,7 +436,7 @@ static void saImmOiCcbApplyCallback(SaIm case CCBUTIL_CREATE: { //Handle the campaign object - if (strcmp(ccbUtilOperationData->param.create.className, campaignClassName) == 0) { + if ((long)ccbUtilOperationData->userData == + SMF_CLASS_CAMPAIGN) { SmfCampaign *newCampaign = new SmfCampaign(ccbUtilOperationData->param.create.parentName, ccbUtilOperationData->param.create.attrValues); @@ -401,8 +449,9 @@ static void saImmOiCcbApplyCallback(SaIm case CCBUTIL_DELETE: { - if (strncmp((char *)ccbUtilOperationData->param.deleteOp.objectName->value, "safSmfCampaign=", 15) == 0) { - TRACE("Deleting campaign %s", ccbUtilOperationData->param.deleteOp.objectName->value); + //Handle the campaign object + if ((long)ccbUtilOperationData->userData == SMF_CLASS_CAMPAIGN) { + TRACE("Deleting campaign %s", +(char*)ccbUtilOperationData->param.deleteOp.objectName->value); SmfCampaignList::instance()->del(ccbUtilOperationData->param.deleteOp.objectName); } break; @@ -411,23 +460,22 @@ static void saImmOiCcbApplyCallback(SaIm case CCBUTIL_MODIFY: { //Handle the campaign object - if (strncmp((char *)ccbUtilOperationData->param.modify.objectName->value, "safSmfCampaign=", 15) == 0) { - TRACE("Modifying campaign %s", ccbUtilOperationData->param.modify.objectName->value); + if ((long)ccbUtilOperationData->userData == SMF_CLASS_CAMPAIGN) { + TRACE("Modifying campaign %s", +(char*)ccbUtilOperationData->param.modify.objectName->value); /* Find Campaign object */ SmfCampaign *campaign = SmfCampaignList::instance()->get(ccbUtilOperationData->param.modify.objectName); if (campaign == NULL) { - LOG_NO("Campaign %s not found", - ccbUtilOperationData->param.modify.objectName->value); + LOG_NO("Campaign %s not found", (char +*)ccbUtilOperationData->param.modify.objectName->value); goto done; } campaign->modify(ccbUtilOperationData->param.modify.attrMods); //Handle the OpenSAFSmfConfig object - }else if (strncmp((char*)ccbUtilOperationData->param.modify.objectName->value, "smfConfig=", 10) == 0) { - TRACE("Modifying configuration object %s", ccbUtilOperationData->param.modify.objectName->value); + } else if ((long)ccbUtilOperationData->userData == SMF_CLASS_CONFIG){ + TRACE("Modifying configuration object %s", (char +*)ccbUtilOperationData->param.modify.objectName->value); openSAFSmfConfigApply = true; } break; ------------------------------------------------------------------------------ Learn Graph Databases - Download FREE O'Reilly Book "Graph Databases" is the definitive new guide to graph databases and their applications. Written by three acclaimed leaders in the field, this first edition is now available. Download your free book today! http://p.sf.net/sfu/13534_NeoTech _______________________________________________ Opensaf-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/opensaf-devel
