mirror of
https://github.com/uutils/shadow.git
synced 2026-10-16 02:48:14 -07:00
* --root is a real chroot in every tool, not a path prefix in eight of them
Five tools called chroot(2) for --root. The other eight -- groupadd,
groupdel, groupmod, grpck, pwck, useradd, userdel, usermod -- folded the
argument into the same resolver --prefix uses, so it only prepended the
directory to the files the tool itself opened.
The difference shows whenever an absolute path is read out of a record
rather than being one of the tool's own files:
useradd -R /mnt/sysroot -m alice
created the home on the *host*, at /home/alice, because the path came
back from login.defs as /home/alice and nothing prefixed it. The skeleton
was copied from the host's /etc/skel. userdel -r -R had the mirror-image
problem and resolved the home to delete against /.
All thirteen now chroot, through one helper in shadow-core rather than
five copies of it, and refuse --root for anyone but root: a setuid-root
binary pointed at a tree of the caller's choosing would read and write
account files that caller controls.
pwck and grpck have no --prefix, matching GNU, so their tests move to a
spawned process: --root cannot be exercised in-process at all now, since
a chroot in the test binary takes every later test into the tree with it,
where /tmp does not exist. That is how this was caught. The other tools'
in-process tests use -P, which is what they meant.
Verified in the deployment container against a minimal target tree: the
account, its home and the skeleton all land inside it, groupadd/groupmod/
groupdel operate on the tree's group file, pwck and grpck read the tree,
userdel -r removes the home from the tree, and the host is untouched
throughout.
Closes #270.
* pwck: name the shadow file in the bad-entry test
The test passed only the passwd file, so the shadow path defaulted to the
host's /etc/shadow. Unprivileged, that cannot be read, and the test
reported 'cannot open' (exit 3) instead of the bad entry it is about
(exit 2). It passed in the containers, which run as root, and failed on
the host runner.
It was --root that hid this: as a path prefix it pointed the default at
the fixture. --root is a chroot now, so the fixture has to name both
files.
* tests: guard the pwck tests that chroot
They spawn 'pwck --root', and chroot(2) needs root: the tool refuses the
option for anyone else. The containers run as root so they passed there,
and the host runner failed them.