From 67417f647876e32bc9464c5ec76740437cc49b46 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Wed, 14 Jul 2010 16:21:55 +0200 Subject: [PATCH] Fix a permissions issue --- .../Framework/Scenes/Scene.Inventory.cs | 102 +++++++++++++++--- .../Scenes/SceneObjectGroup.Inventory.cs | 18 ++-- 2 files changed, 100 insertions(+), 20 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 2ccb5dd58c..f58e27e708 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -384,29 +384,105 @@ namespace OpenSim.Region.Framework.Scenes if (Permissions.PropagatePermissions() && recipient != senderId) { - // First, make sore base is limited to the next perms - itemCopy.BasePermissions = item.BasePermissions & (item.NextPermissions | (uint)PermissionMask.Move); - // By default, current equals base - itemCopy.CurrentPermissions = itemCopy.BasePermissions & item.CurrentPermissions; + // Trying to do this right this time. This is evil. If + // you believe in Good, go elsewhere. Vampires and other + // evil creatores only beyond this point. You have been + // warned. - // If this is an object, replace current perms - // with folded perms + // We're going to mask a lot of things by the next perms + // Tweak the next perms to be nicer to our data + // + // In this mask, all the bits we do NOT want to mess + // with are set. These are: + // + // Transfer + // Copy + // Modufy + uint permsMask = ~ ((uint)PermissionMask.Copy | + (uint)PermissionMask.Transfer | + (uint)PermissionMask.Modify); + + // Now, reduce the next perms to the mask bits + // relevant to the operation + uint nextPerms = permsMask | (item.NextPermissions & + ((uint)PermissionMask.Copy | + (uint)PermissionMask.Transfer | + (uint)PermissionMask.Modify)); + + // nextPerms now has all bits set, except for the actual + // next permission bits. + + // This checks for no mod, no copy, no trans. + // This indicates an error or messed up item. Do it like + // SL and assume trans + if (nextPerms == permsMask) + nextPerms |= (uint)PermissionMask.Transfer; + + // Inventory owner perms are the logical AND of the + // folded perms and the root prim perms, however, if + // the root prim is mod, the inventory perms will be + // mod. This happens on "take" and is of little concern + // here, save for preventing escalation + + // This hack ensures that items previously permalocked + // get unlocked when they're passed or rezzed + uint basePerms = item.BasePermissions | + (uint)PermissionMask.Move; + uint ownerPerms = item.CurrentPermissions; + + // If this is an object, root prim perms may be more + // permissive than folded perms. Use folded perms as + // a mask if (item.InvType == (int)InventoryType.Object) { - itemCopy.CurrentPermissions &= ~(uint)(PermissionMask.Copy | PermissionMask.Modify | PermissionMask.Transfer); - itemCopy.CurrentPermissions |= (item.CurrentPermissions & 7) << 13; + // Create a safe mask for the current perms + uint foldedPerms = (item.CurrentPermissions & 7) << 13; + foldedPerms |= permsMask; + + bool isRootMod = (item.CurrentPermissions & + (uint)PermissionMask.Modify) != 0 ? + true : false; + + // Mask the owner perms to the folded perms + ownerPerms &= foldedPerms; + basePerms &= foldedPerms; + + // If the root was mod, let the mask reflect that + // We also need to adjust the base here, because + // we should be able to edit in-inventory perms + // for the root prim, if it's mod. + if (isRootMod) + { + ownerPerms |= (uint)PermissionMask.Modify; + basePerms |= (uint)PermissionMask.Modify; + } } - // Ensure there is no escalation - itemCopy.CurrentPermissions &= (item.NextPermissions | (uint)PermissionMask.Move); + // These will be applied to the root prim at next rez. + // The slam bit (bit 3) and folded permission (bits 0-2) + // are preserved due to the above mangling + ownerPerms &= nextPerms; - // Need slam bit on xfer - itemCopy.CurrentPermissions |= 8; + // Mask the base permissions. This is a conservative + // approach altering only the three main perms + basePerms &= nextPerms; + + // Assign to the actual item. Make sure the slam bit is + // set, if it wasn't set before. + itemCopy.BasePermissions = basePerms; + itemCopy.CurrentPermissions = ownerPerms | 16; // Slam itemCopy.NextPermissions = item.NextPermissions; - itemCopy.EveryOnePermissions = 0; + // This preserves "everyone can move" + itemCopy.EveryOnePermissions = item.EveryOnePermissions & + nextPerms; + + // Intentionally killing "share with group" here, as + // the recipient will not have the group this is + // set to itemCopy.GroupPermissions = 0; + } else { diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs index f7e46afa6b..f96573d143 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs @@ -281,7 +281,7 @@ namespace OpenSim.Region.Framework.Scenes PermissionMask.Move | PermissionMask.Transfer) | 7; - uint ownerMask = 0x7ffffff; + uint ownerMask = 0x7fffffff; foreach (SceneObjectPart part in m_parts.Values) { ownerMask &= part.OwnerMask; @@ -295,12 +295,16 @@ namespace OpenSim.Region.Framework.Scenes if ((ownerMask & (uint)PermissionMask.Transfer) == 0) perms &= ~(uint)PermissionMask.Transfer; - if ((ownerMask & RootPart.NextOwnerMask & (uint)PermissionMask.Modify) == 0) - perms &= ~((uint)PermissionMask.Modify >> 13); - if ((ownerMask & RootPart.NextOwnerMask & (uint)PermissionMask.Copy) == 0) - perms &= ~((uint)PermissionMask.Copy >> 13); - if ((ownerMask & RootPart.NextOwnerMask & (uint)PermissionMask.Transfer) == 0) - perms &= ~((uint)PermissionMask.Transfer >> 13); + // If root prim permissions are applied here, this would screw + // with in-inventory manipulation of the next owner perms + // in a major way. So, let's move this to the give itself. + // Yes. I know. Evil. +// if ((ownerMask & RootPart.NextOwnerMask & (uint)PermissionMask.Modify) == 0) +// perms &= ~((uint)PermissionMask.Modify >> 13); +// if ((ownerMask & RootPart.NextOwnerMask & (uint)PermissionMask.Copy) == 0) +// perms &= ~((uint)PermissionMask.Copy >> 13); +// if ((ownerMask & RootPart.NextOwnerMask & (uint)PermissionMask.Transfer) == 0) +// perms &= ~((uint)PermissionMask.Transfer >> 13); return perms; }