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 AFS tokens for a cell if encryption is required by config.
+
+ If the Invirt configuration requires connections to this cell to
+ be encrypted, acquires tokens and returns True. Otherwise, returns
+ False. Consumers of this function must still be sure to encrypt
+ their own connections if necessary.
+
+ Cells not listed in the Invirt configuration default to requiring
+ encryption in order to maintain security by default.
+
+ Due to AFS's cross-realm auto-PTS-creation mechanism, using
+ authenticated connections by default should only fail for cells
+ which authenticate directly against the machine's home realm and
+ cells distantly related to the machine's home realm.
+ """
+ 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, pts.PTS_ENCRYPT if auth else pts.PTS_UNAUTH).\
+ getEntry(name)
if ent.id > 0:
return set([ent.name])
else: