You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by sw...@apache.org on 2016/05/11 06:04:21 UTC

[5/9] git commit: updated refs/heads/master to bee2bdc

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4347776a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/command/LdapCreateAccountCmd.java
----------------------------------------------------------------------
diff --git a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/command/LdapCreateAccountCmd.java b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/command/LdapCreateAccountCmd.java
index 1968f85..d845857 100644
--- a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/command/LdapCreateAccountCmd.java
+++ b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/command/LdapCreateAccountCmd.java
@@ -16,12 +16,12 @@
 // under the License.
 package org.apache.cloudstack.api.command;
 
-import java.io.UnsupportedEncodingException;
-import java.security.NoSuchAlgorithmException;
-import java.security.SecureRandom;
-import java.util.Map;
-
-import javax.inject.Inject;
+import com.cloud.domain.DomainVO;
+import com.cloud.user.Account;
+import com.cloud.user.AccountService;
+import com.cloud.user.User;
+import com.cloud.user.UserAccount;
+import org.apache.cloudstack.acl.RoleType;
 import org.apache.cloudstack.api.APICommand;
 import org.apache.cloudstack.api.ApiConstants;
 import org.apache.cloudstack.api.ApiErrorCode;
@@ -31,6 +31,7 @@ import org.apache.cloudstack.api.ResponseObject.ResponseView;
 import org.apache.cloudstack.api.ServerApiException;
 import org.apache.cloudstack.api.response.AccountResponse;
 import org.apache.cloudstack.api.response.DomainResponse;
+import org.apache.cloudstack.api.response.RoleResponse;
 import org.apache.cloudstack.context.CallContext;
 import org.apache.cloudstack.ldap.LdapManager;
 import org.apache.cloudstack.ldap.LdapUser;
@@ -38,11 +39,11 @@ import org.apache.cloudstack.ldap.NoLdapUserMatchingQueryException;
 import org.apache.log4j.Logger;
 import org.bouncycastle.util.encoders.Base64;
 
