Index: trunk/packages/sipb-xen-www/code/main.py
===================================================================
--- trunk/packages/sipb-xen-www/code/main.py	(revision 630)
+++ trunk/packages/sipb-xen-www/code/main.py	(revision 632)
@@ -40,4 +40,13 @@
 from webcommon import InvalidInput, CodeError, State
 import controls
+from getafsgroups import getAfsGroupMembers
+
+def pathSplit(path):
+    if path.startswith('/'):
+        path = path[1:]
+    i = path.find('/')
+    if i == -1:
+        i = len(path)
+    return path[:i], path[i:]
 
 class Checkpoint:
@@ -142,5 +151,5 @@
                 autoinstall=getattr(validate, 'autoinstall', None))
 
-def create(username, state, fields):
+def create(username, state, path, fields):
     """Handler for create requests."""
     try:
@@ -205,5 +214,5 @@
     return d
 
-def listVms(username, state, fields):
+def listVms(username, state, path, fields):
     """Handler for list requests."""
     checkpoint.checkpoint('Getting list dict')
@@ -212,5 +221,5 @@
     return templates.list(searchList=[d])
 
-def vnc(username, state, fields):
+def vnc(username, state, path, fields):
     """VNC applet page.
 
@@ -309,5 +318,5 @@
     return disk_fields
 
-def command(username, state, fields):
+def command(username, state, path, fields):
     """Handler for running commands like boot and delete on a VM."""
     back = fields.getfirst('back')
@@ -395,5 +404,5 @@
                 machine=machine)
 
-def modify(username, state, fields):
+def modify(username, state, path, fields):
     """Handler for modifying attributes of a machine."""
     try:
@@ -415,5 +424,5 @@
 
 
-def helpHandler(username, state, fields):
+def helpHandler(username, state, path, fields):
     """Handler for help messages."""
     simple = fields.getfirst('simple')
@@ -466,5 +475,5 @@
 
 
-def badOperation(u, s, e):
+def badOperation(u, s, p, e):
     """Function called when accessing an unknown URI."""
     return ({'Status': '404 Not Found'}, 'Invalid operation.')
@@ -565,5 +574,5 @@
     return d
 
-def info(username, state, fields):
+def info(username, state, path, fields):
     """Handler for info on a single VM."""
     machine = validation.Validate(username, state, machine_id=fields.getfirst('machine_id')).machine
@@ -572,9 +581,16 @@
     return templates.info(searchList=[d])
 
-def unauthFront(_, _2, fields):
+def unauthFront(_, _2, _3, fields):
     """Information for unauth'd users."""
     return templates.unauth(searchList=[{'simple' : True}])
 
-def throwError(_, __, ___):
+def overlord(username, state, path, fields):
+    if not username in getAfsGroupMembers('system:xvm', 'athena.mit.edu'):
+        raise InvalidInput('username', username, 'Not an overlord.')
+    newstate = State(username, overlord=True)
+    newstate.environ = state.environ
+    return handler(username, newstate, path, fields)
+
+def throwError(_, __, ___, ____):
     """Throw an error, to test the error-tracing mechanisms."""
     raise RuntimeError("test of the emergency broadcast system")
@@ -588,4 +604,5 @@
                help=helpHandler,
                unauth=unauthFront,
+               overlord=overlord,
                errortest=throwError)
 
@@ -626,4 +643,12 @@
     return environ.get('REMOTE_USER', None)
 
+def handler(username, state, path, fields):
+    operation, path = pathSplit(path)
+    if not operation:
+        operation = 'list'
+    print 'Starting', operation
+    fun = mapping.get(operation, badOperation)
+    return fun(username, state, path, fields)
+
 class App:
     def __init__(self, environ, start_response):
@@ -636,4 +661,5 @@
 
     def __iter__(self):
+        start_time = time.time()
         sipb_xen_database.clear_cache()
         sys.stderr = StringIO()
