From d7c5382c58a87b68d356696349828ef44fdf80e2 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Thu, 1 May 2014 12:12:52 -0700 Subject: [PATCH] CLOUDSTACK-6535: IAM:MS:API createVMSnapshot doesn't preserve access rights. --- .../api/command/admin/vm/AddNicToVMCmdByAdmin.java | 3 ++- .../command/admin/volume/CreateVolumeCmdByAdmin.java | 5 ++++- .../api/command/user/volume/CreateVolumeCmd.java | 7 +++++-- .../com/cloud/api/dispatch/ParamProcessWorker.java | 12 ++++++++++++ 4 files changed, 23 insertions(+), 4 deletions(-) diff --git a/api/src/org/apache/cloudstack/api/command/admin/vm/AddNicToVMCmdByAdmin.java b/api/src/org/apache/cloudstack/api/command/admin/vm/AddNicToVMCmdByAdmin.java index ee6d0e78e09..3dd22c15adb 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/vm/AddNicToVMCmdByAdmin.java +++ b/api/src/org/apache/cloudstack/api/command/admin/vm/AddNicToVMCmdByAdmin.java @@ -31,8 +31,9 @@ import org.apache.cloudstack.api.response.UserVmResponse; import org.apache.cloudstack.context.CallContext; import com.cloud.uservm.UserVm; +import com.cloud.vm.VirtualMachine; -@APICommand(name = "addNicToVirtualMachine", description = "Adds VM to specified network by creating a NIC", responseObject = UserVmResponse.class, responseView = ResponseView.Full, +@APICommand(name = "addNicToVirtualMachine", description = "Adds VM to specified network by creating a NIC", responseObject = UserVmResponse.class, responseView = ResponseView.Full, entityType = {VirtualMachine.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = true) public class AddNicToVMCmdByAdmin extends AddNicToVMCmd { public static final Logger s_logger = Logger.getLogger(AddNicToVMCmdByAdmin.class); diff --git a/api/src/org/apache/cloudstack/api/command/admin/volume/CreateVolumeCmdByAdmin.java b/api/src/org/apache/cloudstack/api/command/admin/volume/CreateVolumeCmdByAdmin.java index 5df7481497c..8ff3993cd57 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/volume/CreateVolumeCmdByAdmin.java +++ b/api/src/org/apache/cloudstack/api/command/admin/volume/CreateVolumeCmdByAdmin.java @@ -28,8 +28,11 @@ import org.apache.cloudstack.context.CallContext; import com.cloud.storage.Snapshot; import com.cloud.storage.Volume; +import com.cloud.vm.VirtualMachine; -@APICommand(name = "createVolume", responseObject = VolumeResponse.class, description = "Creates a disk volume from a disk offering. This disk volume must still be attached to a virtual machine to make use of it.", responseView = ResponseView.Full) +@APICommand(name = "createVolume", responseObject = VolumeResponse.class, description = "Creates a disk volume from a disk offering. This disk volume must still be attached to a virtual machine to make use of it.", responseView = ResponseView.Full, entityType = { + Volume.class, VirtualMachine.class}, + requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class CreateVolumeCmdByAdmin extends CreateVolumeCmd { public static final Logger s_logger = Logger.getLogger(CreateVolumeCmdByAdmin.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/user/volume/CreateVolumeCmd.java b/api/src/org/apache/cloudstack/api/command/user/volume/CreateVolumeCmd.java index 0fa540cb0d2..90c1a165abd 100644 --- a/api/src/org/apache/cloudstack/api/command/user/volume/CreateVolumeCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/volume/CreateVolumeCmd.java @@ -19,6 +19,7 @@ package org.apache.cloudstack.api.command.user.volume; import org.apache.log4j.Logger; import org.apache.cloudstack.acl.RoleType; +import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.api.ACL; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiCommandJobType; @@ -42,8 +43,10 @@ import com.cloud.event.EventTypes; import com.cloud.exception.ResourceAllocationException; import com.cloud.storage.Snapshot; import com.cloud.storage.Volume; +import com.cloud.vm.VirtualMachine; -@APICommand(name = "createVolume", responseObject = VolumeResponse.class, description = "Creates a disk volume from a disk offering. This disk volume must still be attached to a virtual machine to make use of it.", responseView = ResponseView.Restricted, entityType = {Volume.class}, +@APICommand(name = "createVolume", responseObject = VolumeResponse.class, description = "Creates a disk volume from a disk offering. This disk volume must still be attached to a virtual machine to make use of it.", responseView = ResponseView.Restricted, entityType = { + Volume.class, VirtualMachine.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class CreateVolumeCmd extends BaseAsyncCreateCustomIdCmd { public static final Logger s_logger = Logger.getLogger(CreateVolumeCmd.class.getName()); @@ -103,7 +106,7 @@ public class CreateVolumeCmd extends BaseAsyncCreateCustomIdCmd { @Parameter(name = ApiConstants.DISPLAY_VOLUME, type = CommandType.BOOLEAN, description = "an optional field, whether to display the volume to the end user or not.", authorized = {RoleType.Admin}) private Boolean displayVolume; - @ACL + @ACL(accessType = AccessType.OperateEntry) @Parameter(name = ApiConstants.VIRTUAL_MACHINE_ID, type = CommandType.UUID, entityType = UserVmResponse.class, diff --git a/server/src/com/cloud/api/dispatch/ParamProcessWorker.java b/server/src/com/cloud/api/dispatch/ParamProcessWorker.java index 2fd772137c2..d8626606410 100644 --- a/server/src/com/cloud/api/dispatch/ParamProcessWorker.java +++ b/server/src/com/cloud/api/dispatch/ParamProcessWorker.java @@ -42,6 +42,7 @@ import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.api.ACL; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiErrorCode; +import org.apache.cloudstack.api.BaseAsyncCreateCmd; import org.apache.cloudstack.api.BaseCmd; import org.apache.cloudstack.api.BaseCmd.CommandType; import org.apache.cloudstack.api.EntityReference; @@ -227,6 +228,17 @@ public class ParamProcessWorker implements DispatchWorker { owner = caller; } + if (cmd instanceof BaseAsyncCreateCmd) { + if (owner.getId() != caller.getId()) { + // mimic impersonation either by passing (account, domainId) or through derived owner from other api parameters + // in this case, we should check access using the owner + _accountMgr.checkAccess(caller, null, owner); + } + } else { + // check access using the caller for other operational cmds + owner = caller; + } + APICommand commandAnnotation = cmd.getClass().getAnnotation(APICommand.class); String apiName = commandAnnotation != null ? commandAnnotation.name() : null;