You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by pr...@apache.org on 2014/01/30 09:06:21 UTC

[1/2] git commit: updated refs/heads/rbac to d12422b

Updated Branches:
  refs/heads/rbac 81323dce5 -> d12422bf6


add 'recursive' column to permission table


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/ce95f312
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/ce95f312
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/ce95f312

Branch: refs/heads/rbac
Commit: ce95f3122b5ea76642c79e609190de5ab94faaa7
Parents: 81323dc
Author: Prachi Damle <pr...@cloud.com>
Authored: Wed Jan 29 15:05:11 2014 -0800
Committer: Prachi Damle <pr...@cloud.com>
Committed: Wed Jan 29 23:48:13 2014 -0800

----------------------------------------------------------------------
 .../cloudstack/iam/server/AclPolicyPermissionVO.java     | 11 ++++++++++-
 .../org/apache/cloudstack/iam/server/IAMServiceImpl.java |  2 +-
 setup/db/db/schema-430to440.sql                          |  1 +
 3 files changed, 12 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ce95f312/services/iam/server/src/org/apache/cloudstack/iam/server/AclPolicyPermissionVO.java
----------------------------------------------------------------------
diff --git a/services/iam/server/src/org/apache/cloudstack/iam/server/AclPolicyPermissionVO.java b/services/iam/server/src/org/apache/cloudstack/iam/server/AclPolicyPermissionVO.java
index 87f490b..4757611 100644
--- a/services/iam/server/src/org/apache/cloudstack/iam/server/AclPolicyPermissionVO.java
+++ b/services/iam/server/src/org/apache/cloudstack/iam/server/AclPolicyPermissionVO.java
@@ -60,6 +60,9 @@ public class AclPolicyPermissionVO implements AclPolicyPermission {
     @Column(name = "permission")
     @Enumerated(value = EnumType.STRING)
     private Permission permission;
+    
+    @Column(name = "recursive")
+    private Boolean recursive;  
 
     @Column(name = GenericDao.REMOVED_COLUMN)
     private Date removed;
@@ -72,7 +75,7 @@ public class AclPolicyPermissionVO implements AclPolicyPermission {
     }
 
     public AclPolicyPermissionVO(long aclPolicyId, String action, String entityType, String accessType, String scope,
-            Long scopeId, Permission permission) {
+            Long scopeId, Permission permission, Boolean recursive) {
         this.aclPolicyId = aclPolicyId;
         this.action = action;
         this.entityType = entityType;
@@ -80,6 +83,7 @@ public class AclPolicyPermissionVO implements AclPolicyPermission {
         this.scope = scope;
         this.scopeId = scopeId;
         this.permission = permission;
+        this.recursive = recursive;
     }
 
     @Override
@@ -169,4 +173,9 @@ public class AclPolicyPermissionVO implements AclPolicyPermission {
     public Date getCreated() {
         return created;
     }
+    
+    public Boolean isRecursive() {
+        return recursive;
+    }
+    
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ce95f312/services/iam/server/src/org/apache/cloudstack/iam/server/IAMServiceImpl.java
----------------------------------------------------------------------
diff --git a/services/iam/server/src/org/apache/cloudstack/iam/server/IAMServiceImpl.java b/services/iam/server/src/org/apache/cloudstack/iam/server/IAMServiceImpl.java
index 11116b0..9d8e2b4 100644
--- a/services/iam/server/src/org/apache/cloudstack/iam/server/IAMServiceImpl.java
+++ b/services/iam/server/src/org/apache/cloudstack/iam/server/IAMServiceImpl.java
@@ -555,7 +555,7 @@ public class IAMServiceImpl extends ManagerBase implements IAMService, Manager {
         AclPolicyPermissionVO permit = _policyPermissionDao.findByPolicyAndEntity(aclPolicyId, entityType, scope, scopeId, action, perm);
         if (permit == null) {
             // not there already
-            permit = new AclPolicyPermissionVO(aclPolicyId, action, entityType, accessType, scope, scopeId, perm);
+            permit = new AclPolicyPermissionVO(aclPolicyId, action, entityType, accessType, scope, scopeId, perm, false);
             _policyPermissionDao.persist(permit);
         }
         return policy;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ce95f312/setup/db/db/schema-430to440.sql
----------------------------------------------------------------------
diff --git a/setup/db/db/schema-430to440.sql b/setup/db/db/schema-430to440.sql
index 92957b2..e792480 100644
--- a/setup/db/db/schema-430to440.sql
+++ b/setup/db/db/schema-430to440.sql
@@ -522,6 +522,7 @@ CREATE TABLE `cloud`.`acl_policy_permission` (
   `scope` varchar(40) DEFAULT NULL,
   `access_type` varchar(40) DEFAULT NULL,
   `permission`  varchar(40) NOT NULL COMMENT 'Allow or Deny',
+  `recursive` int(1) unsigned NOT NULL DEFAULT 0 COMMENT '1 if this permission applies recursively in a group/policy hierarchy',
   `removed` datetime DEFAULT NULL COMMENT 'date the permission was revoked',
   `created` datetime DEFAULT NULL COMMENT 'date the permission was granted',
   PRIMARY KEY (`id`),


[2/2] git commit: updated refs/heads/rbac to d12422b

Posted by pr...@apache.org.
Add policies to domain group for CreateNetwork usecase for a domain wide shared network


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/d12422bf
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/d12422bf
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/d12422bf

Branch: refs/heads/rbac
Commit: d12422bf68a1f71da2ad99a3d0fd17d6578384d9
Parents: ce95f31
Author: Prachi Damle <pr...@cloud.com>
Authored: Wed Jan 29 23:47:08 2014 -0800
Committer: Prachi Damle <pr...@cloud.com>
Committed: Wed Jan 29 23:56:25 2014 -0800

----------------------------------------------------------------------
 .../orchestration/NetworkOrchestrator.java      | 10 +++
 .../acl/RoleBasedAPIAccessChecker.java          | 14 ++--
 .../cloudstack/acl/api/AclApiService.java       |  3 +-
 .../cloudstack/acl/api/AclApiServiceImpl.java   | 88 ++++++++++++++++++--
 .../command/AddAclPermissionToAclPolicyCmd.java |  3 +-
 .../cloudstack/acl/AclApiServiceTest.java       | 12 ++-
 .../apache/cloudstack/iam/api/IAMService.java   |  2 +-
 .../iam/server/AclPolicyPermissionVO.java       |  8 +-
 .../cloudstack/iam/server/IAMServiceImpl.java   |  5 +-
 utils/src/com/cloud/utils/db/EntityManager.java |  2 +
 10 files changed, 119 insertions(+), 28 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d12422bf/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java
----------------------------------------------------------------------
diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java
index 85fa530..8857c00 100755
--- a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java
+++ b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java
@@ -36,6 +36,7 @@ import javax.ejb.Local;
 import javax.inject.Inject;
 import javax.naming.ConfigurationException;
 
+import org.apache.cloudstack.acl.AclEntityType;
 import org.apache.cloudstack.acl.ControlledEntity.ACLType;
 import org.apache.cloudstack.context.CallContext;
 import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
@@ -43,6 +44,8 @@ import org.apache.cloudstack.framework.config.ConfigDepot;
 import org.apache.cloudstack.framework.config.ConfigKey;
 import org.apache.cloudstack.framework.config.Configurable;
 import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
+import org.apache.cloudstack.framework.messagebus.MessageBus;
+import org.apache.cloudstack.framework.messagebus.PublishScope;
 import org.apache.cloudstack.managed.context.ManagedContextRunnable;
 import org.apache.cloudstack.region.PortableIpDao;
 import org.apache.log4j.Logger;
@@ -253,6 +256,8 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
     protected IPAddressDao _publicIpAddressDao;
     @Inject
     protected IpAddressManager _ipAddrMgr;
+    @Inject
+    MessageBus _messageBus;
 
     List<NetworkGuru> networkGurus;
 
@@ -664,6 +669,11 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
 
                         if (domainId != null && aclType == ACLType.Domain) {
                             _networksDao.addDomainToNetwork(id, domainId, subdomainAccess == null ? true : subdomainAccess);
+                            //send event for storing the domain wide resource access
+                            // remove its related ACL permission
+                            Pair<AclEntityType, Long> network = new Pair<AclEntityType, Long>(AclEntityType.Network, id);
+                            _messageBus.publish(_name, EntityManager.MESSAGE_ADD_DOMAIN_WIDE_ENTITY_EVENT,
+                                    PublishScope.LOCAL, network);
                         }
                     }
                 });

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d12422bf/services/iam/plugin/src/org/apache/cloudstack/acl/RoleBasedAPIAccessChecker.java
----------------------------------------------------------------------
diff --git a/services/iam/plugin/src/org/apache/cloudstack/acl/RoleBasedAPIAccessChecker.java b/services/iam/plugin/src/org/apache/cloudstack/acl/RoleBasedAPIAccessChecker.java
index 5a32298..01e3d75 100644
--- a/services/iam/plugin/src/org/apache/cloudstack/acl/RoleBasedAPIAccessChecker.java
+++ b/services/iam/plugin/src/org/apache/cloudstack/acl/RoleBasedAPIAccessChecker.java
@@ -120,19 +120,19 @@ public class RoleBasedAPIAccessChecker extends AdapterBase implements APIChecker
         // add the system-domain capability
 
         _iamSrv.addAclPermissionToAclPolicy(new Long(Account.ACCOUNT_TYPE_ADMIN + 1), null, null, null,
-                "SystemCapability", null, Permission.Allow);
+                "SystemCapability", null, Permission.Allow, false);
         _iamSrv.addAclPermissionToAclPolicy(new Long(Account.ACCOUNT_TYPE_DOMAIN_ADMIN + 1), null, null, null,
-                "DomainCapability", null, Permission.Allow);
+                "DomainCapability", null, Permission.Allow, false);
         _iamSrv.addAclPermissionToAclPolicy(new Long(Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN + 1), null, null, null,
-                "DomainResourceCapability", null, Permission.Allow);
+                "DomainResourceCapability", null, Permission.Allow, false);
 
         // add permissions for public templates
         List<VMTemplateVO> pTmplts = _templateDao.listByPublic();
         for (VMTemplateVO tmpl : pTmplts){
             _iamSrv.addAclPermissionToAclPolicy(new Long(Account.ACCOUNT_TYPE_DOMAIN_ADMIN + 1), AclEntityType.VirtualMachineTemplate.toString(),
-                    PermissionScope.RESOURCE.toString(), tmpl.getId(), "listTemplates", AccessType.UseEntry.toString(), Permission.Allow);
+                    PermissionScope.RESOURCE.toString(), tmpl.getId(), "listTemplates", AccessType.UseEntry.toString(), Permission.Allow, false);
             _iamSrv.addAclPermissionToAclPolicy(new Long(Account.ACCOUNT_TYPE_NORMAL + 1), AclEntityType.VirtualMachineTemplate.toString(),
-                    PermissionScope.RESOURCE.toString(), tmpl.getId(), "listTemplates", AccessType.UseEntry.toString(), Permission.Allow);
+                    PermissionScope.RESOURCE.toString(), tmpl.getId(), "listTemplates", AccessType.UseEntry.toString(), Permission.Allow, false);
         }
 
         for (PluggableService service : _services) {
@@ -256,11 +256,11 @@ public class RoleBasedAPIAccessChecker extends AdapterBase implements APIChecker
 
         if (entityTypes == null || entityTypes.length == 0) {
             _iamSrv.addAclPermissionToAclPolicy(policyId, null, permissionScope.toString(), new Long(AclPolicyPermission.PERMISSION_SCOPE_ID_CURRENT_CALLER),
-                    apiName, (accessType == null) ? null : accessType.toString(), Permission.Allow);
+                    apiName, (accessType == null) ? null : accessType.toString(), Permission.Allow, false);
         } else {
             for (AclEntityType entityType : entityTypes) {
                 _iamSrv.addAclPermissionToAclPolicy(policyId, entityType.toString(), permissionScope.toString(), new Long(AclPolicyPermission.PERMISSION_SCOPE_ID_CURRENT_CALLER),
-                        apiName, (accessType == null) ? null : accessType.toString(), Permission.Allow);
+                        apiName, (accessType == null) ? null : accessType.toString(), Permission.Allow, false);
             }
          }
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d12422bf/services/iam/plugin/src/org/apache/cloudstack/acl/api/AclApiService.java
----------------------------------------------------------------------
diff --git a/services/iam/plugin/src/org/apache/cloudstack/acl/api/AclApiService.java b/services/iam/plugin/src/org/apache/cloudstack/acl/api/AclApiService.java
index 8b96495..45b3957 100644
--- a/services/iam/plugin/src/org/apache/cloudstack/acl/api/AclApiService.java
+++ b/services/iam/plugin/src/org/apache/cloudstack/acl/api/AclApiService.java
@@ -59,7 +59,8 @@ public interface AclApiService extends PluggableService {
 
     void removeAclPolicyFromAccounts(Long policyId, List<Long> accountIds);
 
-    AclPolicy addAclPermissionToAclPolicy(long aclPolicyId, String entityType, PermissionScope scope, Long scopeId, String action, Permission perm);
+    AclPolicy addAclPermissionToAclPolicy(long aclPolicyId, String entityType, PermissionScope scope, Long scopeId,
+            String action, Permission perm, Boolean recursive);
 
     AclPolicy removeAclPermissionFromAclPolicy(long aclPolicyId, String entityType, PermissionScope scope, Long scopeId, String action);
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d12422bf/services/iam/plugin/src/org/apache/cloudstack/acl/api/AclApiServiceImpl.java
----------------------------------------------------------------------
diff --git a/services/iam/plugin/src/org/apache/cloudstack/acl/api/AclApiServiceImpl.java b/services/iam/plugin/src/org/apache/cloudstack/acl/api/AclApiServiceImpl.java
index ee33620..892a7bb 100644
--- a/services/iam/plugin/src/org/apache/cloudstack/acl/api/AclApiServiceImpl.java
+++ b/services/iam/plugin/src/org/apache/cloudstack/acl/api/AclApiServiceImpl.java
@@ -67,6 +67,8 @@ import com.cloud.domain.dao.DomainDao;
 import com.cloud.event.ActionEvent;
 import com.cloud.event.EventTypes;
 import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.network.dao.NetworkDomainDao;
+import com.cloud.network.dao.NetworkDomainVO;
 import com.cloud.template.TemplateManager;
 import com.cloud.user.Account;
 import com.cloud.user.AccountManager;
@@ -103,6 +105,9 @@ public class AclApiServiceImpl extends ManagerBase implements AclApiService, Man
     @Inject
     MessageBus _messageBus;
 
+    @Inject
+    NetworkDomainDao _networkDomainDao;
+
     @Override
     public boolean configure(final String name, final Map<String, Object> params) throws ConfigurationException {
         _messageBus.subscribe(AccountManager.MESSAGE_ADD_ACCOUNT_EVENT, new MessageSubscriber() {
@@ -118,10 +123,10 @@ public class AclApiServiceImpl extends ManagerBase implements AclApiService, Man
                     AccountVO account = _accountDao.findById(accountId);
                     Domain domain = _domainDao.findById(account.getDomainId());
                     if (domain != null) {
-                        ListResponse<AclGroupResponse> domainGroups = listAclGroups(null,
-                                "DomainGrp-" + domain.getUuid(), domain.getId(), null, null);
-                        if (domainGroups.getResponses() != null) {
-                            for (AclGroupResponse group : domainGroups.getResponses()) {
+                        List<AclGroup> domainGroups = listDomainGroup(domain);
+
+                        if (domainGroups != null) {
+                            for (AclGroup group : domainGroups) {
                                 addAccountToAclGroup(accountId, new Long(group.getId()));
                             }
                         }
@@ -161,9 +166,9 @@ public class AclApiServiceImpl extends ManagerBase implements AclApiService, Man
                 if (templateId != null) {
                     s_logger.debug("MessageBus message: new public template registered: " + templateId + ", grant permission to domain admin and normal user policies");
                     _iamSrv.addAclPermissionToAclPolicy(new Long(Account.ACCOUNT_TYPE_DOMAIN_ADMIN + 1), AclEntityType.VirtualMachineTemplate.toString(),
-                            PermissionScope.RESOURCE.toString(), templateId, "listTemplates", AccessType.UseEntry.toString(), Permission.Allow);
+                            PermissionScope.RESOURCE.toString(), templateId, "listTemplates", AccessType.UseEntry.toString(), Permission.Allow, false);
                     _iamSrv.addAclPermissionToAclPolicy(new Long(Account.ACCOUNT_TYPE_NORMAL + 1), AclEntityType.VirtualMachineTemplate.toString(),
-                            PermissionScope.RESOURCE.toString(), templateId, "listTemplates", AccessType.UseEntry.toString(), Permission.Allow);
+                            PermissionScope.RESOURCE.toString(), templateId, "listTemplates", AccessType.UseEntry.toString(), Permission.Allow, false);
                 }
             }
         });
@@ -181,6 +186,7 @@ public class AclApiServiceImpl extends ManagerBase implements AclApiService, Man
             }
         });
 
