Skip to content

Commit

Permalink
passwd: sync etc/{,g}shadow according to etc/{passwd,group}
Browse files Browse the repository at this point in the history
Refer to coreos#49 (comment),
do testing:
1. Remove bin line in group and passwd
2. Build FCOS, see logs:
```
systemd.post: Creating group 'bin' with GID 1.
systemd.post: Creating user 'bin' (bin) with UID 1 and GID 1.
systemd.post: /etc/gshadow: Group "bin" already exists.
```

According to @cgwalters 's pointer:

The above log will lead systemd-sysusers (during systemd.post)
exit early before saving the updated `/etc/{passwd,group}` refer
to [code](https://github.com/systemd/systemd/blob/main/src/sysusers/sysusers.c#L820),
and bin user/group will not be saved finally.

The root cause is that `gshadow` is not consistent with group,
`gshadow` is from setup, and we override group according to https://github.com/coreos/fedora-coreos-config/blob/testing-devel/manifests/group.

The `shadow` is also from setup, and is not consistent with
passwd, we should also sync it.

Fix coreos/fedora-coreos-tracker#1525
  • Loading branch information
HuijingHei authored and lukewarmtemp committed Aug 8, 2023
1 parent f9ba723 commit ae85d63
Showing 1 changed file with 34 additions and 0 deletions.
34 changes: 34 additions & 0 deletions rust/src/passwd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,40 @@ fn write_data_from_treefile(
})
.with_context(|| format!("failed to write /{}", &target_etc_filename))?;

// Regenerate etc/{,g}shadow to sync with etc/{password,group}
let db = rootfs.open(target_etc_filename).map(BufReader::new)?;
let shadow_name = if target == "passwd" {
"shadow"
} else {
"gshadow"
};
let target_etc_shadow = format!("{}{}", dest_path, shadow_name);

match shadow_name {
"shadow" => {
let entries = nameservice::passwd::parse_passwd_content(db)?;
rootfs
.atomic_replace_with(&target_etc_shadow, |target_shadow| -> Result<()> {
for user in entries {
writeln!(target_shadow, "{}:*::0:99999:7:::", user.name)?;
}
Ok(())
})
.with_context(|| format!("Writing {target_etc_shadow}"))?;
}
"gshadow" => {
let entries = nameservice::group::parse_group_content(db)?;
rootfs
.atomic_replace_with(&target_etc_shadow, |target_shadow| -> Result<()> {
for group in entries {
writeln!(target_shadow, "{}:::", group.name)?;
}
Ok(())
})
.with_context(|| format!("Writing {target_etc_shadow}"))?;
}
_ => unreachable!("invalid file path: {}", target_etc_shadow),
}
Ok(true)
}

Expand Down

0 comments on commit ae85d63

Please sign in to comment.