Skip to content

Commit c8d44d9

Browse files
shwstpprweizhouapache
authored andcommitted
api,server: fix entity access
Added access check for: - createNetworkACL - listNetworkACLs - listResourceDetails - listVirtualMachinesUsageHistory - listVolumesUsageHistory Signed-off-by: Abhishek Kumar <[email protected]>
1 parent eee43e5 commit c8d44d9

File tree

6 files changed

+221
-35
lines changed

6 files changed

+221
-35
lines changed

api/src/main/java/com/cloud/server/ResourceManagerUtil.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
public interface ResourceManagerUtil {
2020
long getResourceId(String resourceId, ResourceTag.ResourceObjectType resourceType);
21+
long getResourceId(String resourceId, ResourceTag.ResourceObjectType resourceType, boolean checkAccess);
2122
String getUuid(String resourceId, ResourceTag.ResourceObjectType resourceType);
2223
ResourceTag.ResourceObjectType getResourceType(String resourceTypeStr);
2324
void checkResourceAccessible(Long accountId, Long domainId, String exceptionMessage);

plugins/metrics/src/main/java/org/apache/cloudstack/metrics/MetricsServiceImpl.java

Lines changed: 72 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import java.lang.reflect.InvocationTargetException;
2323
import java.text.DecimalFormat;
2424
import java.util.ArrayList;
25+
import java.util.Arrays;
2526
import java.util.Date;
2627
import java.util.HashMap;
2728
import java.util.List;
@@ -32,8 +33,6 @@
3233
import javax.inject.Inject;
3334
import javax.naming.ConfigurationException;
3435

35-
import com.cloud.dc.ClusterVO;
36-
import com.cloud.utils.Ternary;
3736
import org.apache.cloudstack.api.ApiErrorCode;
3837
import org.apache.cloudstack.api.ListClustersMetricsCmd;
3938
import org.apache.cloudstack.api.ListDbMetricsCmd;
@@ -100,6 +99,7 @@
10099
import com.cloud.capacity.dao.CapacityDao;
101100
import com.cloud.capacity.dao.CapacityDaoImpl;
102101
import com.cloud.cluster.dao.ManagementServerHostDao;
102+
import com.cloud.dc.ClusterVO;
103103
import com.cloud.dc.DataCenter;
104104
import com.cloud.dc.dao.ClusterDao;
105105
import com.cloud.dc.dao.DataCenterDao;
@@ -112,6 +112,7 @@
112112
import com.cloud.host.dao.HostDao;
113113
import com.cloud.network.router.VirtualRouter;
114114
import com.cloud.org.Cluster;
115+
import com.cloud.projects.Project;
115116
import com.cloud.server.DbStatsCollection;
116117
import com.cloud.server.ManagementServerHostStats;
117118
import com.cloud.server.StatsCollector;
@@ -124,6 +125,7 @@
124125
import com.cloud.user.Account;
125126
import com.cloud.user.AccountManager;
126127
import com.cloud.utils.Pair;
128+
import com.cloud.utils.Ternary;
127129
import com.cloud.utils.db.DbProperties;
128130
import com.cloud.utils.db.DbUtil;
129131
import com.cloud.utils.db.Filter;
@@ -184,6 +186,10 @@ public class MetricsServiceImpl extends MutualExclusiveIdsManagerBase implements
184186

185187
private static Gson gson = new Gson();
186188

189+
private final List<Account.Type> AccountTypesWithRecursiveUsageAccess = Arrays.asList(
190+
Account.Type.ADMIN, Account.Type.DOMAIN_ADMIN, Account.Type.READ_ONLY_ADMIN
191+
);
192+
187193
protected MetricsServiceImpl() {
188194
super();
189195
}
@@ -245,17 +251,30 @@ public ListResponse<VolumeMetricsStatsResponse> searchForVolumeMetricsStats(List
245251
* @return the list of VMs.
246252
*/
247253
protected Pair<List<UserVmVO>, Integer> searchForUserVmsInternal(ListVMsUsageHistoryCmd cmd) {
254+
final Long id = cmd.getId();
255+
Account caller = CallContext.current().getCallingAccount();
256+
List<Long> permittedAccounts = new ArrayList<>();
257+
boolean recursive = AccountTypesWithRecursiveUsageAccess.contains(caller.getType());
258+
Ternary<Long, Boolean, Project.ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<>(null, recursive, null);
259+
accountMgr.buildACLSearchParameters(caller, id, null, null, permittedAccounts, domainIdRecursiveListProject, true, false);
260+
Long domainId = domainIdRecursiveListProject.first();
261+
Boolean isRecursive = domainIdRecursiveListProject.second();
262+
Project.ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third();
263+
248264
Filter searchFilter = new Filter(UserVmVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal());
249265
List<Long> ids = getIdsListFromCmd(cmd.getId(), cmd.getIds());
250266
String name = cmd.getName();
251267
String keyword = cmd.getKeyword();
252268

253269
SearchBuilder<UserVmVO> sb = userVmDao.createSearchBuilder();
270+
sb.select(null, SearchCriteria.Func.DISTINCT, sb.entity().getId()); // select distinct
271+
accountMgr.buildACLSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
254272
sb.and("idIN", sb.entity().getId(), SearchCriteria.Op.IN);
255273
sb.and("displayName", sb.entity().getDisplayName(), SearchCriteria.Op.LIKE);
256274
sb.and("state", sb.entity().getState(), SearchCriteria.Op.EQ);
257275

258276
SearchCriteria<UserVmVO> sc = sb.create();
277+
accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
259278
if (CollectionUtils.isNotEmpty(ids)) {
260279
sc.setParameters("idIN", ids.toArray());
261280
}
@@ -269,7 +288,14 @@ protected Pair<List<UserVmVO>, Integer> searchForUserVmsInternal(ListVMsUsageHis
269288
sc.addAnd("displayName", SearchCriteria.Op.SC, ssc);
270289
}
271290

272-
return userVmDao.searchAndCount(sc, searchFilter);
291+
Pair<List<UserVmVO>, Integer> uniqueVmPair = userVmDao.searchAndCount(sc, searchFilter);
292+
Integer count = uniqueVmPair.second();
293+
if (count == 0) {
294+
return new Pair<>(new ArrayList<>(), count);
295+
}
296+
List<Long> vmIds = uniqueVmPair.first().stream().map(UserVmVO::getId).collect(Collectors.toList());
297+
List<UserVmVO> vms = userVmDao.listByIds(vmIds);
298+
return new Pair<>(vms, count);
273299
}
274300

275301
/**
@@ -331,17 +357,49 @@ protected Map<Long,List<VmStatsVO>> searchForVmMetricsStatsInternal(Date startDa
331357
* @return the list of VMs.
332358
*/
333359
protected Pair<List<VolumeVO>, Integer> searchForVolumesInternal(ListVolumesUsageHistoryCmd cmd) {
360+
final Long id = cmd.getId();
361+
Account caller = CallContext.current().getCallingAccount();
362+
List<Long> permittedAccounts = new ArrayList<>();
363+
boolean recursive = AccountTypesWithRecursiveUsageAccess.contains(caller.getType());
364+
Ternary<Long, Boolean, Project.ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<>(null, recursive, null);
365+
accountMgr.buildACLSearchParameters(caller, id, null, null, permittedAccounts, domainIdRecursiveListProject, true, false);
366+
Long domainId = domainIdRecursiveListProject.first();
367+
Boolean isRecursive = domainIdRecursiveListProject.second();
368+
Project.ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third();
369+
334370
Filter searchFilter = new Filter(VolumeVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal());
335371
List<Long> ids = getIdsListFromCmd(cmd.getId(), cmd.getIds());
336372
String name = cmd.getName();
337373
String keyword = cmd.getKeyword();
338374

339375
SearchBuilder<VolumeVO> sb = volumeDao.createSearchBuilder();
376+
sb.select(null, SearchCriteria.Func.DISTINCT, sb.entity().getId()); // select distinct
377+
accountMgr.buildACLSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
340378
sb.and("idIN", sb.entity().getId(), SearchCriteria.Op.IN);
341379
sb.and("name", sb.entity().getName(), SearchCriteria.Op.EQ);
342380
sb.and("state", sb.entity().getState(), SearchCriteria.Op.EQ);
343381

382+
boolean shouldListSystemVmVolumes = accountMgr.isRootAdmin(CallContext.current().getCallingAccountId());
383+
List<Long> vmIds = new ArrayList<>();
384+
if (!shouldListSystemVmVolumes) {
385+
SearchBuilder<UserVmVO> vmSearch = userVmDao.createSearchBuilder();
386+
vmSearch.select(null, SearchCriteria.Func.DISTINCT, vmSearch.entity().getId());
387+
accountMgr.buildACLSearchBuilder(vmSearch, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
388+
SearchCriteria<UserVmVO> vmSc = vmSearch.create();
389+
accountMgr.buildACLSearchCriteria(vmSc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
390+
List<UserVmVO> vms = userVmDao.search(vmSc, null);
391+
vmIds = vms.stream().map(UserVmVO::getId).collect(Collectors.toList());
392+
if (vmIds.isEmpty()) {
393+
sb.and("instanceIdNull", sb.entity().getInstanceId(), SearchCriteria.Op.NULL);
394+
} else {
395+
sb.and().op("instanceIdNull", sb.entity().getInstanceId(), SearchCriteria.Op.NULL);
396+
sb.or("instanceIds", sb.entity().getInstanceId(), SearchCriteria.Op.IN);
397+
sb.cp();
398+
}
399+
}
400+
344401
SearchCriteria<VolumeVO> sc = sb.create();
402+
accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
345403
if (CollectionUtils.isNotEmpty(ids)) {
346404
sc.setParameters("idIN", ids.toArray());
347405
}
@@ -354,8 +412,18 @@ protected Pair<List<VolumeVO>, Integer> searchForVolumesInternal(ListVolumesUsag
354412
ssc.addOr("state", SearchCriteria.Op.EQ, keyword);
355413
sc.addAnd("name", SearchCriteria.Op.SC, ssc);
356414
}
415+
if (!shouldListSystemVmVolumes && CollectionUtils.isNotEmpty(vmIds)) {
416+
sc.setParameters("instanceIds", vmIds.toArray());
417+
}
357418

358-
return volumeDao.searchAndCount(sc, searchFilter);
419+
Pair<List<VolumeVO>, Integer> uniqueVolumePair = volumeDao.searchAndCount(sc, searchFilter);
420+
Integer count = uniqueVolumePair.second();
421+
if (count == 0) {
422+
return new Pair<>(new ArrayList<>(), count);
423+
}
424+
List<Long> volumeIds = uniqueVolumePair.first().stream().map(VolumeVO::getId).collect(Collectors.toList());
425+
List<VolumeVO> volumes = volumeDao.listByIds(volumeIds);
426+
return new Pair<>(volumes, count);
359427
}
360428

361429
/**

0 commit comments

Comments
 (0)