+
         _messageBus.subscribe(EntityManager.MESSAGE_GRANT_ENTITY_EVENT, new MessageSubscriber() {
             @Override
             public void onPublishMessage(String senderAddress, String subject, Object obj) {
@@ -197,9 +203,58 @@ public class AclApiServiceImpl extends ManagerBase implements AclApiService, Man
             }
         });
 
+        _messageBus.subscribe(EntityManager.MESSAGE_ADD_DOMAIN_WIDE_ENTITY_EVENT, new MessageSubscriber() {
+            @Override
+            public void onPublishMessage(String senderAddress, String subject, Object obj) {
+                Pair<AclEntityType, Long> entity = (Pair<AclEntityType, Long>) obj;
+                if (entity != null) {
+                    addDomainWideResourceAccess(entity);
+                }
+            }
+        });
+
         return super.configure(name, params);
     }
 
+    private void addDomainWideResourceAccess(Pair<AclEntityType, Long> entity) {
+
+        String entityType = entity.first().toString();
+        Long entityId = entity.second();
+
+        if (AclEntityType.Network.toString().equals(entityType)) {
+            NetworkDomainVO networkDomainMap = _networkDomainDao.getDomainNetworkMapByNetworkId(entityId);
+            if (networkDomainMap != null) {
+                createPolicyAndAddToDomainGroup("DomainWideNetwork-" + entityId, "domain wide network", entityType,
+                        entityId, "listNetworks", AccessType.UseEntry, networkDomainMap.getDomainId(),
+                        networkDomainMap.isSubdomainAccess());
+            }
+        } else if (AclEntityType.AffinityGroup.toString().equals(entityType)) {
+
+        }
+
+    }
+
+    private void createPolicyAndAddToDomainGroup(String policyName, String description, String entityType,
+            Long entityId, String action, AccessType accessType, Long domainId, Boolean recursive) {
+
+        AclPolicy policy = _iamSrv.createAclPolicy(policyName, description, null);
+       _iamSrv.addAclPermissionToAclPolicy(policy.getId(), entityType, PermissionScope.RESOURCE.toString(),
+               entityId, action, accessType.toString(), Permission.Allow, recursive);
+
+       List<Long> policyList = new ArrayList<Long>();
+       policyList.add(new Long(policy.getId()));
+
+       Domain domain = _domainDao.findById(domainId);
+       if (domain != null) {
+           List<AclGroup> domainGroups = listDomainGroup(domain);
+           if (domainGroups != null) {
+               for (AclGroup group : domainGroups) {
+                   _iamSrv.attachAclPoliciesToGroup(policyList, group.getId());
+               }
+           }
+       }
+    }
+
     @DB
     @Override
     @ActionEvent(eventType = EventTypes.EVENT_ACL_GROUP_CREATE, eventDescription = "Creating Acl Group", create = true)
