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.
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:
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,
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: