Skip to content

Commit 21d03bb

Browse files
shwstpprdhslove
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 efa232b commit 21d03bb

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;
@@ -102,6 +101,7 @@
102101
import com.cloud.capacity.dao.CapacityDao;
103102
import com.cloud.capacity.dao.CapacityDaoImpl;
104103
import com.cloud.cluster.dao.ManagementServerHostDao;
104+
import com.cloud.dc.ClusterVO;
105105
import com.cloud.dc.DataCenter;
106106
import com.cloud.dc.dao.ClusterDao;
107107
import com.cloud.dc.dao.DataCenterDao;
@@ -114,6 +114,7 @@
114114
import com.cloud.host.dao.HostDao;
115115
import com.cloud.network.router.VirtualRouter;
116116
import com.cloud.org.Cluster;
117+
import com.cloud.projects.Project;
117118
import com.cloud.server.DbStatsCollection;
118119
import com.cloud.server.ManagementServerHostStats;
119120
import com.cloud.server.StatsCollector;
@@ -126,6 +127,7 @@
126127
import com.cloud.user.Account;
127128
import com.cloud.user.AccountManager;
128129
import com.cloud.utils.Pair;
130+
import com.cloud.utils.Ternary;
129131
import com.cloud.utils.db.DbProperties;
130132
import com.cloud.utils.db.DbUtil;
131133
import com.cloud.utils.db.Filter;
@@ -188,6 +190,10 @@ public class MetricsServiceImpl extends MutualExclusiveIdsManagerBase implements
188190

189191
private static Gson gson = new Gson();
190192