@@ -309,13 +364,15 @@ public class AclApiServiceImpl extends ManagerBase implements AclApiService, Man
     @DB
     @Override
     @ActionEvent(eventType = EventTypes.EVENT_ACL_POLICY_GRANT, eventDescription = "Granting acl permission to Acl Policy")
-    public AclPolicy addAclPermissionToAclPolicy(long aclPolicyId, String entityType, PermissionScope scope, Long scopeId, String action, Permission perm) {
+    public AclPolicy addAclPermissionToAclPolicy(long aclPolicyId, String entityType, PermissionScope scope,
+            Long scopeId, String action, Permission perm, Boolean recursive) {
         Class<?> cmdClass = _apiServer.getCmdClass(action);
         AccessType accessType = null;
         if (BaseListCmd.class.isAssignableFrom(cmdClass)) {
             accessType = AccessType.ListEntry;
         }
-        return _iamSrv.addAclPermissionToAclPolicy(aclPolicyId, entityType, scope.toString(), scopeId, action, accessType.toString(), perm);
+        return _iamSrv.addAclPermissionToAclPolicy(aclPolicyId, entityType, scope.toString(), scopeId, action,
+                accessType.toString(), perm, recursive);
     }
 
     @DB
@@ -426,6 +483,19 @@ public class AclApiServiceImpl extends ManagerBase implements AclApiService, Man
 
     }
 
