1 | """ |
---|
2 | Present both functional and object-oriented interfaces for executing |
---|
3 | lookups in Hesiod, Project Athena's service name resolution protocol. |
---|
4 | """ |
---|
5 | |
---|
6 | from _hesiod import bind, resolve |
---|
7 | |
---|
8 | from pwd import struct_passwd |
---|
9 | from grp import struct_group |
---|
10 | |
---|
11 | class HesiodParseError(Exception): |
---|
12 | pass |
---|
13 | |
---|
14 | class Lookup(object): |
---|
15 | """ |
---|
16 | A Generic Hesiod lookup |
---|
17 | """ |
---|
18 | def __init__(self, hes_name, hes_type): |
---|
19 | self.results = resolve(hes_name, hes_type) |
---|
20 | self.parseRecords() |
---|
21 | |
---|
22 | def parseRecords(self): |
---|
23 | pass |
---|
24 | |
---|
25 | class FilsysLookup(Lookup): |
---|
26 | def __init__(self, name): |
---|
27 | Lookup.__init__(self, name, 'filsys') |
---|
28 | |
---|
29 | def parseRecords(self): |
---|
30 | Lookup.parseRecords(self) |
---|
31 | |
---|
32 | self.filsys = [] |
---|
33 | self.multiRecords = (len(self.results) > 1) |
---|
34 | |
---|
35 | for result in self.results: |
---|
36 | priority = 0 |
---|
37 | if self.multiRecords: |
---|
38 | result, priority = result.rsplit(" ", 1) |
---|
39 | priority = int(priority) |
---|
40 | |
---|
41 | parts = result.split(" ") |
---|
42 | type = parts[0] |
---|
43 | if type == 'AFS': |
---|
44 | self.filsys.append(dict(type=type, |
---|
45 | location=parts[1], |
---|
46 | mode=parts[2], |
---|
47 | mountpoint=parts[3], |
---|
48 | priority=priority)) |
---|
49 | elif type == 'NFS': |
---|
50 | self.filsys.append(dict(type=type, |
---|
51 | remote_location=parts[1], |
---|
52 | server=parts[2], |
---|
53 | mode=parts[3], |
---|
54 | mountpoint=parts[4], |
---|
55 | priority=priority)) |
---|
56 | elif type == 'ERR': |
---|
57 | self.filsys.append(dict(type=type, |
---|
58 | message=parts[1], |
---|
59 | priority=priority)) |
---|
60 | elif type == 'UFS': |
---|
61 | self.filsys.append(dict(type=type, |
---|
62 | device=parts[1], |
---|
63 | mode=parts[2], |
---|
64 | mountpoint=parts[3], |
---|
65 | priority=priority)) |
---|
66 | elif type == 'LOC': |
---|
67 | self.filsys.append(dict(type=type, |
---|
68 | location=parts[1], |
---|
69 | mode=parts[2], |
---|
70 | mountpoint=parts[3], |
---|
71 | priority=priority)) |
---|
72 | else: |
---|
73 | raise HesiodParseError('Unknown filsys type: %s' % type) |
---|
74 | |
---|
75 | self.filsys.sort(key=(lambda x: x['priority'])) |
---|
76 | |
---|
77 | class PasswdLookup(Lookup): |
---|
78 | def __init__(self, name): |
---|
79 | Lookup.__init__(self, name, 'passwd') |
---|
80 | |
---|
81 | def parseRecords(self): |
---|
82 | passwd_info = self.results[0].split(':') |
---|
83 | passwd_info[2] = int(passwd_info[2]) |
---|
84 | passwd_info[3] = int(passwd_info[3]) |
---|
85 | self.passwd = struct_passwd(passwd_info) |
---|
86 | |
---|
87 | class UidLookup(PasswdLookup): |
---|
88 | def __init__(self, uid): |
---|
89 | Lookup.__init__(self, uid, 'uid') |
---|
90 | |
---|
91 | class GroupLookup(Lookup): |
---|
92 | def __init__(self, group): |
---|
93 | Lookup.__init__(self, group, 'group') |
---|
94 | |
---|
95 | def parseRecords(self): |
---|
96 | group_info = self.results[0].split(':') |
---|
97 | group_info[2] = int(group_info[2]) |
---|
98 | members = group_info[3] |
---|
99 | if members != '': |
---|
100 | members = members.split(',') |
---|
101 | else: |
---|
102 | members = [] |
---|
103 | group_info[3] = members |
---|
104 | |
---|
105 | self.group = struct_group(group_info) |
---|
106 | |
---|
107 | class GidLookup(GroupLookup): |
---|
108 | def __init__(self, gid): |
---|
109 | Lookup.__init__(self, gid, 'gid') |
---|
110 | |
---|
111 | __all__ = ['bind', 'resolve', |
---|
112 | 'Lookup', 'FilsysLookup', 'PasswdLookup', 'UidLookup', |
---|
113 | 'GroupLookup', 'GidLookup', |
---|
114 | 'HesiodParseError'] |
---|