From b9e2606c2ff820369659940e4aafbcb55390794a Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sun, 15 Jan 2017 16:15:40 +0000 Subject: [PATCH] add code for fixing effective permitions. This is a test, and currently too slow for prodution. just finding our way home --- .../World/Permissions/PermissionsModule.cs | 39 ++-- .../Framework/Interfaces/IEntityInventory.cs | 5 + .../Scenes/SceneObjectGroup.Inventory.cs | 177 ++++++++++++++++++ .../Scenes/SceneObjectPartInventory.cs | 46 ++++- 4 files changed, 252 insertions(+), 15 deletions(-) diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs index b60cd93ad2..dcf0c00555 100644 --- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs +++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs @@ -631,7 +631,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions #region Object Permissions #pragma warning disable 0612 - const uint DEFAULT_FLAGS = (uint)~( + const uint DEFAULT_FLAGS = (uint)( PrimFlags.ObjectCopy | // Tells client you can copy the object PrimFlags.ObjectModify | // tells client you can modify the object PrimFlags.ObjectMove | // tells client that you can move the object (only, no mod) @@ -665,6 +665,16 @@ namespace OpenSim.Region.CoreModules.World.Permissions PrimFlags.ObjectMove ); + const uint GOD_FLAGS = (uint)( + PrimFlags.ObjectCopy | // Tells client you can copy the object + PrimFlags.ObjectModify | // tells client you can modify the object + PrimFlags.ObjectMove | // tells client that you can move the object (only, no mod) + PrimFlags.ObjectTransfer | // tells the client that you can /take/ the object if you don't own it + PrimFlags.ObjectYouOwner | // Tells client that you're the owner of the object + PrimFlags.ObjectAnyOwner | // Tells client that someone owns the object + PrimFlags.ObjectOwnerModify // Tells client that you're the owner of the object + ); + public uint GenerateClientFlags(ScenePresence sp, uint curEffectivePerms, UUID objID) { if(sp == null || curEffectivePerms == 0) @@ -684,22 +694,25 @@ namespace OpenSim.Region.CoreModules.World.Permissions // gods have owner rights with Modify and Move always on if(sp.IsGod) { - returnMask = ApplyObjectModifyMasks(task.OwnerMask, objflags, true); - returnMask |= EXTRAGODMASK; - return returnMask; +// returnMask = ApplyObjectModifyMasks(task.OwnerMask, objflags, true); +// returnMask |= EXTRAGODMASK; +// return returnMask; + return objflags | GOD_FLAGS; } + SceneObjectGroup grp = task.ParentGroup; + bool unlocked = (grp.RootPart.OwnerMask & (uint)PermissionMask.Move) != 0; + //bypass option == owner rights if (m_bypassPermissions) { - returnMask = ApplyObjectModifyMasks(task.OwnerMask, objflags, true); + returnMask = ApplyObjectModifyMasks(task.OwnerMask, objflags, true); //?? returnMask |= EXTRAOWNERMASK; if((returnMask & (uint)PrimFlags.ObjectModify) != 0) returnMask |= (uint)PrimFlags.ObjectOwnerModify; return returnMask; } - bool unlocked = (task.ParentGroup.RootPart.OwnerMask & (uint)PermissionMask.Move) != 0; UUID taskOwnerID = task.OwnerID; UUID spID = sp.UUID; @@ -707,7 +720,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions // owner if (spID == taskOwnerID) { - returnMask = ApplyObjectModifyMasks(task.OwnerMask, objflags, unlocked); + returnMask = ApplyObjectModifyMasks(grp.EffectiveOwnerPerms, objflags, unlocked); returnMask |= EXTRAOWNERMASK; if((returnMask & (uint)PrimFlags.ObjectModify) != 0) returnMask |= (uint)PrimFlags.ObjectOwnerModify; @@ -717,7 +730,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions // if not god or owner, do attachments as everyone if(task.ParentGroup.IsAttachment) { - returnMask = ApplyObjectModifyMasks(task.EveryoneMask, objflags, unlocked); + returnMask = ApplyObjectModifyMasks(grp.EffectiveEveryOnePerms, objflags, unlocked); if (taskOwnerID != UUID.Zero) returnMask |= (uint)PrimFlags.ObjectAnyOwner; return returnMask; @@ -729,7 +742,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions // if friends with rights then owner if (!groupdOwned && IsFriendWithPerms(spID, taskOwnerID)) { - returnMask = ApplyObjectModifyMasks(task.OwnerMask, objflags, unlocked); + returnMask = ApplyObjectModifyMasks(grp.EffectiveOwnerPerms, objflags, unlocked); returnMask |= EXTRAOWNERMASK; if((returnMask & (uint)PrimFlags.ObjectModify) != 0) returnMask |= (uint)PrimFlags.ObjectOwnerModify; @@ -745,7 +758,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions // object is owned by group, check role powers if((client.GetGroupPowers(taskGroupID) & (ulong)GroupPowers.ObjectManipulate) != 0) { - returnMask = ApplyObjectModifyMasks(task.OwnerMask, objflags, unlocked); + returnMask = ApplyObjectModifyMasks(grp.EffectiveOwnerPerms, objflags, unlocked); returnMask |= (uint)PrimFlags.ObjectGroupOwned | (uint)PrimFlags.ObjectAnyOwner; @@ -756,7 +769,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions else { // group sharing or everyone - returnMask = ApplyObjectModifyMasks(task.GroupMask | task.EveryoneMask, objflags, unlocked); + returnMask = ApplyObjectModifyMasks(grp.EffectiveGroupOrEveryOnePerms, objflags, unlocked); returnMask |= (uint)PrimFlags.ObjectGroupOwned | (uint)PrimFlags.ObjectAnyOwner; @@ -766,7 +779,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions else { // group sharing or everyone - returnMask = ApplyObjectModifyMasks(task.GroupMask | task.EveryoneMask, objflags, unlocked); + returnMask = ApplyObjectModifyMasks(grp.EffectiveGroupOrEveryOnePerms, objflags, unlocked); if (taskOwnerID != UUID.Zero) returnMask |= (uint)PrimFlags.ObjectAnyOwner; return returnMask; @@ -774,7 +787,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions } // fallback is everyone rights - returnMask = ApplyObjectModifyMasks(task.EveryoneMask, objflags, unlocked); + returnMask = ApplyObjectModifyMasks(grp.EffectiveEveryOnePerms, objflags, unlocked); if (taskOwnerID != UUID.Zero) returnMask |= (uint)PrimFlags.ObjectAnyOwner; return returnMask; diff --git a/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs b/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs index 0c4017eb88..2af6ff0faf 100644 --- a/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs +++ b/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs @@ -278,6 +278,11 @@ namespace OpenSim.Region.Framework.Interfaces /// void ProcessInventoryBackup(ISimulationDataService datastore); + void AggregateEveryOnePerms(ref uint current); + void AggregateGroupOrEveryonePerms(ref uint current); + void AggregateGroupPerms(ref uint current); + void AggregateOwnerPerms(ref uint current); + uint MaskEffectivePermissions(); void ApplyNextOwnerPermissions(); diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs index 9f98554ac0..f44604be3d 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs @@ -248,6 +248,183 @@ namespace OpenSim.Region.Framework.Scenes return -1; } + // new test code, to place in better place later + private object PermissionsLock = new object(); + + private uint m_EffectiveEveryOnePerms; + public uint EffectiveEveryOnePerms + { + get + { + // this can't be done here but on every place where a change may happen (rez, (de)link, contents , perms, etc) + // bc this is on heavy duty code paths + // but for now we need to test the concept + AggregateEveryOnePerms(); + return m_EffectiveEveryOnePerms; + } + } + + public void AggregateEveryOnePerms() + { + lock(PermissionsLock) + { + // get object everyone permissions + uint baseperms = RootPart.EveryoneMask & (uint)PermissionMask.All; + + if(baseperms == 0) + { + m_EffectiveEveryOnePerms = 0; + return; + } + + uint current = baseperms; + SceneObjectPart[] parts = m_parts.GetArray(); + for (int i = 0; i < parts.Length; i++) + { + SceneObjectPart part = parts[i]; + part.Inventory.AggregateEveryOnePerms(ref current); + if( current == 0) + break; + } + // recover move + baseperms &= (uint)PermissionMask.Move; + current |= baseperms; + current &= (uint)PermissionMask.All; + m_EffectiveEveryOnePerms = current; + } + } + + private uint m_EffectiveGroupPerms; + public uint EffectiveGroupPerms + { + get + { + // this can't be done here but on every place where a change may happen (rez, (de)link, contents , perms, etc) + // bc this is on heavy duty code paths + // but for now we need to test the concept + AggregateGroupPerms(); + return m_EffectiveGroupPerms; + } + } + + public void AggregateGroupPerms() + { + lock(PermissionsLock) + { + // get object everyone permissions + uint baseperms = RootPart.GroupMask & (uint)PermissionMask.All; + + if(baseperms == 0) + { + m_EffectiveGroupPerms = 0; + return; + } + + uint current = baseperms; + SceneObjectPart[] parts = m_parts.GetArray(); + for (int i = 0; i < parts.Length; i++) + { + SceneObjectPart part = parts[i]; + part.Inventory.AggregateGroupPerms(ref current); + if( current == 0) + break; + } + // recover modify and move + baseperms &= (uint)(PermissionMask.Move | PermissionMask.Modify ); + current |= baseperms; + current &= (uint)PermissionMask.All; + m_EffectiveGroupPerms = current; + } + } + + private uint m_EffectiveGroupOrEveryOnePerms; + public uint EffectiveGroupOrEveryOnePerms + { + get + { + // this can't be done here but on every place where a change may happen (rez, (de)link, contents , perms, etc) + // bc this is on heavy duty code paths + // but for now we need to test the concept + AggregateGroupOrEveryOnePerms(); + return m_EffectiveGroupOrEveryOnePerms; + } + } + + public void AggregateGroupOrEveryOnePerms() + { + lock(PermissionsLock) + { + // get object everyone permissions + uint baseperms = (RootPart.EveryoneMask | RootPart.GroupMask) & (uint)PermissionMask.All; + + if(baseperms == 0) + { + m_EffectiveGroupOrEveryOnePerms = 0; + return; + } + + uint current = baseperms; + SceneObjectPart[] parts = m_parts.GetArray(); + for (int i = 0; i < parts.Length; i++) + { + SceneObjectPart part = parts[i]; + part.Inventory.AggregateGroupOrEveryonePerms(ref current); + if( current == 0) + break; + } + // recover modify and move + baseperms &= (uint)(PermissionMask.Move | PermissionMask.Modify ); + current |= baseperms; + current &= (uint)PermissionMask.All; + m_EffectiveGroupOrEveryOnePerms = current; + } + } + + private uint m_EffectiveOwnerPerms; + public uint EffectiveOwnerPerms + { + get + { + // this can't be done here but on every place where a change may happen (rez, (de)link, contents , perms, etc) + // bc this is on heavy duty code paths + // but for now we need to test the concept + AggregateOwnerPerms(); + return m_EffectiveOwnerPerms; + } + } + + public void AggregateOwnerPerms() + { + lock(PermissionsLock) + { + // get object everyone permissions + uint baseperms = RootPart.OwnerMask & (uint)PermissionMask.All; + + if(baseperms == 0) + { + m_EffectiveOwnerPerms = 0; + return; + } + + uint current = baseperms; + SceneObjectPart[] parts = m_parts.GetArray(); + for (int i = 0; i < parts.Length; i++) + { + SceneObjectPart part = parts[i]; + part.Inventory.AggregateOwnerPerms(ref current); + if( current == 0) + break; + } + // recover modify and move + baseperms &= (uint)(PermissionMask.Move | PermissionMask.Modify ); + current |= baseperms; + current &= (uint)PermissionMask.All; + if((current & (uint)(PermissionMask.Copy | PermissionMask.Transfer)) == 0) + current |= (uint)PermissionMask.Transfer; + m_EffectiveOwnerPerms = current; + } + } + public uint GetEffectivePermissions() { return GetEffectivePermissions(false); diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index 02b94ce8b8..48ae39e018 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -944,7 +944,7 @@ namespace OpenSim.Region.Framework.Scenes group.SetGroup(m_part.GroupID, null); // TODO: Remove magic number badness - if ((rootPart.OwnerID != item.OwnerID) || (item.CurrentPermissions & 16) != 0 || (item.Flags & (uint)InventoryItemFlags.ObjectSlamPerm) != 0) // Magic number + if ((rootPart.OwnerID != item.OwnerID) || (item.CurrentPermissions & (uint)PermissionMask.Slam) != 0 || (item.Flags & (uint)InventoryItemFlags.ObjectSlamPerm) != 0) // Magic number { if (m_part.ParentGroup.Scene.Permissions.PropagatePermissions()) { @@ -965,7 +965,7 @@ namespace OpenSim.Region.Framework.Scenes foreach (SceneObjectPart part in partList) { // TODO: Remove magic number badness - if ((part.OwnerID != item.OwnerID) || (item.CurrentPermissions & 16) != 0 || (item.Flags & (uint)InventoryItemFlags.ObjectSlamPerm) != 0) // Magic number + if ((part.OwnerID != item.OwnerID) || (item.CurrentPermissions & (uint)PermissionMask.Slam) != 0 || (item.Flags & (uint)InventoryItemFlags.ObjectSlamPerm) != 0) // Magic number { part.LastOwnerID = part.OwnerID; part.OwnerID = item.OwnerID; @@ -1319,6 +1319,48 @@ namespace OpenSim.Region.Framework.Scenes } } + // reduce to minimal set + public void AggregateEveryOnePerms(ref uint current) + { + foreach (TaskInventoryItem item in m_items.Values) + { + current &= item.EveryonePermissions; + if(current == 0) + break; + } + } + + public void AggregateGroupPerms(ref uint current) + { + foreach (TaskInventoryItem item in m_items.Values) + { + current &= item.GroupPermissions; + if(current == 0) + break; + } + } + + public void AggregateGroupOrEveryonePerms(ref uint current) + { + foreach (TaskInventoryItem item in m_items.Values) + { + current &= (item.GroupPermissions | item.EveryonePermissions); + if(current == 0) + break; + } + } + + public void AggregateOwnerPerms(ref uint current) + { + foreach (TaskInventoryItem item in m_items.Values) + { + current &= item.CurrentPermissions; + if(current == 0) + break; + } + } + + public uint MaskEffectivePermissions() { uint mask=0x7fffffff;