+    public List<AclGroup> listDomainGroup(Domain domain) {
+
+        if (domain != null) {
+            String domainPath = domain.getPath();
+            // search for groups
+            Pair<List<AclGroup>, Integer> result = _iamSrv.listAclGroups(null, "DomainGrp-" + domain.getUuid(),
+                    domainPath, null, null);
+            return result.first();
+        }
+        return new ArrayList<AclGroup>();
+
+    }
+
     @Override
     public ListResponse<AclGroupResponse> listAclGroups(Long aclGroupId, String aclGroupName, Long domainId, Long startIndex, Long pageSize) {
         // acl check
@@ -498,7 +568,7 @@ public class AclApiServiceImpl extends ManagerBase implements AclApiService, Man
             String description = "Policy to grant permission to " + entityType + entityId;
             policy = createAclPolicy(caller, aclPolicyName, description, null);
             // add permission to this policy
-            addAclPermissionToAclPolicy(policy.getId(), entityType, PermissionScope.RESOURCE, entityId, action, Permission.Allow);
+            addAclPermissionToAclPolicy(policy.getId(), entityType, PermissionScope.RESOURCE, entityId, action, Permission.Allow, false);
         }
         // attach this policy to list of accounts if not attached already
         Long policyId = policy.getId();

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d12422bf/services/iam/plugin/src/org/apache/cloudstack/acl/api/command/AddAclPermissionToAclPolicyCmd.java
----------------------------------------------------------------------
diff --git a/services/iam/plugin/src/org/apache/cloudstack/acl/api/command/AddAclPermissionToAclPolicyCmd.java b/services/iam/plugin/src/org/apache/cloudstack/acl/api/command/AddAclPermissionToAclPolicyCmd.java
index 33cae75..ec9596a 100644
--- a/services/iam/plugin/src/org/apache/cloudstack/acl/api/command/AddAclPermissionToAclPolicyCmd.java
+++ b/services/iam/plugin/src/org/apache/cloudstack/acl/api/command/AddAclPermissionToAclPolicyCmd.java
@@ -122,7 +122,8 @@ public class AddAclPermissionToAclPolicyCmd extends BaseAsyncCmd {
             InsufficientCapacityException, ServerApiException {
         CallContext.current().setEventDetails("Acl policy Id: " + getId());
         // Only explicit ALLOW is supported for this release, no explicit deny
-        AclPolicy result = _aclApiSrv.addAclPermissionToAclPolicy(id, entityType, PermissionScope.valueOf(scope), scopeId, action, Permission.Allow);
+        AclPolicy result = _aclApiSrv.addAclPermissionToAclPolicy(id, entityType, PermissionScope.valueOf(scope),
+                scopeId, action, Permission.Allow, false);
         if (result != null) {
             AclPolicyResponse response = _aclApiSrv.createAclPolicyResponse(result);
             response.setResponseName(getCommandName());

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d12422bf/services/iam/plugin/test/org/apache/cloudstack/acl/AclApiServiceTest.java
----------------------------------------------------------------------
diff --git a/services/iam/plugin/test/org/apache/cloudstack/acl/AclApiServiceTest.java b/services/iam/plugin/test/org/apache/cloudstack/acl/AclApiServiceTest.java
index 676c0ab..4d418e5 100644
--- a/services/iam/plugin/test/org/apache/cloudstack/acl/AclApiServiceTest.java
+++ b/services/iam/plugin/test/org/apache/cloudstack/acl/AclApiServiceTest.java
@@ -63,6 +63,7 @@ import com.cloud.user.UserVO;
 import com.cloud.user.dao.AccountDao;
 import com.cloud.utils.Pair;
 import com.cloud.utils.component.ComponentContext;
+import com.cloud.network.dao.NetworkDomainDao;
 
 @RunWith(SpringJUnit4ClassRunner.class)
 @ContextConfiguration(loader = AnnotationConfigContextLoader.class)
@@ -272,13 +273,13 @@ public class AclApiServiceTest {
         when(_apiServer.getCmdClass("listVirtualMachines")).thenReturn(clz);
         when(
                 _iamSrv.addAclPermissionToAclPolicy(policyId, AclEntityType.VirtualMachine.toString(), PermissionScope.RESOURCE.toString(), resId, "listVirtualMachines",
-                        AccessType.ListEntry.toString(), Permission.Allow)).thenReturn(policy);
-        _aclSrv.addAclPermissionToAclPolicy(policyId, AclEntityType.VirtualMachine.toString(), PermissionScope.RESOURCE, resId, "listVirtualMachines", Permission.Allow);
+                        AccessType.ListEntry.toString(), Permission.Allow, false)).thenReturn(policy);
+        _aclSrv.addAclPermissionToAclPolicy(policyId, AclEntityType.VirtualMachine.toString(), PermissionScope.RESOURCE, resId, "listVirtualMachines", Permission.Allow, false);
         Pair<List<AclPolicy>, Integer> policyList = new Pair<List<AclPolicy>, Integer>(policies, 1);
         List<AclPolicyPermission> policyPerms = new ArrayList<AclPolicyPermission>();
         AclPolicyPermission perm = new AclPolicyPermissionVO(policyId, "listVirtualMachines", AclEntityType.VirtualMachine.toString(), AccessType.ListEntry.toString(),
                 PermissionScope.RESOURCE.toString(),
-                resId, Permission.Allow);
+                resId, Permission.Allow, false);
         policyPerms.add(perm);
         when(_iamSrv.listAclPolicies(null, "policy1", callerDomainPath, 0L, 20L)).thenReturn(policyList);
         when(_iamSrv.listPolicyPermissions(policyId)).thenReturn(policyPerms);
@@ -324,6 +325,11 @@ public class AclApiServiceTest {
         }
 
         @Bean
+        public NetworkDomainDao networkDomainDao() {
+            return Mockito.mock(NetworkDomainDao.class);
+        }
+
+        @Bean
         public AccountManager accountManager() {
             return Mockito.mock(AccountManager.class);
         }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d12422bf/services/iam/server/src/org/apache/cloudstack/iam/api/IAMService.java
----------------------------------------------------------------------
diff --git a/services/iam/server/src/org/apache/cloudstack/iam/api/IAMService.java b/services/iam/server/src/org/apache/cloudstack/iam/api/IAMService.java
index 76fab05..694abd5 100644
--- a/services/iam/server/src/org/apache/cloudstack/iam/api/IAMService.java
+++ b/services/iam/server/src/org/apache/cloudstack/iam/api/IAMService.java
@@ -59,7 +59,7 @@ public interface IAMService {
     void removeAclPolicyFromAccounts(Long policyId, List<Long> acctIds);
 
     AclPolicy addAclPermissionToAclPolicy(long aclPolicyId, String entityType, String scope, Long scopeId,
-            String action, String accessType, Permission perm);
+            String action, String accessType, Permission perm, Boolean recursive);
 
     AclPolicy removeAclPermissionFromAclPolicy(long aclPolicyId, String entityType, String scope, Long scopeId,
             String action);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d12422bf/services/iam/server/src/org/apache/cloudstack/iam/server/AclPolicyPermissionVO.java
----------------------------------------------------------------------
diff --git a/services/iam/server/src/org/apache/cloudstack/iam/server/AclPolicyPermissionVO.java b/services/iam/server/src/org/apache/cloudstack/iam/server/AclPolicyPermissionVO.java
index 4757611..5d2a36b9 100644
--- a/services/iam/server/src/org/apache/cloudstack/iam/server/AclPolicyPermissionVO.java
+++ b/services/iam/server/src/org/apache/cloudstack/iam/server/AclPolicyPermissionVO.java
@@ -60,9 +60,9 @@ public class AclPolicyPermissionVO implements AclPolicyPermission {
     @Column(name = "permission")
     @Enumerated(value = EnumType.STRING)
     private Permission permission;
-    
+
     @Column(name = "recursive")
-    private Boolean recursive;  
+    private Boolean recursive;
 
     @Column(name = GenericDao.REMOVED_COLUMN)
     private Date removed;
@@ -173,9 +173,9 @@ public class AclPolicyPermissionVO implements AclPolicyPermission {
     public Date getCreated() {
         return created;
     }
-    
+
     public Boolean isRecursive() {
         return recursive;
     }
-    
+
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d12422bf/services/iam/server/src/org/apache/cloudstack/iam/server/IAMServiceImpl.java
----------------------------------------------------------------------
diff --git a/services/iam/server/src/org/apache/cloudstack/iam/server/IAMServiceImpl.java b/services/iam/server/src/org/apache/cloudstack/iam/server/IAMServiceImpl.java
index 9d8e2b4..1dbfaef 100644
--- a/services/iam/server/src/org/apache/cloudstack/iam/server/IAMServiceImpl.java
+++ b/services/iam/server/src/org/apache/cloudstack/iam/server/IAMServiceImpl.java
@@ -543,7 +543,7 @@ public class IAMServiceImpl extends ManagerBase implements IAMService, Manager {
     @DB
     @Override
     public AclPolicy addAclPermissionToAclPolicy(long aclPolicyId, String entityType, String scope, Long scopeId,
-            String action, String accessType, Permission perm) {
+            String action, String accessType, Permission perm, Boolean recursive) {
         // get the Acl Policy entity
         AclPolicy policy = _aclPolicyDao.findById(aclPolicyId);
         if (policy == null) {
@@ -555,7 +555,8 @@ public class IAMServiceImpl extends ManagerBase implements IAMService, Manager {
         AclPolicyPermissionVO permit = _policyPermissionDao.findByPolicyAndEntity(aclPolicyId, entityType, scope, scopeId, action, perm);
         if (permit == null) {
             // not there already
-            permit = new AclPolicyPermissionVO(aclPolicyId, action, entityType, accessType, scope, scopeId, perm, false);
+            permit = new AclPolicyPermissionVO(aclPolicyId, action, entityType, accessType, scope, scopeId, perm,
+                    recursive);
             _policyPermissionDao.persist(permit);
         }
         return policy;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d12422bf/utils/src/com/cloud/utils/db/EntityManager.java
----------------------------------------------------------------------
diff --git a/utils/src/com/cloud/utils/db/EntityManager.java b/utils/src/com/cloud/utils/db/EntityManager.java
index 3226e90..79ef2a0 100644
--- a/utils/src/com/cloud/utils/db/EntityManager.java
+++ b/utils/src/com/cloud/utils/db/EntityManager.java
@@ -72,5 +72,7 @@ public interface EntityManager {
     public <T, K extends Serializable> void remove(Class<T> entityType, K id);
 
     public static final String MESSAGE_REMOVE_ENTITY_EVENT = "Message.RemoveEntity.Event";
+
     public static final String MESSAGE_GRANT_ENTITY_EVENT = "Message.GrantEntity.Event";
+    public static final String MESSAGE_ADD_DOMAIN_WIDE_ENTITY_EVENT = "Message.AddDomainWideEntity.Event";
 }