source: trunk/packages/invirt-base/python/invirt/authz/locker.py @ 2559

Last change on this file since 2559 was 2559, checked in by broder, 14 years ago

Add a invirt.authz.locker module to invirt-base for XVM-style
authorization.

File size: 2.9 KB
Line 
1import errno
2
3from afs import acl
4from afs import fs
5from afs import pts
6
7from invirt.config import structs as config
8
9#
10# expandOwner and expandAdmin form the API that needs to be exported
11# for all authz modules.
12#
13
14# TODO: Make expandOwner and expandAdmin deal with acquiring tokens
15# and encrypting the connection to the prdb as necessary/requested by
16# the configuration.
17def expandOwner(name):
18    """Expand an owner to a list of authorized users.
19
20    For the locker authz module, an owner is an Athena locker. Those
21    users who have been given the administrator ('a') bit on the root
22    of a locker are given access to any VM owned by that locker,
23    unless they also have been given a negative administrator bit.
24
25    If a locker doesn't exist, or we can't access the permissions, we
26    assume the ACL is empty.
27    """
28    try:
29        path = _lockerPath(name)
30        cell = fs.whichcell(path)
31        a = acl.ACL.retrieve(path)
32
33        allowed = set()
34        for ent in a.pos:
35            if a.pos[ent] & acl.ADMINISTER:
36                allowed.update(_expandGroup(ent, cell))
37        for ent in a.neg:
38            if a.neg[ent] & acl.ADMINISTER:
39                allowed.difference_update(_expandGroup(ent, cell))
40
41        return allowed
42    except OSError, e:
43        if e.errno in (errno.ENOENT, errno.EACCES):
44            return []
45        else:
46            raise
47
48
49def expandAdmin(name, owner):
50    """Expand an administrator to a list of authorized users.
51
52    Because the interpretation of an administrator might depend on the
53    owner, the owner is passed in as an argument.
54
55    However, in the case of locker-based authentication, the
56    administrator is always interpreted as an AFS entry (either a user
57    or a group) in the home cell (athena.mit.edu for XVM).
58    """
59    return _expandGroup(name)
60
61
62#
63# These are helper functions, and aren't part of the authz API
64#
65
66def _expandGroup(name, cell=None):
67    """Expand an AFS group into a list of its members.
68
69    Because groups are not global, but can vary from cell to cell,
70    this function accepts as an optional argument the cell in which
71    this group should be resolved.
72
73    If no cell is specified, it is assumed that the default cell (or
74    ThisCell) should be used.
75
76    If the name is a user, not a group, then a single-element set with
77    the same name is returned.
78
79    As with expandOwner, if a group doesn't exist or if we're unable
80    to retrieve its membership, we assume it's empty.
81    """
82    try:
83        ent = pts.PTS(cell).getEntry(name)
84        if ent.id > 0:
85            return set([ent.name])
86        else:
87            return set([x.name for x in ent.members])
88    except OSError, e:
89        if e.errno in (errno.ENOENT, errno.EACCESS):
90            return set()
91        else:
92            raise
93
94
95def _lockerPath(owner):
96    """Given the name of a locker, return a path to that locker.
97
98    This turns out to be pretty simple, thanks to the /mit
99    automounter.
100    """
101    return '/mit/%s' % owner
Note: See TracBrowser for help on using the repository browser.