Skip to content

Commit d5fbd07

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

File tree

11 files changed

+324
-9
lines changed

11 files changed

+324
-9
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
@@ -533,4 +533,8 @@ public void checkApiAccess(Account account, String command) throws PermissionDen
533533
public UserAccount clearUserTwoFactorAuthenticationInSetupStateOnLogin(UserAccount user) {
534534
return null;
535535
}
536+
537+
@Override
538+
public void verifyCallerPrivilegeForUserOrAccountOperations(Account userAccount) {
539+
}
536540
}

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

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@
5050
import javax.inject.Inject;
5151
import javax.naming.ConfigurationException;
5252

53+
import com.cloud.user.AccountManagerImpl;
54+
import org.apache.cloudstack.acl.RoleType;
5355
import org.apache.cloudstack.acl.SecurityChecker;
5456
import org.apache.cloudstack.affinity.AffinityGroup;
5557
import org.apache.cloudstack.affinity.AffinityGroupService;
@@ -481,6 +483,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
481483
private long _defaultPageSize = Long.parseLong(Config.DefaultPageSize.getDefaultValue());
482484
private static final String DOMAIN_NAME_PATTERN = "^((?!-)[A-Za-z0-9-]{1,63}(?<!-)\\.)+[A-Za-z]{1,63}$";
483485
private Set<String> configValuesForValidation = new HashSet<>();
486+
private Set<String> configKeysAllowedOnlyForDefaultAdmin = new HashSet<>();
484487
private Set<String> weightBasedParametersForValidation = new HashSet<>();
485488
private Set<String> overprovisioningFactorsForValidation = new HashSet<>();
486489

@@ -545,6 +548,7 @@ public boolean configure(final String name, final Map<String, Object> params) th
545548
populateConfigValuesForValidationSet();
546549
weightBasedParametersForValidation();
547550
overProvisioningFactorsForValidation();
551+
populateConfigKeysAllowedOnlyForDefaultAdmin();
548552
initMessageBusListener();
549553
return true;
550554
}
@@ -609,6 +613,11 @@ protected void overProvisioningFactorsForValidation() {
609613
overprovisioningFactorsForValidation.add(CapacityManager.StorageOverprovisioningFactor.key());
610614
}
611615

616+
protected void populateConfigKeysAllowedOnlyForDefaultAdmin() {
617+
configKeysAllowedOnlyForDefaultAdmin.add(AccountManagerImpl.listOfRoleTypesAllowedForOperationsOfSameRoleType.key());
618+
configKeysAllowedOnlyForDefaultAdmin.add(AccountManagerImpl.allowOperationsOnUsersInSameAccount.key());
619+
}
620+
612621
private void initMessageBusListener() {
613622
messageBus.subscribe(EventTypes.EVENT_CONFIGURATION_VALUE_EDIT, new MessageSubscriber() {
614623
@Override
@@ -1221,6 +1230,7 @@ protected String validateConfigurationValue(String name, String value, String sc
12211230
logger.error("Missing configuration variable " + name + " in configuration table");
12221231
return "Invalid configuration variable.";
12231232
}
1233+
validateConfigurationAllowedOnlyForDefaultAdmin(name, value);
12241234

12251235
String configScope = cfg.getScope();
12261236
if (scope != null) {
@@ -1255,6 +1265,33 @@ protected String validateConfigurationValue(String name, String value, String sc
12551265
return validateValueRange(name, value, type, configuration);
12561266
}
12571267

1268+
protected void validateConfigurationAllowedOnlyForDefaultAdmin(String configName, String value) {
1269+
if (configKeysAllowedOnlyForDefaultAdmin.contains(configName)) {
1270+
final Long userId = CallContext.current().getCallingUserId();
1271+
if (userId != User.UID_ADMIN) {
1272+
throw new CloudRuntimeException("Only default admin is allowed to change this setting");
1273+
}
1274+
1275+
if (AccountManagerImpl.listOfRoleTypesAllowedForOperationsOfSameRoleType.key().equals(configName)) {
1276+
if (value != null && !value.isBlank()) {
1277+
List<String> validRoleTypes = Arrays.stream(RoleType.values())
1278+
.map(Enum::name)
1279+
.collect(Collectors.toList());
1280+
1281+
boolean allValid = Arrays.stream(value.split(","))
1282+
.map(String::trim)
1283+
.allMatch(validRoleTypes::contains);
1284+
1285+
if (!allValid) {
1286+
throw new CloudRuntimeException("Invalid role types provided in value");
1287+
}
1288+
} else {
1289+
throw new CloudRuntimeException("Value for role types must not be empty");
1290+
}
1291+
}
1292+
}
1293+
}
1294+
12581295
/**
12591296
* Returns whether a value is valid for a configuration of the provided type.
12601297
* Valid configuration values are:

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -939,6 +939,7 @@ public ResourceLimitVO updateResourceLimit(Long accountId, Long domainId, Intege
939939
} else {
940940
_accountMgr.checkAccess(caller, null, true, account);
941941
}
942+
_accountMgr.verifyCallerPrivilegeForUserOrAccountOperations(account);
942943

943944
ownerType = ResourceOwnerType.Account;
944945
ownerId = accountId;
@@ -1090,6 +1091,11 @@ public List<? extends ResourceCount> recalculateResourceCount(Long accountId, Lo
10901091
throw new InvalidParameterValueException("Please specify a valid domain ID.");
10911092
}
10921093
_accountMgr.checkAccess(callerAccount, domain);
1094+
Account account = _entityMgr.findById(Account.class, accountId);
1095+
if (account == null) {
1096+
throw new InvalidParameterValueException("Unable to find account " + accountId);
1097+
}
1098+
_accountMgr.verifyCallerPrivilegeForUserOrAccountOperations(account);
10931099

10941100
if (resourceType != null) {
10951101
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
@@ -206,4 +206,5 @@ void buildACLViewSearchCriteria(SearchCriteria<? extends ControlledViewEntity> s
206206

207207
UserAccount clearUserTwoFactorAuthenticationInSetupStateOnLogin(UserAccount user);
208208

209+
void verifyCallerPrivilegeForUserOrAccountOperations(Account userAccount);
209210
}

0 commit comments

Comments
 (0)