diff --git a/plugins/acl/role-based-access-checkers/src/org/apache/cloudstack/acl/api/RoleBasedAPIAccessChecker.java b/plugins/acl/role-based-access-checkers/src/org/apache/cloudstack/acl/api/RoleBasedAPIAccessChecker.java index f43194aeecc..23f25ca1254 100644 --- a/plugins/acl/role-based-access-checkers/src/org/apache/cloudstack/acl/api/RoleBasedAPIAccessChecker.java +++ b/plugins/acl/role-based-access-checkers/src/org/apache/cloudstack/acl/api/RoleBasedAPIAccessChecker.java @@ -22,6 +22,7 @@ import javax.ejb.Local; import javax.inject.Inject; import org.apache.cloudstack.acl.APIChecker; +import org.apache.cloudstack.acl.AclPolicy; import org.apache.cloudstack.acl.AclRole; import org.apache.cloudstack.acl.AclService; import org.apache.log4j.Logger; @@ -54,10 +55,10 @@ public class RoleBasedAPIAccessChecker extends AdapterBase implements APIChecker throw new PermissionDeniedException("The account id=" + user.getAccountId() + "for user id=" + user.getId() + "is null"); } - List roles = _aclService.listAclPolicies(account.getAccountId()); + List policies = _aclService.listAclPolicies(account.getAccountId()); - boolean isAllowed = _aclService.isAPIAccessibleForPolicies(commandName, roles); + boolean isAllowed = _aclService.isAPIAccessibleForPolicies(commandName, policies); if (!isAllowed) { throw new PermissionDeniedException("The API does not exist or is blacklisted. api: " + commandName); } diff --git a/plugins/acl/role-based-access-checkers/src/org/apache/cloudstack/acl/entity/RoleBasedEntityAccessChecker.java b/plugins/acl/role-based-access-checkers/src/org/apache/cloudstack/acl/entity/RoleBasedEntityAccessChecker.java index ca55e1a0164..129c0019b6e 100644 --- a/plugins/acl/role-based-access-checkers/src/org/apache/cloudstack/acl/entity/RoleBasedEntityAccessChecker.java +++ b/plugins/acl/role-based-access-checkers/src/org/apache/cloudstack/acl/entity/RoleBasedEntityAccessChecker.java @@ -21,28 +21,20 @@ import java.util.List; import javax.inject.Inject; -import org.apache.cloudstack.acl.AclEntityPermissionVO; -import org.apache.cloudstack.acl.AclEntityType; -import org.apache.cloudstack.acl.AclGroupAccountMapVO; -import org.apache.cloudstack.acl.AclRole; -import org.apache.cloudstack.acl.AclRolePermissionVO; +import org.apache.cloudstack.acl.AclPolicy; +import org.apache.cloudstack.acl.AclPolicyPermissionVO; import org.apache.cloudstack.acl.AclService; import org.apache.cloudstack.acl.ControlledEntity; +import org.apache.cloudstack.acl.AclEntityType; import org.apache.cloudstack.acl.PermissionScope; import org.apache.cloudstack.acl.SecurityChecker; -import org.apache.cloudstack.acl.SecurityChecker.AccessType; -import org.apache.cloudstack.acl.dao.AclEntityPermissionDao; import org.apache.cloudstack.acl.dao.AclGroupAccountMapDao; -import org.apache.cloudstack.acl.dao.AclGroupDao; -import org.apache.cloudstack.acl.dao.AclRolePermissionDao; -import org.apache.cloudstack.api.InternalIdentity; +import org.apache.cloudstack.acl.dao.AclPolicyPermissionDao; import org.apache.log4j.Logger; import com.cloud.acl.DomainChecker; -import com.cloud.api.ApiDispatcher; import com.cloud.domain.dao.DomainDao; import com.cloud.exception.PermissionDeniedException; -import com.cloud.template.VirtualMachineTemplate; import com.cloud.user.Account; import com.cloud.user.AccountService; import com.cloud.vm.VirtualMachine; @@ -62,10 +54,8 @@ public class RoleBasedEntityAccessChecker extends DomainChecker implements Secur AclGroupAccountMapDao _aclGroupAccountMapDao; @Inject - AclEntityPermissionDao _entityPermissionDao; + AclPolicyPermissionDao _policyPermissionDao; - @Inject - AclRolePermissionDao _rolePermissionDao; @Override public boolean checkAccess(Account caller, ControlledEntity entity, AccessType accessType) @@ -76,71 +66,42 @@ public class RoleBasedEntityAccessChecker extends DomainChecker implements Secur @Override public boolean checkAccess(Account caller, ControlledEntity entity, AccessType accessType, String action) throws PermissionDeniedException { - if (entity instanceof VirtualMachine) { - String entityType = AclEntityType.VM.toString(); + String entityType = entity.getEntityType().toString(); - if (accessType == null) { - accessType = AccessType.ListEntry; - } + if (accessType == null) { + accessType = AccessType.ListEntry; + } - // check if explicit allow/deny is present for this entity in - // acl_entity_permission + // get all Policies of this caller w.r.t the entity + List policies = _aclService.getEffectivePolicies(caller, entity); + HashMap policyPermissionMap = new HashMap(); - if (entity instanceof InternalIdentity) { - InternalIdentity entityWithId = (InternalIdentity) entity; - - List acctGroups = _aclGroupAccountMapDao.listByAccountId(caller.getId()); - - for (AclGroupAccountMapVO groupMapping : acctGroups) { - AclEntityPermissionVO entityPermission = _entityPermissionDao.findByGroupAndEntity( - groupMapping.getAclGroupId(), entityType, entityWithId.getId(), accessType); - - if (entityPermission != null) { - if (entityPermission.isAllowed()) { - return true; - } else { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Account " + caller + " does not have permission to access resource " - + entity + " for access type: " + accessType); - } - throw new PermissionDeniedException(caller - + " does not have permission to access resource " + entity); - } + for (AclPolicy policy : policies) { + List permissions = _policyPermissionDao.listByPolicyActionAndEntity(policy.getId(), + action, entityType); + for (AclPolicyPermissionVO permission : permissions) { + if (checkPermissionScope(caller, permission.getScope(), entity)) { + if (permission.getEntityType().equals(entityType)) { + policyPermissionMap.put(policy, permission.getPermission().isGranted()); + break; + } else if (permission.getEntityType().equals("*")) { + policyPermissionMap.put(policy, permission.getPermission().isGranted()); } } } - - // get all Roles of this caller w.r.t the entity - List roles = _aclService.getEffectivePolicies(caller, entity); - HashMap rolePermissionMap = new HashMap(); - - for (AclRole role : roles) { - List permissions = _rolePermissionDao.listByRoleAndEntity(role.getId(), - entityType, accessType); - for (AclRolePermissionVO permission : permissions) { - if (checkPermissionScope(caller, permission.getScope(), entity)) { - if (permission.getEntityType().equals(entityType)) { - rolePermissionMap.put(role, permission.isAllowed()); - break; - } else if (permission.getEntityType().equals("*")) { - rolePermissionMap.put(role, permission.isAllowed()); - } - } - } - if (rolePermissionMap.containsKey(role) && rolePermissionMap.get(role)) { - return true; - } + if (policyPermissionMap.containsKey(policy) && policyPermissionMap.get(policy)) { + return true; } + } - if (!roles.isEmpty()) { // Since we reach this point, none of the - // roles granted access - if (s_logger.isDebugEnabled()) { - s_logger.debug("Account " + caller + " does not have permission to access resource " + entity - + " for access type: " + accessType); - } - throw new PermissionDeniedException(caller + " does not have permission to access resource " + entity); + if (!policies.isEmpty()) { // Since we reach this point, none of the + // roles granted access + if (s_logger.isDebugEnabled()) { + s_logger.debug("Account " + caller + " does not have permission to access resource " + entity + + " for access type: " + accessType); } + throw new PermissionDeniedException(caller + " does not have permission to access resource " + entity); } return false; diff --git a/server/src/org/apache/cloudstack/acl/AclServiceImpl.java b/server/src/org/apache/cloudstack/acl/AclServiceImpl.java index 1ab4efeab70..f8ea1e6518d 100644 --- a/server/src/org/apache/cloudstack/acl/AclServiceImpl.java +++ b/server/src/org/apache/cloudstack/acl/AclServiceImpl.java @@ -365,7 +365,7 @@ public class AclServiceImpl extends ManagerBase implements AclService, Manager { @Override public List listAclPolicies(long accountId) { - // static roles of the account + // static policies of the account SearchBuilder groupSB = _aclGroupAccountMapDao.createSearchBuilder(); groupSB.and("account", groupSB.entity().getAccountId(), Op.EQ); @@ -377,12 +377,12 @@ public class AclServiceImpl extends ManagerBase implements AclService, Manager { SearchCriteria policySc = policySB.create(); policySc.setJoinParameters("accountgroupjoin", "account", accountId); - List roleIds = _aclGroupPolicyMapDao.customSearch(policySc, null); + List policyIds = _aclGroupPolicyMapDao.customSearch(policySc, null); SearchBuilder sb = _aclPolicyDao.createSearchBuilder(); sb.and("ids", sb.entity().getId(), Op.IN); SearchCriteria sc = sb.create(); - sc.setParameters("ids", roleIds.toArray(new Object[roleIds.size()])); + sc.setParameters("ids", policyIds.toArray(new Object[policyIds.size()])); List policies = _aclPolicyDao.customSearch(sc, null); return new ArrayList(policies); @@ -647,7 +647,6 @@ public class AclServiceImpl extends ManagerBase implements AclService, Manager { SearchBuilder sb = _policyPermissionDao.createSearchBuilder(); sb.and("action", sb.entity().getAction(), Op.EQ); sb.and("policyId", sb.entity().getAclPolicyId(), Op.IN); - sb.and("entityType", sb.entity().getEntityType(), Op.NULL); SearchCriteria sc = sb.create(); sc.setParameters("policyId", policyIds.toArray(new Object[policyIds.size()])); @@ -667,7 +666,7 @@ public class AclServiceImpl extends ManagerBase implements AclService, Manager { // Get the static Policies of the Caller List policies = listAclPolicies(caller.getId()); - // add any dynamic roles w.r.t the entity + // add any dynamic policies w.r.t the entity if (caller.getId() == entity.getAccountId()) { // The caller owns the entity AclPolicy owner = _aclPolicyDao.findByName(Domain.ROOT_DOMAIN, "RESOURCE_OWNER"); diff --git a/setup/db/db/schema-421to430.sql b/setup/db/db/schema-421to430.sql index f15f2e481e3..ef0745817de 100644 --- a/setup/db/db/schema-421to430.sql +++ b/setup/db/db/schema-421to430.sql @@ -378,8 +378,7 @@ INSERT IGNORE INTO `cloud`.`acl_policy` (id, name, description, uuid, domain_id, INSERT IGNORE INTO `cloud`.`acl_policy` (id, name, description, uuid, domain_id, account_id, created, policy_type) VALUES (3, 'DOMAIN_ADMIN', 'Domain admin role', UUID(), 1, 1, Now(), 'Static'); INSERT IGNORE INTO `cloud`.`acl_policy` (id, name, description, uuid, domain_id, account_id, created, policy_type) VALUES (4, 'RESOURCE_DOMAIN_ADMIN', 'Resource domain admin role', UUID(), 1, 1, Now(), 'Static'); INSERT IGNORE INTO `cloud`.`acl_policy` (id, name, description, uuid, domain_id, account_id, created, policy_type) VALUES (5, 'READ_ONLY_ADMIN', 'Read only admin role', UUID(), 1, 1, Now(), 'Static'); --- RESOURCE_OWNER dynamic policy we will handle that inside java logic --- INSERT IGNORE INTO `cloud`.`acl_policy` (id, name, description, uuid, domain_id, account_id, created, policy_type) VALUES (6, 'RESOURCE_OWNER', 'Resource owner role', UUID(), 1, 1, Now(), 'Dynamic'); +INSERT IGNORE INTO `cloud`.`acl_policy` (id, name, description, uuid, domain_id, account_id, created, policy_type) VALUES (6, 'RESOURCE_OWNER', 'Resource owner role', UUID(), 1, 1, Now(), 'Dynamic'); INSERT IGNORE INTO `cloud`.`acl_group` (id, name, description, uuid, domain_id, account_id, created) VALUES (1, 'NORMAL', 'Domain user group', UUID(), 1, 1, Now());