diff options
author | Oren Hurvitz | 2011-09-11 20:52:35 +0300 |
---|---|---|
committer | Justin Clark-Casey (justincc) | 2011-09-12 20:09:24 +0100 |
commit | 7f318277f141a73207ec64f8521ba410a5743215 (patch) | |
tree | 89849beca9ee1db46db00993b571e363355b4628 /OpenSim/Region/CoreModules | |
parent | minor: put <remarks> tags around some method doc (diff) | |
download | opensim-SC_OLD-7f318277f141a73207ec64f8521ba410a5743215.zip opensim-SC_OLD-7f318277f141a73207ec64f8521ba410a5743215.tar.gz opensim-SC_OLD-7f318277f141a73207ec64f8521ba410a5743215.tar.bz2 opensim-SC_OLD-7f318277f141a73207ec64f8521ba410a5743215.tar.xz |
When creating an OAR, optionally exclude objects according to their permissions
Diffstat (limited to 'OpenSim/Region/CoreModules')
3 files changed, 156 insertions, 40 deletions
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs index 10a83ee..b895afe 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs | |||
@@ -127,6 +127,12 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
127 | 127 | ||
128 | EntityBase[] entities = m_scene.GetEntities(); | 128 | EntityBase[] entities = m_scene.GetEntities(); |
129 | List<SceneObjectGroup> sceneObjects = new List<SceneObjectGroup>(); | 129 | List<SceneObjectGroup> sceneObjects = new List<SceneObjectGroup>(); |
130 | |||
131 | string checkPermissions = null; | ||
132 | int numObjectsSkippedPermissions = 0; | ||
133 | Object temp; | ||
134 | if (options.TryGetValue("checkPermissions", out temp)) | ||
135 | checkPermissions = (string)temp; | ||
130 | 136 | ||
131 | // Filter entities so that we only have scene objects. | 137 | // Filter entities so that we only have scene objects. |
132 | // FIXME: Would be nicer to have this as a proper list in SceneGraph, since lots of methods | 138 | // FIXME: Would be nicer to have this as a proper list in SceneGraph, since lots of methods |
@@ -136,9 +142,19 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
136 | if (entity is SceneObjectGroup) | 142 | if (entity is SceneObjectGroup) |
137 | { | 143 | { |
138 | SceneObjectGroup sceneObject = (SceneObjectGroup)entity; | 144 | SceneObjectGroup sceneObject = (SceneObjectGroup)entity; |
139 | 145 | ||
140 | if (!sceneObject.IsDeleted && !sceneObject.IsAttachment) | 146 | if (!sceneObject.IsDeleted && !sceneObject.IsAttachment) |
141 | sceneObjects.Add((SceneObjectGroup)entity); | 147 | { |
148 | if (!CanUserArchiveObject(m_scene.RegionInfo.EstateSettings.EstateOwner, sceneObject, checkPermissions)) | ||
149 | { | ||
150 | // The user isn't allowed to copy/transfer this object, so it will not be included in the OAR. | ||
151 | ++numObjectsSkippedPermissions; | ||
152 | } | ||
153 | else | ||
154 | { | ||
155 | sceneObjects.Add(sceneObject); | ||
156 | } | ||
157 | } | ||
142 | } | 158 | } |
143 | } | 159 | } |
144 | 160 | ||
@@ -159,7 +175,14 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
159 | { | 175 | { |
160 | m_log.DebugFormat("[ARCHIVER]: Not saving assets since --noassets was specified"); | 176 | m_log.DebugFormat("[ARCHIVER]: Not saving assets since --noassets was specified"); |
161 | } | 177 | } |
162 | 178 | ||
179 | if (numObjectsSkippedPermissions > 0) | ||
180 | { | ||
181 | m_log.DebugFormat( | ||
182 | "[ARCHIVER]: {0} scene objects skipped due to lack of permissions", | ||
183 | numObjectsSkippedPermissions); | ||
184 | } | ||
185 | |||
163 | // Make sure that we also request terrain texture assets | 186 | // Make sure that we also request terrain texture assets |
164 | RegionSettings regionSettings = m_scene.RegionInfo.RegionSettings; | 187 | RegionSettings regionSettings = m_scene.RegionInfo.RegionSettings; |
165 | 188 | ||
@@ -211,6 +234,83 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
211 | } | 234 | } |
212 | 235 | ||
213 | /// <summary> | 236 | /// <summary> |
237 | /// Checks whether the user has permission to export an object group to an OAR. | ||
238 | /// </summary> | ||
239 | /// <param name="user">The user</param> | ||
240 | /// <param name="objGroup">The object group</param> | ||
241 | /// <param name="checkPermissions">Which permissions to check: "C" = Copy, "T" = Transfer</param> | ||
242 | /// <returns>Whether the user is allowed to export the object to an OAR</returns> | ||
243 | private bool CanUserArchiveObject(UUID user, SceneObjectGroup objGroup, string checkPermissions) | ||
244 | { | ||
245 | if (checkPermissions == null) | ||
246 | return true; | ||
247 | |||
248 | IPermissionsModule module = m_scene.RequestModuleInterface<IPermissionsModule>(); | ||
249 | if (module == null) | ||
250 | return true; // this shouldn't happen | ||
251 | |||
252 | // Check whether the user is permitted to export all of the parts in the SOG. If any | ||
253 | // part can't be exported then the entire SOG can't be exported. | ||
254 | |||
255 | bool permitted = true; | ||
256 | //int primNumber = 1; | ||
257 | |||
258 | foreach (SceneObjectPart obj in objGroup.Parts) | ||
259 | { | ||
260 | uint perm; | ||
261 | PermissionClass permissionClass = module.GetPermissionClass(user, obj); | ||
262 | switch (permissionClass) | ||
263 | { | ||
264 | case PermissionClass.Owner: | ||
265 | perm = obj.BaseMask; | ||
266 | break; | ||
267 | case PermissionClass.Group: | ||
268 | perm = obj.GroupMask | obj.EveryoneMask; | ||
269 | break; | ||
270 | case PermissionClass.Everyone: | ||
271 | default: | ||
272 | perm = obj.EveryoneMask; | ||
273 | break; | ||
274 | } | ||
275 | |||
276 | bool canCopy = (perm & (uint)PermissionMask.Copy) != 0; | ||
277 | bool canTransfer = (perm & (uint)PermissionMask.Transfer) != 0; | ||
278 | |||
279 | // Special case: if Everyone can copy the object then this implies it can also be | ||
280 | // Transferred. | ||
281 | // However, if the user is the Owner then we don't check EveryoneMask, because it seems that the mask | ||
282 | // always (incorrectly) includes the Copy bit set in this case. But that's a mistake: the viewer | ||
283 | // does NOT show that the object has Everyone-Copy permissions, and doesn't allow it to be copied. | ||
284 | if (permissionClass != PermissionClass.Owner) | ||
285 | { | ||
286 | canTransfer |= (obj.EveryoneMask & (uint)PermissionMask.Copy) != 0; | ||
287 | } | ||
288 | |||
289 | |||
290 | bool partPermitted = true; | ||
291 | if (checkPermissions.Contains("C") && !canCopy) | ||
292 | partPermitted = false; | ||
293 | if (checkPermissions.Contains("T") && !canTransfer) | ||
294 | partPermitted = false; | ||
295 | |||
296 | //string name = (objGroup.PrimCount == 1) ? objGroup.Name : string.Format("{0} ({1}/{2})", obj.Name, primNumber, objGroup.PrimCount); | ||
297 | //m_log.DebugFormat("[ARCHIVER]: Object permissions: {0}: Base={1:X4}, Owner={2:X4}, Everyone={3:X4}, permissionClass={4}, checkPermissions={5}, canCopy={6}, canTransfer={7}, permitted={8}", | ||
298 | // name, obj.BaseMask, obj.OwnerMask, obj.EveryoneMask, | ||
299 | // permissionClass, checkPermissions, canCopy, canTransfer, permitted); | ||
300 | |||
301 | if (!partPermitted) | ||
302 | { | ||
303 | permitted = false; | ||
304 | break; | ||
305 | } | ||
306 | |||
307 | //++primNumber; | ||
308 | } | ||
309 | |||
310 | return permitted; | ||
311 | } | ||
312 | |||
313 | /// <summary> | ||
214 | /// Create the control file for the most up to date archive | 314 | /// Create the control file for the most up to date archive |
215 | /// </summary> | 315 | /// </summary> |
216 | /// <returns></returns> | 316 | /// <returns></returns> |
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs index 08eb80c..f44a3ba 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs | |||
@@ -128,6 +128,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
128 | // ops.Add("v|version=", delegate(string v) { options["version"] = v; }); | 128 | // ops.Add("v|version=", delegate(string v) { options["version"] = v; }); |
129 | ops.Add("p|profile=", delegate(string v) { options["profile"] = v; }); | 129 | ops.Add("p|profile=", delegate(string v) { options["profile"] = v; }); |
130 | ops.Add("noassets", delegate(string v) { options["noassets"] = v != null; }); | 130 | ops.Add("noassets", delegate(string v) { options["noassets"] = v != null; }); |
131 | ops.Add("perm=", delegate(string v) { options["checkPermissions"] = v; }); | ||
131 | 132 | ||
132 | List<string> mainParams = ops.Parse(cmdparams); | 133 | List<string> mainParams = ops.Parse(cmdparams); |
133 | 134 | ||
diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs index b9bd9a4..3b661ed 100644 --- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs +++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs | |||
@@ -39,7 +39,7 @@ using OpenSim.Services.Interfaces; | |||
39 | 39 | ||
40 | namespace OpenSim.Region.CoreModules.World.Permissions | 40 | namespace OpenSim.Region.CoreModules.World.Permissions |
41 | { | 41 | { |
42 | public class PermissionsModule : IRegionModule | 42 | public class PermissionsModule : IRegionModule, IPermissionsModule |
43 | { | 43 | { |
44 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 44 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
45 | 45 | ||
@@ -150,6 +150,8 @@ namespace OpenSim.Region.CoreModules.World.Permissions | |||
150 | else | 150 | else |
151 | m_log.Debug("[PERMISSIONS]: Enabling all region service permission checks"); | 151 | m_log.Debug("[PERMISSIONS]: Enabling all region service permission checks"); |
152 | 152 | ||
153 | scene.RegisterModuleInterface<IPermissionsModule>(this); | ||
154 | |||
153 | //Register functions with Scene External Checks! | 155 | //Register functions with Scene External Checks! |
154 | m_scene.Permissions.OnBypassPermissions += BypassPermissions; | 156 | m_scene.Permissions.OnBypassPermissions += BypassPermissions; |
155 | m_scene.Permissions.OnSetBypassPermissions += SetBypassPermissions; | 157 | m_scene.Permissions.OnSetBypassPermissions += SetBypassPermissions; |
@@ -574,46 +576,18 @@ namespace OpenSim.Region.CoreModules.World.Permissions | |||
574 | if (objectOwner != UUID.Zero) | 576 | if (objectOwner != UUID.Zero) |
575 | objectEveryoneMask |= (uint)PrimFlags.ObjectAnyOwner; | 577 | objectEveryoneMask |= (uint)PrimFlags.ObjectAnyOwner; |
576 | 578 | ||
577 | if (m_bypassPermissions) | 579 | PermissionClass permissionClass = GetPermissionClass(user, task); |
578 | return objectOwnerMask; | ||
579 | |||
580 | // Object owners should be able to edit their own content | ||
581 | if (user == objectOwner) | ||
582 | return objectOwnerMask; | ||
583 | |||
584 | if (IsFriendWithPerms(user, objectOwner)) | ||
585 | { | ||
586 | return objectOwnerMask; | ||
587 | } | ||
588 | // Estate users should be able to edit anything in the sim if RegionOwnerIsGod is set | ||
589 | if (m_RegionOwnerIsGod && IsEstateManager(user) && !IsAdministrator(objectOwner)) | ||
590 | { | ||
591 | return objectOwnerMask; | ||
592 | } | ||
593 | |||
594 | // Admin should be able to edit anything in the sim (including admin objects) | ||
595 | if (IsAdministrator(user)) | ||
596 | { | ||
597 | return objectOwnerMask; | ||
598 | } | ||
599 | 580 | ||
600 | // Users should be able to edit what is over their land. | 581 | switch (permissionClass) |
601 | Vector3 taskPos = task.AbsolutePosition; | ||
602 | ILandObject parcel = m_scene.LandChannel.GetLandObject(taskPos.X, taskPos.Y); | ||
603 | if (parcel != null && parcel.LandData.OwnerID == user && m_ParcelOwnerIsGod) | ||
604 | { | 582 | { |
605 | // Admin objects should not be editable by the above | 583 | case PermissionClass.Owner: |
606 | if (!IsAdministrator(objectOwner)) | ||
607 | { | ||
608 | return objectOwnerMask; | 584 | return objectOwnerMask; |
609 | } | 585 | case PermissionClass.Group: |
586 | return objectGroupMask | objectEveryoneMask; | ||
587 | case PermissionClass.Everyone: | ||
588 | default: | ||
589 | return objectEveryoneMask; | ||
610 | } | 590 | } |
611 | |||
612 | // Group permissions | ||
613 | if ((task.GroupID != UUID.Zero) && IsGroupMember(task.GroupID, user, 0)) | ||
614 | return objectGroupMask | objectEveryoneMask; | ||
615 | |||
616 | return objectEveryoneMask; | ||
617 | } | 591 | } |
618 | 592 | ||
619 | private uint ApplyObjectModifyMasks(uint setPermissionMask, uint objectFlagsMask) | 593 | private uint ApplyObjectModifyMasks(uint setPermissionMask, uint objectFlagsMask) |
@@ -644,6 +618,47 @@ namespace OpenSim.Region.CoreModules.World.Permissions | |||
644 | return objectFlagsMask; | 618 | return objectFlagsMask; |
645 | } | 619 | } |
646 | 620 | ||
621 | public PermissionClass GetPermissionClass(UUID user, SceneObjectPart obj) | ||
622 | { | ||
623 | if (obj == null) | ||
624 | return PermissionClass.Everyone; | ||
625 | |||
626 | if (m_bypassPermissions) | ||
627 | return PermissionClass.Owner; | ||
628 | |||
629 | // Object owners should be able to edit their own content | ||
630 | UUID objectOwner = obj.OwnerID; | ||
631 | if (user == objectOwner) | ||
632 | return PermissionClass.Owner; | ||
633 | |||
634 | if (IsFriendWithPerms(user, objectOwner)) | ||
635 | return PermissionClass.Owner; | ||
636 | |||
637 | // Estate users should be able to edit anything in the sim if RegionOwnerIsGod is set | ||
638 | if (m_RegionOwnerIsGod && IsEstateManager(user) && !IsAdministrator(objectOwner)) | ||
639 | return PermissionClass.Owner; | ||
640 | |||
641 | // Admin should be able to edit anything in the sim (including admin objects) | ||
642 | if (IsAdministrator(user)) | ||
643 | return PermissionClass.Owner; | ||
644 | |||
645 | // Users should be able to edit what is over their land. | ||
646 | Vector3 taskPos = obj.AbsolutePosition; | ||
647 | ILandObject parcel = m_scene.LandChannel.GetLandObject(taskPos.X, taskPos.Y); | ||
648 | if (parcel != null && parcel.LandData.OwnerID == user && m_ParcelOwnerIsGod) | ||
649 | { | ||
650 | // Admin objects should not be editable by the above | ||
651 | if (!IsAdministrator(objectOwner)) | ||
652 | return PermissionClass.Owner; | ||
653 | } | ||
654 | |||
655 | // Group permissions | ||
656 | if ((obj.GroupID != UUID.Zero) && IsGroupMember(obj.GroupID, user, 0)) | ||
657 | return PermissionClass.Group; | ||
658 | |||
659 | return PermissionClass.Everyone; | ||
660 | } | ||
661 | |||
647 | /// <summary> | 662 | /// <summary> |
648 | /// General permissions checks for any operation involving an object. These supplement more specific checks | 663 | /// General permissions checks for any operation involving an object. These supplement more specific checks |
649 | /// implemented by callers. | 664 | /// implemented by callers. |