Add changelog
[invirt/packages/invirt-web.git] / code / getafsgroups.py
1 #!/usr/bin/python
2 import pprint
3 import subprocess
4 from invirt.config import structs as config
5
6 # import ldap
7 # l = ldap.open("W92-130-LDAP-2.mit.edu")
8 # # ldap.mit.edu is 1/2 broken right now so we're going to the working backend
9 # l.simple_bind_s("", "")
10
11 # def getLdapGroups(user):
12 #     """
13 #     getLdapGroups(user): returns a generator for the list of LDAP groups containing user
14 #     """
15 #     for user_data in l.search_s("ou=affiliates,dc=mit,dc=edu", ldap.SCOPE_ONELEVEL, "uid=" + user, []):
16 #         for group_data in l.search_s("ou=groups,dc=mit,dc=edu", ldap.SCOPE_ONELEVEL, "uniqueMember="+user_data[0], ['cn']):
17 #             yield group_data[1]['cn'][0]
18
19 # def checkLdapGroups(user, group):
20 #     """
21 #     checkLdapGroups(user, group): returns True if and only if user is in LDAP group group
22 #     """
23 #     for result_data in l.search_s("ou=affiliates,dc=mit,dc=edu", ldap.SCOPE_ONELEVEL, "uid=" + user, []):
24 #         if l.search_s("ou=groups,dc=mit,dc=edu", ldap.SCOPE_ONELEVEL, "(&(cn=" + group + ")(uniqueMember="+result_data[0] + "))", []) != []:
25 #             return True
26 #     return False
27
28 class AfsProcessError(Exception):
29     pass
30
31 def getAfsGroupMembers(group, cell):
32     encrypt = True
33     for c in config.authz.afs.cells:
34         if c.cell == cell and hasattr(c, 'auth'):
35             encrypt = c.auth
36     if encrypt:
37         subprocess.check_call(['aklog', cell], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
38     p = subprocess.Popen(["pts", "membership", "-encrypt" if encrypt else '-noauth', group, '-c', cell],
39                          stdout=subprocess.PIPE, stderr=subprocess.PIPE)
40     err = p.stderr.read()
41     if err: #Error code doesn't reveal missing groups, but stderr does
42         if err.startswith('pts: Permission denied ; unable to get membership of '):
43             return []
44         raise AfsProcessError(err)
45     return [line.strip() for line in p.stdout.readlines()[1:]]
46
47 def getLockerPath(locker):
48     if '/' in locker or locker in ['.', '..']:
49         raise AfsProcessError("Locker '%s' is invalid." % locker)
50     return '/mit/' + locker
51
52 def getCell(locker):
53     p = subprocess.Popen(["fs", "whichcell", getLockerPath(locker)], 
54                          stdout=subprocess.PIPE, stderr=subprocess.PIPE)
55     if p.wait():
56         raise AfsProcessError(p.stderr.read())
57     return p.stdout.read().split()[-1][1:-1]
58
59 def getLockerAcl(locker):
60     p = subprocess.Popen(["fs", "listacl", getLockerPath(locker)], 
61                          stdout=subprocess.PIPE, stderr=subprocess.PIPE)
62     if p.wait():
63         raise AfsProcessError(p.stderr.read())
64     lines = p.stdout.readlines()
65     values = []
66     for line in lines[1:]:
67         fields = line.split()
68         if fields[0] == 'Negative':
69             break
70         if 'a' in fields[1]:
71             values.append(fields[0])
72     return values
73
74 def notLockerOwner(user, locker):
75     """
76     notLockerOwner(user, locker) returns false if and only if user administers locker.
77
78     If the user does not own the locker, returns the string reason for
79     the failure.
80     """
81     try:
82         cell = getCell(locker)
83         values = getLockerAcl(locker)
84     except AfsProcessError, e:
85         return str(e)
86
87     for entry in values:
88         if entry == user or (entry[0:6] == "system" and
89                                 user in getAfsGroupMembers(entry, cell)):
90             return False
91     return "You don't have admin bits on " + getLockerPath(locker)
92
93
94 if __name__ == "__main__":
95 #    print list(getldapgroups("tabbott"))
96     print "tabbott" in getAfsGroupMembers("system:debathena", 'athena.mit.edu')
97     print "tabbott" in getAfsGroupMembers("system:debathena", 'sipb.mit.edu')
98     print "tabbott" in getAfsGroupMembers("system:debathena-root", 'athena.mit.edu')
99     print "tabbott" in getAfsGroupMembers("system:hmmt-request", 'athena.mit.edu')
100     print notLockerOwner("tabbott", "tabbott")
101     print notLockerOwner("tabbott", "debathena")
102     print notLockerOwner("tabbott", "sipb")
103     print notLockerOwner("tabbott", "lsc")
104     print notLockerOwner("tabbott", "scripts")
105     print notLockerOwner("ecprice", "hmmt")