2 from __future__ import absolute_import, print_function
5 from bup import compat # to force the LC_CTYPE check
6 from bup.compat import py_maj
7 from bup.helpers import cache_key_value
10 # Using __slots__ makes these much smaller (even than a namedtuple)
13 """Drop in replacement for pwd's structure with bytes instead of strings."""
14 __slots__ = ('pw_name', 'pw_passwd', 'pw_uid', 'pw_gid', 'pw_gecos',
16 def __init__(self, name, passwd, uid, gid, gecos, dir, shell):
17 assert type(name) == bytes
18 assert type(passwd) == bytes
19 assert type(gecos) == bytes
20 assert type(dir) == bytes
21 assert type(shell) == bytes
22 (self.pw_name, self.pw_passwd, self.pw_uid, self.pw_gid,
23 self.pw_gecos, self.pw_dir, self.pw_shell) = \
24 name, passwd, uid, gid, gecos, dir, shell
26 def _passwd_from_py(py):
29 return Passwd(py.pw_name.encode('iso-8859-1'),
30 py.pw_passwd.encode("iso-8859-1"),
32 py.pw_gecos.encode('iso-8859-1'),
33 py.pw_dir.encode('iso-8859-1'),
34 py.pw_shell.encode('iso-8859-1'))
37 return _passwd_from_py(pwd.getpwuid(uid))
40 assert isinstance(name, bytes)
41 return _passwd_from_py(pwd.getpwnam(name.decode('iso-8859-1') if py_maj > 2
46 """Drop in replacement for grp's structure with bytes instead of strings."""
47 __slots__ = 'gr_name', 'gr_passwd', 'gr_gid', 'gr_mem'
48 def __init__(self, name, passwd, gid, mem):
49 assert type(name) == bytes
50 assert type(passwd) == bytes
52 assert type(m) == bytes
53 self.gr_name, self.gr_passwd, self.gr_gid, self.gr_mem = \
54 name, passwd, gid, mem
56 def _group_from_py(py):
59 return Group(py.gr_name.encode('iso-8859-1'),
60 py.gr_passwd.encode('iso-8859-1'),
62 tuple(x.encode('iso-8859-1') for x in py.gr_mem))
65 return _group_from_py(grp.getgrgid(uid))
68 assert isinstance(name, bytes)
69 return _group_from_py(grp.getgrnam(name.decode('iso-8859-1') if py_maj > 2
73 _uid_to_pwd_cache = {}
74 _name_to_pwd_cache = {}
76 def pwd_from_uid(uid):
77 """Return password database entry for uid (may be a cached value).
78 Return None if no entry is found.
80 global _uid_to_pwd_cache, _name_to_pwd_cache
81 entry, cached = cache_key_value(getpwuid, uid, _uid_to_pwd_cache)
82 if entry and not cached:
83 _name_to_pwd_cache[entry.pw_name] = entry
86 def pwd_from_name(name):
87 """Return password database entry for name (may be a cached value).
88 Return None if no entry is found.
90 assert type(name) == bytes
91 global _uid_to_pwd_cache, _name_to_pwd_cache
92 entry, cached = cache_key_value(getpwnam, name, _name_to_pwd_cache)
93 if entry and not cached:
94 _uid_to_pwd_cache[entry.pw_uid] = entry
98 _gid_to_grp_cache = {}
99 _name_to_grp_cache = {}
101 def grp_from_gid(gid):
102 """Return password database entry for gid (may be a cached value).
103 Return None if no entry is found.
105 global _gid_to_grp_cache, _name_to_grp_cache
106 entry, cached = cache_key_value(getgrgid, gid, _gid_to_grp_cache)
107 if entry and not cached:
108 _name_to_grp_cache[entry.gr_name] = entry
112 def grp_from_name(name):
113 """Return password database entry for name (may be a cached value).
114 Return None if no entry is found.
116 assert type(name) == bytes
117 global _gid_to_grp_cache, _name_to_grp_cache
118 entry, cached = cache_key_value(getgrnam, name, _name_to_grp_cache)
119 if entry and not cached:
120 _gid_to_grp_cache[entry.gr_gid] = entry
126 """Get the user's login name."""
130 _username = pwd_from_uid(uid).pw_name or b'user%d' % uid
136 """Get the user's full name."""
138 if not _userfullname:
140 entry = pwd_from_uid(uid)
142 _userfullname = entry.pw_gecos.split(b',')[0] or entry.pw_name
143 if not _userfullname:
144 _userfullname = b'user%d' % uid