MCPcopy
hub / github.com/cockpit-project/cockpit / AccountsPage

Function AccountsPage

pkg/users/users.js:43–158  ·  view source on GitHub ↗
()

Source from the content-addressed store, hash-verified

41};
42
43function AccountsPage() {
44 const [isGroupsExpanded, setIsGroupsExpanded] = useState(false);
45 const { path } = usePageLocation();
46 const accounts = useFile("/etc/passwd", { syntax: etc_passwd_syntax });
47 const groups = useFile("/etc/group", { syntax: etc_group_syntax });
48 const shells = useFile("/etc/shells", { syntax: etc_shells_syntax });
49 const current_user_info = useLoggedInUser();
50
51 // Handle the case where logindef == null, i.e. the file does not exist.
52 // While that's unusual, "empty /etc" is a goal, and it shouldn't crash the page.
53 const [min_gid, setMinGid] = useState(500);
54 const [max_gid, setMaxGid] = useState(60000);
55 const [min_uid, setMinUid] = useState(500);
56 const [max_uid, setMaxUid] = useState(60000);
57 const [details, setDetails] = useState(null);
58
59 useInit(async () => {
60 const logind_client = cockpit.dbus("org.freedesktop.login1");
61
62 const debouncedGetLoginDetails = debounce(100, () => {
63 getLoginDetails(logind_client).then(setDetails);
64 });
65
66 /* We are mostly interested in UserNew/UserRemoved. But SessionRemoved happens immediately after logout,
67 * while UserRemoved lags behind due to the "State: closing" period when the user's systemd instance
68 * etc. are being cleaned up. Also, there's not that many signals and this is debounced, so just react to all
69 * of them. See https://www.freedesktop.org/wiki/Software/systemd/logind/ */
70 logind_client.subscribe({
71 interface: "org.freedesktop.login1.Manager",
72 path: "/org/freedesktop/login1",
73 }, debouncedGetLoginDetails);
74
75 let handleUtmp;
76
77 // Watch /etc/shadow to register lock/unlock/expire changes; but avoid reading it, it's sensitive data
78 const handleShadow = cockpit.file("/etc/shadow", { superuser: "try" });
79 handleShadow.watch(() => debouncedGetLoginDetails(), { read: false });
80
81 let handleLogindef;
82 try {
83 await fsinfo("/etc/login.defs", []);
84 handleLogindef = cockpit.file("/etc/login.defs");
85 } catch (ex) {
86 handleLogindef = cockpit.file("/usr/etc/login.defs");
87 }
88
89 handleLogindef.watch((logindef) => {
90 if (logindef === null)
91 return;
92
93 const minGid = parseInt(logindef.match(/^GID_MIN\s+(\d+)/m)[1]);
94 const maxGid = parseInt(logindef.match(/^GID_MAX\s+(\d+)/m)[1]);
95 const minUid = parseInt(logindef.match(/^UID_MIN\s+(\d+)/m)[1]);
96 const maxUid = parseInt(logindef.match(/^UID_MAX\s+(\d+)/m)[1]);
97
98 if (minGid)
99 setMinGid(minGid);
100 if (maxGid)

Callers

nothing calls this directly

Calls 11

fsinfoFunction · 0.90
usePageLocationFunction · 0.85
useFileFunction · 0.85
useLoggedInUserFunction · 0.85
useInitFunction · 0.85
getLoginDetailsFunction · 0.85
sortGroupsFunction · 0.85
forEachMethod · 0.80
watchMethod · 0.65
closeMethod · 0.65
mapMethod · 0.45

Tested by

no test coverage detected