From ff49a21eca5b084bf0df71f69bce98db0b2f0094 Mon Sep 17 00:00:00 2001 From: Melanie Date: Sat, 9 Oct 2010 01:02:57 +0200 Subject: Fix a security relevant issue with take / take copy --- OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 110 ++++++++++++--------- 1 file changed, 62 insertions(+), 48 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 6d7f984..9b5459d 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -1695,6 +1695,7 @@ namespace OpenSim.Region.Framework.Scenes // build a list of eligible objects List deleteIDs = new List(); List deleteGroups = new List(); + List takeGroups = new List(); // Start with true for both, then remove the flags if objects // that we can't derez are part of the selection @@ -1727,9 +1728,6 @@ namespace OpenSim.Region.Framework.Scenes SceneObjectGroup grp = part.ParentGroup; - deleteGroups.Add(grp); - deleteIDs.Add(grp.LocalId); - if (remoteClient == null) { // Autoreturn has a null client. Nothing else does. So @@ -1756,73 +1754,89 @@ namespace OpenSim.Region.Framework.Scenes if (!Permissions.CanDeleteObject(grp.UUID, remoteClient.AgentId)) permissionToDelete = false; } - } - // Handle god perms - if ((remoteClient != null) && Permissions.IsGod(remoteClient.AgentId)) - { - permissionToTake = true; - permissionToTakeCopy = true; - permissionToDelete = true; - } + // Handle god perms + if ((remoteClient != null) && Permissions.IsGod(remoteClient.AgentId)) + { + permissionToTake = true; + permissionToTakeCopy = true; + permissionToDelete = true; + } - // If we're re-saving, we don't even want to delete - if (action == DeRezAction.SaveToExistingUserInventoryItem) - permissionToDelete = false; + // If we're re-saving, we don't even want to delete + if (action == DeRezAction.SaveToExistingUserInventoryItem) + permissionToDelete = false; - // if we want to take a copy, we also don't want to delete - // Note: after this point, the permissionToTakeCopy flag - // becomes irrelevant. It already includes the permissionToTake - // permission and after excluding no copy items here, we can - // just use that. - if (action == DeRezAction.TakeCopy) - { - // If we don't have permission, stop right here - if (!permissionToTakeCopy) - return; + // if we want to take a copy, we also don't want to delete + // Note: after this point, the permissionToTakeCopy flag + // becomes irrelevant. It already includes the permissionToTake + // permission and after excluding no copy items here, we can + // just use that. + if (action == DeRezAction.TakeCopy) + { + // If we don't have permission, stop right here + if (!permissionToTakeCopy) + return; - permissionToTake = true; - // Don't delete - permissionToDelete = false; - } + permissionToTake = true; + // Don't delete + permissionToDelete = false; + } - if (action == DeRezAction.Return) - { - if (remoteClient != null) + if (action == DeRezAction.Return) { - if (Permissions.CanReturnObjects( - null, - remoteClient.AgentId, - deleteGroups)) + if (remoteClient != null) + { + if (Permissions.CanReturnObjects( + null, + remoteClient.AgentId, + deleteGroups)) + { + permissionToTake = true; + permissionToDelete = true; + + AddReturn(grp.OwnerID, grp.Name, grp.AbsolutePosition, "parcel owner return"); + } + } + else // Auto return passes through here with null agent { permissionToTake = true; permissionToDelete = true; + } - foreach (SceneObjectGroup g in deleteGroups) - { - AddReturn(g.OwnerID, g.Name, g.AbsolutePosition, "parcel owner return"); - } + if (permissionToTake && (!permissionToDelete)) + takeGroups.Add(grp); + + if (permissionToDelete) + { + if (permissionToTake) + deleteGroups.Add(grp); + deleteIDs.Add(grp.LocalId); } } - else // Auto return passes through here with null agent - { - permissionToTake = true; - permissionToDelete = true; - } } SendKillObject(deleteIDs); - if (permissionToTake) + if (deleteGroups.Count > 0) { + foreach (SceneObjectGroup g in deleteGroups) + deleteIDs.Remove(g.LocalId); + m_asyncSceneObjectDeleter.DeleteToInventory( action, destinationID, deleteGroups, remoteClient, - permissionToDelete); + true); + } + if (takeGroups.Count > 0) + { + m_asyncSceneObjectDeleter.DeleteToInventory( + action, destinationID, takeGroups, remoteClient, + false); } - else if (permissionToDelete) + if (deleteIDs.Count > 0) { foreach (SceneObjectGroup g in deleteGroups) - DeleteSceneObject(g, false); + DeleteSceneObject(g, true); } } -- cgit v1.1