adding a security checker whilst creating a volume from a disk offering

This commit is contained in:
abhishek 2010-11-30 17:46:31 -08:00
parent 4387e2ca0a
commit b51a7fec50
6 changed files with 93 additions and 5 deletions

View File

@ -6,6 +6,7 @@ package com.cloud.acl;
import com.cloud.dc.DataCenter;
import com.cloud.domain.Domain;
import com.cloud.exception.PermissionDeniedException;
import com.cloud.offering.DiskOffering;
import com.cloud.offering.ServiceOffering;
import com.cloud.user.Account;
import com.cloud.user.User;
@ -59,6 +60,8 @@ public interface SecurityChecker extends Adapter {
boolean checkAccess(Account account, DataCenter zone) throws PermissionDeniedException;
public boolean checkAccess(Account account, ServiceOffering so) throws PermissionDeniedException;
boolean checkAccess(Account account, DiskOffering dof) throws PermissionDeniedException;
// We should be able to use this method to check against commands. For example, we can
// annotate the command with access annotations and this method can use it to extract

View File

@ -25,6 +25,7 @@ import com.cloud.domain.Domain;
import com.cloud.domain.DomainVO;
import com.cloud.domain.dao.DomainDao;
import com.cloud.exception.PermissionDeniedException;
import com.cloud.offering.DiskOffering;
import com.cloud.offering.ServiceOffering;
import com.cloud.storage.LaunchPermissionVO;
import com.cloud.storage.dao.LaunchPermissionDao;
@ -101,6 +102,52 @@ public class DomainChecker extends AdapterBase implements SecurityChecker {
return checkAccess(account, entity);
}
@Override
public boolean checkAccess(Account account, DiskOffering dof) throws PermissionDeniedException
{
if(account == null || dof.getDomainId() == null)
{//public offering
return true;
}
else
{
//admin has all permissions
if(account.getType() == Account.ACCOUNT_TYPE_ADMIN)
{
return true;
}
//if account is normal user or domain admin
//check if account's domain is a child of zone's domain (Note: This is made consistent with the list command for disk offering)
else if(account.getType() == Account.ACCOUNT_TYPE_NORMAL || account.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN)
{
if(account.getDomainId() == dof.getDomainId())
{
return true; //disk offering and account at exact node
}
else
{
DomainVO domainRecord = _domainDao.findById(account.getDomainId());
if(domainRecord != null)
{
while(true)
{
if(domainRecord.getId() == dof.getDomainId())
{
//found as a child
return true;
}
if(domainRecord.getParent() != null)
domainRecord = _domainDao.findById(domainRecord.getParent());
else
break;
}
}
}
}
}
//not found
return false;
}
@Override
public boolean checkAccess(Account account, ServiceOffering so) throws PermissionDeniedException

View File

@ -26,6 +26,7 @@ import com.cloud.dc.HostPodVO;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientAddressCapacityException;
import com.cloud.exception.PermissionDeniedException;
import com.cloud.offering.DiskOffering;
import com.cloud.offering.ServiceOffering;
import com.cloud.service.ServiceOfferingVO;
import com.cloud.storage.DiskOfferingVO;
@ -155,6 +156,9 @@ public interface ConfigurationManager extends Manager {
void checkAccess(Account caller, DataCenter zone)
throws PermissionDeniedException;
void checkAccess(Account caller, ServiceOffering so)
void checkServiceOfferingAccess(Account caller, ServiceOffering so)
throws PermissionDeniedException;
void checkDiskOfferingAccess(Account caller, DiskOffering dof)
throws PermissionDeniedException;
}

View File

@ -2320,7 +2320,24 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura
}
@Override
public void checkAccess(Account caller, ServiceOffering so) throws PermissionDeniedException {
public void checkDiskOfferingAccess(Account caller, DiskOffering dof) throws PermissionDeniedException {
for (SecurityChecker checker : _secChecker) {
if (checker.checkAccess(caller, dof)) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Access granted to " + caller + " to disk offering:" + dof.getId() + " by " + checker.getName());
}
return;
}else{
throw new PermissionDeniedException("Access denied to "+caller+" by "+checker.getName());
}
}
assert false : "How can all of the security checkers pass on checking this caller?";
throw new PermissionDeniedException("There's no way to confirm " + caller + " has access to disk offering:" + dof.getId());
}
@Override
public void checkServiceOfferingAccess(Account caller, ServiceOffering so) throws PermissionDeniedException {
for (SecurityChecker checker : _secChecker) {
if (checker.checkAccess(caller, so)) {
if (s_logger.isDebugEnabled()) {

View File

@ -1200,9 +1200,9 @@ public class ManagementServerImpl implements ManagementServer {
//do nothing as offering is public
}else{
if(userAccount != null){
_configMgr.checkAccess(userAccount, offering);//user deploying his own vm
_configMgr.checkServiceOfferingAccess(userAccount, offering);//user deploying his own vm
}else{
_configMgr.checkAccess(ctxAccount, offering);
_configMgr.checkServiceOfferingAccess(ctxAccount, offering);
}
}
@ -1230,6 +1230,18 @@ public class ManagementServerImpl implements ManagementServer {
throw new InvalidParameterValueException("Please specify a valid disk offering ID.");
}
if(diskOffering != null){
if(diskOffering.getDomainId() == null){
//do nothing as offering is public
}else{
if(userAccount != null){
_configMgr.checkDiskOfferingAccess(userAccount, diskOffering);//user deploying his own vm
}else{
_configMgr.checkDiskOfferingAccess(ctxAccount, diskOffering);
}
}
}
if (isIso) {
/*iso template doesn;t have hypervisor type, temporarily set it's type as user specified, pass it to storage allocator */
template.setHypervisorType(HypervisorType.getType(cmd.getHypervisor()));
@ -4416,7 +4428,6 @@ public class ManagementServerImpl implements ManagementServer {
Object id = cmd.getId();
Object keyword = cmd.getKeyword();
Long domainId = cmd.getDomainId();
//Keeping this logic consistent with domain specific zones
//if a domainId is provided, we just return the disk offering associated with this domain
if(domainId != null){

View File

@ -1742,6 +1742,12 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag
throw new InvalidParameterValueException("Please specify a valid disk offering.");
}
if(diskOffering.getDomainId() == null){
//do nothing as offering is public
}else{
_configMgr.checkDiskOfferingAccess(account, diskOffering);
}
if(!validateVolumeSizeRange(diskOffering.getDiskSize()/1024)){//convert size from mb to gb for validation
throw new InvalidParameterValueException("Invalid size for custom volume creation: " + size+" ,max volume size is:"+_maxVolumeSizeInGb);
}