Commit 563dc6f8e2 added support for
/etc/{passwd,group} only but since nsswitch.conf(5) appears to document the NIS
entries also for shadow, let's support this case too.
The NIS-catchall entry switches from files to NIS lookup and never goes back,
so it must be the last entry in /etc/passwd (the other +/-{user,@netgroup}
entries don't have to be).
That's how the nss_compat mode for /etc/passwd (and /etc/group) traditionally
works.
It's age-old historic behaviour that the NIS entry must be the last one. It
doesn't seem to be specified somewhere, but it worked like this since very
early SunOS when NIS was first included.
Fixes: #8467
This PR implements the first part of RFE #8046. I.e. this allows to
write:
```
u username -:300
```
Where the uid is chosen automatically but the gid is fixed.
When used in a package installation script, we want to invoke systemd-sysusers
before that package is installed (so it can contain files owned by the newly
created user), so the configuration to use is specified on the command
line. This should be a copy of the configuration that will be installed as
/usr/lib/sysusers.d/package.conf. We still want to obey any overrides in
/etc/sysusers.d or /run/sysusers.d in the usual fashion. Otherwise, we'd get a
different result when systemd-sysusers is run with a copy of the new config on
the command line and when systemd-sysusers is run at boot after package
instalation. In the second case any files in /etc or /run have higher priority,
so the same should happen when the configuration is given on the command line.
More generally, we want the behaviour in this special case to be as close to
the case where the file is finally on disk as possible, so we have to read all
configuration files, since they all might contain overrides and additional
configuration that matters. Even files that have lower priority might specify
additional groups for the user we are creating. Thus, we need to read all
configuration, but insert our new configuration somewhere with the right
priority.
If --target=/path/to/file.conf is given on the command line, we gather the list
of files, and pretend that the command-line config is read from
/path/to/file.conf (doesn't matter if the file on disk actually exists or
not). All package scripts should use this option to obtain consistent and
idempotent behaviour.
The corner case when --target= is specified and there are no positional
arguments is disallowed.
v1:
- version with --config-name=
v2:
- disallow --config-name= and no positional args
v3:
- remove --config-name=
v4:
- add --target= and rework the code completely
v5:
- fix argcounting bug and add example in man page
v6:
- rename --target to --replace
If the configuration is included in a script, this is more convient.
I thought it would be possible to use this for rpm scriptlets with
'%pre -p systemd-sysuser "..."', but apparently there is no way to pass
arguments to the executable ($1 is used for the package installation count).
But this functionality seems generally useful, e.g. for testing and one-off
scripts, so let's keep it.
There's a slight change in behaviour when files are given on the command line:
if we cannot parse them, error out instead of ignoring the failure. When trying
to parse all configuration files, we don't want to fail even if some config
files are broken, but when parsing a list of items specified explicitly, we
should.
v2:
- rename --direct to --inline
This is the first error message when running unprivileged, and the message is
unspecific, so let's at least add some logging at debug level to make this less
confusing.
On Debian/Ubuntu systems the default passwd/group files use a
slightly strange mapping. E.g. in passwd:
```
man❌6:12::/var/cache/man:/sbin/nologin
```
and in group:
```
disk❌6:
man❌12:
```
This is not supported in systemd-sysusers right now because
sysusers will not re-use an existing uid/gid in its normal
mode of operation. Unfortunately this reuse is needed to
replicate the default Debian/Ubuntu users/groups.
This commit enforces reuse when the "uid:gid" syntax is used
to fix this.
I also added a test that replicates the Debian base-passwd
passwd/group file to ensure things are ok.
This means we have more predicable behavior for "u foo uid:gid" lines
and also makes the generated files appear in the same order as the
inputs. So e.g.
```
u root 0 - /root
u daemon 1 - /usr/sbin
u games 5:60 - /usr/games
```
will generate
```
root❌0:0::/root:/bin/sh
daemon❌1:1::/usr/sbin:/sbin/nologin
games❌5:60::/usr/games:/sbin/nologin
```
This PR allows to write sysuser.conf lines like:
```
u games 5:60 -
```
This will create an a "games" user with uid 5 and games group with
gid 60. This is arguable ugly, however it is required to represent
certain configurations like the default passwd file on Debian and
Ubuntu.
When the ":" syntax is used and there is a group with the given
gid already then no new group is created. This allows writing the
following:
```
g unrelated 60
u games 5:60 -
```
which will create a "games" user with the uid 5 and the primary
gid 60. No group games is created here (might be useful for [1]).
[1] https://pagure.io/packaging-committee/issue/442
The advantage is that is the name is mispellt, cpp will warn us.
$ git grep -Ee "conf.set\('(HAVE|ENABLE)_" -l|xargs sed -r -i "s/conf.set\('(HAVE|ENABLE)_/conf.set10('\1_/"
$ git grep -Ee '#ifn?def (HAVE|ENABLE)' -l|xargs sed -r -i 's/#ifdef (HAVE|ENABLE)/#if \1/; s/#ifndef (HAVE|ENABLE)/#if ! \1/;'
$ git grep -Ee 'if.*defined\(HAVE' -l|xargs sed -i -r 's/defined\((HAVE_[A-Z0-9_]*)\)/\1/g'
$ git grep -Ee 'if.*defined\(ENABLE' -l|xargs sed -i -r 's/defined\((ENABLE_[A-Z0-9_]*)\)/\1/g'
+ manual changes to meson.build
squash! build-sys: use #if Y instead of #ifdef Y everywhere
v2:
- fix incorrect setting of HAVE_LIBIDN2
In nss-systemd we synthesize user entries for "nobody" and "root", as
fallback if we boot up with an entirely empty /etc. This is supposed to
be a fallback only though, and it's intended that both users exists
regularly in /etc/passwd + /etc/group. Before this patch
systemd-sysusers would never create the entries however as it notices
the synthetic entries. Let's add a way how systemd-sysusers can tell
nss-systemd not to synthesize the entries for itself.
Fixes: #6808
For files which are vital to boot
1. Avoid opening any window where power loss will zero them out or worse.
I know app developers all coded to the ext3 implementation, but
the only formal documentation we have says we're broken if we actually
rely on it. E.g.
* `man mount`, search for `auto_da_alloc`.
* http://www.linux-mtd.infradead.org/faq/ubifs.html#L_atomic_change
* https://thunk.org/tytso/blog/2009/03/15/dont-fear-the-fsync/
2. If we tell the kernel we're interested in writing them to disk, it will
tell us if that fails. So at minimum, this means we play our part in
notifying the user about errors.
I refactored error-handling in `udevadm-hwdb` a little. It turns out I did
exactly the same as had already been done in the `systemd-hwdb` version,
i.e. commit d702dcd.
Some distros (openSUSE) don't have group shadow support enabled. This can lead
to the following error:
# systemd-sysusers
Creating group foofoo with gid 478.
# systemd-sysusers
# groupdel foofoo
# systemd-sysusers
Creating group foofoo with gid 478.
Failed to write files: File exists
This patch adds --disable-gshadow option to configure. If used,
systemd-sysvusers won't consider /etc/gshadow.
This patch extracts the code which is in charge to write the new users or
groups into temporary files and move it into 4 dedicated functions.
This part was previously inlined in makes_files() making this function quite
big and hard to read and maintain.
There should be no functional change.
This adds a unified "copy_flags" parameter to all copy_xyz() function
calls, replacing the various boolean flags so far used. This should make
many invocations more readable as it is clear what behaviour is
precisely requested. This also prepares ground for adding support for
more modes later on.
We don't have plural in the name of any other -util files and this
inconsistency trips me up every time I try to type this file name
from memory. "formats-util" is even hard to pronounce.
Fixes:
Oct 20 09:10:49 systemd-sysusers[144]: Direct leak of 20 byte(s) in 1 object(s) allocated from:
Oct 20 09:10:49 systemd-sysusers[144]: #0 0x7f3565a13e60 in malloc (/lib64/libasan.so.3+0xc6e60)
Oct 20 09:10:49 systemd-sysusers[144]: #1 0x7f3565526bd0 in malloc_multiply src/basic/alloc-util.h:70
Oct 20 09:10:49 systemd-sysusers[144]: #2 0x7f356552cb55 in tempfn_xxxxxx src/basic/fileio.c:1116
Oct 20 09:10:49 systemd-sysusers[144]: #3 0x7f356552c4f0 in fopen_temporary src/basic/fileio.c:1042
Oct 20 09:10:49 systemd-sysusers[144]: #4 0x7f356555e00e in fopen_temporary_label src/basic/fileio-label.c:63
Oct 20 09:10:49 systemd-sysusers[144]: #5 0x56197c4a1766 in make_backup src/sysusers/sysusers.c:209
Oct 20 09:10:49 systemd-sysusers[144]: #6 0x56197c4a6335 in write_files src/sysusers/sysusers.c:710
Oct 20 09:10:49 systemd-sysusers[144]: #7 0x56197c4ae571 in main src/sysusers/sysusers.c:1817
Oct 20 09:10:49 systemd-sysusers[144]: #8 0x7f3564dee730 in __libc_start_main (/lib64/libc.so.6+0x20730)
Fixes:
```
==28075== 64 bytes in 1 blocks are definitely lost in loss record 2 of 3
==28075== at 0x4C2BAEE: malloc (vg_replace_malloc.c:298)
==28075== by 0x4C2DCA1: realloc (vg_replace_malloc.c:785)
==28075== by 0x4ED40A2: greedy_realloc (alloc-util.c:57)
==28075== by 0x4E90F87: extract_first_word (extract-word.c:78)
==28075== by 0x4E91813: extract_many_words (extract-word.c:270)
==28075== by 0x10FE93: parse_line (sysusers.c:1325)
==28075== by 0x11198B: read_config_file (sysusers.c:1640)
==28075== by 0x111EB8: main (sysusers.c:1773)
==28075==
```
gcc is confused by the common idiom of
return errno ? -errno : -ESOMETHING
and thinks a positive value may be returned. Replace this condition
with errno > 0 to help gcc and avoid many spurious warnings. I filed
a gcc rfe a long time ago, but it hard to say if it will ever be
implemented [1].
Both conventions were used in the codebase, this change makes things
more consistent. This is a follow up to bcb161b023.
[1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61846
The macro is generically useful for putting together search paths, hence
let's make it truly generic, by dropping the implicit ".d" appending it
does, and leave that to the caller. Also rename it from
CONF_DIRS_NULSTR() to CONF_PATHS_NULSTR(), since it's not strictly about
dirs that way, but any kind of file system path.
Also, mark CONF_DIR_SPLIT_USR() as internal macro by renaming it to
_CONF_PATHS_SPLIT_USR() so that the leading underscore indicates that
it's internal.
There are more than enough calls doing string manipulations to deserve
its own files, hence do something about it.
This patch also sorts the #include blocks of all files that needed to be
updated, according to the sorting suggestions from CODING_STYLE. Since
pretty much every file needs our string manipulation functions this
effectively means that most files have sorted #include blocks now.
Also touches a few unrelated include files.