In invirt.authz.locker, deal with getting tokens and
authorEvan Broder <broder@mit.edu>
Mon, 23 Nov 2009 06:37:40 +0000 (01:37 -0500)
committerEvan Broder <broder@mit.edu>
Mon, 23 Nov 2009 06:37:40 +0000 (01:37 -0500)
authenticating/encrypting connections when necessary.

svn path=/trunk/packages/invirt-base/; revision=2562

python/invirt/authz/locker.py

index 4e22d2a..a564e10 100644 (file)
@@ -4,16 +4,17 @@ from afs import acl
 from afs import fs
 from afs import pts
 
+from invirt import common
 from invirt.config import structs as config
+from invirt import remctl
+
 
 #
 # expandOwner and expandAdmin form the API that needs to be exported
 # for all authz modules.
 #
 
-# TODO: Make expandOwner and expandAdmin deal with acquiring tokens
-# and encrypting the connection to the prdb as necessary/requested by
-# the configuration.
+
 def expandOwner(name):
     """Expand an owner to a list of authorized users.
 
@@ -28,15 +29,16 @@ def expandOwner(name):
     try:
         path = _lockerPath(name)
         cell = fs.whichcell(path)
+        auth = _authenticate(cell)
         a = acl.ACL.retrieve(path)
 
         allowed = set()
         for ent in a.pos:
             if a.pos[ent] & acl.ADMINISTER:
-                allowed.update(_expandGroup(ent, cell))
+                allowed.update(_expandGroup(ent, cell=cell, auth=auth))
         for ent in a.neg:
             if a.neg[ent] & acl.ADMINISTER:
-                allowed.difference_update(_expandGroup(ent, cell))
+                allowed.difference_update(_expandGroup(ent, cell=cell, auth=auth))
 
         return allowed
     except OSError, e:
@@ -56,14 +58,49 @@ def expandAdmin(name, owner):
     administrator is always interpreted as an AFS entry (either a user
     or a group) in the home cell (athena.mit.edu for XVM).
     """
-    return _expandGroup(name)
+    cell = config.authz.cells[0].cell
+    auth = _authenticate(cell)
+    return _expandGroup(name, cell=cell, auth=auth)
 
 
 #
 # These are helper functions, and aren't part of the authz API
 #
 
-def _expandGroup(name, cell=None):
+
+def _authenticate(cell):
+    """Acquire credentials if possible for a particular cell.
+
+    This function returns True if an authenticated connection to the
+    cell should be established; False otherwise.
+
+    If a cell isn't explicitly listed in the configuration file,
+    _authenticate will assume that it /should/ authenticate to the
+    cell.
+
+    The assumption is that choosing to authenticate to a cell will
+    fail in two cases: (a) the cell authenticates against the
+    machine's home realm and there is no PTS ID in the cell, or (b)
+    the cell doesn't authenticate against the machine's home realm and
+    doesn't have cross-realm authentication setup.
+
+    In the former case, it should be possible for the sysadmins to
+    list all cells that authenticate against the home realm (including
+    those where attempting authentication would be problematic). In
+    the latter case, such a cell would be at best distantly connected
+    to the home cell, and we probably don't want to give it quota
+    anyway.
+    """
+    for c in config.authz.cells:
+        if c.cell == cell and not c.auth:
+            return False
+
+    remctl.checkKinit()
+    common.captureOutput(['aklog', '-c', cell])
+    return True
+
+
+def _expandGroup(name, cell=None, auth=False):
     """Expand an AFS group into a list of its members.
 
     Because groups are not global, but can vary from cell to cell,
@@ -80,7 +117,7 @@ def _expandGroup(name, cell=None):
     to retrieve its membership, we assume it's empty.
     """
     try:
-        ent = pts.PTS(cell).getEntry(name)
+        ent = pts.PTS(cell, 3 if auth else 0).getEntry(name)
         if ent.id > 0:
             return set([ent.name])
         else: