From de28b2d575940de1e156578965144304bfcb5eba Mon Sep 17 00:00:00 2001 From: Griatch Date: Thu, 17 Mar 2011 22:28:30 +0000 Subject: [PATCH] Fixes @locks to block self-escalation. Fixed a few bugs in @reload that caused it to reload also unsafe modules. --- src/commands/default/admin.py | 18 +++++++++++++++++- src/locks/lockhandler.py | 2 +- src/objects/objects.py | 2 +- src/utils/reloads.py | 6 +++--- 4 files changed, 22 insertions(+), 6 deletions(-) diff --git a/src/commands/default/admin.py b/src/commands/default/admin.py index 392300c243..c1fed242a9 100644 --- a/src/commands/default/admin.py +++ b/src/commands/default/admin.py @@ -11,6 +11,8 @@ from src.server.sessionhandler import SESSIONS from src.utils import utils from src.commands.default.muxcommand import MuxCommand +PERMISSION_HIERARCHY = [p.lower() for p in settings.PERMISSION_HIERARCHY] + class CmdBoot(MuxCommand): """ @boot @@ -386,9 +388,23 @@ class CmdPerm(MuxCommand): else: # add a new permission permissions = obj.permissions + + caller.permissions + + + for perm in self.rhslist: + + perm = perm.lower() + + # don't allow to set a permission higher in the hierarchy than the one the + # caller has (to prevent self-escalation) + if perm in PERMISSION_HIERARCHY and not obj.locks.check_lockstring(caller, "dummy:perm(%s)" % perm): + caller.msg("You cannot assign a permission higher than the one you have yourself.") + return + if perm in permissions: - cstring += "\nPermission '%s' is already defined on %s%s." % (rhs, obj.name) + cstring += "\nPermission '%s' is already defined on %s." % (rhs, obj.name) else: permissions.append(perm) obj.permissions = permissions diff --git a/src/locks/lockhandler.py b/src/locks/lockhandler.py index 72310c81cc..dc7503636f 100644 --- a/src/locks/lockhandler.py +++ b/src/locks/lockhandler.py @@ -319,7 +319,7 @@ class LockHandler(object): else: return default - def check_lockstring(self, accessing_obj, accessed_obj, lockstring): + def check_lockstring(self, accessing_obj, lockstring): """ Do a direct check against a lockstring ('atype:func()..'), without any intermediary storage on the accessed object (this can be left diff --git a/src/objects/objects.py b/src/objects/objects.py index a85731c48e..b0f550d592 100644 --- a/src/objects/objects.py +++ b/src/objects/objects.py @@ -87,7 +87,7 @@ class Object(TypeClass): dbref = self.dbobj.dbref - self.locks.add("control:id(%s)" % dbref) + self.locks.add("control:id(%s) or perm(Immortals)" % dbref) self.locks.add("examine:perm(Builders)") self.locks.add("edit:perm(Wizards)") self.locks.add("delete:perm(Wizards)") diff --git a/src/utils/reloads.py b/src/utils/reloads.py index 1c544a3f9f..49f5d29981 100644 --- a/src/utils/reloads.py +++ b/src/utils/reloads.py @@ -34,8 +34,8 @@ def reload_modules(): # should never need to do that anyway). Updating src requires a server # reboot. Modules in except_dirs are considered ok to reload despite being # inside src/ - protected_dirs = ('src.',) - except_dirs = ('src.commands.default.') + protected_dirs = ('src.',) # note that these MUST be tuples! + except_dirs = ('src.commands.default.',) # " # flag 'dangerous' typeclasses (those which retain a memory # reference, notably Scripts with a timer component) for @@ -50,7 +50,7 @@ def reload_modules(): def safe_dir_to_reload(modpath): "Check so modpath is not a subdir of a protected dir, and not an ok exception" - return not any(modpath.startswith(pdir) and not any(modpath.startswith(pdir) for pdir in except_dirs) for pdir in protected_dirs) + return not any(modpath.startswith(pdir) and not any(modpath.startswith(edir) for edir in except_dirs) for pdir in protected_dirs) def safe_mod_to_reload(modpath): "Check so modpath is not in an unsafe module" return not any(mpath.startswith(modpath) for mpath in unsafe_modules)