You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by mc...@apache.org on 2014/05/20 00:46:30 UTC

[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 <mi...@citrix.com>
Authored: Mon May 19 15:44:22 2014 -0700
Committer: Min Chen <mi...@citrix.com>
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<? extends StickinessPolicy> 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 @@
     </dependency>    
     <dependency>
       <groupId>org.apache.cloudstack</groupId>
+      <artifactId>cloud-plugin-iam</artifactId>
+      <version>${project.version}</version>
+    </dependency>   
+    <dependency>
+      <groupId>org.apache.cloudstack</groupId>
+      <artifactId>cloud-iam</artifactId>
+      <version>${project.version}</version>
+    </dependency>         
+    <dependency>
+      <groupId>org.apache.cloudstack</groupId>
       <artifactId>cloud-framework-ipc</artifactId>
       <version>${project.version}</version>
     </dependency>

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 @@
         <property name="orderConfigKey" value="security.checkers.order" />
         <property name="excludeKey" value="security.checkers.exclude" />
         <property name="orderConfigDefault"
-            value="AffinityGroupAccessChecker,DomainChecker" />
+            value="RoleBasedEntityAccessChecker,AffinityGroupAccessChecker,DomainChecker" />
     </bean>
 
     <bean id="resourceDiscoverersRegistry"

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/26a6aa54/engine/schema/src/com/cloud/upgrade/dao/Upgrade430to440.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade430to440.java b/engine/schema/src/com/cloud/upgrade/dao/Upgrade430to440.java
index da71d44..26277dd 100644
--- a/engine/schema/src/com/cloud/upgrade/dao/Upgrade430to440.java
+++ b/engine/schema/src/com/cloud/upgrade/dao/Upgrade430to440.java
@@ -59,10 +59,57 @@ public class Upgrade430to440 implements DbUpgrade {
 
     @Override
     public void performDataMigration(Connection conn) {
+        populateIAMGroupAccountMap(conn);
         secondaryIpsAccountAndDomainIdsUpdate(conn);
         moveCidrsToTheirOwnTable(conn);
     }
 
+    // populate iam_group_account_map table for existing accounts
+    private void populateIAMGroupAccountMap(Connection conn) {
+        PreparedStatement acctInsert = null;
+        PreparedStatement acctQuery = null;
+        ResultSet rs = null;
+
+        s_logger.debug("Populating iam_group_account_map table for existing accounts...");
+        try {
+            acctInsert = conn
+                    .prepareStatement("INSERT INTO `cloud`.`iam_group_account_map` (group_id, account_id, created) values(?, ?, Now())");
+            acctQuery = conn
+                    .prepareStatement("select id, type from `cloud`.`account` where removed is null");
+            rs = acctQuery.executeQuery();
+
+            while (rs.next()) {
+                Long acct_id = rs.getLong("id");
+                short type = rs.getShort("type");
+
+                // insert entry in iam_group_account_map table
+                acctInsert.setLong(1, type + 1);
+                acctInsert.setLong(2, acct_id);
+                acctInsert.executeUpdate();
+            }
+        } catch (SQLException e) {
+            String msg = "Unable to populate iam_group_account_map for existing accounts." + e.getMessage();
+            s_logger.error(msg);
+            throw new CloudRuntimeException(msg, e);
+        } finally {
+            try {
+                if (rs != null) {
+                    rs.close();
+                }
+
+                if (acctInsert != null) {
+                    acctInsert.close();
+                }
+                if (acctQuery != null) {
+                    acctQuery.close();
+                }
+            } catch (SQLException e) {
+            }
+        }
+        s_logger.debug("Completed populate iam_group_account_map for existing accounts.");
+    }
+
+
 
     private void secondaryIpsAccountAndDomainIdsUpdate(Connection conn) {
         PreparedStatement pstmt = null;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/26a6aa54/framework/db/src/com/cloud/utils/db/SearchBase.java
----------------------------------------------------------------------
diff --git a/framework/db/src/com/cloud/utils/db/SearchBase.java b/framework/db/src/com/cloud/utils/db/SearchBase.java
index d19918a..4ec9a41 100644
--- a/framework/db/src/com/cloud/utils/db/SearchBase.java
+++ b/framework/db/src/com/cloud/utils/db/SearchBase.java
@@ -235,7 +235,17 @@ public abstract class SearchBase<J extends SearchBase<?, T, K>, 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<SearchBase<?, ?, ?>> 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<Attribute> 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<? extends ControlledEntity> sc, SearchCriteria<? extends ControlledEntity> aclSc, boolean isRecursive,
-            List<Long> permittedDomains, List<Long> permittedAccounts, List<Long> permittedResources, ListProjectResourcesCriteria listProjectResourcesCriteria) {
+    public void buildACLSearchBuilder(SearchBuilder<? extends ControlledEntity> sb, boolean isRecursive, List<Long> permittedDomains, List<Long> permittedAccounts,
+            List<Long> permittedResources, ListProjectResourcesCriteria listProjectResourcesCriteria) {
         // TODO Auto-generated method stub
 
     }
 
     @Override
-    public List<String> listAclGroupsByAccount(Long accountId) {
+    public void buildACLSearchCriteria(SearchCriteria<? extends ControlledEntity> sc, boolean isRecursive, List<Long> permittedDomains, List<Long> permittedAccounts,
+            List<Long> 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<? extends ControlledEntity> sc, SearchCriteria<? extends ControlledEntity> aclSc, boolean isRecursive,
+            List<Long> permittedDomains, List<Long> permittedAccounts, List<Long> permittedResources, ListProjectResourcesCriteria listProjectResourcesCriteria) {
         // TODO Auto-generated method stub
 
     }
 
     @Override
-    public UserAccount authenticateUser(String arg0, String arg1, Long arg2, String arg3, Map<String, Object[]> arg4) {
+    public List<String> listAclGroupsByAccount(Long accountId) {
         // TODO Auto-generated method stub
         return null;
     }
 
     @Override
-    public void buildACLSearchBuilder(
-            SearchBuilder<? extends ControlledEntity> arg0, Long arg1,
-            boolean arg2, List<Long> arg3, ListProjectResourcesCriteria arg4) {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void buildACLSearchCriteria(
-            SearchCriteria<? extends ControlledEntity> arg0, Long arg1,
-            boolean arg2, List<Long> arg3, ListProjectResourcesCriteria arg4) {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void buildACLSearchParameters(Account arg0, Long arg1, String arg2,
-            Long arg3, List<Long> arg4,
-            Ternary<Long, Boolean, ListProjectResourcesCriteria> arg5,
-            boolean arg6, boolean arg7) {
+    public UserAccount lockUser(long arg0) {
         // TODO Auto-generated method stub
-
+        return null;
     }
 
     @Override
-    public void buildACLViewSearchBuilder(SearchBuilder<? extends ControlledViewEntity> sb, Long domainId, boolean isRecursive, List<Long> permittedAccounts,
-            ListProjectResourcesCriteria listProjectResourcesCriteria) {
+    public void markUserRegistered(long arg0) {
         // TODO Auto-generated method stub
 
     }
 
     @Override
-    public void buildACLViewSearchBuilder(SearchBuilder<? extends ControlledViewEntity> sb, Long domainId, boolean isRecursive, List<Long> permittedAccounts,
-            ListProjectResourcesCriteria listProjectResourcesCriteria, List<Long> grantedIds, List<Long> revokedIds) {
+    public UserAccount authenticateUser(String arg0, String arg1, Long arg2, String arg3, Map<String, Object[]> arg4) {
         // TODO Auto-generated method stub
+        return null;
     }
 
-    @Override
-    public void buildACLViewSearchCriteria(SearchCriteria<? extends ControlledViewEntity> sc, Long domainId, boolean isRecursive, List<Long> permittedAccounts,
-            ListProjectResourcesCriteria listProjectResourcesCriteria) {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void buildACLViewSearchCriteria(SearchCriteria<? extends ControlledEntity> sc, Long domainId, boolean isRecursive, List<Long> permittedAccounts,
-            ListProjectResourcesCriteria listProjectResourcesCriteria, List<Long> grantedIds, List<Long> 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 @@
 
     <bean id="networkModelImpl" class="com.cloud.network.NetworkModelImpl">
         <property name="networkElements" value="#{networkElementsRegistry.registered}" />
+        <property name="securityCheckers" value="#{securityCheckersRegistry.registered}" />
     </bean>
 
     <bean id="configurationServerImpl" class="com.cloud.server.ConfigurationServerImpl" />

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<Object, AccessType> 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<String, String> 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<Object, AccessType> entitiesToAccess) {
+    private void doAccessChecks(final BaseCmd cmd, final Map<Object, AccessType> 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<ControlledEntity> entitiesToOperate = new ArrayList<ControlledEntity>();
             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"})