mantis 8479: deep change DeRezObjects(..) doing independent permitions checks per action. m_useTrashOnDelete should now work except if god deletes, but still not recomended

0.9.1.0-post-fixes
UbitUmarov 2019-02-15 01:09:37 +00:00
parent 52947b6280
commit f58e1f6265
2 changed files with 78 additions and 110 deletions

View File

@ -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)

View File

@ -2110,7 +2110,7 @@ namespace OpenSim.Region.Framework.Scenes
// build a list of eligible objects
List<uint> deleteIDs = new List<uint>();
List<SceneObjectGroup> deleteGroups = new List<SceneObjectGroup>();
List<SceneObjectGroup> takeGroups = new List<SceneObjectGroup>();
List<SceneObjectGroup> takeCopyGroups = new List<SceneObjectGroup>();
List<SceneObjectGroup> takeDeleteGroups = new List<SceneObjectGroup>();
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,90 +2144,69 @@ 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)
{
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
case DeRezAction.TakeCopy:
{
if (action == DeRezAction.TakeCopy)
{
if (!Permissions.CanTakeCopyObject(grp, sp))
permissionToTakeCopy = false;
}
else
{
permissionToTakeCopy = false;
}
if (!Permissions.CanTakeObject(grp, sp))
permissionToTake = false;
if (!Permissions.CanDeleteObject(grp, remoteClient))
permissionToDelete = false;
if (Permissions.CanTakeCopyObject(grp, sp))
takeCopyGroups.Add(grp);
break;
}
// Handle god perms
case DeRezAction.Take:
{
if (Permissions.CanTakeObject(grp, sp))
takeDeleteGroups.Add(grp);
break;
}
case DeRezAction.GodTakeCopy:
{
if((remoteClient != null) && Permissions.IsGod(remoteClient.AgentId))
{
permissionToTake = true;
permissionToTakeCopy = true;
permissionToDelete = true;
takeCopyGroups.Add(grp);
break;
}
// 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)
case DeRezAction.Delete:
{
// If we don't have permission, stop right here
if (!permissionToTakeCopy)
if (Permissions.CanDeleteObject(grp, remoteClient))
{
remoteClient.SendAlertMessage("You don't have permission to take the object");
return;
if(m_useTrashOnDelete || (sp.IsGod && grp.OwnerID != sp.UUID))
takeDeleteGroups.Add(grp);
else
deleteGroups.Add(grp);
}
break;
}
permissionToTake = true;
// Don't delete
permissionToDelete = false;
}
if (action == DeRezAction.Return)
case DeRezAction.Return:
{
if (remoteClient != null)
{
if (Permissions.CanReturnObjects(
null,
remoteClient,
new List<SceneObjectGroup>() {grp}))
if (Permissions.CanReturnObjects( null, remoteClient, new List<SceneObjectGroup>() {grp}))
{
permissionToTake = true;
permissionToDelete = true;
takeDeleteGroups.Add(grp);
if (AddToReturns)
AddReturn(grp.OwnerID == grp.GroupID ? grp.LastOwnerID : grp.OwnerID, grp.Name, grp.AbsolutePosition,
"parcel owner return");
@ -2236,37 +2214,31 @@ namespace OpenSim.Region.Framework.Scenes
}
else // Auto return passes through here with null agent
{
permissionToTake = true;
permissionToDelete = true;
}
}
if (permissionToDelete)
{
if (permissionToTake)
takeDeleteGroups.Add(grp);
else
deleteGroups.Add(grp);
deleteIDs.Add(grp.LocalId);
}
else if(permissionToTake)
takeGroups.Add(grp);
break;
}
default:
break;
}
}
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)