From 32785921d0a4a074b92da0f4ec322cf451a4642f Mon Sep 17 00:00:00 2001 From: mingchen Date: Tue, 13 May 2008 16:22:57 +0000 Subject: *Complete redo of the permissions module *Removed hardcoded permissions checks *Added permissions checks where needed --- .../Modules/World/Permissions/PermissionsModule.cs | 818 ++++++++++++--------- 1 file changed, 479 insertions(+), 339 deletions(-) (limited to 'OpenSim/Region/Environment/Modules/World/Permissions') diff --git a/OpenSim/Region/Environment/Modules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/Environment/Modules/World/Permissions/PermissionsModule.cs index 4e31ae6..cead2d8 100644 --- a/OpenSim/Region/Environment/Modules/World/Permissions/PermissionsModule.cs +++ b/OpenSim/Region/Environment/Modules/World/Permissions/PermissionsModule.cs @@ -27,16 +27,23 @@ using libsecondlife; using Nini.Config; - +using System; +using System.Reflection; +using log4net; using OpenSim.Region.Environment.Interfaces; +using OpenSim.Region.Environment.Modules.Framework; +using OpenSim.Region.Environment.Modules.Framework.InterfaceCommander; using OpenSim.Region.Environment.Scenes; namespace OpenSim.Region.Environment.Modules.World.Permissions { - public class PermissionsModule : IRegionModule, IScenePermissions + public class PermissionsModule : IRegionModule, IScenePermissions, ICommandableModule { protected Scene m_scene; + private readonly Commander m_commander = new Commander("Permissions"); + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + #region Constants // These are here for testing. They will be taken out //private uint PERM_ALL = (uint)2147483647; @@ -45,16 +52,89 @@ namespace OpenSim.Region.Environment.Modules.World.Permissions private uint PERM_MOVE = (uint)524288; //private uint PERM_TRANS = (uint)8192; private uint PERM_LOCKED = (uint)540672; - + + #endregion + + #region Bypass Permissions / Debug Permissions Stuff + // Bypasses the permissions engine private bool m_bypassPermissions = false; - + private bool m_bypassPermissionsValue = true; + private bool m_debugPermissions = false; public bool BypassPermissions { get { return m_bypassPermissions; } set { m_bypassPermissions = value; } } + public bool BypassPermissionsValue + { + get { return m_bypassPermissionsValue; } + set { m_bypassPermissionsValue = value; } + } + + public bool DebugPermissions + { + get { return m_debugPermissions; } + set { m_debugPermissions = value; } + } + #endregion + + #region ICommandableModule Members + + public ICommander CommandInterface + { + get { throw new System.NotImplementedException(); } + } + + + private void InterfaceDebugPermissions(Object[] args) + { + if ((bool)args[0] == true) + { + m_debugPermissions = true; + m_log.Info("[PERMISSIONS]: Permissions Debugging Enabled."); + } + else + { + m_debugPermissions = false; + m_log.Info("[PERMISSIONS]: Permissions Debugging Disabled."); + } + } + + private void InterfaceBypassPermissions(Object[] args) + { + if ((bool)args[0] == true) + { + m_log.Info("[PERMISSIONS]: Permissions Bypass Enabled."); + m_bypassPermissionsValue = (bool)args[1]; + } + else + { + m_bypassPermissions = false; + m_log.Info("[PERMISSIONS]: Permissions Bypass Disabled. Normal Operation."); + } + } + + /// + /// Processes commandline input. Do not call directly. + /// + /// Commandline arguments + private void EventManager_OnPluginConsole(string[] args) + { + if (args[0] == "permissions") + { + string[] tmpArgs = new string[args.Length - 2]; + int i; + for (i = 2; i < args.Length; i++) + tmpArgs[i - 2] = args[i]; + + m_commander.ProcessConsoleCommand(args[1], tmpArgs); + } + } + + #endregion + #region IRegionModule Members public void Initialise(Scene scene, IConfigSource config) @@ -67,29 +147,52 @@ namespace OpenSim.Region.Environment.Modules.World.Permissions m_scene.RegisterModuleInterface(this); - //Register External Permission Checks! - m_scene.ExternalChecks.addCheckAbandonParcel(this.CanAbandonParcel); - m_scene.ExternalChecks.addCheckCopyObject(this.CanCopyObject); - m_scene.ExternalChecks.addCheckDeRezObject(this.CanDeRezObject); - m_scene.ExternalChecks.addCheckEditEstateTerrain(this.CanEditEstateTerrain); - m_scene.ExternalChecks.addCheckEditObject(this.CanEditObject); - m_scene.ExternalChecks.addCheckEditParcel(this.CanEditParcel); - m_scene.ExternalChecks.addCheckEditScript(this.CanEditScript); - m_scene.ExternalChecks.addCheckInstantMessage(this.CanInstantMessage); - m_scene.ExternalChecks.addCheckInventoryTransfer(this.CanInventoryTransfer); - m_scene.ExternalChecks.addCheckMoveObject(this.CanEditObjectPosition); - m_scene.ExternalChecks.addCheckRestartSim(this.CanRestartSim); - m_scene.ExternalChecks.addCheckReturnObject(this.CanReturnObject); - m_scene.ExternalChecks.addCheckRezObject(this.CanRezObject); - m_scene.ExternalChecks.addCheckBeGodLike(this.CanBeGodLike); - m_scene.ExternalChecks.addCheckRunConsoleCommand(this.CanRunConsoleCommand); - m_scene.ExternalChecks.addCheckRunScript(this.CanRunScript); - m_scene.ExternalChecks.addCheckSellParcel(this.CanSellParcel); - //m_scene.ExternalChecks.addCheckTakeObject; -- NOT YET IMPLEMENTED - m_scene.ExternalChecks.addCheckTerraformLandCommand(this.CanTerraform); + //Register functions with Scene External Checks! + m_scene.ExternalChecks.addCheckAbandonParcel(CanAbandonParcel); //FULLY IMPLEMENTED + m_scene.ExternalChecks.addCheckBeGodLike(CanBeGodLike); //FULLY IMPLEMENTED + m_scene.ExternalChecks.addCheckDuplicateObject(CanDuplicateObject); //FULLY IMPLEMENTED + m_scene.ExternalChecks.addCheckDeleteObject(CanDeleteObject); //MAYBE FULLY IMPLEMENTED + m_scene.ExternalChecks.addCheckEditObject(CanEditObject);//MAYBE FULLY IMPLEMENTED + m_scene.ExternalChecks.addCheckEditParcel(CanEditParcel); //FULLY IMPLEMENTED + m_scene.ExternalChecks.addCheckEditScript(CanEditScript); //NOT YET IMPLEMENTED + m_scene.ExternalChecks.addCheckInstantMessage(CanInstantMessage); //FULLY IMPLEMENTED + m_scene.ExternalChecks.addCheckInventoryTransfer(CanInventoryTransfer); //NOT YET IMPLEMENTED + m_scene.ExternalChecks.addCheckIssueEstateCommand(CanIssueEstateCommand); //FULLY IMPLEMENTED + m_scene.ExternalChecks.addCheckMoveObject(CanMoveObject); //HOPEFULLY FULLY IMPLEMENTED + m_scene.ExternalChecks.addCheckObjectEntry(CanObjectEntry); //FULLY IMPLEMENTED + m_scene.ExternalChecks.addCheckReturnObject(CanReturnObject); //NOT YET IMPLEMENTED + m_scene.ExternalChecks.addCheckRezObject(CanRezObject); //HOPEFULLY FULLY IMPLEMENTED + m_scene.ExternalChecks.addCheckRunConsoleCommand(CanRunConsoleCommand); //FULLY IMPLEMENTED + m_scene.ExternalChecks.addCheckRunScript(CanRunScript); //NOT YET IMPLEMENTED + m_scene.ExternalChecks.addCheckSellParcel(CanSellParcel); //FULLY IMPLEMENTED + m_scene.ExternalChecks.addCheckTakeObject(CanTakeObject); //FULLY IMPLEMENTED + m_scene.ExternalChecks.addCheckTakeCopyObject(CanTakeCopyObject); //FULLY IMPLEMENTED + m_scene.ExternalChecks.addCheckTerraformLand(CanTerraformLand); //FULL IMPLEMENTED (POINT ONLY!!! NOT AREA!!!) + m_scene.ExternalChecks.addCheckViewScript(CanViewScript); //NOT YET IMPLEMENTED + + //NEEDED PERMS: + //CanLinkObject + //CanDelinkObject + //CanBuyLand + + + //Register Debug Commands + Command bypassCommand = new Command("bypass", InterfaceBypassPermissions, "Force the permissions a specific way to test permissions"); + bypassCommand.AddArgument("enable_bypass_perms", "true to enable bypassing all perms", "Boolean"); + bypassCommand.AddArgument("bypass_perms_value", "true/false: true will ignore all perms; false will restrict everything", "Boolean"); + + m_commander.RegisterCommand("bypass", bypassCommand); + + Command debugCommand = new Command("debug", InterfaceDebugPermissions, "Force the permissions a specific way to test permissions"); + debugCommand.AddArgument("enable_debug_perms", "true to enable debugging to console all perms", "Boolean"); + + m_commander.RegisterCommand("debug", debugCommand); + m_scene.RegisterModuleCommander("CommanderPermissions", m_commander); + m_scene.EventManager.OnPluginConsole += new EventManager.OnPluginConsoleDelegate(EventManager_OnPluginConsole); } + public void PostInitialise() { } @@ -110,18 +213,19 @@ namespace OpenSim.Region.Environment.Modules.World.Permissions #endregion + #region Helper Functions protected void SendPermissionError(LLUUID user, string reason) { m_scene.EventManager.TriggerPermissionError(user, reason); } + protected void DebugPermissionInformation(string permissionCalled) + { + if(m_debugPermissions) + m_log.Info("[PERMISSIONS]: " + permissionCalled + " was called from " + m_scene.RegionInfo.RegionName); + } protected bool IsAdministrator(LLUUID user) { - if (m_bypassPermissions) - { - return true; - } - // If there is no master avatar, return false if (m_scene.RegionInfo.MasterAvatarAssignedUUID != LLUUID.Zero) { @@ -133,117 +237,19 @@ namespace OpenSim.Region.Environment.Modules.World.Permissions protected bool IsEstateManager(LLUUID user) { - if (m_bypassPermissions) - { - return true; - } - if (user != LLUUID.Zero) { LLUUID[] estatemanagers = m_scene.RegionInfo.EstateSettings.estateManagers; - for (int i = 0; i < estatemanagers.Length; i++) + foreach(LLUUID estatemanager in estatemanagers) { - if (estatemanagers[i] == user) + if (estatemanager == user) return true; } } return false; } - - protected bool IsGridUser(LLUUID user) - { - return true; - } - - protected bool IsGuest(LLUUID user) - { - return false; - } - - public bool CanRezObject(int objectCount, LLUUID user, LLVector3 position,Scene scene) - { - bool permission = false; - - - - string reason = "Insufficient permission"; - - ILandObject land = m_scene.LandChannel.GetLandObject(position.X, position.Y); - if (land == null) return false; - - if ((land.landData.landFlags & ((int)Parcel.ParcelFlags.CreateObjects)) == - (int)Parcel.ParcelFlags.CreateObjects) - permission = true; - - //TODO: check for group rights - - 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 permission; - } - - /// 255) - X = 255; - if (Y > 255) - Y = 255; - if (X < 0) - X = 0; - if (Y < 0) - Y = 0; - - // Land owner can terraform too - ILandObject parcel = m_scene.LandChannel.GetLandObject(X, Y); - if (parcel != null && GenericParcelPermission(user, parcel)) - permission = true; - if (!permission) - SendPermissionError(user, "Not authorized to terraform at this location."); + // This is an exception to the generic object permission. + // Administrators who lock their objects should not be able to move them, + // however generic object permission should return true. + // This keeps locked objects from being affected by random click + drag actions by accident + // and allows the administrator to grab or delete a locked object. - return permission; - } + // Administrators and estate managers are still able to click+grab locked objects not + // owned by them in the scene + // This is by design. - #region Estate Permissions + if (locked && (moverID == objectOwner)) + return false; + } + return permission; + } - public bool GenericEstatePermission(LLUUID user) - { - // Default: deny - bool permission = false; + private bool CanObjectEntry(LLUUID objectID, LLVector3 newPoint, Scene scene) + { + DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); + if (m_bypassPermissions) return m_bypassPermissionsValue; - // Estate admins should be able to use estate tools - if (IsEstateManager(user)) - permission = true; + if ((newPoint.X > 257f || newPoint.X < -1f || newPoint.Y > 257f || newPoint.Y < -1f)) + { + return true; + } - // Administrators always have permission - if (IsAdministrator(user)) - permission = true; + ILandObject land = m_scene.LandChannel.GetLandObject(newPoint.X, newPoint.Y); - return permission; - } + if (land == null) + { + return false; + } - public bool CanEditEstateTerrain(LLUUID user, Scene scene) - { - return GenericEstatePermission(user); - } + if ((land.landData.landFlags & ((int)Parcel.ParcelFlags.AllowAllObjectEntry)) != 0) + { + return true; + } - public bool CanRestartSim(LLUUID user, Scene scene) - { - // Since this is potentially going on a grid... + //TODO: check for group rights - return GenericEstatePermission(user); - //return m_scene.RegionInfo.MasterAvatarAssignedUUID == user; - } + if (!m_scene.Entities.ContainsKey(objectID)) + { + return false; + } - public bool CanBeGodLike(LLUUID user, Scene scene) - { - return GenericEstatePermission(user); - } + // If it's not an object, we cant edit it. + if (!(m_scene.Entities[objectID] is SceneObjectGroup)) + { + return false; + } - #endregion + SceneObjectGroup task = (SceneObjectGroup)m_scene.Entities[objectID]; - #region Parcel Permissions + if (GenericParcelPermission(task.OwnerID, newPoint)) + { + return true; + } - protected bool GenericParcelPermission(LLUUID user, ILandObject parcel) - { - bool permission = false; + //Otherwise, false! + return false; + } - if (parcel.landData.ownerID == user) + private bool CanReturnObject(LLUUID objectID, LLUUID returnerID, Scene scene) { - permission = true; + DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); + if (m_bypassPermissions) return m_bypassPermissionsValue; + + return GenericObjectPermission(returnerID, objectID); } - if (parcel.landData.isGroupOwned) + private bool CanRezObject(int objectCount, LLUUID owner, LLVector3 objectPosition, Scene scene) { - // TODO: Need to do some extra checks here. Requires group code. + DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); + if (m_bypassPermissions) return m_bypassPermissionsValue; + + bool permission = false; + + ILandObject land = m_scene.LandChannel.GetLandObject(objectPosition.X, objectPosition.Y); + if (land == null) return false; + + if ((land.landData.landFlags & ((int)Parcel.ParcelFlags.CreateObjects)) == + (int)Parcel.ParcelFlags.CreateObjects) + permission = true; + + //TODO: check for group rights + + if (IsAdministrator(owner)) + { + permission = true; + } + + if (GenericParcelPermission(owner, objectPosition)) + { + permission = true; + } + + return permission; } - if (IsEstateManager(user)) + private bool CanRunConsoleCommand(LLUUID user, Scene requestFromScene) { - permission = true; + DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); + if (m_bypassPermissions) return m_bypassPermissionsValue; + + + return IsAdministrator(user); } - if (IsAdministrator(user)) + private bool CanRunScript(LLUUID script, LLUUID user, Scene scene) { - permission = true; + DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); + if (m_bypassPermissions) return m_bypassPermissionsValue; + + return true; } - return permission; - } + private bool CanSellParcel(LLUUID user, ILandObject parcel, Scene scene) + { + DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); + if (m_bypassPermissions) return m_bypassPermissionsValue; - protected bool GenericParcelPermission(LLUUID user, LLVector3 pos) - { - ILandObject parcel = m_scene.LandChannel.GetLandObject(pos.X, pos.Y); - if (parcel == null) return false; - return GenericParcelPermission(user, parcel); - } + return GenericParcelPermission(user, parcel); + } - public bool CanEditParcel(LLUUID user, ILandObject parcel, Scene scene) - { - return GenericParcelPermission(user, parcel); - } + private bool CanTakeObject(LLUUID objectID, LLUUID stealer, Scene scene) + { + DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); + if (m_bypassPermissions) return m_bypassPermissionsValue; - public bool CanSellParcel(LLUUID user, ILandObject parcel, Scene scene) - { - return GenericParcelPermission(user, parcel); - } + return GenericObjectPermission(stealer,objectID); + } - public bool CanAbandonParcel(LLUUID user, ILandObject parcel, Scene scene) - { - return GenericParcelPermission(user, parcel); - } + private bool CanTakeCopyObject(LLUUID objectID, LLUUID userID, Scene inScene) + { + DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); + if (m_bypassPermissions) return m_bypassPermissionsValue; + + bool permission = GenericObjectPermission(userID, objectID); + if (permission) + { + if (!m_scene.Entities.ContainsKey(objectID)) + { + return false; + } + + // If it's not an object, we cant edit it. + if (!(m_scene.Entities[objectID] is SceneObjectGroup)) + { + return false; + } + + SceneObjectGroup task = (SceneObjectGroup)m_scene.Entities[objectID]; + LLUUID taskOwner = null; + // Added this because at this point in time it wouldn't be wise for + // the administrator object permissions to take effect. + LLUUID objectOwner = task.OwnerID; + + + if ((task.RootPart.EveryoneMask & PERM_COPY) != 0) + permission = true; + } + return permission; + } + + private bool CanTerraformLand(LLUUID user, LLVector3 position, Scene requestFromScene) + { + DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); + if (m_bypassPermissions) return m_bypassPermissionsValue; + + bool permission = false; + + // Estate override + if (GenericEstatePermission(user)) + permission = true; + float X = position.X; + float Y = position.Y; + + if (X > 255) + X = 255; + if (Y > 255) + Y = 255; + if (X < 0) + X = 0; + if (Y < 0) + Y = 0; + + // Land owner can terraform too + ILandObject parcel = m_scene.LandChannel.GetLandObject(X, Y); + if (parcel != null && GenericParcelPermission(user, parcel)) + permission = true; + + + return permission; + } + + private bool CanViewScript(LLUUID script, LLUUID user, Scene scene) + { + DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); + if (m_bypassPermissions) return m_bypassPermissionsValue; + + return true; + } #endregion + + } + } -- cgit v1.1