Return-Path: X-Original-To: apmail-cloudstack-commits-archive@www.apache.org Delivered-To: apmail-cloudstack-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id DC94411529 for ; Mon, 19 May 2014 22:46:27 +0000 (UTC) Received: (qmail 42964 invoked by uid 500); 19 May 2014 22:46:27 -0000 Delivered-To: apmail-cloudstack-commits-archive@cloudstack.apache.org Received: (qmail 42851 invoked by uid 500); 19 May 2014 22:46:27 -0000 Mailing-List: contact commits-help@cloudstack.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@cloudstack.apache.org Delivered-To: mailing list commits@cloudstack.apache.org Received: (qmail 42547 invoked by uid 99); 19 May 2014 22:46:27 -0000 Received: from tyr.zones.apache.org (HELO tyr.zones.apache.org) (140.211.11.114) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 19 May 2014 22:46:27 +0000 Received: by tyr.zones.apache.org (Postfix, from userid 65534) id 125E4936649; Mon, 19 May 2014 22:46:27 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: mchen@apache.org To: commits@cloudstack.apache.org Date: Mon, 19 May 2014 22:46:30 -0000 Message-Id: <13cf322eb7154351bf70ba457a9564c8@git.apache.org> In-Reply-To: <94769a3eaa384199ace00ef5d4a70b1e@git.apache.org> References: <94769a3eaa384199ace00ef5d4a70b1e@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [5/5] git commit: updated refs/heads/4.4-forward-iam to 26a6aa5 Revert "Disable IAM feature from 4.4 release." This reverts commit 9484328eb7bae480ed0c4ee90df9e717e27043f3. Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/26a6aa54 Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/26a6aa54 Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/26a6aa54 Branch: refs/heads/4.4-forward-iam Commit: 26a6aa54602cc5507011142150a1c437f0341bd6 Parents: 9484328 Author: Min Chen Authored: Mon May 19 15:44:22 2014 -0700 Committer: Min Chen Committed: Mon May 19 15:44:22 2014 -0700 ---------------------------------------------------------------------- api/src/com/cloud/network/NetworkModel.java | 4 + api/src/com/cloud/user/AccountService.java | 7 +- .../apache/cloudstack/acl/SecurityChecker.java | 6 +- .../address/AssociateIPAddrCmdByAdmin.java | 5 +- .../command/admin/vm/AddNicToVMCmdByAdmin.java | 1 - .../user/address/AssociateIPAddrCmd.java | 1 + .../firewall/CreatePortForwardingRuleCmd.java | 1 - .../AssignToLoadBalancerRuleCmd.java | 9 +- .../ListLBStickinessPoliciesCmd.java | 4 +- .../command/user/nat/DisableStaticNatCmd.java | 5 +- .../command/user/nat/EnableStaticNatCmd.java | 9 +- .../user/snapshot/CreateSnapshotCmd.java | 2 + .../api/command/user/vm/AddNicToVMCmd.java | 1 + .../user/vmsnapshot/CreateVMSnapshotCmd.java | 3 +- .../command/user/volume/AttachVolumeCmd.java | 4 +- .../command/user/volume/CreateVolumeCmd.java | 4 + client/pom.xml | 10 + client/tomcatconf/commands.properties.in | 15 + .../core/spring-core-registry-core-context.xml | 2 +- .../com/cloud/upgrade/dao/Upgrade430to440.java | 47 ++ .../db/src/com/cloud/utils/db/SearchBase.java | 12 +- .../lb/InternalLoadBalancerVMManagerImpl.java | 9 +- .../contrail/management/ServiceManagerImpl.java | 5 +- .../contrail/management/MockAccountManager.java | 86 +-- .../spring-server-core-managers-context.xml | 1 + server/src/com/cloud/acl/DomainChecker.java | 19 +- server/src/com/cloud/api/ApiDispatcher.java | 22 - server/src/com/cloud/api/ApiResponseHelper.java | 2 +- .../cloud/api/dispatch/ParamProcessWorker.java | 107 ++- .../com/cloud/api/query/QueryManagerImpl.java | 743 ++++++++++++++++--- .../configuration/ConfigurationManagerImpl.java | 3 +- .../com/cloud/network/IpAddressManagerImpl.java | 17 +- .../src/com/cloud/network/NetworkModelImpl.java | 45 +- .../com/cloud/network/NetworkServiceImpl.java | 26 +- .../cloud/network/as/AutoScaleManagerImpl.java | 38 +- .../network/firewall/FirewallManagerImpl.java | 23 +- .../lb/LoadBalancingRulesManagerImpl.java | 52 +- .../VirtualNetworkApplianceManagerImpl.java | 10 +- .../cloud/network/rules/RulesManagerImpl.java | 46 +- .../security/SecurityGroupManagerImpl.java | 8 +- .../network/vpc/NetworkACLServiceImpl.java | 56 +- .../com/cloud/network/vpc/VpcManagerImpl.java | 65 +- .../network/vpn/RemoteAccessVpnManagerImpl.java | 42 +- .../network/vpn/Site2SiteVpnManagerImpl.java | 57 +- .../com/cloud/projects/ProjectManagerImpl.java | 18 +- .../resourcelimit/ResourceLimitManagerImpl.java | 8 +- .../com/cloud/server/ManagementServerImpl.java | 36 +- .../com/cloud/servlet/ConsoleProxyServlet.java | 2 +- .../com/cloud/storage/VolumeApiServiceImpl.java | 23 +- .../storage/snapshot/SnapshotManagerImpl.java | 26 +- .../cloud/tags/TaggedResourceManagerImpl.java | 4 +- .../com/cloud/template/TemplateAdapterBase.java | 4 +- .../com/cloud/template/TemplateManagerImpl.java | 34 +- server/src/com/cloud/user/AccountManager.java | 33 +- .../src/com/cloud/user/AccountManagerImpl.java | 649 +++++----------- server/src/com/cloud/vm/UserVmManagerImpl.java | 111 +-- .../vm/snapshot/VMSnapshotManagerImpl.java | 25 +- .../affinity/AffinityGroupServiceImpl.java | 13 +- .../lb/ApplicationLoadBalancerManagerImpl.java | 15 +- .../cloudstack/network/lb/CertServiceImpl.java | 8 +- .../GlobalLoadBalancingRulesServiceImpl.java | 14 +- .../com/cloud/event/EventControlsUnitTest.java | 2 +- .../com/cloud/network/MockNetworkModelImpl.java | 8 + .../com/cloud/user/MockAccountManagerImpl.java | 75 +- server/test/com/cloud/vm/UserVmManagerTest.java | 8 +- .../vm/snapshot/VMSnapshotManagerTest.java | 2 +- .../com/cloud/vpc/MockNetworkModelImpl.java | 8 + .../iam/RoleBasedEntityAccessChecker.java | 19 +- services/pom.xml | 1 + test/integration/smoke/test_vm_iam.py | 719 ++++++++++++++++++ 70 files changed, 2318 insertions(+), 1181 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cloudstack/blob/26a6aa54/api/src/com/cloud/network/NetworkModel.java ---------------------------------------------------------------------- diff --git a/api/src/com/cloud/network/NetworkModel.java b/api/src/com/cloud/network/NetworkModel.java index f6555db..1e0a8e8 100644 --- a/api/src/com/cloud/network/NetworkModel.java +++ b/api/src/com/cloud/network/NetworkModel.java @@ -22,6 +22,8 @@ import java.util.List; import java.util.Map; import java.util.Set; +import org.apache.cloudstack.acl.SecurityChecker.AccessType; + import com.cloud.dc.Vlan; import com.cloud.exception.InsufficientAddressCapacityException; import com.cloud.exception.InvalidParameterValueException; @@ -273,4 +275,6 @@ public interface NetworkModel { boolean isNetworkReadyForGc(long networkId); boolean getNetworkEgressDefaultPolicy(Long networkId); + + void checkNetworkPermissions(Account owner, Network network, AccessType accessType); } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cloudstack/blob/26a6aa54/api/src/com/cloud/user/AccountService.java ---------------------------------------------------------------------- diff --git a/api/src/com/cloud/user/AccountService.java b/api/src/com/cloud/user/AccountService.java index eac8a76..6cc86cd 100755 --- a/api/src/com/cloud/user/AccountService.java +++ b/api/src/com/cloud/user/AccountService.java @@ -103,12 +103,11 @@ public interface AccountService { RoleType getRoleType(Account account); - void checkAccess(Account account, Domain domain) throws PermissionDeniedException; + void checkAccess(Account caller, Domain domain) throws PermissionDeniedException; - void checkAccess(Account account, AccessType accessType, boolean sameOwner, ControlledEntity... entities) throws PermissionDeniedException; + void checkAccess(Account caller, AccessType accessType, ControlledEntity... entities) throws PermissionDeniedException; - void checkAccess(Account account, AccessType accessType, boolean sameOwner, String apiName, - ControlledEntity... entities) throws PermissionDeniedException; + void checkAccess(Account caller, AccessType accessType, String apiName, ControlledEntity... entities) throws PermissionDeniedException; Long finalyzeAccountId(String accountName, Long domainId, Long projectId, boolean enabledOnly); http://git-wip-us.apache.org/repos/asf/cloudstack/blob/26a6aa54/api/src/org/apache/cloudstack/acl/SecurityChecker.java ---------------------------------------------------------------------- diff --git a/api/src/org/apache/cloudstack/acl/SecurityChecker.java b/api/src/org/apache/cloudstack/acl/SecurityChecker.java index 4170871..79366bd 100644 --- a/api/src/org/apache/cloudstack/acl/SecurityChecker.java +++ b/api/src/org/apache/cloudstack/acl/SecurityChecker.java @@ -31,10 +31,10 @@ import com.cloud.utils.component.Adapter; public interface SecurityChecker extends Adapter { public enum AccessType { - ModifyProject, - OperateEntry, + ListEntry, UseEntry, - ListEntry + OperateEntry, + ModifyProject, } /** http://git-wip-us.apache.org/repos/asf/cloudstack/blob/26a6aa54/api/src/org/apache/cloudstack/api/command/admin/address/AssociateIPAddrCmdByAdmin.java ---------------------------------------------------------------------- diff --git a/api/src/org/apache/cloudstack/api/command/admin/address/AssociateIPAddrCmdByAdmin.java b/api/src/org/apache/cloudstack/api/command/admin/address/AssociateIPAddrCmdByAdmin.java index dbff93f..494a6d6 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/address/AssociateIPAddrCmdByAdmin.java +++ b/api/src/org/apache/cloudstack/api/command/admin/address/AssociateIPAddrCmdByAdmin.java @@ -31,8 +31,11 @@ import com.cloud.exception.InsufficientCapacityException; import com.cloud.exception.ResourceAllocationException; import com.cloud.exception.ResourceUnavailableException; import com.cloud.network.IpAddress; +import com.cloud.network.vpc.Vpc; -@APICommand(name = "associateIpAddress", description = "Acquires and associates a public IP to an account.", responseObject = IPAddressResponse.class, responseView = ResponseView.Full) +@APICommand(name = "associateIpAddress", description = "Acquires and associates a public IP to an account.", responseObject = IPAddressResponse.class, responseView = ResponseView.Full, + entityType = {IpAddress.class, Vpc.class}, + requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class AssociateIPAddrCmdByAdmin extends AssociateIPAddrCmd { public static final Logger s_logger = Logger.getLogger(AssociateIPAddrCmdByAdmin.class.getName()); http://git-wip-us.apache.org/repos/asf/cloudstack/blob/26a6aa54/api/src/org/apache/cloudstack/api/command/admin/vm/AddNicToVMCmdByAdmin.java ---------------------------------------------------------------------- diff --git a/api/src/org/apache/cloudstack/api/command/admin/vm/AddNicToVMCmdByAdmin.java b/api/src/org/apache/cloudstack/api/command/admin/vm/AddNicToVMCmdByAdmin.java index 945f849..3dd22c1 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/vm/AddNicToVMCmdByAdmin.java +++ b/api/src/org/apache/cloudstack/api/command/admin/vm/AddNicToVMCmdByAdmin.java @@ -33,7 +33,6 @@ import org.apache.cloudstack.context.CallContext; import com.cloud.uservm.UserVm; import com.cloud.vm.VirtualMachine; - @APICommand(name = "addNicToVirtualMachine", description = "Adds VM to specified network by creating a NIC", responseObject = UserVmResponse.class, responseView = ResponseView.Full, entityType = {VirtualMachine.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = true) public class AddNicToVMCmdByAdmin extends AddNicToVMCmd { http://git-wip-us.apache.org/repos/asf/cloudstack/blob/26a6aa54/api/src/org/apache/cloudstack/api/command/user/address/AssociateIPAddrCmd.java ---------------------------------------------------------------------- diff --git a/api/src/org/apache/cloudstack/api/command/user/address/AssociateIPAddrCmd.java b/api/src/org/apache/cloudstack/api/command/user/address/AssociateIPAddrCmd.java index 96174e1..48fe43e 100644 --- a/api/src/org/apache/cloudstack/api/command/user/address/AssociateIPAddrCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/address/AssociateIPAddrCmd.java @@ -58,6 +58,7 @@ import com.cloud.projects.Project; import com.cloud.user.Account; @APICommand(name = "associateIpAddress", description = "Acquires and associates a public IP to an account.", responseObject = IPAddressResponse.class, responseView = ResponseView.Restricted, + entityType = {IpAddress.class, Vpc.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class AssociateIPAddrCmd extends BaseAsyncCreateCmd { public static final Logger s_logger = Logger.getLogger(AssociateIPAddrCmd.class.getName()); http://git-wip-us.apache.org/repos/asf/cloudstack/blob/26a6aa54/api/src/org/apache/cloudstack/api/command/user/firewall/CreatePortForwardingRuleCmd.java ---------------------------------------------------------------------- diff --git a/api/src/org/apache/cloudstack/api/command/user/firewall/CreatePortForwardingRuleCmd.java b/api/src/org/apache/cloudstack/api/command/user/firewall/CreatePortForwardingRuleCmd.java index 865cd1b..6fb120f 100644 --- a/api/src/org/apache/cloudstack/api/command/user/firewall/CreatePortForwardingRuleCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/firewall/CreatePortForwardingRuleCmd.java @@ -49,7 +49,6 @@ import com.cloud.utils.net.Ip; import com.cloud.utils.net.NetUtils; import com.cloud.vm.VirtualMachine; - @APICommand(name = "createPortForwardingRule", description = "Creates a port forwarding rule", responseObject = FirewallRuleResponse.class, entityType = {FirewallRule.class, VirtualMachine.class, IpAddress.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) http://git-wip-us.apache.org/repos/asf/cloudstack/blob/26a6aa54/api/src/org/apache/cloudstack/api/command/user/loadbalancer/AssignToLoadBalancerRuleCmd.java ---------------------------------------------------------------------- diff --git a/api/src/org/apache/cloudstack/api/command/user/loadbalancer/AssignToLoadBalancerRuleCmd.java b/api/src/org/apache/cloudstack/api/command/user/loadbalancer/AssignToLoadBalancerRuleCmd.java index dd9adef..db4d70e 100644 --- a/api/src/org/apache/cloudstack/api/command/user/loadbalancer/AssignToLoadBalancerRuleCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/loadbalancer/AssignToLoadBalancerRuleCmd.java @@ -23,8 +23,11 @@ import java.util.Iterator; import java.util.List; import java.util.Map; +import com.cloud.utils.net.NetUtils; import org.apache.log4j.Logger; +import org.apache.cloudstack.acl.SecurityChecker.AccessType; +import org.apache.cloudstack.api.ACL; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.ApiErrorCode; @@ -38,15 +41,15 @@ import org.apache.cloudstack.context.CallContext; import com.cloud.event.EventTypes; import com.cloud.exception.InvalidParameterValueException; +import com.cloud.network.rules.FirewallRule; import com.cloud.network.rules.LoadBalancer; import com.cloud.user.Account; import com.cloud.utils.StringUtils; -import com.cloud.utils.net.NetUtils; import com.cloud.vm.VirtualMachine; @APICommand(name = "assignToLoadBalancerRule", description = "Assigns virtual machine or a list of virtual machines to a load balancer rule.", - responseObject = SuccessResponse.class, + responseObject = SuccessResponse.class, entityType = {FirewallRule.class, VirtualMachine.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class AssignToLoadBalancerRuleCmd extends BaseAsyncCmd { @@ -58,6 +61,7 @@ public class AssignToLoadBalancerRuleCmd extends BaseAsyncCmd { //////////////// API parameters ///////////////////// ///////////////////////////////////////////////////// + @ACL(accessType = AccessType.OperateEntry) @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = FirewallRuleResponse.class, @@ -65,6 +69,7 @@ public class AssignToLoadBalancerRuleCmd extends BaseAsyncCmd { description = "the ID of the load balancer rule") private Long id; + @ACL(accessType = AccessType.OperateEntry) @Parameter(name = ApiConstants.VIRTUAL_MACHINE_IDS, type = CommandType.LIST, collectionType = CommandType.UUID, http://git-wip-us.apache.org/repos/asf/cloudstack/blob/26a6aa54/api/src/org/apache/cloudstack/api/command/user/loadbalancer/ListLBStickinessPoliciesCmd.java ---------------------------------------------------------------------- diff --git a/api/src/org/apache/cloudstack/api/command/user/loadbalancer/ListLBStickinessPoliciesCmd.java b/api/src/org/apache/cloudstack/api/command/user/loadbalancer/ListLBStickinessPoliciesCmd.java index 9905c0b..dd03191 100644 --- a/api/src/org/apache/cloudstack/api/command/user/loadbalancer/ListLBStickinessPoliciesCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/loadbalancer/ListLBStickinessPoliciesCmd.java @@ -86,7 +86,7 @@ public class ListLBStickinessPoliciesCmd extends BaseListCmd { if (lb != null) { //check permissions Account caller = CallContext.current().getCallingAccount(); - _accountService.checkAccess(caller, null, true, lb); + _accountService.checkAccess(caller, null, lb); List stickinessPolicies = _lbService.searchForLBStickinessPolicies(this); LBStickinessResponse spResponse = _responseGenerator.createLBStickinessPolicyResponse(stickinessPolicies, lb); spResponses.add(spResponse); @@ -94,7 +94,7 @@ public class ListLBStickinessPoliciesCmd extends BaseListCmd { } response.setResponseName(getCommandName()); - this.setResponseObject(response); + setResponseObject(response); } } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/26a6aa54/api/src/org/apache/cloudstack/api/command/user/nat/DisableStaticNatCmd.java ---------------------------------------------------------------------- diff --git a/api/src/org/apache/cloudstack/api/command/user/nat/DisableStaticNatCmd.java b/api/src/org/apache/cloudstack/api/command/user/nat/DisableStaticNatCmd.java index 1df77ec..2a9311e 100644 --- a/api/src/org/apache/cloudstack/api/command/user/nat/DisableStaticNatCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/nat/DisableStaticNatCmd.java @@ -34,8 +34,11 @@ import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.NetworkRuleConflictException; import com.cloud.exception.ResourceUnavailableException; import com.cloud.network.IpAddress; +import com.cloud.network.vpc.Vpc; +import com.cloud.vm.VirtualMachine; @APICommand(name = "disableStaticNat", description = "Disables static rule for given ip address", responseObject = SuccessResponse.class, + entityType = {IpAddress.class, VirtualMachine.class, Vpc.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class DisableStaticNatCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(DeletePortForwardingRuleCmd.class.getName()); @@ -89,7 +92,7 @@ public class DisableStaticNatCmd extends BaseAsyncCmd { if (result) { SuccessResponse response = new SuccessResponse(getCommandName()); - this.setResponseObject(response); + setResponseObject(response); } else { throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to disable static nat"); } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/26a6aa54/api/src/org/apache/cloudstack/api/command/user/nat/EnableStaticNatCmd.java ---------------------------------------------------------------------- diff --git a/api/src/org/apache/cloudstack/api/command/user/nat/EnableStaticNatCmd.java b/api/src/org/apache/cloudstack/api/command/user/nat/EnableStaticNatCmd.java index aa4e287..9d88876 100644 --- a/api/src/org/apache/cloudstack/api/command/user/nat/EnableStaticNatCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/nat/EnableStaticNatCmd.java @@ -18,6 +18,8 @@ package org.apache.cloudstack.api.command.user.nat; import org.apache.log4j.Logger; +import org.apache.cloudstack.acl.SecurityChecker.AccessType; +import org.apache.cloudstack.api.ACL; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.ApiErrorCode; @@ -33,10 +35,13 @@ import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.NetworkRuleConflictException; import com.cloud.exception.ResourceUnavailableException; import com.cloud.network.IpAddress; +import com.cloud.network.vpc.Vpc; import com.cloud.user.Account; import com.cloud.uservm.UserVm; +import com.cloud.vm.VirtualMachine; @APICommand(name = "enableStaticNat", description = "Enables static nat for given ip address", responseObject = SuccessResponse.class, + entityType = {IpAddress.class, VirtualMachine.class, Vpc.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class EnableStaticNatCmd extends BaseCmd { public static final Logger s_logger = Logger.getLogger(CreateIpForwardingRuleCmd.class.getName()); @@ -47,10 +52,12 @@ public class EnableStaticNatCmd extends BaseCmd { //////////////// API parameters ///////////////////// ///////////////////////////////////////////////////// + @ACL(accessType = AccessType.OperateEntry) @Parameter(name = ApiConstants.IP_ADDRESS_ID, type = CommandType.UUID, entityType = IPAddressResponse.class, required = true, description = "the public IP " + "address id for which static nat feature is being enabled") private Long ipAddressId; + @ACL(accessType = AccessType.OperateEntry) @Parameter(name = ApiConstants.VIRTUAL_MACHINE_ID, type = CommandType.UUID, entityType = UserVmResponse.class, required = true, description = "the ID of " + "the virtual machine for enabling static nat feature") private Long virtualMachineId; @@ -133,7 +140,7 @@ public class EnableStaticNatCmd extends BaseCmd { boolean result = _rulesService.enableStaticNat(ipAddressId, virtualMachineId, getNetworkId(), getVmSecondaryIp()); if (result) { SuccessResponse response = new SuccessResponse(getCommandName()); - this.setResponseObject(response); + setResponseObject(response); } else { throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to enable static nat"); } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/26a6aa54/api/src/org/apache/cloudstack/api/command/user/snapshot/CreateSnapshotCmd.java ---------------------------------------------------------------------- diff --git a/api/src/org/apache/cloudstack/api/command/user/snapshot/CreateSnapshotCmd.java b/api/src/org/apache/cloudstack/api/command/user/snapshot/CreateSnapshotCmd.java index df7fe82..bd8662e 100644 --- a/api/src/org/apache/cloudstack/api/command/user/snapshot/CreateSnapshotCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/snapshot/CreateSnapshotCmd.java @@ -18,6 +18,7 @@ package org.apache.cloudstack.api.command.user.snapshot; import org.apache.log4j.Logger; +import org.apache.cloudstack.api.ACL; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiCommandJobType; import org.apache.cloudstack.api.ApiConstants; @@ -62,6 +63,7 @@ public class CreateSnapshotCmd extends BaseAsyncCreateCmd { description = "The domain ID of the snapshot. If used with the account parameter, specifies a domain for the account associated with the disk volume.") private Long domainId; + @ACL @Parameter(name = ApiConstants.VOLUME_ID, type = CommandType.UUID, entityType = VolumeResponse.class, required = true, description = "The ID of the disk volume") private Long volumeId; http://git-wip-us.apache.org/repos/asf/cloudstack/blob/26a6aa54/api/src/org/apache/cloudstack/api/command/user/vm/AddNicToVMCmd.java ---------------------------------------------------------------------- diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/AddNicToVMCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/AddNicToVMCmd.java index f265ecf..fd30152 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vm/AddNicToVMCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vm/AddNicToVMCmd.java @@ -54,6 +54,7 @@ public class AddNicToVMCmd extends BaseAsyncCmd { required=true, description="Virtual Machine ID") private Long vmId; + @ACL @Parameter(name = ApiConstants.NETWORK_ID, type = CommandType.UUID, entityType = NetworkResponse.class, required = true, description = "Network ID") private Long netId; http://git-wip-us.apache.org/repos/asf/cloudstack/blob/26a6aa54/api/src/org/apache/cloudstack/api/command/user/vmsnapshot/CreateVMSnapshotCmd.java ---------------------------------------------------------------------- diff --git a/api/src/org/apache/cloudstack/api/command/user/vmsnapshot/CreateVMSnapshotCmd.java b/api/src/org/apache/cloudstack/api/command/user/vmsnapshot/CreateVMSnapshotCmd.java index 10ff5cd..1310ba5 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vmsnapshot/CreateVMSnapshotCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vmsnapshot/CreateVMSnapshotCmd.java @@ -19,7 +19,6 @@ package org.apache.cloudstack.api.command.user.vmsnapshot; import java.util.logging.Logger; -import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.api.ACL; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; @@ -43,7 +42,7 @@ public class CreateVMSnapshotCmd extends BaseAsyncCreateCmd { public static final Logger s_logger = Logger.getLogger(CreateVMSnapshotCmd.class.getName()); private static final String s_name = "createvmsnapshotresponse"; - @ACL(accessType = AccessType.OperateEntry) + @ACL @Parameter(name = ApiConstants.VIRTUAL_MACHINE_ID, type = CommandType.UUID, required = true, entityType = UserVmResponse.class, description = "The ID of the vm") private Long vmId; http://git-wip-us.apache.org/repos/asf/cloudstack/blob/26a6aa54/api/src/org/apache/cloudstack/api/command/user/volume/AttachVolumeCmd.java ---------------------------------------------------------------------- diff --git a/api/src/org/apache/cloudstack/api/command/user/volume/AttachVolumeCmd.java b/api/src/org/apache/cloudstack/api/command/user/volume/AttachVolumeCmd.java index 467ffc4..8034745 100644 --- a/api/src/org/apache/cloudstack/api/command/user/volume/AttachVolumeCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/volume/AttachVolumeCmd.java @@ -37,7 +37,8 @@ import com.cloud.storage.Volume; import com.cloud.user.Account; import com.cloud.vm.VirtualMachine; -@APICommand(name = "attachVolume", description = "Attaches a disk volume to a virtual machine.", responseObject = VolumeResponse.class, responseView = ResponseView.Restricted, entityType = {VirtualMachine.class}, +@APICommand(name = "attachVolume", description = "Attaches a disk volume to a virtual machine.", responseObject = VolumeResponse.class, responseView = ResponseView.Restricted, entityType = { + VirtualMachine.class, Volume.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class AttachVolumeCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(AttachVolumeCmd.class.getName()); @@ -52,6 +53,7 @@ public class AttachVolumeCmd extends BaseAsyncCmd { + "* 4 - /dev/xvde" + "* 5 - /dev/xvdf" + "* 6 - /dev/xvdg" + "* 7 - /dev/xvdh" + "* 8 - /dev/xvdi" + "* 9 - /dev/xvdj") private Long deviceId; + @ACL(accessType = AccessType.OperateEntry) @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = VolumeResponse.class, required = true, description = "the ID of the disk volume") private Long id; http://git-wip-us.apache.org/repos/asf/cloudstack/blob/26a6aa54/api/src/org/apache/cloudstack/api/command/user/volume/CreateVolumeCmd.java ---------------------------------------------------------------------- diff --git a/api/src/org/apache/cloudstack/api/command/user/volume/CreateVolumeCmd.java b/api/src/org/apache/cloudstack/api/command/user/volume/CreateVolumeCmd.java index 1e3c01c..dc91261 100644 --- a/api/src/org/apache/cloudstack/api/command/user/volume/CreateVolumeCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/volume/CreateVolumeCmd.java @@ -19,6 +19,8 @@ package org.apache.cloudstack.api.command.user.volume; import org.apache.log4j.Logger; import org.apache.cloudstack.acl.RoleType; +import org.apache.cloudstack.acl.SecurityChecker.AccessType; +import org.apache.cloudstack.api.ACL; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiCommandJobType; import org.apache.cloudstack.api.ApiConstants; @@ -91,6 +93,7 @@ public class CreateVolumeCmd extends BaseAsyncCreateCustomIdCmd { @Parameter(name = ApiConstants.MAX_IOPS, type = CommandType.LONG, description = "max iops") private Long maxIops; + @ACL @Parameter(name = ApiConstants.SNAPSHOT_ID, type = CommandType.UUID, entityType = SnapshotResponse.class, @@ -103,6 +106,7 @@ public class CreateVolumeCmd extends BaseAsyncCreateCustomIdCmd { @Parameter(name = ApiConstants.DISPLAY_VOLUME, type = CommandType.BOOLEAN, description = "an optional field, whether to display the volume to the end user or not.", authorized = {RoleType.Admin}) private Boolean displayVolume; + @ACL(accessType = AccessType.OperateEntry) @Parameter(name = ApiConstants.VIRTUAL_MACHINE_ID, type = CommandType.UUID, entityType = UserVmResponse.class, http://git-wip-us.apache.org/repos/asf/cloudstack/blob/26a6aa54/client/pom.xml ---------------------------------------------------------------------- diff --git a/client/pom.xml b/client/pom.xml index 1a972c9..eda8a85 100644 --- a/client/pom.xml +++ b/client/pom.xml @@ -228,6 +228,16 @@ org.apache.cloudstack + cloud-plugin-iam + ${project.version} + + + org.apache.cloudstack + cloud-iam + ${project.version} + + + org.apache.cloudstack cloud-framework-ipc ${project.version} http://git-wip-us.apache.org/repos/asf/cloudstack/blob/26a6aa54/client/tomcatconf/commands.properties.in ---------------------------------------------------------------------- diff --git a/client/tomcatconf/commands.properties.in b/client/tomcatconf/commands.properties.in index d247aa0..da3fbfc 100644 --- a/client/tomcatconf/commands.properties.in +++ b/client/tomcatconf/commands.properties.in @@ -732,6 +732,21 @@ listLdapUsers=3 ldapCreateAccount=3 importLdapUsers=3 +### IAM commands +createIAMPolicy=1 +deleteIAMPolicy=1 +listIAMPolicies=1 +addIAMPermissionToIAMPolicy=1 +removeIAMPermissionFromIAMPolicy=1 +createIAMGroup=1 +deleteIAMGroup=1 +listIAMGroups=1 +addAccountToIAMGroup=1 +removeAccountFromIAMGroup=1 +attachIAMPolicyToIAMGroup=1 +removeIAMPolicyFromIAMGroup=1 +attachIAMPolicyToAccount=1 +removeIAMPolicyFromAccount=1 #### juniper-contrail commands createServiceInstance=1 http://git-wip-us.apache.org/repos/asf/cloudstack/blob/26a6aa54/core/resources/META-INF/cloudstack/core/spring-core-registry-core-context.xml ---------------------------------------------------------------------- diff --git a/core/resources/META-INF/cloudstack/core/spring-core-registry-core-context.xml b/core/resources/META-INF/cloudstack/core/spring-core-registry-core-context.xml index d54823a..0f58d7d 100644 --- a/core/resources/META-INF/cloudstack/core/spring-core-registry-core-context.xml +++ b/core/resources/META-INF/cloudstack/core/spring-core-registry-core-context.xml @@ -46,7 +46,7 @@ + value="RoleBasedEntityAccessChecker,AffinityGroupAccessChecker,DomainChecker" /> , T, K> { if (_entity == null || _specifiedAttrs == null || _specifiedAttrs.size() != 1) { throw new RuntimeException("Now now, better specify an attribute or else we can't help you"); } - return _specifiedAttrs.get(0); + if (_specifiedAttrs.size() > 0) { + return _specifiedAttrs.get(0); + } + // look for attributes from joins + for (JoinBuilder> join : _joins.values()) { + SearchBase sb = join.getT(); + if (sb.getSpecifiedAttribute() != null) { + return sb.getSpecifiedAttribute(); + } + } + throw new CloudRuntimeException("Unable to find any specified attributes. You sure you know what you're doing?"); } protected List getSpecifiedAttributes() { http://git-wip-us.apache.org/repos/asf/cloudstack/blob/26a6aa54/plugins/network-elements/internal-loadbalancer/src/org/apache/cloudstack/network/lb/InternalLoadBalancerVMManagerImpl.java ---------------------------------------------------------------------- diff --git a/plugins/network-elements/internal-loadbalancer/src/org/apache/cloudstack/network/lb/InternalLoadBalancerVMManagerImpl.java b/plugins/network-elements/internal-loadbalancer/src/org/apache/cloudstack/network/lb/InternalLoadBalancerVMManagerImpl.java index aa763d5..89707c9 100644 --- a/plugins/network-elements/internal-loadbalancer/src/org/apache/cloudstack/network/lb/InternalLoadBalancerVMManagerImpl.java +++ b/plugins/network-elements/internal-loadbalancer/src/org/apache/cloudstack/network/lb/InternalLoadBalancerVMManagerImpl.java @@ -27,11 +27,12 @@ import javax.ejb.Local; import javax.inject.Inject; import javax.naming.ConfigurationException; +import org.apache.log4j.Logger; + import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; import org.apache.cloudstack.lb.ApplicationLoadBalancerRuleVO; import org.apache.cloudstack.lb.dao.ApplicationLoadBalancerRuleDao; -import org.apache.log4j.Logger; import com.cloud.agent.AgentManager; import com.cloud.agent.api.Answer; @@ -519,7 +520,7 @@ public class InternalLoadBalancerVMManagerImpl extends ManagerBase implements In return true; } - _accountMgr.checkAccess(caller, null, true, internalLbVm); + _accountMgr.checkAccess(caller, null, internalLbVm); _itMgr.expunge(internalLbVm.getUuid()); _internalLbVmDao.remove(internalLbVm.getId()); @@ -534,7 +535,7 @@ public class InternalLoadBalancerVMManagerImpl extends ManagerBase implements In } //check permissions - _accountMgr.checkAccess(caller, null, true, internalLbVm); + _accountMgr.checkAccess(caller, null, internalLbVm); return stopInternalLbVm(internalLbVm, forced, caller, callerUserId); } @@ -912,7 +913,7 @@ public class InternalLoadBalancerVMManagerImpl extends ManagerBase implements In } //check permissions - _accountMgr.checkAccess(caller, null, true, internalLbVm); + _accountMgr.checkAccess(caller, null, internalLbVm); return startInternalLbVm(internalLbVm, caller, callerUserId, null); } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/26a6aa54/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ServiceManagerImpl.java ---------------------------------------------------------------------- diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ServiceManagerImpl.java b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ServiceManagerImpl.java index f34eacc..acd9b4e 100644 --- a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ServiceManagerImpl.java +++ b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ServiceManagerImpl.java @@ -30,6 +30,7 @@ import javax.inject.Inject; import net.juniper.contrail.api.ApiConnector; import net.juniper.contrail.api.types.ServiceInstance; +import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.network.contrail.api.response.ServiceInstanceResponse; import org.apache.cloudstack.network.contrail.model.ServiceInstanceModel; @@ -136,10 +137,10 @@ public class ServiceManagerImpl implements ServiceManager { // TODO: permission model. // service instances need to be able to access the public network. if (left.getTrafficType() == TrafficType.Guest) { - _networkModel.checkNetworkPermissions(owner, left); + _networkModel.checkNetworkPermissions(owner, left, AccessType.UseEntry); } if (right.getTrafficType() == TrafficType.Guest) { - _networkModel.checkNetworkPermissions(owner, right); + _networkModel.checkNetworkPermissions(owner, right, AccessType.UseEntry); } final ApiConnector api = _manager.getApiConnector(); http://git-wip-us.apache.org/repos/asf/cloudstack/blob/26a6aa54/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/MockAccountManager.java ---------------------------------------------------------------------- diff --git a/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/MockAccountManager.java b/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/MockAccountManager.java index 1a29f9c..a39fb43 100644 --- a/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/MockAccountManager.java +++ b/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/MockAccountManager.java @@ -34,7 +34,6 @@ import org.apache.cloudstack.api.command.admin.user.RegisterCmd; import org.apache.cloudstack.api.command.admin.user.UpdateUserCmd; import org.apache.cloudstack.context.CallContext; -import com.cloud.api.query.vo.ControlledViewEntity; import com.cloud.configuration.ResourceLimit; import com.cloud.configuration.dao.ResourceCountDao; import com.cloud.domain.Domain; @@ -102,11 +101,6 @@ public class MockAccountManager extends ManagerBase implements AccountManager { } @Override - public void checkAccess(Account arg0, AccessType arg1, boolean arg2, ControlledEntity... arg3) throws PermissionDeniedException { - // TODO Auto-generated method stub - } - - @Override public String[] createApiKeyAndSecretKey(RegisterCmd arg0) { // TODO Auto-generated method stub return null; @@ -208,90 +202,51 @@ public class MockAccountManager extends ManagerBase implements AccountManager { } - - @Override - public void buildACLViewSearchCriteria(SearchCriteria sc, SearchCriteria aclSc, boolean isRecursive, - List permittedDomains, List permittedAccounts, List permittedResources, ListProjectResourcesCriteria listProjectResourcesCriteria) { + public void buildACLSearchBuilder(SearchBuilder sb, boolean isRecursive, List permittedDomains, List permittedAccounts, + List permittedResources, ListProjectResourcesCriteria listProjectResourcesCriteria) { // TODO Auto-generated method stub } @Override - public List listAclGroupsByAccount(Long accountId) { + public void buildACLSearchCriteria(SearchCriteria sc, boolean isRecursive, List permittedDomains, List permittedAccounts, + List permittedResources, ListProjectResourcesCriteria listProjectResourcesCriteria) { // TODO Auto-generated method stub - return null; - } - @Override - public UserAccount lockUser(long arg0) { - // TODO Auto-generated method stub - return null; } @Override - public void markUserRegistered(long arg0) { + public void buildACLViewSearchCriteria(SearchCriteria sc, SearchCriteria aclSc, boolean isRecursive, + List permittedDomains, List permittedAccounts, List permittedResources, ListProjectResourcesCriteria listProjectResourcesCriteria) { // TODO Auto-generated method stub } @Override - public UserAccount authenticateUser(String arg0, String arg1, Long arg2, String arg3, Map arg4) { + public List listAclGroupsByAccount(Long accountId) { // TODO Auto-generated method stub return null; } @Override - public void buildACLSearchBuilder( - SearchBuilder arg0, Long arg1, - boolean arg2, List arg3, ListProjectResourcesCriteria arg4) { - // TODO Auto-generated method stub - - } - - @Override - public void buildACLSearchCriteria( - SearchCriteria arg0, Long arg1, - boolean arg2, List arg3, ListProjectResourcesCriteria arg4) { - // TODO Auto-generated method stub - - } - - @Override - public void buildACLSearchParameters(Account arg0, Long arg1, String arg2, - Long arg3, List arg4, - Ternary arg5, - boolean arg6, boolean arg7) { + public UserAccount lockUser(long arg0) { // TODO Auto-generated method stub - + return null; } @Override - public void buildACLViewSearchBuilder(SearchBuilder sb, Long domainId, boolean isRecursive, List permittedAccounts, - ListProjectResourcesCriteria listProjectResourcesCriteria) { + public void markUserRegistered(long arg0) { // TODO Auto-generated method stub } @Override - public void buildACLViewSearchBuilder(SearchBuilder sb, Long domainId, boolean isRecursive, List permittedAccounts, - ListProjectResourcesCriteria listProjectResourcesCriteria, List grantedIds, List revokedIds) { + public UserAccount authenticateUser(String arg0, String arg1, Long arg2, String arg3, Map arg4) { // TODO Auto-generated method stub + return null; } - @Override - public void buildACLViewSearchCriteria(SearchCriteria sc, Long domainId, boolean isRecursive, List permittedAccounts, - ListProjectResourcesCriteria listProjectResourcesCriteria) { - // TODO Auto-generated method stub - - } - - @Override - public void buildACLViewSearchCriteria(SearchCriteria sc, Long domainId, boolean isRecursive, List permittedAccounts, - ListProjectResourcesCriteria listProjectResourcesCriteria, List grantedIds, List revokedIds) { - // TODO Auto-generated method stub - - } @Override public Long checkAccessAndSpecifyAuthority(Account arg0, Long arg1) { @@ -407,15 +362,24 @@ public class MockAccountManager extends ManagerBase implements AccountManager { } + @Override - public void checkAccess(Account account, AccessType accessType, boolean sameOwner, String apiName, - ControlledEntity... entities) throws PermissionDeniedException { + public Long finalyzeAccountId(String accountName, Long domainId, Long projectId, boolean enabledOnly) { // TODO Auto-generated method stub + return null; } @Override - public Long finalyzeAccountId(String accountName, Long domainId, Long projectId, boolean enabledOnly) { + public void checkAccess(Account account, AccessType accessType, ControlledEntity... entities) throws PermissionDeniedException { // TODO Auto-generated method stub - return null; + } + + @Override + public void checkAccess(Account account, AccessType accessType, String apiName, ControlledEntity... entities) throws PermissionDeniedException { + // TODO Auto-generated method stub + + } + + } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/26a6aa54/server/resources/META-INF/cloudstack/core/spring-server-core-managers-context.xml ---------------------------------------------------------------------- diff --git a/server/resources/META-INF/cloudstack/core/spring-server-core-managers-context.xml b/server/resources/META-INF/cloudstack/core/spring-server-core-managers-context.xml index fc1c7e2..09abcb7 100644 --- a/server/resources/META-INF/cloudstack/core/spring-server-core-managers-context.xml +++ b/server/resources/META-INF/cloudstack/core/spring-server-core-managers-context.xml @@ -74,6 +74,7 @@ + http://git-wip-us.apache.org/repos/asf/cloudstack/blob/26a6aa54/server/src/com/cloud/acl/DomainChecker.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/acl/DomainChecker.java b/server/src/com/cloud/acl/DomainChecker.java index 729a0d1..9ee65db 100755 --- a/server/src/com/cloud/acl/DomainChecker.java +++ b/server/src/com/cloud/acl/DomainChecker.java @@ -19,6 +19,7 @@ package com.cloud.acl; import javax.ejb.Local; import javax.inject.Inject; +import org.apache.log4j.Logger; import org.springframework.stereotype.Component; import org.apache.cloudstack.acl.ControlledEntity; @@ -50,6 +51,8 @@ import com.cloud.utils.component.AdapterBase; @Local(value = SecurityChecker.class) public class DomainChecker extends AdapterBase implements SecurityChecker { + public static final Logger s_logger = Logger.getLogger(DomainChecker.class); + @Inject DomainDao _domainDao; @Inject @@ -101,6 +104,15 @@ public class DomainChecker extends AdapterBase implements SecurityChecker { @Override public boolean checkAccess(Account caller, ControlledEntity entity, AccessType accessType) throws PermissionDeniedException { + + if (caller.getId() == Account.ACCOUNT_ID_SYSTEM || _accountService.isRootAdmin(caller.getId())) { + // no need to make permission checks if the system/root admin makes the call + if (s_logger.isTraceEnabled()) { + s_logger.trace("No need to make permission check for System/RootAdmin account, returning true"); + } + return true; + } + if (entity instanceof VirtualMachineTemplate) { VirtualMachineTemplate template = (VirtualMachineTemplate)entity; @@ -332,20 +344,15 @@ public class DomainChecker extends AdapterBase implements SecurityChecker { if (action != null && ("SystemCapability".equals(action))) { if (caller != null && caller.getType() == Account.ACCOUNT_TYPE_ADMIN) { return true; - } else { - return false; } + } else if (action != null && ("DomainCapability".equals(action))) { if (caller != null && caller.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN) { return true; - } else { - return false; } } else if (action != null && ("DomainResourceCapability".equals(action))) { if (caller != null && caller.getType() == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN) { return true; - } else { - return false; } } return checkAccess(caller, entity, accessType); http://git-wip-us.apache.org/repos/asf/cloudstack/blob/26a6aa54/server/src/com/cloud/api/ApiDispatcher.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/api/ApiDispatcher.java b/server/src/com/cloud/api/ApiDispatcher.java index 3447662..b6b9b29 100755 --- a/server/src/com/cloud/api/ApiDispatcher.java +++ b/server/src/com/cloud/api/ApiDispatcher.java @@ -23,10 +23,6 @@ import javax.inject.Inject; import org.apache.log4j.Logger; -import org.apache.cloudstack.acl.ControlledEntity; -import org.apache.cloudstack.acl.InfrastructureEntity; -import org.apache.cloudstack.acl.SecurityChecker.AccessType; -import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.BaseAsyncCmd; import org.apache.cloudstack.api.BaseAsyncCreateCmd; @@ -40,7 +36,6 @@ import org.apache.cloudstack.framework.jobs.AsyncJobManager; import com.cloud.api.dispatch.DispatchChain; import com.cloud.api.dispatch.DispatchChainFactory; import com.cloud.api.dispatch.DispatchTask; -import com.cloud.user.Account; import com.cloud.user.AccountManager; public class ApiDispatcher { @@ -79,23 +74,6 @@ public class ApiDispatcher { asyncCreationDispatchChain.dispatch(new DispatchTask(cmd, params)); } - private void doAccessChecks(BaseCmd cmd, Map entitiesToAccess) { - Account caller = CallContext.current().getCallingAccount(); - - APICommand commandAnnotation = cmd.getClass().getAnnotation(APICommand.class); - String apiName = commandAnnotation != null ? commandAnnotation.name() : null; - - if (!entitiesToAccess.isEmpty()) { - for (Object entity : entitiesToAccess.keySet()) { - if (entity instanceof ControlledEntity) { - _accountMgr.checkAccess(caller, entitiesToAccess.get(entity), false, apiName, (ControlledEntity) entity); - } else if (entity instanceof InfrastructureEntity) { - //FIXME: Move this code in adapter, remove code from Account manager - } - } - } - } - public void dispatch(final BaseCmd cmd, final Map params, final boolean execute) throws Exception { // Let the chain of responsibility dispatch gradually standardDispatchChain.dispatch(new DispatchTask(cmd, params)); http://git-wip-us.apache.org/repos/asf/cloudstack/blob/26a6aa54/server/src/com/cloud/api/ApiResponseHelper.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java index a4f08fd..6746c13 100755 --- a/server/src/com/cloud/api/ApiResponseHelper.java +++ b/server/src/com/cloud/api/ApiResponseHelper.java @@ -1855,7 +1855,7 @@ public class ApiResponseHelper implements ResponseGenerator { throw new PermissionDeniedException("Account " + caller + " is not authorized to see job id=" + job.getId()); } } else if (_accountMgr.isDomainAdmin(caller.getId())) { - _accountMgr.checkAccess(caller, null, true, jobOwner); + _accountMgr.checkAccess(caller, null, jobOwner); } return createAsyncJobResponse(_jobMgr.queryJob(cmd.getId(), true)); http://git-wip-us.apache.org/repos/asf/cloudstack/blob/26a6aa54/server/src/com/cloud/api/dispatch/ParamProcessWorker.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/api/dispatch/ParamProcessWorker.java b/server/src/com/cloud/api/dispatch/ParamProcessWorker.java index 0bb0220..ba5bebf 100644 --- a/server/src/com/cloud/api/dispatch/ParamProcessWorker.java +++ b/server/src/com/cloud/api/dispatch/ParamProcessWorker.java @@ -40,6 +40,7 @@ import org.apache.cloudstack.acl.InfrastructureEntity; import org.apache.cloudstack.acl.SecurityChecker; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.api.ACL; +import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiErrorCode; import org.apache.cloudstack.api.BaseAsyncCreateCmd; import org.apache.cloudstack.api.BaseCmd; @@ -55,7 +56,11 @@ import org.apache.cloudstack.api.command.user.event.DeleteEventsCmd; import org.apache.cloudstack.api.command.user.event.ListEventsCmd; import org.apache.cloudstack.context.CallContext; +import com.cloud.dc.DataCenter; import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.PermissionDeniedException; +import com.cloud.offering.DiskOffering; +import com.cloud.offering.ServiceOffering; import com.cloud.user.Account; import com.cloud.user.AccountManager; import com.cloud.utils.DateUtil; @@ -217,27 +222,111 @@ public class ParamProcessWorker implements DispatchWorker { } - private void doAccessChecks(BaseCmd cmd, Map entitiesToAccess) { + private void doAccessChecks(final BaseCmd cmd, final Map entitiesToAccess) { Account caller = CallContext.current().getCallingAccount(); - Account owner = _accountMgr.getActiveAccountById(cmd.getEntityOwnerId()); + Account owner = _accountMgr.getAccount(cmd.getEntityOwnerId()); + if (owner == null) { + owner = caller; + } if (cmd instanceof BaseAsyncCreateCmd) { - // check that caller can access the owner account. - _accountMgr.checkAccess(caller, null, true, owner); + if (owner.getId() != caller.getId()) { + // mimic impersonation either by passing (account, domainId) or through derived owner from other api parameters + // in this case, we should check access using the owner + _accountMgr.checkAccess(caller, null, owner); + } + } else { + // check access using the caller for other operational cmds + owner = caller; } + APICommand commandAnnotation = cmd.getClass().getAnnotation(APICommand.class); + + String apiName = commandAnnotation != null ? commandAnnotation.name() : null; + if (!entitiesToAccess.isEmpty()) { - // check that caller can access the owner account. - _accountMgr.checkAccess(caller, null, true, owner); + List entitiesToOperate = new ArrayList(); for (Object entity : entitiesToAccess.keySet()) { if (entity instanceof ControlledEntity) { - _accountMgr.checkAccess(caller, entitiesToAccess.get(entity), true, (ControlledEntity) entity); + + if (AccessType.OperateEntry == entitiesToAccess.get(entity)) { + entitiesToOperate.add((ControlledEntity) entity); + } else { + _accountMgr.checkAccess(owner, entitiesToAccess.get(entity), apiName, + (ControlledEntity) entity); + } } else if (entity instanceof InfrastructureEntity) { - // FIXME: Move this code in adapter, remove code from - // Account manager + if (entity instanceof DataCenter) { + checkZoneAccess(owner, (DataCenter)entity); + } else if (entity instanceof ServiceOffering) { + checkServiceOfferingAccess(owner, (ServiceOffering)entity); + } else if (entity instanceof DiskOffering) { + checkDiskOfferingAccess(owner, (DiskOffering)entity); + } + } + } + + if (!entitiesToOperate.isEmpty()) { + _accountMgr.checkAccess(owner, AccessType.OperateEntry, apiName, + entitiesToOperate.toArray(new ControlledEntity[entitiesToOperate.size()])); + } + + } + } + + private void checkDiskOfferingAccess(Account caller, DiskOffering dof) { + 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()); + } + + private void checkServiceOfferingAccess(Account caller, ServiceOffering sof) { + for (SecurityChecker checker : _secChecker) { + if (checker.checkAccess(caller, sof)) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Access granted to " + caller + " to service offering:" + sof.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:" + + sof.getId()); + } + + private void checkZoneAccess(Account caller, DataCenter zone) { + for (SecurityChecker checker : _secChecker) { + if (checker.checkAccess(caller, zone)) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Access granted to " + caller + " to zone:" + zone.getId() + " by " + + checker.getName()); + } + return; + } else { + throw new PermissionDeniedException("Access denied to " + caller + " by " + checker.getName() + + " for zone " + zone.getId()); + } + } + + 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 zone:" + + zone.getId()); } @SuppressWarnings({"unchecked", "rawtypes"})