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); 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) if (permissionToDelete)
{ {
foreach (SceneObjectGroup g in objectGroups) foreach (SceneObjectGroup g in objectGroups)
g.DeleteGroupFromScene(false); g.DeleteGroupFromScene(false);
} }
if (Enabled)
lock (m_inventoryTicker)
m_inventoryTicker.Start();
} }
private void InventoryRunDeleteTimer(object sender, ElapsedEventArgs e) private void InventoryRunDeleteTimer(object sender, ElapsedEventArgs e)

View File

@ -2110,7 +2110,7 @@ namespace OpenSim.Region.Framework.Scenes
// build a list of eligible objects // build a list of eligible objects
List<uint> deleteIDs = new List<uint>(); List<uint> deleteIDs = new List<uint>();
List<SceneObjectGroup> deleteGroups = new List<SceneObjectGroup>(); List<SceneObjectGroup> deleteGroups = new List<SceneObjectGroup>();
List<SceneObjectGroup> takeGroups = new List<SceneObjectGroup>(); List<SceneObjectGroup> takeCopyGroups = new List<SceneObjectGroup>();
List<SceneObjectGroup> takeDeleteGroups = new List<SceneObjectGroup>(); List<SceneObjectGroup> takeDeleteGroups = new List<SceneObjectGroup>();
ScenePresence sp = null; ScenePresence sp = null;
@ -2119,11 +2119,10 @@ namespace OpenSim.Region.Framework.Scenes
else if(action != DeRezAction.Return) else if(action != DeRezAction.Return)
return; // only Return can be called without a client return; // only Return can be called without a client
// Start with true for both, then remove the flags if objects // this is not as 0.8x code
// that we can't derez are part of the selection // 0.8x did refuse all operation is not allowed on all objects
bool permissionToTake = true; // this will do it on allowed objects
bool permissionToTakeCopy = true; // current viewers only ask if all allowed
bool permissionToDelete = true;
foreach (uint localID in localIDs) foreach (uint localID in localIDs)
{ {
@ -2136,8 +2135,8 @@ namespace OpenSim.Region.Framework.Scenes
continue; continue;
} }
// Already deleted by someone else SceneObjectGroup grp = part.ParentGroup;
if (part.ParentGroup.IsDeleted) if (grp == null || grp.IsDeleted)
{ {
//Client still thinks the object exists, kill it //Client still thinks the object exists, kill it
deleteIDs.Add(localID); deleteIDs.Add(localID);
@ -2145,128 +2144,101 @@ namespace OpenSim.Region.Framework.Scenes
} }
// Can't delete child prims // Can't delete child prims
if (part != part.ParentGroup.RootPart) if (part != grp.RootPart)
continue; continue;
SceneObjectGroup grp = part.ParentGroup;
if (grp.IsAttachment) 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 // If child prims have invalid perms, fix them
grp.AdjustChildPrimPermissions(false); grp.AdjustChildPrimPermissions(false);
if (remoteClient == null) switch (action)
{ {
// Autoreturn has a null client. Nothing else does. So case DeRezAction.SaveToExistingUserInventoryItem:
// allow only returns
if (action != DeRezAction.Return)
{ {
m_log.WarnFormat( if (Permissions.CanTakeCopyObject(grp, sp))
"[AGENT INVENTORY]: Ignoring attempt to {0} {1} {2} without a client", takeCopyGroups.Add(grp);
action, grp.Name, grp.UUID); break;
return;
} }
permissionToTakeCopy = false; case DeRezAction.TakeCopy:
}
else
{
if (action == DeRezAction.TakeCopy)
{ {
if (!Permissions.CanTakeCopyObject(grp, sp)) if (Permissions.CanTakeCopyObject(grp, sp))
permissionToTakeCopy = false; takeCopyGroups.Add(grp);
} break;
else
{
permissionToTakeCopy = false;
}
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)
{
remoteClient.SendAlertMessage("You don't have permission to take the object");
return;
} }
permissionToTake = true; case DeRezAction.Take:
// Don't delete
permissionToDelete = false;
}
if (action == DeRezAction.Return)
{
if (remoteClient != null)
{ {
if (Permissions.CanReturnObjects( if (Permissions.CanTakeObject(grp, sp))
null, takeDeleteGroups.Add(grp);
remoteClient, break;
new List<SceneObjectGroup>() {grp})) }
case DeRezAction.GodTakeCopy:
{
if((remoteClient != null) && Permissions.IsGod(remoteClient.AgentId))
takeCopyGroups.Add(grp);
break;
}
case DeRezAction.Delete:
{
if (Permissions.CanDeleteObject(grp, remoteClient))
{ {
permissionToTake = true; if(m_useTrashOnDelete || (sp.IsGod && grp.OwnerID != sp.UUID))
permissionToDelete = true; takeDeleteGroups.Add(grp);
if(AddToReturns) else
AddReturn(grp.OwnerID == grp.GroupID ? grp.LastOwnerID : grp.OwnerID, grp.Name, grp.AbsolutePosition, deleteGroups.Add(grp);
"parcel owner return");
} }
break;
} }
else // Auto return passes through here with null agent
{
permissionToTake = true;
permissionToDelete = true;
}
}
if (permissionToDelete) case DeRezAction.Return:
{ {
if (permissionToTake) if (remoteClient != null)
takeDeleteGroups.Add(grp); {
else if (Permissions.CanReturnObjects( null, remoteClient, new List<SceneObjectGroup>() {grp}))
deleteGroups.Add(grp); {
deleteIDs.Add(grp.LocalId); 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;
}
default:
break;
} }
else if(permissionToTake)
takeGroups.Add(grp);
} }
SendKillObject(deleteIDs); if(deleteIDs.Count > 0)
SendKillObject(deleteIDs);
if (takeDeleteGroups.Count > 0) if (takeDeleteGroups.Count > 0)
{ {
m_asyncSceneObjectDeleter.DeleteToInventory( m_asyncSceneObjectDeleter.DeleteToInventory(action, destinationID, takeDeleteGroups,
action, destinationID, takeDeleteGroups, remoteClient, remoteClient, true);
true);
} }
if (takeGroups.Count > 0)
if (takeCopyGroups.Count > 0)
{ {
m_asyncSceneObjectDeleter.DeleteToInventory( m_asyncSceneObjectDeleter.DeleteToInventory(action, destinationID, takeCopyGroups,
action, destinationID, takeGroups, remoteClient, remoteClient, false);
false);
} }
if (deleteGroups.Count > 0) if (deleteGroups.Count > 0)
{ {
foreach (SceneObjectGroup g in deleteGroups) foreach (SceneObjectGroup g in deleteGroups)