From 13f31fdf85c404896c166932730b7b8bc5416626 Mon Sep 17 00:00:00 2001
From: Oren Hurvitz
Date: Mon, 4 Nov 2013 19:28:24 +0200
Subject: Refactored setting permissions when rezzing items: use the same
function when rezzing from user inventory and prim inventory.
Also, fixed a bug: when rezzing a coalesced object from a prim's inventory, apply the coalesced object's name and description only to the first sub-object; not to all the objects in the coalescence. (This was already done correctly when rezzing from a user's inventory.)
---
OpenSim/Framework/PermissionsUtil.cs | 68 ++++++++++++++++++++
.../InventoryAccess/InventoryAccessModule.cs | 51 ++++-----------
.../Region/Framework/Scenes/SceneObjectGroup.cs | 3 +
OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 58 +++++++++++++++++
.../Framework/Scenes/SceneObjectPartInventory.cs | 74 +++++-----------------
5 files changed, 160 insertions(+), 94 deletions(-)
create mode 100644 OpenSim/Framework/PermissionsUtil.cs
(limited to 'OpenSim')
diff --git a/OpenSim/Framework/PermissionsUtil.cs b/OpenSim/Framework/PermissionsUtil.cs
new file mode 100644
index 0000000..3dce04d
--- /dev/null
+++ b/OpenSim/Framework/PermissionsUtil.cs
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSimulator Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using System.Text;
+using log4net;
+
+namespace OpenSim.Framework
+{
+ public static class PermissionsUtil
+ {
+ private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+
+ ///
+ /// Logs permissions flags. Useful when debugging permission problems.
+ ///
+ ///
+ public static void LogPermissions(String name, String message, uint basePerm, uint curPerm, uint nextPerm)
+ {
+ m_log.DebugFormat("Permissions of \"{0}\" at \"{1}\": Base {2} ({3:X4}), Current {4} ({5:X4}), NextOwner {6} ({7:X4})",
+ name, message,
+ PermissionsToString(basePerm), basePerm, PermissionsToString(curPerm), curPerm, PermissionsToString(nextPerm), nextPerm);
+ }
+
+ ///
+ /// Converts a permissions bit-mask to a string (e.g., "MCT").
+ ///
+ private static string PermissionsToString(uint perms)
+ {
+ string str = "";
+ if ((perms & (int)PermissionMask.Modify) != 0)
+ str += "M";
+ if ((perms & (int)PermissionMask.Copy) != 0)
+ str += "C";
+ if ((perms & (int)PermissionMask.Transfer) != 0)
+ str += "T";
+ if (str == "")
+ str = ".";
+ return str;
+ }
+ }
+}
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
index 831922e..da36ed0 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
@@ -512,10 +512,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
item.EveryOnePermissions = so.RootPart.EveryoneMask & so.RootPart.NextOwnerMask;
item.GroupPermissions = so.RootPart.GroupMask & so.RootPart.NextOwnerMask;
- // Magic number badness. Maybe this deserves an enum.
- // bit 4 (16) is the "Slam" bit, it means treat as passed
- // and apply next owner perms on rez
- item.CurrentPermissions |= 16; // Slam!
+ // apply next owner perms on rez
+ item.CurrentPermissions |= SceneObjectGroup.SLAM;
}
else
{
@@ -809,11 +807,15 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
group.RootPart.Shape.LastAttachPoint = (byte)group.AttachmentPoint;
}
- foreach (SceneObjectPart part in group.Parts)
+ if (item == null)
{
- // Make the rezzer the owner, as this is not necessarily set correctly in the serialized asset.
- part.LastOwnerID = part.OwnerID;
- part.OwnerID = remoteClient.AgentId;
+ // Change ownership. Normally this is done in DoPreRezWhenFromItem(), but in this case we must do it here.
+ foreach (SceneObjectPart part in group.Parts)
+ {
+ // Make the rezzer the owner, as this is not necessarily set correctly in the serialized asset.
+ part.LastOwnerID = part.OwnerID;
+ part.OwnerID = remoteClient.AgentId;
+ }
}
if (!attachment)
@@ -969,44 +971,19 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
// "[INVENTORY ACCESS MODULE]: rootPart.OwnedID {0}, item.Owner {1}, item.CurrentPermissions {2:X}",
// rootPart.OwnerID, item.Owner, item.CurrentPermissions);
- if ((rootPart.OwnerID != item.Owner) ||
- (item.CurrentPermissions & 16) != 0)
+ if ((rootPart.OwnerID != item.Owner) || (item.CurrentPermissions & SceneObjectGroup.SLAM) != 0)
{
//Need to kill the for sale here
rootPart.ObjectSaleType = 0;
rootPart.SalePrice = 10;
-
- if (m_Scene.Permissions.PropagatePermissions())
- {
- foreach (SceneObjectPart part in so.Parts)
- {
- if ((item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0)
- {
- part.EveryoneMask = item.EveryOnePermissions;
- part.NextOwnerMask = item.NextPermissions;
- }
- part.GroupMask = 0; // DO NOT propagate here
- }
-
- so.ApplyNextOwnerPermissions();
- }
}
-
+
foreach (SceneObjectPart part in so.Parts)
{
part.FromUserInventoryItemID = fromUserInventoryItemId;
-
- if ((part.OwnerID != item.Owner) ||
- (item.CurrentPermissions & 16) != 0)
- {
- part.Inventory.ChangeInventoryOwner(item.Owner);
- part.GroupMask = 0; // DO NOT propagate here
- }
-
- part.EveryoneMask = item.EveryOnePermissions;
- part.NextOwnerMask = item.NextPermissions;
+ part.ApplyPermissionsOnRez(item, true, m_Scene);
}
-
+
rootPart.TrimPermissions();
if (isAttachment)
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index 4b4e4ba..23507f4 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -109,6 +109,9 @@ namespace OpenSim.Region.Framework.Scenes
STATUS_ROTATE_Z = 0x008,
}
+ // This flag has the same purpose as InventoryItemFlags.ObjectSlamPerm
+ public static readonly uint SLAM = 16;
+
// private PrimCountTaintedDelegate handlerPrimCountTainted = null;
///
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index ea9d0d8..1cf7726 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -4800,6 +4800,64 @@ namespace OpenSim.Region.Framework.Scenes
{
ParentGroup.AddScriptLPS(count);
}
+
+ ///
+ /// Sets a prim's owner and permissions when it's rezzed.
+ ///
+ /// The inventory item from which the item was rezzed
+ /// True: the item is being rezzed from the user's inventory. False: from a prim's inventory.
+ /// The scene the prim is being rezzed into
+ public void ApplyPermissionsOnRez(InventoryItemBase item, bool userInventory, Scene scene)
+ {
+ if ((OwnerID != item.Owner) || ((item.CurrentPermissions & SceneObjectGroup.SLAM) != 0) || ((item.Flags & (uint)InventoryItemFlags.ObjectSlamPerm) != 0))
+ {
+ if (scene.Permissions.PropagatePermissions())
+ {
+ if ((item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0)
+ {
+ // Apply the item's permissions to the object
+ //LogPermissions("Before applying item permissions");
+ if (userInventory)
+ {
+ EveryoneMask = item.EveryOnePermissions;
+ NextOwnerMask = item.NextPermissions;
+ }
+ else
+ {
+ if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteEveryone) != 0)
+ EveryoneMask = item.EveryOnePermissions;
+ if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteNextOwner) != 0)
+ NextOwnerMask = item.NextPermissions;
+ if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteGroup) != 0)
+ GroupMask = item.GroupPermissions;
+ }
+ //LogPermissions("After applying item permissions");
+ }
+ }
+
+ GroupMask = 0; // DO NOT propagate here
+ }
+
+ if (OwnerID != item.Owner)
+ {
+ //LogPermissions("Before ApplyNextOwnerPermissions");
+ ApplyNextOwnerPermissions();
+ //LogPermissions("After ApplyNextOwnerPermissions");
+
+ LastOwnerID = OwnerID;
+ OwnerID = item.Owner;
+ Inventory.ChangeInventoryOwner(item.Owner);
+ }
+ }
+
+ ///
+ /// Logs the prim's permissions. Useful when debugging permission problems.
+ ///
+ ///
+ private void LogPermissions(String message)
+ {
+ PermissionsUtil.LogPermissions(Name, message, BaseMask, OwnerMask, NextOwnerMask);
+ }
public void ApplyNextOwnerPermissions()
{
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
index 380e402..5fa01e3 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
@@ -764,48 +764,27 @@ namespace OpenSim.Region.Framework.Scenes
// Since renaming the item in the inventory does not affect the name stored
// in the serialization, transfer the correct name from the inventory to the
// object itself before we rez.
- rootPart.Name = item.Name;
- rootPart.Description = item.Description;
-
- SceneObjectPart[] partList = group.Parts;
-
- 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
+ // Only do these for the first object if we are rezzing a coalescence.
+ if (i == 0)
{
- if (m_part.ParentGroup.Scene.Permissions.PropagatePermissions())
- {
- foreach (SceneObjectPart part in partList)
- {
- if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteEveryone) != 0)
- part.EveryoneMask = item.EveryonePermissions;
- if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteNextOwner) != 0)
- part.NextOwnerMask = item.NextPermissions;
- if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteGroup) != 0)
- part.GroupMask = item.GroupPermissions;
- }
-
- group.ApplyNextOwnerPermissions();
- }
+ rootPart.Name = item.Name;
+ rootPart.Description = item.Description;
}
- 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
- {
- part.LastOwnerID = part.OwnerID;
- part.OwnerID = item.OwnerID;
- part.Inventory.ChangeInventoryOwner(item.OwnerID);
- }
+ group.SetGroup(m_part.GroupID, null);
- if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteEveryone) != 0)
- part.EveryoneMask = item.EveryonePermissions;
- if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteNextOwner) != 0)
- part.NextOwnerMask = item.NextPermissions;
- if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteGroup) != 0)
- part.GroupMask = item.GroupPermissions;
+ foreach (SceneObjectPart part in group.Parts)
+ {
+ // Convert between InventoryItem classes. You can never have too many similar but slightly different classes :)
+ InventoryItemBase dest = new InventoryItemBase(item.ItemID, item.OwnerID);
+ dest.BasePermissions = item.BasePermissions;
+ dest.CurrentPermissions = item.CurrentPermissions;
+ dest.EveryOnePermissions = item.EveryonePermissions;
+ dest.GroupPermissions = item.GroupPermissions;
+ dest.NextPermissions = item.NextPermissions;
+ dest.Flags = item.Flags;
+
+ part.ApplyPermissionsOnRez(dest, false, m_part.ParentGroup.Scene);
}
rootPart.TrimPermissions();
@@ -1130,25 +1109,6 @@ namespace OpenSim.Region.Framework.Scenes
mask &= ~((uint)PermissionMask.Transfer >> 13);
if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Modify) == 0)
mask &= ~((uint)PermissionMask.Modify >> 13);
-
- if (item.InvType != (int)InventoryType.Object)
- {
- if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Copy) == 0)
- mask &= ~((uint)PermissionMask.Copy >> 13);
- if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Transfer) == 0)
- mask &= ~((uint)PermissionMask.Transfer >> 13);
- if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Modify) == 0)
- mask &= ~((uint)PermissionMask.Modify >> 13);
- }
- else
- {
- if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0)
- mask &= ~((uint)PermissionMask.Copy >> 13);
- if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0)
- mask &= ~((uint)PermissionMask.Transfer >> 13);
- if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0)
- mask &= ~((uint)PermissionMask.Modify >> 13);
- }
if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
mask &= ~(uint)PermissionMask.Copy;
--
cgit v1.1