another good point for checkin, added the domain checker for checks against service offerings, whilst deploying virtual machines

This commit is contained in:
abhishek 2010-11-30 12:59:04 -08:00
parent 9a6eaaf21f
commit 1dfdcf51cb
5 changed files with 84 additions and 2 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.ServiceOffering;
import com.cloud.user.Account;
import com.cloud.user.User;
import com.cloud.utils.component.Adapter;
@ -57,6 +58,8 @@ public interface SecurityChecker extends Adapter {
boolean checkAccess(Account account, DataCenter zone) throws PermissionDeniedException;
public boolean checkAccess(Account account, ServiceOffering so) 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
// OwnedBy and PartOf interfaces on the object and use it to verify against a user.

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.ServiceOffering;
import com.cloud.storage.LaunchPermissionVO;
import com.cloud.storage.dao.LaunchPermissionDao;
import com.cloud.template.VirtualMachineTemplate;
@ -100,6 +101,54 @@ public class DomainChecker extends AdapterBase implements SecurityChecker {
return checkAccess(account, entity);
}
@Override
public boolean checkAccess(Account account, ServiceOffering so) throws PermissionDeniedException
{
if(account == null || so.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
//check if account's domain is a child of zone's domain
else if(account.getType() == Account.ACCOUNT_TYPE_NORMAL || account.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN)
{
if(account.getDomainId() == so.getDomainId())
{
return true; //service offering and account at exact node
}
else
{
DomainVO domainRecord = _domainDao.findById(account.getDomainId());
if(domainRecord != null)
{
while(true)
{
if(domainRecord.getId() == so.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, DataCenter zone) throws PermissionDeniedException {
if(account == null || zone.getDomainId() == null){//public zone

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.ServiceOffering;
import com.cloud.service.ServiceOfferingVO;
import com.cloud.storage.DiskOfferingVO;
import com.cloud.user.Account;
@ -153,5 +154,7 @@ public interface ConfigurationManager extends Manager {
void checkAccess(Account caller, DataCenter zone)
throws PermissionDeniedException;
void checkAccess(Account caller, ServiceOffering so)
throws PermissionDeniedException;
}

View File

@ -2311,7 +2311,24 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura
return deleteVlanAndPublicIpRange(userId, vlanDbId);
}
@Override
public void checkAccess(Account caller, ServiceOffering so) throws PermissionDeniedException {
for (SecurityChecker checker : _secChecker) {
if (checker.checkAccess(caller, so)) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Access granted to " + caller + " to service offering:" + so.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 service offering:" + so.getId());
}
@Override
public void checkAccess(Account caller, DataCenter zone) throws PermissionDeniedException {
for (SecurityChecker checker : _secChecker) {

View File

@ -1196,6 +1196,16 @@ public class ManagementServerImpl implements ManagementServer {
throw new InvalidParameterValueException("Unable to find service offering: " + serviceOfferingId);
}
if(offering.getDomainId() == null){
//do nothing as offering is public
}else{
if(userAccount != null){
_configMgr.checkAccess(userAccount, offering);//user deploying his own vm
}else{
_configMgr.checkAccess(ctxAccount, offering);
}
}
VMTemplateVO template = _templateDao.findById(templateId);
// Make sure a valid template ID was specified
if (template == null) {