From f58e1f626562778a5491a6bad79b18b3962a6c38 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Fri, 15 Feb 2019 01:09:37 +0000 Subject: mantis 8479: deep change DeRezObjects(..) doing independent permitions checks per action. m_useTrashOnDelete should now work except if god deletes, but still not recomended --- .../Scenes/AsyncSceneObjectGroupDeleter.cs | 12 +- OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 162 +++++++++------------ 2 files changed, 71 insertions(+), 103 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs b/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs index 7509686..eae6d6f 100644 --- a/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs +++ b/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs @@ -94,19 +94,15 @@ namespace OpenSim.Region.Framework.Scenes m_inventoryDeletes.Enqueue(dtis); } - if (Enabled) - lock (m_inventoryTicker) - m_inventoryTicker.Start(); - - // Visually remove it, even if it isnt really gone yet. This means that if we crash before the object - // has gone to inventory, it will reappear in the region again on restart instead of being lost. - // This is not ideal since the object will still be available for manipulation when it should be, but it's - // better than losing the object for now. if (permissionToDelete) { foreach (SceneObjectGroup g in objectGroups) g.DeleteGroupFromScene(false); } + + if (Enabled) + lock (m_inventoryTicker) + m_inventoryTicker.Start(); } private void InventoryRunDeleteTimer(object sender, ElapsedEventArgs e) diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index e6e0354..6450c8b 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -2110,7 +2110,7 @@ namespace OpenSim.Region.Framework.Scenes // build a list of eligible objects List deleteIDs = new List(); List deleteGroups = new List(); - List takeGroups = new List(); + List takeCopyGroups = new List(); List takeDeleteGroups = new List(); ScenePresence sp = null; @@ -2119,11 +2119,10 @@ namespace OpenSim.Region.Framework.Scenes else if(action != DeRezAction.Return) return; // only Return can be called without a client - // Start with true for both, then remove the flags if objects - // that we can't derez are part of the selection - bool permissionToTake = true; - bool permissionToTakeCopy = true; - bool permissionToDelete = true; + // this is not as 0.8x code + // 0.8x did refuse all operation is not allowed on all objects + // this will do it on allowed objects + // current viewers only ask if all allowed foreach (uint localID in localIDs) { @@ -2136,8 +2135,8 @@ namespace OpenSim.Region.Framework.Scenes continue; } - // Already deleted by someone else - if (part.ParentGroup.IsDeleted) + SceneObjectGroup grp = part.ParentGroup; + if (grp == null || grp.IsDeleted) { //Client still thinks the object exists, kill it deleteIDs.Add(localID); @@ -2145,128 +2144,101 @@ namespace OpenSim.Region.Framework.Scenes } // Can't delete child prims - if (part != part.ParentGroup.RootPart) + if (part != grp.RootPart) continue; - SceneObjectGroup grp = part.ParentGroup; if (grp.IsAttachment) - continue; + { + if(!sp.IsGod || action != DeRezAction.Return || action != DeRezAction.Delete) + continue; + // this may break the attachment, but its a security action + // viewers don't allow it anyways + } // If child prims have invalid perms, fix them grp.AdjustChildPrimPermissions(false); - if (remoteClient == null) + switch (action) { - // Autoreturn has a null client. Nothing else does. So - // allow only returns - if (action != DeRezAction.Return) + case DeRezAction.SaveToExistingUserInventoryItem: { - m_log.WarnFormat( - "[AGENT INVENTORY]: Ignoring attempt to {0} {1} {2} without a client", - action, grp.Name, grp.UUID); - return; + if (Permissions.CanTakeCopyObject(grp, sp)) + takeCopyGroups.Add(grp); + break; } - permissionToTakeCopy = false; - } - else - { - if (action == DeRezAction.TakeCopy) + case DeRezAction.TakeCopy: { - if (!Permissions.CanTakeCopyObject(grp, sp)) - permissionToTakeCopy = false; + if (Permissions.CanTakeCopyObject(grp, sp)) + takeCopyGroups.Add(grp); + break; } - else + + case DeRezAction.Take: { - permissionToTakeCopy = false; + if (Permissions.CanTakeObject(grp, sp)) + takeDeleteGroups.Add(grp); + break; } - if (!Permissions.CanTakeObject(grp, sp)) - permissionToTake = false; - - if (!Permissions.CanDeleteObject(grp, remoteClient)) - permissionToDelete = false; - } - - // 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 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) + case DeRezAction.GodTakeCopy: { - remoteClient.SendAlertMessage("You don't have permission to take the object"); - return; + if((remoteClient != null) && Permissions.IsGod(remoteClient.AgentId)) + takeCopyGroups.Add(grp); + break; } - permissionToTake = true; - // Don't delete - permissionToDelete = false; - } - - if (action == DeRezAction.Return) - { - if (remoteClient != null) + case DeRezAction.Delete: { - if (Permissions.CanReturnObjects( - null, - remoteClient, - new List() {grp})) + if (Permissions.CanDeleteObject(grp, remoteClient)) { - permissionToTake = true; - permissionToDelete = true; - if(AddToReturns) - AddReturn(grp.OwnerID == grp.GroupID ? grp.LastOwnerID : grp.OwnerID, grp.Name, grp.AbsolutePosition, - "parcel owner return"); + if(m_useTrashOnDelete || (sp.IsGod && grp.OwnerID != sp.UUID)) + takeDeleteGroups.Add(grp); + else + deleteGroups.Add(grp); } + break; } - else // Auto return passes through here with null agent + + case DeRezAction.Return: { - permissionToTake = true; - permissionToDelete = true; + if (remoteClient != null) + { + if (Permissions.CanReturnObjects( null, remoteClient, new List() {grp})) + { + takeDeleteGroups.Add(grp); + if (AddToReturns) + AddReturn(grp.OwnerID == grp.GroupID ? grp.LastOwnerID : grp.OwnerID, grp.Name, grp.AbsolutePosition, + "parcel owner return"); + } + } + else // Auto return passes through here with null agent + { + takeDeleteGroups.Add(grp); + } + break; } - } - if (permissionToDelete) - { - if (permissionToTake) - takeDeleteGroups.Add(grp); - else - deleteGroups.Add(grp); - deleteIDs.Add(grp.LocalId); + default: + break; } - else if(permissionToTake) - takeGroups.Add(grp); } - SendKillObject(deleteIDs); + if(deleteIDs.Count > 0) + SendKillObject(deleteIDs); if (takeDeleteGroups.Count > 0) { - m_asyncSceneObjectDeleter.DeleteToInventory( - action, destinationID, takeDeleteGroups, remoteClient, - true); + m_asyncSceneObjectDeleter.DeleteToInventory(action, destinationID, takeDeleteGroups, + remoteClient, true); } - if (takeGroups.Count > 0) + + if (takeCopyGroups.Count > 0) { - m_asyncSceneObjectDeleter.DeleteToInventory( - action, destinationID, takeGroups, remoteClient, - false); + m_asyncSceneObjectDeleter.DeleteToInventory(action, destinationID, takeCopyGroups, + remoteClient, false); } + if (deleteGroups.Count > 0) { foreach (SceneObjectGroup g in deleteGroups) -- cgit v1.1