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 return _passwd_from_py(pwd.getpwnam(name))
44 """Drop in replacement for grp's structure with bytes instead of strings."""
45 __slots__ = 'gr_name', 'gr_passwd', 'gr_gid', 'gr_mem'
46 def __init__(self, name, passwd, gid, mem):
47 assert type(name) == bytes
48 assert type(passwd) == bytes
50 assert type(m) == bytes
51 self.gr_name, self.gr_passwd, self.gr_gid, self.gr_mem = \
52 name, passwd, gid, mem
54 def _group_from_py(py):
57 return Group(py.gr_name.encode('iso-8859-1'),
58 py.gr_passwd.encode('iso-8859-1'),
60 tuple(x.encode('iso-8859-1') for x in py.gr_mem))
63 return _group_from_py(pwd.getgrgid(uid))
66 return _group_from_py(pwd.getgrnam(name))
69 _uid_to_pwd_cache = {}
70 _name_to_pwd_cache = {}
72 def pwd_from_uid(uid):
73 """Return password database entry for uid (may be a cached value).
74 Return None if no entry is found.
76 global _uid_to_pwd_cache, _name_to_pwd_cache
77 entry, cached = cache_key_value(getpwuid, uid, _uid_to_pwd_cache)
78 if entry and not cached:
79 _name_to_pwd_cache[entry.pw_name] = entry
82 def pwd_from_name(name):
83 """Return password database entry for name (may be a cached value).
84 Return None if no entry is found.
86 assert type(name) == bytes
87 global _uid_to_pwd_cache, _name_to_pwd_cache
88 entry, cached = cache_key_value(getpwnam, name, _name_to_pwd_cache)
89 if entry and not cached:
90 _uid_to_pwd_cache[entry.pw_uid] = entry
94 _gid_to_grp_cache = {}
95 _name_to_grp_cache = {}
97 def grp_from_gid(gid):
98 """Return password database entry for gid (may be a cached value).
99 Return None if no entry is found.
101 global _gid_to_grp_cache, _name_to_grp_cache
102 entry, cached = cache_key_value(grp.getgrgid, gid, _gid_to_grp_cache)
103 if entry and not cached:
104 _name_to_grp_cache[entry.gr_name] = entry
108 def grp_from_name(name):
109 """Return password database entry for name (may be a cached value).
110 Return None if no entry is found.
112 assert type(name) == bytes
113 global _gid_to_grp_cache, _name_to_grp_cache
114 entry, cached = cache_key_value(grp.getgrnam, name, _name_to_grp_cache)
115 if entry and not cached:
116 _gid_to_grp_cache[entry.gr_gid] = entry
122 """Get the user's login name."""
126 _username = pwd_from_uid(uid).pw_name or b'user%d' % uid
132 """Get the user's full name."""
134 if not _userfullname:
136 entry = pwd_from_uid(uid)
138 _userfullname = entry.pw_gecos.split(b',')[0] or entry.pw_name
139 if not _userfullname:
140 _userfullname = b'user%d' % uid