// Copyright 2012 Citrix Systems, Inc. Licensed under the // Apache License, Version 2.0 (the "License"); you may not use this // file except in compliance with the License. Citrix Systems, Inc. // reserves all rights not expressly granted by 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. // // Automatically generated by addcopyright.py at 04/03/2012 package com.cloud.acl; import javax.ejb.Local; import com.cloud.api.BaseCmd; import com.cloud.dc.DataCenter; import com.cloud.domain.Domain; import com.cloud.domain.DomainVO; import com.cloud.domain.dao.DomainDao; import com.cloud.exception.PermissionDeniedException; import com.cloud.network.Network; import com.cloud.network.NetworkManager; import com.cloud.offering.DiskOffering; import com.cloud.offering.ServiceOffering; import com.cloud.projects.ProjectManager; import com.cloud.projects.dao.ProjectAccountDao; import com.cloud.storage.LaunchPermissionVO; import com.cloud.storage.dao.LaunchPermissionDao; import com.cloud.template.VirtualMachineTemplate; import com.cloud.user.Account; import com.cloud.user.User; import com.cloud.user.dao.AccountDao; import com.cloud.utils.component.AdapterBase; import com.cloud.utils.component.Inject; @Local(value=SecurityChecker.class) public class DomainChecker extends AdapterBase implements SecurityChecker { @Inject DomainDao _domainDao; @Inject AccountDao _accountDao; @Inject LaunchPermissionDao _launchPermissionDao; @Inject ProjectManager _projectMgr; @Inject ProjectAccountDao _projecAccountDao; @Inject NetworkManager _networkMgr; protected DomainChecker() { super(); } @Override public boolean checkAccess(Account caller, Domain domain) throws PermissionDeniedException { if (caller.getState() != Account.State.enabled) { throw new PermissionDeniedException(caller + " is disabled."); } long domainId = domain.getId(); if (caller.getType() == Account.ACCOUNT_TYPE_NORMAL) { if (caller.getDomainId() != domainId) { throw new PermissionDeniedException(caller + " does not have permission to operate within domain id=" + domain.getId()); } } else if (!_domainDao.isChildDomain(caller.getDomainId(), domainId)) { throw new PermissionDeniedException(caller + " does not have permission to operate within domain id=" + domain.getId()); } return true; } @Override public boolean checkAccess(User user, Domain domain) throws PermissionDeniedException { if (user.getRemoved() != null) { throw new PermissionDeniedException(user + " is no longer active."); } Account account = _accountDao.findById(user.getAccountId()); return checkAccess(account, domain); } @Override public boolean checkAccess(Account caller, ControlledEntity entity, AccessType accessType) throws PermissionDeniedException { if (entity instanceof VirtualMachineTemplate) { VirtualMachineTemplate template = (VirtualMachineTemplate)entity; Account owner = _accountDao.findById(template.getAccountId()); // validate that the template is usable by the account if (!template.isPublicTemplate()) { if (BaseCmd.isRootAdmin(caller.getType()) || (owner.getId() == caller.getId())) { return true; } // since the current account is not the owner of the template, check the launch permissions table to see if the // account can launch a VM from this template LaunchPermissionVO permission = _launchPermissionDao.findByTemplateAndAccount(template.getId(), caller.getId()); if (permission == null) { throw new PermissionDeniedException(caller + " does not have permission to launch instances from " + template); } } else { // Domain admin and regular user can delete/modify only templates created by them if (accessType != null && accessType == AccessType.ModifyEntry) { if (!BaseCmd.isRootAdmin(caller.getType()) && owner.getId() != caller.getId()) { throw new PermissionDeniedException("Domain Admin and regular users can modify only their own Public templates"); } } } return true; } else if (entity instanceof Network && accessType != null && accessType == AccessType.UseNetwork) { _networkMgr.checkNetworkPermissions(caller, (Network)entity); } else { if (caller.getType() == Account.ACCOUNT_TYPE_NORMAL) { Account account = _accountDao.findById(entity.getAccountId()); if (account != null && account.getType() == Account.ACCOUNT_TYPE_PROJECT) { //only project owner can delete/modify the project if (accessType != null && accessType == AccessType.ModifyProject) { if (!_projectMgr.canModifyProjectAccount(caller, account.getId())) { throw new PermissionDeniedException(caller + " does not have permission to operate with resource " + entity); } } else if (!_projectMgr.canAccessProjectAccount(caller, account.getId())){ throw new PermissionDeniedException(caller + " does not have permission to operate with resource " + entity); } } else { if (caller.getId() != entity.getAccountId()) { throw new PermissionDeniedException(caller + " does not have permission to operate with resource " + entity); } } } } return true; } @Override public boolean checkAccess(User user, ControlledEntity entity) throws PermissionDeniedException { Account account = _accountDao.findById(user.getAccountId()); return checkAccess(account, entity, null); } @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_RESOURCE_DOMAIN_ADMIN || 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 { 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 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 service offering) else if(account.getType() == Account.ACCOUNT_TYPE_NORMAL || account.getType() == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN || 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 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_PROJECT){ if(account.getDomainId() == zone.getDomainId()){ return true; //zone and account at exact node }else{ DomainVO domainRecord = _domainDao.findById(account.getDomainId()); if(domainRecord != null) { while(true){ if(domainRecord.getId() == zone.getDomainId()){ //found as a child return true; } if(domainRecord.getParent() != null) { domainRecord = _domainDao.findById(domainRecord.getParent()); } else { break; } } } } //not found return false; } //if account is domain admin //check if the account's domain is either child of zone's domain, or if zone's domain is child of account's domain else if(account.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN){ if(account.getDomainId() == zone.getDomainId()){ return true; //zone and account at exact node }else{ DomainVO zoneDomainRecord = _domainDao.findById(zone.getDomainId()); DomainVO accountDomainRecord = _domainDao.findById(account.getDomainId()); if(accountDomainRecord != null) { DomainVO localRecord = accountDomainRecord; while(true){ if(localRecord.getId() == zone.getDomainId()){ //found as a child return true; } if(localRecord.getParent() != null) { localRecord = _domainDao.findById(localRecord.getParent()); } else { break; } } } //didn't find in upper tree if(zoneDomainRecord.getPath().contains(accountDomainRecord.getPath())){ return true; } } //not found return false; } } return false; } }