aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region
diff options
context:
space:
mode:
authorOren Hurvitz2011-09-11 20:52:35 +0300
committerJustin Clark-Casey (justincc)2011-09-12 20:09:24 +0100
commit7f318277f141a73207ec64f8521ba410a5743215 (patch)
tree89849beca9ee1db46db00993b571e363355b4628 /OpenSim/Region
parentminor: put <remarks> tags around some method doc (diff)
downloadopensim-SC-7f318277f141a73207ec64f8521ba410a5743215.zip
opensim-SC-7f318277f141a73207ec64f8521ba410a5743215.tar.gz
opensim-SC-7f318277f141a73207ec64f8521ba410a5743215.tar.bz2
opensim-SC-7f318277f141a73207ec64f8521ba410a5743215.tar.xz
When creating an OAR, optionally exclude objects according to their permissions
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/Application/OpenSim.cs10
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs106
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs1
-rw-r--r--OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs89
-rw-r--r--OpenSim/Region/Framework/Interfaces/IPermissionsModule.cs54
5 files changed, 216 insertions, 44 deletions
diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs
index fe1525b..e5b9dcb 100644
--- a/OpenSim/Region/Application/OpenSim.cs
+++ b/OpenSim/Region/Application/OpenSim.cs
@@ -269,13 +269,15 @@ namespace OpenSim
269 269
270 m_console.Commands.AddCommand("region", false, "save oar", 270 m_console.Commands.AddCommand("region", false, "save oar",
271 //"save oar [-v|--version=<N>] [-p|--profile=<url>] [<OAR path>]", 271 //"save oar [-v|--version=<N>] [-p|--profile=<url>] [<OAR path>]",
272 "save oar [-p|--profile=<url>] [--noassets] [<OAR path>]", 272 "save oar [-p|--profile=<url>] [--noassets] [--perm=<permissions>] [<OAR path>]",
273 "Save a region's data to an OAR archive.", 273 "Save a region's data to an OAR archive.",
274// "-v|--version=<N> generates scene objects as per older versions of the serialization (e.g. -v=0)" + Environment.NewLine 274// "-v|--version=<N> generates scene objects as per older versions of the serialization (e.g. -v=0)" + Environment.NewLine
275 "-p|--profile=<url> adds the url of the profile service to the saved user information." + Environment.NewLine 275 "-p|--profile=<url> adds the url of the profile service to the saved user information." + Environment.NewLine
276 + " The OAR path must be a filesystem path." 276 + "--noassets stops assets being saved to the OAR." + Environment.NewLine
277 + " If this is not given then the oar is saved to region.oar in the current directory." + Environment.NewLine 277 + "--perm stops objects with insufficient permissions from being saved to the OAR." + Environment.NewLine
278 + "--noassets stops assets being saved to the OAR.", 278 + " <permissions> can contain one or more of these characters: \"C\" = Copy, \"T\" = Transfer" + Environment.NewLine
279 + "The OAR path must be a filesystem path."
280 + " If this is not given then the oar is saved to region.oar in the current directory.",
279 SaveOar); 281 SaveOar);
280 282
281 m_console.Commands.AddCommand("region", false, "edit scale", 283 m_console.Commands.AddCommand("region", false, "edit scale",
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
40namespace OpenSim.Region.CoreModules.World.Permissions 40namespace 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.
diff --git a/OpenSim/Region/Framework/Interfaces/IPermissionsModule.cs b/OpenSim/Region/Framework/Interfaces/IPermissionsModule.cs
new file mode 100644
index 0000000..1ed978b
--- /dev/null
+++ b/OpenSim/Region/Framework/Interfaces/IPermissionsModule.cs
@@ -0,0 +1,54 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using OpenMetaverse;
29using OpenSim.Region.Framework.Scenes;
30
31namespace OpenSim.Region.Framework.Interfaces
32{
33 /// <value>
34 /// Which set of permissions a user has.
35 /// </value>
36 public enum PermissionClass
37 {
38 Owner,
39 Group,
40 Everyone
41 };
42
43 public interface IPermissionsModule
44 {
45
46 /// <summary>
47 /// Returns the type of permissions that the user has over an object.
48 /// </summary>
49 /// <param name="user">The user</param>
50 /// <param name="obj">The object</param>
51 /// <returns>The type of permissions the user has over the object</returns>
52 PermissionClass GetPermissionClass(UUID user, SceneObjectPart obj);
53 }
54}