1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-03-22 18:50:08 +03:00

feature #2742: Enforce System DS Access Rights to deploy VMs

This commit is contained in:
Ruben S. Montero 2015-04-16 12:36:07 +02:00
parent 8d1f22c038
commit 3f0a7fc0cd
2 changed files with 76 additions and 16 deletions

View File

@ -643,6 +643,7 @@ void VirtualMachineDeploy::request_execute(xmlrpc_c::paramList const& paramList,
{
Nebula& nd = Nebula::instance();
DispatchManager * dm = nd.get_dm();
DatastorePool * dspool = nd.get_dspool();
VirtualMachine * vm;
@ -652,7 +653,9 @@ void VirtualMachineDeploy::request_execute(xmlrpc_c::paramList const& paramList,
int cluster_id;
string ds_location;
bool is_public_cloud;
PoolObjectAuth host_perms;
PoolObjectAuth host_perms, ds_perms;
PoolObjectAuth * auth_ds_perms;
string tm_mad;
@ -691,16 +694,9 @@ void VirtualMachineDeploy::request_execute(xmlrpc_c::paramList const& paramList,
}
// ------------------------------------------------------------------------
// Authorize request
// Get information about the system DS to use (tm_mad & permissions)
// ------------------------------------------------------------------------
auth = vm_authorization(id, 0, 0, att, &host_perms, 0, auth_op);
if (auth == false)
{
return;
}
if ((vm = get_vm(id, att)) == 0)
{
return;
@ -716,10 +712,6 @@ void VirtualMachineDeploy::request_execute(xmlrpc_c::paramList const& paramList,
vm->unlock();
// ------------------------------------------------------------------------
// Get information about the system DS to use (tm_mad)
// ------------------------------------------------------------------------
if (is_public_cloud) // Set ds_id to -1 and tm_mad empty(). This is used by
{ // by VirtualMachine::get_host_is_cloud()
ds_id = -1;
@ -758,6 +750,41 @@ void VirtualMachineDeploy::request_execute(xmlrpc_c::paramList const& paramList,
}
}
if (ds_id == -1)
{
auth_ds_perms = 0;
}
else
{
Datastore * ds = dspool->get(ds_id, true);
if (ds == 0 )
{
failure_response(NO_EXISTS,
get_error(object_name(PoolObjectSQL::DATASTORE), ds_id),
att);
return;
}
ds->get_permissions(ds_perms);
ds->unlock();
auth_ds_perms = &ds_perms;
}
// ------------------------------------------------------------------------
// Authorize request
// ------------------------------------------------------------------------
auth = vm_authorization(id, 0, 0, att, &host_perms, auth_ds_perms, auth_op);
if (auth == false)
{
return;
}
// ------------------------------------------------------------------------
// Check request consistency:
// - VM States are right

View File

@ -617,14 +617,16 @@ static bool match_host(AclXML * acls, VirtualMachineXML* vm, int vmem, int vcpu,
* @param vm the virtual machine
* @param vdisk vm requirement
* @param ds to evaluate vm assgiment
* @param n_auth number of ds authorized for the user, incremented if needed
* @param n_error number of requirement errors, incremented if needed
* @param n_matched number of system ds that fullfil VM sched_requirements
* @param n_fits number of system ds with capacity that fits the VM requirements
* @param error, string describing why the host is not valid
* @return true for a positive match
*/
static bool match_system_ds(VirtualMachineXML* vm, long long vdisk,
DatastoreXML * ds, int& n_error, int& n_fits, int &n_matched, string &error)
static bool match_system_ds(AclXML * acls, VirtualMachineXML* vm, long long vdisk,
DatastoreXML * ds, int& n_auth, int& n_error, int& n_fits, int &n_matched,
string &error)
{
// -------------------------------------------------------------------------
// Check datastore capacity for shared systems DS (non-shared will be
@ -638,6 +640,31 @@ static bool match_system_ds(VirtualMachineXML* vm, long long vdisk,
n_fits++;
// -------------------------------------------------------------------------
// Check if user is authorized
// -------------------------------------------------------------------------
if ( vm->get_uid() != 0 && vm->get_gid() != 0 )
{
PoolObjectAuth dsperms;
dsperms.oid = ds->get_oid();
dsperms.cid = ds->get_cid();
dsperms.obj_type = PoolObjectSQL::DATASTORE;
// Only include the VM group ID
set<int> gids;
gids.insert(vm->get_gid());
if ( !acls->authorize(vm->get_uid(), gids, dsperms, AuthRequest::USE))
{
error = "Permission denied.";
return false;
}
}
n_auth++;
// -------------------------------------------------------------------------
// Evaluate VM requirements
// -------------------------------------------------------------------------
@ -840,6 +867,7 @@ void Scheduler::match_schedule()
// ---------------------------------------------------------------------
n_resources = 0;
n_auth = 0;
n_matched = 0;
n_error = 0;
n_fits = 0;
@ -848,7 +876,8 @@ void Scheduler::match_schedule()
{
ds = static_cast<DatastoreXML *>(h_it->second);
if (match_system_ds(vm, vm_disk, ds, n_error, n_fits, n_matched, m_error))
if (match_system_ds(acls, vm, vm_disk, ds, n_auth, n_error, n_fits,
n_matched, m_error))
{
vm->add_match_datastore(ds->get_oid());
@ -890,6 +919,10 @@ void Scheduler::match_schedule()
vm->log(oss.str());
}
else if (n_auth == 0)
{
vm->log("User is not authorized to use any system datastore");
}
else if (n_fits == 0)
{
vm->log("No system datastore with enough capacity for the VM");