Fixed account security checks for domain admins in following commands:

* listPortForwardingRules
* listIpForwardingRules
* listRemoteAccessVpns
* listVpnUsers
This commit is contained in:
alena 2011-02-07 16:21:07 -08:00
parent b322fb072f
commit 0082b8435a
10 changed files with 162 additions and 133 deletions

View File

@ -91,7 +91,7 @@ public class ListIpForwardingRulesCmd extends BaseListCmd {
@Override
public void execute(){
List<? extends PortForwardingRule> result = _rulesService.searchForIpForwardingRules(publicIpAddressId, id, vmId, this.getStartIndex(), this.getPageSizeVal());
List<? extends PortForwardingRule> result = _rulesService.searchForIpForwardingRules(publicIpAddressId, id, vmId, this.getStartIndex(), this.getPageSizeVal(), this.getAccountName(), this.getDomainId());
ListResponse<IpForwardingRuleResponse> response = new ListResponse<IpForwardingRuleResponse>();
List<IpForwardingRuleResponse> ipForwardingResponses = new ArrayList<IpForwardingRuleResponse>();
for (PortForwardingRule rule : result) {

View File

@ -26,7 +26,7 @@ import com.cloud.exception.ResourceUnavailableException;
import com.cloud.user.Account;
public interface RulesService {
List<? extends PortForwardingRule> searchForIpForwardingRules(Long ipId, Long id, Long vmId, Long start, Long size);
List<? extends PortForwardingRule> searchForIpForwardingRules(Long ipId, Long id, Long vmId, Long start, Long size, String accountName, Long domainId);
/**
* Creates a port forwarding rule between two ip addresses or between

View File

@ -34,6 +34,7 @@ import com.cloud.api.commands.ListLoadBalancerRuleInstancesCmd;
import com.cloud.api.commands.ListLoadBalancerRulesCmd;
import com.cloud.api.commands.UpdateLoadBalancerRuleCmd;
import com.cloud.dc.dao.VlanDao;
import com.cloud.domain.Domain;
import com.cloud.domain.DomainVO;
import com.cloud.domain.dao.DomainDao;
import com.cloud.event.ActionEvent;
@ -64,6 +65,7 @@ import com.cloud.user.AccountManager;
import com.cloud.user.UserContext;
import com.cloud.user.dao.AccountDao;
import com.cloud.uservm.UserVm;
import com.cloud.utils.Pair;
import com.cloud.utils.component.Inject;
import com.cloud.utils.component.Manager;
import com.cloud.utils.db.DB;
@ -1259,35 +1261,16 @@ public class LoadBalancingRulesManagerImpl implements LoadBalancingRulesManager,
@Override
public List<LoadBalancerVO> searchForLoadBalancers(ListLoadBalancerRulesCmd cmd) throws InvalidParameterValueException, PermissionDeniedException {
Account caller = UserContext.current().getCaller();
Long domainId = cmd.getDomainId();
String accountName = cmd.getAccountName();
Long accountId = null;
Long ipId = cmd.getPublicIpId();
String path = null;
if (_accountMgr.isAdmin(caller.getType())) {
if (domainId != null) {
if ((caller != null) && !_domainDao.isChildDomain(caller.getDomainId(), domainId)) {
throw new PermissionDeniedException("Invalid domain id (" + domainId + ") given, unable to list load balancers");
}
if (accountName != null) {
caller = _accountMgr.getActiveAccount(accountName, domainId);
if (caller == null) {
throw new InvalidParameterValueException("Unable to find account " + accountName + " in domain " + domainId);
}
accountId = caller.getId();
}
}
if (caller.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN) {
DomainVO domain = _domainDao.findById(caller.getDomainId());
if (domain != null) {
path = domain.getPath();
}
}
} else {
domainId = caller.getDomainId();
accountId = caller.getId();
Pair<String, Long> accountDomainPair = _accountMgr.finalizeAccountDomainForList(caller, cmd.getAccountName(), cmd.getDomainId());
String accountName = accountDomainPair.first();
Long domainId = accountDomainPair.second();
if (caller.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN) {
Domain domain = _accountMgr.getDomain(caller.getDomainId());
path = domain.getPath();
}
Filter searchFilter = new Filter(LoadBalancerVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal());
@ -1342,10 +1325,12 @@ public class LoadBalancingRulesManagerImpl implements LoadBalancingRulesManager,
sc.setJoinParameters("lbVMSearch", "instanceId", instanceId);
}
if (accountId != null) {
sc.setParameters("accountId", accountId);
} else if (domainId != null) {
if (domainId != null) {
sc.setParameters("domainId", domainId);
if (accountName != null) {
Account account = _accountMgr.getActiveAccount(accountName, domainId);
sc.setParameters("accountId", account.getId());
}
}
if (path != null) {

View File

@ -1519,13 +1519,6 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
public boolean associateIP(Network network, List<? extends PublicIpAddress> ipAddress) throws ResourceUnavailableException {
DomainRouterVO router = _routerDao.findByNetwork(network.getId());
if (router == null) {
//Return true only when domR entry exists, has Destroyed state and not null Removed field
//because it happens just in case when this method is called as a part of account cleanup.
//In all other cases return false
router = _routerDao.findByNetworkIncludingRemoved(network.getId());
if (router != null && (router.getState() == State.Destroyed || router.getState() == State.Expunging)) {
return true;
}
s_logger.warn("Unable to associate ip addresses, virtual router doesn't exist in the network " + network.getId());
throw new ResourceUnavailableException("Unable to assign ip addresses", DataCenter.class, network.getDataCenterId());
}

View File

@ -28,6 +28,9 @@ import org.apache.log4j.Logger;
import com.cloud.agent.api.to.PortForwardingRuleTO;
import com.cloud.api.commands.ListPortForwardingRulesCmd;
import com.cloud.domain.Domain;
import com.cloud.domain.DomainVO;
import com.cloud.domain.dao.DomainDao;
import com.cloud.event.ActionEvent;
import com.cloud.event.EventTypes;
import com.cloud.event.UsageEventVO;
@ -58,6 +61,7 @@ import com.cloud.utils.component.Inject;
import com.cloud.utils.component.Manager;
import com.cloud.utils.db.DB;
import com.cloud.utils.db.Filter;
import com.cloud.utils.db.JoinBuilder;
import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria;
import com.cloud.utils.db.SearchCriteria.Op;
@ -82,6 +86,7 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager {
@Inject NetworkManager _networkMgr;
@Inject EventDao _eventDao;
@Inject UsageEventDao _usageEventDao;
@Inject DomainDao _domainDao;
@Override
public void detectRulesConflict(FirewallRule newRule, IpAddress ipAddress) throws NetworkRuleConflictException {
@ -409,6 +414,7 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager {
public List<? extends PortForwardingRule> listPortForwardingRules(ListPortForwardingRulesCmd cmd) {
Account caller = UserContext.current().getCaller();
Long ipId = cmd.getIpAddressId();
String path = null;
Pair<String, Long> accountDomainPair = _accountMgr.finalizeAccountDomainForList(caller, cmd.getAccountName(), cmd.getDomainId());
String accountName = accountDomainPair.first();
@ -422,6 +428,11 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager {
_accountMgr.checkAccess(caller, ipAddressVO);
}
if (caller.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN) {
Domain domain = _accountMgr.getDomain(caller.getDomainId());
path = domain.getPath();
}
Filter filter = new Filter(PortForwardingRuleVO.class, "id", false, cmd.getStartIndex(), cmd.getPageSizeVal());
SearchBuilder<PortForwardingRuleVO> sb = _forwardingDao.createSearchBuilder();
sb.and("ip", sb.entity().getSourceIpAddressId(), Op.EQ);
@ -429,6 +440,13 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager {
sb.and("domainId", sb.entity().getDomainId(), Op.EQ);
sb.and("oneToOneNat", sb.entity().isOneToOneNat(), Op.EQ);
if (path != null) {
//for domain admin we should show only subdomains information
SearchBuilder<DomainVO> domainSearch = _domainDao.createSearchBuilder();
domainSearch.and("path", domainSearch.entity().getPath(), SearchCriteria.Op.LIKE);
sb.join("domainSearch", domainSearch, sb.entity().getDomainId(), domainSearch.entity().getId(), JoinBuilder.JoinType.INNER);
}
SearchCriteria<PortForwardingRuleVO> sc = sb.create();
if (ipId != null) {
@ -444,6 +462,10 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager {
}
sc.setParameters("oneToOneNat", false);
if (path != null) {
sc.setJoinParameters("domainSearch", "path", path + "%");
}
return _forwardingDao.search(sc, filter);
}
@ -515,8 +537,62 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager {
}
@Override
public List<PortForwardingRuleVO> searchForIpForwardingRules(Long ipId, Long id, Long vmId, Long start, Long size) {
return _forwardingDao.searchNatRules(ipId, id, vmId, start, size);
public List<PortForwardingRuleVO> searchForIpForwardingRules(Long ipId, Long id, Long vmId, Long start, Long size, String accountName, Long domainId) {
Account caller = UserContext.current().getCaller();
String path = null;
Pair<String, Long> accountDomainPair = _accountMgr.finalizeAccountDomainForList(caller, accountName, domainId);
accountName = accountDomainPair.first();
domainId = accountDomainPair.second();
if(ipId != null){
IPAddressVO ipAddressVO = _ipAddressDao.findById(ipId);
if (ipAddressVO == null || !ipAddressVO.readyToUse()) {
throw new InvalidParameterValueException("Ip address id=" + ipId + " not ready for port forwarding rules yet");
}
_accountMgr.checkAccess(caller, ipAddressVO);
}
if (caller.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN) {
Domain domain = _accountMgr.getDomain(caller.getDomainId());
path = domain.getPath();
}
Filter filter = new Filter(PortForwardingRuleVO.class, "id", false, start, size);
SearchBuilder<PortForwardingRuleVO> sb = _forwardingDao.createSearchBuilder();
sb.and("ip", sb.entity().getSourceIpAddressId(), Op.EQ);
sb.and("accountId", sb.entity().getAccountId(), Op.EQ);
sb.and("domainId", sb.entity().getDomainId(), Op.EQ);
sb.and("oneToOneNat", sb.entity().isOneToOneNat(), Op.EQ);
if (path != null) {
//for domain admin we should show only subdomains information
SearchBuilder<DomainVO> domainSearch = _domainDao.createSearchBuilder();
domainSearch.and("path", domainSearch.entity().getPath(), SearchCriteria.Op.LIKE);
sb.join("domainSearch", domainSearch, sb.entity().getDomainId(), domainSearch.entity().getId(), JoinBuilder.JoinType.INNER);
}
SearchCriteria<PortForwardingRuleVO> sc = sb.create();
if (ipId != null) {
sc.setParameters("ip", ipId);
}
if (domainId != null) {
sc.setParameters("domainId", domainId);
if (accountName != null) {
Account account = _accountMgr.getActiveAccount(accountName, domainId);
sc.setParameters("accountId", account.getId());
}
}
sc.setParameters("oneToOneNat", true);
if (path != null) {
sc.setJoinParameters("domainSearch", "path", path + "%");
}
return _forwardingDao.search(sc, filter);
}
@Override @ActionEvent (eventType=EventTypes.EVENT_NET_RULE_ADD, eventDescription="applying forwarding rule", async=true)

View File

@ -34,8 +34,6 @@ public interface PortForwardingRulesDao extends GenericDao<PortForwardingRuleVO,
List<PortForwardingRuleVO> listByIpAndNotRevoked(long ipId);
List<PortForwardingRuleVO> listByIp(long ipId);
List<PortForwardingRuleVO> searchNatRules(Long ipId, Long id, Long vmId, Long startIndex, Long pageSize);
List<PortForwardingRuleVO> listByVm(Long vmId);

View File

@ -102,28 +102,6 @@ public class PortForwardingRulesDaoImpl extends GenericDaoBase<PortForwardingRul
return listBy(sc, null);
}
@Override
public List<PortForwardingRuleVO> searchNatRules(Long ipId, Long id, Long vmId, Long startIndex, Long pageSize) {
Filter searchFilter = new Filter(PortForwardingRuleVO.class, "id", true, startIndex, pageSize);
SearchCriteria<PortForwardingRuleVO> sc = AllFieldsSearch.create();
if (ipId != null) {
sc.setParameters("ipId", ipId);
}
if (id != null) {
sc.setParameters("id", id);
}
if (vmId != null) {
sc.setParameters("vmId", vmId);
}
sc.setParameters("oneToOneNat", true);
return listBy(sc, searchFilter);
}
@Override
public List<PortForwardingRuleVO> listByNetworkId(long networkId) {
SearchCriteria<PortForwardingRuleVO> sc = AllFieldsSearch.create();

View File

@ -17,7 +17,6 @@
*/
package com.cloud.network.vpn;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@ -30,12 +29,12 @@ import com.cloud.api.commands.ListRemoteAccessVpnsCmd;
import com.cloud.api.commands.ListVpnUsersCmd;
import com.cloud.configuration.Config;
import com.cloud.configuration.dao.ConfigurationDao;
import com.cloud.domain.Domain;
import com.cloud.domain.DomainVO;
import com.cloud.domain.dao.DomainDao;
import com.cloud.exception.AccountLimitException;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.NetworkRuleConflictException;
import com.cloud.exception.PermissionDeniedException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.network.Network;
import com.cloud.network.NetworkManager;
@ -68,6 +67,7 @@ import com.cloud.utils.db.Filter;
import com.cloud.utils.db.JoinBuilder;
import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria;
import com.cloud.utils.db.SearchCriteria.Op;
import com.cloud.utils.db.Transaction;
import com.cloud.utils.net.NetUtils;
@ -400,35 +400,19 @@ public class RemoteAccessVpnManagerImpl implements RemoteAccessVpnService, Manag
@Override
public List<VpnUserVO> searchForVpnUsers(ListVpnUsersCmd cmd) {
Account account = UserContext.current().getCaller();
String accountName = cmd.getAccountName();
Long domainId = cmd.getDomainId();
Long accountId = null;
Account caller = UserContext.current().getCaller();
String username = cmd.getUsername();
String path = null;
//Verify account information
if (account.getType() == Account.ACCOUNT_TYPE_ADMIN) {
if (domainId != null) {
if ((account != null) && !_domainDao.isChildDomain(account.getDomainId(), domainId)) {
throw new PermissionDeniedException("Invalid domain id (" + domainId + ") given, unable to list virtual machines.");
}
if (accountName != null) {
account = _accountDao.findActiveAccount(accountName, domainId);
if (account == null) {
throw new InvalidParameterValueException("Unable to find account " + accountName + " in domain " + domainId);
}
accountId = account.getId();
}
}
if (account.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN) {
DomainVO domain = _domainDao.findById(account.getDomainId());
if (domain != null) {
domainId = domain.getId();
}
}
} else {
accountId = account.getId();
Pair<String, Long> accountDomainPair = _accountMgr.finalizeAccountDomainForList(caller, cmd.getAccountName(), cmd.getDomainId());
String accountName = accountDomainPair.first();
Long domainId = accountDomainPair.second();
if (caller.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN) {
Domain domain = _accountMgr.getDomain(caller.getDomainId());
path = domain.getPath();
}
Filter searchFilter = new Filter(VpnUserVO.class, "username", true, cmd.getStartIndex(), cmd.getPageSizeVal());
@ -439,11 +423,11 @@ public class RemoteAccessVpnManagerImpl implements RemoteAccessVpnService, Manag
sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
sb.and("username", sb.entity().getUsername(), SearchCriteria.Op.EQ);
sb.and("accountId", sb.entity().getAccountId(), SearchCriteria.Op.EQ);
sb.and("domainId", sb.entity().getDomainId(), SearchCriteria.Op.EQ);
sb.and("state", sb.entity().getState(), SearchCriteria.Op.EQ);
if ((accountId == null) && (domainId != null)) {
// if accountId isn't specified, we can do a domain match for the
// admin case
if (path != null) {
//for domain admin we should show only subdomains information
SearchBuilder<DomainVO> domainSearch = _domainDao.createSearchBuilder();
domainSearch.and("path", domainSearch.entity().getPath(), SearchCriteria.Op.LIKE);
sb.join("domainSearch", domainSearch, sb.entity().getDomainId(), domainSearch.entity().getId(), JoinBuilder.JoinType.INNER);
@ -462,11 +446,16 @@ public class RemoteAccessVpnManagerImpl implements RemoteAccessVpnService, Manag
sc.setParameters("username", username);
}
if (accountId != null) {
sc.setParameters("accountId", accountId);
} else if (domainId != null) {
DomainVO domain = _domainDao.findById(domainId);
sc.setJoinParameters("domainSearch", "path", domain.getPath() + "%");
if (domainId != null) {
sc.setParameters("domainId", domainId);
if (accountName != null) {
Account account = _accountMgr.getActiveAccount(accountName, domainId);
sc.setParameters("accountId", account.getId());
}
}
if (path != null) {
sc.setJoinParameters("domainSearch", "path", path + "%");
}
return _vpnUsersDao.search(sc, searchFilter);
@ -476,8 +465,16 @@ public class RemoteAccessVpnManagerImpl implements RemoteAccessVpnService, Manag
public List<RemoteAccessVpnVO> searchForRemoteAccessVpns(ListRemoteAccessVpnsCmd cmd) {
// do some parameter validation
Account caller = UserContext.current().getCaller();
String accountName = cmd.getAccountName();
Long domainId = cmd.getDomainId();
String path = null;
Pair<String, Long> accountDomainPair = _accountMgr.finalizeAccountDomainForList(caller, cmd.getAccountName(), cmd.getDomainId());
String accountName = accountDomainPair.first();
Long domainId = accountDomainPair.second();
if (caller.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN) {
Domain domain = _accountMgr.getDomain(caller.getDomainId());
path = domain.getPath();
}
Long ipAddressId = cmd.getPublicIpId();
if (ipAddressId != null) {
@ -492,31 +489,44 @@ public class RemoteAccessVpnManagerImpl implements RemoteAccessVpnService, Manag
}
}
_accountMgr.checkAccess(caller, publicIp);
List<RemoteAccessVpnVO> vpns = new ArrayList<RemoteAccessVpnVO>(1);
RemoteAccessVpnVO remoteVpn = _remoteAccessVpnDao.findById(ipAddressId);
if (remoteVpn != null) {
vpns.add(remoteVpn);
}
return vpns;
}
Account owner = null;
if (accountName != null) {
owner = _accountDao.findAccount(accountName, domainId);
Filter filter = new Filter(RemoteAccessVpnVO.class, "serverAddressId", false, cmd.getStartIndex(), cmd.getPageSizeVal());
SearchBuilder<RemoteAccessVpnVO> sb = _remoteAccessVpnDao.createSearchBuilder();
sb.and("serverAddressId", sb.entity().getServerAddressId(), Op.EQ);
sb.and("accountId", sb.entity().getAccountId(), Op.EQ);
sb.and("domainId", sb.entity().getDomainId(), Op.EQ);
sb.and("state", sb.entity().getState(), Op.EQ);
if (path != null) {
//for domain admin we should show only subdomains information
SearchBuilder<DomainVO> domainSearch = _domainDao.createSearchBuilder();
domainSearch.and("path", domainSearch.entity().getPath(), SearchCriteria.Op.LIKE);
sb.join("domainSearch", domainSearch, sb.entity().getDomainId(), domainSearch.entity().getId(), JoinBuilder.JoinType.INNER);
}
_accountMgr.checkAccess(caller, owner);
SearchCriteria<RemoteAccessVpnVO> sc = sb.create();
Filter searchFilter = new Filter(RemoteAccessVpnVO.class, "serverAddress", true, cmd.getStartIndex(), cmd.getPageSizeVal());
SearchCriteria<RemoteAccessVpnVO> sc = VpnSearch.create();
sc.setParameters("accountId", owner.getId());
sc.setParameters("state", RemoteAccessVpn.State.Running);
DomainVO domain = _domainDao.findById(domainId);
sc.setJoinParameters("domainSearch", "path", domain.getPath() + "%");
if (ipAddressId != null) {
sc.setParameters("serverAddressId", ipAddressId);
}
if (domainId != null) {
sc.setParameters("domainId", domainId);
if (accountName != null) {
Account account = _accountMgr.getActiveAccount(accountName, domainId);
sc.setParameters("accountId", account.getId());
}
}
if (path != null) {
sc.setJoinParameters("domainSearch", "path", path + "%");
}
return _remoteAccessVpnDao.search(sc, searchFilter);
return _remoteAccessVpnDao.search(sc, filter);
}
@Override

View File

@ -79,8 +79,6 @@ public interface DomainRouterDao extends GenericDao<DomainRouterVO, Long> {
DomainRouterVO findBy(long accountId, long dcId, Role role);
DomainRouterVO findByNetwork(long networkId);
DomainRouterVO findByNetworkIncludingRemoved(long networkId);
DomainRouterVO findByNetworkAndPod(long networkId, long podId);
}

View File

@ -143,15 +143,6 @@ public class DomainRouterDaoImpl extends GenericDaoBase<DomainRouterVO, Long> im
sc.setParameters("network", networkId);
return findOneBy(sc);
}
@Override
public DomainRouterVO findByNetworkIncludingRemoved(long networkId) {
SearchCriteria<DomainRouterVO> sc = AllFieldsSearch.create();
sc.setParameters("network", networkId);
return findOneIncludingRemovedBy(sc);
}
@Override
public List<DomainRouterVO> listByLastHostId(Long hostId) {