diff --git a/include/ImageTemplate.h b/include/ImageTemplate.h index 7749ae71ff..7a9e116a62 100644 --- a/include/ImageTemplate.h +++ b/include/ImageTemplate.h @@ -33,32 +33,6 @@ public: ~ImageTemplate(){}; - /** - * Checks the template for RESTRICTED ATTRIBUTES - * @param rs_attr the first restricted attribute found if any - * @return true if a restricted attribute is found in the template - */ - bool check(string& rs_attr) - { - return Template::check(rs_attr, restricted_attributes); - }; - - /** - * Deletes all restricted attributes - */ - void remove_restricted() - { - Template::remove_restricted(restricted_attributes); - }; - - /** - * Deletes all the attributes, except the restricted ones - */ - void remove_all_except_restricted() - { - Template::remove_all_except_restricted(restricted_attributes); - }; - bool is_saving() { bool save_as_hot; @@ -73,25 +47,29 @@ public: replace("SAVE_AS_HOT", "YES"); } + // ------------------------------------------------------------------------- + // Restricted attributes interface implementation + // ------------------------------------------------------------------------- + virtual bool check_restricted(string& rs_attr, const Template* base) + { + return Template::check_restricted(rs_attr, base, restricted); + } + + virtual bool check_restricted(string& rs_attr) + { + return Template::check_restricted(rs_attr, restricted); + } + + static void parse_restricted(vector& ra) + { + Template::parse_restricted(ra, restricted); + } + private: - friend class ImagePool; - - static vector restricted_attributes; - - bool has_restricted() - { - return restricted_attributes.size() > 0; - }; - /** - * Stores the attributes as restricted, these attributes will be used in - * ImageTemplate::check - * @param rattrs Attributes to restrict + * Restricted attribute list for ImageTemplates */ - static void set_restricted_attributes(vector& rattrs) - { - Template::set_restricted_attributes(rattrs, restricted_attributes); - }; + static std::map > restricted; }; /* -------------------------------------------------------------------------- */ diff --git a/include/Template.h b/include/Template.h index 33c8416cb0..8b155e4d68 100644 --- a/include/Template.h +++ b/include/Template.h @@ -19,7 +19,9 @@ #include #include +#include #include +#include #include #include @@ -55,8 +57,6 @@ public: separator = t.separator; xml_root = t.xml_root; - attributes.clear(); - for (it = t.attributes.begin() ; it != t.attributes.end() ; it++) { attributes.insert(make_pair(it->first,(it->second)->clone())); @@ -404,39 +404,47 @@ public: /** * Merges another Template, adding the new attributes and * replacing the existing ones - * * @param from_tmpl the template to be merged */ void merge(const Template * from_tmpl); - /** - * Deletes all restricted attributes - */ - virtual void remove_restricted(); + /** + * Check if the template can be safely merge with a base template. If a + * restricted attribute is found it is check that it has the same value in + * base. + * @param rs_attr the first restricted attribute found with a different + * value in base + * @param base template used to check restricted values. + * + * @return true if a restricted attribute with a different value is found + * in the template + * + * The version of this method without base template just look for any + * restricted attribute. + */ + virtual bool check_restricted(string& rs_attr, const Template* base) + { + return false; + } - /** - * Deletes all the attributes, except the restricted ones - */ - virtual void remove_all_except_restricted(); + virtual bool check_restricted(string& rs_attr) + { + return false; + } - /** - * @return true if the template defines one or more restricted attributes - */ - virtual bool has_restricted(); - - /** - * @return true if template is empty - */ - bool empty() - { - return attributes.empty(); - } + /** + * @return true if template is empty + */ + bool empty() + { + return attributes.empty(); + } protected: /** * The template attributes */ - multimap attributes; + multimap attributes; /** * Builds a SingleAttribute from the given node @@ -455,32 +463,37 @@ protected: Attribute* vector_xml_att(const xmlNode * node); /** - * Stores the attributes as restricted, these attributes will be used in - * Template::check - * @param rattrs Attributes to restrict - * @param restricted_attributes The attributes will be stored here + * Parses a list of restricted attributes in the form ATTRIBUTE_NAME or + * ATTRIBUTE_NAME/SUBATTRIBUTE. + * @param ras list of restricted attributes + * @param rattr_m result list of attributes indexed by ATTRIBUTE_NAME. + * RAs are stored: + * { + * RESTRICTED_ATTR_NAME => [ RESTRICTED_SUB_ATTRIBUTES ], + * ... + * } + * If the RA is Single the sub attribute list will be empty. */ - static void set_restricted_attributes( - vector& rattrs, - vector& restricted_attributes); + static void parse_restricted(const vector& ras, + std::map >& rattr_m); /** - * Checks the template for RESTRICTED ATTRIBUTES - * @param rs_attr the first restricted attribute found if any - * @return true if a restricted attribute is found in the template + * Check if the template can be safely merge with a base template. If a + * restricted attribute is found it is check that it has the same value in + * base. + * @param rs_attr the first restricted attribute found with a different + * value in base + * @param base template used to check restricted values. + * @param ras list of restricted attributes. + * + * @return true if a restricted attribute with a different value is found + * in the template */ - bool check(string& rs_attr, const vector &restricted_attributes); - - /** - * Deletes all restricted attributes - */ - void remove_restricted(const vector &restricted_attributes); - - /** - * Deletes all the attributes, except the restricted ones - */ - void remove_all_except_restricted(const vector &restricted_attributes); + bool check_restricted(string& rs_attr, const Template* base, + const std::map >& ras); + bool check_restricted(string& rs_attr, + const std::map >& ras); /** * Updates the xml root element name * diff --git a/include/VirtualMachineTemplate.h b/include/VirtualMachineTemplate.h index eb1bba36b8..8c21190c03 100644 --- a/include/VirtualMachineTemplate.h +++ b/include/VirtualMachineTemplate.h @@ -29,8 +29,7 @@ using namespace std; class VirtualMachineTemplate : public Template { public: - VirtualMachineTemplate(): - Template(false,'=',"TEMPLATE"){}; + VirtualMachineTemplate():Template(false,'=',"TEMPLATE"){}; VirtualMachineTemplate( bool _replace_mode, @@ -42,32 +41,6 @@ public: VirtualMachineTemplate(VirtualMachineTemplate& vmt):Template(vmt){}; - /** - * Checks the template for RESTRICTED ATTRIBUTES - * @param rs_attr the first restricted attribute found if any - * @return true if a restricted attribute is found in the template - */ - bool check(string& rs_attr) - { - return Template::check(rs_attr, restricted_attributes); - }; - - /** - * Deletes all restricted attributes - */ - void remove_restricted() - { - Template::remove_restricted(restricted_attributes); - }; - - /** - * Deletes all the attributes, except the restricted ones - */ - void remove_all_except_restricted() - { - Template::remove_all_except_restricted(restricted_attributes); - }; - void set_xml_root(const char * _xml_root) { Template::set_xml_root(_xml_root); @@ -85,26 +58,29 @@ public: target_name, const string& target_uname, const string& new_name, const string& new_uname); + // ------------------------------------------------------------------------- + // Restricted attributes interface implementation + // ------------------------------------------------------------------------- + virtual bool check_restricted(string& rs_attr, const Template* base) + { + return Template::check_restricted(rs_attr, base, restricted); + } + + virtual bool check_restricted(string& rs_attr) + { + return Template::check_restricted(rs_attr, restricted); + } + + static void parse_restricted(vector& ra) + { + Template::parse_restricted(ra, restricted); + } + private: - - friend class VirtualMachinePool; - - static vector restricted_attributes; - - bool has_restricted() - { - return restricted_attributes.size() > 0; - }; - /** - * Stores the attributes as restricted, these attributes will be used in - * VirtualMachineTemplate::check - * @param rattrs Attributes to restrict + * Restricted attribute list for VirtualMachineTemplates */ - static void set_restricted_attributes(vector& rattrs) - { - Template::set_restricted_attributes(rattrs, restricted_attributes); - }; + static std::map > restricted; }; /* -------------------------------------------------------------------------- */ diff --git a/include/VirtualNetworkTemplate.h b/include/VirtualNetworkTemplate.h index 47b135c466..05a8e1cf8f 100644 --- a/include/VirtualNetworkTemplate.h +++ b/include/VirtualNetworkTemplate.h @@ -27,57 +27,33 @@ using namespace std; class VirtualNetworkTemplate : public Template { public: - VirtualNetworkTemplate(): - Template(false,'=',"TEMPLATE"){}; + VirtualNetworkTemplate():Template(false,'=',"TEMPLATE"){}; ~VirtualNetworkTemplate(){}; - /** - * Checks the template for RESTRICTED ATTRIBUTES - * @param rs_attr the first restricted attribute found if any - * @return true if a restricted attribute is found in the template - */ - bool check(string& rs_attr) + // ------------------------------------------------------------------------- + // Restricted attributes interface implementation + // ------------------------------------------------------------------------- + virtual bool check_restricted(string& rs_attr, const Template* base) { - return Template::check(rs_attr, restricted_attributes); - }; + return Template::check_restricted(rs_attr, base, restricted); + } - /** - * Deletes all restricted attributes - */ - void remove_restricted() + virtual bool check_restricted(string& rs_attr) { - Template::remove_restricted(restricted_attributes); - }; + return Template::check_restricted(rs_attr, restricted); + } - /** - * Deletes all the attributes, except the restricted ones - */ - void remove_all_except_restricted() + static void parse_restricted(vector& ra) { - Template::remove_all_except_restricted(restricted_attributes); - }; + Template::parse_restricted(ra, restricted); + } private: - - friend class VirtualNetworkPool; - - static vector restricted_attributes; - - bool has_restricted() - { - return restricted_attributes.size() > 0; - }; - /** - * Stores the attributes as restricted, these attributes will be used in - * VirtualMachineTemplate::check - * @param rattrs Attributes to restrict + * Restricted attribute list for VirtualNetworkTemplates */ - static void set_restricted_attributes(vector& rattrs) - { - Template::set_restricted_attributes(rattrs, restricted_attributes); - }; + static std::map > restricted; }; /* -------------------------------------------------------------------------- */ diff --git a/share/etc/oned.conf b/share/etc/oned.conf index c3e7ff164a..72fa1459b2 100644 --- a/share/etc/oned.conf +++ b/share/etc/oned.conf @@ -897,31 +897,31 @@ VM_RESTRICTED_ATTR = "CONTEXT/FILES" VM_RESTRICTED_ATTR = "NIC/MAC" VM_RESTRICTED_ATTR = "NIC/VLAN_ID" VM_RESTRICTED_ATTR = "NIC/BRIDGE" -#VM_RESTRICTED_ATTR = "NIC/INBOUND_AVG_BW" -#VM_RESTRICTED_ATTR = "NIC/INBOUND_PEAK_BW" -#VM_RESTRICTED_ATTR = "NIC/INBOUND_PEAK_KB" -#VM_RESTRICTED_ATTR = "NIC/OUTBOUND_AVG_BW" -#VM_RESTRICTED_ATTR = "NIC/OUTBOUND_PEAK_BW" -#VM_RESTRICTED_ATTR = "NIC/OUTBOUND_PEAK_KB" -#VM_RESTRICTED_ATTR = "NIC/OPENNEBULA_MANAGED" -#VM_RESTRICTED_ATTR = "NIC/VCENTER_INSTANCE_ID" -#VM_RESTRICTED_ATTR = "NIC/VCENTER_NET_REF" -#VM_RESTRICTED_ATTR = "NIC/VCENTER_PORTGROUP_TYPE" +VM_RESTRICTED_ATTR = "NIC/INBOUND_AVG_BW" +VM_RESTRICTED_ATTR = "NIC/INBOUND_PEAK_BW" +VM_RESTRICTED_ATTR = "NIC/INBOUND_PEAK_KB" +VM_RESTRICTED_ATTR = "NIC/OUTBOUND_AVG_BW" +VM_RESTRICTED_ATTR = "NIC/OUTBOUND_PEAK_BW" +VM_RESTRICTED_ATTR = "NIC/OUTBOUND_PEAK_KB" +VM_RESTRICTED_ATTR = "NIC/OPENNEBULA_MANAGED" +VM_RESTRICTED_ATTR = "NIC/VCENTER_INSTANCE_ID" +VM_RESTRICTED_ATTR = "NIC/VCENTER_NET_REF" +VM_RESTRICTED_ATTR = "NIC/VCENTER_PORTGROUP_TYPE" VM_RESTRICTED_ATTR = "NIC_DEFAULT/MAC" VM_RESTRICTED_ATTR = "NIC_DEFAULT/VLAN_ID" VM_RESTRICTED_ATTR = "NIC_DEFAULT/BRIDGE" -#VM_RESTRICTED_ATTR = "DISK/TOTAL_BYTES_SEC" -#VM_RESTRICTED_ATTR = "DISK/READ_BYTES_SEC" -#VM_RESTRICTED_ATTR = "DISK/WRITE_BYTES_SEC" -#VM_RESTRICTED_ATTR = "DISK/TOTAL_IOPS_SEC" -#VM_RESTRICTED_ATTR = "DISK/READ_IOPS_SEC" -#VM_RESTRICTED_ATTR = "DISK/WRITE_IOPS_SEC" -#VM_RESTRICTED_ATTR = "DISK/OPENNEBULA_MANAGED" -#VM_RESTRICTED_ATTR = "DISK/VCENTER_DS_REF" -#VM_RESTRICTED_ATTR = "DISK/VCENTER_INSTANCE_ID" +VM_RESTRICTED_ATTR = "DISK/TOTAL_BYTES_SEC" +VM_RESTRICTED_ATTR = "DISK/READ_BYTES_SEC" +VM_RESTRICTED_ATTR = "DISK/WRITE_BYTES_SEC" +VM_RESTRICTED_ATTR = "DISK/TOTAL_IOPS_SEC" +VM_RESTRICTED_ATTR = "DISK/READ_IOPS_SEC" +VM_RESTRICTED_ATTR = "DISK/WRITE_IOPS_SEC" +VM_RESTRICTED_ATTR = "DISK/OPENNEBULA_MANAGED" +VM_RESTRICTED_ATTR = "DISK/VCENTER_DS_REF" +VM_RESTRICTED_ATTR = "DISK/VCENTER_INSTANCE_ID" #VM_RESTRICTED_ATTR = "DISK/SIZE" -#VM_RESTRICTED_ATTR = "DISK/ORIGINAL_SIZE" -#VM_RESTRICTED_ATTR = "DISK/SIZE_PREV" +VM_RESTRICTED_ATTR = "DISK/ORIGINAL_SIZE" +VM_RESTRICTED_ATTR = "DISK/SIZE_PREV" VM_RESTRICTED_ATTR = "CPU_COST" VM_RESTRICTED_ATTR = "MEMORY_COST" VM_RESTRICTED_ATTR = "DISK_COST" @@ -929,10 +929,10 @@ VM_RESTRICTED_ATTR = "PCI" VM_RESTRICTED_ATTR = "EMULATOR" VM_RESTRICTED_ATTR = "RAW" VM_RESTRICTED_ATTR = "USER_PRIORITY" -#VM_RESTRICTED_ATTR = "USER_INPUTS/CPU" -#VM_RESTRICTED_ATTR = "USER_INPUTS/MEMORY" -#VM_RESTRICTED_ATTR = "USER_INPUTS/VCPU" -#VM_RESTRICTED_ATTR = "TEMPLATE/VCENTER_VM_FOLDER" +VM_RESTRICTED_ATTR = "USER_INPUTS/CPU" +VM_RESTRICTED_ATTR = "USER_INPUTS/MEMORY" +VM_RESTRICTED_ATTR = "USER_INPUTS/VCPU" +VM_RESTRICTED_ATTR = "VCENTER_VM_FOLDER" #VM_RESTRICTED_ATTR = "RANK" #VM_RESTRICTED_ATTR = "SCHED_RANK" @@ -940,7 +940,7 @@ VM_RESTRICTED_ATTR = "USER_PRIORITY" #VM_RESTRICTED_ATTR = "SCHED_REQUIREMENTS" IMAGE_RESTRICTED_ATTR = "SOURCE" -#IMAGE_RESTRICTED_ATTR = "TEMPLATE/VCENTER_IMPORTED" +IMAGE_RESTRICTED_ATTR = "VCENTER_IMPORTED" #******************************************************************************* # The following restricted attributes only apply to VNets that are a reservation. diff --git a/src/image/ImagePool.cc b/src/image/ImagePool.cc index f57f3eab53..346929ad70 100644 --- a/src/image/ImagePool.cc +++ b/src/image/ImagePool.cc @@ -67,7 +67,7 @@ ImagePool::ImagePool( _default_type = "OS"; } - ImageTemplate::set_restricted_attributes(restricted_attrs); + ImageTemplate::parse_restricted(restricted_attrs); register_hooks(hook_mads, remotes_location); } diff --git a/src/image/ImageTemplate.cc b/src/image/ImageTemplate.cc index 2bcf649c63..a22fc561d1 100644 --- a/src/image/ImageTemplate.cc +++ b/src/image/ImageTemplate.cc @@ -19,7 +19,7 @@ /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -vector ImageTemplate::restricted_attributes; +std::map > ImageTemplate::restricted; /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ diff --git a/src/pool/PoolObjectSQL.cc b/src/pool/PoolObjectSQL.cc index 75b2e287d5..cce38bf2c4 100644 --- a/src/pool/PoolObjectSQL.cc +++ b/src/pool/PoolObjectSQL.cc @@ -172,6 +172,8 @@ void PoolObjectSQL::clear_template_error_message() int PoolObjectSQL::replace_template( const string& tmpl_str, bool keep_restricted, string& error) { + string ra; + Template * old_tmpl = 0; Template * new_tmpl = get_new_template(); @@ -189,19 +191,22 @@ int PoolObjectSQL::replace_template( if (obj_template != 0) { + if ( keep_restricted && new_tmpl->check_restricted(ra, obj_template) ) + { + error = "Tried to change restricted attribute: " + ra; + + delete new_tmpl; + return -1; + } + old_tmpl = new Template(*obj_template); } - - if (keep_restricted && new_tmpl->has_restricted()) + else if ( keep_restricted && new_tmpl->check_restricted(ra) ) { - new_tmpl->remove_restricted(); + error = "Tried to set restricted attribute: " + ra; - if (obj_template != 0) - { - obj_template->remove_all_except_restricted(); - - new_tmpl->merge(obj_template); - } + delete new_tmpl; + return -1; } delete obj_template; @@ -237,6 +242,7 @@ int PoolObjectSQL::append_template( { Template * old_tmpl = 0; Template * new_tmpl = get_new_template(); + string rname; if ( new_tmpl == 0 ) { @@ -250,21 +256,26 @@ int PoolObjectSQL::append_template( return -1; } - if (keep_restricted) - { - new_tmpl->remove_restricted(); - } - if ( obj_template != 0 ) { - old_tmpl = new Template(*obj_template); - + if (keep_restricted && new_tmpl->check_restricted(rname, obj_template)) + { + error ="User Template includes a restricted attribute " + rname; + delete new_tmpl; + return -1; + } obj_template->merge(new_tmpl); delete new_tmpl; } else { + if (keep_restricted && new_tmpl->check_restricted(rname)) + { + error ="User Template includes a restricted attribute " + rname; + delete new_tmpl; + return -1; + } obj_template = new_tmpl; } diff --git a/src/rm/RequestManagerAllocate.cc b/src/rm/RequestManagerAllocate.cc index e4b58d46f4..ec03ea1f28 100644 --- a/src/rm/RequestManagerAllocate.cc +++ b/src/rm/RequestManagerAllocate.cc @@ -87,7 +87,7 @@ bool VirtualMachineAllocate::allocate_authorization( if ( att.uid != 0 && att.gid != GroupPool::ONEADMIN_ID ) { - if (ttmpl->check(aname)) + if (ttmpl->check_restricted(aname)) { att.resp_msg = "VM Template includes a restricted attribute "+aname; failure_response(AUTHORIZATION, att); @@ -513,9 +513,10 @@ void ImageAllocate::request_execute(xmlrpc_c::paramList const& params, // ------------ Check template for restricted attributes -------------- - if ( att.uid != UserPool::ONEADMIN_ID && att.gid != GroupPool::ONEADMIN_ID ) + if ( att.uid != UserPool::ONEADMIN_ID && + att.gid != GroupPool::ONEADMIN_ID ) { - if (tmpl->check(aname)) + if (tmpl->check_restricted(aname)) { att.resp_msg = "Template includes a restricted attribute "+aname; failure_response(AUTHORIZATION, att); @@ -528,7 +529,7 @@ void ImageAllocate::request_execute(xmlrpc_c::paramList const& params, // ------------------ Check permissions and ACLs ---------------------- tmpl->to_xml(tmpl_str); - ar.add_create_auth(att.uid, att.gid, auth_object, tmpl_str); // CREATE IMAGE + ar.add_create_auth(att.uid, att.gid, auth_object, tmpl_str); ar.add_auth(AuthRequest::USE, ds_perms); // USE DATASTORE @@ -649,7 +650,7 @@ bool TemplateAllocate::allocate_authorization( VirtualMachineTemplate * ttmpl = static_cast(tmpl); // ------------ Check template for restricted attributes ------------------- - if (ttmpl->check(aname)) + if (ttmpl->check_restricted(aname)) { att.resp_msg = "VM Template includes a restricted attribute " + aname; diff --git a/src/rm/RequestManagerVMTemplate.cc b/src/rm/RequestManagerVMTemplate.cc index fd40a301ba..68b854a8fb 100644 --- a/src/rm/RequestManagerVMTemplate.cc +++ b/src/rm/RequestManagerVMTemplate.cc @@ -274,7 +274,7 @@ Request::ErrorCode VMTemplateInstantiate::merge( if (att.uid!=UserPool::ONEADMIN_ID && att.gid!=GroupPool::ONEADMIN_ID) { - if (uattrs.check(aname)) + if (uattrs.check_restricted(aname, tmpl)) { att.resp_msg ="User Template includes a restricted attribute " + aname; diff --git a/src/rm/RequestManagerVirtualMachine.cc b/src/rm/RequestManagerVirtualMachine.cc index 7d049a08d6..9aa69cade2 100644 --- a/src/rm/RequestManagerVirtualMachine.cc +++ b/src/rm/RequestManagerVirtualMachine.cc @@ -69,7 +69,8 @@ bool RequestManagerVirtualMachine::vm_authorization( { string t_xml; - ar.add_create_auth(att.uid, att.gid, PoolObjectSQL::IMAGE, tmpl->to_xml(t_xml)); + ar.add_create_auth(att.uid, att.gid, PoolObjectSQL::IMAGE, + tmpl->to_xml(t_xml)); } if ( vtmpl != 0 ) @@ -1836,7 +1837,7 @@ void VirtualMachineResize::request_execute(xmlrpc_c::paramList const& paramList, { string aname; - if (tmpl.check(aname)) + if (tmpl.check_restricted(aname)) { att.resp_msg = "Template includes a restricted attribute " + aname; failure_response(AUTHORIZATION, att); @@ -1911,7 +1912,9 @@ void VirtualMachineResize::request_execute(xmlrpc_c::paramList const& paramList, case VirtualMachine::DONE: case VirtualMachine::SUSPENDED: case VirtualMachine::ACTIVE: - att.resp_msg="Resize action is not available for state "+vm->state_str(); + att.resp_msg="Resize action is not available for state " + + vm->state_str(); + failure_response(ACTION, att); vm->unlock(); @@ -2043,7 +2046,9 @@ void VirtualMachineResize::request_execute(xmlrpc_c::paramList const& paramList, case VirtualMachine::DONE: case VirtualMachine::SUSPENDED: case VirtualMachine::ACTIVE: - att.resp_msg = "Resize action is not available for state " + vm->state_str(); + att.resp_msg = "Resize action is not available for state " + + vm->state_str(); + failure_response(ACTION, att); vm->unlock(); @@ -2299,14 +2304,15 @@ Request::ErrorCode VirtualMachineAttachNic::request_execute(int id, { string aname; - if (tmpl.check(aname)) + if (tmpl.check_restricted(aname)) { att.resp_msg = "NIC includes a restricted attribute " + aname; return AUTHORIZATION; } } - if (quota_authorization(&tmpl, Quotas::NETWORK, att_quota, att.resp_msg) == false) + if (quota_authorization(&tmpl, Quotas::NETWORK, att_quota, + att.resp_msg) == false) { return AUTHORIZATION; } @@ -2893,7 +2899,7 @@ void VirtualMachineUpdateConf::request_execute( { string aname; - if (tmpl.check(aname)) + if (tmpl.check_restricted(aname)) { att.resp_msg = "Template includes a restricted attribute " + aname; failure_response(AUTHORIZATION, att); diff --git a/src/template/Template.cc b/src/template/Template.cc index 785eb09dc9..e51d79f6d9 100644 --- a/src/template/Template.cc +++ b/src/template/Template.cc @@ -331,7 +331,6 @@ int Template::erase(const string& name) attributes.erase(index.first,index.second); return j; - } /* -------------------------------------------------------------------------- */ @@ -587,24 +586,6 @@ int Template::from_xml_node(const xmlNodePtr node) /* ------------------------------------------------------------------------ */ /* ------------------------------------------------------------------------ */ -void Template::merge(const Template * from_tmpl) -{ - multimap::const_iterator it; - - for (it = from_tmpl->attributes.begin(); it != from_tmpl->attributes.end(); ++it) - { - this->erase(it->first); - } - - for (it = from_tmpl->attributes.begin(); it != from_tmpl->attributes.end(); ++it) - { - this->set(it->second->clone()); - } -} - -/* ------------------------------------------------------------------------ */ -/* ------------------------------------------------------------------------ */ - void Template::rebuild_attributes(const xmlNode * root_element) { xmlNode * cur_node = 0; @@ -639,241 +620,6 @@ void Template::rebuild_attributes(const xmlNode * root_element) /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -void Template::set_restricted_attributes(vector& rattrs, - vector& restricted_attributes) -{ - for (unsigned int i = 0 ; i < rattrs.size() ; i++ ) - { - string va = rattrs[i]->value(); - restricted_attributes.push_back(one_util::toupper(va)); - } -} - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - -static int get_attributes( - multimap& attributes, - const string& name, vector& values) -{ - multimap::const_iterator i; - pair::const_iterator, - multimap::const_iterator> index; - int j; - - index = attributes.equal_range(name); - - for ( i = index.first,j=0 ; i != index.second ; i++,j++ ) - { - values.push_back(i->second); - } - - return j; -} - -bool Template::check(string& rs_attr, const vector &restricted_attributes) -{ - size_t pos; - string avector, vattr; - vector values; - - for (unsigned int i=0; i < restricted_attributes.size(); i++) - { - pos = restricted_attributes[i].find("/"); - - if (pos != string::npos) //Vector Attribute - { - int num; - - avector = restricted_attributes[i].substr(0,pos); - vattr = restricted_attributes[i].substr(pos+1); - - //Template contains the attr - if ((num = get_attributes(attributes, avector, values)) > 0 ) - { - const VectorAttribute * attr; - - for (int j=0; j(values[j]); - - if (attr == 0) - { - continue; - } - - if ( !attr->vector_value(vattr.c_str()).empty() ) - { - rs_attr = restricted_attributes[i]; - return true; - } - } - } - } - else //Single Attribute - { - if (get_attributes(attributes, restricted_attributes[i], values) > 0) - { - rs_attr = restricted_attributes[i]; - return true; - } - } - } - - return false; -} - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - -void Template::remove_restricted() -{} - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - -void Template::remove_all_except_restricted() -{} - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - -bool Template::has_restricted() -{ - return false; -} - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - -static int get_attributes( - multimap& attributes, - const string& name, vector& values) -{ - multimap::iterator i; - pair::iterator, - multimap::iterator> index; - int j; - - index = attributes.equal_range(name); - - for ( i = index.first,j=0 ; i != index.second ; i++,j++ ) - { - values.push_back(i->second); - } - - return j; -} - -void Template::remove_restricted(const vector &restricted_attributes) -{ - size_t pos; - string avector, vattr; - vector values; - - for (unsigned int i=0; i < restricted_attributes.size(); i++) - { - pos = restricted_attributes[i].find("/"); - - if (pos != string::npos) //Vector Attribute - { - int num; - - avector = restricted_attributes[i].substr(0,pos); - vattr = restricted_attributes[i].substr(pos+1); - - //Template contains the attr - if ((num = get_attributes(attributes, avector,values)) > 0 ) - { - VectorAttribute * attr; - - for (int j=0; j(values[j]); - - if (attr == 0) - { - continue; - } - - attr->remove(vattr); - } - } - } - else //Single Attribute - { - erase(restricted_attributes[i]); - } - } -} - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - -void Template::remove_all_except_restricted(const vector &restricted_attributes) -{ - size_t pos; - string avector, vattr; - vector values; - - vector restricted; - - for (unsigned int i=0; i < restricted_attributes.size(); i++) - { - pos = restricted_attributes[i].find("/"); - - if (pos != string::npos) //Vector Attribute - { - int num; - - avector = restricted_attributes[i].substr(0,pos); - vattr = restricted_attributes[i].substr(pos+1); - - //Template contains the attr - if ((num = get_attributes(attributes, avector,values)) > 0 ) - { - VectorAttribute * attr; - - for (int j=0; j(values[j]); - - if (attr == 0) - { - continue; - } - - if ( !attr->vector_value(vattr.c_str()).empty() ) - { - restricted.push_back(attr); - } - } - } - } - else //Single Attribute - { - get_attributes(attributes, restricted_attributes[i], restricted); - } - } - - vector::iterator res_it; - - for (res_it = restricted.begin(); res_it != restricted.end(); res_it++) - { - remove(*res_it); - } - - clear(); - - for (res_it = restricted.begin(); res_it != restricted.end(); res_it++) - { - set(*res_it); - } -} - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - void Template::clear() { if (attributes.empty()) @@ -891,3 +637,177 @@ void Template::clear() attributes.clear(); } + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ +/* RESTRICTED ATTRIBUTES INTERFACE */ +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +void Template::merge(const Template * from) +{ + multimap::const_iterator it, jt; + + for (it = from->attributes.begin(); it != from->attributes.end(); ++it) + { + erase(it->first); + } + + for (it = from->attributes.begin(); it != from->attributes.end(); ++it) + { + set(it->second->clone()); + } +} + +/* ------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------ */ + +void Template::parse_restricted(const vector& ras, + std::map >& ras_m) +{ + vector::const_iterator it; + + for (it = ras.begin(); it != ras.end(); ++it) + { + string va = (*it)->value(); + size_t pos = va.find("/"); + + if (pos != string::npos) //Vector Attribute + { + string avector = va.substr(0,pos); + string vattr = va.substr(pos+1); + + map >::iterator jt; + + jt = ras_m.find(avector); + + if ( jt == ras_m.end() ) + { + std::set aset; + + aset.insert(vattr); + + ras_m.insert(make_pair(avector, aset)); + } + else + { + jt->second.insert(vattr); + } + } + else + { + std::set eset; + + ras_m.insert(make_pair(va, eset)); + } + } +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +static void restricted_values(const string& vname, const set& vsubs, + const Template* tmpl, vector& rstrings) +{ + string value; + + vector::const_iterator va_it; + vector va; + + tmpl->get(vname, va); + + for ( va_it = va.begin(); va_it != va.end() ; ++va_it ) + { + for (set::iterator jt = vsubs.begin(); jt != vsubs.end(); ++jt) + { + if ( (*va_it)->vector_value(*jt, value) == 0 ) + { + rstrings.push_back(*jt + value); + } + } + } + + sort(rstrings.begin(), rstrings.end()); +} + +bool Template::check_restricted(string& ra, const Template* base, + const std::map >& ras) +{ + std::map >::const_iterator rit; + + for ( rit = ras.begin(); rit != ras.end(); ++rit ) + { + if (!(rit->second).empty()) + { + vector rvalues, rvalues_base; + + restricted_values(rit->first, rit->second, this, rvalues); + restricted_values(rit->first, rit->second, base, rvalues_base); + + if ( rvalues != rvalues_base ) + { + ra = rit->first; + return true; + } + } + else + { + if ( get(rit->first, ra) ) + { + string ra_b; + + base->get(rit->first, ra_b); + + if ( ra_b != ra ) + { + return true; + } + } + } + } + + return false; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +bool Template::check_restricted(string& ra, + const std::map >& ras) +{ + std::map >::const_iterator rit; + + for ( rit = ras.begin(); rit != ras.end(); ++rit ) + { + const std::set& sub = rit->second; + + if (!sub.empty()) //Vector Attribute + { + // ----------------------------------------------------------------- + // ----------------------------------------------------------------- + std::set::iterator jt; + std::vector::iterator va_it; + + std::vector va; + + get(rit->first, va); + + for ( va_it = va.begin(); va_it != va.end() ; ++va_it ) + { + for ( jt = sub.begin(); jt != sub.end(); ++jt ) + { + if ( (*va_it)->vector_value(*jt, ra) == 0 ) + { + return true; + } + } + } + } + else if ( get(rit->first, ra) ) //Single Attribute + { + return true; + } + } + + return false; +} diff --git a/src/vm/VirtualMachine.cc b/src/vm/VirtualMachine.cc index c588171a46..367586e3b6 100644 --- a/src/vm/VirtualMachine.cc +++ b/src/vm/VirtualMachine.cc @@ -2223,6 +2223,8 @@ int VirtualMachine::replace_template( bool keep_restricted, string& error) { + string ra; + VirtualMachineTemplate * new_tmpl = new VirtualMachineTemplate(false,'=',"USER_TEMPLATE"); @@ -2238,17 +2240,23 @@ int VirtualMachine::replace_template( return -1; } - if (keep_restricted) + if (user_obj_template != 0) { - new_tmpl->remove_restricted(); - - if (user_obj_template != 0) + if (keep_restricted && new_tmpl->check_restricted(ra, user_obj_template)) { - user_obj_template->remove_all_except_restricted(); + error = "Tried to change restricted attribute: " + ra; - new_tmpl->merge(user_obj_template); + delete new_tmpl; + return -1; } } + else if (keep_restricted && new_tmpl->check_restricted(ra)) + { + error = "Tried to set restricted attribute: " + ra; + + delete new_tmpl; + return -1; + } delete user_obj_template; @@ -2267,6 +2275,7 @@ int VirtualMachine::append_template( { VirtualMachineTemplate * new_tmpl = new VirtualMachineTemplate(false,'=',"USER_TEMPLATE"); + string rname; if ( new_tmpl == 0 ) { @@ -2280,18 +2289,26 @@ int VirtualMachine::append_template( return -1; } - if (keep_restricted) - { - new_tmpl->remove_restricted(); - } - if (user_obj_template != 0) { + if (keep_restricted && new_tmpl->check_restricted(rname, user_obj_template)) + { + error ="User Template includes a restricted attribute " + rname; + delete new_tmpl; + return -1; + } user_obj_template->merge(new_tmpl); + delete new_tmpl; } else { + if (keep_restricted && new_tmpl->check_restricted(rname)) + { + error ="User Template includes a restricted attribute " + rname; + delete new_tmpl; + return -1; + } user_obj_template = new_tmpl; } diff --git a/src/vm/VirtualMachinePool.cc b/src/vm/VirtualMachinePool.cc index 6cb0660de8..973f0376fd 100644 --- a/src/vm/VirtualMachinePool.cc +++ b/src/vm/VirtualMachinePool.cc @@ -207,7 +207,7 @@ VirtualMachinePool::VirtualMachinePool( } // Set restricted attributes - VirtualMachineTemplate::set_restricted_attributes(restricted_attrs); + VirtualMachineTemplate::parse_restricted(restricted_attrs); } /* -------------------------------------------------------------------------- */ diff --git a/src/vm/VirtualMachineTemplate.cc b/src/vm/VirtualMachineTemplate.cc index 2dfaded14d..e3cfd49415 100644 --- a/src/vm/VirtualMachineTemplate.cc +++ b/src/vm/VirtualMachineTemplate.cc @@ -19,7 +19,7 @@ /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -vector VirtualMachineTemplate::restricted_attributes; +std::map > VirtualMachineTemplate::restricted; /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ diff --git a/src/vnm/VirtualNetworkPool.cc b/src/vnm/VirtualNetworkPool.cc index 34d4ca3e51..151da929d3 100644 --- a/src/vnm/VirtualNetworkPool.cc +++ b/src/vnm/VirtualNetworkPool.cc @@ -90,7 +90,8 @@ VirtualNetworkPool::VirtualNetworkPool( _mac_prefix <<= 8; _mac_prefix += tmp; - VirtualNetworkTemplate::set_restricted_attributes(restricted_attrs); + VirtualNetworkTemplate::parse_restricted(restricted_attrs); + AddressRange::set_restricted_attributes(restricted_attrs); register_hooks(hook_mads, remotes_location); diff --git a/src/vnm/VirtualNetworkTemplate.cc b/src/vnm/VirtualNetworkTemplate.cc index dd60829748..7d584f7337 100644 --- a/src/vnm/VirtualNetworkTemplate.cc +++ b/src/vnm/VirtualNetworkTemplate.cc @@ -19,7 +19,7 @@ /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -vector VirtualNetworkTemplate::restricted_attributes; +std::map > VirtualNetworkTemplate::restricted; /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */