diff --git a/include/PoolObjectSQL.h b/include/PoolObjectSQL.h index 6875988dda..a025ab20ef 100644 --- a/include/PoolObjectSQL.h +++ b/include/PoolObjectSQL.h @@ -161,6 +161,33 @@ public: gname = _gname; }; + /** + * Changes the object's permissions + * + * @param _owner_u New permission: 1 allow, 0 deny, -1 do not change + * @param _owner_m New permission: 1 allow, 0 deny, -1 do not change + * @param _owner_a New permission: 1 allow, 0 deny, -1 do not change + * @param _group_u New permission: 1 allow, 0 deny, -1 do not change + * @param _group_m New permission: 1 allow, 0 deny, -1 do not change + * @param _group_a New permission: 1 allow, 0 deny, -1 do not change + * @param _other_u New permission: 1 allow, 0 deny, -1 do not change + * @param _other_m New permission: 1 allow, 0 deny, -1 do not change + * @param _other_a New permission: 1 allow, 0 deny, -1 do not change + * @param error_str Returns the error reason, if any + * + * @return 0 on success + */ + int set_permissions(int _owner_u, + int _owner_m, + int _owner_a, + int _group_u, + int _group_m, + int _group_a, + int _other_u, + int _other_m, + int _other_a, + string& error_str); + /* --------------------------------------------------------------------- */ /** @@ -421,6 +448,22 @@ protected: */ int perms_from_xml(); + /** + * Sets the permission attribute to the new_perm value, if it is different + * from -1 + * + * @param perm the permissions attribute, must be -1, 0 or 1, its value + * must be checked before + * @param new_perm the new value. If it is -1, it will be ignored + */ + void set_perm(int &perm, const int &new_perm) + { + if ( new_perm != -1 ) + { + perm = new_perm; + } + }; + /** * The object's unique ID */ diff --git a/include/RequestManagerChmod.h b/include/RequestManagerChmod.h new file mode 100644 index 0000000000..c0b94ba106 --- /dev/null +++ b/include/RequestManagerChmod.h @@ -0,0 +1,124 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2011, OpenNebula Project Leads (OpenNebula.org) */ +/* */ +/* 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 REQUEST_MANAGER_CHMOD_H_ +#define REQUEST_MANAGER_CHMOD_H_ + +#include "Request.h" +#include "Nebula.h" + +using namespace std; + +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + +class RequestManagerChmod : public Request +{ +protected: + RequestManagerChmod(const string& method_name, + const string& help, + const string& params = "A:siii") + :Request(method_name,params,help){}; + + ~RequestManagerChmod(){}; + + /* -------------------------------------------------------------------- */ + + virtual void request_execute(xmlrpc_c::paramList const& _paramList, + RequestAttributes& att); +}; + +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + +class VirtualMachineChmod : public RequestManagerChmod +{ +public: + VirtualMachineChmod(): + RequestManagerChmod("VirtualMachineChmod", + "Changes ownership of a virtual machine") + { + Nebula& nd = Nebula::instance(); + pool = nd.get_vmpool(); + auth_object = PoolObjectSQL::VM; + }; + + ~VirtualMachineChmod(){}; +}; + +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + +class TemplateChmod : public RequestManagerChmod +{ +public: + TemplateChmod(): + RequestManagerChmod("TemplateChmod", + "Changes ownership of a virtual machine template") + { + Nebula& nd = Nebula::instance(); + pool = nd.get_tpool(); + auth_object = PoolObjectSQL::TEMPLATE; + }; + + ~TemplateChmod(){}; +}; + +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + + +class VirtualNetworkChmod: public RequestManagerChmod +{ +public: + VirtualNetworkChmod(): + RequestManagerChmod("VirtualNetworkChmod", + "Changes ownership of a virtual network") + { + Nebula& nd = Nebula::instance(); + pool = nd.get_vnpool(); + auth_object = PoolObjectSQL::NET; + }; + + ~VirtualNetworkChmod(){}; + +}; + +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + +class ImageChmod: public RequestManagerChmod +{ +public: + ImageChmod(): + RequestManagerChmod("ImageChmod", + "Changes ownership of an image") + { + Nebula& nd = Nebula::instance(); + pool = nd.get_ipool(); + auth_object = PoolObjectSQL::IMAGE; + }; + + ~ImageChmod(){}; + +}; + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +#endif diff --git a/src/pool/PoolObjectSQL.cc b/src/pool/PoolObjectSQL.cc index dd66ad6040..34909809af 100644 --- a/src/pool/PoolObjectSQL.cc +++ b/src/pool/PoolObjectSQL.cc @@ -269,3 +269,44 @@ void PoolObjectSQL::get_permissions(PoolObjectAuth& auth) /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ + +int PoolObjectSQL::set_permissions( int _owner_u, + int _owner_m, + int _owner_a, + int _group_u, + int _group_m, + int _group_a, + int _other_u, + int _other_m, + int _other_a, + string& error_str) +{ + if ( _owner_u < -1 || _owner_u > 1 ) goto error_value; + if ( _owner_m < -1 || _owner_m > 1 ) goto error_value; + if ( _owner_a < -1 || _owner_a > 1 ) goto error_value; + if ( _group_u < -1 || _group_u > 1 ) goto error_value; + if ( _group_m < -1 || _group_m > 1 ) goto error_value; + if ( _group_a < -1 || _group_a > 1 ) goto error_value; + if ( _other_u < -1 || _other_u > 1 ) goto error_value; + if ( _other_m < -1 || _other_m > 1 ) goto error_value; + if ( _other_a < -1 || _other_a > 1 ) goto error_value; + + set_perm(owner_u, _owner_u); + set_perm(owner_m, _owner_m); + set_perm(owner_a, _owner_a); + set_perm(group_u, _group_u); + set_perm(group_m, _group_m); + set_perm(group_a, _group_a); + set_perm(other_u, _other_u); + set_perm(other_m, _other_m); + set_perm(other_a, _other_a); + + return 0; + +error_value: + error_str = "New permission values must be -1, 0 or 1"; + return -1; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ diff --git a/src/rm/RequestManager.cc b/src/rm/RequestManager.cc index 07a1fa18ef..8ac7b95c5c 100644 --- a/src/rm/RequestManager.cc +++ b/src/rm/RequestManager.cc @@ -25,6 +25,7 @@ #include "RequestManagerAllocate.h" #include "RequestManagerUpdateTemplate.h" #include "RequestManagerChown.h" +#include "RequestManagerChmod.h" #include "RequestManagerVirtualNetwork.h" #include "RequestManagerVirtualMachine.h" @@ -307,6 +308,12 @@ void RequestManager::register_xml_methods() xmlrpc_c::methodPtr image_chown(new ImageChown()); xmlrpc_c::methodPtr user_chown(new UserChown()); + // Chmod Methods + xmlrpc_c::methodPtr vm_chmod(new VirtualMachineChmod()); + xmlrpc_c::methodPtr template_chmod(new TemplateChmod()); + xmlrpc_c::methodPtr vn_chmod(new VirtualNetworkChmod()); + xmlrpc_c::methodPtr image_chmod(new ImageChmod()); + // ACL Methods xmlrpc_c::methodPtr acl_addrule(new AclAddRule()); xmlrpc_c::methodPtr acl_delrule(new AclDelRule()); @@ -320,6 +327,7 @@ void RequestManager::register_xml_methods() RequestManagerRegistry.addMethod("one.vm.allocate", vm_allocate); RequestManagerRegistry.addMethod("one.vm.info", vm_info); RequestManagerRegistry.addMethod("one.vm.chown", vm_chown); + RequestManagerRegistry.addMethod("one.vm.chmod", vm_chmod); RequestManagerRegistry.addMethod("one.vmpool.info", vm_pool_info); @@ -330,6 +338,7 @@ void RequestManager::register_xml_methods() RequestManagerRegistry.addMethod("one.template.delete", template_delete); RequestManagerRegistry.addMethod("one.template.info", template_info); RequestManagerRegistry.addMethod("one.template.chown", template_chown); + RequestManagerRegistry.addMethod("one.template.chmod", template_chmod); RequestManagerRegistry.addMethod("one.templatepool.info",template_pool_info); @@ -359,6 +368,7 @@ void RequestManager::register_xml_methods() RequestManagerRegistry.addMethod("one.vn.delete", vn_delete); RequestManagerRegistry.addMethod("one.vn.info", vn_info); RequestManagerRegistry.addMethod("one.vn.chown", vn_chown); + RequestManagerRegistry.addMethod("one.vn.chmod", vn_chmod); RequestManagerRegistry.addMethod("one.vnpool.info", vnpool_info); @@ -381,6 +391,7 @@ void RequestManager::register_xml_methods() RequestManagerRegistry.addMethod("one.image.delete", image_delete); RequestManagerRegistry.addMethod("one.image.info", image_info); RequestManagerRegistry.addMethod("one.image.chown", image_chown); + RequestManagerRegistry.addMethod("one.image.chmod", image_chmod); RequestManagerRegistry.addMethod("one.image.chtype", image_chtype); RequestManagerRegistry.addMethod("one.imagepool.info", imagepool_info); diff --git a/src/rm/RequestManagerChmod.cc b/src/rm/RequestManagerChmod.cc new file mode 100644 index 0000000000..544a7f8197 --- /dev/null +++ b/src/rm/RequestManagerChmod.cc @@ -0,0 +1,133 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2011, OpenNebula Project Leads (OpenNebula.org) */ +/* */ +/* 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 "RequestManagerChmod.h" + +#include "NebulaLog.h" +#include "Nebula.h" + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +void RequestManagerChmod::request_execute(xmlrpc_c::paramList const& paramList, + RequestAttributes& att) +{ + int oid = xmlrpc_c::value_int(paramList.getInt(1)); + + int owner_u = xmlrpc_c::value_int(paramList.getInt(2)); + int owner_m = xmlrpc_c::value_int(paramList.getInt(3)); + int owner_a = xmlrpc_c::value_int(paramList.getInt(4)); + + int group_u = xmlrpc_c::value_int(paramList.getInt(5)); + int group_m = xmlrpc_c::value_int(paramList.getInt(6)); + int group_a = xmlrpc_c::value_int(paramList.getInt(7)); + + int other_u = xmlrpc_c::value_int(paramList.getInt(8)); + int other_m = xmlrpc_c::value_int(paramList.getInt(9)); + int other_a = xmlrpc_c::value_int(paramList.getInt(10)); + + PoolObjectSQL * object; + string error_str; + + if ( att.uid != 0 ) + { + AuthRequest::Operation op = AuthRequest::MANAGE; + PoolObjectAuth perms; + + object = pool->get(oid,true); + + if ( object == 0 ) + { + failure_response(NO_EXISTS, + get_error(object_name(auth_object),oid), + att); + return; + } + + object->get_permissions(perms); + + object->unlock(); + + if ( owner_a == perms.owner_a ) + { + owner_a = -1; + } + + if ( group_a == perms.group_a ) + { + group_a = -1; + } + + if ( other_a == perms.other_a ) + { + other_a = -1; + } + + if ( owner_a != -1 || group_a != -1 || other_a != -1 ) + { + op = AuthRequest::ADMIN; + } + + AuthRequest ar(att.uid, att.gid); + + ar.add_auth(op, perms); + + if (UserPool::authorize(ar) == -1) + { + failure_response(AUTHORIZATION, + authorization_error(ar.message, att), + att); + + return; + } + } + + // ------------- Update the object --------------------- + + object = pool->get(oid,true); + + if ( object == 0 ) + { + failure_response(NO_EXISTS, + get_error(object_name(auth_object),oid), + att); + return; + } + + int rc = object->set_permissions(owner_u, owner_m, owner_a, group_u, + group_m, group_a, other_u, other_m, other_a, error_str); + + if ( rc != 0 ) + { + failure_response(INTERNAL, + request_error("Error updating permissions",error_str), + att); + + object->unlock(); + return; + } + + pool->update(object); + + object->unlock(); + + success_response(oid, att); + + return; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ diff --git a/src/rm/SConstruct b/src/rm/SConstruct index 4da221823f..c9d4f8c4cd 100644 --- a/src/rm/SConstruct +++ b/src/rm/SConstruct @@ -38,6 +38,7 @@ source_files=[ 'RequestManagerImage.cc', 'RequestManagerChown.cc', 'RequestManagerAcl.cc', + 'RequestManagerChmod.cc', ] # Build library