@@ -646,15 +672,8 @@
         if self.username is None:
             operation = 'unauth'
-        if operation.startswith('/'):
-            operation = operation[1:]
-        if not operation:
-            operation = 'list'
-        print 'Starting', operation
-
-        start_time = time.time()
-        fun = mapping.get(operation, badOperation)
+
         try:
             checkpoint.checkpoint('Before')
-            output = fun(self.username, self.state, fields)
+            output = handler(self.username, self.state, operation, fields)
             checkpoint.checkpoint('After')
 
Index: trunk/packages/sipb-xen-www/code/validation.py
===================================================================
--- trunk/packages/sipb-xen-www/code/validation.py	(revision 630)
+++ trunk/packages/sipb-xen-www/code/validation.py	(revision 632)
@@ -37,5 +37,5 @@
 
         if machine_id is not None:
-            self.machine = testMachineId(username, machine_id)
+            self.machine = testMachineId(username, state, machine_id)
         machine = getattr(self, 'machine', None)
 
@@ -59,5 +59,5 @@
                                       on=not created_new)
         if disksize is not None:
-            self.disksize = validDisk(self.owner, disksize, machine)
+            self.disksize = validDisk(self.owner, state, disksize, machine)
         if vmtype is not None:
             self.vmtype = validVmType(vmtype)
@@ -124,7 +124,7 @@
     return False
 
-def haveAccess(user, machine):
+def haveAccess(user, state, machine):
     """Return whether a user has administrative access to a machine"""
-    return user in cache_acls.accessList(machine)
+    return state.overlord or user in cache_acls.accessList(machine)
 
 def owns(user, machine):
@@ -158,14 +158,14 @@
                            "Minimum %s MiB" % MIN_MEMORY_SINGLE)
     max_val = maxMemory(owner, g, machine, on)
-    if memory > max_val:
+    if not g.overlord and memory > max_val:
         raise InvalidInput('memory', memory,
                            'Maximum %s MiB for %s' % (max_val, owner))
     return memory
 
-def validDisk(owner, disk, machine=None):
+def validDisk(owner, g, disk, machine=None):
     """Parse and validate limits for disk for a given owner and machine."""
     try:
         disk = float(disk)
-        if disk > maxDisk(owner, machine):
+        if not g.overlord and disk > maxDisk(owner, machine):
             raise InvalidInput('disk', disk,
                                "Maximum %s G" % maxDisk(owner, machine))
@@ -186,5 +186,5 @@
     return t
 
-def testMachineId(user, machine_id, exists=True):
+def testMachineId(user, state, machine_id, exists=True):
     """Parse, validate and check authorization for a given user and machine.
 
@@ -201,5 +201,5 @@
     if exists and machine is None:
         raise InvalidInput('machine_id', machine_id, "Does not exist.")
-    if machine is not None and not haveAccess(user, machine):
+    if machine is not None and not haveAccess(user, state, machine):
         raise InvalidInput('machine_id', machine_id,
                            "You do not have access to this machine.")
Index: trunk/packages/sipb-xen-www/code/webcommon.py
===================================================================
--- trunk/packages/sipb-xen-www/code/webcommon.py	(revision 630)
+++ trunk/packages/sipb-xen-www/code/webcommon.py	(revision 632)
@@ -39,9 +39,15 @@
 class State(object):
     """State for a request"""
-    def __init__(self, user):
+    def __init__(self, user, overlord=False):
         self.username = user
+        self.overlord = overlord
 
-    machines = cachedproperty(lambda self:
-                                  Machine.query().join('acl').select_by(user=self.username))
+    def getMachines(self):
+        if self.overlord:
+            return Machine.select()
+        else:
+            return Machine.query().join('acl').select_by(user=self.username)
+
+    machines = cachedproperty(getMachines)
     xmlist_raw = cachedproperty(lambda self: controls.getList())
     xmlist = cachedproperty(lambda self:
