From 50e318c401f69b7b3946b0a630d455bf7fe4118c Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sun, 22 Jan 2017 03:23:50 +0000 Subject: [PATCH] work around group sharing and owned permitions issues, fix a non copy objects delete issue --- .../World/Permissions/PermissionsModule.cs | 208 ++++++++++++++---- .../Framework/Scenes/Scene.Inventory.cs | 33 +-- .../Framework/Scenes/Scene.Permissions.cs | 34 ++- .../Scenes/SceneObjectGroup.Inventory.cs | 32 +-- 4 files changed, 216 insertions(+), 91 deletions(-) diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs index 890d07ab01..e16022df39 100644 --- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs +++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs @@ -267,6 +267,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions m_scene.Permissions.OnIsAdministrator += IsAdministrator; m_scene.Permissions.OnIsEstateManager += IsEstateManager; m_scene.Permissions.OnDuplicateObject += CanDuplicateObject; + m_scene.Permissions.OnDeleteObjectByIDs += CanDeleteObjectByIDs; m_scene.Permissions.OnDeleteObject += CanDeleteObject; m_scene.Permissions.OnEditObjectByIDs += CanEditObjectByIDs; m_scene.Permissions.OnEditObject += CanEditObject; @@ -674,6 +675,12 @@ namespace OpenSim.Region.CoreModules.World.Permissions PrimFlags.ObjectAnyOwner // Tells client that someone owns the object ); + const uint SHAREDMASK = (uint)( + PermissionMask.Move | + PermissionMask.Modify | + PermissionMask.Copy + ); + public uint GenerateClientFlags(SceneObjectPart task, ScenePresence sp, uint curEffectivePerms) { if(sp == null || task == null || curEffectivePerms == 0) @@ -749,20 +756,12 @@ namespace OpenSim.Region.CoreModules.World.Permissions ulong powers = 0; if(taskGroupID != UUID.Zero && GroupMemberPowers(taskGroupID, sp, ref powers)) { - if(groupdOwned) + // shared as priority over group roles + bool notShared = (grp.EffectiveGroupPerms & SHAREDMASK) == 0; + if(groupdOwned && notShared) { // object is owned by group, check role powers - if((powers & (ulong)GroupPowers.ObjectManipulate) != 0) - { - returnMask = ApplyObjectModifyMasks(grp.EffectiveOwnerPerms, objflags, unlocked); - returnMask |= - (uint)PrimFlags.ObjectGroupOwned | - (uint)PrimFlags.ObjectAnyOwner; - if((returnMask & (uint)PrimFlags.ObjectModify) != 0) - returnMask |= (uint)PrimFlags.ObjectOwnerModify; - return returnMask; - } - else + if((powers & (ulong)GroupPowers.ObjectManipulate) == 0) { // group sharing or everyone returnMask = ApplyObjectModifyMasks(grp.EffectiveGroupOrEveryOnePerms, objflags, unlocked); @@ -771,12 +770,30 @@ namespace OpenSim.Region.CoreModules.World.Permissions (uint)PrimFlags.ObjectAnyOwner; return returnMask; } + + // we may have copy without transfer + uint grpEffectiveOwnerPerms = grp.EffectiveOwnerPerms; + if((grpEffectiveOwnerPerms & (uint)PermissionMask.Transfer) == 0) + grpEffectiveOwnerPerms &= ~(uint)PermissionMask.Copy; + returnMask = ApplyObjectModifyMasks(grpEffectiveOwnerPerms, objflags, unlocked); + returnMask |= + (uint)PrimFlags.ObjectGroupOwned | + (uint)PrimFlags.ObjectAnyOwner; + if((returnMask & (uint)PrimFlags.ObjectModify) != 0) + returnMask |= (uint)PrimFlags.ObjectOwnerModify; + return returnMask; } else { // group sharing or everyone returnMask = ApplyObjectModifyMasks(grp.EffectiveGroupOrEveryOnePerms, objflags, unlocked); - if (taskOwnerID != UUID.Zero) + if(groupdOwned) + { + returnMask |= + (uint)PrimFlags.ObjectGroupOwned | + (uint)PrimFlags.ObjectAnyOwner; + } + else if (taskOwnerID != UUID.Zero) returnMask |= (uint)PrimFlags.ObjectAnyOwner; return returnMask; } @@ -886,18 +903,21 @@ namespace OpenSim.Region.CoreModules.World.Permissions return group.EffectiveOwnerPerms & lockmask; UUID sogGroupID = group.GroupID; - if (sogGroupID != UUID.Zero) + ulong powers = 0; + if (sogGroupID != UUID.Zero && GroupMemberPowers(sogGroupID, currentUser, ref powers)) { - ulong powers = 0; - if(GroupMemberPowers(sogGroupID, currentUser, ref powers)) - { - if(sogGroupID == objectOwner) - { - if((powers & (ulong)GroupPowers.ObjectManipulate) != 0) - return group.EffectiveOwnerPerms & lockmask; - } + bool Shared = (group.EffectiveGroupPerms & SHAREDMASK) != 0; + + if(Shared || sogGroupID != objectOwner) return group.EffectiveGroupOrEveryOnePerms & lockmask; - } + + if((powers & (ulong)GroupPowers.ObjectManipulate) == 0) + return group.EffectiveGroupOrEveryOnePerms & lockmask; + + uint grpEffectiveOwnerPerms = group.EffectiveOwnerPerms & lockmask; + if((grpEffectiveOwnerPerms & (uint)PermissionMask.Transfer) == 0) + grpEffectiveOwnerPerms &= ~(uint)PermissionMask.Copy; + return grpEffectiveOwnerPerms; } return group.EffectiveEveryOnePerms & lockmask; @@ -939,18 +959,21 @@ namespace OpenSim.Region.CoreModules.World.Permissions return group.EffectiveOwnerPerms & lockmask; UUID sogGroupID = group.GroupID; - if (sogGroupID != UUID.Zero) + ulong powers = 0; + if (sogGroupID != UUID.Zero && GroupMemberPowers(sogGroupID, sp, ref powers)) { - ulong powers = 0; - if(GroupMemberPowers(sogGroupID, sp, ref powers)) - { - if(sogGroupID == objectOwner) - { - if((powers & (ulong)GroupPowers.ObjectManipulate) != 0) - return group.EffectiveOwnerPerms & lockmask; - } + bool Shared = (group.EffectiveGroupPerms & SHAREDMASK) != 0; + + if(Shared || sogGroupID != objectOwner) return group.EffectiveGroupOrEveryOnePerms & lockmask; - } + + if((powers & (ulong)GroupPowers.ObjectManipulate) == 0) + return group.EffectiveGroupOrEveryOnePerms & lockmask; + + uint grpEffectiveOwnerPerms = group.EffectiveOwnerPerms & lockmask; + if((grpEffectiveOwnerPerms & (uint)PermissionMask.Transfer) == 0) + grpEffectiveOwnerPerms &= ~(uint)PermissionMask.Copy; + return grpEffectiveOwnerPerms; } return group.EffectiveEveryOnePerms & lockmask; @@ -1167,15 +1190,59 @@ namespace OpenSim.Region.CoreModules.World.Permissions if((perms & (uint)PermissionMask.Copy) == 0) return false; - if(sog.OwnerID != sp.UUID && sog.OwnerID != sog.GroupID && (perms & (uint)PermissionMask.Transfer) == 0) + if(sog.OwnerID != sp.UUID && (perms & (uint)PermissionMask.Transfer) == 0) return false; //If they can rez, they can duplicate return CanRezObject(0, sp.UUID, sog.AbsolutePosition, scene); } - private bool CanDeleteObject(UUID objectID, UUID userID, Scene scene) + private bool CanDeleteObject(SceneObjectGroup sog, ScenePresence sp) { + // ignoring locked. viewers should warn and ask for confirmation + + DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); + if (m_bypassPermissions) return m_bypassPermissionsValue; + + if (sog == null || sog.IsDeleted || sp == null || sp.IsDeleted) + return false; + + if(sog.IsAttachment) + return false; + + UUID sogOwnerID = sog.OwnerID; + UUID spID = sp.UUID; + + if(sogOwnerID == spID) + return true; + + if (sp.IsGod) + return true; + + if (IsFriendWithPerms(sog.UUID, sogOwnerID)) + return true; + + UUID sogGroupID = sog.GroupID; + if (sogGroupID != UUID.Zero) + { + ulong powers = 0; + if(GroupMemberPowers(sogGroupID, sp, ref powers)) + { + if(sogGroupID == sogOwnerID) + { + if((powers & (ulong)GroupPowers.ObjectManipulate) != 0) + return true; + } + return (sog.EffectiveGroupPerms & (uint)PermissionMask.Modify) != 0; + } + } + return false; + } + + private bool CanDeleteObjectByIDs(UUID objectID, UUID userID, Scene scene) + { + // ignoring locked. viewers should warn and ask for confirmation + DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); if (m_bypassPermissions) return m_bypassPermissionsValue; @@ -1183,11 +1250,35 @@ namespace OpenSim.Region.CoreModules.World.Permissions if (sog == null) return false; - // ignoring locked. viewers should warn and ask for confirmation - uint perms = GetObjectPermissions(userID, sog, false); - if((perms & (uint)PermissionMask.Modify) == 0) + if(sog.IsAttachment) return false; - return true; + + UUID sogOwnerID = sog.OwnerID; + + if(sogOwnerID == userID) + return true; + + if (IsAdministrator(userID)) + return true; + + if (IsFriendWithPerms(objectID, sogOwnerID)) + return true; + + UUID sogGroupID = sog.GroupID; + if (sogGroupID != UUID.Zero) + { + ulong powers = 0; + if(GroupMemberPowers(sogGroupID, userID, ref powers)) + { + if(sogGroupID == sogOwnerID) + { + if((powers & (ulong)GroupPowers.ObjectManipulate) != 0) + return true; + } + return (sog.EffectiveGroupPerms & (uint)PermissionMask.Modify) != 0; + } + } + return false; } private bool CanEditObjectByIDs(UUID objectID, UUID userID, Scene scene) @@ -1667,6 +1758,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions private bool CanTakeObject(SceneObjectGroup sog, ScenePresence sp) { + // ignore locked, viewers shell ask for confirmation DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); if (m_bypassPermissions) return m_bypassPermissionsValue; @@ -1677,14 +1769,36 @@ namespace OpenSim.Region.CoreModules.World.Permissions if(sog.IsAttachment) return false; - // ignore locked, viewers shell ask for confirmation - uint perms = GetObjectPermissions(sp, sog, false); - if((perms & (uint)PermissionMask.Modify) == 0) - return false; + UUID sogOwnerID = sog.OwnerID; + UUID spID = sp.UUID; - if (sog.OwnerID != sp.UUID && ((perms & (uint)PermissionMask.Transfer) == 0)) - return false; - return true; + if(sogOwnerID == spID) + return true; + + if (sp.IsGod) + return true; + + if((sog.EffectiveOwnerPerms & (uint)PermissionMask.Transfer) == 0) + return false; + + if (IsFriendWithPerms(sog.UUID, sogOwnerID)) + return true; + + UUID sogGroupID = sog.GroupID; + if (sogGroupID != UUID.Zero) + { + ulong powers = 0; + if(GroupMemberPowers(sogGroupID, sp, ref powers)) + { + if(sogGroupID == sogOwnerID) + { + if((powers & (ulong)GroupPowers.ObjectManipulate) != 0) + return true; + } + return (sog.EffectiveGroupPerms & (uint)PermissionMask.Modify) != 0; + } + } + return false; } private bool CanTakeCopyObject(SceneObjectGroup sog, ScenePresence sp) @@ -1703,7 +1817,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions if((perms & (uint)PermissionMask.Copy) == 0) return false; - if(sog.OwnerID != sp.UUID && sog.OwnerID != sog.GroupID && (perms & (uint)PermissionMask.Transfer) == 0) + if(sog.OwnerID != sp.UUID && (perms & (uint)PermissionMask.Transfer) == 0) return false; return true; } diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 3230a2ba6f..a1eb721cd3 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -1380,18 +1380,10 @@ namespace OpenSim.Region.Framework.Scenes return; } - if ((taskItem.CurrentPermissions & (uint)PermissionMask.Copy) == 0) + if (!Permissions.CanCopyObjectInventory(itemId, part.UUID, remoteClient.AgentId)) { - // If the item to be moved is no copy, we need to be able to - // edit the prim. - if (!Permissions.CanEditObjectInventory(part.UUID, remoteClient.AgentId)) - return; - } - else - { - // If the item is copiable, then we just need to have perms - // on it. The delete check is a pure rights check - if (!Permissions.CanDeleteObject(part.UUID, remoteClient.AgentId)) + // check also if we can delete the no copy item + if(!Permissions.CanEditObject(part.UUID, remoteClient.AgentId)) return; } @@ -2125,6 +2117,7 @@ namespace OpenSim.Region.Framework.Scenes List deleteIDs = new List(); List deleteGroups = new List(); List takeGroups = new List(); + List takeDeleteGroups = new List(); ScenePresence sp = remoteClient.SceneAgent as ScenePresence; @@ -2192,7 +2185,7 @@ namespace OpenSim.Region.Framework.Scenes if (!Permissions.CanTakeObject(grp, sp)) permissionToTake = false; - if (!Permissions.CanDeleteObject(grp.UUID, remoteClient.AgentId)) + if (!Permissions.CanDeleteObject(grp, remoteClient)) permissionToDelete = false; } @@ -2249,26 +2242,24 @@ namespace OpenSim.Region.Framework.Scenes } } - if (permissionToTake && (!permissionToDelete)) - takeGroups.Add(grp); - if (permissionToDelete) { if (permissionToTake) + takeDeleteGroups.Add(grp); + else deleteGroups.Add(grp); deleteIDs.Add(grp.LocalId); } + else if(permissionToTake) + takeGroups.Add(grp); } SendKillObject(deleteIDs); - if (deleteGroups.Count > 0) + if (takeDeleteGroups.Count > 0) { - foreach (SceneObjectGroup g in deleteGroups) - deleteIDs.Remove(g.LocalId); - m_asyncSceneObjectDeleter.DeleteToInventory( - action, destinationID, deleteGroups, remoteClient, + action, destinationID, takeDeleteGroups, remoteClient, true); } if (takeGroups.Count > 0) @@ -2277,7 +2268,7 @@ namespace OpenSim.Region.Framework.Scenes action, destinationID, takeGroups, remoteClient, false); } - if (deleteIDs.Count > 0) + if (deleteGroups.Count > 0) { foreach (SceneObjectGroup g in deleteGroups) DeleteSceneObject(g, true); diff --git a/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs b/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs index e941210d77..754609aca3 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs @@ -42,7 +42,8 @@ namespace OpenSim.Region.Framework.Scenes public delegate bool BypassPermissionsHandler(); public delegate bool PropagatePermissionsHandler(); public delegate bool RezObjectHandler(int objectCount, UUID owner, Vector3 objectPosition, Scene scene); - public delegate bool DeleteObjectHandler(UUID objectID, UUID deleter, Scene scene); + public delegate bool DeleteObjectHandlerByIDs(UUID objectID, UUID deleter, Scene scene); + public delegate bool DeleteObjectHandler(SceneObjectGroup sog, ScenePresence sp); public delegate bool TransferObjectHandler(UUID objectID, UUID recipient, Scene scene); public delegate bool TakeObjectHandler(SceneObjectGroup sog, ScenePresence sp); public delegate bool SellGroupObjectHandler(UUID userID, UUID groupID, Scene scene); @@ -114,6 +115,7 @@ namespace OpenSim.Region.Framework.Scenes public event BypassPermissionsHandler OnBypassPermissions; public event PropagatePermissionsHandler OnPropagatePermissions; public event RezObjectHandler OnRezObject; + public event DeleteObjectHandlerByIDs OnDeleteObjectByIDs; public event DeleteObjectHandler OnDeleteObject; public event TransferObjectHandler OnTransferObject; public event TakeObjectHandler OnTakeObject; @@ -262,11 +264,11 @@ namespace OpenSim.Region.Framework.Scenes { bool result = true; - DeleteObjectHandler handler = OnDeleteObject; + DeleteObjectHandlerByIDs handler = OnDeleteObjectByIDs; if (handler != null) { Delegate[] list = handler.GetInvocationList(); - foreach (DeleteObjectHandler h in list) + foreach (DeleteObjectHandlerByIDs h in list) { if (h(objectID, deleter, m_scene) == false) { @@ -279,6 +281,32 @@ namespace OpenSim.Region.Framework.Scenes return result; } + public bool CanDeleteObject(SceneObjectGroup sog, IClientAPI client) + { + bool result = true; + + DeleteObjectHandler handler = OnDeleteObject; + if (handler != null) + { + if(sog == null || client == null || client.SceneAgent == null) + return false; + + ScenePresence sp = client.SceneAgent as ScenePresence; + + Delegate[] list = handler.GetInvocationList(); + foreach (DeleteObjectHandler h in list) + { + if (h(sog, sp) == false) + { + result = false; + break; + } + } + } + + return result; + } + public bool CanTransferObject(UUID objectID, UUID recipient) { bool result = true; diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs index b9fa8e4290..ddb03c3a68 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs @@ -315,8 +315,7 @@ namespace OpenSim.Region.Framework.Scenes const uint copytransfermast = (uint)(PermissionMask.Copy | PermissionMask.Transfer); uint basePerms = (RootPart.BaseMask & allmask) | (uint)PermissionMask.Move; - bool noBaseTransfer = (RootPart.OwnerID != RootPart.GroupID && - (basePerms & (uint)PermissionMask.Transfer) == 0); + bool noBaseTransfer = (basePerms & (uint)PermissionMask.Transfer) == 0; uint rootOwnerPerms = RootPart.OwnerMask; uint owner = rootOwnerPerms; @@ -342,17 +341,17 @@ namespace OpenSim.Region.Framework.Scenes owner &= basePerms; m_EffectiveOwnerPerms = owner; + uint ownertransfermask = owner & (uint)PermissionMask.Transfer; // recover modify and move rootGroupPerms &= movemodmask; group |= rootGroupPerms; if(noBaseTransfer) group &=~(uint)PermissionMask.Copy; + else + group |= ownertransfermask; uint groupOrEveryone = group; - - if((group & copytransfermast) == 0) - group |= (uint)PermissionMask.Transfer; m_EffectiveGroupPerms = group & owner; // recover move @@ -361,15 +360,12 @@ namespace OpenSim.Region.Framework.Scenes everyone &= ~(uint)PermissionMask.Modify; if(noBaseTransfer) everyone &=~(uint)PermissionMask.Copy; + else + everyone |= ownertransfermask; groupOrEveryone |= everyone; - if((everyone & copytransfermast) == 0) - everyone |= (uint)PermissionMask.Transfer; m_EffectiveEveryOnePerms = everyone & owner; - - if((groupOrEveryone & copytransfermast) == 0) - groupOrEveryone |= (uint)PermissionMask.Transfer; m_EffectiveGroupOrEveryOnePerms = groupOrEveryone & owner; } } @@ -386,8 +382,7 @@ namespace OpenSim.Region.Framework.Scenes const uint copytransfermast = (uint)(PermissionMask.Copy | PermissionMask.Transfer); uint basePerms = (RootPart.BaseMask & allmask) | (uint)PermissionMask.Move; - bool noBaseTransfer = (RootPart.OwnerID == RootPart.GroupID && - (basePerms & (uint)PermissionMask.Transfer) == 0); + bool noBaseTransfer = (basePerms & (uint)PermissionMask.Transfer) == 0; uint rootOwnerPerms = RootPart.OwnerMask; uint owner = rootOwnerPerms; @@ -412,17 +407,17 @@ namespace OpenSim.Region.Framework.Scenes owner &= basePerms; m_EffectiveOwnerPerms = owner; + uint ownertransfermask = owner & (uint)PermissionMask.Transfer; // recover modify and move rootGroupPerms &= movemodmask; group |= rootGroupPerms; if(noBaseTransfer) group &=~(uint)PermissionMask.Copy; + else + group |= ownertransfermask; uint groupOrEveryone = group; - - if((group & copytransfermast) == 0) - group |= (uint)PermissionMask.Transfer; m_EffectiveGroupPerms = group & owner; // recover move @@ -431,15 +426,12 @@ namespace OpenSim.Region.Framework.Scenes everyone &= ~(uint)PermissionMask.Modify; if(noBaseTransfer) everyone &=~(uint)PermissionMask.Copy; + else + everyone |= ownertransfermask; groupOrEveryone |= everyone; - if((everyone & copytransfermast) == 0) - everyone |= (uint)PermissionMask.Transfer; m_EffectiveEveryOnePerms = everyone & owner; - - if((groupOrEveryone & copytransfermast) == 0) - groupOrEveryone |= (uint)PermissionMask.Transfer; m_EffectiveGroupOrEveryOnePerms = groupOrEveryone & owner; } }