Skip to content

Commit a0080a0

Browse files
nvazquezharikrishna-patnala
authored andcommitted
Adding privilege checks on user and account operations
Co-authored-by: Harikrishna <[email protected]>
1 parent e2f1879 commit a0080a0

File tree

10 files changed

+321
-10
lines changed

10 files changed

+321
-10
lines changed

api/src/main/java/com/cloud/user/Account.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ public static Type getFromValue(Integer type){
7171
}
7272

7373
public static final long ACCOUNT_ID_SYSTEM = 1;
74+
public static final long ACCOUNT_ID_ADMIN = 2;
7475

7576
public String getAccountName();
7677

plugins/network-elements/juniper-contrail/src/test/java/org/apache/cloudstack/network/contrail/management/MockAccountManager.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -521,4 +521,8 @@ public ConfigKey<?>[] getConfigKeys() {
521521
public UserAccount clearUserTwoFactorAuthenticationInSetupStateOnLogin(UserAccount user) {
522522
return null;
523523
}
524+
525+
@Override
526+
public void verifyCallerPrivilegeForUserOrAccountOperations(Account userAccount) {
527+
}
524528
}

server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,13 @@
4747

4848

4949
import com.cloud.hypervisor.HypervisorGuru;
50+
import com.cloud.user.AccountManagerImpl;
5051
import com.cloud.utils.crypt.DBEncryptionUtil;
5152
import com.cloud.host.HostTagVO;
5253
import com.cloud.storage.StoragePoolTagVO;
5354
import com.cloud.storage.VolumeApiServiceImpl;
5455
import com.googlecode.ipv6.IPv6Address;
56+
import org.apache.cloudstack.acl.RoleType;
5557
import org.apache.cloudstack.acl.SecurityChecker;
5658
import org.apache.cloudstack.affinity.AffinityGroup;
5759
import org.apache.cloudstack.affinity.AffinityGroupService;
@@ -470,6 +472,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
470472
private long _defaultPageSize = Long.parseLong(Config.DefaultPageSize.getDefaultValue());
471473
private static final String DOMAIN_NAME_PATTERN = "^((?!-)[A-Za-z0-9-]{1,63}(?<!-)\\.)+[A-Za-z]{1,63}$";
472474
private Set<String> configValuesForValidation = new HashSet<String>();
475+
private Set<String> configKeysAllowedOnlyForDefaultAdmin = new HashSet<String>();
473476
private Set<String> weightBasedParametersForValidation = new HashSet<String>();
474477
private Set<String> overprovisioningFactorsForValidation = new HashSet<String>();
475478

@@ -533,6 +536,7 @@ public boolean configure(final String name, final Map<String, Object> params) th
533536
populateConfigValuesForValidationSet();
534537
weightBasedParametersForValidation();
535538
overProvisioningFactorsForValidation();
539+
populateConfigKeysAllowedOnlyForDefaultAdmin();
536540
initMessageBusListener();
537541
return true;
538542
}
@@ -596,6 +600,11 @@ private void overProvisioningFactorsForValidation() {
596600
overprovisioningFactorsForValidation.add(CapacityManager.StorageOverprovisioningFactor.key());
597601
}
598602

603+
protected void populateConfigKeysAllowedOnlyForDefaultAdmin() {
604+
configKeysAllowedOnlyForDefaultAdmin.add(AccountManagerImpl.listOfRoleTypesAllowedForOperationsOfSameRoleType.key());
605+
configKeysAllowedOnlyForDefaultAdmin.add(AccountManagerImpl.allowOperationsOnUsersInSameAccount.key());
606+
}
607+
599608
private void initMessageBusListener() {
600609
messageBus.subscribe(EventTypes.EVENT_CONFIGURATION_VALUE_EDIT, new MessageSubscriber() {
601610
@Override
@@ -1183,6 +1192,7 @@ protected String validateConfigurationValue(final String name, String value, fin
11831192
s_logger.error("Missing configuration variable " + name + " in configuration table");
11841193
return "Invalid configuration variable.";
11851194
}
1195+
validateConfigurationAllowedOnlyForDefaultAdmin(name, value);
11861196

11871197
final String configScope = cfg.getScope();
11881198
if (scope != null) {
@@ -1347,6 +1357,33 @@ protected String validateConfigurationValue(final String name, String value, fin
13471357
return String.format("Invalid value for configuration [%s].", name);
13481358
}
13491359

1360+
protected void validateConfigurationAllowedOnlyForDefaultAdmin(String configName, String value) {
1361+
if (configKeysAllowedOnlyForDefaultAdmin.contains(configName)) {
1362+
final Long userId = CallContext.current().getCallingUserId();
1363+
if (userId != User.UID_ADMIN) {
1364+
throw new CloudRuntimeException("Only default admin is allowed to change this setting");
1365+
}
1366+
1367+
if (AccountManagerImpl.listOfRoleTypesAllowedForOperationsOfSameRoleType.key().equals(configName)) {
1368+
if (value != null && !value.isBlank()) {
1369+
List<String> validRoleTypes = Arrays.stream(RoleType.values())
1370+
.map(Enum::name)
1371+
.collect(Collectors.toList());
1372+
1373+
boolean allValid = Arrays.stream(value.split(","))
1374+
.map(String::trim)
1375+
.allMatch(validRoleTypes::contains);
1376+
1377+
if (!allValid) {
1378+
throw new CloudRuntimeException("Invalid role types provided in value");
1379+
}
1380+
} else {
1381+
throw new CloudRuntimeException("Value for role types must not be empty");
1382+
}
1383+
}
1384+
}
1385+
}
1386+
13501387
/**
13511388
* A valid value should be an integer between min and max (the values from the range).
13521389
*/

server/src/main/java/com/cloud/resourcelimit/ResourceLimitManagerImpl.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -784,6 +784,7 @@ public ResourceLimitVO updateResourceLimit(Long accountId, Long domainId, Intege
784784
} else {
785785
_accountMgr.checkAccess(caller, null, true, account);
786786
}
787+
_accountMgr.verifyCallerPrivilegeForUserOrAccountOperations(account);
787788

788789
ownerType = ResourceOwnerType.Account;
789790
ownerId = accountId;
@@ -853,6 +854,11 @@ public List<ResourceCountVO> recalculateResourceCount(Long accountId, Long domai
853854
throw new InvalidParameterValueException("Please specify a valid domain ID.");
854855
}
855856
_accountMgr.checkAccess(callerAccount, domain);
857+
Account account = _entityMgr.findById(Account.class, accountId);
858+
if (account == null) {
859+
throw new InvalidParameterValueException("Unable to find account " + accountId);
860+
}
861+
_accountMgr.verifyCallerPrivilegeForUserOrAccountOperations(account);
856862

857863
if (resourceType != null) {
858864
resourceTypes.add(resourceType);

server/src/main/java/com/cloud/user/AccountManager.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,4 +200,5 @@ void buildACLViewSearchCriteria(SearchCriteria<? extends ControlledViewEntity> s
200200

201201
UserAccount clearUserTwoFactorAuthenticationInSetupStateOnLogin(UserAccount user);
202202

203+
void verifyCallerPrivilegeForUserOrAccountOperations(Account userAccount);
203204
}

0 commit comments

Comments
 (0)