From 5699bb2e64766da634ca4be34bc2d8eab991f2e1 Mon Sep 17 00:00:00 2001 From: Adam Frisby Date: Wed, 15 Aug 2007 14:10:26 +0000 Subject: [PATCH] * Permissions! - You can now only perform certain functions (such as editing other peoples objects) if you have permission to do so. * Moved OnPermissionError to EventManager - now triggers a standard blue alert. * Terraforming now requires permission via the permissions manager. [Defaults to admin-only] * Permissions manager is now substantiated in Scene * Buttload of new permissions added. * Estate manager operations now require various levels of permission to operate * OGS1 now produces 'summary reports' for a commsManager of each scene it maintains connections for. Reduces grid network traffic for ping checks. * Added new "permissions true" / "permissions false" console command to enable or disable permissions. --- OpenSim/Region/Application/OpenSimMain.cs | 11 ++ .../Communications/OGS1/OGS1GridServices.cs | 10 ++ OpenSim/Region/Environment/EstateManager.cs | 48 +++---- .../Region/Environment/PermissionManager.cs | 119 ++++++++++++++++-- .../Scenes/Scene.PacketHandlers.cs | 42 ++++--- OpenSim/Region/Environment/Scenes/Scene.cs | 16 +++ .../Region/Environment/Scenes/SceneEvents.cs | 9 ++ 7 files changed, 208 insertions(+), 47 deletions(-) diff --git a/OpenSim/Region/Application/OpenSimMain.cs b/OpenSim/Region/Application/OpenSimMain.cs index 887db67d23..9f95e01537 100644 --- a/OpenSim/Region/Application/OpenSimMain.cs +++ b/OpenSim/Region/Application/OpenSimMain.cs @@ -320,6 +320,17 @@ namespace OpenSim } break; + case "permissions": + // Treats each user as a super-admin when disabled + foreach (Scene scene in m_localScenes) + { + if (Convert.ToBoolean(cmdparams[0])) + scene.PermissionsMngr.EnablePermissions(); + else + scene.PermissionsMngr.DisablePermissions(); + } + break; + case "backup": foreach (Scene scene in m_localScenes) { diff --git a/OpenSim/Region/Communications/OGS1/OGS1GridServices.cs b/OpenSim/Region/Communications/OGS1/OGS1GridServices.cs index 32b0cfc2b0..071ad0f21e 100644 --- a/OpenSim/Region/Communications/OGS1/OGS1GridServices.cs +++ b/OpenSim/Region/Communications/OGS1/OGS1GridServices.cs @@ -260,6 +260,16 @@ namespace OpenSim.Region.Communications.OGS1 Hashtable respData = new Hashtable(); respData["online"] = "true"; + foreach (ulong region in this.listeners.Keys) + { + Hashtable regData = new Hashtable(); + RegionInfo reg = regions[region]; + regData["status"] = "active"; + regData["handle"] = region.ToString(); + + respData[reg.SimUUID.ToStringHyphenated()] = regData; + } + response.Value = respData; return response; diff --git a/OpenSim/Region/Environment/EstateManager.cs b/OpenSim/Region/Environment/EstateManager.cs index 83bfbb4ab6..447a22c8ac 100644 --- a/OpenSim/Region/Environment/EstateManager.cs +++ b/OpenSim/Region/Environment/EstateManager.cs @@ -147,35 +147,37 @@ namespace OpenSim.Region.Environment public void handleEstateOwnerMessage(EstateOwnerMessagePacket packet, IClientAPI remote_client) { - if (remote_client.AgentId == m_regInfo.MasterAvatarAssignedUUID) + switch (Helpers.FieldToUTF8String(packet.MethodData.Method)) { - switch (Helpers.FieldToUTF8String(packet.MethodData.Method)) - { - case "getinfo": - this.sendRegionInfoPacketToAll(); - break; - case "setregioninfo": + case "getinfo": + this.sendRegionInfoPacketToAll(); + break; + case "setregioninfo": + if (m_scene.PermissionsMngr.CanEditEstateTerrain(remote_client.AgentId)) estateSetRegionInfoHandler(packet); - break; - case "texturebase": + break; + case "texturebase": + if (m_scene.PermissionsMngr.CanEditEstateTerrain(remote_client.AgentId)) estateTextureBaseHandler(packet); - break; - case "texturedetail": + break; + case "texturedetail": + if (m_scene.PermissionsMngr.CanEditEstateTerrain(remote_client.AgentId)) estateTextureDetailHandler(packet); - break; - case "textureheights": + break; + case "textureheights": + if (m_scene.PermissionsMngr.CanEditEstateTerrain(remote_client.AgentId)) estateTextureHeightsHandler(packet); - break; - case "texturecommit": - sendRegionHandshakeToAll(); - break; - case "setregionterrain": + break; + case "texturecommit": + sendRegionHandshakeToAll(); + break; + case "setregionterrain": + if (m_scene.PermissionsMngr.CanEditEstateTerrain(remote_client.AgentId)) estateSetRegionTerrainHandler(packet); - break; - default: - MainLog.Instance.Error("EstateOwnerMessage: Unknown method requested\n" + packet.ToString()); - break; - } + break; + default: + MainLog.Instance.Error("EstateOwnerMessage: Unknown method requested\n" + packet.ToString()); + break; } } diff --git a/OpenSim/Region/Environment/PermissionManager.cs b/OpenSim/Region/Environment/PermissionManager.cs index 07585668b2..2698d3f2b6 100644 --- a/OpenSim/Region/Environment/PermissionManager.cs +++ b/OpenSim/Region/Environment/PermissionManager.cs @@ -15,36 +15,80 @@ namespace OpenSim.Region.Environment { protected Scene m_scene; + // Bypasses the permissions engine (always returns OK) + // disable in any production environment + // TODO: Change this to false when permissions are a desired default + // TODO: Move to configuration option. + private bool bypassPermissions = true; + public PermissionManager(Scene scene) { m_scene = scene; } - public delegate void OnPermissionErrorDelegate(LLUUID user, string reason); - public event OnPermissionErrorDelegate OnPermissionError; + public void DisablePermissions() + { + bypassPermissions = true; + } + + public void EnablePermissions() + { + bypassPermissions = false; + } protected virtual void SendPermissionError(LLUUID user, string reason) { - if (OnPermissionError != null) - OnPermissionError(user, reason); + m_scene.EventManager.TriggerPermissionError(user, reason); } protected virtual bool IsAdministrator(LLUUID user) { + if (bypassPermissions) + return bypassPermissions; + return m_scene.RegionInfo.MasterAvatarAssignedUUID == user; } protected virtual bool IsEstateManager(LLUUID user) + { + if (bypassPermissions) + return bypassPermissions; + + return false; + } + + protected virtual bool IsGridUser(LLUUID user) + { + return true; + } + + protected virtual bool IsGuest(LLUUID user) { return false; } public virtual bool CanRezObject(LLUUID user, LLVector3 position) { + bool permission = false; + + string reason = "Insufficient permission"; + + if (IsAdministrator(user)) + permission = true; + else + reason = "Not an administrator"; + + if (GenericParcelPermission(user, position)) + permission = true; + else + reason = "Not the parcel owner"; + + if (!permission) + SendPermissionError(user, reason); + return true; } - #region Object Permissions protected virtual bool GenericObjectPermission(LLUUID user, LLUUID obj) @@ -105,19 +149,71 @@ namespace OpenSim.Region.Environment #endregion + #region Communication Permissions + + public virtual bool GenericCommunicationPermission(LLUUID user, LLUUID target) + { + bool permission = false; + string reason = "Only registered users may communicate with another account."; + + if (IsGridUser(user)) + permission = true; + + if (!IsGridUser(user)) + { + permission = false; + reason = "The person that you are messaging is not a registered user."; + } + if (IsAdministrator(user)) + permission = true; + + if (IsEstateManager(user)) + permission = true; + + if (!permission) + SendPermissionError(user, reason); + + return permission; + } + + public virtual bool CanInstantMessage(LLUUID user, LLUUID target) + { + return GenericCommunicationPermission(user, target); + } + + public virtual bool CanInventoryTransfer(LLUUID user, LLUUID target) + { + return GenericCommunicationPermission(user, target); + } + + #endregion + public virtual bool CanEditScript(LLUUID user, LLUUID script) { - return false; + return IsAdministrator(user); } public virtual bool CanRunScript(LLUUID user, LLUUID script) { - return false; + return IsAdministrator(user); } - public virtual bool CanTerraform(LLUUID user, LLUUID position) + public virtual bool CanTerraform(LLUUID user, LLVector3 position) { - return false; + bool permission = false; + + // Estate override + if (GenericEstatePermission(user)) + permission = true; + + // Land owner can terraform too + if (GenericParcelPermission(user, m_scene.LandManager.getLandObject(position.X, position.Y))) + permission = true; + + if (!permission) + SendPermissionError(user, "Not authorized to terraform at this location."); + + return permission; } #region Estate Permissions @@ -168,6 +264,11 @@ namespace OpenSim.Region.Environment return permission; } + protected virtual bool GenericParcelPermission(LLUUID user, LLVector3 pos) + { + return GenericParcelPermission(user, m_scene.LandManager.getLandObject(pos.X, pos.Y)); + } + public virtual bool CanEditParcel(LLUUID user, Land parcel) { return GenericParcelPermission(user, parcel); diff --git a/OpenSim/Region/Environment/Scenes/Scene.PacketHandlers.cs b/OpenSim/Region/Environment/Scenes/Scene.PacketHandlers.cs index bba0138fbb..cca8998170 100644 --- a/OpenSim/Region/Environment/Scenes/Scene.PacketHandlers.cs +++ b/OpenSim/Region/Environment/Scenes/Scene.PacketHandlers.cs @@ -50,6 +50,12 @@ namespace OpenSim.Region.Environment.Scenes /// Distance from the west border where the cursor is located public void ModifyTerrain(float height, float seconds, byte brushsize, byte action, float north, float west, IClientAPI remoteUser) { + // Do a permissions check before allowing terraforming. + // random users are now no longer allowed to terraform + // if permissions are enabled. + if (!PermissionsMngr.CanTerraform(remoteUser.AgentId, new LLVector3(north, west, 0))) + return; + // Shiny. double size = (double)(1 << brushsize); @@ -240,15 +246,18 @@ namespace OpenSim.Region.Environment.Scenes } if (selectedEnt != null) { - List avatars = this.RequestAvatarList(); - foreach (ScenePresence avatar in avatars) + if (PermissionsMngr.CanDeRezObject(simClient.AgentId, selectedEnt.m_uuid)) { - avatar.ControllingClient.SendKillObject(this.m_regionHandle, selectedEnt.LocalId); - } - - lock (Entities) - { - Entities.Remove(selectedEnt.m_uuid); + List avatars = this.RequestAvatarList(); + foreach (ScenePresence avatar in avatars) + { + avatar.ControllingClient.SendKillObject(this.m_regionHandle, selectedEnt.LocalId); + } + + lock (Entities) + { + Entities.Remove(selectedEnt.m_uuid); + } } } } @@ -501,16 +510,19 @@ namespace OpenSim.Region.Environment.Scenes public void MoveObject(LLUUID objectID, LLVector3 offset, LLVector3 pos, IClientAPI remoteClient) { - bool hasPrim = false; - foreach (EntityBase ent in Entities.Values) + if (PermissionsMngr.CanEditObject(remoteClient.AgentId, objectID)) { - if (ent is SceneObjectGroup) + bool hasPrim = false; + foreach (EntityBase ent in Entities.Values) { - hasPrim = ((SceneObjectGroup)ent).HasChildPrim(objectID); - if (hasPrim != false) + if (ent is SceneObjectGroup) { - ((SceneObjectGroup)ent).GrabMovement(offset, pos, remoteClient); - break; + hasPrim = ((SceneObjectGroup)ent).HasChildPrim(objectID); + if (hasPrim != false) + { + ((SceneObjectGroup)ent).GrabMovement(offset, pos, remoteClient); + break; + } } } } diff --git a/OpenSim/Region/Environment/Scenes/Scene.cs b/OpenSim/Region/Environment/Scenes/Scene.cs index 6c87c5da52..0fa3ab7e86 100644 --- a/OpenSim/Region/Environment/Scenes/Scene.cs +++ b/OpenSim/Region/Environment/Scenes/Scene.cs @@ -110,6 +110,13 @@ namespace OpenSim.Region.Environment.Scenes get { return m_scriptManager; } } + private PermissionManager m_permissionManager; + + public PermissionManager PermissionsMngr + { + get { return m_permissionManager; } + } + public Dictionary Objects { get { return Prims; } @@ -143,10 +150,13 @@ namespace OpenSim.Region.Environment.Scenes m_estateManager = new EstateManager(this, m_regInfo); m_scriptManager = new ScriptManager(this); m_eventManager = new EventManager(); + m_permissionManager = new PermissionManager(this); m_eventManager.OnParcelPrimCountAdd += m_LandManager.addPrimToLandPrimCounts; + m_eventManager.OnPermissionError += SendPermissionAlert; + MainLog.Instance.Verbose("Creating new entitities instance"); Entities = new Dictionary(); Avatars = new Dictionary(); @@ -966,6 +976,12 @@ namespace OpenSim.Region.Environment.Scenes #endregion #region Alert Methods + + void SendPermissionAlert(LLUUID user, string reason) + { + SendAlertToUser(user, reason, false); + } + public void SendGeneralAlert(string message) { foreach (ScenePresence presence in this.Avatars.Values) diff --git a/OpenSim/Region/Environment/Scenes/SceneEvents.cs b/OpenSim/Region/Environment/Scenes/SceneEvents.cs index cb5a967c6a..050207cdef 100644 --- a/OpenSim/Region/Environment/Scenes/SceneEvents.cs +++ b/OpenSim/Region/Environment/Scenes/SceneEvents.cs @@ -33,7 +33,16 @@ namespace OpenSim.Region.Environment.Scenes public event OnShutdownDelegate OnShutdown; public delegate void ObjectGrabDelegate(uint localID, LLVector3 offsetPos, IClientAPI remoteClient); + public delegate void OnPermissionErrorDelegate(LLUUID user, string reason); public event ObjectGrabDelegate OnObjectGrab; + public event OnPermissionErrorDelegate OnPermissionError; + + + public void TriggerPermissionError(LLUUID user, string reason) + { + if (OnPermissionError != null) + OnPermissionError(user, reason); + } public void TriggerOnScriptConsole(string[] args) {