The name "def.h" originates from before the rule of "no needless abbreviations"
was established. Let's rename the file to clarify that it contains a collection
of various semi-related constants.
This adds an additional name check when cross-matching new group
entries against existing users, which allows coalescing entries
matching both ID and name.
It provides a small idempotence enhancement when creating groups
in cases where matching user entries are in place. By fine-tuning
the conflict detection logic, this avoids picking up new random
IDs and correctly prefers configuration values instead.
This renames UidRange -> UidRangeEntry, and reintroduces UidRange which
contains the array of UidRangeEntry and its size.
No fucntional changes, just refactoring.
We have fairly nice error messages for specific operations, but only at debug
level. Instead, we'd print a fairly useless generic message:
Before:
Failed to write files: Invalid argument
After:
Failed to add existing group "users" to temporary group file: Invalid argument
Fixes#10241.
/bin/sh as a shell is punishing. There is no good reason to make
the occasional root login unpleasant.
Since /bin/sh is usually /bin/bash in compat mode, i.e. if one is
available, the other will be too, /bin/bash is almost as good as a default.
But to avoid a regression in the situation where /bin/bash (or
DEFAULT_USER_SHELL) is not installed, we check with access() and fall back
to /bin/sh. This should make this change in behaviour less risky.
(FWIW, e.g. Fedora/RHEL use /bin/bash as default for root.)
This is a follow-up of sorts for 53350c7bba,
which added the default-user-shell option, but most likely with the idea
of using /bin/bash less ;)
Fixes#24369.
We'd warn that "-" and "/sbin/nologin" are different, even even though
"/sbin/nologin" is the default we'd use. So let's stop warning in all cases
where the config would lead to the same file, also under different paths,
or when both shells are nologin shells.
The general idea is to avoid warnings when sysusers config is moved between
packages (and not exactly the same), or when it is generated from some template
and the details change in an unimportant way.
We try to chase symlinks. This means that on unmerged-usr systems we'll find
that e.g. /usr/bin/bash and /bin/bash are equivalent if the basic fs structure
is already in place (bash doesn't actually have to be installed, enough that
the /bin symlink exists). I think this is a good result: after all, /bin/bash
and /usr/bin/bash *may* be different things on an unmerged-usr system.
Fixes#24215.
/home/zbyszek/src/systemd-work/testcase.conf:3: '//sbin//nologin' is not a valid login shell field.
This isn't very useful. The usual argument holds: people use templates to
construct config, so paths may have doubled slashes and similar. Let's simplify
paths so that the value that is pushed to /etc/passwd is nice and clean.
https://github.com/systemd/systemd/pull/6636 added `fsync()` when
temporary shadow, group, and gshadow files are created, but it was
not added for passwd. As far as I can tell, this seems to have been
an oversight. I'm seeing real world issues where a blank /etc/passwd
file is being created if a machine loses power early in the boot process.
This tweaks user creation logic to properly take into consideration
an explicitly requested GID.
It fixes a bug where the creation flow would mistakenly fall back
to use the username instead, resulting in wrong lookups in case of
users and groups using the same name.
This relaxes the availability check when creating a group, if an
explicit GID has been requested.
It avoids mixing up users and groups entries with valid and unique
UIDs/GIDs, but each having the same ID number.
This is a natural extension of d6bce6e224: if we are installing sd-boot, we
want to use the sd-boot layout, so let's write the appropriate
KERNEL_INSTALL_LAYOUT setting. Effectively, if we do 'booctl install',
kernel-install will not autodetect the layout anymore.
And 357376d0bb added support for KERNEL_INSTALL_MACHINE_ID. We need to support
it here too. We both read it, so that we create the right directories, and also
write it if it wasn't written yet and we created some directories using it, so
that kernel-install that is executed later knows the machine-id that matches
the directories we crated.
The code is changed in some places to fail if we can't figure out the current
status. When installing the boot loader it's probably better not to guess.
Without any markup, the sentence could be quite confusing:
g user 55
g user 56
→
"Two or more conflicting lines for user configured"
It also wasn't clear which line is ignored.
Inspired by https://github.com/systemd/systemd/pull/21156.
user-record.[ch] are about the UserRecord JSON stuff, and the UID
allocation range stuff (i.e. login.defs handling) is a very different
thing, and complex enough on its own, let's give it its own c/h files.
No code changes, just some splitting out of code.
In general we almost never hit those asserts in production code, so users see
them very rarely, if ever. But either way, we just need something that users
can pass to the developers.
We have quite a few of those asserts, and some have fairly nice messages, but
many are like "WTF?" or "???" or "unexpected something". The error that is
printed includes the file location, and function name. In almost all functions
there's at most one assert, so the function name alone is enough to identify
the failure for a developer. So we don't get much extra from the message, and
we might just as well drop them.
Dropping them makes our code a tiny bit smaller, and most importantly, improves
development experience by making it easy to insert such an assert in the code
without thinking how to phrase the argument.
This fixes repart's, systemctl's, sysusers' and tmpfiles' specifier
expansion to honour the root dir specified with --root=. This is
relevant for specifiers such as %m, %o, … which are directly sourced
from files on disk.
This doesn't try to be overly smart: specifiers referring to runtime
concepts (i.e. boot ID, architecture, hostname) rather than files on the
medium are left as is. There's certainly a point to be made that they
should fail in case --root= is specified, but I am not entirely convinced
about that, and it's certainly something we can look into later if
there's reason to.
I wondered for a while how to hook this up best, but given that quite a
large number of specifiers resolve to data from files on disks, and most
of our tools needs this, I ultimately decided to make the root dir a
first class parameter to specifier_printf().
Replaces: #16187Fixes: #16183
This moves the definition of the specifier table consisting only of
system and /tmp specifiers into generic code so that we can share it.
This patch only adds one user of it for now. Follow-up patches will add
more.
This is not very pretty, but the code in fs-util.c already provisions for
missing /proc. We ourselves are careful to set up /proc, but not everybody
is and it is important for sysusers to also work where shadow-utils would:
I would like to replace calls to useradd and groupadd in Fedora systemd rpm
scriptlets with a call to sysusers. It has a number of advantages:
- dogfooding
- we don't need to manually duplicate the information from our sysusers
files to scriptlets
- a dependency on shadow-utils is dropped, which transitively drops dependencies
on setup and fedora-repos and bunch of other stuff.
We could try to get 'dnf' and 'rpm --root' and such to be reworked,
but not in any reasonable timeframe. And even if this was done, we'd still
want to support older rpm/dnf versions.
I'm trying to use systemd-sysusers for systemd.rpm itself, and the invocation
in dnf chroot is failing like this:
...
Creating group input with gid 999.
Creating group kvm with gid 36.
Creating group render with gid 998.
Creating group sgx with gid 997.
Creating group systemd-journal with gid 190.
Creating group systemd-network with gid 192.
Creating user systemd-network (systemd Network Management) with uid 192 and gid 192.
Creating group systemd-oom with gid 996.
Creating user systemd-oom (systemd Userspace OOM Killer) with uid 996 and gid 996.
Creating group systemd-resolve with gid 193.
Creating user systemd-resolve (systemd Resolver) with uid 193 and gid 193.
Creating group systemd-timesync with gid 995.
Creating user systemd-timesync (systemd Time Synchronization) with uid 995 and gid 995.
Creating group systemd-coredump with gid 994.
Creating user systemd-coredump (systemd Core Dumper) with uid 994 and gid 994.
Failed to write files: Function not implemented
Let's add more info to make such failures easier to debug.
We usually call specifier_printf() and then check the validity of
the result. In many cases, validity checkers, e.g. path_is_valid(),
refuse too long strings. This makes specifier_printf() refuse such
long results earlier.
Moreover, unit_full_string() and description field in sysuser now
refuse results longer than LONG_LINE_MAX. config_parse() already
refuses the line longer than LONG_LINE_MAX. Hence, it should be ok
to set the same value as the maximum length of the resolved string.
Let's add three defines for the 3 special cases of passwords.
Some of our tools used different values for the "locked"/"invalid" case,
let's settle on using "!*" which means the password is both locked *and*
invalid.
Other tools like to use "!!" for this case, which however is less than
ideal I think, since the this could also be a considered an entry with
an empty password, that can be enabled again by unlocking it twice.
Let's enable this in all tools that intend to write to the OS images.
It's not conditionalized for now, as there already is conditionalization
in the existance or absence of the flag in the GPT partition table (and
it's opt-in), hence it should be OK to just enable this by default for
now if the flag is set.