-import com.cloud.domain.DomainVO;
-import com.cloud.user.Account;
-import com.cloud.user.AccountService;
-import com.cloud.user.User;
-import com.cloud.user.UserAccount;
+import javax.inject.Inject;
+import java.io.UnsupportedEncodingException;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.util.Map;
 
 @APICommand(name = "ldapCreateAccount", description = "Creates an account from an LDAP user", responseObject = AccountResponse.class, since = "4.2.0", requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
 public class LdapCreateAccountCmd extends BaseCmd {
@@ -55,9 +56,12 @@ public class LdapCreateAccountCmd extends BaseCmd {
     @Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, description = "Creates the user under the specified account. If no account is specified, the username will be used as the account name.")
     private String accountName;
 
-    @Parameter(name = ApiConstants.ACCOUNT_TYPE, type = CommandType.SHORT, required = true, description = "Type of the account.  Specify 0 for user, 1 for root admin, and 2 for domain admin")
+    @Parameter(name = ApiConstants.ACCOUNT_TYPE, type = CommandType.SHORT, description = "Type of the account. Specify 0 for user, 1 for root admin, and 2 for domain admin")
     private Short accountType;
 
+    @Parameter(name = ApiConstants.ROLE_ID, type = CommandType.UUID, entityType = RoleResponse.class, description = "Creates the account under the specified role.")
+    private Long roleId;
+
     @Parameter(name = ApiConstants.DOMAIN_ID, type = CommandType.UUID, entityType = DomainResponse.class, description = "Creates the user under the specified domain.")
     private Long domainId;
 
@@ -92,7 +96,7 @@ public class LdapCreateAccountCmd extends BaseCmd {
     UserAccount createCloudstackUserAccount(final LdapUser user, String accountName, Long domainId) {
         Account account = _accountService.getActiveAccountByName(accountName, domainId);
         if (account == null) {
-            return _accountService.createUserAccount(username, generatePassword(), user.getFirstname(), user.getLastname(), user.getEmail(), timezone, accountName, accountType,
+            return _accountService.createUserAccount(username, generatePassword(), user.getFirstname(), user.getLastname(), user.getEmail(), timezone, accountName, getAccountType(), getRoleId(),
                     domainId, networkDomain, details, accountUUID, userUUID, User.Source.LDAP);
         } else {
             User newUser = _accountService.createUser(username, generatePassword(), user.getFirstname(), user.getLastname(), user.getEmail(), timezone, accountName, domainId,
@@ -101,6 +105,14 @@ public class LdapCreateAccountCmd extends BaseCmd {
         }
     }
 
+    public Short getAccountType() {
+        return RoleType.getAccountTypeByRole(roleService.findRole(roleId), accountType);
+    }
+
+    public Long getRoleId() {
+        return RoleType.getRoleByAccountType(roleId, accountType);
+    }
+
     private String getAccountName() {
         String name = accountName;
         if (accountName == null) {
@@ -119,6 +131,9 @@ public class LdapCreateAccountCmd extends BaseCmd {
 
     @Override
     public void execute() throws ServerApiException {
+        if (getAccountType() == null && getRoleId() == null) {
+            throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Both account type and role ID are not provided");
+        }
         final CallContext callContext = getCurrentContext();
         String finalAccountName = getAccountName();
         Long finalDomainId = getDomainId();

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4347776a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/command/LdapImportUsersCmd.java
----------------------------------------------------------------------
diff --git a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/command/LdapImportUsersCmd.java b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/command/LdapImportUsersCmd.java
index 63549f1..9fdd700 100644
--- a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/command/LdapImportUsersCmd.java
+++ b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/command/LdapImportUsersCmd.java
@@ -29,6 +29,7 @@ import javax.inject.Inject;
 import com.cloud.user.Account;
 import com.cloud.user.User;
 import com.cloud.user.UserAccount;
+import org.apache.cloudstack.acl.RoleType;
 import org.apache.cloudstack.api.APICommand;
 import org.apache.cloudstack.api.ApiConstants;
 import org.apache.cloudstack.api.ApiErrorCode;
@@ -38,6 +39,7 @@ import org.apache.cloudstack.api.ServerApiException;
 import org.apache.cloudstack.api.response.DomainResponse;
 import org.apache.cloudstack.api.response.LdapUserResponse;
 import org.apache.cloudstack.api.response.ListResponse;
+import org.apache.cloudstack.api.response.RoleResponse;
 import org.apache.cloudstack.ldap.LdapManager;
 import org.apache.cloudstack.ldap.LdapUser;
 import org.apache.cloudstack.ldap.NoLdapUserMatchingQueryException;
@@ -70,10 +72,12 @@ public class LdapImportUsersCmd extends BaseListCmd {
 
     @Parameter(name = ApiConstants.ACCOUNT_TYPE,
                type = CommandType.SHORT,
-               required = true,
                description = "Type of the account.  Specify 0 for user, 1 for root admin, and 2 for domain admin")
     private Short accountType;
 
+    @Parameter(name = ApiConstants.ROLE_ID, type = CommandType.UUID, entityType = RoleResponse.class, description = "Creates the account under the specified role.")
+    private Long roleId;
+
     @Parameter(name = ApiConstants.ACCOUNT_DETAILS, type = CommandType.MAP, description = "details for account used to store specific parameters")
     private Map<String, String> details;
 
@@ -112,7 +116,7 @@ public class LdapImportUsersCmd extends BaseListCmd {
         Account account = _accountService.getActiveAccountByName(accountName, domain.getId());
         if (account == null) {
             s_logger.debug("No account exists with name: " + accountName + " creating the account and an user with name: " + user.getUsername() + " in the account");
-            _accountService.createUserAccount(user.getUsername(), generatePassword(), user.getFirstname(), user.getLastname(), user.getEmail(), timezone, accountName, accountType,
+            _accountService.createUserAccount(user.getUsername(), generatePassword(), user.getFirstname(), user.getLastname(), user.getEmail(), timezone, accountName, getAccountType(), getRoleId(),
                     domain.getId(), domain.getNetworkDomain(), details, UUID.randomUUID().toString(), UUID.randomUUID().toString(), User.Source.LDAP);
         } else {
 //            check if the user exists. if yes, call update
@@ -131,7 +135,9 @@ public class LdapImportUsersCmd extends BaseListCmd {
     @Override
     public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException,
         ResourceAllocationException, NetworkRuleConflictException {
-
+        if (getAccountType() == null && getRoleId() == null) {
+            throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Both account type and role ID are not provided");
+        }
         List<LdapUser> users;
         try {
             if (StringUtils.isNotBlank(groupName)) {
@@ -161,6 +167,14 @@ public class LdapImportUsersCmd extends BaseListCmd {
         setResponseObject(response);
     }
 
+    public Short getAccountType() {
+        return RoleType.getAccountTypeByRole(roleService.findRole(roleId), accountType);
+    }
+
+    public Long getRoleId() {
+        return RoleType.getRoleByAccountType(roleId, accountType);
+    }
+
     private String getAccountName(LdapUser user) {
         String finalAccountName = accountName;
         if(finalAccountName == null ) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4347776a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/command/LinkDomainToLdapCmd.java
----------------------------------------------------------------------
diff --git a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/command/LinkDomainToLdapCmd.java b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/command/LinkDomainToLdapCmd.java
index ae3e706..477e80f 100644
--- a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/command/LinkDomainToLdapCmd.java
+++ b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/command/LinkDomainToLdapCmd.java
@@ -23,6 +23,7 @@ import javax.inject.Inject;
 import com.cloud.exception.InvalidParameterValueException;
 import com.cloud.user.User;
 import com.cloud.user.UserAccount;
+import org.apache.cloudstack.acl.RoleType;
 import org.apache.cloudstack.api.APICommand;
 import org.apache.cloudstack.api.ApiConstants;
 import org.apache.cloudstack.api.ApiErrorCode;
@@ -82,7 +83,7 @@ public class LinkDomainToLdapCmd extends BaseCmd {
                     if (account == null) {
                         try {
                             UserAccount userAccount = _accountService.createUserAccount(admin, "", ldapUser.getFirstname(), ldapUser.getLastname(), ldapUser.getEmail(), null,
-                                    admin, Account.ACCOUNT_TYPE_DOMAIN_ADMIN, domainId, null, null, UUID.randomUUID().toString(), UUID.randomUUID().toString(), User.Source.LDAP);
+                                    admin, Account.ACCOUNT_TYPE_DOMAIN_ADMIN, RoleType.DomainAdmin.getId(), domainId, null, null, UUID.randomUUID().toString(), UUID.randomUUID().toString(), User.Source.LDAP);
                             response.setAdminId(String.valueOf(userAccount.getAccountId()));
                             s_logger.info("created an account with name " + admin + " in the given domain " + domainId);
                         } catch (Exception e) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4347776a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapAuthenticator.java
----------------------------------------------------------------------
diff --git a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapAuthenticator.java b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapAuthenticator.java
index 5683b50..add39c5 100644
--- a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapAuthenticator.java
+++ b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapAuthenticator.java
@@ -21,6 +21,7 @@ import java.util.UUID;
 
 import javax.inject.Inject;
 
+import org.apache.cloudstack.acl.RoleType;
 import org.apache.commons.lang.StringUtils;
 import org.apache.log4j.Logger;
 
@@ -119,7 +120,8 @@ public class LdapAuthenticator extends AdapterBase implements UserAuthenticator
 
     private void createCloudStackUserAccount(LdapUser user, long domainId, short accountType) {
         String username = user.getUsername();
-        _accountManager.createUserAccount(username, "", user.getFirstname(), user.getLastname(), user.getEmail(), null, username, accountType, domainId, null, null,
+        _accountManager.createUserAccount(username, "", user.getFirstname(), user.getLastname(), user.getEmail(), null, username,
+                                          accountType, RoleType.getByAccountType(accountType).getId(), domainId, null, null,
                                           UUID.randomUUID().toString(), UUID.randomUUID().toString(), User.Source.LDAP);
     }
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4347776a/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapImportUsersCmdSpec.groovy
----------------------------------------------------------------------
diff --git a/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapImportUsersCmdSpec.groovy b/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapImportUsersCmdSpec.groovy
index 514caeb..434151a 100644
--- a/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapImportUsersCmdSpec.groovy
+++ b/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapImportUsersCmdSpec.groovy
@@ -246,7 +246,7 @@ class LdapImportUsersCmdSpec extends spock.lang.Specification {
         1 * accountService.getActiveAccountByName('ACCOUNT', 0) >>  Mock(AccountVO)
         1 * accountService.getActiveUserAccount('rmurphy',0) >> Mock(UserAccountVO)
         0 * accountService.createUser('rmurphy', _ , 'Ryan', 'Murphy', 'rmurphy@test.com', null, 'ACCOUNT', 0, _) >> Mock(UserVO)
-        0 * accountService.createUserAccount('rmurphy', _, 'Ryan', 'Murphy', 'rmurphy@test.com', null, 'ACCOUNT', 2, 0, 'DOMAIN', null, _, _)
+        0 * accountService.createUserAccount('rmurphy', _, 'Ryan', 'Murphy', 'rmurphy@test.com', null, 'ACCOUNT', 2, null, 0, 'DOMAIN', null, _, _)
         1 * accountService.updateUser(_,'Ryan', 'Murphy', 'rmurphy@test.com', null, null, null, null, null);
 
         def ldapImportUsersCmd = new LdapImportUsersCmd(ldapManager, domainService, accountService)

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4347776a/scripts/util/migrate-dynamicroles.py
----------------------------------------------------------------------
diff --git a/scripts/util/migrate-dynamicroles.py b/scripts/util/migrate-dynamicroles.py
new file mode 100755
index 0000000..e97e94c
--- /dev/null
+++ b/scripts/util/migrate-dynamicroles.py
@@ -0,0 +1,136 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+import os
+import sys
+import uuid
+
+from contextlib import closing
+from optparse import OptionParser
+
+try:
+    import MySQLdb
+except ImportError:
+    print("MySQLdb cannot be imported, please install python-mysqldb(apt) or mysql-python(yum)")
+    sys.exit(1)
+
+dryrun = False
+
+
+def runSql(conn, query):
+    if dryrun:
+        print("Running SQL query: " + query)
+        return
+    with closing(conn.cursor()) as cursor:
+        cursor.execute(query)
+
+
+def migrateApiRolePermissions(apis, conn):
+    # All allow for root admin role Admin(id:1)
+    runSql(conn, "INSERT INTO `cloud`.`role_permissions` (`uuid`, `role_id`, `rule`, `permission`, `sort_order`) values (UUID(), 1, '*', 'ALLOW', 0);")
+    # Migrate rules based on commands.properties rule for ResourceAdmin(id:2), DomainAdmin(id:3), User(id:4)
+    octetKey = {2:2, 3:4, 4:8}
+    for role in [2, 3, 4]:
+        sortOrder = 0
+        for api in sorted(apis.keys()):
+            # Ignore auth commands
+            if api in ['login', 'logout', 'samlSso', 'samlSlo', 'listIdps', 'listAndSwitchSamlAccount', 'getSPMetadata']:
+                continue
+            if (octetKey[role] & int(apis[api])) > 0:
+                runSql(conn, "INSERT INTO `cloud`.`role_permissions` (`uuid`, `role_id`, `rule`, `permission`, `sort_order`) values (UUID(), %d, '%s', 'ALLOW', %d);" % (role, api, sortOrder))
+                sortOrder += 1
+
+
+def main():
+    parser = OptionParser()
+    parser.add_option("-b", "--db", action="store", type="string", dest="db", default="cloud",
+                        help="The name of the database, default: cloud")
+    parser.add_option("-u", "--user", action="store", type="string", dest="user", default="cloud",
+                        help="User name a MySQL user with privileges on cloud database")
+    parser.add_option("-p", "--password", action="store", type="string", dest="password", default="cloud",
+                        help="Password of a MySQL user with privileges on cloud database")
+    parser.add_option("-H", "--host", action="store", type="string", dest="host", default="127.0.0.1",
+                        help="Host or IP of the MySQL server")
+    parser.add_option("-P", "--port", action="store", type="int", dest="port", default=3306,
+                        help="Host or IP of the MySQL server")
+    parser.add_option("-f", "--properties-file", action="store", type="string", dest="commandsfile", default="/etc/cloudstack/management/commands.properties",
+                        help="The commands.properties file")
+    parser.add_option("-d", "--dryrun", action="store_true", dest="dryrun", default=False,
+                        help="Dry run and debug operations this tool will perform")
+    (options, args) = parser.parse_args()
+
+    print("Apache CloudStack Role Permission Migration Tool")
+    print("(c) Apache CloudStack Authors and the ASF, under the Apache License, Version 2.0\n")
+
+    global dryrun
+    if options.dryrun:
+        dryrun = True
+
+    conn = MySQLdb.connect(
+            host=options.host,
+            user=options.user,
+            passwd=options.password,
+            port=int(options.port),
+            db=options.db)
+
+    if not os.path.isfile(options.commandsfile):
+        print("Provided commands.properties cannot be accessed or does not exist, please check check permissions")
+        sys.exit(1)
+
+    while True:
+        choice = raw_input("Running this migration tool will remove any " +
+                           "default-role permissions from cloud.role_permissions. " +
+                           "Do you want to continue? [y/N]").lower()
+        if choice == 'y':
+            break
+        else:
+            print("Aborting!")
+            sys.exit(1)
+
+    # Generate API to permission octet map
+    apiMap = {}
+    with open(options.commandsfile) as f:
+        for line in f.readlines():
+            if not line or line == '' or line == '\n' or line.startswith('#'):
+                continue
+            name, value = line.split('=')
+            apiMap[name.strip()] = value.strip()
+
+    # Rename and deprecate old commands.properties file
+    if not dryrun:
+        os.rename(options.commandsfile, options.commandsfile + '.deprecated')
+    print("The commands.properties file has been deprecated and moved at: " + options.commandsfile + '.deprecated')
+
+    # Truncate any rules in cloud.role_permissions table
+    runSql(conn, "DELETE FROM `cloud`.`role_permissions` WHERE `role_id` in (1,2,3,4);")
+
+    # Migrate rules from commands.properties to cloud.role_permissions
+    migrateApiRolePermissions(apiMap, conn)
+    print("Static role permissions from commands.properties have been migrated into the db")
+
+    # Enable dynamic role based API checker
+    runSql(conn, "UPDATE `cloud`.`configuration` SET value='true' where name='dynamic.apichecker.enabled'")
+    conn.commit()
+    conn.close()
+
+    print("Dynamic role based API checker has been enabled!")
+
+
+if __name__ == '__main__':
+    main()

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4347776a/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 e39d918..6618e3e 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
@@ -37,6 +37,8 @@
                   value="#{pluggableAPIAuthenticatorsRegistry.registered}" />
     </bean>
 
+    <bean id="roleManagerImpl" class="org.apache.cloudstack.acl.RoleManagerImpl" />
+
     <bean id="accountManagerImpl" class="com.cloud.user.AccountManagerImpl">
         <property name="userAuthenticators"
             value="#{userAuthenticatorsRegistry.registered}" />

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4347776a/server/src/com/cloud/api/ApiDBUtils.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/ApiDBUtils.java b/server/src/com/cloud/api/ApiDBUtils.java
index 1c55c67..d6b529f 100644
--- a/server/src/com/cloud/api/ApiDBUtils.java
+++ b/server/src/com/cloud/api/ApiDBUtils.java
@@ -27,6 +27,8 @@ import java.util.Set;
 import javax.annotation.PostConstruct;
 import javax.inject.Inject;
 
+import org.apache.cloudstack.acl.Role;
+import org.apache.cloudstack.acl.RoleService;
 import org.apache.cloudstack.affinity.AffinityGroup;
 import org.apache.cloudstack.affinity.AffinityGroupResponse;
 import org.apache.cloudstack.affinity.dao.AffinityGroupDao;
@@ -423,6 +425,7 @@ public class ApiDBUtils {
     static AffinityGroupJoinDao s_affinityGroupJoinDao;
     static GlobalLoadBalancingRulesService s_gslbService;
     static NetworkACLDao s_networkACLDao;
+    static RoleService s_roleService;
     static AccountService s_accountService;
     static ResourceMetaDataService s_resourceDetailsService;
     static HostGpuGroupsDao s_hostGpuGroupsDao;
@@ -646,6 +649,8 @@ public class ApiDBUtils {
     @Inject
     private NetworkACLDao networkACLDao;
     @Inject
+    private RoleService roleService;
+    @Inject
     private AccountService accountService;
     @Inject
     private ConfigurationManager configMgr;
@@ -768,6 +773,7 @@ public class ApiDBUtils {
         // Note: stats collector should already have been initialized by this time, otherwise a null instance is returned
         s_statsCollector = StatsCollector.getInstance();
         s_networkACLDao = networkACLDao;
+        s_roleService = roleService;
         s_accountService = accountService;
         s_resourceDetailsService = resourceDetailsService;
         s_hostGpuGroupsDao = hostGpuGroupsDao;
@@ -1695,6 +1701,15 @@ public class ApiDBUtils {
 
     public static UserResponse newUserResponse(UserAccountJoinVO usr, Long domainId) {
         UserResponse response = s_userAccountJoinDao.newUserResponse(usr);
+        // Populate user account role information
+        if (usr.getAccountRoleId() != null) {
+            Role role = s_roleService.findRole( usr.getAccountRoleId());
+            if (role != null) {
+                response.setRoleId(role.getUuid());
+                response.setRoleType(role.getRoleType());
+                response.setRoleName(role.getName());
+            }
+        }
         if (domainId != null && usr.getDomainId() != domainId)
             response.setIsCallerChildDomain(true);
         else
@@ -1820,7 +1835,17 @@ public class ApiDBUtils {
     }
 
     public static AccountResponse newAccountResponse(ResponseView view, AccountJoinVO ve) {
-        return s_accountJoinDao.newAccountResponse(view, ve);
+        AccountResponse response = s_accountJoinDao.newAccountResponse(view, ve);
+        // Populate account role information
+        if (ve.getRoleId() != null) {
+            Role role = s_roleService.findRole(ve.getRoleId());
+            if (role != null) {
+                response.setRoleId(role.getUuid());
+                response.setRoleType(role.getRoleType());
+                response.setRoleName(role.getName());
+            }
+        }
+        return response;
     }
 
     public static AccountJoinVO newAccountView(Account e) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4347776a/server/src/com/cloud/api/ApiResponseGsonHelper.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/ApiResponseGsonHelper.java b/server/src/com/cloud/api/ApiResponseGsonHelper.java
index 1708fa7..19db96a 100644
--- a/server/src/com/cloud/api/ApiResponseGsonHelper.java
+++ b/server/src/com/cloud/api/ApiResponseGsonHelper.java
@@ -68,7 +68,7 @@ public class ApiResponseGsonHelper {
                     boolean permittedParameter = false;
                     Account caller = CallContext.current().getCallingAccount();
                     for (RoleType allowedRole : allowedRoles) {
-                        if (allowedRole.getValue() == caller.getType()) {
+                        if (allowedRole.getAccountType() == caller.getType()) {
                             permittedParameter = true;
                             break;
                         }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4347776a/server/src/com/cloud/api/ApiServer.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/ApiServer.java b/server/src/com/cloud/api/ApiServer.java
index 6ec2f18..d7da425 100644
--- a/server/src/com/cloud/api/ApiServer.java
+++ b/server/src/com/cloud/api/ApiServer.java
@@ -797,15 +797,15 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer
                     s_logger.debug(ex.getMessage());
                     throw new ServerApiException(ApiErrorCode.API_LIMIT_EXCEED, ex.getMessage());
                 } catch (final PermissionDeniedException ex) {
-                    s_logger.debug("The given command:" + commandName + " does not exist or it is not available for user with id:" + userId);
-                    throw new ServerApiException(ApiErrorCode.UNSUPPORTED_ACTION_ERROR, "The given command does not exist or it is not available for user");
+                    s_logger.debug("The user with id:" + userId + " is not allowed to request the API command or the API command does not exist: " + commandName);
+                    throw new ServerApiException(ApiErrorCode.UNSUPPORTED_ACTION_ERROR, "The user is not allowed to request the API command or the API command does not exist");
                 }
                 return true;
             } else {
                 // check against every available command to see if the command exists or not
                 if (!s_apiNameCmdClassMap.containsKey(commandName) && !commandName.equals("login") && !commandName.equals("logout")) {
-                    s_logger.debug("The given command:" + commandName + " does not exist or it is not available for user with id:" + userId);
-                    throw new ServerApiException(ApiErrorCode.UNSUPPORTED_ACTION_ERROR, "The given command does not exist or it is not available for user");
+                    s_logger.debug("The user with id:" + userId + " is not allowed to request the API command or the API command does not exist: " + commandName);
+                    throw new ServerApiException(ApiErrorCode.UNSUPPORTED_ACTION_ERROR, "The user is not allowed to request the API command or the API command does not exist");
                 }
             }
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4347776a/server/src/com/cloud/api/query/vo/AccountJoinVO.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/query/vo/AccountJoinVO.java b/server/src/com/cloud/api/query/vo/AccountJoinVO.java
index 8d642ed..f251abc 100644
--- a/server/src/com/cloud/api/query/vo/AccountJoinVO.java
+++ b/server/src/com/cloud/api/query/vo/AccountJoinVO.java
@@ -48,6 +48,9 @@ public class AccountJoinVO extends BaseViewVO implements InternalIdentity, Ident
     @Column(name = "type")
     private short type;
 
+    @Column(name = "role_id")
+    private Long roleId;
+
     @Column(name = "state")
     @Enumerated(value = EnumType.STRING)
     private State state;
@@ -202,6 +205,10 @@ public class AccountJoinVO extends BaseViewVO implements InternalIdentity, Ident
         return type;
     }
 
+    public Long getRoleId() {
+        return roleId;
+    }
+
     public State getState() {
         return state;
     }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4347776a/server/src/com/cloud/api/query/vo/UserAccountJoinVO.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/query/vo/UserAccountJoinVO.java b/server/src/com/cloud/api/query/vo/UserAccountJoinVO.java
index 0e66ca0..e6b1ace 100644
--- a/server/src/com/cloud/api/query/vo/UserAccountJoinVO.java
+++ b/server/src/com/cloud/api/query/vo/UserAccountJoinVO.java
@@ -96,6 +96,9 @@ public class UserAccountJoinVO extends BaseViewVO implements InternalIdentity, I
     @Column(name = "account_type")
     private short accountType;
 
+    @Column(name = "account_role_id")
+    private Long accountRoleId;
+
     @Column(name = "domain_id")
     private long domainId;
 
@@ -149,6 +152,10 @@ public class UserAccountJoinVO extends BaseViewVO implements InternalIdentity, I
         return accountType;
     }
 
+    public Long getAccountRoleId() {
+        return accountRoleId;
+    }
+
     public long getDomainId() {
         return domainId;
     }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4347776a/server/src/com/cloud/api/response/ApiResponseSerializer.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/response/ApiResponseSerializer.java b/server/src/com/cloud/api/response/ApiResponseSerializer.java
index 59426e6..2b9717d 100644
--- a/server/src/com/cloud/api/response/ApiResponseSerializer.java
+++ b/server/src/com/cloud/api/response/ApiResponseSerializer.java
@@ -251,7 +251,7 @@ public class ApiResponseSerializer {
                     boolean permittedParameter = false;
                     Account caller = CallContext.current().getCallingAccount();
                     for (RoleType allowedRole : allowedRoles) {
-                        if (allowedRole.getValue() == caller.getType()) {
+                        if (allowedRole.getAccountType() == caller.getType()) {
                             permittedParameter = true;
                             break;
                         }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4347776a/server/src/com/cloud/projects/ProjectManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/projects/ProjectManagerImpl.java b/server/src/com/cloud/projects/ProjectManagerImpl.java
index ee66506..a8dd225 100644
--- a/server/src/com/cloud/projects/ProjectManagerImpl.java
+++ b/server/src/com/cloud/projects/ProjectManagerImpl.java
@@ -211,7 +211,7 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager {
         StringBuilder acctNm = new StringBuilder("PrjAcct-");
                 acctNm.append(name).append("-").append(ownerFinal.getDomainId());
 
-        Account projectAccount = _accountMgr.createAccount(acctNm.toString(), Account.ACCOUNT_TYPE_PROJECT, domainId, null, null, UUID.randomUUID().toString());
+        Account projectAccount = _accountMgr.createAccount(acctNm.toString(), Account.ACCOUNT_TYPE_PROJECT, null, domainId, null, null, UUID.randomUUID().toString());
 
                 Project project = _projectDao.persist(new ProjectVO(name, displayText, ownerFinal.getDomainId(), projectAccount.getId()));
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4347776a/server/src/com/cloud/server/ConfigurationServerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/server/ConfigurationServerImpl.java b/server/src/com/cloud/server/ConfigurationServerImpl.java
index 16e4ff0..13f98a2 100644
--- a/server/src/com/cloud/server/ConfigurationServerImpl.java
+++ b/server/src/com/cloud/server/ConfigurationServerImpl.java
@@ -449,7 +449,7 @@ public class ConfigurationServerImpl extends ManagerBase implements Configuratio
             public void doInTransactionWithoutResult(TransactionStatus status) {
                 TransactionLegacy txn = TransactionLegacy.currentTxn();
                 // insert system account
-                String insertSql = "INSERT INTO `cloud`.`account` (id, uuid, account_name, type, domain_id, account.default) VALUES (1, UUID(), 'system', '1', '1', 1)";
+                String insertSql = "INSERT INTO `cloud`.`account` (id, uuid, account_name, type, role_id, domain_id, account.default) VALUES (1, UUID(), 'system', '1', '1', '1', 1)";
 
                 try {
                     PreparedStatement stmt = txn.prepareAutoCloseStatement(insertSql);
@@ -476,8 +476,8 @@ public class ConfigurationServerImpl extends ManagerBase implements Configuratio
                 String lastname = "cloud";
 
                 // create an account for the admin user first
-                insertSql = "INSERT INTO `cloud`.`account` (id, uuid, account_name, type, domain_id, account.default) VALUES (" + id + ", UUID(), '" + username
-                        + "', '1', '1', 1)";
+                insertSql = "INSERT INTO `cloud`.`account` (id, uuid, account_name, type, role_id, domain_id, account.default) VALUES (" + id + ", UUID(), '" + username
+                        + "', '1', '1', '1', 1)";
                 try {
                     PreparedStatement stmt = txn.prepareAutoCloseStatement(insertSql);
                     stmt.executeUpdate();

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4347776a/server/src/com/cloud/user/AccountManager.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/user/AccountManager.java b/server/src/com/cloud/user/AccountManager.java
index 7b9e093..9789a22 100644
--- a/server/src/com/cloud/user/AccountManager.java
+++ b/server/src/com/cloud/user/AccountManager.java
@@ -50,7 +50,7 @@ public interface AccountManager extends AccountService {
 
     Long checkAccessAndSpecifyAuthority(Account caller, Long zoneId);
 
-    Account createAccount(String accountName, short accountType, Long domainId, String networkDomain, Map<String, String> details, String uuid);
+    Account createAccount(String accountName, short accountType, Long roleId, Long domainId, String networkDomain, Map<String, String> details, String uuid);
 
     /**
      * Logs out a user

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4347776a/server/src/com/cloud/user/AccountManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/user/AccountManagerImpl.java b/server/src/com/cloud/user/AccountManagerImpl.java
index d3eb40c..7e80681 100644
--- a/server/src/com/cloud/user/AccountManagerImpl.java
+++ b/server/src/com/cloud/user/AccountManagerImpl.java
@@ -994,9 +994,9 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
         @ActionEvent(eventType = EventTypes.EVENT_USER_CREATE, eventDescription = "creating User")
     })
     public UserAccount createUserAccount(final String userName, final String password, final String firstName, final String lastName, final String email, final String timezone,
-            String accountName, final short accountType, Long domainId, final String networkDomain, final Map<String, String> details, String accountUUID, final String userUUID) {
+            String accountName, final short accountType, final Long roleId, Long domainId, final String networkDomain, final Map<String, String> details, String accountUUID, final String userUUID) {
 
-        return createUserAccount(userName, password, firstName, lastName, email, timezone, accountName, accountType, domainId, networkDomain, details, accountUUID, userUUID,
+        return createUserAccount(userName, password, firstName, lastName, email, timezone, accountName, accountType, roleId, domainId, networkDomain, details, accountUUID, userUUID,
                 User.Source.UNKNOWN);
     }
 
@@ -1011,7 +1011,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
         @ActionEvent(eventType = EventTypes.EVENT_USER_CREATE, eventDescription = "creating User")
     })
     public UserAccount createUserAccount(final String userName, final String password, final String firstName, final String lastName, final String email,
-        final String timezone, String accountName, final short accountType, Long domainId, final String networkDomain, final Map<String, String> details,
+        final String timezone, String accountName, final short accountType, final Long roleId, Long domainId, final String networkDomain, final Map<String, String> details,
         String accountUUID, final String userUUID, final User.Source source) {
 
         if (accountName == null) {
@@ -1065,7 +1065,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
                 if (accountUUID == null) {
                     accountUUID = UUID.randomUUID().toString();
                 }
-                AccountVO account = createAccount(accountNameFinal, accountType, domainIdFinal, networkDomain, details, accountUUID);
+                AccountVO account = createAccount(accountNameFinal, accountType, roleId, domainIdFinal, networkDomain, details, accountUUID);
                 long accountId = account.getId();
 
                 // create the first user for the account
@@ -1869,27 +1869,10 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
 
     @Override
     public RoleType getRoleType(Account account) {
-        RoleType roleType = RoleType.Unknown;
-        if (account == null)
-            return roleType;
-        short accountType = account.getType();
-
-        // Account type to role type translation
-        switch (accountType) {
-            case Account.ACCOUNT_TYPE_ADMIN:
-                roleType = RoleType.Admin;
-                break;
-            case Account.ACCOUNT_TYPE_DOMAIN_ADMIN:
-                roleType = RoleType.DomainAdmin;
-                break;
-            case Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN:
-                roleType = RoleType.ResourceAdmin;
-                break;
-            case Account.ACCOUNT_TYPE_NORMAL:
-                roleType = RoleType.User;
-                break;
+        if (account == null) {
+            return RoleType.Unknown;
         }
-        return roleType;
+        return RoleType.getByAccountType(account.getType());
     }
 
     @Override
@@ -1916,7 +1899,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
 
     @Override
     @DB
-    public AccountVO createAccount(final String accountName, final short accountType, final Long domainId, final String networkDomain, final Map<String, String> details,
+    public AccountVO createAccount(final String accountName, final short accountType, final Long roleId, final Long domainId, final String networkDomain, final Map<String, String> details,
         final String uuid) {
         // Validate domain
         Domain domain = _domainMgr.getDomain(domainId);
@@ -1929,7 +1912,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
         }
 
         if ((domainId != Domain.ROOT_DOMAIN) && (accountType == Account.ACCOUNT_TYPE_ADMIN)) {
-            throw new InvalidParameterValueException("Invalid account type " + accountType + " given for an account in domain " + domainId + "; unable to create user.");
+            throw new InvalidParameterValueException("Invalid account type " + accountType + " given for an account in domain " + domainId + "; unable to create user of admin role type in non-ROOT domain.");
         }
 
         // Validate account/user/domain settings
@@ -1961,7 +1944,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
         return Transaction.execute(new TransactionCallback<AccountVO>() {
             @Override
             public AccountVO doInTransaction(TransactionStatus status) {
-        AccountVO account = _accountDao.persist(new AccountVO(accountName, domainId, networkDomain, accountType, uuid));
+        AccountVO account = _accountDao.persist(new AccountVO(accountName, domainId, networkDomain, accountType, roleId, uuid));
 
         if (account == null) {
             throw new CloudRuntimeException("Failed to create account name " + accountName + " in domain id=" + domainId);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4347776a/server/src/org/apache/cloudstack/acl/RoleManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/org/apache/cloudstack/acl/RoleManagerImpl.java b/server/src/org/apache/cloudstack/acl/RoleManagerImpl.java
new file mode 100644
index 0000000..7363b13
--- /dev/null
+++ b/server/src/org/apache/cloudstack/acl/RoleManagerImpl.java
@@ -0,0 +1,264 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.acl;
+
+import com.cloud.event.ActionEvent;
+import com.cloud.event.EventTypes;
+import com.cloud.exception.PermissionDeniedException;
+import com.cloud.user.Account;
+import com.cloud.user.dao.AccountDao;
+import com.cloud.utils.ListUtils;
+import com.cloud.utils.PropertiesUtil;
+import com.cloud.utils.component.ManagerBase;
+import com.cloud.utils.component.PluggableService;
+import com.cloud.utils.db.Transaction;
+import com.cloud.utils.db.TransactionCallback;
+import com.cloud.utils.db.TransactionStatus;
+import com.google.common.base.Strings;
+import org.apache.cloudstack.acl.dao.RoleDao;
+import org.apache.cloudstack.acl.dao.RolePermissionsDao;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.command.admin.acl.CreateRoleCmd;
+import org.apache.cloudstack.api.command.admin.acl.CreateRolePermissionCmd;
+import org.apache.cloudstack.api.command.admin.acl.DeleteRoleCmd;
+import org.apache.cloudstack.api.command.admin.acl.DeleteRolePermissionCmd;
+import org.apache.cloudstack.api.command.admin.acl.ListRolePermissionsCmd;
+import org.apache.cloudstack.api.command.admin.acl.ListRolesCmd;
+import org.apache.cloudstack.api.command.admin.acl.UpdateRoleCmd;
+import org.apache.cloudstack.api.command.admin.acl.UpdateRolePermissionCmd;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.framework.config.ConfigKey;
+import org.apache.cloudstack.framework.config.Configurable;
+
+import javax.ejb.Local;
+import javax.inject.Inject;
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+@Local(value = {RoleService.class})
+public class RoleManagerImpl extends ManagerBase implements RoleService, Configurable, PluggableService {
+    @Inject
+    private AccountDao accountDao;
+    @Inject
+    private RoleDao roleDao;
+    @Inject
+    private RolePermissionsDao rolePermissionsDao;
+
+    private void checkCallerAccess() {
+        if (!isEnabled()) {
+            throw new PermissionDeniedException("Dynamic api checker is not enabled, aborting role operation");
+        }
+        Account caller = CallContext.current().getCallingAccount();
+        if (caller == null || caller.getRoleId() == null) {
+            throw new PermissionDeniedException("Restricted API called by an invalid user account");
+        }
+        Role callerRole = findRole(caller.getRoleId());
+        if (callerRole == null || callerRole.getRoleType() != RoleType.Admin) {
+            throw new PermissionDeniedException("Restricted API called by an user account of non-Admin role type");
+        }
+    }
+
+    @Override
+    public boolean isEnabled() {
+        File apiCmdFile = PropertiesUtil.findConfigFile(PropertiesUtil.getDefaultApiCommandsFileName());
+        return RoleService.EnableDynamicApiChecker.value() && (apiCmdFile == null || !apiCmdFile.exists());
+    }
+
+    @Override
+    public Role findRole(final Long id) {
+        if (id == null || id < 1L) {
+            return null;
+        }
+        return roleDao.findById(id);
+    }
+
+    @Override
+    public RolePermission findRolePermission(final Long id) {
+        if (id == null) {
+            return null;
+        }
+        return rolePermissionsDao.findById(id);
+    }
+
+    @Override
+    public RolePermission findRolePermissionByUuid(final String uuid) {
+        if (Strings.isNullOrEmpty(uuid)) {
+            return null;
+        }
+        return rolePermissionsDao.findByUuid(uuid);
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_ROLE_CREATE, eventDescription = "creating Role")
+    public Role createRole(final String name, final RoleType roleType, final String description) {
+        checkCallerAccess();
+        if (roleType == null || roleType == RoleType.Unknown) {
+            throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Invalid role type provided");
+        }
+        return Transaction.execute(new TransactionCallback<RoleVO>() {
+            @Override
+            public RoleVO doInTransaction(TransactionStatus status) {
+                return roleDao.persist(new RoleVO(name, roleType, description));
+            }
+        });
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_ROLE_UPDATE, eventDescription = "updating Role")
+    public boolean updateRole(final Role role, final String name, final RoleType roleType, final String description) {
+        checkCallerAccess();
+        if (role == null) {
+            return false;
+        }
+        if (roleType != null && roleType == RoleType.Unknown) {
+            throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Unknown is not a valid role type");
+        }
+        RoleVO roleVO = (RoleVO) role;
+        if (!Strings.isNullOrEmpty(name)) {
+            roleVO.setName(name);
+        }
+        if (roleType != null) {
+            if (role.getId() <= RoleType.User.getId()) {
+                throw new PermissionDeniedException("The role type of default roles cannot be changed");
+            }
+            List<? extends Account> accounts = accountDao.findAccountsByRole(role.getId());
+            if (accounts == null || accounts.isEmpty()) {
+                roleVO.setRoleType(roleType);
+            } else {
+                throw new PermissionDeniedException("Found accounts that have role in use, won't allow to change role type");
+            }
+        }
+        if (!Strings.isNullOrEmpty(description)) {
+            roleVO.setDescription(description);
+        }
+        return roleDao.update(role.getId(), roleVO);
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_ROLE_DELETE, eventDescription = "deleting Role")
+    public boolean deleteRole(final Role role) {
+        checkCallerAccess();
+        if (role == null) {
+            return false;
+        }
+        if (role.getId() <= RoleType.User.getId()) {
+            throw new PermissionDeniedException("Default roles cannot be deleted");
+        }
+        List<? extends Account> accounts = accountDao.findAccountsByRole(role.getId());
+        if (accounts == null || accounts.size() == 0) {
+            return Transaction.execute(new TransactionCallback<Boolean>() {
+                @Override
+                public Boolean doInTransaction(TransactionStatus status) {
+                    List<? extends RolePermission> rolePermissions = rolePermissionsDao.findAllByRoleIdSorted(role.getId());
+                    if (rolePermissions != null && !rolePermissions.isEmpty()) {
+                        for (RolePermission rolePermission : rolePermissions) {
+                            rolePermissionsDao.remove(rolePermission.getId());
+                        }
+                    }
+                    return roleDao.remove(role.getId());
+                }
+            });
+        }
+        throw new PermissionDeniedException("Found accounts that have role in use, won't allow to delete role");
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_ROLE_PERMISSION_CREATE, eventDescription = "creating Role Permission")
+    public RolePermission createRolePermission(final Role role, final Rule rule, final RolePermission.Permission permission, final String description) {
+        checkCallerAccess();
+        return Transaction.execute(new TransactionCallback<RolePermissionVO>() {
+            @Override
+            public RolePermissionVO doInTransaction(TransactionStatus status) {
+                return rolePermissionsDao.persist(new RolePermissionVO(role.getId(), rule.toString(), permission, description));
+            }
+        });
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_ROLE_PERMISSION_UPDATE, eventDescription = "updating Role Permission order")
+    public boolean updateRolePermission(final Role role, final List<RolePermission> newOrder) {
+        checkCallerAccess();
+        return role != null && newOrder != null && rolePermissionsDao.update(role, newOrder);
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_ROLE_PERMISSION_DELETE, eventDescription = "deleting Role Permission")
+    public boolean deleteRolePermission(final RolePermission rolePermission) {
+        checkCallerAccess();
+        return rolePermission != null && rolePermissionsDao.remove(rolePermission.getId());
+    }
+
+    @Override
+    public List<Role> findRolesByName(final String name) {
+        List<? extends Role> roles = null;
+        if (!Strings.isNullOrEmpty(name)) {
+            roles = roleDao.findAllByName(name);
+        }
+        return ListUtils.toListOfInterface(roles);
+    }
+
+    @Override
+    public List<Role> findRolesByType(final RoleType roleType) {
+        List<? extends Role> roles = null;
+        if (roleType != null) {
+            roles = roleDao.findAllByRoleType(roleType);
+        }
+        return ListUtils.toListOfInterface(roles);
+    }
+
+    @Override
+    public List<Role> listRoles() {
+        List<? extends Role> roles = roleDao.listAll();
+        return ListUtils.toListOfInterface(roles);
+    }
+
+    @Override
+    public List<RolePermission> findAllPermissionsBy(final Long roleId) {
+        List<? extends RolePermission> permissions = rolePermissionsDao.findAllByRoleIdSorted(roleId);
+        if (permissions != null) {
+            return new ArrayList<>(permissions);
+        }
+        return Collections.emptyList();
+    }
+
+    @Override
+    public String getConfigComponentName() {
+        return RoleService.class.getSimpleName();
+    }
+
+    @Override
+    public ConfigKey<?>[] getConfigKeys() {
+        return new ConfigKey<?>[]{RoleService.EnableDynamicApiChecker};
+    }
+
+    @Override
+    public List<Class<?>> getCommands() {
+        final List<Class<?>> cmdList = new ArrayList<>();
+        cmdList.add(CreateRoleCmd.class);
+        cmdList.add(ListRolesCmd.class);
+        cmdList.add(UpdateRoleCmd.class);
+        cmdList.add(DeleteRoleCmd.class);
+        cmdList.add(CreateRolePermissionCmd.class);
+        cmdList.add(ListRolePermissionsCmd.class);
+        cmdList.add(UpdateRolePermissionCmd.class);
+        cmdList.add(DeleteRolePermissionCmd.class);
+        return cmdList;
+    }
+ }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4347776a/server/test/com/cloud/user/MockAccountManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/test/com/cloud/user/MockAccountManagerImpl.java b/server/test/com/cloud/user/MockAccountManagerImpl.java
index 3971fd6..fd85167 100644
--- a/server/test/com/cloud/user/MockAccountManagerImpl.java
+++ b/server/test/com/cloud/user/MockAccountManagerImpl.java
@@ -328,13 +328,13 @@ public class MockAccountManagerImpl extends ManagerBase implements Manager, Acco
 
     @Override
     public UserAccount createUserAccount(String userName, String password, String firstName, String lastName, String email, String timezone, String accountName,
-        short accountType, Long domainId, String networkDomain, Map<String, String> details, String accountUUID, String userUUID) {
+        short accountType, Long roleId, Long domainId, String networkDomain, Map<String, String> details, String accountUUID, String userUUID) {
         // TODO Auto-generated method stub
         return null;
     }
 
     @Override
-    public UserAccount createUserAccount(String userName, String password, String firstName, String lastName, String email, String timezone, String accountName, short accountType,
+    public UserAccount createUserAccount(String userName, String password, String firstName, String lastName, String email, String timezone, String accountName, short accountType, Long roleId,
                                          Long domainId, String networkDomain, Map<String, String> details, String accountUUID, String userUUID, User.Source source) {
         // TODO Auto-generated method stub
         return null;
@@ -366,7 +366,7 @@ public class MockAccountManagerImpl extends ManagerBase implements Manager, Acco
     }
 
     @Override
-    public Account createAccount(String accountName, short accountType, Long domainId, String networkDomain, Map<String, String> details, String uuid) {
+    public Account createAccount(String accountName, short accountType, Long roleId, Long domainId, String networkDomain, Map<String, String> details, String uuid) {
         // TODO Auto-generated method stub
         return null;
     }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4347776a/services/iam/plugin/src/org/apache/cloudstack/iam/RoleBasedAPIAccessChecker.java
----------------------------------------------------------------------
diff --git a/services/iam/plugin/src/org/apache/cloudstack/iam/RoleBasedAPIAccessChecker.java b/services/iam/plugin/src/org/apache/cloudstack/iam/RoleBasedAPIAccessChecker.java
index 634ce0a..3072b77 100644
--- a/services/iam/plugin/src/org/apache/cloudstack/iam/RoleBasedAPIAccessChecker.java
+++ b/services/iam/plugin/src/org/apache/cloudstack/iam/RoleBasedAPIAccessChecker.java
@@ -196,7 +196,7 @@ public class RoleBasedAPIAccessChecker extends AdapterBase implements APIChecker
             try {
                 short cmdPermissions = Short.parseShort(roleMask);
                 for (RoleType roleType : RoleType.values()) {
-                    if ((cmdPermissions & roleType.getValue()) != 0)
+                    if ((cmdPermissions & roleType.getMask()) != 0)
                         commandsPropertiesRoleBasedApisMap.get(roleType).add(apiName);
                 }
             } catch (NumberFormatException nfe) {