193+
private final List<Account.Type> AccountTypesWithRecursiveUsageAccess = Arrays.asList(
194+
Account.Type.ADMIN, Account.Type.DOMAIN_ADMIN, Account.Type.READ_ONLY_ADMIN
195+
);
196+
191197
protected MetricsServiceImpl() {
192198
super();
193199
}
@@ -249,17 +255,30 @@ public ListResponse<VolumeMetricsStatsResponse> searchForVolumeMetricsStats(List
249255
* @return the list of VMs.
250256
*/
251257
protected Pair<List<UserVmVO>, Integer> searchForUserVmsInternal(ListVMsUsageHistoryCmd cmd) {
258+
final Long id = cmd.getId();
259+
Account caller = CallContext.current().getCallingAccount();
260+
List<Long> permittedAccounts = new ArrayList<>();
261+
boolean recursive = AccountTypesWithRecursiveUsageAccess.contains(caller.getType());
262+
Ternary<Long, Boolean, Project.ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<>(null, recursive, null);
263+
accountMgr.buildACLSearchParameters(caller, id, null, null, permittedAccounts, domainIdRecursiveListProject, true, false);
264+
Long domainId = domainIdRecursiveListProject.first();
265+
Boolean isRecursive = domainIdRecursiveListProject.second();
266+
Project.ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third();
267+
252268
Filter searchFilter = new Filter(UserVmVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal());
253269
List<Long> ids = getIdsListFromCmd(cmd.getId(), cmd.getIds());
254270
String name = cmd.getName();
255271
String keyword = cmd.getKeyword();
256272

257273
SearchBuilder<UserVmVO> sb = userVmDao.createSearchBuilder();
274+
sb.select(null, SearchCriteria.Func.DISTINCT, sb.entity().getId()); // select distinct
275+
accountMgr.buildACLSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
258276
sb.and("idIN", sb.entity().getId(), SearchCriteria.Op.IN);
259277
sb.and("displayName", sb.entity().getDisplayName(), SearchCriteria.Op.LIKE);
260278
sb.and("state", sb.entity().getState(), SearchCriteria.Op.EQ);
261279

262280
SearchCriteria<UserVmVO> sc = sb.create();
281+
accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
263282
if (CollectionUtils.isNotEmpty(ids)) {
264283
sc.setParameters("idIN", ids.toArray());
265284
}
@@ -274,7 +293,14 @@ protected Pair<List<UserVmVO>, Integer> searchForUserVmsInternal(ListVMsUsageHis
274293
sc.addAnd("displayName", SearchCriteria.Op.SC, ssc);
275294
}
276295

277-
return userVmDao.searchAndCount(sc, searchFilter);
296+
Pair<List<UserVmVO>, Integer> uniqueVmPair = userVmDao.searchAndCount(sc, searchFilter);
297+
Integer count = uniqueVmPair.second();
298+
if (count == 0) {
299+
return new Pair<>(new ArrayList<>(), count);
300+
}
301+
List<Long> vmIds = uniqueVmPair.first().stream().map(UserVmVO::getId).collect(Collectors.toList());
302+
List<UserVmVO> vms = userVmDao.listByIds(vmIds);
303+
return new Pair<>(vms, count);
278304
}
279305

280306
/**
@@ -336,17 +362,49 @@ protected Map<Long,List<VmStatsVO>> searchForVmMetricsStatsInternal(Date startDa
336362
* @return the list of VMs.
337363
*/
338364
protected Pair<List<VolumeVO>, Integer> searchForVolumesInternal(ListVolumesUsageHistoryCmd cmd) {
365+
final Long id = cmd.getId();
366+
Account caller = CallContext.current().getCallingAccount();
367+
List<Long> permittedAccounts = new ArrayList<>();
368+
boolean recursive = AccountTypesWithRecursiveUsageAccess.contains(caller.getType());
369+
Ternary<Long, Boolean, Project.ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<>(null, recursive, null);
370+
accountMgr.buildACLSearchParameters(caller, id, null, null, permittedAccounts, domainIdRecursiveListProject, true, false);
371+
Long domainId = domainIdRecursiveListProject.first();
372+
Boolean isRecursive = domainIdRecursiveListProject.second();
373+
Project.ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third();
374+
339375
Filter searchFilter = new Filter(VolumeVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal());
340376
List<Long> ids = getIdsListFromCmd(cmd.getId(), cmd.getIds());
341377
String name = cmd.getName();
342378
String keyword = cmd.getKeyword();
343379

344380
SearchBuilder<VolumeVO> sb = volumeDao.createSearchBuilder();
381+
sb.select(null, SearchCriteria.Func.DISTINCT, sb.entity().getId()); // select distinct
382+
accountMgr.buildACLSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
345383
sb.and("idIN", sb.entity().getId(), SearchCriteria.Op.IN);
346384
sb.and("name", sb.entity().getName(), SearchCriteria.Op.EQ);
347385
sb.and("state", sb.entity().getState(), SearchCriteria.Op.EQ);
348386

387+
boolean shouldListSystemVmVolumes = accountMgr.isRootAdmin(CallContext.current().getCallingAccountId());
388+
List<Long> vmIds = new ArrayList<>();
389+
if (!shouldListSystemVmVolumes) {
390+
SearchBuilder<UserVmVO> vmSearch = userVmDao.createSearchBuilder();
391+
vmSearch.select(null, SearchCriteria.Func.DISTINCT, vmSearch.entity().getId());
392+
accountMgr.buildACLSearchBuilder(vmSearch, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
393+
SearchCriteria<UserVmVO> vmSc = vmSearch.create();
394+
accountMgr.buildACLSearchCriteria(vmSc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
395+
List<UserVmVO> vms = userVmDao.search(vmSc, null);
396+
vmIds = vms.stream().map(UserVmVO::getId).collect(Collectors.toList());
397+
if (vmIds.isEmpty()) {
398+
sb.and("instanceIdNull", sb.entity().getInstanceId(), SearchCriteria.Op.NULL);
399+
} else {
400+
sb.and().op("instanceIdNull", sb.entity().getInstanceId(), SearchCriteria.Op.NULL);
401+
sb.or("instanceIds", sb.entity().getInstanceId(), SearchCriteria.Op.IN);
402+
sb.cp();
403+
}
404+
}
405+
349406
SearchCriteria<VolumeVO> sc = sb.create();
407+
accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
350408
if (CollectionUtils.isNotEmpty(ids)) {
351409
sc.setParameters("idIN", ids.toArray());
352410
}
@@ -359,8 +417,18 @@ protected Pair<List<VolumeVO>, Integer> searchForVolumesInternal(ListVolumesUsag
359417
ssc.addOr("state", SearchCriteria.Op.EQ, keyword);
360418
sc.addAnd("name", SearchCriteria.Op.SC, ssc);
361419
}
420+
if (!shouldListSystemVmVolumes && CollectionUtils.isNotEmpty(vmIds)) {
421+
sc.setParameters("instanceIds", vmIds.toArray());
422+
}
362423

363-
return volumeDao.searchAndCount(sc, searchFilter);
424+
Pair<List<VolumeVO>, Integer> uniqueVolumePair = volumeDao.searchAndCount(sc, searchFilter);
425+
Integer count = uniqueVolumePair.second();
426+
if (count == 0) {
427+
return new Pair<>(new ArrayList<>(), count);
428+
}
429+
List<Long> volumeIds = uniqueVolumePair.first().stream().map(VolumeVO::getId).collect(Collectors.toList());
430+
List<VolumeVO> volumes = volumeDao.listByIds(volumeIds);
431+
return new Pair<>(volumes, count);
364432
}
365433

366434
/**

0 commit comments

Comments
 (0)