X-Git-Url: http://xvm.mit.edu/gitweb/invirt/packages/python-afs.git/blobdiff_plain/c7607e2c1d074431922b99adb8b83c3fa8c16ae7..09b4d45674f9d37d44c68f52c9a965b14b7e336f:/afs/acl.py diff --git a/afs/acl.py b/afs/acl.py index da0821f..a5293bd 100644 --- a/afs/acl.py +++ b/afs/acl.py @@ -5,18 +5,20 @@ from _acl import getCallerAccess _canonical = { "read": "rl", - "write": "rwlidwk", - "all": "rwlidwka", + "write": "rlidwk", + "all": "rlidwka", "mail": "lik", "none": "", } +_reverseCanonical = dict((y, x) for (x, y) in _canonical.iteritems()) + _charBitAssoc = [ ('r', READ), - ('w', WRITE), - ('i', INSERT), ('l', LOOKUP), + ('i', INSERT), ('d', DELETE), + ('w', WRITE), ('k', LOCK), ('a', ADMINISTER), ('A', USR0), @@ -32,6 +34,13 @@ _charBitAssoc = [ _char2bit = dict(_charBitAssoc) +def rightsToEnglish(s): + """Turns a rlwidwka string into a canonical name if possible""" + if s in _reverseCanonical: + return _reverseCanonical[s] + else: + return '' + def readRights(s): """Canonicalizes string rights to bitmask""" if s in _canonical: s = _canonical[s] @@ -70,6 +79,16 @@ def _parseAcl(inp): neg[name] = int(acl) return (pos, neg) +def _unparseAcl(pos, neg): + npos = len(pos) + nneg = len(neg) + acl = "%d\n%d\n" % (npos, nneg) + for p in pos.items(): + acl += "%s\t%d\n" % p + for n in neg.items(): + acl += "%s\t%d\n" % n + return acl + class ACL(object): def __init__(self, pos, neg): """ @@ -81,8 +100,31 @@ class ACL(object): self.pos = pos self.neg = neg @staticmethod - def retrieve(dir, follow=1): + def retrieve(dir, follow=True): """Retrieve the ACL for an AFS directory""" pos, neg = _parseAcl(_acl.getAcl(dir, follow)) return ACL(pos, neg) - + def apply(self, dir, follow=True): + """Apply the ACL to a directory""" + self._clean() + _acl.setAcl(dir, _unparseAcl(self.pos, self.neg), follow) + def _clean(self): + """Clean an ACL by removing any entries whose bitmask is 0""" + for n,a in self.pos.items(): + if a == 0: + del self.pos[n] + for n,a in self.neg.items(): + if a == 0: + del self.neg[n] + def set(self, user, bitmask, negative=False): + """Set the bitmask for a given user""" + if bitmask < 0 or bitmask > max(_char2bit.values()): + raise ValueError, "Invalid bitmask" + if negative: + self.neg[user] = bitmask + else: + self.pos[user] = bitmask + def remove(self, user, negative=False): + """Convenience function to removeSet the bitmask for a given user""" + self.set(user, 0, negative) +