work around group sharing and owned permitions issues, fix a non copy objects delete issue

httptests
UbitUmarov 2017-01-22 03:23:50 +00:00
parent c14ec1a9bd
commit 50e318c401
4 changed files with 216 additions and 91 deletions

View File

@ -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;
}

View File

@ -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<uint> deleteIDs = new List<uint>();
List<SceneObjectGroup> deleteGroups = new List<SceneObjectGroup>();
List<SceneObjectGroup> takeGroups = new List<SceneObjectGroup>();
List<SceneObjectGroup> takeDeleteGroups = new List<SceneObjectGroup>();
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);

View File

@ -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;

View File

@ -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;
}
}