aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim')
-rw-r--r--OpenSim/Framework/IClientAPI.cs2
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs23
-rw-r--r--OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs225
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.Permissions.cs9
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs3
5 files changed, 179 insertions, 83 deletions
diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs
index 1267993..eedba9d 100644
--- a/OpenSim/Framework/IClientAPI.cs
+++ b/OpenSim/Framework/IClientAPI.cs
@@ -1112,7 +1112,7 @@ namespace OpenSim.Framework
1112 /// <param name="localID"></param> 1112 /// <param name="localID"></param>
1113 void SendKillObject(List<uint> localID); 1113 void SendKillObject(List<uint> localID);
1114 1114
1115 void SendPartFullUpdate(ISceneEntity ent, uint? parentID); 1115// void SendPartFullUpdate(ISceneEntity ent, uint? parentID);
1116 1116
1117 void SendAnimations(UUID[] animID, int[] seqs, UUID sourceAgentId, UUID[] objectIDs); 1117 void SendAnimations(UUID[] animID, int[] seqs, UUID sourceAgentId, UUID[] objectIDs);
1118 void SendRegionHandshake(RegionInfo regionInfo, RegionHandshakeArgs args); 1118 void SendRegionHandshake(RegionInfo regionInfo, RegionHandshakeArgs args);
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index df34668..8ba1ba3 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -4126,14 +4126,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4126// Vector3 mycamera = Vector3.Zero; 4126// Vector3 mycamera = Vector3.Zero;
4127 Vector3 mypos = Vector3.Zero; 4127 Vector3 mypos = Vector3.Zero;
4128 ScenePresence mysp = (ScenePresence)SceneAgent; 4128 ScenePresence mysp = (ScenePresence)SceneAgent;
4129 if(mysp != null && !mysp.IsDeleted) 4129
4130 // we should have a presence
4131 if(mysp == null)
4132 return;
4133
4134 if(doCulling)
4130 { 4135 {
4131 cullingrange = mysp.DrawDistance + m_scene.ReprioritizationDistance + 16f; 4136 cullingrange = mysp.DrawDistance + m_scene.ReprioritizationDistance + 16f;
4132// mycamera = mysp.CameraPosition; 4137// mycamera = mysp.CameraPosition;
4133 mypos = mysp.AbsolutePosition; 4138 mypos = mysp.AbsolutePosition;
4134 } 4139 }
4135 else
4136 doCulling = false;
4137 4140
4138 while (maxUpdatesBytes > 0) 4141 while (maxUpdatesBytes > 0)
4139 { 4142 {
@@ -4330,7 +4333,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4330 if (update.Entity is ScenePresence) 4333 if (update.Entity is ScenePresence)
4331 ablock = CreateAvatarUpdateBlock((ScenePresence)update.Entity); 4334 ablock = CreateAvatarUpdateBlock((ScenePresence)update.Entity);
4332 else 4335 else
4333 ablock = CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId); 4336 ablock = CreatePrimUpdateBlock((SceneObjectPart)update.Entity, mysp);
4334 objectUpdateBlocks.Add(ablock); 4337 objectUpdateBlocks.Add(ablock);
4335 objectUpdates.Value.Add(update); 4338 objectUpdates.Value.Add(update);
4336 maxUpdatesBytes -= ablock.Length; 4339 maxUpdatesBytes -= ablock.Length;
@@ -4462,6 +4465,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4462 } 4465 }
4463 4466
4464 // hack.. dont use 4467 // hack.. dont use
4468/*
4465 public void SendPartFullUpdate(ISceneEntity ent, uint? parentID) 4469 public void SendPartFullUpdate(ISceneEntity ent, uint? parentID)
4466 { 4470 {
4467 if (ent is SceneObjectPart) 4471 if (ent is SceneObjectPart)
@@ -4472,7 +4476,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4472 packet.RegionData.TimeDilation = Utils.FloatToUInt16(m_scene.TimeDilation, 0.0f, 1.0f); 4476 packet.RegionData.TimeDilation = Utils.FloatToUInt16(m_scene.TimeDilation, 0.0f, 1.0f);
4473 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1]; 4477 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1];
4474 4478
4475 ObjectUpdatePacket.ObjectDataBlock blk = CreatePrimUpdateBlock(part, this.m_agentId); 4479 ObjectUpdatePacket.ObjectDataBlock blk = CreatePrimUpdateBlock(part, mysp);
4476 if (parentID.HasValue) 4480 if (parentID.HasValue)
4477 { 4481 {
4478 blk.ParentID = parentID.Value; 4482 blk.ParentID = parentID.Value;
@@ -4488,7 +4492,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4488// updatesThisCall, Name, SceneAgent.IsChildAgent ? "child" : "root", Scene.Name); 4492// updatesThisCall, Name, SceneAgent.IsChildAgent ? "child" : "root", Scene.Name);
4489// 4493//
4490 } 4494 }
4491 4495*/
4492 public void ReprioritizeUpdates() 4496 public void ReprioritizeUpdates()
4493 { 4497 {
4494 lock (m_entityUpdates.SyncRoot) 4498 lock (m_entityUpdates.SyncRoot)
@@ -5726,7 +5730,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5726 return update; 5730 return update;
5727 } 5731 }
5728 5732
5729 protected ObjectUpdatePacket.ObjectDataBlock CreatePrimUpdateBlock(SceneObjectPart data, UUID recipientID) 5733// protected ObjectUpdatePacket.ObjectDataBlock CreatePrimUpdateBlock(SceneObjectPart data, UUID recipientID)
5734 protected ObjectUpdatePacket.ObjectDataBlock CreatePrimUpdateBlock(SceneObjectPart data, ScenePresence sp)
5730 { 5735 {
5731 byte[] objectData = new byte[60]; 5736 byte[] objectData = new byte[60];
5732 data.RelativePosition.ToBytes(objectData, 0); 5737 data.RelativePosition.ToBytes(objectData, 0);
@@ -5826,12 +5831,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5826 5831
5827 #region PrimFlags 5832 #region PrimFlags
5828 5833
5829 PrimFlags flags = (PrimFlags)m_scene.Permissions.GenerateClientFlags(recipientID, data.UUID); 5834 PrimFlags flags = (PrimFlags)m_scene.Permissions.GenerateClientFlags(sp, data.UUID);
5830 5835
5831 // Don't send the CreateSelected flag to everyone 5836 // Don't send the CreateSelected flag to everyone
5832 flags &= ~PrimFlags.CreateSelected; 5837 flags &= ~PrimFlags.CreateSelected;
5833 5838
5834 if (recipientID == data.OwnerID) 5839 if (sp.UUID == data.OwnerID)
5835 { 5840 {
5836 if (data.CreateSelected) 5841 if (data.CreateSelected)
5837 { 5842 {
diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
index 75d90f3..094da2b 100644
--- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
+++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
@@ -479,7 +479,32 @@ namespace OpenSim.Region.CoreModules.World.Permissions
479 479
480 return false; 480 return false;
481 } 481 }
482/*
483 private bool CheckGroupPowers(ScenePresence sp, UUID groupID, ulong powersMask)
484 {
485 if(sp == null || sp.ControllingClient == null)
486 return false;
487
488 ulong grpPowers = sp.ControllingClient.GetGroupPowers(groupID);
482 489
490 return (grpPowers & powersMask) != 0;
491 }
492
493 private bool CheckActiveGroupPowers(ScenePresence sp, UUID groupID, ulong powersMask)
494 {
495 if(sp == null || sp.ControllingClient == null)
496 return false;
497
498 if(sp.ControllingClient.ActiveGroupId != groupID)
499 return false;
500 // activeGroupPowers only get current selected role powers, at least with xmlgroups.
501 // lets get any role avoiding the extra burden of user also having to change role
502 // ulong grpPowers = sp.ControllingClient.ActiveGroupPowers(groupID);
503 ulong grpPowers = sp.ControllingClient.GetGroupPowers(groupID);
504
505 return (grpPowers & powersMask) != 0;
506 }
507*/
483 /// <summary> 508 /// <summary>
484 /// Parse a user set configuration setting 509 /// Parse a user set configuration setting
485 /// </summary> 510 /// </summary>
@@ -605,73 +630,150 @@ namespace OpenSim.Region.CoreModules.World.Permissions
605 } 630 }
606 631
607 #region Object Permissions 632 #region Object Permissions
633#pragma warning disable 0612
634 const uint DEFAULT_FLAGS = (uint)~(
635 PrimFlags.ObjectCopy | // Tells client you can copy the object
636 PrimFlags.ObjectModify | // tells client you can modify the object
637 PrimFlags.ObjectMove | // tells client that you can move the object (only, no mod)
638 PrimFlags.ObjectTransfer | // tells the client that you can /take/ the object if you don't own it
639 PrimFlags.ObjectYouOwner | // Tells client that you're the owner of the object
640 PrimFlags.ObjectAnyOwner | // Tells client that someone owns the object
641 PrimFlags.ObjectOwnerModify // Tells client that you're the owner of the object
642 );
643
644 const uint NOT_DEFAULT_FLAGS = (uint)~(
645 PrimFlags.ObjectCopy | // Tells client you can copy the object
646 PrimFlags.ObjectModify | // tells client you can modify the object
647 PrimFlags.ObjectMove | // tells client that you can move the object (only, no mod)
648 PrimFlags.ObjectTransfer | // tells the client that you can /take/ the object if you don't own it
649 PrimFlags.ObjectYouOwner | // Tells client that you're the owner of the object
650 PrimFlags.ObjectAnyOwner | // Tells client that someone owns the object
651 PrimFlags.ObjectOwnerModify // Tells client that you're the owner of the object
652 );
653#pragma warning restore 0612
608 654
609 public uint GenerateClientFlags(UUID user, UUID objID) 655 const uint EXTRAOWNERMASK = (uint)(
610 { 656 PrimFlags.ObjectYouOwner |
611 // Here's the way this works, 657 PrimFlags.ObjectAnyOwner
612 // ObjectFlags and Permission flags are two different enumerations 658 );
613 // ObjectFlags, however, tells the client to change what it will allow the user to do. 659
614 // So, that means that all of the permissions type ObjectFlags are /temporary/ and only 660 const uint EXTRAGODMASK = (uint)(
615 // supposed to be set when customizing the objectflags for the client. 661 PrimFlags.ObjectYouOwner |
662 PrimFlags.ObjectAnyOwner |
663 PrimFlags.ObjectOwnerModify |
664 PrimFlags.ObjectModify |
665 PrimFlags.ObjectMove
666 );
616 667
617 // These temporary objectflags get computed and added in this function based on the 668 public uint GenerateClientFlags(ScenePresence sp, uint curEffectivePerms, UUID objID)
618 // Permission mask that's appropriate! 669 {
619 // Outside of this method, they should never be added to objectflags! 670 if(sp == null || curEffectivePerms == 0)
620 // -teravus 671 return (uint)0;
621 672
622 SceneObjectPart task = m_scene.GetSceneObjectPart(objID); 673 SceneObjectPart task = m_scene.GetSceneObjectPart(objID);
623 674
624 // this shouldn't ever happen.. return no permissions/objectflags. 675 // this shouldn't ever happen.. return no permissions/objectflags.
625 if (task == null) 676 if (task == null)
626 return (uint)0; 677 return (uint)0;
678
679 // Remove any of the objectFlags that are temporary. These will get added back if appropriate
680 uint objflags = curEffectivePerms & NOT_DEFAULT_FLAGS ;
627 681
628 uint objflags = task.GetEffectiveObjectFlags(); 682 uint returnMask;
629 UUID objectOwner = task.OwnerID;
630
631 683
632 // Remove any of the objectFlags that are temporary. These will get added back if appropriate 684 // gods have owner rights with Modify and Move always on
633 // in the next bit of code 685 if(sp.IsGod)
686 {
687 returnMask = ApplyObjectModifyMasks(task.OwnerMask, objflags);
688 returnMask |= EXTRAGODMASK;
689 return returnMask;
690 }
634 691
635 // libomv will moan about PrimFlags.ObjectYouOfficer being 692 //bypass option == owner rights
636 // deprecated 693 if (m_bypassPermissions)
637#pragma warning disable 0612 694 {
638 objflags &= (uint) 695 returnMask = ApplyObjectModifyMasks(task.OwnerMask, objflags);
639 ~(PrimFlags.ObjectCopy | // Tells client you can copy the object 696 returnMask |= EXTRAOWNERMASK;
640 PrimFlags.ObjectModify | // tells client you can modify the object 697 if((returnMask & (uint)PrimFlags.ObjectModify) != 0)
641 PrimFlags.ObjectMove | // tells client that you can move the object (only, no mod) 698 returnMask |= (uint)PrimFlags.ObjectOwnerModify;
642 PrimFlags.ObjectTransfer | // tells the client that you can /take/ the object if you don't own it 699 return returnMask;
643 PrimFlags.ObjectYouOwner | // Tells client that you're the owner of the object 700 }
644 PrimFlags.ObjectAnyOwner | // Tells client that someone owns the object
645 PrimFlags.ObjectOwnerModify | // Tells client that you're the owner of the object
646 PrimFlags.ObjectYouOfficer // Tells client that you've got group object editing permission. Used when ObjectGroupOwned is set
647 );
648#pragma warning restore 0612
649 701
650 // Creating the three ObjectFlags options for this method to choose from. 702 UUID taskOwnerID = task.OwnerID;
651 // Customize the OwnerMask 703 UUID spID = sp.UUID;
652 uint objectOwnerMask = ApplyObjectModifyMasks(task.OwnerMask, objflags);
653 objectOwnerMask |= (uint)PrimFlags.ObjectYouOwner | (uint)PrimFlags.ObjectAnyOwner | (uint)PrimFlags.ObjectOwnerModify;
654 704
655 // Customize the GroupMask 705 // owner
656 uint objectGroupMask = ApplyObjectModifyMasks(task.GroupMask, objflags); 706 if (spID == taskOwnerID)
707 {
708 returnMask = ApplyObjectModifyMasks(task.OwnerMask, objflags);
709 returnMask |= EXTRAOWNERMASK;
710 if((returnMask & (uint)PrimFlags.ObjectModify) != 0)
711 returnMask |= (uint)PrimFlags.ObjectOwnerModify;
712 return returnMask;
713 }
657 714
658 // Customize the EveryoneMask 715 // if not god or owner, do attachments as everyone
659 uint objectEveryoneMask = ApplyObjectModifyMasks(task.EveryoneMask, objflags); 716 if(task.ParentGroup.IsAttachment)
660 if (objectOwner != UUID.Zero) 717 {
661 objectEveryoneMask |= (uint)PrimFlags.ObjectAnyOwner; 718 returnMask = ApplyObjectModifyMasks(task.EveryoneMask, objflags);
719 if (taskOwnerID != UUID.Zero)
720 returnMask |= (uint)PrimFlags.ObjectAnyOwner;
721 return returnMask;
722 }
662 723
663 PermissionClass permissionClass = GetPermissionClass(user, task); 724 // if friends with rights then owner
725 if (IsFriendWithPerms(spID, taskOwnerID))
726 {
727 returnMask = ApplyObjectModifyMasks(task.OwnerMask, objflags);
728 returnMask |= EXTRAOWNERMASK;
729 if((returnMask & (uint)PrimFlags.ObjectModify) != 0)
730 returnMask |= (uint)PrimFlags.ObjectOwnerModify;
731 return returnMask;
732 }
664 733
665 switch (permissionClass) 734 // group owned or shared ?
735 UUID taskGroupID = task.GroupID;
736 IClientAPI client = sp.ControllingClient;
737 if(taskGroupID != UUID.Zero && client != null && client.IsGroupMember(taskGroupID))
666 { 738 {
667 case PermissionClass.Owner: 739 if(taskGroupID == taskOwnerID)
668 return objectOwnerMask; 740 {
669 case PermissionClass.Group: 741 // object is owned by group, owner rights and group role powers do apply
670 return objectGroupMask | objectEveryoneMask; 742 if((client.GetGroupPowers(taskGroupID) & (ulong)GroupPowers.ObjectManipulate) != 0)
671 case PermissionClass.Everyone: 743 // instead forcing active group can be safeguard againts casual mistakes ??
672 default: 744 //if(CheckActiveGroupPowers(sp, task.GroupID, (ulong)GroupPowers.ObjectManipulate))
673 return objectEveryoneMask; 745 {
746 returnMask = ApplyObjectModifyMasks(task.OwnerMask, objflags);
747 returnMask |=
748 (uint)PrimFlags.ObjectGroupOwned |
749 (uint)PrimFlags.ObjectAnyOwner;
750 if((returnMask & (uint)PrimFlags.ObjectModify) != 0)
751 returnMask |= (uint)PrimFlags.ObjectOwnerModify;
752 return returnMask;
753 }
754 else
755 {
756 // no special rights
757 returnMask = ApplyObjectModifyMasks(task.EveryoneMask, objflags);
758 returnMask |= (uint)PrimFlags.ObjectAnyOwner;
759 return returnMask;
760 }
761 }
762 else
763 {
764 // group sharing
765 returnMask = ApplyObjectModifyMasks(task.GroupMask, objflags);
766 if (taskOwnerID != UUID.Zero)
767 returnMask |= (uint)PrimFlags.ObjectAnyOwner;
768 return returnMask;
769 }
674 } 770 }
771
772 // fallback is everyone rights
773 returnMask = ApplyObjectModifyMasks(task.EveryoneMask, objflags);
774 if (taskOwnerID != UUID.Zero)
775 returnMask |= (uint)PrimFlags.ObjectAnyOwner;
776 return returnMask;
675 } 777 }
676 778
677 private uint ApplyObjectModifyMasks(uint setPermissionMask, uint objectFlagsMask) 779 private uint ApplyObjectModifyMasks(uint setPermissionMask, uint objectFlagsMask)
@@ -702,6 +804,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions
702 return objectFlagsMask; 804 return objectFlagsMask;
703 } 805 }
704 806
807 // OARs need this method that handles offline users
705 public PermissionClass GetPermissionClass(UUID user, SceneObjectPart obj) 808 public PermissionClass GetPermissionClass(UUID user, SceneObjectPart obj)
706 { 809 {
707 if (obj == null) 810 if (obj == null)
@@ -715,31 +818,19 @@ namespace OpenSim.Region.CoreModules.World.Permissions
715 if (user == objectOwner) 818 if (user == objectOwner)
716 return PermissionClass.Owner; 819 return PermissionClass.Owner;
717 820
718 if (IsFriendWithPerms(user, objectOwner) && !obj.ParentGroup.IsAttachment)
719 return PermissionClass.Owner;
720
721 // Estate users should be able to edit anything in the sim if RegionOwnerIsGod is set
722 if (m_RegionOwnerIsGod && IsEstateManager(user) && !IsAdministrator(objectOwner))
723 return PermissionClass.Owner;
724
725 // Admin should be able to edit anything in the sim (including admin objects) 821 // Admin should be able to edit anything in the sim (including admin objects)
726 if (IsAdministrator(user)) 822 if (IsAdministrator(user))
727 return PermissionClass.Owner; 823 return PermissionClass.Owner;
728 824
729/* to review later 825 if(!obj.ParentGroup.IsAttachment)
730 // Users should be able to edit what is over their land.
731 Vector3 taskPos = obj.AbsolutePosition;
732 ILandObject parcel = m_scene.LandChannel.GetLandObject(taskPos.X, taskPos.Y);
733 if (parcel != null && parcel.LandData.OwnerID == user && m_ParcelOwnerIsGod)
734 { 826 {
735 // Admin objects should not be editable by the above 827 if (IsFriendWithPerms(user, objectOwner) )
736 if (!IsAdministrator(objectOwner))
737 return PermissionClass.Owner; 828 return PermissionClass.Owner;
829
830 // Group permissions
831 if (obj.GroupID != UUID.Zero && IsGroupMember(obj.GroupID, user, 0))
832 return PermissionClass.Group;
738 } 833 }
739*/
740 // Group permissions
741 if ((obj.GroupID != UUID.Zero) && IsGroupMember(obj.GroupID, user, 0))
742 return PermissionClass.Group;
743 834
744 return PermissionClass.Everyone; 835 return PermissionClass.Everyone;
745 } 836 }
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs b/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs
index 893b38c..e045c43 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs
@@ -37,7 +37,7 @@ using OpenSim.Region.Framework.Interfaces;
37namespace OpenSim.Region.Framework.Scenes 37namespace OpenSim.Region.Framework.Scenes
38{ 38{
39 #region Delegates 39 #region Delegates
40 public delegate uint GenerateClientFlagsHandler(UUID userID, UUID objectID); 40 public delegate uint GenerateClientFlagsHandler(ScenePresence sp, uint curEffectivePerms, UUID objectID);
41 public delegate void SetBypassPermissionsHandler(bool value); 41 public delegate void SetBypassPermissionsHandler(bool value);
42 public delegate bool BypassPermissionsHandler(); 42 public delegate bool BypassPermissionsHandler();
43 public delegate bool PropagatePermissionsHandler(); 43 public delegate bool PropagatePermissionsHandler();
@@ -167,7 +167,7 @@ namespace OpenSim.Region.Framework.Scenes
167 167
168 #region Object Permission Checks 168 #region Object Permission Checks
169 169
170 public uint GenerateClientFlags(UUID userID, UUID objectID) 170 public uint GenerateClientFlags(ScenePresence sp, UUID objectID)
171 { 171 {
172 // libomv will moan about PrimFlags.ObjectYouOfficer being 172 // libomv will moan about PrimFlags.ObjectYouOfficer being
173 // obsolete... 173 // obsolete...
@@ -179,8 +179,7 @@ namespace OpenSim.Region.Framework.Scenes
179 PrimFlags.ObjectTransfer | 179 PrimFlags.ObjectTransfer |
180 PrimFlags.ObjectYouOwner | 180 PrimFlags.ObjectYouOwner |
181 PrimFlags.ObjectAnyOwner | 181 PrimFlags.ObjectAnyOwner |
182 PrimFlags.ObjectOwnerModify | 182 PrimFlags.ObjectOwnerModify;
183 PrimFlags.ObjectYouOfficer;
184#pragma warning restore 0612 183#pragma warning restore 0612
185 184
186 SceneObjectPart part = m_scene.GetSceneObjectPart(objectID); 185 SceneObjectPart part = m_scene.GetSceneObjectPart(objectID);
@@ -196,7 +195,7 @@ namespace OpenSim.Region.Framework.Scenes
196 Delegate[] list = handlerGenerateClientFlags.GetInvocationList(); 195 Delegate[] list = handlerGenerateClientFlags.GetInvocationList();
197 foreach (GenerateClientFlagsHandler check in list) 196 foreach (GenerateClientFlagsHandler check in list)
198 { 197 {
199 perms &= check(userID, objectID); 198 perms &= check(sp, perms, objectID);
200 } 199 }
201 } 200 }
202 return perms; 201 return perms;
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index 5928764..bf991c6 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -2233,7 +2233,8 @@ namespace OpenSim.Region.Framework.Scenes
2233 { 2233 {
2234 if (part.OwnerID != userId) 2234 if (part.OwnerID != userId)
2235 { 2235 {
2236 part.LastOwnerID = part.OwnerID; 2236 if(part.GroupID != part.OwnerID)
2237 part.LastOwnerID = part.OwnerID;
2237 part.OwnerID = userId; 2238 part.OwnerID = userId;
2238 } 2239 }
2239 }); 2240 });