This makes syntax be the same for commands which are started by the manager and
those which are spawned directly (when --scope is used).
Before:
$ systemd-run -q -t echo '$TERM'
xterm-256color
$ systemd-run -q --scope echo '$TERM'
$TERM
Now:
$ systemd-run -q --scope echo '$TERM'
xterm-256color
Previous behaviour can be restored via --expand-environment=no:
$ systemd-run -q --scope --expand-environment=no echo '$TERM'
$TERM
Fixes#22948.
At some level, this is a compat break. Fortunately --scope is not very widely
used, so I think we can get away with this. Having different syntax depending
on whether --scope was used or not was bad UX.
A NEWS entry will be required.
This uses StartExecEx to get the equivalent of ExecStart=:. StartExecEx was
added in b3d593673c, so this will not work with
older systemds.
A hint is emitted if we get an error indicating lack of support. PID1 returns
SD_BUS_ERROR_PROPERTY_READ_ONLY, but I'm checking for
SD_BUS_ERROR_UNKNOWN_PROPERTY too for safety.
Just refactoring, in preparation for future changes.
(Though I think it'd be reasonable to do anyway, those functions were
awfully long.)
'git diff' displays this badly. The middle part of start_transient_service()
is moved to make_transient_service_unit(), and the middle part of
start_transient_trigger() is moved to make_transient_trigger_unit().
start_transient_service() would return two ints: one normally and one via
*retval. We can just return one int and propagate it directly, because we
use DEFINE_MAIN_FUNCTION_WITH_POSITIVE_FAILURE().
The property name is called ExecStartEx, but we have to write it as ExecStart=
in the unit file. :(
Bug introduced in b3d593673c when ex-properties
were initially added.
In addition, we cannot escape $ as $$, because when ":" is used, we wouldn't
unescape $$ back to $.
Unfortunately we can't escape $ when ':' is used to prohibit variable expansion:
ExecStart=:echo $$
is not the same as
ExecStart=:echo $
This just adds the functionality and the unittests, without using it anywhere
for real yet.
Our escaping of '$' is '$$', not '\$'. We would write unit files that
were not valid:
$ systemd-run --user bash -c 'echo $$; sleep 1000'
Running as unit: run-r1c7c45b5b69f487c86ae205e12100808.service
$ systemctl cat --user run-r1c7c45b5b69f487c86ae205e12100808
# /run/user/1000/systemd/transient/run-r1c7c45b5b69f487c86ae205e12100808.service
...
ExecStart="/usr/bin/bash" "-c" "echo \$\$\; sleep 1000"
$ systemd-analyze verify /run/user/1000/systemd/transient/run-r1c7c45b5b69f487c86ae205e12100808.service
/run/user/1000/systemd/transient/run-r1c7c45b5b69f487c86ae205e12100808.service:7:
Ignoring unknown escape sequences: "echo \$\$\; sleep 1000"
Similarly, ';' cannot be escaped as '\;'. Only a handful of characters
listed in "Supported escapes" is allowed.
Escaping of "'" can be done, but it's not useful because we use double quotes
around the string anyway whenever we do escaping.
unit_write_setting() is called all over the place. In a great majority of
places we write either fixed strings or something that we generate ourselves,
so no escaping or quoting is needed. (And it's not allowed, e.g.
'Type="oneshot"' would not work.) But if we forgot to add escaping or quoting
for a free-style string, it would probably allow writing a unit file that would
be read completely wrong. I looked over various places where
unit_write_setting() is called, and I couldn't find any place where
quoting/escaping was forgotten. But trying to figure out the full
ramifications of this change is not easy.
__builtin_popcount() is a bit of a mouthful, so let's provide a helper.
Using _Generic has the advantage that if a type other then the ones on
the list is given, compilation will fail. This is nice, because if by any
change we pass a wider type, it is rejected immediately instead of being
truncated.
log.h is also needed. It is included transitively, but let's include it
directly.
macro.h is *not* needed.
None of the existing test files fit very well. test-unit-serialize is
pretty close, but it does special cgroup setup, which we don't need in
this case. I hope we can add more tests in the future for this basic
functionality, so I'm adding a brand new file names after the source file
it's testing.
Move the tests that link to libcore into a separate subgroup.
They are special and it makes sense to keep them together. While
at it, make the list alphabetical.
Also, merge the list additions into one. No idea why it was like that.
I was testing transient units and user@.service crashed. I restarted it, and
tried to create a transient unit. It failed because
/run/user/1000/systemd/transient/ remained after the previous aborted run:
Failed to start transient service unit: Unit run-u0.service was already loaded or has a fragment file.
Remove the directory during initial startup so we don't get confused by our own
files.
I was changing how some properties are appended to the StartTransientUnit call
and messed up the message contents. When something is wrong with how the
message is structed, we would return a very generic
"Failed to start transient service unit: No such device or address".
Mention that it was property setting that failed, and translate ENXIO to a
different message. bus_unit_set_properties() or any of the children it calls
may also return other errors, in particular EBADMSG or ENOMEM, but the error
message that is generated for those is understandable, so we don't need to
"translate" them explicitly.
bus_unit_set_properties() is called from two places, so it seems nicer to
generate the message internally, rather than ask the caller to do that. Also,
now bus_unit_set_properties() always sets <error>, which is nicer for the
callers.
The description was split — part was under ExecStart= and part in "Command lines".
Now the whole generic part is moved to the separate section, and under ExecStart=
only the stuff that is specific to that option is described.
This just moves the text and removes some repetitions.
After 'if (DEBUG_LOGGING)' is added, the two call sites are almost identical,
except that we forgot LOG_UNIT_INVOCATION_ID(unit).
I removed the handling of the log_oom(). It's a debug message only after all,
and it's unlikely to fail.
The function had a provision for NULL input, and would return NULL, but that
looks like an error and all callers pass in a non-NULL arg and report oom on
NULL. So assert that the input is non-NULL.
All callers specifed the output buffer, so we can simplify the logic to only
make an allocation if appropriate and change the return type to 'const *'.
No functional change.
If we created the dir successfully, we let chmod_and_chown_at() do its thing
and shouldn't go into the part where we check if the existing directory has the
right permissions and ownership and possibly adjust them. The code was doing
that, by relying on the fact that chmod_and_chown_at() does not return -EEXIST.
That's probably true, but seems unnecessarilly complicated.
Follow-up for c1b1492a94.
Prevent attackers from spoofing the tpmKey portion of the AuthSession by
adding a trusted key to the LUKS header metadata. Also, use a persistent
object rather than a transient object.
This provides the following benifits:
1. No way to MITM the tpmKey portion of the session, see [1] for
details.
2. Strengthens the encrypted sessions, note that the bindKey could be
dropped now.
3. Speed, once it's created we just use it.
4. Owner Auth is needed to call create primary, so using the SRK
creates a scratch space for normal users.
This is a "first to set" model, in where the first person to set the key
in the LUKS header wins. Thus, setup should be done in a known good
state. If an SRK, which is a primary key at a special persistent
address, is found, it will use whatever is there. If not, it creates an
SRK. The SRK follows the convetions used through the tpm2-software
organization code on GitHub [2], however, a split has occured between
Windows and Linux with respect to SRK templates. The Linux SRK is
generated with the unique field size set to 0, in Windows, it properly
sets the size to key size in bytes and the unique data to all 0's of that
size. Note the proper templates for SRKs is covered in spec [3].
However, the most important thing, is that both SRKs are passwordless,
and thus they should be interchangable. If Windows is the first to make
the SRK, systemd will gladly accept it and vice-versa.
1. Without the bindKey being utilized, an attacker was able to intercept
this and fake a key, thus being able to decrypt and encrypt traffic as
needed. Introduction of the bindKey strengthened this, but allows for
the attacker to brute force AES128CFB using pin guesses. Introduction of
the salt increases the difficulty of this attack as well as DA attacks
on the TPM objects itself.
2. https://github.com/tpm2-software
3. https://trustedcomputinggroup.org/wp-content/uploads/TCG-TPM-v2.0-Provisioning-Guidance-Published-v1r1.pdfFixes: #20668Fixes: #22637
Signed-off-by: William Roberts <william.c.roberts@intel.com>
pam_nologin looks for /etc/nologin and /run/nologin.
user-sessions creates (and removes) /run/nologin, but also removes
/etc/nologin. (This behaviour is unchanged since the introduction
of the binary in e92787416c691c3f34f47349e5eae3fa68eae856.)
By not removing pam_nologin we fully drop compatibility with PAM < 1.1.
This has the advantage that now /etc/nologin can be used by administrator to
disable user logins, e.g. for extended maintanance. We already specified
PAM >= 1.1.2 as dependency, so this was already covered.
The makes the code match the man page.
Fixes#26965.
Follow-up for d2ebd50d7f
We now modify our cmdline to use '=' for all arguments,
but didn't change early setup check to work with that.
So every daemon-reexec does a full setup, thus breaking
running user sessions.
Fixes#27106