sysusers: gracefully handle existing group in /etc/gshadow
systemd-sysusers currently skips entries for groups that already exists. However, if a group exists only in /etc/gshadow and not in /etc/group, systemd-sysusers panics: ~# groupdel sgx ~# systemd-sysusers; echo $? Creating group 'sgx' with GID 106. 0 ~# systemd-sysusers; echo $? 0 ~# sed -i '/sgx/d' /etc/group ~# systemd-sysusers; echo $? Creating group 'sgx' with GID 106. /etc/gshadow: Group "sgx" already exists. 1 To fix this, let's mirror the logic from the user path (write_temporary_shadow()) where we simply drop the user from the "todo" queue if it already exists in /etc/shadow instead of throwing an error.
This commit is contained in:
committed by
Yu Watanabe
parent
f4cb4596a3
commit
36a9875c1d
@@ -932,10 +932,13 @@ static int write_temporary_gshadow(
|
||||
while ((r = fgetsgent_sane(original, &sg)) > 0) {
|
||||
|
||||
i = ordered_hashmap_get(c->groups, sg->sg_namp);
|
||||
if (i && i->todo_group)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EEXIST),
|
||||
"%s: Group \"%s\" already exists.",
|
||||
gshadow_path, sg->sg_namp);
|
||||
if (i && i->todo_group) {
|
||||
/* The group already exists in /etc/gshadow. Only the
|
||||
* /etc/gshadow stage is left, so we can safely remove
|
||||
* the item from the todo set. */
|
||||
i->todo_group = false;
|
||||
ordered_hashmap_remove(c->todo_gids, GID_TO_PTR(i->gid));
|
||||
}
|
||||
|
||||
r = putsgent_with_members(c, sg, gshadow);
|
||||
if (r < 0)
|
||||
|
||||
@@ -23,7 +23,7 @@ prepare_testdir() {
|
||||
mkdir -p "$TESTDIR/etc/sysusers.d/"
|
||||
mkdir -p "$TESTDIR/usr/lib/sysusers.d/"
|
||||
rm -f "$TESTDIR"/etc/*{passwd,group,shadow}
|
||||
for i in $1.initial-{passwd,group,shadow}; do
|
||||
for i in $1.initial-{passwd,group,shadow,gshadow}; do
|
||||
test -f "$i" && cp "$i" "$TESTDIR/etc/${i#*.initial-}"
|
||||
done
|
||||
return 0
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
testgroup:x:333:
|
||||
@@ -0,0 +1 @@
|
||||
testgroup:!::
|
||||
@@ -0,0 +1,4 @@
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
# Test that a group pre-existing in /etc/gshadow but missing from
|
||||
# /etc/group is handled gracefully instead of failing with EEXIST.
|
||||
g testgroup 333
|
||||
@@ -0,0 +1 @@
|
||||
testuser:x:444:
|
||||
@@ -0,0 +1 @@
|
||||
testuser:x:444:444:Test User:/:NOLOGIN
|
||||
@@ -0,0 +1 @@
|
||||
testuser:!*::0:99999:7:::
|
||||
@@ -0,0 +1,4 @@
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
# Test that a user pre-existing in /etc/shadow but missing from
|
||||
# /etc/passwd is handled gracefully (existing entry is updated).
|
||||
u testuser 444 "Test User"
|
||||
Reference in New Issue
Block a user