diff --git a/include/Group.h b/include/Group.h index 5fbf6f9c09..2425b9570f 100644 --- a/include/Group.h +++ b/include/Group.h @@ -18,10 +18,12 @@ #define GROUP_H_ #include "PoolSQL.h" +#include "GroupTemplate.h" #include "ObjectCollection.h" #include "User.h" #include "QuotasSQL.h" #include "Template.h" +#include "VMActions.h" using namespace std; @@ -115,14 +117,14 @@ public: int update_quotas(SqlDB *db) { return quota.update(oid, db->get_local_db()); - }; + } /** * Factory method for Group templates */ Template * get_new_template() const override { - return new Template; + return new GroupTemplate; } /** @@ -137,6 +139,15 @@ public: void sunstone_views(const string& user_default, const string& user_views, const string& admin_default, const string& admin_views); + /** + * @return the operation level (admin, manage or use) associated to the + * given action for this group + */ + AuthRequest::Operation get_vm_auth_op(VMActions::Action action) const + { + return vm_actions.get_auth_op(action); + } + private: // ------------------------------------------------------------------------- @@ -158,8 +169,8 @@ private: // Allow users in this group to see it group_u = 1; - obj_template = new Template; - }; + obj_template = new GroupTemplate; + } virtual ~Group() = default; @@ -180,6 +191,11 @@ private: void add_admin_rules(int user_id); void del_admin_rules(int user_id); + /** + * List of VM actions and rights for this group + */ + VMActions vm_actions; + // ************************************************************************* // DataBase implementation (Private) // ************************************************************************* @@ -208,7 +224,7 @@ private: ostringstream oss_group(Group::db_bootstrap); return db->exec_local_wr(oss_group); - }; + } /** * Reads the Group (identified with its OID) from the database. @@ -258,7 +274,7 @@ private: { string error_str; return insert_replace(db, true, error_str); - }; + } /** * Function to print the Group object into a string in diff --git a/include/GroupPool.h b/include/GroupPool.h index 362a315ee4..0facab829f 100644 --- a/include/GroupPool.h +++ b/include/GroupPool.h @@ -27,9 +27,10 @@ class GroupPool : public PoolSQL { public: GroupPool(SqlDB * db, vector hook_mads, - const string& remotes_location, bool is_federation_slave); + const string& remotes_location, bool is_federation_slave, + vector& restricted_attrs); - ~GroupPool(){}; + ~GroupPool() = default; /* ---------------------------------------------------------------------- */ /* Constants for DB management */ diff --git a/include/GroupTemplate.h b/include/GroupTemplate.h new file mode 100644 index 0000000000..49df0aa84c --- /dev/null +++ b/include/GroupTemplate.h @@ -0,0 +1,60 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2019, OpenNebula Project, OpenNebula Systems */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); you may */ +/* not use this file except in compliance with the License. You may obtain */ +/* a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */ +/* See the License for the specific language governing permissions and */ +/* limitations under the License. */ +/* -------------------------------------------------------------------------- */ + +#ifndef GROUP_TEMPLATE_H_ +#define GROUP_TEMPLATE_H_ + +#include "Template.h" + +/** + * User Template class, it represents the attributes of an user + */ +class GroupTemplate : public Template +{ +public: + GroupTemplate() : Template(false, '=', "TEMPLATE") {} + + ~GroupTemplate() = default; + + // ------------------------------------------------------------------------- + // Restricted attributes interface implementation + // ------------------------------------------------------------------------- + bool check_restricted(string& rs_attr, const Template* base) override + { + return Template::check_restricted(rs_attr, base, restricted); + } + + bool check_restricted(string& rs_attr) override + { + return Template::check_restricted(rs_attr, restricted); + } + + static void parse_restricted(vector& ra) + { + Template::parse_restricted(ra, restricted); + } + +private: + /** + * Restricted attribute list for GroupTemplate + */ + static std::map> restricted; +}; + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +#endif /*GROUP_TEMPLATE_H_*/ diff --git a/include/History.h b/include/History.h index 3e45417d50..abd6dc3dad 100644 --- a/include/History.h +++ b/include/History.h @@ -19,6 +19,7 @@ #include "ObjectSQL.h" #include "ObjectXML.h" +#include "VMActions.h" using namespace std; @@ -29,65 +30,6 @@ using namespace std; class History:public ObjectSQL, public ObjectXML { public: - - enum VMAction - { //Associated XML-RPC API call - NONE_ACTION = 0, // "one.vm.migrate" - MIGRATE_ACTION = 1, // "one.vm.migrate" - LIVE_MIGRATE_ACTION = 2, - //SHUTDOWN_ACTION = 3, - //SHUTDOWN_HARD_ACTION = 4, - UNDEPLOY_ACTION = 5, // "one.vm.action" - UNDEPLOY_HARD_ACTION = 6, // "one.vm.action" - HOLD_ACTION = 7, // "one.vm.action" - RELEASE_ACTION = 8, // "one.vm.action" - STOP_ACTION = 9, // "one.vm.action" - SUSPEND_ACTION = 10, // "one.vm.action" - RESUME_ACTION = 11, // "one.vm.action" - //BOOT_ACTION = 12, - DELETE_ACTION = 13, // "one.vm.recover" - DELETE_RECREATE_ACTION = 14, // "one.vm.recover" - REBOOT_ACTION = 15, // "one.vm.action" - REBOOT_HARD_ACTION = 16, // "one.vm.action" - RESCHED_ACTION = 17, // "one.vm.action" - UNRESCHED_ACTION = 18, // "one.vm.action" - POWEROFF_ACTION = 19, // "one.vm.action" - POWEROFF_HARD_ACTION = 20, // "one.vm.action" - DISK_ATTACH_ACTION = 21, // "one.vm.attach" - DISK_DETACH_ACTION = 22, // "one.vm.detach" - NIC_ATTACH_ACTION = 23, // "one.vm.attachnic" - NIC_DETACH_ACTION = 24, // "one.vm.detachnic" - DISK_SNAPSHOT_CREATE_ACTION = 25, // "one.vm.disksnapshotcreate" - DISK_SNAPSHOT_DELETE_ACTION = 26, // "one.vm.disksnapshotdelete" - TERMINATE_ACTION = 27, // "one.vm.action" - TERMINATE_HARD_ACTION = 28, // "one.vm.action" - DISK_RESIZE_ACTION = 29, // "one.vm.diskresize" - DEPLOY_ACTION = 30, // "one.vm.deploy" - CHOWN_ACTION = 31, // "one.vm.chown" - CHMOD_ACTION = 32, // "one.vm.chmod" - UPDATECONF_ACTION = 33, // "one.vm.updateconf" - RENAME_ACTION = 34, // "one.vm.rename" - RESIZE_ACTION = 35, // "one.vm.resize" - UPDATE_ACTION = 36, // "one.vm.update" - SNAPSHOT_CREATE_ACTION = 37, // "one.vm.snapshotcreate" - SNAPSHOT_DELETE_ACTION = 38, // "one.vm.snapshotdelete" - SNAPSHOT_REVERT_ACTION = 39, // "one.vm.snapshotrevert" - DISK_SAVEAS_ACTION = 40, // "one.vm.disksaveas" - DISK_SNAPSHOT_REVERT_ACTION = 41, // "one.vm.disksnapshotrevert" - RECOVER_ACTION = 42, // "one.vm.recover" - RETRY_ACTION = 43, // "one.vm.recover" - MONITOR_ACTION = 44, // internal, monitoring process - DISK_SNAPSHOT_RENAME_ACTION = 45, // "one.vm.disksnapshotrename" - ALIAS_ATTACH_ACTION = 46, // "one.vm.attachnic" - ALIAS_DETACH_ACTION = 47, // "one.vm.detachnic" - POFF_MIGRATE_ACTION = 48, // "one.vm.migrate" - POFF_HARD_MIGRATE_ACTION = 49 // "one.vm.migrate" - }; - - static string action_to_str(VMAction action); - - static int action_from_str(const string& st, VMAction& action); - History(int oid, int _seq = -1); History( @@ -170,7 +112,7 @@ private: time_t epilog_stime; time_t epilog_etime; - VMAction action; + VMActions::Action action; string vm_info; diff --git a/include/Nebula.h b/include/Nebula.h index e8e7b7930e..e15a3f7c72 100644 --- a/include/Nebula.h +++ b/include/Nebula.h @@ -572,7 +572,7 @@ public: * Return the Authorization operation for a VM action * */ - AuthRequest::Operation get_vm_auth_op(History::VMAction action) + AuthRequest::Operation get_vm_auth_op(VMActions::Action action) { return nebula_configuration->get_vm_auth_op(action); } diff --git a/include/NebulaTemplate.h b/include/NebulaTemplate.h index 82d8a5d5c8..c8586b8929 100644 --- a/include/NebulaTemplate.h +++ b/include/NebulaTemplate.h @@ -20,7 +20,7 @@ #include "Template.h" #include "ActionSet.h" #include "AuthRequest.h" -#include "History.h" +#include "VMActions.h" #include @@ -89,11 +89,27 @@ public: */ virtual int load_configuration(); + /** + * Returns action set from a string of actions seperated by commas + */ + static int set_vm_auth_ops(const std::string& ops_str, + ActionSet& ops_set, std::string& error); + /** * @param action * @return authorization operation configured for the given VM action */ - AuthRequest::Operation get_vm_auth_op(History::VMAction action); + AuthRequest::Operation get_vm_auth_op(VMActions::Action action) + { + AuthRequest::Operation aop = vm_actions.get_auth_op(action); + + if (aop == AuthRequest::NONE) + { + aop = AuthRequest::MANAGE; + } + + return aop; + } private: /** @@ -107,19 +123,9 @@ private: string var_location; /** - * Set of VM actions that require USE permission + * Default set of VM action permissions */ - ActionSet vm_use_actions; - - /** - * Set of VM actions that require MANAGE permission - */ - ActionSet vm_manage_actions; - - /** - * Set of VM actions that require ADMIN permission - */ - ActionSet vm_admin_actions; + VMActions vm_actions; /** * Sets the defaults value for the template @@ -177,12 +183,6 @@ private: */ void set_conf_vn(const std::string& name, const std::string& bridge_type); - - /** - * Sets auth permissions for vm operations - */ - int set_vm_auth_ops(std::string& error); }; - #endif /*NEBULA_TEMPLATE_H_*/ diff --git a/include/Request.h b/include/Request.h index e8b6db586d..e077ca54b7 100644 --- a/include/Request.h +++ b/include/Request.h @@ -24,6 +24,7 @@ #include "AuthRequest.h" #include "PoolObjectSQL.h" #include "Quotas.h" +#include "History.h" using namespace std; @@ -57,12 +58,15 @@ public: uint64_t replication_idx; - RequestAttributes() + AuthRequest::Operation auth_op; /**< Auth operation for the request */ + + RequestAttributes(AuthRequest::Operation api_auth_op) { resp_obj = PoolObjectSQL::NONE; resp_id = -1; resp_msg = ""; replication_idx = UINT64_MAX; + auth_op = api_auth_op; }; RequestAttributes(const RequestAttributes& ra) @@ -89,6 +93,8 @@ public: resp_msg = ra.resp_msg; replication_idx = ra.replication_idx; + + auth_op = ra.auth_op; }; RequestAttributes(int _uid, int _gid, const RequestAttributes& ra) @@ -117,6 +123,7 @@ public: resp_msg = ""; replication_idx = UINT64_MAX; + auth_op = ra.auth_op; }; bool is_admin() const @@ -134,6 +141,14 @@ public: { return gid == GroupPool::ONEADMIN_ID; } + + /** + * Set the operation level (admin, manage or use) associated to this + * request. Precedence is: user > group > system. + * + * @param action perfomed on the VM object + */ + void set_auth_op(VMActions::Action action); }; /** @@ -189,39 +204,49 @@ public: } protected: + /* ---------------------------------------------------------------------- */ + /* Global configuration attributes por API calls */ + /* ---------------------------------------------------------------------- */ + static string format_str; + static const long long xmlrpc_timeout; //Timeout (ms) for request forwarding + /* ---------------------------------------------------------------------- */ /* Static Request Attributes: shared among request of the same method */ /* ---------------------------------------------------------------------- */ - PoolSQL * pool; /**< Pool of objects */ - string method_name; /**< The name of the XML-RPC method */ + PoolSQL * pool; + string method_name; - PoolObjectSQL::ObjectType auth_object;/**< Auth object for the request */ - AuthRequest::Operation auth_op; /**< Auth operation for the request */ + // Configuration for authentication level of the API call + PoolObjectSQL::ObjectType auth_object; + AuthRequest::Operation auth_op; + VMActions::Action vm_action; + + // Logging configuration fot the API call set hidden_params; + bool log_method_call; - static string format_str; - - bool log_method_call; //Write method call and result to the log - - bool leader_only; //Method can be only execute by leaders or solo servers - - static const long long xmlrpc_timeout; //Timeout (ms) for request forwarding + //Method can be only execute by leaders or solo servers + bool leader_only; /* ---------------------------------------------------------------------- */ /* Class Constructors */ /* ---------------------------------------------------------------------- */ - Request(const string& mn, const string& signature, const string& help): - pool(0),method_name(mn) + Request(const string& mn, const string& signature, const string& help) { + pool = nullptr; + + method_name = mn; + _signature = signature; _help = help; hidden_params.clear(); log_method_call = true; - leader_only = true; + + vm_action = VMActions::NONE_ACTION; }; virtual ~Request() = default; @@ -336,25 +361,7 @@ protected: * * @return true if the user is authorized. */ - bool basic_authorization(int oid, RequestAttributes& att) - { - return basic_authorization(oid, auth_op, att); - }; - - /** - * Performs a basic authorization for this request using the uid/gid - * from the request. The function gets the object from the pool to get - * the public attribute and its owner. The authorization is based on - * object and type of operation for the request. - * @param oid of the object, can be -1 for objects to be created, or - * pools. - * @param op operation of the request. - * @param att the specific request attributes - * - * @return true if the user is authorized. - */ - bool basic_authorization(int oid, AuthRequest::Operation op, - RequestAttributes& att); + bool basic_authorization(int oid, RequestAttributes& att); /** * Performs a basic authorization for this request using the uid/gid @@ -364,7 +371,6 @@ protected: * @param pool object pool * @param oid of the object, can be -1 for objects to be created, or * pools. - * @param op operation of the request. * @param att the specific request attributes * * @return SUCCESS if the user is authorized. @@ -372,7 +378,6 @@ protected: static ErrorCode basic_authorization( PoolSQL* pool, int oid, - AuthRequest::Operation op, PoolObjectSQL::ObjectType auth_object, RequestAttributes& att); diff --git a/include/RequestManagerClone.h b/include/RequestManagerClone.h index 3fbdb66d0e..ce6dbecac1 100644 --- a/include/RequestManagerClone.h +++ b/include/RequestManagerClone.h @@ -117,11 +117,11 @@ protected: }; ErrorCode merge(Template * tmpl, const string &s_a, RequestAttributes& att) override - { - VMTemplateInstantiate vm_instantiate; + { + VMTemplateInstantiate vm_instantiate; - return vm_instantiate.merge(tmpl, s_a, att); - }; + return vm_instantiate.merge(tmpl, s_a, att); + }; }; /* ------------------------------------------------------------------------- */ diff --git a/include/RequestManagerDelete.h b/include/RequestManagerDelete.h index 013e77667b..336df3172e 100644 --- a/include/RequestManagerDelete.h +++ b/include/RequestManagerDelete.h @@ -59,8 +59,7 @@ protected: void request_execute(xmlrpc_c::paramList const& paramList, RequestAttributes& att) override; - ErrorCode delete_object(int oid, bool recursive, - RequestAttributes& att, AuthRequest::Operation auth); + ErrorCode delete_object(int oid, bool recursive, RequestAttributes& att); /* -------------------------------------------------------------------- */ @@ -105,7 +104,7 @@ public: ErrorCode request_execute(int oid, bool recursive, RequestAttributes& att) { - return delete_object(oid, recursive, att, auth_op); + return delete_object(oid, recursive, att); } protected: @@ -133,7 +132,7 @@ public: ErrorCode request_execute(int oid, bool recursive, RequestAttributes& att) { - return delete_object(oid, false, att, auth_op); + return delete_object(oid, false, att); } }; @@ -188,7 +187,7 @@ public: ErrorCode request_execute(int oid, RequestAttributes& att) { - return delete_object(oid, false, att, auth_op); + return delete_object(oid, false, att); }; void request_execute(xmlrpc_c::paramList const& paramList, @@ -327,6 +326,7 @@ public: { Nebula& nd = Nebula::instance(); pool = nd.get_clpool(); + auth_object = PoolObjectSQL::CLUSTER; auth_op = AuthRequest::ADMIN; }; diff --git a/include/RequestManagerInfo.h b/include/RequestManagerInfo.h index 61a5ccd7dd..45d56c2d94 100644 --- a/include/RequestManagerInfo.h +++ b/include/RequestManagerInfo.h @@ -69,7 +69,8 @@ public: /* -------------------------------------------------------------------- */ - void to_xml(RequestAttributes& att, PoolObjectSQL * object, string& str) override + void to_xml(RequestAttributes& att, PoolObjectSQL * object, + string& str) override { static_cast(object)->to_xml_extended(str); }; diff --git a/include/RequestManagerMarketPlaceApp.h b/include/RequestManagerMarketPlaceApp.h index 64c3c46cf3..a04e66569a 100644 --- a/include/RequestManagerMarketPlaceApp.h +++ b/include/RequestManagerMarketPlaceApp.h @@ -27,8 +27,8 @@ class RequestManagerMarketPlaceApp: public Request { protected: RequestManagerMarketPlaceApp(const std::string& method_name, - const std::string& help, const std::string& params) : - Request(method_name, params, help) + const std::string& help, const std::string& params) : + Request(method_name, params, help) { Nebula& nd = Nebula::instance(); pool = nd.get_apppool(); @@ -42,7 +42,7 @@ protected: /* --------------------------------------------------------------------- */ virtual void request_execute(xmlrpc_c::paramList const& _paramList, - RequestAttributes& att) = 0; + RequestAttributes& att) = 0; }; /* ------------------------------------------------------------------------- */ @@ -52,12 +52,12 @@ class MarketPlaceAppEnable : public RequestManagerMarketPlaceApp { public: MarketPlaceAppEnable(): RequestManagerMarketPlaceApp("one.marketapp.enable", - "Enables or disables a marketplace app", "A:sib"){}; + "Enables or disables a marketplace app", "A:sib"){}; ~MarketPlaceAppEnable(){}; void request_execute(xmlrpc_c::paramList const& _paramList, - RequestAttributes& att) override; + RequestAttributes& att) override; }; /* -------------------------------------------------------------------------- */ diff --git a/include/RequestManagerRename.h b/include/RequestManagerRename.h index e7cdd81e76..c13b5f64d7 100644 --- a/include/RequestManagerRename.h +++ b/include/RequestManagerRename.h @@ -122,18 +122,16 @@ public: Nebula& nd = Nebula::instance(); pool = nd.get_vmpool(); auth_object = PoolObjectSQL::VM; + vm_action = VMActions::RENAME_ACTION; + } - auth_op = nd.get_vm_auth_op(History::RENAME_ACTION); - }; - - ~VirtualMachineRename(){}; + ~VirtualMachineRename() = default; int exist(const string& name, int uid) override { return -1; } - int extra_updates(PoolObjectSQL * obj) override { VirtualMachine * vm; @@ -148,7 +146,7 @@ public: vm = static_cast(obj); return vmpool->update_search(vm); - }; + } }; /* ------------------------------------------------------------------------- */ diff --git a/include/RequestManagerSecurityGroup.h b/include/RequestManagerSecurityGroup.h index 9877648043..dbb28bdeca 100644 --- a/include/RequestManagerSecurityGroup.h +++ b/include/RequestManagerSecurityGroup.h @@ -38,5 +38,4 @@ public: void request_execute(xmlrpc_c::paramList const& pl, RequestAttributes& att) override; }; - #endif diff --git a/include/RequestManagerSystem.h b/include/RequestManagerSystem.h index c7638c34b5..83a9269057 100644 --- a/include/RequestManagerSystem.h +++ b/include/RequestManagerSystem.h @@ -30,7 +30,10 @@ class RequestManagerSystem: public Request { protected: RequestManagerSystem(const string& method_name, const string& help, - const string& params) :Request(method_name,params,help) {}; + const string& params) :Request(method_name,params,help) + { + auth_op = AuthRequest::ADMIN; + }; ~RequestManagerSystem(){}; @@ -49,8 +52,7 @@ public: SystemVersion(): RequestManagerSystem("one.system.version", "Returns the OpenNebula version", - "A:s") - {}; + "A:s") {} ~SystemVersion(){}; @@ -67,8 +69,7 @@ public: SystemConfig(): RequestManagerSystem("one.system.config", "Returns the OpenNebula configuration", - "A:s") - {}; + "A:s") {} ~SystemConfig(){}; @@ -83,10 +84,7 @@ class SystemSql: public RequestManagerSystem { public: SystemSql():RequestManagerSystem("one.system.sql", - "Executes and replicates SQL commands on the DB backend","A:ssb") - { - auth_op = AuthRequest::ADMIN; - }; + "Executes and replicates SQL commands on the DB backend","A:ssb") {} ~SystemSql(){}; @@ -101,10 +99,7 @@ class SystemSqlQuery: public RequestManagerSystem { public: SystemSqlQuery():RequestManagerSystem("one.system.sqlquery", - "Executes SQL queries on the DB backend","A:ss") - { - auth_op = AuthRequest::ADMIN; - }; + "Executes SQL queries on the DB backend","A:ss") { } ~SystemSqlQuery(){}; @@ -144,10 +139,7 @@ public: UserQuotaInfo(): RequestManagerSystem("one.userquota.info", "Returns the default user quota limits", - "A:s") - { - auth_op = AuthRequest::ADMIN; - }; + "A:s") { } ~UserQuotaInfo(){}; @@ -164,10 +156,7 @@ public: GroupQuotaInfo(): RequestManagerSystem("one.groupquota.info", "Returns the default group quota limits", - "A:s") - { - auth_op = AuthRequest::ADMIN; - }; + "A:s") { } ~GroupQuotaInfo(){}; @@ -185,10 +174,7 @@ protected: const string& help): RequestManagerSystem(method_name, help, - "A:ss") - { - auth_op = AuthRequest::ADMIN; - }; + "A:ss") { } ~QuotaUpdate(){}; @@ -208,10 +194,7 @@ class UserQuotaUpdate : public QuotaUpdate public: UserQuotaUpdate(): QuotaUpdate("one.userquota.update", - "Updates the default user quota limits") - { - auth_op = AuthRequest::ADMIN; - }; + "Updates the default user quota limits") { } int set_default_quota(Template *tmpl, string& error) override; @@ -226,10 +209,7 @@ class GroupQuotaUpdate : public QuotaUpdate public: GroupQuotaUpdate(): QuotaUpdate("one.groupquota.update", - "Updates the default group quota limits") - { - auth_op = AuthRequest::ADMIN; - }; + "Updates the default group quota limits") { } int set_default_quota(Template *tmpl, string& error) override; diff --git a/include/RequestManagerUpdateTemplate.h b/include/RequestManagerUpdateTemplate.h index 38c8c09b60..53e44d8770 100644 --- a/include/RequestManagerUpdateTemplate.h +++ b/include/RequestManagerUpdateTemplate.h @@ -110,12 +110,12 @@ public: Nebula& nd = Nebula::instance(); pool = nd.get_vmpool(); auth_object = PoolObjectSQL::VM; + vm_action = VMActions::UPDATE_ACTION; + } - auth_op = nd.get_vm_auth_op(History::UPDATE_ACTION); - }; - - ~VirtualMachineUpdateTemplate(){}; + ~VirtualMachineUpdateTemplate() = default; +protected: int extra_updates(PoolObjectSQL * obj) override { VirtualMachine * vm; diff --git a/include/RequestManagerVNTemplate.h b/include/RequestManagerVNTemplate.h index d4f64af99d..b3b1b372d7 100644 --- a/include/RequestManagerVNTemplate.h +++ b/include/RequestManagerVNTemplate.h @@ -81,7 +81,7 @@ public: const string& s_uattr, Template* extra_attrs, int& vid, RequestAttributes& att); - /** + /** * Parse & merge user attributes (check if the request user is not oneadmin) * @param tmpl to merge the attributes to * @param s_uattr Template supplied by user to merge with the original diff --git a/include/RequestManagerVirtualMachine.h b/include/RequestManagerVirtualMachine.h index 22e25615de..4bfd600aa1 100644 --- a/include/RequestManagerVirtualMachine.h +++ b/include/RequestManagerVirtualMachine.h @@ -39,9 +39,9 @@ protected: auth_object = PoolObjectSQL::VM; auth_op = AuthRequest::MANAGE; - }; + } - ~RequestManagerVirtualMachine(){}; + ~RequestManagerVirtualMachine() = default; /* -------------------------------------------------------------------- */ @@ -54,8 +54,7 @@ protected: RequestAttributes& att, PoolObjectAuth * host_perms, PoolObjectAuth * ds_perm, - PoolObjectAuth * img_perm, - AuthRequest::Operation op); + PoolObjectAuth * img_perm); bool quota_resize_authorization( Template * deltas, @@ -114,14 +113,13 @@ protected: class VirtualMachineAction : public RequestManagerVirtualMachine { public: - //auth_op is MANAGE for all actions but "resched" and "unresched" - //this is dynamically set for each request in the execute method VirtualMachineAction(): RequestManagerVirtualMachine("one.vm.action", "Performs an action on a virtual machine", - "A:ssi"){}; - ~VirtualMachineAction(){}; + "A:ssi") {} + ~VirtualMachineAction() = default; +protected: void request_execute(xmlrpc_c::paramList const& _paramList, RequestAttributes& att) override; }; @@ -137,11 +135,12 @@ public: "Deploys a virtual machine", "A:siibis") { - auth_op = Nebula::instance().get_vm_auth_op(History::DEPLOY_ACTION); - }; + vm_action = VMActions::DEPLOY_ACTION; + } - ~VirtualMachineDeploy(){}; + ~VirtualMachineDeploy() = default; +protected: void request_execute(xmlrpc_c::paramList const& _paramList, RequestAttributes& att) override; }; @@ -155,12 +154,14 @@ public: VirtualMachineMigrate(): RequestManagerVirtualMachine("one.vm.migrate", "Migrates a virtual machine", - "A:siibbii"){ - auth_op = Nebula::instance().get_vm_auth_op(History::MIGRATE_ACTION); - }; + "A:siibbii") + { + vm_action = VMActions::MIGRATE_ACTION; + } - ~VirtualMachineMigrate(){}; + ~VirtualMachineMigrate() = default; +protected: void request_execute(xmlrpc_c::paramList const& _paramList, RequestAttributes& att) override; }; @@ -174,12 +175,14 @@ public: VirtualMachineDiskSaveas(): RequestManagerVirtualMachine("one.vm.disksaveas", "Save a disk from virtual machine as a new image", - "A:siissi"){ - auth_op= Nebula::instance().get_vm_auth_op(History::DISK_SAVEAS_ACTION); - }; + "A:siissi") + { + vm_action = VMActions::DISK_SAVEAS_ACTION; + } - ~VirtualMachineDiskSaveas(){}; + ~VirtualMachineDiskSaveas() = default; +protected: void request_execute(xmlrpc_c::paramList const& _paramList, RequestAttributes& att) override; }; @@ -190,22 +193,20 @@ public: class VirtualMachineMonitoring : public RequestManagerVirtualMachine { public: - VirtualMachineMonitoring(): RequestManagerVirtualMachine("one.vm.monitoring", "Returns the virtual machine monitoring records", - "A:si"){ - auth_op = AuthRequest::USE_NO_LCK; - }; + "A:si") + { + auth_op = AuthRequest::USE_NO_LCK; + vm_action = VMActions::MONITOR_ACTION; + } - ~VirtualMachineMonitoring(){}; + ~VirtualMachineMonitoring() = default; +protected: void request_execute(xmlrpc_c::paramList const& paramList, RequestAttributes& att) override; - - virtual bool is_locked(xmlrpc_c::paramList const& paramList, RequestAttributes& att){ - return false; - }; }; /* ------------------------------------------------------------------------- */ @@ -217,11 +218,13 @@ public: VirtualMachineAttach(): RequestManagerVirtualMachine("one.vm.attach", "Attaches a new disk to the virtual machine", - "A:sis"){ - auth_op= Nebula::instance().get_vm_auth_op(History::DISK_ATTACH_ACTION); - }; + "A:sis") + { + auth_op = AuthRequest::USE_NO_LCK; + vm_action = VMActions::DISK_ATTACH_ACTION; + } - ~VirtualMachineAttach(){}; + ~VirtualMachineAttach() = default; /** * Process a DISK attahment request to a Virtual Machine @@ -248,13 +251,15 @@ public: VirtualMachineDetach(): RequestManagerVirtualMachine("one.vm.detach", "Detaches a disk from a virtual machine", - "A:sii"){ - //Attach & detach are set to the same auth op in OpenNebulaTemplate - auth_op= Nebula::instance().get_vm_auth_op(History::DISK_DETACH_ACTION); - }; + "A:sii") + { + auth_op = AuthRequest::USE_NO_LCK; + vm_action = VMActions::DISK_DETACH_ACTION; + } - ~VirtualMachineDetach(){}; + ~VirtualMachineDetach() = default; +protected: void request_execute(xmlrpc_c::paramList const& _paramList, RequestAttributes& att) override; }; @@ -268,11 +273,12 @@ public: VirtualMachineAttachNic(): RequestManagerVirtualMachine("one.vm.attachnic", "Attaches a new NIC to the virtual machine", - "A:sis"){ - auth_op = Nebula::instance().get_vm_auth_op(History::NIC_ATTACH_ACTION); - }; + "A:sis") + { + vm_action = VMActions::NIC_ATTACH_ACTION; + } - ~VirtualMachineAttachNic(){}; + ~VirtualMachineAttachNic() = default; /** * Process a NIC attahment request to a Virtual Machine @@ -285,10 +291,8 @@ public: RequestAttributes& att); protected: - void request_execute(xmlrpc_c::paramList const& pl, RequestAttributes& ra) override; - }; /* -------------------------------------------------------------------------- */ @@ -300,12 +304,12 @@ public: VirtualMachineDetachNic(): RequestManagerVirtualMachine("one.vm.detachnic", "Detaches a NIC from a virtual machine", - "A:sii"){ - //Attach & detach are set to the same auth op in OpenNebulaTemplate - auth_op = Nebula::instance().get_vm_auth_op(History::NIC_DETACH_ACTION); - }; + "A:sii") + { + vm_action = VMActions::NIC_DETACH_ACTION; + } - ~VirtualMachineDetachNic(){}; + ~VirtualMachineDetachNic() = default; /** * Process a NIC detach request to a Virtual Machine @@ -330,12 +334,14 @@ public: VirtualMachineResize(): RequestManagerVirtualMachine("one.vm.resize", "Changes the capacity of the virtual machine", - "A:sisb"){ - auth_op = Nebula::instance().get_vm_auth_op(History::RESIZE_ACTION); - }; + "A:sisb") + { + vm_action = VMActions::RESIZE_ACTION; + } - ~VirtualMachineResize(){}; + ~VirtualMachineResize() = default; +protected: void request_execute(xmlrpc_c::paramList const& _paramList, RequestAttributes& att) override; }; @@ -349,15 +355,14 @@ public: VirtualMachineSnapshotCreate(): RequestManagerVirtualMachine("one.vm.snapshotcreate", "Creates a new virtual machine snapshot", - "A:sis"){ - Nebula& nd = Nebula::instance(); + "A:sis") + { + vm_action = VMActions::SNAPSHOT_CREATE_ACTION; + } - //All VM snapshot operations are set to the same auth value - auth_op = nd.get_vm_auth_op(History::SNAPSHOT_CREATE_ACTION); - }; - - ~VirtualMachineSnapshotCreate(){}; + ~VirtualMachineSnapshotCreate() = default; +protected: void request_execute(xmlrpc_c::paramList const& _paramList, RequestAttributes& att) override; }; @@ -371,15 +376,14 @@ public: VirtualMachineSnapshotRevert(): RequestManagerVirtualMachine("one.vm.snapshotrevert", "Reverts a virtual machine to a snapshot", - "A:sii"){ - Nebula& nd = Nebula::instance(); + "A:sii") + { + vm_action = VMActions::SNAPSHOT_REVERT_ACTION; + } - //All VM snapshot operations are set to the same auth value - auth_op = nd.get_vm_auth_op(History::SNAPSHOT_REVERT_ACTION); - }; - - ~VirtualMachineSnapshotRevert(){}; + ~VirtualMachineSnapshotRevert() = default; +protected: void request_execute(xmlrpc_c::paramList const& _paramList, RequestAttributes& att) override; }; @@ -393,15 +397,14 @@ public: VirtualMachineSnapshotDelete(): RequestManagerVirtualMachine("one.vm.snapshotdelete", "Deletes a virtual machine snapshot", - "A:sii"){ - Nebula& nd = Nebula::instance(); + "A:sii") + { + vm_action = VMActions::SNAPSHOT_DELETE_ACTION; + } - //All VM snapshot operations are set to the same auth value - auth_op = nd.get_vm_auth_op(History::SNAPSHOT_DELETE_ACTION); - }; - - ~VirtualMachineSnapshotDelete(){}; + ~VirtualMachineSnapshotDelete() = default; +protected: void request_execute(xmlrpc_c::paramList const& _paramList, RequestAttributes& att) override; }; @@ -415,9 +418,14 @@ public: VirtualMachineRecover(): RequestManagerVirtualMachine("one.vm.recover", "Recovers a virtual machine", - "A:sii"){}; - ~VirtualMachineRecover(){}; + "A:sii") + { + vm_action = VMActions::RECOVER_ACTION; + } + ~VirtualMachineRecover() = default; + +protected: void request_execute(xmlrpc_c::paramList const& _paramList, RequestAttributes& att) override; }; @@ -428,22 +436,17 @@ public: class VirtualMachinePoolCalculateShowback : public RequestManagerVirtualMachine { public: - VirtualMachinePoolCalculateShowback(): RequestManagerVirtualMachine("one.vmpool.calculateshowback", "Processes all the history records, and stores the monthly cost" " for each VM", "A:sii") { - Nebula& nd = Nebula::instance(); - pool = nd.get_vmpool(); - auth_object = PoolObjectSQL::VM; - }; + } - ~VirtualMachinePoolCalculateShowback(){}; - - /* -------------------------------------------------------------------- */ + ~VirtualMachinePoolCalculateShowback() = default; +protected: void request_execute(xmlrpc_c::paramList const& paramList, RequestAttributes& att) override; }; @@ -457,16 +460,17 @@ public: VirtualMachineDiskSnapshotCreate(): RequestManagerVirtualMachine("one.vm.disksnapshotcreate", "Creates a new virtual machine disk snapshot", - "A:siis"){ + "A:siis") + { Nebula& nd = Nebula::instance(); ipool = nd.get_ipool(); - //All VM disk snapshot operations are set to the same auth value - auth_op = nd.get_vm_auth_op(History::DISK_SNAPSHOT_CREATE_ACTION); - }; + vm_action = VMActions::DISK_SNAPSHOT_CREATE_ACTION; + } - ~VirtualMachineDiskSnapshotCreate(){}; + ~VirtualMachineDiskSnapshotCreate() = default; +protected: void request_execute(xmlrpc_c::paramList const& _paramList, RequestAttributes& att) override; @@ -483,15 +487,14 @@ public: VirtualMachineDiskSnapshotRevert(): RequestManagerVirtualMachine("one.vm.disksnapshotrevert", "Reverts disk state to a snapshot", - "A:siii"){ - Nebula& nd = Nebula::instance(); + "A:siii") + { + vm_action = VMActions::DISK_SNAPSHOT_REVERT_ACTION; + } - //All VM disk snapshot operations are set to the same auth value - auth_op = nd.get_vm_auth_op(History::DISK_SNAPSHOT_REVERT_ACTION); - }; - - ~VirtualMachineDiskSnapshotRevert(){}; + ~VirtualMachineDiskSnapshotRevert() = default; +protected: void request_execute(xmlrpc_c::paramList const& _paramList, RequestAttributes& att) override; }; @@ -505,16 +508,17 @@ public: VirtualMachineDiskSnapshotDelete(): RequestManagerVirtualMachine("one.vm.disksnapshotdelete", "Deletes a disk snapshot", - "A:siii"){ + "A:siii") + { Nebula& nd = Nebula::instance(); ipool = nd.get_ipool(); - //All VM disk snapshot operations are set to the same auth value - auth_op = nd.get_vm_auth_op(History::DISK_SNAPSHOT_DELETE_ACTION); - }; + vm_action = VMActions::DISK_SNAPSHOT_DELETE_ACTION; + } - ~VirtualMachineDiskSnapshotDelete(){}; + ~VirtualMachineDiskSnapshotDelete() = default; +protected: void request_execute(xmlrpc_c::paramList const& _paramList, RequestAttributes& att) override; @@ -531,15 +535,14 @@ public: VirtualMachineDiskSnapshotRename(): RequestManagerVirtualMachine("one.vm.disksnapshotrename", "Rename a disk snapshot", - "A:siiis"){ - Nebula& nd = Nebula::instance(); + "A:siiis") + { + vm_action = VMActions::DISK_SNAPSHOT_RENAME_ACTION; + } - //All VM disk snapshot operations are set to the same auth value - auth_op = nd.get_vm_auth_op(History::DISK_SNAPSHOT_RENAME_ACTION); - }; - - ~VirtualMachineDiskSnapshotRename(){}; + ~VirtualMachineDiskSnapshotRename() = default; +protected: void request_execute(xmlrpc_c::paramList const& _paramList, RequestAttributes& att) override; }; @@ -553,33 +556,41 @@ public: VirtualMachineUpdateConf(): RequestManagerVirtualMachine("one.vm.updateconf", "Updates several configuration attributes of a VM", - "A:sis"){ - auth_op = Nebula::instance().get_vm_auth_op(History::UPDATECONF_ACTION); - }; + "A:sis") + { + vm_action = VMActions::UPDATECONF_ACTION; + } - ~VirtualMachineUpdateConf(){}; + ~VirtualMachineUpdateConf() = default; +protected: void request_execute(xmlrpc_c::paramList const& _paramList, RequestAttributes& att) override; }; +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + class VirtualMachineDiskResize : public RequestManagerVirtualMachine { public: VirtualMachineDiskResize(): RequestManagerVirtualMachine("one.vm.diskresize", "Resizes a disk from a virtual machine", - "A:siis"){ + "A:siis") + { Nebula& nd = Nebula::instance(); ipool = nd.get_ipool(); - auth_op = nd.get_vm_auth_op(History::DISK_RESIZE_ACTION); - }; + vm_action = VMActions::DISK_RESIZE_ACTION; + } - ~VirtualMachineDiskResize(){}; + ~VirtualMachineDiskResize() = default; +protected: void request_execute(xmlrpc_c::paramList const& _paramList, RequestAttributes& att) override; + private: ImagePool* ipool; }; diff --git a/include/RequestManagerVirtualRouter.h b/include/RequestManagerVirtualRouter.h index 6e6e4a44b0..abb97a2584 100644 --- a/include/RequestManagerVirtualRouter.h +++ b/include/RequestManagerVirtualRouter.h @@ -38,6 +38,7 @@ protected: pool = nd.get_vrouterpool(); auth_object = PoolObjectSQL::VROUTER; + auth_op = AuthRequest::MANAGE; }; ~RequestManagerVirtualRouter(){}; @@ -56,10 +57,7 @@ class VirtualRouterInstantiate : public RequestManagerVirtualRouter public: VirtualRouterInstantiate() : RequestManagerVirtualRouter( "one.vrouter.instantiate", "Instantiates a new virtual machine " - "associated to a virtual router", "A:siiisbs") - { - auth_op = AuthRequest::MANAGE; - }; + "associated to a virtual router", "A:siiisbs") { } ~VirtualRouterInstantiate(){}; @@ -76,10 +74,7 @@ class VirtualRouterAttachNic : public RequestManagerVirtualRouter public: VirtualRouterAttachNic():RequestManagerVirtualRouter("one.vrouter.attachnic", "Attaches a new NIC to the virtual router, and its virtual machines", - "A:sis") - { - auth_op = AuthRequest::MANAGE; - }; + "A:sis") { } ~VirtualRouterAttachNic(){}; @@ -95,10 +90,7 @@ class VirtualRouterDetachNic : public RequestManagerVirtualRouter { public: VirtualRouterDetachNic():RequestManagerVirtualRouter("one.vrouter.detachnic", - "Detaches a NIC from a virtual router, and its virtual machines","A:sii") - { - auth_op = AuthRequest::MANAGE; - }; + "Detaches a NIC from a virtual router, and its virtual machines","A:sii") { } ~VirtualRouterDetachNic(){}; diff --git a/include/User.h b/include/User.h index ffee8aa897..e536dd00c6 100644 --- a/include/User.h +++ b/include/User.h @@ -22,6 +22,8 @@ #include "ObjectCollection.h" #include "QuotasSQL.h" #include "LoginToken.h" +#include "VMActions.h" +#include "AuthRequest.h" class UserQuotas; @@ -224,6 +226,15 @@ public: return groups.contains(_group_id); } + /** + * @return the operation level (admin, manage or use) associated to the + * given action for this group + */ + AuthRequest::Operation get_vm_auth_op(VMActions::Action action) const + { + return vm_actions.get_auth_op(action); + } + // ************************************************************************* // Quotas // ************************************************************************* @@ -241,7 +252,7 @@ public: int update_quotas(SqlDB *db) { return quota.update(oid, db->get_local_db()); - }; + } // ************************************************************************* // Login tokens @@ -283,6 +294,11 @@ private: */ ObjectCollection groups; + /** + * List of VM actions and rights for this user + */ + VMActions vm_actions; + // ************************************************************************* // Authentication session used to cache authentication calls // ************************************************************************* @@ -310,7 +326,7 @@ private: ostringstream oss_user(User::db_bootstrap); return db->exec_local_wr(oss_user); - }; + } /** * Reads the User (identified with its OID) from the database. @@ -375,7 +391,7 @@ protected: session(0) { obj_template = new UserTemplate; - }; + } virtual ~User() = default; @@ -406,7 +422,7 @@ protected: { string error_str; return insert_replace(db, true, error_str); - }; + } }; #endif /*USER_H_*/ diff --git a/include/UserPool.h b/include/UserPool.h index 7177afa4d8..8e299fa2d9 100644 --- a/include/UserPool.h +++ b/include/UserPool.h @@ -41,20 +41,21 @@ class UserPool : public PoolSQL { public: - UserPool(SqlDB * db, - time_t __session_expiration_time, - vector hook_mads, - const string& remotes_location, - bool is_federation_slave); + UserPool(SqlDB * db, + time_t __session_expiration_time, + vector hook_mads, + const string& remotes_location, + bool is_federation_slave, + vector& restricted_attrs); - ~UserPool(){}; + ~UserPool() = default; /** * Function to allocate a new User object * @param oid the id assigned to the User * @return the oid assigned to the object or -1 in case of failure */ - int allocate ( + int allocate( int * oid, const string& uname, int gid, diff --git a/include/UserTemplate.h b/include/UserTemplate.h index eb05dbde8c..719a7c04fe 100644 --- a/include/UserTemplate.h +++ b/include/UserTemplate.h @@ -19,17 +19,39 @@ #include "Template.h" -using namespace std; - /** * User Template class, it represents the attributes of an user */ class UserTemplate : public Template { public: - UserTemplate() : Template(true,'=',"TEMPLATE"){}; + UserTemplate() : Template(true,'=',"TEMPLATE") {} - ~UserTemplate(){}; + ~UserTemplate() = default; + + // ------------------------------------------------------------------------- + // Restricted attributes interface implementation + // ------------------------------------------------------------------------- + bool check_restricted(string& rs_attr, const Template* base) override + { + return Template::check_restricted(rs_attr, base, restricted); + } + + bool check_restricted(string& rs_attr) override + { + return Template::check_restricted(rs_attr, restricted); + } + + static void parse_restricted(vector& ra) + { + Template::parse_restricted(ra, restricted); + } + +private: + /** + * Restricted attribute list for UserTemplate + */ + static std::map> restricted; }; /* -------------------------------------------------------------------------- */ diff --git a/include/VMActions.h b/include/VMActions.h new file mode 100644 index 0000000000..d3a787f2dc --- /dev/null +++ b/include/VMActions.h @@ -0,0 +1,144 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2019, OpenNebula Project, OpenNebula Systems */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); you may */ +/* not use this file except in compliance with the License. You may obtain */ +/* a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */ +/* See the License for the specific language governing permissions and */ +/* limitations under the License. */ +/* -------------------------------------------------------------------------- */ + +#ifndef VMACTIONS_H +#define VMACTIONS_H + +#include "ActionSet.h" +#include "AuthRequest.h" + +class Template; + +class VMActions +{ +public: + + enum Action + { //Associated XML-RPC API call + NONE_ACTION = 0, // "one.vm.migrate" + MIGRATE_ACTION = 1, // "one.vm.migrate" + LIVE_MIGRATE_ACTION = 2, + //SHUTDOWN_ACTION = 3, + //SHUTDOWN_HARD_ACTION = 4, + UNDEPLOY_ACTION = 5, // "one.vm.action" + UNDEPLOY_HARD_ACTION = 6, // "one.vm.action" + HOLD_ACTION = 7, // "one.vm.action" + RELEASE_ACTION = 8, // "one.vm.action" + STOP_ACTION = 9, // "one.vm.action" + SUSPEND_ACTION = 10, // "one.vm.action" + RESUME_ACTION = 11, // "one.vm.action" + //BOOT_ACTION = 12, + DELETE_ACTION = 13, // "one.vm.recover" + DELETE_RECREATE_ACTION = 14, // "one.vm.recover" + REBOOT_ACTION = 15, // "one.vm.action" + REBOOT_HARD_ACTION = 16, // "one.vm.action" + RESCHED_ACTION = 17, // "one.vm.action" + UNRESCHED_ACTION = 18, // "one.vm.action" + POWEROFF_ACTION = 19, // "one.vm.action" + POWEROFF_HARD_ACTION = 20, // "one.vm.action" + DISK_ATTACH_ACTION = 21, // "one.vm.attach" + DISK_DETACH_ACTION = 22, // "one.vm.detach" + NIC_ATTACH_ACTION = 23, // "one.vm.attachnic" + NIC_DETACH_ACTION = 24, // "one.vm.detachnic" + DISK_SNAPSHOT_CREATE_ACTION = 25, // "one.vm.disksnapshotcreate" + DISK_SNAPSHOT_DELETE_ACTION = 26, // "one.vm.disksnapshotdelete" + TERMINATE_ACTION = 27, // "one.vm.action" + TERMINATE_HARD_ACTION = 28, // "one.vm.action" + DISK_RESIZE_ACTION = 29, // "one.vm.diskresize" + DEPLOY_ACTION = 30, // "one.vm.deploy" + CHOWN_ACTION = 31, // "one.vm.chown" + CHMOD_ACTION = 32, // "one.vm.chmod" + UPDATECONF_ACTION = 33, // "one.vm.updateconf" + RENAME_ACTION = 34, // "one.vm.rename" + RESIZE_ACTION = 35, // "one.vm.resize" + UPDATE_ACTION = 36, // "one.vm.update" + SNAPSHOT_CREATE_ACTION = 37, // "one.vm.snapshotcreate" + SNAPSHOT_DELETE_ACTION = 38, // "one.vm.snapshotdelete" + SNAPSHOT_REVERT_ACTION = 39, // "one.vm.snapshotrevert" + DISK_SAVEAS_ACTION = 40, // "one.vm.disksaveas" + DISK_SNAPSHOT_REVERT_ACTION = 41, // "one.vm.disksnapshotrevert" + RECOVER_ACTION = 42, // "one.vm.recover" + RETRY_ACTION = 43, // "one.vm.recover" + MONITOR_ACTION = 44, // internal, monitoring process + DISK_SNAPSHOT_RENAME_ACTION = 45, // "one.vm.disksnapshotrename" + ALIAS_ATTACH_ACTION = 46, // "one.vm.attachnic" + ALIAS_DETACH_ACTION = 47, // "one.vm.detachnic" + POFF_MIGRATE_ACTION = 48, // "one.vm.migrate" + POFF_HARD_MIGRATE_ACTION = 49 // "one.vm.migrate" + }; + + static string action_to_str(Action action); + + static int action_from_str(const string& st, Action& action); + + /** + * @return true if action requires ADMIN right + */ + bool is_admin(Action action) const + { + return admin_actions.is_set(action); + } + + /** + * @return true if action requires ADMIN right + */ + bool is_use(Action action) const + { + return use_actions.is_set(action); + } + + /** + * @return true if action requires ADMIN right + */ + bool is_manage(Action action) const + { + return manage_actions.is_set(action); + } + + /** + * @return the auth type for the given action + */ + AuthRequest::Operation get_auth_op(Action action) const; + + /** + * Sets the auth operations based on the provided template + */ + int set_auth_ops(const Template& tmpl, string& error); + +private: + /** + * Set of VM actions that require USE permission + */ + ActionSet use_actions; + + /** + * Set of VM actions that require MANAGE permission + */ + ActionSet manage_actions; + + /** + * Set of VM actions that require ADMIN permission + */ + ActionSet admin_actions; + + /** + * Returns action set from a string of actions seperated by commas + */ + int set_auth_ops(const std::string& ops_str, + ActionSet& ops_set, std::string& error); +}; + +#endif /*VMACTIONS_H*/ diff --git a/include/VirtualMachine.h b/include/VirtualMachine.h index 209507d6ff..522ac3861a 100644 --- a/include/VirtualMachine.h +++ b/include/VirtualMachine.h @@ -653,7 +653,7 @@ public: * function MUST be called before this one. * @return the action that closed the current history record */ - const History::VMAction get_action() const + const VMActions::Action get_action() const { return history->action; }; @@ -662,7 +662,7 @@ public: * Returns the action that closed the history record in the previous host * @return the action that closed the history record in the previous host */ - const History::VMAction get_previous_action() const + const VMActions::Action get_previous_action() const { return previous_history->action; }; @@ -821,7 +821,7 @@ public: * Sets the action that closed the history record * @param action that closed the history record */ - void set_action(History::VMAction action, int uid, int gid, int req_id) + void set_action(VMActions::Action action, int uid, int gid, int req_id) { history->action = action; @@ -831,7 +831,7 @@ public: history->req_id = req_id; }; - void set_internal_action(History::VMAction action) + void set_internal_action(VMActions::Action action) { history->action = action; @@ -843,7 +843,7 @@ public: void clear_action() { - history->action = History::NONE_ACTION; + history->action = VMActions::NONE_ACTION; history->uid = -1; history->gid = -1; @@ -851,7 +851,7 @@ public: history->req_id = -1; } - void set_previous_action(History::VMAction action, int uid, int gid,int rid) + void set_previous_action(VMActions::Action action, int uid, int gid,int rid) { previous_history->action = action; @@ -1139,7 +1139,7 @@ public: * @param action VM action to check * @return true if the current VM MAD supports the given action for imported VMs */ - bool is_imported_action_supported(History::VMAction action) const; + bool is_imported_action_supported(VMActions::Action action) const; // ------------------------------------------------------------------------ // Virtual Router related functions diff --git a/include/VirtualMachineManager.h b/include/VirtualMachineManager.h index 1ed0ff2d75..a2a1db5434 100644 --- a/include/VirtualMachineManager.h +++ b/include/VirtualMachineManager.h @@ -153,7 +153,7 @@ public: * @param action * @return True if it is supported */ - bool is_imported_action_supported(const string& mad,History::VMAction action) + bool is_imported_action_supported(const string& mad, VMActions::Action action) { const VirtualMachineManagerDriver * vmd = get(mad); diff --git a/include/VirtualMachineManagerDriver.h b/include/VirtualMachineManagerDriver.h index c797b43b20..df6b9c36dc 100644 --- a/include/VirtualMachineManagerDriver.h +++ b/include/VirtualMachineManagerDriver.h @@ -24,7 +24,7 @@ #include "Mad.h" #include "ActionSet.h" #include "VirtualMachinePool.h" -#include "History.h" +#include "VMActions.h" using namespace std; @@ -90,7 +90,7 @@ public: * @param action * @return True if it is supported */ - bool is_imported_action_supported(History::VMAction action) const + bool is_imported_action_supported(VMActions::Action action) const { return imported_actions.is_set(action); } @@ -159,7 +159,7 @@ private: * List of available actions for imported VMs. Each bit is an action * as defined in History.h, 1=supported and 0=not supported */ - ActionSet imported_actions; + ActionSet imported_actions; /** * Set to true if the hypervisor can keep system snapshots across diff --git a/share/etc/oned.conf b/share/etc/oned.conf index 8900020339..69446ebf9f 100644 --- a/share/etc/oned.conf +++ b/share/etc/oned.conf @@ -1177,6 +1177,14 @@ VNET_RESTRICTED_ATTR = "CLUSTER_IDS" VNET_RESTRICTED_ATTR = "EXTERNAL" +USER_RESTRICTED_ATTR = "VM_USE_OPERATIONS" +USER_RESTRICTED_ATTR = "VM_MANAGE_OPERATIONS" +USER_RESTRICTED_ATTR = "VM_ADMIN_OPERATIONS" + +GROUP_RESTRICTED_ATTR = "VM_USE_OPERATIONS" +GROUP_RESTRICTED_ATTR = "VM_MANAGE_OPERATIONS" +GROUP_RESTRICTED_ATTR = "VM_ADMIN_OPERATIONS" + #******************************************************************************* # Inherited Attributes Configuration #******************************************************************************* diff --git a/src/dm/DispatchManagerActions.cc b/src/dm/DispatchManagerActions.cc index 5eccfd8467..4d56c951c7 100644 --- a/src/dm/DispatchManagerActions.cc +++ b/src/dm/DispatchManagerActions.cc @@ -1218,7 +1218,7 @@ int DispatchManager::delete_recreate(VirtualMachine * vm, case VirtualMachine::HOLD: if (vm->hasHistory()) { - vm->set_action(History::DELETE_RECREATE_ACTION, ra.uid, ra.gid, + vm->set_action(VMActions::DELETE_RECREATE_ACTION, ra.uid, ra.gid, ra.req_id); vmpool->update_history(vm); } @@ -1384,7 +1384,7 @@ int DispatchManager::attach(int vid, VirtualMachineTemplate * tmpl, vm->set_etime(the_time); - vm->set_action(History::DISK_ATTACH_ACTION, ra.uid, ra.gid, ra.req_id); + vm->set_action(VMActions::DISK_ATTACH_ACTION, ra.uid, ra.gid, ra.req_id); vmpool->update_history(vm); @@ -1474,7 +1474,7 @@ int DispatchManager::detach(int vid, int disk_id, const RequestAttributes& ra, vm->set_etime(the_time); - vm->set_action(History::DISK_DETACH_ACTION, ra.uid, ra.gid, ra.req_id); + vm->set_action(VMActions::DISK_DETACH_ACTION, ra.uid, ra.gid, ra.req_id); vmpool->update_history(vm); @@ -1764,11 +1764,11 @@ int DispatchManager::attach_nic(int vid, VirtualMachineTemplate* tmpl, if ( tmpl->get("NIC") != 0 ) { - vm->set_action(History::NIC_ATTACH_ACTION, ra.uid, ra.gid, ra.req_id); + vm->set_action(VMActions::NIC_ATTACH_ACTION, ra.uid, ra.gid, ra.req_id); } else { - vm->set_action(History::ALIAS_ATTACH_ACTION, ra.uid, ra.gid, ra.req_id); + vm->set_action(VMActions::ALIAS_ATTACH_ACTION, ra.uid, ra.gid, ra.req_id); } vmpool->update_history(vm); @@ -1862,11 +1862,11 @@ int DispatchManager::detach_nic(int vid, int nic_id,const RequestAttributes& ra, if ( !vm->get_nic(nic_id)->is_alias() ) { - vm->set_action(History::NIC_DETACH_ACTION, ra.uid, ra.gid, ra.req_id); + vm->set_action(VMActions::NIC_DETACH_ACTION, ra.uid, ra.gid, ra.req_id); } else { - vm->set_action(History::ALIAS_DETACH_ACTION, ra.uid, ra.gid, ra.req_id); + vm->set_action(VMActions::ALIAS_DETACH_ACTION, ra.uid, ra.gid, ra.req_id); } vmpool->update_history(vm); @@ -1996,7 +1996,7 @@ int DispatchManager::disk_snapshot_create(int vid, int did, const string& name, vm->set_etime(the_time); - vm->set_action(History::DISK_SNAPSHOT_CREATE_ACTION, ra.uid, ra.gid, + vm->set_action(VMActions::DISK_SNAPSHOT_CREATE_ACTION, ra.uid, ra.gid, ra.req_id); vmpool->update_history(vm); @@ -2192,7 +2192,7 @@ int DispatchManager::disk_snapshot_delete(int vid, int did, int snap_id, vm->set_etime(the_time); - vm->set_action(History::DISK_SNAPSHOT_DELETE_ACTION, ra.uid, ra.gid, + vm->set_action(VMActions::DISK_SNAPSHOT_DELETE_ACTION, ra.uid, ra.gid, ra.req_id); vmpool->update_history(vm); @@ -2307,7 +2307,7 @@ int DispatchManager::disk_resize(int vid, int did, long long new_size, vm->set_etime(the_time); - vm->set_action(History::DISK_RESIZE_ACTION, ra.uid, ra.gid, + vm->set_action(VMActions::DISK_RESIZE_ACTION, ra.uid, ra.gid, ra.req_id); vmpool->update_history(vm); diff --git a/src/dm/DispatchManagerStates.cc b/src/dm/DispatchManagerStates.cc index cb6f33edb0..4d34c5f2ee 100644 --- a/src/dm/DispatchManagerStates.cc +++ b/src/dm/DispatchManagerStates.cc @@ -101,9 +101,9 @@ void DispatchManager::stop_success_action(int vid) vm->set_state(VirtualMachine::LCM_INIT); //Set history action field to perform the right TM command on resume - if (vm->get_action() == History::NONE_ACTION) + if (vm->get_action() == VMActions::NONE_ACTION) { - vm->set_internal_action(History::STOP_ACTION); + vm->set_internal_action(VMActions::STOP_ACTION); vmpool->update_history(vm); } @@ -161,9 +161,9 @@ void DispatchManager::undeploy_success_action(int vid) vm->set_state(VirtualMachine::LCM_INIT); //Set history action field to perform the right TM command on resume - if (vm->get_action() == History::NONE_ACTION) + if (vm->get_action() == VMActions::NONE_ACTION) { - vm->set_internal_action(History::UNDEPLOY_ACTION); + vm->set_internal_action(VMActions::UNDEPLOY_ACTION); vmpool->update_history(vm); } diff --git a/src/group/Group.cc b/src/group/Group.cc index da5856154c..039d93343a 100644 --- a/src/group/Group.cc +++ b/src/group/Group.cc @@ -248,6 +248,9 @@ string& Group::to_xml_extended(string& xml, bool extended) const int Group::from_xml(const string& xml) { int rc = 0; + + string error; + vector content; vector::iterator it; @@ -283,6 +286,8 @@ int Group::from_xml(const string& xml) ObjectXML::free_nodes(content); content.clear(); + rc += vm_actions.set_auth_ops(*obj_template, error); + if (rc != 0) { return -1; @@ -540,42 +545,41 @@ void Group::sunstone_views(const string& user_default, const string& user_views, const string& admin_default, const string& admin_views) { - VectorAttribute * sunstone = obj_template->get("SUNSTONE"); + VectorAttribute * sunstone = obj_template->get("SUNSTONE"); - if ( sunstone == 0 ) - { - map vvalue; + if ( sunstone == 0 ) + { + map vvalue; - vvalue.insert(make_pair("DEFAULT_VIEW", user_default)); - vvalue.insert(make_pair("VIEWS", user_views)); - vvalue.insert(make_pair("GROUP_ADMIN_DEFAULT_VIEW", admin_default)); - vvalue.insert(make_pair("GROUP_ADMIN_VIEWS", admin_views)); + vvalue.insert(make_pair("DEFAULT_VIEW", user_default)); + vvalue.insert(make_pair("VIEWS", user_views)); + vvalue.insert(make_pair("GROUP_ADMIN_DEFAULT_VIEW", admin_default)); + vvalue.insert(make_pair("GROUP_ADMIN_VIEWS", admin_views)); - sunstone = new VectorAttribute("SUNSTONE", vvalue); + sunstone = new VectorAttribute("SUNSTONE", vvalue); - obj_template->set(sunstone); - } - else - { - if ( sunstone->vector_value("DEFAULT_VIEW").empty() ) - { - sunstone->replace("DEFAULT_VIEW", user_default); - } + obj_template->set(sunstone); + } + else + { + if ( sunstone->vector_value("DEFAULT_VIEW").empty() ) + { + sunstone->replace("DEFAULT_VIEW", user_default); + } - if ( sunstone->vector_value("VIEWS").empty() ) - { - sunstone->replace("VIEWS", user_views); - } + if ( sunstone->vector_value("VIEWS").empty() ) + { + sunstone->replace("VIEWS", user_views); + } - if ( sunstone->vector_value("GROUP_ADMIN_DEFAULT_VIEW").empty() ) - { - sunstone->replace("GROUP_ADMIN_DEFAULT_VIEW", admin_default); - } + if ( sunstone->vector_value("GROUP_ADMIN_DEFAULT_VIEW").empty() ) + { + sunstone->replace("GROUP_ADMIN_DEFAULT_VIEW", admin_default); + } - if ( sunstone->vector_value("GROUP_ADMIN_VIEWS").empty() ) - { - sunstone->replace("GROUP_ADMIN_VIEWS", admin_views); - } - } + if ( sunstone->vector_value("GROUP_ADMIN_VIEWS").empty() ) + { + sunstone->replace("GROUP_ADMIN_VIEWS", admin_views); + } + } } - diff --git a/src/group/GroupPool.cc b/src/group/GroupPool.cc index 29a5edaf38..2912ce3059 100644 --- a/src/group/GroupPool.cc +++ b/src/group/GroupPool.cc @@ -38,7 +38,8 @@ const int GroupPool::USERS_ID = 1; /* -------------------------------------------------------------------------- */ GroupPool::GroupPool(SqlDB * db, vector hook_mads, - const string& remotes_location, bool is_federation_slave) : + const string& remotes_location, bool is_federation_slave, + vector& restricted_attrs) : PoolSQL(db, Group::table) { ostringstream oss; @@ -61,7 +62,7 @@ GroupPool::GroupPool(SqlDB * db, vector hook_mads, rc = PoolSQL::allocate(group, error_str); - if( rc < 0 ) + if (rc < 0) { goto error_groups; } @@ -72,7 +73,7 @@ GroupPool::GroupPool(SqlDB * db, vector hook_mads, rc = PoolSQL::allocate(group, error_str); - if(rc < 0) + if (rc < 0) { goto error_groups; } @@ -82,6 +83,9 @@ GroupPool::GroupPool(SqlDB * db, vector hook_mads, register_hooks(hook_mads, remotes_location); + // Set restricted attributes + GroupTemplate::parse_restricted(restricted_attrs); + return; error_groups: @@ -222,7 +226,7 @@ int GroupPool::drop(PoolObjectSQL * objsql, string& error_msg) /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -int GroupPool::dump(string& oss, const string& where, +int GroupPool::dump(string& oss, const string& where, const string& limit, bool desc) { int rc; diff --git a/src/group/GroupTemplate.cc b/src/group/GroupTemplate.cc new file mode 100644 index 0000000000..66836fac6a --- /dev/null +++ b/src/group/GroupTemplate.cc @@ -0,0 +1,22 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2019, OpenNebula Project, OpenNebula Systems */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); you may */ +/* not use this file except in compliance with the License. You may obtain */ +/* a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */ +/* See the License for the specific language governing permissions and */ +/* limitations under the License. */ +/* -------------------------------------------------------------------------- */ + +#include "GroupTemplate.h" + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +std::map> GroupTemplate::restricted; diff --git a/src/group/SConstruct b/src/group/SConstruct index 8fca4c4b09..3ff39623af 100644 --- a/src/group/SConstruct +++ b/src/group/SConstruct @@ -23,7 +23,8 @@ lib_name='nebula_group' # Sources to generate the library source_files=[ 'GroupPool.cc', - 'Group.cc' + 'Group.cc', + 'GroupTemplate.cc' ] # Build library diff --git a/src/lcm/LifeCycleActions.cc b/src/lcm/LifeCycleActions.cc index 40ad73d604..89de6d0e3d 100644 --- a/src/lcm/LifeCycleActions.cc +++ b/src/lcm/LifeCycleActions.cc @@ -55,13 +55,13 @@ void LifeCycleManager::deploy_action(const LCMAction& la) if (vm->hasPreviousHistory()) { - if (vm->get_previous_action() == History::STOP_ACTION) + if (vm->get_previous_action() == VMActions::STOP_ACTION) { vm_state = VirtualMachine::PROLOG_RESUME; tm_action = TMAction::PROLOG_RESUME; } - else if (vm->get_previous_action() == History::UNDEPLOY_ACTION || - vm->get_previous_action() == History::UNDEPLOY_HARD_ACTION) + else if (vm->get_previous_action() == VMActions::UNDEPLOY_ACTION || + vm->get_previous_action() == VMActions::UNDEPLOY_HARD_ACTION) { vm_state = VirtualMachine::PROLOG_UNDEPLOY; tm_action = TMAction::PROLOG_RESUME; @@ -125,7 +125,7 @@ void LifeCycleManager::suspend_action(const LCMAction& la) vm->set_resched(false); - vm->set_action(History::SUSPEND_ACTION, la.uid(), la.gid(), la.req_id()); + vm->set_action(VMActions::SUSPEND_ACTION, la.uid(), la.gid(), la.req_id()); vmpool->update_history(vm); @@ -170,7 +170,7 @@ void LifeCycleManager::stop_action(const LCMAction& la) vm->set_resched(false); - vm->set_action(History::STOP_ACTION, la.uid(), la.gid(), la.req_id()); + vm->set_action(VMActions::STOP_ACTION, la.uid(), la.gid(), la.req_id()); vmpool->update_history(vm); @@ -188,7 +188,7 @@ void LifeCycleManager::stop_action(const LCMAction& la) vm->set_state(VirtualMachine::ACTIVE); vm->set_state(VirtualMachine::EPILOG_STOP); - vm->set_action(History::STOP_ACTION, la.uid(), la.gid(), la.req_id()); + vm->set_action(VMActions::STOP_ACTION, la.uid(), la.gid(), la.req_id()); vm->set_epilog_stime(time(0)); @@ -235,18 +235,18 @@ void LifeCycleManager::migrate_action(const LCMAction& la) // SAVE_MIGRATE STATE //---------------------------------------------------- - History::VMAction action; + VMActions::Action action; switch (la.action()) { case LCMAction::POFF_MIGRATE : - action = History::POFF_MIGRATE_ACTION; + action = VMActions::POFF_MIGRATE_ACTION; break; case LCMAction::POFF_HARD_MIGRATE : - action = History::POFF_HARD_MIGRATE_ACTION; + action = VMActions::POFF_HARD_MIGRATE_ACTION; break; default : - action = History::MIGRATE_ACTION; + action = VMActions::MIGRATE_ACTION; break; } @@ -297,14 +297,14 @@ void LifeCycleManager::migrate_action(const LCMAction& la) if (vm->get_state() == VirtualMachine::POWEROFF) { vm->set_state(VirtualMachine::PROLOG_MIGRATE_POWEROFF); - vm->set_action(History::MIGRATE_ACTION, la.uid(), la.gid(), + vm->set_action(VMActions::MIGRATE_ACTION, la.uid(), la.gid(), la.req_id()); } else if (vm->get_state() == VirtualMachine::SUSPENDED) { vm->set_state(VirtualMachine::PROLOG_MIGRATE_SUSPEND); - vm->set_action(History::MIGRATE_ACTION, la.uid(), la.gid(), + vm->set_action(VMActions::MIGRATE_ACTION, la.uid(), la.gid(), la.req_id()); } else //VirtualMachine::UNKNOWN @@ -315,7 +315,7 @@ void LifeCycleManager::migrate_action(const LCMAction& la) vm->set_previous_etime(the_time); - vm->set_previous_action(History::MIGRATE_ACTION, la.uid(), la.gid(), + vm->set_previous_action(VMActions::MIGRATE_ACTION, la.uid(), la.gid(), la.req_id()); vm->set_previous_vm_info(); @@ -400,12 +400,12 @@ void LifeCycleManager::live_migrate_action(const LCMAction& la) vm->set_stime(time(0)); - vm->set_action(History::LIVE_MIGRATE_ACTION, la.uid(), la.gid(), + vm->set_action(VMActions::LIVE_MIGRATE_ACTION, la.uid(), la.gid(), la.req_id()); vmpool->update_history(vm); - vm->set_previous_action(History::LIVE_MIGRATE_ACTION, la.uid(),la.gid(), + vm->set_previous_action(VMActions::LIVE_MIGRATE_ACTION, la.uid(),la.gid(), la.req_id()); vmpool->update_previous_history(vm); @@ -475,14 +475,14 @@ void LifeCycleManager::shutdown_action(const LCMAction& la, bool hard) if (hard) { - vm->set_action(History::TERMINATE_HARD_ACTION, la.uid(), la.gid(), + vm->set_action(VMActions::TERMINATE_HARD_ACTION, la.uid(), la.gid(), la.req_id()); vmm->trigger(VMMAction::CANCEL,vid); } else { - vm->set_action(History::TERMINATE_ACTION, la.uid(), la.gid(), + vm->set_action(VMActions::TERMINATE_ACTION, la.uid(), la.gid(), la.req_id()); vmm->trigger(VMMAction::SHUTDOWN,vid); @@ -502,7 +502,7 @@ void LifeCycleManager::shutdown_action(const LCMAction& la, bool hard) Quotas::vm_check(uid, gid, "a_tmpl, error); - vm->set_action(History::TERMINATE_ACTION, la.uid(), la.gid(), + vm->set_action(VMActions::TERMINATE_ACTION, la.uid(), la.gid(), la.req_id()); vm->set_epilog_stime(time(0)); @@ -523,7 +523,7 @@ void LifeCycleManager::shutdown_action(const LCMAction& la, bool hard) Quotas::vm_check(uid, gid, "a_tmpl, error); - vm->set_action(History::TERMINATE_ACTION, la.uid(), la.gid(), + vm->set_action(VMActions::TERMINATE_ACTION, la.uid(), la.gid(), la.req_id()); vm->set_epilog_stime(time(0)); @@ -574,14 +574,14 @@ void LifeCycleManager::undeploy_action(const LCMAction& la, bool hard) if (hard) { - vm->set_action(History::UNDEPLOY_HARD_ACTION, la.uid(), la.gid(), + vm->set_action(VMActions::UNDEPLOY_HARD_ACTION, la.uid(), la.gid(), la.req_id()); vmm->trigger(VMMAction::CANCEL,vid); } else { - vm->set_action(History::UNDEPLOY_ACTION, la.uid(), la.gid(), + vm->set_action(VMActions::UNDEPLOY_ACTION, la.uid(), la.gid(), la.req_id()); vmm->trigger(VMMAction::SHUTDOWN,vid); @@ -608,7 +608,7 @@ void LifeCycleManager::undeploy_action(const LCMAction& la, bool hard) vm->set_state(VirtualMachine::ACTIVE); vm->set_state(VirtualMachine::EPILOG_UNDEPLOY); - vm->set_action(History::UNDEPLOY_ACTION, la.uid(), la.gid(), + vm->set_action(VMActions::UNDEPLOY_ACTION, la.uid(), la.gid(), la.req_id()); vm->set_epilog_stime(time(0)); @@ -678,14 +678,14 @@ void LifeCycleManager::poweroff_action(int vid, bool hard, const LCMAction& la) if (hard) { - vm->set_action(History::POWEROFF_HARD_ACTION, la.uid(), la.gid(), + vm->set_action(VMActions::POWEROFF_HARD_ACTION, la.uid(), la.gid(), la.req_id()); vmm->trigger(VMMAction::CANCEL,vid); } else { - vm->set_action(History::POWEROFF_ACTION, la.uid(), la.gid(), + vm->set_action(VMActions::POWEROFF_ACTION, la.uid(), la.gid(), la.req_id()); vmm->trigger(VMMAction::SHUTDOWN,vid); @@ -742,7 +742,7 @@ void LifeCycleManager::restore_action(const LCMAction& la) vm->set_running_stime(the_time); - vm->set_action(History::RESUME_ACTION, la.uid(), la.gid(), la.req_id()); + vm->set_action(VMActions::RESUME_ACTION, la.uid(), la.gid(), la.req_id()); vmpool->insert_history(vm); @@ -801,7 +801,7 @@ void LifeCycleManager::restart_action(const LCMAction& la) vm->set_running_stime(the_time); - vm->set_action(History::RESUME_ACTION, la.uid(), la.gid(), la.req_id()); + vm->set_action(VMActions::RESUME_ACTION, la.uid(), la.gid(), la.req_id()); vmpool->insert_history(vm); @@ -977,12 +977,12 @@ void LifeCycleManager::clean_up_vm(VirtualMachine * vm, bool dispose, if (dispose) { vm->set_state(VirtualMachine::CLEANUP_DELETE); - vm->set_action(History::DELETE_ACTION, la.uid(), la.gid(), la.req_id()); + vm->set_action(VMActions::DELETE_ACTION, la.uid(), la.gid(), la.req_id()); } else { vm->set_state(VirtualMachine::CLEANUP_RESUBMIT); - vm->set_action(History::DELETE_RECREATE_ACTION, la.uid(), la.gid(), + vm->set_action(VMActions::DELETE_RECREATE_ACTION, la.uid(), la.gid(), la.req_id()); } @@ -1617,7 +1617,7 @@ void LifeCycleManager::retry(VirtualMachine * vm) case VirtualMachine::SHUTDOWN: case VirtualMachine::SHUTDOWN_POWEROFF: case VirtualMachine::SHUTDOWN_UNDEPLOY: - if (vm->get_action() == History::TERMINATE_ACTION) + if (vm->get_action() == VMActions::TERMINATE_ACTION) { vmm->trigger(VMMAction::SHUTDOWN,vid); } diff --git a/src/lcm/LifeCycleStates.cc b/src/lcm/LifeCycleStates.cc index f1911b5a54..201fe0add9 100644 --- a/src/lcm/LifeCycleStates.cc +++ b/src/lcm/LifeCycleStates.cc @@ -673,8 +673,8 @@ void LifeCycleManager::prolog_success_action(int vid) case VirtualMachine::PROLOG_MIGRATE: case VirtualMachine::PROLOG_MIGRATE_FAILURE: //recover success - if (vm->get_action() == History::POFF_MIGRATE_ACTION || - vm->get_action() == History::POFF_HARD_MIGRATE_ACTION) + if (vm->get_action() == VMActions::POFF_MIGRATE_ACTION || + vm->get_action() == VMActions::POFF_HARD_MIGRATE_ACTION) { action = VMMAction::DEPLOY; vm->set_state(VirtualMachine::BOOT); @@ -1105,7 +1105,7 @@ void LifeCycleManager::monitor_suspend_action(int vid) vm->set_vm_info(); - vm->set_internal_action(History::MONITOR_ACTION); + vm->set_internal_action(VMActions::MONITOR_ACTION); vmpool->update_history(vm); @@ -1198,7 +1198,7 @@ void LifeCycleManager::monitor_poweroff_action(int vid) vm->set_vm_info(); - vm->set_internal_action(History::MONITOR_ACTION); + vm->set_internal_action(VMActions::MONITOR_ACTION); vmpool->update_history(vm); diff --git a/src/nebula/Nebula.cc b/src/nebula/Nebula.cc index 9b965250c2..9b20745a9b 100644 --- a/src/nebula/Nebula.cc +++ b/src/nebula/Nebula.cc @@ -639,20 +639,23 @@ void Nebula::start(bool bootstrap_only) /* ----------------------- Group/User Pool -------------------------- */ vector user_hooks; vector group_hooks; + vector user_restricted_attrs; + vector group_restricted_attrs; time_t expiration_time; nebula_configuration->get("GROUP_HOOK", group_hooks); + nebula_configuration->get("GROUP_RESTRICTED_ATTR", group_restricted_attrs); gpool = new GroupPool(db_ptr, group_hooks, remotes_location, - is_federation_slave()); + is_federation_slave(), group_restricted_attrs); nebula_configuration->get("SESSION_EXPIRATION_TIME", expiration_time); - nebula_configuration->get("USER_HOOK", user_hooks); + nebula_configuration->get("USER_RESTRICTED_ATTR", user_restricted_attrs); upool = new UserPool(db_ptr, expiration_time, user_hooks, - remotes_location, is_federation_slave()); + remotes_location, is_federation_slave(), user_restricted_attrs); /* -------------------- Image/Datastore Pool ------------------------ */ string image_type; diff --git a/src/nebula/NebulaTemplate.cc b/src/nebula/NebulaTemplate.cc index 51f4608a8c..c6141a2dd0 100644 --- a/src/nebula/NebulaTemplate.cc +++ b/src/nebula/NebulaTemplate.cc @@ -94,7 +94,7 @@ int OpenNebulaTemplate::load_configuration() return -1; } - if ( set_vm_auth_ops(error) != 0 ) + if ( vm_actions.set_auth_ops(*this, error) != 0 ) { cout << "\nError while parsing configuration file:\n" << error << endl; return -1; @@ -711,203 +711,3 @@ int OpenNebulaTemplate::load_key() return 0; } -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - -static int _set_vm_auth_ops(const std::string& ops_str, - ActionSet& ops_set, std::string& error_op) -{ - std::set ops; - std::set::iterator it; - - one_util::split_unique(ops_str, ',', ops); - - for ( it = ops.begin() ; it != ops.end() ; ++it ) - { - std::string the_op = one_util::trim(*it); - - one_util::tolower(the_op); - - if ( the_op == "migrate" ) - { - ops_set.set(History::MIGRATE_ACTION); - ops_set.set(History::LIVE_MIGRATE_ACTION); - } - else if ( the_op == "delete" ) - { - ops_set.set(History::DELETE_ACTION); - ops_set.set(History::DELETE_RECREATE_ACTION); - } - else if ( the_op == "recover" ) - { - ops_set.set(History::RECOVER_ACTION); - } - else if ( the_op == "retry" ) - { - ops_set.set(History::RETRY_ACTION); - } - else if ( the_op == "deploy" ) - { - ops_set.set(History::DEPLOY_ACTION); - } - else if ( the_op == "resched" ) - { - ops_set.set(History::RESCHED_ACTION); - ops_set.set(History::UNRESCHED_ACTION); - } - else if ( the_op == "undeploy" ) - { - ops_set.set(History::UNDEPLOY_ACTION); - ops_set.set(History::UNDEPLOY_HARD_ACTION); - } - else if ( the_op == "hold" ) - { - ops_set.set(History::HOLD_ACTION); - } - else if ( the_op == "release" ) - { - ops_set.set(History::RELEASE_ACTION); - } - else if ( the_op == "stop" ) - { - ops_set.set(History::STOP_ACTION); - } - else if ( the_op == "suspend" ) - { - ops_set.set(History::SUSPEND_ACTION); - } - else if ( the_op == "resume" ) - { - ops_set.set(History::RESUME_ACTION); - } - else if ( the_op == "reboot" ) - { - ops_set.set(History::REBOOT_ACTION); - ops_set.set(History::REBOOT_HARD_ACTION); - } - else if ( the_op == "poweroff" ) - { - ops_set.set(History::POWEROFF_ACTION); - ops_set.set(History::POWEROFF_HARD_ACTION); - } - else if ( the_op == "disk-attach" ) - { - ops_set.set(History::DISK_ATTACH_ACTION); - ops_set.set(History::DISK_DETACH_ACTION); - } - else if ( the_op == "nic-attach" ) - { - ops_set.set(History::NIC_ATTACH_ACTION); - ops_set.set(History::NIC_DETACH_ACTION); - } - else if ( the_op == "disk-snapshot" ) - { - ops_set.set(History::DISK_SNAPSHOT_CREATE_ACTION); - ops_set.set(History::DISK_SNAPSHOT_DELETE_ACTION); - ops_set.set(History::DISK_SNAPSHOT_REVERT_ACTION); - ops_set.set(History::DISK_SNAPSHOT_RENAME_ACTION); - } - else if ( the_op == "terminate" ) - { - ops_set.set(History::TERMINATE_ACTION); - ops_set.set(History::TERMINATE_HARD_ACTION); - } - else if ( the_op == "disk-resize" ) - { - ops_set.set(History::DISK_RESIZE_ACTION); - } - else if ( the_op == "snapshot" ) - { - ops_set.set(History::SNAPSHOT_CREATE_ACTION); - ops_set.set(History::SNAPSHOT_DELETE_ACTION); - ops_set.set(History::SNAPSHOT_REVERT_ACTION); - } - else if ( the_op == "updateconf" ) - { - ops_set.set(History::UPDATECONF_ACTION); - } - else if ( the_op == "rename" ) - { - ops_set.set(History::RENAME_ACTION); - } - else if ( the_op == "resize" ) - { - ops_set.set(History::RESIZE_ACTION); - } - else if ( the_op == "update" ) - { - ops_set.set(History::UPDATE_ACTION); - } - else if ( the_op == "disk-saveas" ) - { - ops_set.set(History::DISK_SAVEAS_ACTION); - } - else - { - error_op = the_op; - return -1; - } - } - - return 0; -} - -/* -------------------------------------------------------------------------- */ - -int OpenNebulaTemplate::set_vm_auth_ops(std::string& error) -{ - std::string error_op; - - std::string admin, manage, use; - - get("VM_ADMIN_OPERATIONS", admin); - - if ( _set_vm_auth_ops(admin, vm_admin_actions, error_op) != 0 ) - { - goto error_op; - } - - get("VM_MANAGE_OPERATIONS", manage); - - if ( _set_vm_auth_ops(manage, vm_manage_actions, error_op) != 0 ) - { - goto error_op; - } - - get("VM_USE_OPERATIONS", use); - - if ( _set_vm_auth_ops(use, vm_use_actions, error_op) != 0 ) - { - goto error_op; - } - - return 0; - -error_op: - error = "Unknown vm operation: " + error_op; - return -1; -} - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - -AuthRequest::Operation OpenNebulaTemplate::get_vm_auth_op(History::VMAction ac) -{ - if ( vm_admin_actions.is_set(ac) ) - { - return AuthRequest::ADMIN; - } - else if ( vm_manage_actions.is_set(ac) ) - { - return AuthRequest::MANAGE; - } - else if ( vm_use_actions.is_set(ac) ) - { - return AuthRequest::USE; - } - else - { - return AuthRequest::MANAGE; - } - -} diff --git a/src/rm/Request.cc b/src/rm/Request.cc index e38d6ae0aa..109874958d 100644 --- a/src/rm/Request.cc +++ b/src/rm/Request.cc @@ -356,7 +356,7 @@ void Request::execute( const xmlrpc_c::callInfo * _callInfoP, xmlrpc_c::value * const _retval) { - RequestAttributes att; + RequestAttributes att(auth_op); att.retval = _retval; att.session = xmlrpc_c::value_string(_paramList.getString(0)); @@ -371,6 +371,8 @@ void Request::execute( bool authenticated = upool->authenticate(att.session, att.password, att.uid, att.gid, att.uname, att.gname, att.group_ids, att.umask); + att.set_auth_op(vm_action); + if ( log_method_call ) { log_method_invoked(att, _paramList, format_str, method_name, @@ -440,11 +442,9 @@ void Request::execute( /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -bool Request::basic_authorization(int oid, - AuthRequest::Operation op, - RequestAttributes& att) +bool Request::basic_authorization(int oid, RequestAttributes& att) { - ErrorCode ec = basic_authorization(pool, oid, op, auth_object, att); + ErrorCode ec = basic_authorization(pool, oid, auth_object, att); if (ec == SUCCESS) { @@ -463,7 +463,6 @@ bool Request::basic_authorization(int oid, Request::ErrorCode Request::basic_authorization( PoolSQL* pool, int oid, - AuthRequest::Operation op, PoolObjectSQL::ObjectType auth_object, RequestAttributes& att) { @@ -493,7 +492,7 @@ Request::ErrorCode Request::basic_authorization( AuthRequest ar(att.uid, att.group_ids); - ar.add_auth(op, perms); + ar.add_auth(att.auth_op, perms); if (UserPool::authorize(ar) == -1) { @@ -942,25 +941,29 @@ int Request::get_info( /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -Request::ErrorCode Request::as_uid_gid(Template * tmpl, - RequestAttributes& att) +Request::ErrorCode Request::as_uid_gid(Template * tmpl, RequestAttributes& att) { string gname; string uname; PoolObjectAuth uperms; PoolObjectAuth gperms; + int uid = att.uid, as_uid = -1, as_gid = -1; + set gids = att.group_ids; + int rc; - UserPool * upool = Nebula::instance().get_upool(); + UserPool * upool = Nebula::instance().get_upool(); GroupPool * gpool = Nebula::instance().get_gpool(); if ( tmpl->get("AS_UID", as_uid) ) { tmpl->erase("AS_UID"); - rc = get_info(upool, as_uid, PoolObjectSQL::USER, att, uperms, uname,true); + + rc = get_info(upool, as_uid, PoolObjectSQL::USER, att, uperms, uname, + true); if ( rc == -1 ) { @@ -975,7 +978,9 @@ Request::ErrorCode Request::as_uid_gid(Template * tmpl, if ( tmpl->get("AS_GID", as_gid) ) { tmpl->erase("AS_GID"); - rc = get_info(gpool, as_gid, PoolObjectSQL::GROUP, att, gperms, gname,true); + + rc = get_info(gpool, as_gid, PoolObjectSQL::GROUP, att, gperms, gname, + true); if ( rc == -1 ) { @@ -1031,3 +1036,52 @@ Request::ErrorCode Request::as_uid_gid(Template * tmpl, /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ + +void RequestAttributes::set_auth_op(VMActions::Action action) +{ + if (action == VMActions::NONE_ACTION) + { + return; + } + + AuthRequest::Operation result = AuthRequest::NONE; + + auto& nd = Nebula::instance(); + auto user = nd.get_upool()->get_ro(uid); + + if (user != nullptr) + { + result = user->get_vm_auth_op(action); + } + + user->unlock(); + + if (result != AuthRequest::NONE) + { + auth_op = result; + return; + } + + auto group = nd.get_gpool()->get_ro(gid); + + if (group != nullptr) + { + result = group->get_vm_auth_op(action); + } + + group->unlock(); + + if (result != AuthRequest::NONE) + { + auth_op = result; + return; + } + + result = nd.get_vm_auth_op(action); + + if (result != AuthRequest::NONE) + { + auth_op = result; + } +} + diff --git a/src/rm/RequestManagerChown.cc b/src/rm/RequestManagerChown.cc index 9025af8764..5330efaf74 100644 --- a/src/rm/RequestManagerChown.cc +++ b/src/rm/RequestManagerChown.cc @@ -332,7 +332,7 @@ void RequestManagerChown::request_execute(xmlrpc_c::paramList const& paramList, return; } - ar.add_auth(auth_op, operms); // MANAGE OBJECT + ar.add_auth(att.auth_op, operms); // MANAGE OBJECT if ( noid > -1 ) { @@ -411,7 +411,7 @@ void RequestManagerChown::request_execute(xmlrpc_c::paramList const& paramList, } // --------------- Recursive change associated VM objects ------------------ - // IMPORTANT!: pool/auth_object members are redirected to the VM pool to + // IMPORTANT!: pool/auth_object members are redirected to the VM pool to // chown VMs // ------------------------------------------------------------------------- bool error_vm_quotas = false; @@ -546,7 +546,7 @@ void UserChown::request_execute(xmlrpc_c::paramList const& paramList, AuthRequest ar(att.uid, att.group_ids); - ar.add_auth(auth_op, uperms); // MANAGE USER + ar.add_auth(att.auth_op, uperms); // MANAGE USER ar.add_auth(AuthRequest::USE, ngperms); // USE GROUP if (UserPool::authorize(ar) == -1) diff --git a/src/rm/RequestManagerClone.cc b/src/rm/RequestManagerClone.cc index 132050e126..6d1fb0d7b5 100644 --- a/src/rm/RequestManagerClone.cc +++ b/src/rm/RequestManagerClone.cc @@ -89,7 +89,7 @@ Request::ErrorCode RequestManagerClone::clone(int source_id, const string &name, AuthRequest ar(att.uid, att.group_ids); - ar.add_auth(auth_op, perms); //USE OBJECT + ar.add_auth(att.auth_op, perms); //USE OBJECT tmpl->to_xml(tmpl_str); diff --git a/src/rm/RequestManagerCluster.cc b/src/rm/RequestManagerCluster.cc index b7842b00c9..5027938256 100644 --- a/src/rm/RequestManagerCluster.cc +++ b/src/rm/RequestManagerCluster.cc @@ -59,7 +59,7 @@ void RequestManagerCluster::action_generic( AuthRequest ar(att.uid, att.group_ids); - ar.add_auth(auth_op, c_perms); // ADMIN CLUSTER + ar.add_auth(att.auth_op, c_perms); // ADMIN CLUSTER ar.add_auth(AuthRequest::ADMIN, obj_perms); // ADMIN OBJECT if (UserPool::authorize(ar) == -1) @@ -218,7 +218,7 @@ void RequestManagerClusterHost::add_generic( AuthRequest ar(att.uid, att.group_ids); - ar.add_auth(auth_op, c_perms); // ADMIN CLUSTER + ar.add_auth(att.auth_op, c_perms); // ADMIN CLUSTER ar.add_auth(AuthRequest::ADMIN, obj_perms); // ADMIN HOST if (UserPool::authorize(ar) == -1) diff --git a/src/rm/RequestManagerDelete.cc b/src/rm/RequestManagerDelete.cc index 7db2088d46..3435ddde0c 100644 --- a/src/rm/RequestManagerDelete.cc +++ b/src/rm/RequestManagerDelete.cc @@ -20,8 +20,8 @@ /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -static Request::ErrorCode delete_authorization(PoolSQL* pool, - int oid, AuthRequest::Operation auth_op, RequestAttributes& att) +static Request::ErrorCode delete_authorization(PoolSQL* pool, int oid, + RequestAttributes& att) { PoolObjectAuth perms; @@ -39,7 +39,7 @@ static Request::ErrorCode delete_authorization(PoolSQL* pool, AuthRequest ar(att.uid, att.group_ids); - ar.add_auth(auth_op, perms); // OBJECT + ar.add_auth(att.auth_op, perms); // OBJECT if (UserPool::authorize(ar) == -1) { @@ -64,7 +64,7 @@ void RequestManagerDelete::request_execute(xmlrpc_c::paramList const& paramList, recursive = xmlrpc_c::value_boolean(paramList.getBoolean(2)); } - ErrorCode ec = delete_object(oid, recursive, att, auth_op); + ErrorCode ec = delete_object(oid, recursive, att); if ( ec == SUCCESS ) { @@ -79,10 +79,8 @@ void RequestManagerDelete::request_execute(xmlrpc_c::paramList const& paramList, void ImageDelete::request_execute(xmlrpc_c::paramList const& paramList, RequestAttributes& att) { - int oid = xmlrpc_c::value_int(paramList.getInt(1)); - AuthRequest::Operation auth = auth_op; + int oid = xmlrpc_c::value_int(paramList.getInt(1)); - //get the image Image* img = static_cast(pool)->get_ro(oid); if (img == 0) @@ -94,12 +92,12 @@ void ImageDelete::request_execute(xmlrpc_c::paramList const& paramList, if (img->is_locked()) { - auth = AuthRequest::ADMIN; + att.auth_op = AuthRequest::ADMIN; } img->unlock(); - ErrorCode ec = delete_object(oid, false, att, auth); + ErrorCode ec = delete_object(oid, false, att); if ( ec == SUCCESS ) { @@ -115,13 +113,13 @@ void ImageDelete::request_execute(xmlrpc_c::paramList const& paramList, /* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */ -Request::ErrorCode RequestManagerDelete::delete_object(int oid, - bool recursive, RequestAttributes& att, AuthRequest::Operation auth) +Request::ErrorCode RequestManagerDelete::delete_object(int oid, bool recursive, + RequestAttributes& att) { string err; ErrorCode ec; - ec = delete_authorization(pool, oid, auth, att); + ec = delete_authorization(pool, oid, att); if ( ec != SUCCESS ) { diff --git a/src/rm/RequestManagerImage.cc b/src/rm/RequestManagerImage.cc index 6b93adf6cc..c8b9ecf39f 100644 --- a/src/rm/RequestManagerImage.cc +++ b/src/rm/RequestManagerImage.cc @@ -99,8 +99,7 @@ Request::ErrorCode ImagePersistent::request_execute( ErrorCode ec; - ec = basic_authorization(ipool, id, - AuthRequest::MANAGE, PoolObjectSQL::IMAGE, att); + ec = basic_authorization(ipool, id, PoolObjectSQL::IMAGE, att); if ( ec != SUCCESS) { diff --git a/src/rm/RequestManagerInfo.cc b/src/rm/RequestManagerInfo.cc index edb62a69af..3ca66fabd4 100644 --- a/src/rm/RequestManagerInfo.cc +++ b/src/rm/RequestManagerInfo.cc @@ -120,7 +120,7 @@ void TemplateInfo::request_execute(xmlrpc_c::paramList const& paramList, AuthRequest ar(att.uid, att.group_ids); - ar.add_auth(auth_op, perms); //USE TEMPLATE + ar.add_auth(att.auth_op, perms); //USE TEMPLATE if (extended) { @@ -209,7 +209,7 @@ void VirtualNetworkTemplateInfo::request_execute(xmlrpc_c::paramList const& para AuthRequest ar(att.uid, att.group_ids); - ar.add_auth(auth_op, perms); //USE TEMPLATE + ar.add_auth(att.auth_op, perms); //USE TEMPLATE if (UserPool::authorize(ar) == -1) { diff --git a/src/rm/RequestManagerRename.cc b/src/rm/RequestManagerRename.cc index ddbd2f13b2..5229c24721 100644 --- a/src/rm/RequestManagerRename.cc +++ b/src/rm/RequestManagerRename.cc @@ -63,7 +63,7 @@ void RequestManagerRename::request_execute(xmlrpc_c::paramList const& paramList, AuthRequest ar(att.uid, att.group_ids); - ar.add_auth(auth_op, operms); // MANAGE OBJECT + ar.add_auth(att.auth_op, operms); // MANAGE OBJECT if (UserPool::authorize(ar) == -1) { diff --git a/src/rm/RequestManagerUpdateTemplate.cc b/src/rm/RequestManagerUpdateTemplate.cc index 9fc81a6edd..7c1dca1290 100644 --- a/src/rm/RequestManagerUpdateTemplate.cc +++ b/src/rm/RequestManagerUpdateTemplate.cc @@ -127,4 +127,3 @@ void RequestManagerUpdateTemplate::request_execute( return; } - diff --git a/src/rm/RequestManagerUser.cc b/src/rm/RequestManagerUser.cc index 8f0bc6a701..f7eebf83ff 100644 --- a/src/rm/RequestManagerUser.cc +++ b/src/rm/RequestManagerUser.cc @@ -430,7 +430,7 @@ void UserLogin::request_execute(xmlrpc_c::paramList const& paramList, AuthRequest ar(att.uid, att.group_ids); - ar.add_auth(auth_op, perms); + ar.add_auth(att.auth_op, perms); if (UserPool::authorize(ar) == -1) { diff --git a/src/rm/RequestManagerVirtualMachine.cc b/src/rm/RequestManagerVirtualMachine.cc index 6a7db31b32..294df63250 100644 --- a/src/rm/RequestManagerVirtualMachine.cc +++ b/src/rm/RequestManagerVirtualMachine.cc @@ -30,8 +30,7 @@ bool RequestManagerVirtualMachine::vm_authorization( RequestAttributes& att, PoolObjectAuth * host_perm, PoolObjectAuth * ds_perm, - PoolObjectAuth * img_perm, - AuthRequest::Operation op) + PoolObjectAuth * img_perm) { PoolObjectSQL * object; PoolObjectAuth vm_perms; @@ -52,7 +51,7 @@ bool RequestManagerVirtualMachine::vm_authorization( AuthRequest ar(att.uid, att.group_ids); - ar.add_auth(op, vm_perms); + ar.add_auth(att.auth_op, vm_perms); if (host_perm != nullptr) { @@ -496,8 +495,7 @@ void VirtualMachineAction::request_execute(xmlrpc_c::paramList const& paramList, ostringstream oss; string error; - AuthRequest::Operation op; - History::VMAction action; + VMActions::Action action; VirtualMachineTemplate quota_tmpl; @@ -513,11 +511,12 @@ void VirtualMachineAction::request_execute(xmlrpc_c::paramList const& paramList, action_st = "terminate"; } - History::action_from_str(action_st, action); + VMActions::action_from_str(action_st, action); - op = nd.get_vm_auth_op(action); + // Update the authorization level for the action + att.set_auth_op(action); - if ( vm_authorization(id, 0, 0, att, 0, 0, 0, op) == false ) + if (vm_authorization(id, 0, 0, att, 0, 0, 0) == false) { return; } @@ -527,21 +526,7 @@ void VirtualMachineAction::request_execute(xmlrpc_c::paramList const& paramList, return; } - vm->get_template_attribute("MEMORY", memory); - vm->get_template_attribute("CPU", cpu); - - quota_tmpl.add("RUNNING_MEMORY", memory); - quota_tmpl.add("RUNNING_CPU", cpu); - quota_tmpl.add("RUNNING_VMS", 1); - - quota_tmpl.add("VMS", 0); - quota_tmpl.add("MEMORY", 0); - quota_tmpl.add("CPU", 0); - - RequestAttributes& att_aux(att); - att_aux.uid = vm->get_uid(); - att_aux.gid = vm->get_gid(); - + // Check if the action is supported for imported VMs if (vm->is_imported() && !vm->is_imported_action_supported(action)) { att.resp_msg = "Action \"" + action_st + "\" is not supported for " @@ -553,11 +538,30 @@ void VirtualMachineAction::request_execute(xmlrpc_c::paramList const& paramList, return; } + // Generate quota information for resume action + RequestAttributes& att_aux(att); + + if (action == VMActions::RESUME_ACTION) + { + vm->get_template_attribute("MEMORY", memory); + vm->get_template_attribute("CPU", cpu); + + quota_tmpl.add("RUNNING_MEMORY", memory); + quota_tmpl.add("RUNNING_CPU", cpu); + quota_tmpl.add("RUNNING_VMS", 1); + + quota_tmpl.add("VMS", 0); + quota_tmpl.add("MEMORY", 0); + quota_tmpl.add("CPU", 0); + + att_aux.uid = vm->get_uid(); + att_aux.gid = vm->get_gid(); + } + vm->unlock(); - if ( action == History::RESUME_ACTION && - !quota_authorization("a_tmpl, Quotas::VIRTUALMACHINE, att_aux, - att.resp_msg) ) + if (action == VMActions::RESUME_ACTION && !quota_authorization("a_tmpl, + Quotas::VIRTUALMACHINE, att_aux, att.resp_msg)) { failure_response(ACTION, att); return; @@ -565,49 +569,49 @@ void VirtualMachineAction::request_execute(xmlrpc_c::paramList const& paramList, switch (action) { - case History::TERMINATE_ACTION: + case VMActions::TERMINATE_ACTION: rc = dm->terminate(id, false, att, error); break; - case History::TERMINATE_HARD_ACTION: + case VMActions::TERMINATE_HARD_ACTION: rc = dm->terminate(id, true, att, error); break; - case History::HOLD_ACTION: + case VMActions::HOLD_ACTION: rc = dm->hold(id, att, error); break; - case History::RELEASE_ACTION: + case VMActions::RELEASE_ACTION: rc = dm->release(id, att, error); break; - case History::STOP_ACTION: + case VMActions::STOP_ACTION: rc = dm->stop(id, att, error); break; - case History::SUSPEND_ACTION: + case VMActions::SUSPEND_ACTION: rc = dm->suspend(id, att, error); break; - case History::RESUME_ACTION: + case VMActions::RESUME_ACTION: rc = dm->resume(id, att, error); break; - case History::REBOOT_ACTION: + case VMActions::REBOOT_ACTION: rc = dm->reboot(id, false, att, error); break; - case History::REBOOT_HARD_ACTION: + case VMActions::REBOOT_HARD_ACTION: rc = dm->reboot(id, true, att, error); break; - case History::RESCHED_ACTION: + case VMActions::RESCHED_ACTION: rc = dm->resched(id, true, att, error); break; - case History::UNRESCHED_ACTION: + case VMActions::UNRESCHED_ACTION: rc = dm->resched(id, false, att, error); break; - case History::POWEROFF_ACTION: + case VMActions::POWEROFF_ACTION: rc = dm->poweroff(id, false, att, error); break; - case History::POWEROFF_HARD_ACTION: + case VMActions::POWEROFF_HARD_ACTION: rc = dm->poweroff(id, true, att, error); break; - case History::UNDEPLOY_ACTION: + case VMActions::UNDEPLOY_ACTION: rc = dm->undeploy(id, false, att, error); break; - case History::UNDEPLOY_HARD_ACTION: + case VMActions::UNDEPLOY_HARD_ACTION: rc = dm->undeploy(id, true, att, error); break; default: @@ -702,7 +706,7 @@ int set_vnc_port(VirtualMachine *vm, int cluster_id, RequestAttributes& att) { return 0; } - else if (vm->hasHistory() && vm->get_action()==History::STOP_ACTION) + else if (vm->hasHistory() && vm->get_action()==VMActions::STOP_ACTION) { return 0; } @@ -761,6 +765,7 @@ void VirtualMachineDeploy::request_execute(xmlrpc_c::paramList const& paramList, bool auth = false; bool check_nic_auto = false; + // ------------------------------------------------------------------------ // Get request parameters and information about the target host // ------------------------------------------------------------------------ @@ -815,9 +820,9 @@ void VirtualMachineDeploy::request_execute(xmlrpc_c::paramList const& paramList, } if (vm->hasHistory() && - (vm->get_action() == History::STOP_ACTION || - vm->get_action() == History::UNDEPLOY_ACTION || - vm->get_action() == History::UNDEPLOY_HARD_ACTION)) + (vm->get_action() == VMActions::STOP_ACTION || + vm->get_action() == VMActions::UNDEPLOY_ACTION || + vm->get_action() == VMActions::UNDEPLOY_HARD_ACTION)) { ds_id = vm->get_ds_id(); @@ -924,13 +929,11 @@ void VirtualMachineDeploy::request_execute(xmlrpc_c::paramList const& paramList, return; } - auth = vm_authorization(id, 0, &tmpl, att, &host_perms, auth_ds_perms,0, - auth_op); + auth = vm_authorization(id, 0, &tmpl, att, &host_perms, auth_ds_perms,0); } else { - auth = vm_authorization(id, 0, 0, att, &host_perms, auth_ds_perms, 0, - auth_op); + auth = vm_authorization(id, 0, 0, att, &host_perms, auth_ds_perms, 0); } if (auth == false) @@ -1068,7 +1071,7 @@ void VirtualMachineMigrate::request_execute(xmlrpc_c::paramList const& paramList string error; - History::VMAction action; + VMActions::Action action; // ------------------------------------------------------------------------ // Get request parameters and information about the target host @@ -1134,8 +1137,7 @@ void VirtualMachineMigrate::request_execute(xmlrpc_c::paramList const& paramList // ------------------------------------------------------------------------ // Authorize request // ------------------------------------------------------------------------ - - auth = vm_authorization(id, 0, 0, att, &host_perms, auth_ds_perms, 0, auth_op); + auth = vm_authorization(id, 0, 0, att, &host_perms, auth_ds_perms, 0); if (auth == false) { @@ -1174,7 +1176,7 @@ void VirtualMachineMigrate::request_execute(xmlrpc_c::paramList const& paramList if (live) { - action = History::LIVE_MIGRATE_ACTION; + action = VMActions::LIVE_MIGRATE_ACTION; if ( vm->is_pinned() ) { @@ -1187,7 +1189,7 @@ void VirtualMachineMigrate::request_execute(xmlrpc_c::paramList const& paramList } else { - action = History::MIGRATE_ACTION; + action = VMActions::MIGRATE_ACTION; } if (vm->is_imported() && !vm->is_imported_action_supported(action)) @@ -1589,7 +1591,7 @@ void VirtualMachineDiskSaveas::request_execute( // ------------------------------------------------------------------------- // Authorize the operation & check quotas // ------------------------------------------------------------------------- - rc_auth = vm_authorization(id, itemplate, 0, att, 0,&ds_perms,0,auth_op); + rc_auth = vm_authorization(id, itemplate, 0, att, 0, &ds_perms, 0); if ( rc_auth == true ) { @@ -1720,7 +1722,7 @@ void VirtualMachineMonitoring::request_execute( string oss; - bool auth = vm_authorization(id, 0, 0, att, 0, 0, 0, auth_op); + bool auth = vm_authorization(id, 0, 0, att, 0, 0, 0); if ( auth == false ) { @@ -1829,8 +1831,7 @@ Request::ErrorCode VirtualMachineAttach::request_execute(int id, // ------------------------------------------------------------------------- // Authorize the operation & check quotas // ------------------------------------------------------------------------- - - if ( vm_authorization(id, 0, &tmpl, att, 0, 0, 0, auth_op) == false ) + if (vm_authorization(id, 0, &tmpl, att, 0, 0, 0) == false) { return AUTHORIZATION; } @@ -1914,8 +1915,7 @@ void VirtualMachineDetach::request_execute(xmlrpc_c::paramList const& paramList, // ------------------------------------------------------------------------- // Authorize the operation // ------------------------------------------------------------------------- - - if ( vm_authorization(id, 0, 0, att, 0, 0, 0, auth_op) == false ) + if (vm_authorization(id, 0, 0, att, 0, 0, 0) == false) { return; } @@ -2038,7 +2038,7 @@ void VirtualMachineResize::request_execute(xmlrpc_c::paramList const& paramList, /* ---------------------------------------------------------------------- */ /* Authorize the operation & restricted attributes */ /* ---------------------------------------------------------------------- */ - if ( vm_authorization(id, 0, 0, att, 0, 0, 0, auth_op) == false ) + if (vm_authorization(id, 0, 0, att, 0, 0, 0) == false) { return; } @@ -2217,8 +2217,7 @@ void VirtualMachineSnapshotCreate::request_execute( // ------------------------------------------------------------------------- // Authorize the operation // ------------------------------------------------------------------------- - - if ( vm_authorization(id, 0, 0, att, 0, 0, 0, auth_op) == false ) + if (vm_authorization(id, 0, 0, att, 0, 0, 0) == false) { return; } @@ -2255,8 +2254,7 @@ void VirtualMachineSnapshotRevert::request_execute( // ------------------------------------------------------------------------- // Authorize the operation // ------------------------------------------------------------------------- - - if ( vm_authorization(id, 0, 0, att, 0, 0, 0, auth_op) == false ) + if (vm_authorization(id, 0, 0, att, 0, 0, 0) == false) { return; } @@ -2293,8 +2291,7 @@ void VirtualMachineSnapshotDelete::request_execute( // ------------------------------------------------------------------------- // Authorize the operation // ------------------------------------------------------------------------- - - if ( vm_authorization(id, 0, 0, att, 0, 0, 0, auth_op) == false ) + if (vm_authorization(id, 0, 0, att, 0, 0, 0) == false) { return; } @@ -2560,23 +2557,21 @@ void VirtualMachineRecover::request_execute( Nebula& nd = Nebula::instance(); DispatchManager * dm = nd.get_dm(); - AuthRequest::Operation aop; - switch (op) { case 0: //recover-failure case 1: //recover-success - aop = nd.get_vm_auth_op(History::RECOVER_ACTION); + att.set_auth_op(VMActions::RECOVER_ACTION); break; case 2: //retry - aop = nd.get_vm_auth_op(History::RETRY_ACTION); + att.set_auth_op(VMActions::RETRY_ACTION); break; case 3: //delete case 4: //delete-recreate set same as delete in OpenNebulaTemplate case 5: //delete-db - aop = nd.get_vm_auth_op(History::DELETE_ACTION); + att.set_auth_op(VMActions::DELETE_ACTION); break; default: @@ -2585,7 +2580,7 @@ void VirtualMachineRecover::request_execute( return; } - if ( vm_authorization(id, 0, 0, att, 0, 0, 0, aop) == false ) + if (vm_authorization(id, 0, 0, att, 0, 0, 0) == false) { return; } @@ -2751,14 +2746,10 @@ void VirtualMachineDiskSnapshotCreate::request_execute( } /* ---------- Attributes for quota update requests ---------------------- */ - - RequestAttributes img_att_quota; - RequestAttributes vm_att_quota; + PoolObjectAuth img_perms; if (img_ds_quota) { - PoolObjectAuth img_perms; - Image* img = ipool->get_ro(img_id); if (img == nullptr) @@ -2774,19 +2765,21 @@ void VirtualMachineDiskSnapshotCreate::request_execute( img->unlock(); - if (vm_authorization(id, 0, 0, att, 0, 0, &img_perms, auth_op) == false) + if (vm_authorization(id, 0, 0, att, 0, 0, &img_perms) == false) { return; } - img_att_quota = RequestAttributes(img_perms.uid, img_perms.gid, att); } - if ( vm_authorization(id, 0, 0, att, 0, 0, 0, auth_op) == false ) + if (vm_authorization(id, 0, 0, att, 0, 0, 0) == false) { return; } - vm_att_quota = RequestAttributes(vm_perms.uid, vm_perms.gid, att); + RequestAttributes vm_att_quota = RequestAttributes(vm_perms.uid, + vm_perms.gid, att); + RequestAttributes img_att_quota = RequestAttributes(img_perms.uid, + img_perms.gid, att); /* ---------------------------------------------------------------------- */ /* Check quotas for the new size in image/system datastoress */ @@ -2874,7 +2867,7 @@ void VirtualMachineDiskSnapshotRevert::request_execute( int did = xmlrpc_c::value_int(paramList.getInt(2)); int snap_id = xmlrpc_c::value_int(paramList.getInt(3)); - if ( vm_authorization(id, 0, 0, att, 0, 0, 0, auth_op) == false ) + if (vm_authorization(id, 0, 0, att, 0, 0, 0) == false) { return; } @@ -2955,12 +2948,12 @@ void VirtualMachineDiskSnapshotDelete::request_execute( img->unlock(); - if (vm_authorization(id, 0, 0, att, 0, 0, &img_perms, auth_op) == false) + if (vm_authorization(id, 0, 0, att, 0, 0, &img_perms) == false) { return; } } - else if ( vm_authorization(id, 0, 0, att, 0, 0, 0, auth_op) == false ) + else if (vm_authorization(id, 0, 0, att, 0, 0, 0) == false) { return; } @@ -2998,7 +2991,7 @@ void VirtualMachineDiskSnapshotRename::request_execute(xmlrpc_c::paramList const int snap_id = xmlrpc_c::value_int(paramList.getInt(3)); string new_snap_name = xmlrpc_c::value_string(paramList.getString(4)); - if ( vm_authorization(id, 0, 0, att, 0, 0, 0, auth_op) == false ) + if (vm_authorization(id, 0, 0, att, 0, 0, 0) == false) { return; } @@ -3072,7 +3065,7 @@ void VirtualMachineUpdateConf::request_execute( /* ---------------------------------------------------------------------- */ /* Authorize the operation & restricted attributes */ /* ---------------------------------------------------------------------- */ - if ( vm_authorization(id, 0, 0, att, 0, 0, 0, auth_op) == false ) + if (vm_authorization(id, 0, 0, att, 0, 0, 0) == false) { return; } @@ -3260,13 +3253,10 @@ void VirtualMachineDiskResize::request_execute( /* ---------------------------------------------------------------------- */ /* Authorize the request for VM and IMAGE for persistent disks */ /* ---------------------------------------------------------------------- */ - RequestAttributes img_att_quota; - RequestAttributes vm_att_quota; + PoolObjectAuth img_perms; if ( img_ds_quota ) { - PoolObjectAuth img_perms; - if ( img_id != -1 ) { Image* img = ipool->get_ro(img_id); @@ -3285,23 +3275,24 @@ void VirtualMachineDiskResize::request_execute( img->unlock(); } - if (vm_authorization(id, 0, 0, att, 0, 0, &img_perms, auth_op) == false) + if (vm_authorization(id, 0, 0, att, 0, 0, &img_perms) == false) { return; } - - img_att_quota = RequestAttributes(img_perms.uid, img_perms.gid, att); } if ( vm_ds_quota ) { - if ( vm_authorization(id, 0, 0, att, 0, 0, 0, auth_op) == false ) + if (vm_authorization(id, 0, 0, att, 0, 0, 0) == false) { return; } } - vm_att_quota = RequestAttributes(vm_perms.uid, vm_perms.gid, att); + RequestAttributes img_att_quota = RequestAttributes(img_perms.uid, + img_perms.gid, att); + RequestAttributes vm_att_quota = RequestAttributes(vm_perms.uid, + vm_perms.gid, att); /* ---------------------------------------------------------------------- */ /* Check quotas for the new size in image/system datastoress */ diff --git a/src/scheduler/src/pool/VirtualMachineXML.cc b/src/scheduler/src/pool/VirtualMachineXML.cc index 6696d25b11..d0610e81d9 100644 --- a/src/scheduler/src/pool/VirtualMachineXML.cc +++ b/src/scheduler/src/pool/VirtualMachineXML.cc @@ -57,8 +57,8 @@ void VirtualMachineXML::init_attributes() resched = tmp == 1; xpath(action, "/VM/HISTORY_RECORDS/HISTORY/ACTION", -1); - resume = (action == History::STOP_ACTION || action == History::UNDEPLOY_ACTION - || action == History::UNDEPLOY_HARD_ACTION ); + resume = (action == VMActions::STOP_ACTION || action == VMActions::UNDEPLOY_ACTION + || action == VMActions::UNDEPLOY_HARD_ACTION ); xpath(hid, "/VM/HISTORY_RECORDS/HISTORY/HID", -1); xpath(dsid, "/VM/HISTORY_RECORDS/HISTORY/DS_ID", -1); diff --git a/src/um/SConstruct b/src/um/SConstruct index 897292d8f0..dcbad17135 100644 --- a/src/um/SConstruct +++ b/src/um/SConstruct @@ -24,6 +24,7 @@ lib_name='nebula_um' source_files=[ 'User.cc', 'UserPool.cc', + 'UserTemplate.cc', 'Quota.cc', 'QuotaDatastore.cc', 'QuotaNetwork.cc', diff --git a/src/um/User.cc b/src/um/User.cc index 29a9cb9706..d614344496 100644 --- a/src/um/User.cc +++ b/src/um/User.cc @@ -267,7 +267,11 @@ string& User::to_xml_extended(string& xml, bool extended) const int User::from_xml(const string& xml) { int rc = 0; + int int_enabled; + + string error; + vector content; // Initialize the internal XML object @@ -309,6 +313,8 @@ int User::from_xml(const string& xml) ObjectXML::free_nodes(content); content.clear(); + rc += vm_actions.set_auth_ops(*obj_template, error); + rc += groups.from_xml(this, "/USER/"); if (rc != 0) @@ -435,5 +441,3 @@ int User::get_default_umask() return (umask & 0777); } -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ diff --git a/src/um/UserPool.cc b/src/um/UserPool.cc index dc7926d3b4..72be1d0270 100644 --- a/src/um/UserPool.cc +++ b/src/um/UserPool.cc @@ -51,11 +51,12 @@ string UserPool::oneadmin_name; /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -UserPool::UserPool(SqlDB * db, - time_t __session_expiration_time, - vector hook_mads, - const string& remotes_location, - bool is_federation_slave): +UserPool::UserPool(SqlDB * db, + time_t __session_expiration_time, + vector hook_mads, + const string& remotes_location, + bool is_federation_slave, + vector& restricted_attrs): PoolSQL(db, User::table) { int one_uid = -1; @@ -186,6 +187,9 @@ UserPool::UserPool(SqlDB * db, register_hooks(hook_mads, remotes_location); + // Set restricted attributes + UserTemplate::parse_restricted(restricted_attrs); + return; error_readoneauth: @@ -305,7 +309,7 @@ static int master_chgrp(int user_id, int group_id, string& error_str) /* -------------------------------------------------------------------------- */ -int UserPool::allocate ( +int UserPool::allocate( int * oid, const string& uname, int gid, diff --git a/src/um/UserTemplate.cc b/src/um/UserTemplate.cc new file mode 100644 index 0000000000..092393d6b2 --- /dev/null +++ b/src/um/UserTemplate.cc @@ -0,0 +1,22 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2019, OpenNebula Project, OpenNebula Systems */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); you may */ +/* not use this file except in compliance with the License. You may obtain */ +/* a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */ +/* See the License for the specific language governing permissions and */ +/* limitations under the License. */ +/* -------------------------------------------------------------------------- */ + +#include "UserTemplate.h" + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +std::map> UserTemplate::restricted; diff --git a/src/vm/History.cc b/src/vm/History.cc index 75eec7cb46..3427e44a66 100644 --- a/src/vm/History.cc +++ b/src/vm/History.cc @@ -57,7 +57,7 @@ History::History( running_etime(0), epilog_stime(0), epilog_etime(0), - action(NONE_ACTION), + action(VMActions::NONE_ACTION), vm_info(""){}; /* -------------------------------------------------------------------------- */ @@ -91,7 +91,7 @@ History::History( running_etime(0), epilog_stime(0), epilog_etime(0), - action(NONE_ACTION), + action(VMActions::NONE_ACTION), vm_info(_vm_info) { non_persistent_data(); @@ -456,7 +456,7 @@ int History::rebuild_attributes() rc += xpath(gid, "/HISTORY/GID", -1); rc += xpath(req_id, "/HISTORY/REQUEST_ID", -1); - action = static_cast(int_action); + action = static_cast(int_action); // ------------------------------------------------------------------------- ObjectXML::get_nodes("/HISTORY/VM", content); @@ -486,344 +486,3 @@ int History::rebuild_attributes() return 0; } -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - -string History::action_to_str(VMAction action) -{ - string st; - - switch (action) - { - case MIGRATE_ACTION: - st = "migrate"; - break; - case POFF_MIGRATE_ACTION: - st = "poweroff-migrate"; - break; - case POFF_HARD_MIGRATE_ACTION: - st = "poweroff-hard-migrate"; - break; - case LIVE_MIGRATE_ACTION: - st = "live-migrate"; - break; - case TERMINATE_ACTION: - st = "terminate"; - break; - case TERMINATE_HARD_ACTION: - st = "terminate-hard"; - break; - case UNDEPLOY_ACTION: - st = "undeploy"; - break; - case UNDEPLOY_HARD_ACTION: - st = "undeploy-hard"; - break; - case HOLD_ACTION: - st = "hold"; - break; - case RELEASE_ACTION: - st = "release"; - break; - case STOP_ACTION: - st = "stop"; - break; - case SUSPEND_ACTION: - st = "suspend"; - break; - case RESUME_ACTION: - st = "resume"; - break; - case DELETE_ACTION: - st = "delete"; - break; - case DELETE_RECREATE_ACTION: - st = "delete-recreate"; - break; - case REBOOT_ACTION: - st = "reboot"; - break; - case REBOOT_HARD_ACTION: - st = "reboot-hard"; - break; - case RESCHED_ACTION: - st = "resched"; - break; - case UNRESCHED_ACTION: - st = "unresched"; - break; - case POWEROFF_ACTION: - st = "poweroff"; - break; - case POWEROFF_HARD_ACTION: - st = "poweroff-hard"; - break; - case DISK_ATTACH_ACTION: - st = "disk-attach"; - break; - case DISK_DETACH_ACTION: - st = "disk-detach"; - break; - case NIC_ATTACH_ACTION: - st = "nic-attach"; - break; - case NIC_DETACH_ACTION: - st = "nic-detach"; - break; - case ALIAS_ATTACH_ACTION: - st = "alias-attach"; - break; - case ALIAS_DETACH_ACTION: - st = "alias-detach"; - break; - case DISK_SNAPSHOT_CREATE_ACTION: - st = "disk-snapshot-create"; - break; - case DISK_SNAPSHOT_DELETE_ACTION: - st = "disk-snapshot-delete"; - break; - case DISK_SNAPSHOT_RENAME_ACTION: - st = "disk-snapshot-rename"; - break; - case DISK_RESIZE_ACTION: - st = "disk-resize"; - break; - case DEPLOY_ACTION: - st = "deploy"; - break; - case CHOWN_ACTION: - st = "chown"; - break; - case CHMOD_ACTION: - st = "chmod"; - break; - case UPDATECONF_ACTION: - st = "updateconf"; - break; - case RENAME_ACTION: - st = "rename"; - break; - case RESIZE_ACTION: - st = "resize"; - break; - case UPDATE_ACTION: - st = "update"; - break; - case SNAPSHOT_CREATE_ACTION: - st = "snapshot-create"; - break; - case SNAPSHOT_DELETE_ACTION: - st = "snapshot-delete"; - break; - case SNAPSHOT_REVERT_ACTION: - st = "snapshot-revert"; - break; - case DISK_SAVEAS_ACTION: - st = "disk-saveas"; - break; - case DISK_SNAPSHOT_REVERT_ACTION: - st = "disk-snapshot-revert"; - break; - case RECOVER_ACTION: - st = "recover"; - break; - case RETRY_ACTION: - st = "retry"; - break; - case MONITOR_ACTION: - st = "monitor"; - break; - case NONE_ACTION: - st = "none"; - break; - } - - return st; -}; - -int History::action_from_str(const string& st, VMAction& action) -{ - if (st == "migrate") - { - action = MIGRATE_ACTION; - } - else if (st == "live-migrate") - { - action = LIVE_MIGRATE_ACTION; - } - else if (st == "terminate") - { - action = TERMINATE_ACTION; - } - else if (st == "terminate-hard") - { - action = TERMINATE_HARD_ACTION; - } - else if (st == "undeploy") - { - action = UNDEPLOY_ACTION; - } - else if (st == "undeploy-hard") - { - action = UNDEPLOY_HARD_ACTION; - } - else if (st == "hold") - { - action = HOLD_ACTION; - } - else if (st == "release") - { - action = RELEASE_ACTION; - } - else if (st == "stop") - { - action = STOP_ACTION; - } - else if (st == "suspend") - { - action = SUSPEND_ACTION; - } - else if (st == "resume") - { - action = RESUME_ACTION; - } - else if (st == "delete") - { - action = DELETE_ACTION; - } - else if (st == "delete-recreate") - { - action = DELETE_RECREATE_ACTION; - } - else if (st == "reboot") - { - action = REBOOT_ACTION; - } - else if (st == "reboot-hard") - { - action = REBOOT_HARD_ACTION; - } - else if (st == "resched") - { - action = RESCHED_ACTION; - } - else if (st == "unresched") - { - action = UNRESCHED_ACTION; - } - else if (st == "poweroff") - { - action = POWEROFF_ACTION; - } - else if (st == "poweroff-hard") - { - action = POWEROFF_HARD_ACTION; - } - else if (st == "disk-attach") - { - action = DISK_ATTACH_ACTION; - } - else if (st == "disk-detach") - { - action = DISK_DETACH_ACTION; - } - else if (st == "nic-attach") - { - action = NIC_ATTACH_ACTION; - } - else if (st == "nic-detach") - { - action = NIC_DETACH_ACTION; - } - else if (st == "alias-attach") - { - action = ALIAS_ATTACH_ACTION; - } - else if (st == "alias-detach") - { - action = ALIAS_DETACH_ACTION; - } - else if (st == "disk-snapshot-create") - { - action = DISK_SNAPSHOT_CREATE_ACTION; - } - else if (st == "disk-snapshot-snap-delete") - { - action = DISK_SNAPSHOT_DELETE_ACTION; - } - else if (st == "disk-snapshot-rename") - { - action = DISK_SNAPSHOT_RENAME_ACTION; - } - else if (st == "disk-resize") - { - action = DISK_RESIZE_ACTION; - } - else if ( st == "deploy") - { - action = DEPLOY_ACTION; - } - else if ( st == "chown") - { - action = CHOWN_ACTION; - } - else if ( st == "chmod") - { - action = CHMOD_ACTION; - } - else if ( st == "updateconf") - { - action = UPDATECONF_ACTION; - } - else if ( st == "rename") - { - action = RENAME_ACTION; - } - else if ( st == "resize") - { - action = RESIZE_ACTION; - } - else if ( st == "update") - { - action = UPDATE_ACTION; - } - else if ( st == "snapshot-create") - { - action = SNAPSHOT_CREATE_ACTION; - } - else if ( st == "snapshot-delete") - { - action = SNAPSHOT_DELETE_ACTION; - } - else if ( st == "snapshot-revert") - { - action = SNAPSHOT_REVERT_ACTION; - } - else if ( st == "disk-saveas") - { - action = DISK_SAVEAS_ACTION; - } - else if ( st == "disk-snapshot-revert") - { - action = DISK_SNAPSHOT_REVERT_ACTION; - } - else if ( st == "recover") - { - action = RECOVER_ACTION; - } - else if ( st == "retry") - { - action = RETRY_ACTION; - } - else if ( st == "monitor") - { - action = MONITOR_ACTION; - } - else - { - action = NONE_ACTION; - return -1; - } - - return 0; -}; diff --git a/src/vm/SConstruct b/src/vm/SConstruct index 1a1cbeeacf..474a83c390 100644 --- a/src/vm/SConstruct +++ b/src/vm/SConstruct @@ -33,6 +33,7 @@ source_files=[ 'VirtualMachineSystemSnapshot.cc', 'VirtualMachineParser.cc', 'VirtualMachineContext.cc', + 'VMActions.cc', 'Snapshots.cc' ] diff --git a/src/vm/VMActions.cc b/src/vm/VMActions.cc new file mode 100644 index 0000000000..1623efd671 --- /dev/null +++ b/src/vm/VMActions.cc @@ -0,0 +1,550 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2019, OpenNebula Project, OpenNebula Systems */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); you may */ +/* not use this file except in compliance with the License. You may obtain */ +/* a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */ +/* See the License for the specific language governing permissions and */ +/* limitations under the License. */ +/* -------------------------------------------------------------------------- */ + +#include "VMActions.h" +#include "NebulaUtil.h" +#include "Template.h" + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +AuthRequest::Operation VMActions::get_auth_op(Action action) const +{ + if (admin_actions.is_set(action)) + { + return AuthRequest::ADMIN; + } + else if (manage_actions.is_set(action)) + { + return AuthRequest::MANAGE; + } + else if (use_actions.is_set(action)) + { + return AuthRequest::USE; + } + + return AuthRequest::NONE; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +int VMActions::set_auth_ops(const Template& tmpl, string& error) +{ + std::string admin, manage, use; + + tmpl.get("VM_ADMIN_OPERATIONS", admin); + if (set_auth_ops(admin, admin_actions, error) != 0) + { + return -1; + } + + tmpl.get("VM_MANAGE_OPERATIONS", manage); + if (set_auth_ops(manage, manage_actions, error) != 0) + { + return -1; + } + + tmpl.get("VM_USE_OPERATIONS", use); + if (set_auth_ops(use, use_actions, error) != 0) + { + return -1; + } + + return 0; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +int VMActions::set_auth_ops(const string& ops_str, + ActionSet& ops_set, string& error) +{ + std::set ops; + + one_util::split_unique(ops_str, ',', ops); + + for (const string& op : ops) + { + std::string the_op = one_util::trim(op); + + one_util::tolower(the_op); + + if ( the_op == "migrate" ) + { + ops_set.set(MIGRATE_ACTION); + ops_set.set(LIVE_MIGRATE_ACTION); + } + else if ( the_op == "delete" ) + { + ops_set.set(DELETE_ACTION); + ops_set.set(DELETE_RECREATE_ACTION); + } + else if ( the_op == "recover" ) + { + ops_set.set(RECOVER_ACTION); + } + else if ( the_op == "retry" ) + { + ops_set.set(RETRY_ACTION); + } + else if ( the_op == "deploy" ) + { + ops_set.set(DEPLOY_ACTION); + } + else if ( the_op == "resched" ) + { + ops_set.set(RESCHED_ACTION); + ops_set.set(UNRESCHED_ACTION); + } + else if ( the_op == "undeploy" ) + { + ops_set.set(UNDEPLOY_ACTION); + ops_set.set(UNDEPLOY_HARD_ACTION); + } + else if ( the_op == "hold" ) + { + ops_set.set(HOLD_ACTION); + } + else if ( the_op == "release" ) + { + ops_set.set(RELEASE_ACTION); + } + else if ( the_op == "stop" ) + { + ops_set.set(STOP_ACTION); + } + else if ( the_op == "suspend" ) + { + ops_set.set(SUSPEND_ACTION); + } + else if ( the_op == "resume" ) + { + ops_set.set(RESUME_ACTION); + } + else if ( the_op == "reboot" ) + { + ops_set.set(REBOOT_ACTION); + ops_set.set(REBOOT_HARD_ACTION); + } + else if ( the_op == "poweroff" ) + { + ops_set.set(POWEROFF_ACTION); + ops_set.set(POWEROFF_HARD_ACTION); + } + else if ( the_op == "disk-attach" ) + { + ops_set.set(DISK_ATTACH_ACTION); + ops_set.set(DISK_DETACH_ACTION); + } + else if ( the_op == "nic-attach" ) + { + ops_set.set(NIC_ATTACH_ACTION); + ops_set.set(NIC_DETACH_ACTION); + } + else if ( the_op == "disk-snapshot" ) + { + ops_set.set(DISK_SNAPSHOT_CREATE_ACTION); + ops_set.set(DISK_SNAPSHOT_DELETE_ACTION); + ops_set.set(DISK_SNAPSHOT_REVERT_ACTION); + ops_set.set(DISK_SNAPSHOT_RENAME_ACTION); + } + else if ( the_op == "terminate" ) + { + ops_set.set(TERMINATE_ACTION); + ops_set.set(TERMINATE_HARD_ACTION); + } + else if ( the_op == "disk-resize" ) + { + ops_set.set(DISK_RESIZE_ACTION); + } + else if ( the_op == "snapshot" ) + { + ops_set.set(SNAPSHOT_CREATE_ACTION); + ops_set.set(SNAPSHOT_DELETE_ACTION); + ops_set.set(SNAPSHOT_REVERT_ACTION); + } + else if ( the_op == "updateconf" ) + { + ops_set.set(UPDATECONF_ACTION); + } + else if ( the_op == "rename" ) + { + ops_set.set(RENAME_ACTION); + } + else if ( the_op == "resize" ) + { + ops_set.set(RESIZE_ACTION); + } + else if ( the_op == "update" ) + { + ops_set.set(UPDATE_ACTION); + } + else if ( the_op == "disk-saveas" ) + { + ops_set.set(DISK_SAVEAS_ACTION); + } + else + { + error = "Unknown vm operation: " + the_op; + return -1; + } + } + + return 0; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +string VMActions::action_to_str(Action action) +{ + string st; + + switch (action) + { + case MIGRATE_ACTION: + st = "migrate"; + break; + case POFF_MIGRATE_ACTION: + st = "poweroff-migrate"; + break; + case POFF_HARD_MIGRATE_ACTION: + st = "poweroff-hard-migrate"; + break; + case LIVE_MIGRATE_ACTION: + st = "live-migrate"; + break; + case TERMINATE_ACTION: + st = "terminate"; + break; + case TERMINATE_HARD_ACTION: + st = "terminate-hard"; + break; + case UNDEPLOY_ACTION: + st = "undeploy"; + break; + case UNDEPLOY_HARD_ACTION: + st = "undeploy-hard"; + break; + case HOLD_ACTION: + st = "hold"; + break; + case RELEASE_ACTION: + st = "release"; + break; + case STOP_ACTION: + st = "stop"; + break; + case SUSPEND_ACTION: + st = "suspend"; + break; + case RESUME_ACTION: + st = "resume"; + break; + case DELETE_ACTION: + st = "delete"; + break; + case DELETE_RECREATE_ACTION: + st = "delete-recreate"; + break; + case REBOOT_ACTION: + st = "reboot"; + break; + case REBOOT_HARD_ACTION: + st = "reboot-hard"; + break; + case RESCHED_ACTION: + st = "resched"; + break; + case UNRESCHED_ACTION: + st = "unresched"; + break; + case POWEROFF_ACTION: + st = "poweroff"; + break; + case POWEROFF_HARD_ACTION: + st = "poweroff-hard"; + break; + case DISK_ATTACH_ACTION: + st = "disk-attach"; + break; + case DISK_DETACH_ACTION: + st = "disk-detach"; + break; + case NIC_ATTACH_ACTION: + st = "nic-attach"; + break; + case NIC_DETACH_ACTION: + st = "nic-detach"; + break; + case ALIAS_ATTACH_ACTION: + st = "alias-attach"; + break; + case ALIAS_DETACH_ACTION: + st = "alias-detach"; + break; + case DISK_SNAPSHOT_CREATE_ACTION: + st = "disk-snapshot-create"; + break; + case DISK_SNAPSHOT_DELETE_ACTION: + st = "disk-snapshot-delete"; + break; + case DISK_SNAPSHOT_RENAME_ACTION: + st = "disk-snapshot-rename"; + break; + case DISK_RESIZE_ACTION: + st = "disk-resize"; + break; + case DEPLOY_ACTION: + st = "deploy"; + break; + case CHOWN_ACTION: + st = "chown"; + break; + case CHMOD_ACTION: + st = "chmod"; + break; + case UPDATECONF_ACTION: + st = "updateconf"; + break; + case RENAME_ACTION: + st = "rename"; + break; + case RESIZE_ACTION: + st = "resize"; + break; + case UPDATE_ACTION: + st = "update"; + break; + case SNAPSHOT_CREATE_ACTION: + st = "snapshot-create"; + break; + case SNAPSHOT_DELETE_ACTION: + st = "snapshot-delete"; + break; + case SNAPSHOT_REVERT_ACTION: + st = "snapshot-revert"; + break; + case DISK_SAVEAS_ACTION: + st = "disk-saveas"; + break; + case DISK_SNAPSHOT_REVERT_ACTION: + st = "disk-snapshot-revert"; + break; + case RECOVER_ACTION: + st = "recover"; + break; + case RETRY_ACTION: + st = "retry"; + break; + case MONITOR_ACTION: + st = "monitor"; + break; + case NONE_ACTION: + st = "none"; + break; + } + + return st; +}; + +int VMActions::action_from_str(const string& st, Action& action) +{ + if (st == "migrate") + { + action = MIGRATE_ACTION; + } + else if (st == "live-migrate") + { + action = LIVE_MIGRATE_ACTION; + } + else if (st == "terminate") + { + action = TERMINATE_ACTION; + } + else if (st == "terminate-hard") + { + action = TERMINATE_HARD_ACTION; + } + else if (st == "undeploy") + { + action = UNDEPLOY_ACTION; + } + else if (st == "undeploy-hard") + { + action = UNDEPLOY_HARD_ACTION; + } + else if (st == "hold") + { + action = HOLD_ACTION; + } + else if (st == "release") + { + action = RELEASE_ACTION; + } + else if (st == "stop") + { + action = STOP_ACTION; + } + else if (st == "suspend") + { + action = SUSPEND_ACTION; + } + else if (st == "resume") + { + action = RESUME_ACTION; + } + else if (st == "delete") + { + action = DELETE_ACTION; + } + else if (st == "delete-recreate") + { + action = DELETE_RECREATE_ACTION; + } + else if (st == "reboot") + { + action = REBOOT_ACTION; + } + else if (st == "reboot-hard") + { + action = REBOOT_HARD_ACTION; + } + else if (st == "resched") + { + action = RESCHED_ACTION; + } + else if (st == "unresched") + { + action = UNRESCHED_ACTION; + } + else if (st == "poweroff") + { + action = POWEROFF_ACTION; + } + else if (st == "poweroff-hard") + { + action = POWEROFF_HARD_ACTION; + } + else if (st == "disk-attach") + { + action = DISK_ATTACH_ACTION; + } + else if (st == "disk-detach") + { + action = DISK_DETACH_ACTION; + } + else if (st == "nic-attach") + { + action = NIC_ATTACH_ACTION; + } + else if (st == "nic-detach") + { + action = NIC_DETACH_ACTION; + } + else if (st == "alias-attach") + { + action = ALIAS_ATTACH_ACTION; + } + else if (st == "alias-detach") + { + action = ALIAS_DETACH_ACTION; + } + else if (st == "disk-snapshot-create") + { + action = DISK_SNAPSHOT_CREATE_ACTION; + } + else if (st == "disk-snapshot-snap-delete") + { + action = DISK_SNAPSHOT_DELETE_ACTION; + } + else if (st == "disk-snapshot-rename") + { + action = DISK_SNAPSHOT_RENAME_ACTION; + } + else if (st == "disk-resize") + { + action = DISK_RESIZE_ACTION; + } + else if ( st == "deploy") + { + action = DEPLOY_ACTION; + } + else if ( st == "chown") + { + action = CHOWN_ACTION; + } + else if ( st == "chmod") + { + action = CHMOD_ACTION; + } + else if ( st == "updateconf") + { + action = UPDATECONF_ACTION; + } + else if ( st == "rename") + { + action = RENAME_ACTION; + } + else if ( st == "resize") + { + action = RESIZE_ACTION; + } + else if ( st == "update") + { + action = UPDATE_ACTION; + } + else if ( st == "snapshot-create") + { + action = SNAPSHOT_CREATE_ACTION; + } + else if ( st == "snapshot-delete") + { + action = SNAPSHOT_DELETE_ACTION; + } + else if ( st == "snapshot-revert") + { + action = SNAPSHOT_REVERT_ACTION; + } + else if ( st == "disk-saveas") + { + action = DISK_SAVEAS_ACTION; + } + else if ( st == "disk-snapshot-revert") + { + action = DISK_SNAPSHOT_REVERT_ACTION; + } + else if ( st == "recover") + { + action = RECOVER_ACTION; + } + else if ( st == "retry") + { + action = RETRY_ACTION; + } + else if ( st == "monitor") + { + action = MONITOR_ACTION; + } + else + { + action = NONE_ACTION; + return -1; + } + + return 0; +}; diff --git a/src/vm/VirtualMachine.cc b/src/vm/VirtualMachine.cc index c8ec580a7a..aa711603f8 100644 --- a/src/vm/VirtualMachine.cc +++ b/src/vm/VirtualMachine.cc @@ -2107,7 +2107,7 @@ string VirtualMachine::get_import_state() /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -bool VirtualMachine::is_imported_action_supported(History::VMAction action) const +bool VirtualMachine::is_imported_action_supported(VMActions::Action action) const { if (!hasHistory()) { diff --git a/src/vm/VirtualMachineContext.cc b/src/vm/VirtualMachineContext.cc index 3e20f987eb..2b55a0239e 100644 --- a/src/vm/VirtualMachineContext.cc +++ b/src/vm/VirtualMachineContext.cc @@ -350,8 +350,8 @@ int VirtualMachine::generate_network_context(VectorAttribute* context, } bool alias_detach = hasPreviousHistory() && - previous_history->action == History::ALIAS_DETACH_ACTION && - vatts[i]->vector_value("ATTACH") == "YES"; + previous_history->action == VMActions::ALIAS_DETACH_ACTION && + vatts[i]->vector_value("ATTACH") == "YES"; parse_context_network(NETWORK_CONTEXT, &tmp_context, vatts[i], alias_detach); parse_context_network(NETWORK6_CONTEXT, &tmp_context, vatts[i], alias_detach); diff --git a/src/vmm/VirtualMachineManagerDriver.cc b/src/vmm/VirtualMachineManagerDriver.cc index 5c46c741f9..7a98d15bd5 100644 --- a/src/vmm/VirtualMachineManagerDriver.cc +++ b/src/vmm/VirtualMachineManagerDriver.cc @@ -115,29 +115,29 @@ VirtualMachineManagerDriver::VirtualMachineManagerDriver( } else { - NebulaLog::log("VMM", Log::INFO, "Using default imported VMs actions"); + NebulaLog::log("VMM", Log::INFO, "Using default imported VMs actions"); - it = attrs.find("NAME"); + it = attrs.find("NAME"); - if (it != attrs.end()) - { - if ( it->second == "kvm" || it->second == "xen" ) - { - action_defaults = imported_actions_default; - } - else if ( it->second == "sl" || it->second == "ec2" || - it->second == "az" || it->second == "vcenter" ) - { + if (it != attrs.end()) + { + if ( it->second == "kvm" || it->second == "xen" ) + { + action_defaults = imported_actions_default; + } + else if ( it->second == "sl" || it->second == "ec2" || + it->second == "az" || it->second == "vcenter" ) + { action_defaults = imported_actions_default_public; - } - } + } + } } vector actions; vector::iterator vit; string action; - History::VMAction id; + VMActions::Action id; actions = one_util::split(action_defaults, ','); @@ -145,7 +145,7 @@ VirtualMachineManagerDriver::VirtualMachineManagerDriver( { action = one_util::trim(*vit); - if ( History::action_from_str(action, id) != 0 ) + if ( VMActions::action_from_str(action, id) != 0 ) { NebulaLog::log("VMM", Log::ERROR, "Wrong action: " + action); continue;