Compare commits

...

32 Commits

Author SHA1 Message Date
Lennart Poettering 7d20404816
Merge pull request #14685 from poettering/sd-bus-bool-as-int
sd-bus documentation: highlight bool vs. int situation
2020-01-28 17:57:30 +01:00
Lennart Poettering b940fb1f4f
Merge pull request #14594 from keszybz/id128-show-gpt
Print gpt table values in systemd-id128
2020-01-28 17:23:50 +01:00
Ashley Davis 8bc943b472 fix erroneous "`" in boot loader spec 2020-01-29 00:52:54 +09:00
Lennart Poettering e0db55a643 man: document that sd_bus_message_read_array() only supports trivial types
Fixes: #14641
2020-01-28 16:52:15 +01:00
Lennart Poettering 10c238b2cc man: clarify that we decode D-Bus bools as "int", not as C99 "bool"
Fixes: #14643
2020-01-28 16:38:53 +01:00
Lennart Poettering e5667705fa man: describe types slightly more accurately 2020-01-28 16:38:38 +01:00
Lennart Poettering 979bdc47c9 man: enclose C type names in <type></type> 2020-01-28 16:37:57 +01:00
Zbigniew Jędrzejewski-Szmek ebe2ab60cc
Merge pull request #14611 from yuwata/network-fix-reconfigure
network: fix reconfigure
2020-01-28 16:10:28 +01:00
Zbigniew Jędrzejewski-Szmek d2b45da40a
Merge pull request #14633 from poettering/logind-switch-polkit
add polkit hookup for VT switching in logind
2020-01-28 16:09:09 +01:00
Lennart Poettering 8615bec7a0
Merge pull request #14667 from yuwata/boot-random-seed-mode
boot: parse random-seed-mode
2020-01-28 15:42:10 +01:00
Yu Watanabe 1b3cccfdac unit: add AF_ALG to systemd-networkd.service
networkd uses khash, and khash requires AF_ALG.
2020-01-28 15:34:04 +01:00
Lennart Poettering 4523f1db0f
Merge pull request #14675 from yuwata/network-dhcp-accept-nul
network: accept NUL character in SendOption=
2020-01-28 15:18:16 +01:00
Yu Watanabe 11a182aa1e test: drop sector-size line from output of sfdisk
The following commit adds 'sector-size' line to the output of sfdisk
command:
e56ca06815

Fixes #14664.
2020-01-28 15:16:13 +01:00
dann frazier 37b9966e25 test: Synchronize journal before reading from it
There's a race condition in the sysuser test where it may try to read
entries from the journal before they are available. Fix it by adding a
`journalctl --sync` call.

BugLink: https://bugs.launchpad.net/bugs/1776654
2020-01-28 15:11:58 +01:00
Lennart Poettering 766840af42
Merge pull request #14673 from keur/protect_clock
Protect clock
2020-01-28 15:11:41 +01:00
Lennart Poettering 006c44c1e8 TODO: add various items as result from devconf.cz 2020 discussions 2020-01-28 15:05:20 +01:00
Kevin Kuehler 022d334561 man: doc: Document ProtectClock= 2020-01-27 11:21:36 -08:00
Yu Watanabe 732e3a6104 network: accept NUL character in SendOption=
Closes #14609.
2020-01-27 19:58:10 +09:00
Yu Watanabe a6a36dea2d test: add tests for UNESCAPE_ACCEPT_NUL 2020-01-27 19:58:06 +09:00
Yu Watanabe 0e72e469f8 escape: introduce UNESCAPE_ACCEPT_NUL flag 2020-01-27 18:04:46 +09:00
Yu Watanabe 46dc83440f escape: make cunescape() and cunescape_length() inline 2020-01-27 17:38:41 +09:00
Kevin Kuehler 9f37272a19 analyze: Add ProtectClock= to analyze-security 2020-01-26 12:44:47 -08:00
Kevin Kuehler fc64760dda core: shared: Add ProtectClock= to systemd.exec 2020-01-26 12:23:33 -08:00
Yu Watanabe fe5a698f76 bootspec: parse random-seed-mode line in loader.conf
Fixes #14657.
2020-01-26 13:20:34 +09:00
Yu Watanabe a14c18ba7b sd-boot: fix typo
Fixes #14657.
2020-01-26 13:20:21 +09:00
Zbigniew Jędrzejewski-Szmek dc972b0740 systemd-id128: add new verb to print GPT partitions UUIDs 2020-01-23 23:32:13 +01:00
Zbigniew Jędrzejewski-Szmek 19ce38ce62 shared/gpt: export gpt_partition_type_uuid_{to,from}_string functions 2020-01-23 22:56:23 +01:00
Lennart Poettering 4acf0cfd2f logind: check PolicyKit before allowing VT switch
Let's lock this down a bit. Effectively nothing much changes, since the
default PK policy will allow users on the VT to change VT. Only users
with no local VT session won't be able to switch VTs.
2020-01-22 12:34:31 +01:00
Lennart Poettering 269e4d2d6b shared: split out polkit stuff from bus-util.c → bus-polkit.c
It's enough, complex stuff to warrant its own source file.

No other changes, just splitting out.
2020-01-22 12:34:10 +01:00
Yu Watanabe 2c0d7ed393 network: do nothing if link is in pending or linger state on reconfiguring 2020-01-22 16:08:12 +09:00
Yu Watanabe 0ce0e3470e network: synchronously save state file when link is being reconfigured 2020-01-22 16:08:12 +09:00
Yu Watanabe 8ae7b8a1e1 network: set dirty flag when link is being reconfigured 2020-01-22 16:08:12 +09:00
67 changed files with 914 additions and 548 deletions

37
TODO
View File

@ -19,6 +19,11 @@ Janitorial Clean-ups:
Features:
* homed/userdb: distuingish passwords and recovery keys in the records, since
we probably want to use different PBKDF algorithms/settings for them:
passwords have low entropy but recovery keys should have good entropy key
hence we can make them quicker to work.
* bootctl:
- teach it to prepare an ESP wholesale, i.e. with mkfs.vfat invocation
- teach it to copy in unified kernel images and maybe type #1 boot loader spec entries from host
@ -56,8 +61,6 @@ Features:
TPM-less mode, and set up linear DM mapping instead (inspired by kpartx), so
that the device paths stay the same, regardless if crypto is used or not.
* move discoverable partitions spec into markdown and our tree
* systemd-repart: by default generate minimized partition tables (i.e. tables
that only covere the space actually used, excluding any free space at the
end), in order to maximize dd'ability. Requires libfdisk work, see
@ -66,7 +69,9 @@ Features:
* systemd-repart: optionally, allow specifiying a path to initialize new
partitions from, i.e. an fs image file or a source device node. This would
then turn systemd-repart into a simple installer: with a few .repart files
you could replicate the host system on another device.
you could replicate the host system on another device. a full installer would
then be: "systemd-repart /dev/sda && bootctl install /dev/sda &&
systemd-firstboot --image= …"
* systemd-repart: MBR partition table support. Care needs to be taken regarding
Type=, so that partition definitions can sanely apply to both the GPT and the
@ -78,6 +83,32 @@ Features:
* systemd-repart: allow sizing partitions as factor of available RAM, so that
we can reasonably size swap partitions for hibernation.
* systemd-repart: allow running mkfs before making partitions pop up +
encryption via LUKS to allow booting into an empty root with only /usr mounted in
* systemd-repart: allow managing the gpt read-only partition flag + auto-mount flag
* systemd-repart: allow disabling growing of specific partitions, or making
them (think ESP: we don't ever want to grow it, since we cannot resize vfat)
* systemd-repart: add specifier expansion, add especifier that refers to root
device node of current system, /usr device node, and matching verity, so that
an installer can be made a "copy" installer of the booted OS
* systemd-repart: make it a static checker during early boot for existance and
absence of other partitions for trusted boot environments
* systemd-repart: when no configuration is found, exit early do not check
partition table, so that it is safe to run in the initrd on any system
* systemd-repart: allow config of partition uuid
* userdb: allow username prefix searches in varlink API
* userdb: allow existance checks
* pid: activation by journal search expression
* when switching root from initrd to host, set the machine_id env var so that
if the host has no machine ID set yet we continue to use the random one the
initrd had set.

View File

@ -60,7 +60,7 @@ Everything described below is located on a placeholder file system `$BOOT`. The
* Otherwise, if the OS is installed on a disk with MBR disk label, a new partition with MBR type id of 0xEA shall be created, of a suitable size (let's say 500MB), and it should be used as `$BOOT`.
* On disks with GPT disk labels
* If the OS is installed on a disk with GPT disk label, and a partition with the GPT type GUID of `bc13c2ff-59e6-4262-a352-b275fd6f7172` already exists, it should be used as `$BOOT`.
* Otherwise, if the OS is installed on a disk with GPT disk label, and an ESP partition (i.e. with the GPT type UID of `c12a7328-f81f-11d2-ba4b-00a0c93ec93b`) already exists and is large enough (let's say 250MB`) and otherwise qualifies, it should be used as `$BOOT`.
* Otherwise, if the OS is installed on a disk with GPT disk label, and an ESP partition (i.e. with the GPT type UID of `c12a7328-f81f-11d2-ba4b-00a0c93ec93b`) already exists and is large enough (let's say 250MB) and otherwise qualifies, it should be used as `$BOOT`.
* Otherwise, if the OS is installed on a disk with GPT disk label, and if the ESP partition already exists but is too small, a new suitably sized (let's say 500MB) partition with GPT type GUID of `bc13c2ff-59e6-4262-a352-b275fd6f7172` shall be created and it should be used as `$BOOT`.
* Otherwise, if the OS is installed on a disk with GPT disk label, and no ESP partition exists yet, a new suitably sized (let's say 500MB) ESP should be created and should be used as `$BOOT`.

View File

@ -64,6 +64,9 @@ Other GPT type IDs might be used on Linux, for example to mark software RAID or
LVM partitions. The definitions of those GPT types is outside of the scope of
this specification.
[systemd-id128(1)](http://www.freedesktop.org/software/systemd/man/systemd-i128.html)
may be used to list those UUIDs.
## Partition Names
For partitions of the types listed above it is recommended to use

View File

@ -192,6 +192,7 @@ All execution-related settings are available for transient units.
✓ PrivateUsers=
✓ ProtectSystem=
✓ ProtectHome=
✓ ProtectClock=
✓ MountFlags=
✓ MountAPIVFS=
✓ Personality=

View File

@ -60,13 +60,13 @@
<para>For each type specified in the type string, one or more arguments need to be specified
after the <parameter>types</parameter> parameter, in the same order. The arguments must be
pointers to appropriate types (a pointer to <code>int8_t</code> for a <literal>y</literal> in
the type string, a pointer to <code>int32_t</code> for an <literal>i</literal>, a pointer to
<code>const char*</code> for an <literal>s</literal>, ...) which are set based on the values in
pointers to appropriate types (a pointer to <type>int8_t</type> for a <literal>y</literal> in
the type string, a pointer to <type>int32_t</type> for an <literal>i</literal>, a pointer to
<type>const char*</type> for an <literal>s</literal>, ...) which are set based on the values in
the message. As an exception, in case or array and variant types, the first argument is an
"input" argument that further specifies how the message should be read. See the table below for
a complete list of allowed arguments and their types. Note that, if the basic type is a pointer
(e.g., <code>const char *</code> in the case of a string), the argument is a pointer to a
(e.g., <type>const char *</type> in the case of a string), the argument is a pointer to a
pointer, and also the pointer value that is written is only borrowed and the contents must be
copied if they are to be used after the end of the messages lifetime.</para>
@ -99,7 +99,7 @@
<entry><literal>a</literal></entry>
<entry><constant>SD_BUS_TYPE_ARRAY</constant></entry>
<entry>array</entry>
<entry>int, which specifies the expected length <parameter>n</parameter> of the array</entry>
<entry><type>int</type>, which specifies the expected length <parameter>n</parameter> of the array</entry>
<entry><parameter>n</parameter> sets of arguments appropriate for the array element type</entry>
</row>
@ -174,6 +174,14 @@ int64_t x;
sd_bus_message_read(m, "x", &amp;x);</programlisting>
<para>Read a boolean value:</para>
<programlisting>sd_bus_message *m;
int x; /* Do not use C99 'bool' type here, it's typically smaller
in memory and would cause memory corruption */
sd_bus_message_read(m, "b", &amp;x);</programlisting>
<para>Read all types of integers:</para>
<programlisting>uint8_t y;

View File

@ -48,6 +48,10 @@
appropriate for the data type. The data is part of the message — it may not be modified and is
valid only as long as the message is referenced. After this function returns, the "read pointer"
points at the next element after the array.</para>
<para>Note that this function only supports arrays of trivial types, i.e. arrays of booleans, the various
integer types, as well as floating point numbers. In particular it may not be used for arrays of strings,
structures or similar.</para>
</refsect1>
<refsect1>
@ -68,8 +72,8 @@
<varlistentry>
<term><constant>-EINVAL</constant></term>
<listitem><para>Specified type is invalid or the message parameter or one of the output
parameters are <constant>NULL</constant>.</para></listitem>
<listitem><para>Specified type is invalid or not a trivial type (see above), or the message
parameter or one of the output parameters are <constant>NULL</constant>.</para></listitem>
</varlistentry>
<varlistentry>

View File

@ -55,10 +55,10 @@
If <parameter>p</parameter> is not <constant>NULL</constant>, it should contain
a pointer to an appropriate object. For example, if <parameter>type</parameter>
is <constant>'y'</constant>, the object passed in <parameter>p</parameter>
should have type <code>uint8_t *</code>. If <parameter>type</parameter> is
should have type <type>uint8_t *</type>. If <parameter>type</parameter> is
<constant>'s'</constant>, the object passed in <parameter>p</parameter> should
have type <code>const char **</code>. Note that, if the basic type is a pointer
(e.g., <code>const char *</code> in the case of a string), the pointer is only
have type <type>const char **</type>. Note that, if the basic type is a pointer
(e.g., <type>const char *</type> in the case of a string), the pointer is only
borrowed and the contents must be copied if they are to be used after the end
of the messages lifetime. Similarly, during the lifetime of such a pointer, the
message must not be modified. See the table below for a complete list of allowed
@ -85,92 +85,92 @@
<row>
<entry><literal>y</literal></entry>
<entry><constant>SD_BUS_TYPE_BYTE</constant></entry>
<entry>unsigned integer</entry>
<entry>uint8_t *</entry>
<entry>8bit unsigned integer</entry>
<entry><type>uint8_t *</type></entry>
</row>
<row>
<entry><literal>b</literal></entry>
<entry><constant>SD_BUS_TYPE_BOOLEAN</constant></entry>
<entry>boolean</entry>
<entry>int *</entry>
<entry><type>int *</type> (NB: not <type>bool *</type>)</entry>
</row>
<row>
<entry><literal>n</literal></entry>
<entry><constant>SD_BUS_TYPE_INT16</constant></entry>
<entry>signed integer</entry>
<entry>int16_t *</entry>
<entry>16bit signed integer</entry>
<entry><type>int16_t *</type></entry>
</row>
<row>
<entry><literal>q</literal></entry>
<entry><constant>SD_BUS_TYPE_UINT16</constant></entry>
<entry>unsigned integer</entry>
<entry>uint16_t *</entry>
<entry>16bit unsigned integer</entry>
<entry><type>uint16_t *</type></entry>
</row>
<row>
<entry><literal>i</literal></entry>
<entry><constant>SD_BUS_TYPE_INT32</constant></entry>
<entry>signed integer</entry>
<entry>int32_t *</entry>
<entry>32bit signed integer</entry>
<entry><type>int32_t *</type></entry>
</row>
<row>
<entry><literal>u</literal></entry>
<entry><constant>SD_BUS_TYPE_UINT32</constant></entry>
<entry>unsigned integer</entry>
<entry>uint32_t *</entry>
<entry>32bit unsigned integer</entry>
<entry><type>uint32_t *</type></entry>
</row>
<row>
<entry><literal>x</literal></entry>
<entry><constant>SD_BUS_TYPE_INT64</constant></entry>
<entry>signed integer</entry>
<entry>int64_t *</entry>
<entry>64bit signed integer</entry>
<entry><type>int64_t *</type></entry>
</row>
<row>
<entry><literal>t</literal></entry>
<entry><constant>SD_BUS_TYPE_UINT64</constant></entry>
<entry>unsigned integer</entry>
<entry>uint64_t *</entry>
<entry>64bit unsigned integer</entry>
<entry><type>uint64_t *</type></entry>
</row>
<row>
<entry><literal>d</literal></entry>
<entry><constant>SD_BUS_TYPE_DOUBLE</constant></entry>
<entry>floating-point</entry>
<entry>double *</entry>
<entry>IEEE 754 double precision floating-point</entry>
<entry><type>double *</type></entry>
</row>
<row>
<entry><literal>s</literal></entry>
<entry><constant>SD_BUS_TYPE_STRING</constant></entry>
<entry>Unicode string</entry>
<entry>const char **</entry>
<entry>UTF-8 string</entry>
<entry><type>const char **</type></entry>
</row>
<row>
<entry><literal>o</literal></entry>
<entry><constant>SD_BUS_TYPE_OBJECT_PATH</constant></entry>
<entry>object path</entry>
<entry>const char **</entry>
<entry>D-Bus object path stringy</entry>
<entry><type>const char **</type></entry>
</row>
<row>
<entry><literal>g</literal></entry>
<entry><constant>SD_BUS_TYPE_SIGNATURE</constant></entry>
<entry>signature</entry>
<entry>const char **</entry>
<entry>D-Bus signature string</entry>
<entry><type>const char **</type></entry>
</row>
<row>
<entry><literal>h</literal></entry>
<entry><constant>SD_BUS_TYPE_UNIX_FD</constant></entry>
<entry>UNIX file descriptor</entry>
<entry>int *</entry>
<entry><type>int *</type></entry>
</row>
</tbody>
</tgroup>

View File

@ -73,6 +73,10 @@
will be printed. This is available in systemd services. See
<citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
</para>
<para>With <command>show</command>, well-known UUIDs are printed. When no arguments are specified, all
known UUIDs are shown. When arguments are specified, they must be the names or values of one or more
known UUIDs, which are then printed.</para>
</refsect1>
<refsect1>

View File

@ -405,11 +405,11 @@ CapabilityBoundingSet=~CAP_B CAP_C</programlisting>
<varname>RestrictAddressFamilies=</varname>, <varname>RestrictNamespaces=</varname>,
<varname>PrivateDevices=</varname>, <varname>ProtectKernelTunables=</varname>,
<varname>ProtectKernelModules=</varname>, <varname>ProtectKernelLogs=</varname>,
<varname>MemoryDenyWriteExecute=</varname>, <varname>RestrictRealtime=</varname>,
<varname>RestrictSUIDSGID=</varname>, <varname>DynamicUser=</varname> or <varname>LockPersonality=</varname>
are specified. Note that even if this setting is overridden by them, <command>systemctl show</command> shows the
original value of this setting. Also see <ulink
url="https://www.kernel.org/doc/html/latest/userspace-api/no_new_privs.html">No New Privileges
<varname>ProtectClock=</varname>, <varname>MemoryDenyWriteExecute=</varname>,
<varname>RestrictRealtime=</varname>, <varname>RestrictSUIDSGID=</varname>, <varname>DynamicUser=</varname>
or <varname>LockPersonality=</varname> are specified. Note that even if this setting is overridden by them,
<command>systemctl show</command> shows the original value of this setting.
Also see <ulink url="https://www.kernel.org/doc/html/latest/userspace-api/no_new_privs.html">No New Privileges
Flag</ulink>.</para></listitem>
</varlistentry>
@ -1296,6 +1296,21 @@ BindReadOnlyPaths=/var/lib/systemd</programlisting>
<xi:include href="system-only.xml" xpointer="singular"/></listitem>
</varlistentry>
<varlistentry>
<term><varname>ProtectClock=</varname></term>
<listitem><para>Takes a boolean argument. If set, writes to the hardware clock or system clock will be denied.
It is recommended to turn this on for most services that do not need modify the clock. Defaults to off. Enabling
this option removes <constant>CAP_SYS_TIME</constant> and <constant>CAP_WAKE_ALARM</constant> from the
capability bounding set for this unit, installs a system call filter to block calls that can set the
clock, and <varname>DeviceAllow=char-rtc r</varname> is implied. This ensures <filename>/dev/rtc0</filename>,
<filename>/dev/rtc1</filename>, etc are made read only to the service. See
<citerefentry><refentrytitle>systemd.resource-control</refentrytitle><manvolnum>5</manvolnum></citerefentry>
for the details about <varname>DeviceAllow=</varname>.</para>
<xi:include href="system-only.xml" xpointer="singular"/></listitem>
</varlistentry>
<varlistentry>
<term><varname>ProtectKernelTunables=</varname></term>
@ -1807,7 +1822,7 @@ SystemCallErrorNumber=EPERM</programlisting>
mappings. Specifically these are the options <varname>PrivateTmp=</varname>,
<varname>PrivateDevices=</varname>, <varname>ProtectSystem=</varname>, <varname>ProtectHome=</varname>,
<varname>ProtectKernelTunables=</varname>, <varname>ProtectControlGroups=</varname>,
<varname>ProtectKernelLogs=</varname>, <varname>ReadOnlyPaths=</varname>,
<varname>ProtectKernelLogs=</varname>, <varname>ProtectClock=</varname>, <varname>ReadOnlyPaths=</varname>,
<varname>InaccessiblePaths=</varname> and <varname>ReadWritePaths=</varname>.</para></listitem>
</varlistentry>

View File

@ -65,6 +65,7 @@ struct security_info {
bool protect_kernel_modules;
bool protect_kernel_tunables;
bool protect_kernel_logs;
bool protect_clock;
char *protect_home;
char *protect_system;
@ -783,6 +784,16 @@ static const struct security_assessor security_assessor_table[] = {
.assess = assess_bool,
.offset = offsetof(struct security_info, protect_kernel_logs),
},
{
.id = "ProtectClock=",
.description_good = "Service cannot write to the hardware clock or system clock",
.description_bad = "Service may write to the hardware clock or system clock",
.url = "https://www.freedesktop.org/software/systemd/man/systemd.exec.html#ProtectClock=",
.weight = 1000,
.range = 1,
.assess = assess_bool,
.offset = offsetof(struct security_info, protect_clock),
},
{
.id = "ProtectHome=",
.url = "https://www.freedesktop.org/software/systemd/man/systemd.exec.html#ProtectHome=",
@ -1907,6 +1918,7 @@ static int acquire_security_info(sd_bus *bus, const char *name, struct security_
{ "ProtectKernelModules", "b", NULL, offsetof(struct security_info, protect_kernel_modules) },
{ "ProtectKernelTunables", "b", NULL, offsetof(struct security_info, protect_kernel_tunables) },
{ "ProtectKernelLogs", "b", NULL, offsetof(struct security_info, protect_kernel_logs) },
{ "ProtectClock", "b", NULL, offsetof(struct security_info, protect_clock) },
{ "ProtectSystem", "s", NULL, offsetof(struct security_info, protect_system) },
{ "RemoveIPC", "b", NULL, offsetof(struct security_info, remove_ipc) },
{ "RestrictAddressFamilies", "(bas)", property_read_restrict_address_families, 0 },
@ -1984,6 +1996,10 @@ static int acquire_security_info(sd_bus *bus, const char *name, struct security_
if (info->protect_kernel_logs)
info->capability_bounding_set &= ~(UINT64_C(1) << CAP_SYSLOG);
if (info->protect_clock)
info->capability_bounding_set &= ~((UINT64_C(1) << CAP_SYS_TIME) |
(UINT64_C(1) << CAP_WAKE_ALARM));
if (info->private_devices)
info->capability_bounding_set &= ~((UINT64_C(1) << CAP_MKNOD) |
(UINT64_C(1) << CAP_SYS_RAWIO));

View File

@ -102,7 +102,7 @@ char *cescape(const char *s) {
return cescape_length(s, strlen(s));
}
int cunescape_one(const char *p, size_t length, char32_t *ret, bool *eight_bit) {
int cunescape_one(const char *p, size_t length, char32_t *ret, bool *eight_bit, bool accept_nul) {
int r = 1;
assert(p);
@ -171,7 +171,7 @@ int cunescape_one(const char *p, size_t length, char32_t *ret, bool *eight_bit)
return -EINVAL;
/* Don't allow NUL bytes */
if (a == 0 && b == 0)
if (a == 0 && b == 0 && !accept_nul)
return -EINVAL;
*ret = (a << 4U) | b;
@ -199,7 +199,7 @@ int cunescape_one(const char *p, size_t length, char32_t *ret, bool *eight_bit)
c = ((uint32_t) a[0] << 12U) | ((uint32_t) a[1] << 8U) | ((uint32_t) a[2] << 4U) | (uint32_t) a[3];
/* Don't allow 0 chars */
if (c == 0)
if (c == 0 && !accept_nul)
return -EINVAL;
*ret = c;
@ -227,7 +227,7 @@ int cunescape_one(const char *p, size_t length, char32_t *ret, bool *eight_bit)
((uint32_t) a[4] << 12U) | ((uint32_t) a[5] << 8U) | ((uint32_t) a[6] << 4U) | (uint32_t) a[7];
/* Don't allow 0 chars */
if (c == 0)
if (c == 0 && !accept_nul)
return -EINVAL;
/* Don't allow invalid code points */
@ -267,7 +267,7 @@ int cunescape_one(const char *p, size_t length, char32_t *ret, bool *eight_bit)
return -EINVAL;
/* don't allow NUL bytes */
if (a == 0 && b == 0 && c == 0)
if (a == 0 && b == 0 && c == 0 && !accept_nul)
return -EINVAL;
/* Don't allow bytes above 255 */
@ -333,7 +333,7 @@ int cunescape_length_with_prefix(const char *s, size_t length, const char *prefi
return -EINVAL;
}
k = cunescape_one(f + 1, remaining - 1, &u, &eight_bit);
k = cunescape_one(f + 1, remaining - 1, &u, &eight_bit, flags & UNESCAPE_ACCEPT_NUL);
if (k < 0) {
if (flags & UNESCAPE_RELAX) {
/* Invalid escape code, let's take it literal then */
@ -360,14 +360,6 @@ int cunescape_length_with_prefix(const char *s, size_t length, const char *prefi
return t - r;
}
int cunescape_length(const char *s, size_t length, UnescapeFlags flags, char **ret) {
return cunescape_length_with_prefix(s, length, NULL, flags, ret);
}
int cunescape(const char *s, UnescapeFlags flags, char **ret) {
return cunescape_length(s, strlen(s), flags, ret);
}
char *xescape_full(const char *s, const char *bad, size_t console_width, bool eight_bits) {
char *ans, *t, *prev, *prev2;
const char *f;

View File

@ -29,7 +29,8 @@
#define SHELL_NEED_ESCAPE_POSIX "\\\'"
typedef enum UnescapeFlags {
UNESCAPE_RELAX = 1,
UNESCAPE_RELAX = 1 << 0,
UNESCAPE_ACCEPT_NUL = 1 << 1,
} UnescapeFlags;
typedef enum EscapeStyle {
@ -41,10 +42,14 @@ char *cescape(const char *s);
char *cescape_length(const char *s, size_t n);
int cescape_char(char c, char *buf);
int cunescape(const char *s, UnescapeFlags flags, char **ret);
int cunescape_length(const char *s, size_t length, UnescapeFlags flags, char **ret);
int cunescape_length_with_prefix(const char *s, size_t length, const char *prefix, UnescapeFlags flags, char **ret);
int cunescape_one(const char *p, size_t length, char32_t *ret, bool *eight_bit);
static inline int cunescape_length(const char *s, size_t length, UnescapeFlags flags, char **ret) {
return cunescape_length_with_prefix(s, length, NULL, flags, ret);
}
static inline int cunescape(const char *s, UnescapeFlags flags, char **ret) {
return cunescape_length(s, strlen(s), flags, ret);
}
int cunescape_one(const char *p, size_t length, char32_t *ret, bool *eight_bit, bool accept_nul);
char *xescape_full(const char *s, const char *bad, size_t console_width, bool eight_bits);
static inline char *xescape(const char *s, const char *bad) {

View File

@ -90,7 +90,7 @@ int extract_first_word(const char **p, char **ret, const char *separators, Extra
bool eight_bit = false;
char32_t u;
r = cunescape_one(*p, (size_t) -1, &u, &eight_bit);
r = cunescape_one(*p, (size_t) -1, &u, &eight_bit, false);
if (r < 0) {
if (flags & EXTRACT_CUNESCAPE_RELAX) {
s[sz++] = '\\';

View File

@ -404,10 +404,10 @@ static VOID print_status(Config *config, CHAR16 *loaded_image_path) {
Print(L"random-seed-mode: off\n");
break;
case RANDOM_SEED_WITH_SYSTEM_TOKEN:
Print(L"random-seed-node: with-system-token\n");
Print(L"random-seed-mode: with-system-token\n");
break;
case RANDOM_SEED_ALWAYS:
Print(L"random-seed-node: always\n");
Print(L"random-seed-mode: always\n");
break;
default:
;

View File

@ -1284,6 +1284,9 @@ int bus_exec_context_set_transient_property(
if (streq(name, "ProtectKernelLogs"))
return bus_set_transient_bool(u, name, &c->protect_kernel_logs, message, flags, error);
if (streq(name, "ProtectClock"))
return bus_set_transient_bool(u, name, &c->protect_clock, message, flags, error);
if (streq(name, "ProtectControlGroups"))
return bus_set_transient_bool(u, name, &c->protect_control_groups, message, flags, error);

View File

@ -5,6 +5,7 @@
#include "alloc-util.h"
#include "bpf-firewall.h"
#include "bus-common-errors.h"
#include "bus-polkit.h"
#include "cgroup-util.h"
#include "condition.h"
#include "dbus-job.h"

View File

@ -10,7 +10,7 @@
#include "bus-common-errors.h"
#include "bus-error.h"
#include "bus-internal.h"
#include "bus-util.h"
#include "bus-polkit.h"
#include "dbus-automount.h"
#include "dbus-cgroup.h"
#include "dbus-device.h"

View File

@ -1402,6 +1402,7 @@ static bool context_has_no_new_privileges(const ExecContext *c) {
c->restrict_realtime ||
c->restrict_suid_sgid ||
exec_context_restrict_namespaces_set(c) ||
c->protect_clock ||
c->protect_kernel_tunables ||
c->protect_kernel_modules ||
c->protect_kernel_logs ||
@ -1564,6 +1565,19 @@ static int apply_protect_kernel_logs(const Unit *u, const ExecContext *c) {
return seccomp_protect_syslog();
}
static int apply_protect_clock(const Unit *u, const ExecContext *c) {
assert(u);
assert(c);
if (!c->protect_clock)
return 0;
if (skip_seccomp_unavailable(u, "ProtectClock="))
return 0;
return seccomp_load_syscall_filter_set(SCMP_ACT_ALLOW, syscall_filter_sets + SYSCALL_FILTER_SET_CLOCK, SCMP_ACT_ERRNO(EPERM), false);
}
static int apply_private_devices(const Unit *u, const ExecContext *c) {
assert(u);
assert(c);
@ -3797,6 +3811,12 @@ static int exec_child(
return log_unit_error_errno(unit, r, "Failed to apply kernel log restrictions: %m");
}
r = apply_protect_clock(unit, context);
if (r < 0) {
*exit_status = EXIT_SECCOMP;
return log_unit_error_errno(unit, r, "Failed to apply clock restrictions: %m");
}
r = apply_private_devices(unit, context);
if (r < 0) {
*exit_status = EXIT_SECCOMP;
@ -4437,6 +4457,7 @@ void exec_context_dump(const ExecContext *c, FILE* f, const char *prefix) {
"%sProtectKernelTunables: %s\n"
"%sProtectKernelModules: %s\n"
"%sProtectKernelLogs: %s\n"
"%sProtectClock: %s\n"
"%sProtectControlGroups: %s\n"
"%sPrivateNetwork: %s\n"
"%sPrivateUsers: %s\n"
@ -4458,6 +4479,7 @@ void exec_context_dump(const ExecContext *c, FILE* f, const char *prefix) {
prefix, yes_no(c->protect_kernel_tunables),
prefix, yes_no(c->protect_kernel_modules),
prefix, yes_no(c->protect_kernel_logs),
prefix, yes_no(c->protect_clock),
prefix, yes_no(c->protect_control_groups),
prefix, yes_no(c->private_network),
prefix, yes_no(c->private_users),

View File

@ -258,6 +258,7 @@ struct ExecContext {
bool protect_kernel_tunables;
bool protect_kernel_modules;
bool protect_kernel_logs;
bool protect_clock;
bool protect_control_groups;
ProtectSystem protect_system;
ProtectHome protect_home;

View File

@ -116,6 +116,7 @@ $1.PrivateDevices, config_parse_bool, 0,
$1.ProtectKernelTunables, config_parse_bool, 0, offsetof($1, exec_context.protect_kernel_tunables)
$1.ProtectKernelModules, config_parse_bool, 0, offsetof($1, exec_context.protect_kernel_modules)
$1.ProtectKernelLogs, config_parse_bool, 0, offsetof($1, exec_context.protect_kernel_logs)
$1.ProtectClock, config_parse_bool, 0, offsetof($1, exec_context.protect_clock)
$1.ProtectControlGroups, config_parse_bool, 0, offsetof($1, exec_context.protect_control_groups)
$1.NetworkNamespacePath, config_parse_unit_path_printf, 0, offsetof($1, exec_context.network_namespace_path)
$1.PrivateNetwork, config_parse_bool, 0, offsetof($1, exec_context.private_network)

View File

@ -4287,6 +4287,9 @@ int unit_patch_contexts(Unit *u) {
if (ec->protect_kernel_logs)
ec->capability_bounding_set &= ~(UINT64_C(1) << CAP_SYSLOG);
if (ec->protect_clock)
ec->capability_bounding_set &= ~((UINT64_C(1) << CAP_SYS_TIME) | (UINT64_C(1) << CAP_WAKE_ALARM));
if (ec->dynamic_user) {
if (!ec->user) {
r = user_from_unit_name(u, &ec->user);
@ -4345,6 +4348,12 @@ int unit_patch_contexts(Unit *u) {
if (r < 0)
return r;
}
if (ec->protect_clock) {
r = cgroup_add_device_allow(cc, "char-rtc", "r");
if (r < 0)
return r;
}
}
return 0;

View File

@ -8,7 +8,7 @@
#include "alloc-util.h"
#include "bus-common-errors.h"
#include "bus-util.h"
#include "bus-polkit.h"
#include "def.h"
#include "env-file-label.h"
#include "env-file.h"

View File

@ -4,9 +4,12 @@
#include <stdio.h>
#include "alloc-util.h"
#include "gpt.h"
#include "id128-print.h"
#include "main-func.h"
#include "pretty-print.h"
#include "strv.h"
#include "format-table.h"
#include "terminal-util.h"
#include "util.h"
#include "verbs.h"
@ -63,6 +66,85 @@ static int verb_invocation_id(int argc, char **argv, void *userdata) {
return id128_pretty_print(id, arg_mode);
}
static int show_one(Table **table, const char *name, sd_id128_t uuid, bool first) {
int r;
if (arg_mode == ID128_PRINT_PRETTY) {
_cleanup_free_ char *id = NULL;
id = strreplace(name, "-", "_");
if (!id)
return log_oom();
ascii_strupper(id);
r = id128_pretty_print_sample(id, uuid);
if (r < 0)
return r;
if (!first)
puts("");
return 0;
} else {
if (!*table) {
*table = table_new("name", "uuid");
if (!*table)
return log_oom();
table_set_width(*table, 0);
}
return table_add_many(*table,
TABLE_STRING, name,
arg_mode == ID128_PRINT_ID128 ? TABLE_ID128 : TABLE_UUID,
uuid);
}
}
static int verb_show(int argc, char **argv, void *userdata) {
_cleanup_(table_unrefp) Table *table = NULL;
char **p;
int r;
argv = strv_skip(argv, 1);
if (strv_isempty(argv))
for (const GptPartitionType *e = gpt_partition_type_table; e->name; e++) {
r = show_one(&table, e->name, e->uuid, e == gpt_partition_type_table);
if (r < 0)
return r;
}
else
STRV_FOREACH(p, argv) {
sd_id128_t uuid;
bool have_uuid;
const char *id;
/* Check if the argument is an actual UUID first */
have_uuid = sd_id128_from_string(*p, &uuid) >= 0;
if (have_uuid)
id = gpt_partition_type_uuid_to_string(uuid) ?: "XYZ";
else {
r = gpt_partition_type_uuid_from_string(*p, &uuid);
if (r < 0)
return log_error_errno(r, "Unknown identifier \"%s\".", *p);
id = *p;
}
r = show_one(&table, id, uuid, p == argv);
if (r < 0)
return r;
}
if (table) {
r = table_print(table, NULL);
if (r < 0)
return log_error_errno(r, "Failed to print table: %m");
}
return 0;
}
static int help(void) {
_cleanup_free_ char *link = NULL;
int r;
@ -74,10 +156,11 @@ static int help(void) {
printf("%s [OPTIONS...] COMMAND\n\n"
"%sGenerate and print 128bit identifiers.%s\n"
"\nCommands:\n"
" new Generate a new id128 string\n"
" new Generate a new ID\n"
" machine-id Print the ID of current machine\n"
" boot-id Print the ID of current boot\n"
" invocation-id Print the ID of current invocation\n"
" show [NAME] Print one or more well-known IDs\n"
" help Show this help\n"
"\nOptions:\n"
" -h --help Show this help\n"
@ -155,6 +238,7 @@ static int id128_main(int argc, char *argv[]) {
{ "machine-id", VERB_ANY, 1, 0, verb_machine_id },
{ "boot-id", VERB_ANY, 1, 0, verb_boot_id },
{ "invocation-id", VERB_ANY, 1, 0, verb_invocation_id },
{ "show", VERB_ANY, VERB_ANY, 0, verb_show },
{ "help", VERB_ANY, VERB_ANY, 0, verb_help },
{}
};

View File

@ -7,7 +7,7 @@
#include "alloc-util.h"
#include "bus-common-errors.h"
#include "bus-util.h"
#include "bus-polkit.h"
#include "def.h"
#include "fd-util.h"
#include "float.h"

View File

@ -5,7 +5,7 @@
#include <sys/types.h>
#include <unistd.h>
#include "bus-util.h"
#include "bus-polkit.h"
#include "env-file-label.h"
#include "env-file.h"
#include "env-util.h"

View File

@ -15,7 +15,7 @@
#include "alloc-util.h"
#include "bus-error.h"
#include "bus-message.h"
#include "bus-util.h"
#include "bus-polkit.h"
#include "def.h"
#include "keymap-util.h"
#include "locale-util.h"

View File

@ -12,13 +12,14 @@
#include "bootspec.h"
#include "bus-common-errors.h"
#include "bus-error.h"
#include "bus-polkit.h"
#include "bus-unit-util.h"
#include "bus-util.h"
#include "cgroup-util.h"
#include "device-util.h"
#include "dirent-util.h"
#include "efivars.h"
#include "efi-loader.h"
#include "efivars.h"
#include "env-util.h"
#include "escape.h"
#include "fd-util.h"
@ -1015,6 +1016,8 @@ static int method_activate_session(sd_bus_message *message, void *userdata, sd_b
if (r < 0)
return r;
/* PolicyKit is done by bus_session_method_activate() */
return bus_session_method_activate(message, session, error);
}
@ -1046,6 +1049,20 @@ static int method_activate_session_on_seat(sd_bus_message *message, void *userda
return sd_bus_error_setf(error, BUS_ERROR_SESSION_NOT_ON_SEAT,
"Session %s not on seat %s", session_name, seat_name);
r = bus_verify_polkit_async(
message,
CAP_SYS_ADMIN,
"org.freedesktop.login1.chvt",
NULL,
false,
UID_INVALID,
&m->polkit_registry,
error);
if (r < 0)
return r;
if (r == 0)
return 1; /* Will call us back */
r = session_activate(session);
if (r < 0)
return r;

View File

@ -5,6 +5,7 @@
#include "alloc-util.h"
#include "bus-common-errors.h"
#include "bus-label.h"
#include "bus-polkit.h"
#include "bus-util.h"
#include "logind-dbus.h"
#include "logind-seat-dbus.h"
@ -177,6 +178,20 @@ static int method_activate_session(sd_bus_message *message, void *userdata, sd_b
if (session->seat != s)
return sd_bus_error_setf(error, BUS_ERROR_SESSION_NOT_ON_SEAT, "Session %s not on seat %s", name, s->id);
r = bus_verify_polkit_async(
message,
CAP_SYS_ADMIN,
"org.freedesktop.login1.chvt",
NULL,
false,
UID_INVALID,
&s->manager->polkit_registry,
error);
if (r < 0)
return r;
if (r == 0)
return 1; /* Will call us back */
r = session_activate(session);
if (r < 0)
return r;
@ -197,7 +212,21 @@ static int method_switch_to(sd_bus_message *message, void *userdata, sd_bus_erro
return r;
if (to <= 0)
return -EINVAL;
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid virtual terminal");
r = bus_verify_polkit_async(
message,
CAP_SYS_ADMIN,
"org.freedesktop.login1.chvt",
NULL,
false,
UID_INVALID,
&s->manager->polkit_registry,
error);
if (r < 0)
return r;
if (r == 0)
return 1; /* Will call us back */
r = seat_switch_to(s, to);
if (r < 0)
@ -213,6 +242,20 @@ static int method_switch_to_next(sd_bus_message *message, void *userdata, sd_bus
assert(message);
assert(s);
r = bus_verify_polkit_async(
message,
CAP_SYS_ADMIN,
"org.freedesktop.login1.chvt",
NULL,
false,
UID_INVALID,
&s->manager->polkit_registry,
error);
if (r < 0)
return r;
if (r == 0)
return 1; /* Will call us back */
r = seat_switch_to_next(s);
if (r < 0)
return r;
@ -227,6 +270,20 @@ static int method_switch_to_previous(sd_bus_message *message, void *userdata, sd
assert(message);
assert(s);
r = bus_verify_polkit_async(
message,
CAP_SYS_ADMIN,
"org.freedesktop.login1.chvt",
NULL,
false,
UID_INVALID,
&s->manager->polkit_registry,
error);
if (r < 0)
return r;
if (r == 0)
return 1; /* Will call us back */
r = seat_switch_to_previous(s);
if (r < 0)
return r;

View File

@ -5,6 +5,7 @@
#include "alloc-util.h"
#include "bus-common-errors.h"
#include "bus-label.h"
#include "bus-polkit.h"
#include "bus-util.h"
#include "fd-util.h"
#include "logind-brightness.h"
@ -190,6 +191,20 @@ int bus_session_method_activate(sd_bus_message *message, void *userdata, sd_bus_
assert(message);
assert(s);
r = bus_verify_polkit_async(
message,
CAP_SYS_ADMIN,
"org.freedesktop.login1.chvt",
NULL,
false,
UID_INVALID,
&s->manager->polkit_registry,
error);
if (r < 0)
return r;
if (r == 0)
return 1; /* Will call us back */
r = session_activate(s);
if (r < 0)
return r;

View File

@ -3,6 +3,7 @@
#include <errno.h>
#include "alloc-util.h"
#include "bus-polkit.h"
#include "bus-util.h"
#include "format-util.h"
#include "logind-dbus.h"

View File

@ -9,7 +9,7 @@
#include "alloc-util.h"
#include "bus-error.h"
#include "bus-util.h"
#include "bus-polkit.h"
#include "cgroup-util.h"
#include "def.h"
#include "device-util.h"

View File

@ -391,4 +391,14 @@
</defaults>
</action>
<action id="org.freedesktop.login1.chvt">
<description gettext-domain="systemd">Change Session</description>
<message gettext-domain="systemd">Authentication is required for changing the virtual terminal.</message>
<defaults>
<allow_any>auth_admin_keep</allow_any>
<allow_inactive>auth_admin_keep</allow_inactive>
<allow_active>yes</allow_active>
</defaults>
</action>
</policyconfig>

View File

@ -5,6 +5,7 @@
#include "alloc-util.h"
#include "bus-label.h"
#include "bus-polkit.h"
#include "bus-util.h"
#include "copy.h"
#include "dissect-image.h"

View File

@ -14,6 +14,7 @@
#include "bus-common-errors.h"
#include "bus-internal.h"
#include "bus-label.h"
#include "bus-polkit.h"
#include "bus-util.h"
#include "copy.h"
#include "env-file.h"

View File

@ -8,6 +8,7 @@
#include "alloc-util.h"
#include "btrfs-util.h"
#include "bus-common-errors.h"
#include "bus-polkit.h"
#include "bus-util.h"
#include "cgroup-util.h"
#include "errno-util.h"

View File

@ -10,7 +10,7 @@
#include "alloc-util.h"
#include "bus-error.h"
#include "bus-util.h"
#include "bus-polkit.h"
#include "cgroup-util.h"
#include "dirent-util.h"
#include "fd-util.h"

View File

@ -390,7 +390,7 @@ int config_parse_dhcp_send_option(
break;
}
case DHCP_OPTION_DATA_STRING:
sz = cunescape(p, 0, &q);
sz = cunescape(p, UNESCAPE_ACCEPT_NUL, &q);
if (sz < 0) {
log_syntax(unit, LOG_ERR, filename, line, sz,
"Failed to decode DHCPv4 option data, ignoring assignment: %s", p);

View File

@ -6,6 +6,7 @@
#include "alloc-util.h"
#include "bus-common-errors.h"
#include "bus-polkit.h"
#include "bus-util.h"
#include "dns-domain.h"
#include "networkd-link-bus.h"
@ -620,6 +621,12 @@ int bus_link_method_reconfigure(sd_bus_message *message, void *userdata, sd_bus_
if (r < 0)
return r;
link_set_state(l, LINK_STATE_INITIALIZED);
r = link_save(l);
if (r < 0)
return r;
link_clean(l);
return sd_bus_reply_method_return(message, NULL);
}

View File

@ -3023,9 +3023,6 @@ static int link_reconfigure_internal(Link *link, sd_netlink_message *m, bool for
Network *network;
int r;
if (IN_SET(link->state, LINK_STATE_PENDING, LINK_STATE_LINGER))
return 0;
if (m) {
_cleanup_strv_free_ char **s = NULL;
@ -3089,6 +3086,7 @@ static int link_reconfigure_internal(Link *link, sd_netlink_message *m, bool for
return r;
link_set_state(link, LINK_STATE_INITIALIZED);
link_dirty(link);
/* link_configure_duid() returns 0 if it requests product UUID. In that case,
* link_configure() is called later asynchronously. */
@ -3127,6 +3125,9 @@ int link_reconfigure(Link *link, bool force) {
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
int r;
if (IN_SET(link->state, LINK_STATE_PENDING, LINK_STATE_LINGER))
return 0;
r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_GETLINK,
link->ifindex);
if (r < 0)

View File

@ -6,7 +6,7 @@
#include "alloc-util.h"
#include "bus-common-errors.h"
#include "bus-util.h"
#include "bus-polkit.h"
#include "networkd-link-bus.h"
#include "networkd-link.h"
#include "networkd-manager-bus.h"

View File

@ -11,6 +11,7 @@
#include "sd-netlink.h"
#include "alloc-util.h"
#include "bus-polkit.h"
#include "bus-util.h"
#include "conf-parser.h"
#include "def.h"

View File

@ -818,76 +818,6 @@ static void context_place_partitions(Context *context) {
}
}
typedef struct GptPartitionType {
sd_id128_t uuid;
const char *name;
} GptPartitionType;
static const GptPartitionType gpt_partition_type_table[] = {
{ GPT_ROOT_X86, "root-x86" },
{ GPT_ROOT_X86_VERITY, "root-x86-verity" },
{ GPT_ROOT_X86_64, "root-x86-64" },
{ GPT_ROOT_X86_64_VERITY, "root-x86-64-verity" },
{ GPT_ROOT_ARM, "root-arm" },
{ GPT_ROOT_ARM_VERITY, "root-arm-verity" },
{ GPT_ROOT_ARM_64, "root-arm64" },
{ GPT_ROOT_ARM_64_VERITY, "root-arm64-verity" },
{ GPT_ROOT_IA64, "root-ia64" },
{ GPT_ROOT_IA64_VERITY, "root-ia64-verity" },
#ifdef GPT_ROOT_NATIVE
{ GPT_ROOT_NATIVE, "root" },
{ GPT_ROOT_NATIVE_VERITY, "root-verity" },
#endif
#ifdef GPT_ROOT_SECONDARY
{ GPT_ROOT_SECONDARY, "root-secondary" },
{ GPT_ROOT_SECONDARY_VERITY, "root-secondary-verity" },
#endif
{ GPT_ESP, "esp" },
{ GPT_XBOOTLDR, "xbootldr" },
{ GPT_SWAP, "swap" },
{ GPT_HOME, "home" },
{ GPT_SRV, "srv" },
{ GPT_VAR, "var" },
{ GPT_TMP, "tmp" },
{ GPT_LINUX_GENERIC, "linux-generic", },
};
static const char *gpt_partition_type_uuid_to_string(sd_id128_t id) {
for (size_t i = 0; i < ELEMENTSOF(gpt_partition_type_table); i++)
if (sd_id128_equal(id, gpt_partition_type_table[i].uuid))
return gpt_partition_type_table[i].name;
return NULL;
}
static const char *gpt_partition_type_uuid_to_string_harder(
sd_id128_t id,
char buffer[static ID128_UUID_STRING_MAX]) {
const char *s;
assert(buffer);
s = gpt_partition_type_uuid_to_string(id);
if (s)
return s;
return id128_to_uuid_string(id, buffer);
}
static int gpt_partition_type_uuid_from_string(const char *s, sd_id128_t *ret) {
assert(s);
assert(ret);
for (size_t i = 0; i < ELEMENTSOF(gpt_partition_type_table); i++)
if (streq(s, gpt_partition_type_table[i].name)) {
*ret = gpt_partition_type_table[i].uuid;
return 0;
}
return sd_id128_from_string(s, ret);
}
static int config_parse_type(
const char *unit,
const char *filename,

View File

@ -3,7 +3,7 @@
#include "alloc-util.h"
#include "btrfs-util.h"
#include "bus-common-errors.h"
#include "bus-util.h"
#include "bus-polkit.h"
#include "fd-util.h"
#include "io-util.h"
#include "machine-image.h"

View File

@ -8,6 +8,7 @@
#include "alloc-util.h"
#include "bus-common-errors.h"
#include "bus-label.h"
#include "bus-polkit.h"
#include "bus-util.h"
#include "fd-util.h"
#include "fileio.h"

View File

@ -7,7 +7,7 @@
#include "sd-daemon.h"
#include "alloc-util.h"
#include "bus-util.h"
#include "bus-polkit.h"
#include "def.h"
#include "main-func.h"
#include "portabled-bus.h"

View File

@ -2,6 +2,7 @@
#include "alloc-util.h"
#include "bus-common-errors.h"
#include "bus-polkit.h"
#include "bus-util.h"
#include "dns-domain.h"
#include "memory-util.h"

View File

@ -1,9 +1,10 @@
/* SPDX-License-Identifier: LGPL-2.1+ */
#include "alloc-util.h"
#include "bus-util.h"
#include "bus-polkit.h"
#include "missing_capability.h"
#include "resolved-dnssd.h"
#include "resolved-dnssd-bus.h"
#include "resolved-dnssd.h"
#include "resolved-link.h"
#include "strv.h"
#include "user-util.h"

View File

@ -6,6 +6,7 @@
#include "alloc-util.h"
#include "bus-common-errors.h"
#include "bus-polkit.h"
#include "bus-util.h"
#include "parse-util.h"
#include "resolve-util.h"

View File

@ -14,7 +14,7 @@
#include "af-list.h"
#include "alloc-util.h"
#include "bus-util.h"
#include "bus-polkit.h"
#include "dirent-util.h"
#include "dns-domain.h"
#include "fd-util.h"

View File

@ -164,6 +164,7 @@ void boot_config_free(BootConfig *config) {
free(config->auto_entries);
free(config->auto_firmware);
free(config->console_mode);
free(config->random_seed_mode);
free(config->entry_oneshot);
free(config->entry_default);
@ -229,6 +230,8 @@ static int boot_loader_read_conf(const char *path, BootConfig *config) {
r = free_and_strdup(&config->auto_firmware, p);
else if (streq(field, "console-mode"))
r = free_and_strdup(&config->console_mode, p);
else if (streq(field, "random-seed-mode"))
r = free_and_strdup(&config->random_seed_mode, p);
else {
log_notice("%s:%u: Unknown line \"%s\", ignoring.", path, line, field);
continue;

View File

@ -43,6 +43,7 @@ typedef struct BootConfig {
char *auto_entries;
char *auto_firmware;
char *console_mode;
char *random_seed_mode;
char *entry_oneshot;
char *entry_default;

358
src/shared/bus-polkit.c Normal file
View File

@ -0,0 +1,358 @@
/* SPDX-License-Identifier: LGPL-2.1+ */
#include "bus-internal.h"
#include "bus-message.h"
#include "bus-polkit.h"
#include "strv.h"
#include "user-util.h"
static int check_good_user(sd_bus_message *m, uid_t good_user) {
_cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
uid_t sender_uid;
int r;
assert(m);
if (good_user == UID_INVALID)
return 0;
r = sd_bus_query_sender_creds(m, SD_BUS_CREDS_EUID, &creds);
if (r < 0)
return r;
/* Don't trust augmented credentials for authorization */
assert_return((sd_bus_creds_get_augmented_mask(creds) & SD_BUS_CREDS_EUID) == 0, -EPERM);
r = sd_bus_creds_get_euid(creds, &sender_uid);
if (r < 0)
return r;
return sender_uid == good_user;
}
int bus_test_polkit(
sd_bus_message *call,
int capability,
const char *action,
const char **details,
uid_t good_user,
bool *_challenge,
sd_bus_error *e) {
int r;
assert(call);
assert(action);
/* Tests non-interactively! */
r = check_good_user(call, good_user);
if (r != 0)
return r;
r = sd_bus_query_sender_privilege(call, capability);
if (r < 0)
return r;
else if (r > 0)
return 1;
#if ENABLE_POLKIT
else {
_cleanup_(sd_bus_message_unrefp) sd_bus_message *request = NULL;
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
int authorized = false, challenge = false;
const char *sender, **k, **v;
sender = sd_bus_message_get_sender(call);
if (!sender)
return -EBADMSG;
r = sd_bus_message_new_method_call(
call->bus,
&request,
"org.freedesktop.PolicyKit1",
"/org/freedesktop/PolicyKit1/Authority",
"org.freedesktop.PolicyKit1.Authority",
"CheckAuthorization");
if (r < 0)
return r;
r = sd_bus_message_append(
request,
"(sa{sv})s",
"system-bus-name", 1, "name", "s", sender,
action);
if (r < 0)
return r;
r = sd_bus_message_open_container(request, 'a', "{ss}");
if (r < 0)
return r;
STRV_FOREACH_PAIR(k, v, details) {
r = sd_bus_message_append(request, "{ss}", *k, *v);
if (r < 0)
return r;
}
r = sd_bus_message_close_container(request);
if (r < 0)
return r;
r = sd_bus_message_append(request, "us", 0, NULL);
if (r < 0)
return r;
r = sd_bus_call(call->bus, request, 0, e, &reply);
if (r < 0) {
/* Treat no PK available as access denied */
if (sd_bus_error_has_name(e, SD_BUS_ERROR_SERVICE_UNKNOWN)) {
sd_bus_error_free(e);
return -EACCES;
}
return r;
}
r = sd_bus_message_enter_container(reply, 'r', "bba{ss}");
if (r < 0)
return r;
r = sd_bus_message_read(reply, "bb", &authorized, &challenge);
if (r < 0)
return r;
if (authorized)
return 1;
if (_challenge) {
*_challenge = challenge;
return 0;
}
}
#endif
return -EACCES;
}
#if ENABLE_POLKIT
typedef struct AsyncPolkitQuery {
sd_bus_message *request, *reply;
sd_bus_message_handler_t callback;
void *userdata;
sd_bus_slot *slot;
Hashmap *registry;
} AsyncPolkitQuery;
static void async_polkit_query_free(AsyncPolkitQuery *q) {
if (!q)
return;
sd_bus_slot_unref(q->slot);
if (q->registry && q->request)
hashmap_remove(q->registry, q->request);
sd_bus_message_unref(q->request);
sd_bus_message_unref(q->reply);
free(q);
}
static int async_polkit_callback(sd_bus_message *reply, void *userdata, sd_bus_error *error) {
_cleanup_(sd_bus_error_free) sd_bus_error error_buffer = SD_BUS_ERROR_NULL;
AsyncPolkitQuery *q = userdata;
int r;
assert(reply);
assert(q);
q->slot = sd_bus_slot_unref(q->slot);
q->reply = sd_bus_message_ref(reply);
r = sd_bus_message_rewind(q->request, true);
if (r < 0) {
r = sd_bus_reply_method_errno(q->request, r, NULL);
goto finish;
}
r = q->callback(q->request, q->userdata, &error_buffer);
r = bus_maybe_reply_error(q->request, r, &error_buffer);
finish:
async_polkit_query_free(q);
return r;
}
#endif
int bus_verify_polkit_async(
sd_bus_message *call,
int capability,
const char *action,
const char **details,
bool interactive,
uid_t good_user,
Hashmap **registry,
sd_bus_error *error) {
#if ENABLE_POLKIT
_cleanup_(sd_bus_message_unrefp) sd_bus_message *pk = NULL;
AsyncPolkitQuery *q;
const char *sender, **k, **v;
sd_bus_message_handler_t callback;
void *userdata;
int c;
#endif
int r;
assert(call);
assert(action);
assert(registry);
r = check_good_user(call, good_user);
if (r != 0)
return r;
#if ENABLE_POLKIT
q = hashmap_get(*registry, call);
if (q) {
int authorized, challenge;
/* This is the second invocation of this function, and
* there's already a response from polkit, let's
* process it */
assert(q->reply);
if (sd_bus_message_is_method_error(q->reply, NULL)) {
const sd_bus_error *e;
e = sd_bus_message_get_error(q->reply);
/* Treat no PK available as access denied */
if (sd_bus_error_has_name(e, SD_BUS_ERROR_SERVICE_UNKNOWN) ||
sd_bus_error_has_name(e, SD_BUS_ERROR_NAME_HAS_NO_OWNER))
return -EACCES;
/* Copy error from polkit reply */
sd_bus_error_copy(error, e);
return -sd_bus_error_get_errno(e);
}
r = sd_bus_message_enter_container(q->reply, 'r', "bba{ss}");
if (r >= 0)
r = sd_bus_message_read(q->reply, "bb", &authorized, &challenge);
if (r < 0)
return r;
if (authorized)
return 1;
if (challenge)
return sd_bus_error_set(error, SD_BUS_ERROR_INTERACTIVE_AUTHORIZATION_REQUIRED, "Interactive authentication required.");
return -EACCES;
}
#endif
r = sd_bus_query_sender_privilege(call, capability);
if (r < 0)
return r;
else if (r > 0)
return 1;
#if ENABLE_POLKIT
if (sd_bus_get_current_message(call->bus) != call)
return -EINVAL;
callback = sd_bus_get_current_handler(call->bus);
if (!callback)
return -EINVAL;
userdata = sd_bus_get_current_userdata(call->bus);
sender = sd_bus_message_get_sender(call);
if (!sender)
return -EBADMSG;
c = sd_bus_message_get_allow_interactive_authorization(call);
if (c < 0)
return c;
if (c > 0)
interactive = true;
r = hashmap_ensure_allocated(registry, NULL);
if (r < 0)
return r;
r = sd_bus_message_new_method_call(
call->bus,
&pk,
"org.freedesktop.PolicyKit1",
"/org/freedesktop/PolicyKit1/Authority",
"org.freedesktop.PolicyKit1.Authority",
"CheckAuthorization");
if (r < 0)
return r;
r = sd_bus_message_append(
pk,
"(sa{sv})s",
"system-bus-name", 1, "name", "s", sender,
action);
if (r < 0)
return r;
r = sd_bus_message_open_container(pk, 'a', "{ss}");
if (r < 0)
return r;
STRV_FOREACH_PAIR(k, v, details) {
r = sd_bus_message_append(pk, "{ss}", *k, *v);
if (r < 0)
return r;
}
r = sd_bus_message_close_container(pk);
if (r < 0)
return r;
r = sd_bus_message_append(pk, "us", interactive, NULL);
if (r < 0)
return r;
q = new0(AsyncPolkitQuery, 1);
if (!q)
return -ENOMEM;
q->request = sd_bus_message_ref(call);
q->callback = callback;
q->userdata = userdata;
r = hashmap_put(*registry, call, q);
if (r < 0) {
async_polkit_query_free(q);
return r;
}
q->registry = *registry;
r = sd_bus_call_async(call->bus, &q->slot, pk, async_polkit_callback, q, 0);
if (r < 0) {
async_polkit_query_free(q);
return r;
}
return 0;
#endif
return -EACCES;
}
void bus_verify_polkit_async_registry_free(Hashmap *registry) {
#if ENABLE_POLKIT
hashmap_free_with_destructor(registry, async_polkit_query_free);
#endif
}

11
src/shared/bus-polkit.h Normal file
View File

@ -0,0 +1,11 @@
/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
#include "sd-bus.h"
#include "hashmap.h"
int bus_test_polkit(sd_bus_message *call, int capability, const char *action, const char **details, uid_t good_user, bool *_challenge, sd_bus_error *e);
int bus_verify_polkit_async(sd_bus_message *call, int capability, const char *action, const char **details, bool interactive, uid_t good_user, Hashmap **registry, sd_bus_error *error);
void bus_verify_polkit_async_registry_free(Hashmap *registry);

View File

@ -854,6 +854,7 @@ static int bus_append_execute_property(sd_bus_message *m, const char *field, con
"ProtectKernelTunables",
"ProtectKernelModules",
"ProtectKernelLogs",
"ProtectClock",
"ProtectControlGroups",
"MountAPIVFS",
"CPUSchedulingResetOnFork",

View File

@ -9,7 +9,6 @@
#include <sys/socket.h>
#include <unistd.h>
#include "sd-bus-protocol.h"
#include "sd-bus.h"
#include "sd-daemon.h"
#include "sd-event.h"
@ -22,15 +21,12 @@
#include "bus-util.h"
#include "cap-list.h"
#include "cgroup-util.h"
#include "def.h"
#include "escape.h"
#include "fd-util.h"
#include "mountpoint-util.h"
#include "nsflags.h"
#include "parse-util.h"
#include "path-util.h"
#include "proc-cmdline.h"
#include "rlimit-util.h"
#include "socket-util.h"
#include "stdio-util.h"
#include "strv.h"
#include "user-util.h"
@ -185,357 +181,6 @@ int bus_name_has_owner(sd_bus *c, const char *name, sd_bus_error *error) {
return has_owner;
}
static int check_good_user(sd_bus_message *m, uid_t good_user) {
_cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
uid_t sender_uid;
int r;
assert(m);
if (good_user == UID_INVALID)
return 0;
r = sd_bus_query_sender_creds(m, SD_BUS_CREDS_EUID, &creds);
if (r < 0)
return r;
/* Don't trust augmented credentials for authorization */
assert_return((sd_bus_creds_get_augmented_mask(creds) & SD_BUS_CREDS_EUID) == 0, -EPERM);
r = sd_bus_creds_get_euid(creds, &sender_uid);
if (r < 0)
return r;
return sender_uid == good_user;
}
int bus_test_polkit(
sd_bus_message *call,
int capability,
const char *action,
const char **details,
uid_t good_user,
bool *_challenge,
sd_bus_error *e) {
int r;
assert(call);
assert(action);
/* Tests non-interactively! */
r = check_good_user(call, good_user);
if (r != 0)
return r;
r = sd_bus_query_sender_privilege(call, capability);
if (r < 0)
return r;
else if (r > 0)
return 1;
#if ENABLE_POLKIT
else {
_cleanup_(sd_bus_message_unrefp) sd_bus_message *request = NULL;
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
int authorized = false, challenge = false;
const char *sender, **k, **v;
sender = sd_bus_message_get_sender(call);
if (!sender)
return -EBADMSG;
r = sd_bus_message_new_method_call(
call->bus,
&request,
"org.freedesktop.PolicyKit1",
"/org/freedesktop/PolicyKit1/Authority",
"org.freedesktop.PolicyKit1.Authority",
"CheckAuthorization");
if (r < 0)
return r;
r = sd_bus_message_append(
request,
"(sa{sv})s",
"system-bus-name", 1, "name", "s", sender,
action);
if (r < 0)
return r;
r = sd_bus_message_open_container(request, 'a', "{ss}");
if (r < 0)
return r;
STRV_FOREACH_PAIR(k, v, details) {
r = sd_bus_message_append(request, "{ss}", *k, *v);
if (r < 0)
return r;
}
r = sd_bus_message_close_container(request);
if (r < 0)
return r;
r = sd_bus_message_append(request, "us", 0, NULL);
if (r < 0)
return r;
r = sd_bus_call(call->bus, request, 0, e, &reply);
if (r < 0) {
/* Treat no PK available as access denied */
if (sd_bus_error_has_name(e, SD_BUS_ERROR_SERVICE_UNKNOWN)) {
sd_bus_error_free(e);
return -EACCES;
}
return r;
}
r = sd_bus_message_enter_container(reply, 'r', "bba{ss}");
if (r < 0)
return r;
r = sd_bus_message_read(reply, "bb", &authorized, &challenge);
if (r < 0)
return r;
if (authorized)
return 1;
if (_challenge) {
*_challenge = challenge;
return 0;
}
}
#endif
return -EACCES;
}
#if ENABLE_POLKIT
typedef struct AsyncPolkitQuery {
sd_bus_message *request, *reply;
sd_bus_message_handler_t callback;
void *userdata;
sd_bus_slot *slot;
Hashmap *registry;
} AsyncPolkitQuery;
static void async_polkit_query_free(AsyncPolkitQuery *q) {
if (!q)
return;
sd_bus_slot_unref(q->slot);
if (q->registry && q->request)
hashmap_remove(q->registry, q->request);
sd_bus_message_unref(q->request);
sd_bus_message_unref(q->reply);
free(q);
}
static int async_polkit_callback(sd_bus_message *reply, void *userdata, sd_bus_error *error) {
_cleanup_(sd_bus_error_free) sd_bus_error error_buffer = SD_BUS_ERROR_NULL;
AsyncPolkitQuery *q = userdata;
int r;
assert(reply);
assert(q);
q->slot = sd_bus_slot_unref(q->slot);
q->reply = sd_bus_message_ref(reply);
r = sd_bus_message_rewind(q->request, true);
if (r < 0) {
r = sd_bus_reply_method_errno(q->request, r, NULL);
goto finish;
}
r = q->callback(q->request, q->userdata, &error_buffer);
r = bus_maybe_reply_error(q->request, r, &error_buffer);
finish:
async_polkit_query_free(q);
return r;
}
#endif
int bus_verify_polkit_async(
sd_bus_message *call,
int capability,
const char *action,
const char **details,
bool interactive,
uid_t good_user,
Hashmap **registry,
sd_bus_error *error) {
#if ENABLE_POLKIT
_cleanup_(sd_bus_message_unrefp) sd_bus_message *pk = NULL;
AsyncPolkitQuery *q;
const char *sender, **k, **v;
sd_bus_message_handler_t callback;
void *userdata;
int c;
#endif
int r;
assert(call);
assert(action);
assert(registry);
r = check_good_user(call, good_user);
if (r != 0)
return r;
#if ENABLE_POLKIT
q = hashmap_get(*registry, call);
if (q) {
int authorized, challenge;
/* This is the second invocation of this function, and
* there's already a response from polkit, let's
* process it */
assert(q->reply);
if (sd_bus_message_is_method_error(q->reply, NULL)) {
const sd_bus_error *e;
e = sd_bus_message_get_error(q->reply);
/* Treat no PK available as access denied */
if (sd_bus_error_has_name(e, SD_BUS_ERROR_SERVICE_UNKNOWN) ||
sd_bus_error_has_name(e, SD_BUS_ERROR_NAME_HAS_NO_OWNER))
return -EACCES;
/* Copy error from polkit reply */
sd_bus_error_copy(error, e);
return -sd_bus_error_get_errno(e);
}
r = sd_bus_message_enter_container(q->reply, 'r', "bba{ss}");
if (r >= 0)
r = sd_bus_message_read(q->reply, "bb", &authorized, &challenge);
if (r < 0)
return r;
if (authorized)
return 1;
if (challenge)
return sd_bus_error_set(error, SD_BUS_ERROR_INTERACTIVE_AUTHORIZATION_REQUIRED, "Interactive authentication required.");
return -EACCES;
}
#endif
r = sd_bus_query_sender_privilege(call, capability);
if (r < 0)
return r;
else if (r > 0)
return 1;
#if ENABLE_POLKIT
if (sd_bus_get_current_message(call->bus) != call)
return -EINVAL;
callback = sd_bus_get_current_handler(call->bus);
if (!callback)
return -EINVAL;
userdata = sd_bus_get_current_userdata(call->bus);
sender = sd_bus_message_get_sender(call);
if (!sender)
return -EBADMSG;
c = sd_bus_message_get_allow_interactive_authorization(call);
if (c < 0)
return c;
if (c > 0)
interactive = true;
r = hashmap_ensure_allocated(registry, NULL);
if (r < 0)
return r;
r = sd_bus_message_new_method_call(
call->bus,
&pk,
"org.freedesktop.PolicyKit1",
"/org/freedesktop/PolicyKit1/Authority",
"org.freedesktop.PolicyKit1.Authority",
"CheckAuthorization");
if (r < 0)
return r;
r = sd_bus_message_append(
pk,
"(sa{sv})s",
"system-bus-name", 1, "name", "s", sender,
action);
if (r < 0)
return r;
r = sd_bus_message_open_container(pk, 'a', "{ss}");
if (r < 0)
return r;
STRV_FOREACH_PAIR(k, v, details) {
r = sd_bus_message_append(pk, "{ss}", *k, *v);
if (r < 0)
return r;
}
r = sd_bus_message_close_container(pk);
if (r < 0)
return r;
r = sd_bus_message_append(pk, "us", interactive, NULL);
if (r < 0)
return r;
q = new0(AsyncPolkitQuery, 1);
if (!q)
return -ENOMEM;
q->request = sd_bus_message_ref(call);
q->callback = callback;
q->userdata = userdata;
r = hashmap_put(*registry, call, q);
if (r < 0) {
async_polkit_query_free(q);
return r;
}
q->registry = *registry;
r = sd_bus_call_async(call->bus, &q->slot, pk, async_polkit_callback, q, 0);
if (r < 0) {
async_polkit_query_free(q);
return r;
}
return 0;
#endif
return -EACCES;
}
void bus_verify_polkit_async_registry_free(Hashmap *registry) {
#if ENABLE_POLKIT
hashmap_free_with_destructor(registry, async_polkit_query_free);
#endif
}
int bus_check_peercred(sd_bus *c) {
struct ucred ucred;
int fd, r;

View File

@ -9,8 +9,8 @@
#include "sd-bus.h"
#include "sd-event.h"
#include "hashmap.h"
#include "macro.h"
#include "set.h"
#include "string-util.h"
#include "time-util.h"
@ -52,11 +52,6 @@ int bus_name_has_owner(sd_bus *c, const char *name, sd_bus_error *error);
int bus_check_peercred(sd_bus *c);
int bus_test_polkit(sd_bus_message *call, int capability, const char *action, const char **details, uid_t good_user, bool *_challenge, sd_bus_error *e);
int bus_verify_polkit_async(sd_bus_message *call, int capability, const char *action, const char **details, bool interactive, uid_t good_user, Hashmap **registry, sd_bus_error *error);
void bus_verify_polkit_async_registry_free(Hashmap *registry);
int bus_connect_system_systemd(sd_bus **_bus);
int bus_connect_user_systemd(sd_bus **_bus);

70
src/shared/gpt.c Normal file
View File

@ -0,0 +1,70 @@
/* SPDX-License-Identifier: LGPL-2.1+ */
#include "gpt.h"
#include "string-util.h"
const GptPartitionType gpt_partition_type_table[] = {
{ GPT_ROOT_X86, "root-x86" },
{ GPT_ROOT_X86_VERITY, "root-x86-verity" },
{ GPT_ROOT_X86_64, "root-x86-64" },
{ GPT_ROOT_X86_64_VERITY, "root-x86-64-verity" },
{ GPT_ROOT_ARM, "root-arm" },
{ GPT_ROOT_ARM_VERITY, "root-arm-verity" },
{ GPT_ROOT_ARM_64, "root-arm64" },
{ GPT_ROOT_ARM_64_VERITY, "root-arm64-verity" },
{ GPT_ROOT_IA64, "root-ia64" },
{ GPT_ROOT_IA64_VERITY, "root-ia64-verity" },
#ifdef GPT_ROOT_NATIVE
{ GPT_ROOT_NATIVE, "root" },
{ GPT_ROOT_NATIVE_VERITY, "root-verity" },
#endif
#ifdef GPT_ROOT_SECONDARY
{ GPT_ROOT_SECONDARY, "root-secondary" },
{ GPT_ROOT_SECONDARY_VERITY, "root-secondary-verity" },
#endif
{ GPT_ESP, "esp" },
{ GPT_XBOOTLDR, "xbootldr" },
{ GPT_SWAP, "swap" },
{ GPT_HOME, "home" },
{ GPT_SRV, "srv" },
{ GPT_VAR, "var" },
{ GPT_TMP, "tmp" },
{ GPT_LINUX_GENERIC, "linux-generic", },
{}
};
const char *gpt_partition_type_uuid_to_string(sd_id128_t id) {
for (size_t i = 0; i < ELEMENTSOF(gpt_partition_type_table) - 1; i++)
if (sd_id128_equal(id, gpt_partition_type_table[i].uuid))
return gpt_partition_type_table[i].name;
return NULL;
}
const char *gpt_partition_type_uuid_to_string_harder(
sd_id128_t id,
char buffer[static ID128_UUID_STRING_MAX]) {
const char *s;
assert(buffer);
s = gpt_partition_type_uuid_to_string(id);
if (s)
return s;
return id128_to_uuid_string(id, buffer);
}
int gpt_partition_type_uuid_from_string(const char *s, sd_id128_t *ret) {
assert(s);
assert(ret);
for (size_t i = 0; i < ELEMENTSOF(gpt_partition_type_table) - 1; i++)
if (streq(s, gpt_partition_type_table[i].name)) {
*ret = gpt_partition_type_table[i].uuid;
return 0;
}
return sd_id128_from_string(s, ret);
}

View File

@ -5,6 +5,8 @@
#include "sd-id128.h"
#include "id128-util.h"
/* We only support root disk discovery for x86, x86-64, Itanium and ARM for
* now, since EFI for anything else doesn't really exist, and we only
* care for root partitions on the same disk as the EFI ESP. */
@ -65,3 +67,16 @@
#define GPT_FLAG_NO_AUTO (1ULL << 63)
#define GPT_LINUX_GENERIC SD_ID128_MAKE(0f,c6,3d,af,84,83,47,72,8e,79,3d,69,d8,47,7d,e4)
const char *gpt_partition_type_uuid_to_string(sd_id128_t id);
const char *gpt_partition_type_uuid_to_string_harder(
sd_id128_t id,
char buffer[static ID128_UUID_STRING_MAX]);
int gpt_partition_type_uuid_from_string(const char *s, sd_id128_t *ret);
typedef struct GptPartitionType {
sd_id128_t uuid;
const char *name;
} GptPartitionType;
extern const GptPartitionType gpt_partition_type_table[];

View File

@ -10,24 +10,11 @@
#include "pretty-print.h"
#include "terminal-util.h"
int id128_pretty_print(sd_id128_t id, Id128PrettyPrintMode mode) {
int id128_pretty_print_sample(const char *name, sd_id128_t id) {
_cleanup_free_ char *man_link = NULL, *mod_link = NULL;
const char *on, *off;
unsigned i;
assert(mode >= 0);
assert(mode < _ID128_PRETTY_PRINT_MODE_MAX);
if (mode == ID128_PRINT_ID128) {
printf(SD_ID128_FORMAT_STR "\n",
SD_ID128_FORMAT_VAL(id));
return 0;
} else if (mode == ID128_PRINT_UUID) {
printf(SD_ID128_UUID_FORMAT_STR "\n",
SD_ID128_FORMAT_VAL(id));
return 0;
}
on = ansi_highlight();
off = ansi_normal();
@ -42,24 +29,41 @@ int id128_pretty_print(sd_id128_t id, Id128PrettyPrintMode mode) {
"As UUID:\n"
"%s" SD_ID128_UUID_FORMAT_STR "%s\n\n"
"As %s macro:\n"
"%s#define XYZ SD_ID128_MAKE(",
"%s#define %s SD_ID128_MAKE(",
on, SD_ID128_FORMAT_VAL(id), off,
on, SD_ID128_FORMAT_VAL(id), off,
man_link,
on);
on, name);
for (i = 0; i < 16; i++)
printf("%02x%s", id.bytes[i], i != 15 ? "," : "");
printf(")%s\n\n", off);
printf("As Python constant:\n"
">>> import %s\n"
">>> %sXYZ = uuid.UUID('" SD_ID128_FORMAT_STR "')%s\n",
">>> %s%s = uuid.UUID('" SD_ID128_FORMAT_STR "')%s\n",
mod_link,
on, SD_ID128_FORMAT_VAL(id), off);
on, name, SD_ID128_FORMAT_VAL(id), off);
return 0;
}
int id128_pretty_print(sd_id128_t id, Id128PrettyPrintMode mode) {
assert(mode >= 0);
assert(mode < _ID128_PRETTY_PRINT_MODE_MAX);
if (mode == ID128_PRINT_ID128) {
printf(SD_ID128_FORMAT_STR "\n",
SD_ID128_FORMAT_VAL(id));
return 0;
} else if (mode == ID128_PRINT_UUID) {
printf(SD_ID128_UUID_FORMAT_STR "\n",
SD_ID128_FORMAT_VAL(id));
return 0;
} else
return id128_pretty_print_sample("XYZ", id);
}
int id128_print_new(Id128PrettyPrintMode mode) {
sd_id128_t id;
int r;

View File

@ -14,5 +14,6 @@ typedef enum Id128PrettyPrintMode {
_ID128_PRETTY_PRINT_MODE_INVALID = -1
} Id128PrettyPrintMode;
int id128_pretty_print_sample(const char *name, sd_id128_t id);
int id128_pretty_print(sd_id128_t id, Id128PrettyPrintMode mode);
int id128_print_new(Id128PrettyPrintMode mode);

View File

@ -27,6 +27,8 @@ shared_sources = files('''
bus-unit-util.h
bus-util.c
bus-util.h
bus-polkit.c
bus-polkit.h
bus-wait-for-jobs.c
bus-wait-for-jobs.h
bus-wait-for-units.c
@ -85,6 +87,7 @@ shared_sources = files('''
fstab-util.h
generator.c
generator.h
gpt.c
gpt.h
group-record-nss.c
group-record-nss.h

View File

@ -96,6 +96,22 @@ static void test_cunescape(void) {
assert_se(cunescape("A=A\\\\x0aB", UNESCAPE_RELAX, &unescaped) >= 0);
assert_se(streq_ptr(unescaped, "A=A\\x0aB"));
unescaped = mfree(unescaped);
assert_se(cunescape("\\x00\\x00\\x00", UNESCAPE_ACCEPT_NUL, &unescaped) == 3);
assert_se(memcmp(unescaped, "\0\0\0", 3) == 0);
unescaped = mfree(unescaped);
assert_se(cunescape("\\u0000\\u0000\\u0000", UNESCAPE_ACCEPT_NUL, &unescaped) == 3);
assert_se(memcmp(unescaped, "\0\0\0", 3) == 0);
unescaped = mfree(unescaped);
assert_se(cunescape("\\U00000000\\U00000000\\U00000000", UNESCAPE_ACCEPT_NUL, &unescaped) == 3);
assert_se(memcmp(unescaped, "\0\0\0", 3) == 0);
unescaped = mfree(unescaped);
assert_se(cunescape("\\000\\000\\000", UNESCAPE_ACCEPT_NUL, &unescaped) == 3);
assert_se(memcmp(unescaped, "\0\0\0", 3) == 0);
}
static void test_shell_escape_one(const char *s, const char *bad, const char *expected) {

View File

@ -12,7 +12,7 @@
#include "alloc-util.h"
#include "bus-common-errors.h"
#include "bus-error.h"
#include "bus-util.h"
#include "bus-polkit.h"
#include "clock-util.h"
#include "conf-files.h"
#include "def.h"

View File

@ -114,6 +114,7 @@ test_run() {
prepare_testdir ${f%.input}
cp $f $TESTDIR/usr/lib/sysusers.d/test.conf
systemd-sysusers --root=$TESTDIR 2> /dev/null
journalctl --sync
journalctl -t systemd-sysusers -o cat | tail -n1 > $TESTDIR/tmp/err
if ! diff -u $TESTDIR/tmp/err ${f%.*}.expected-err; then
echo "**** Unexpected error output for $f"

View File

@ -14,7 +14,7 @@ test_setup() {
setup_basic_environment
mask_supporting_services
dracut_install truncate sfdisk
dracut_install truncate sfdisk grep
# setup the testsuite service
cat >$initdir/etc/systemd/system/testsuite.service <<EOF

View File

@ -15,7 +15,7 @@ SEED=e2a40bf9-73f1-4278-9160-49c031e7aef8
systemd-repart /tmp/zzz --empty=force --dry-run=no --seed=$SEED
sfdisk -d /tmp/zzz > /tmp/empty
sfdisk -d /tmp/zzz | grep -v -e 'sector-size' -e '^$' > /tmp/empty
cmp /tmp/empty - <<EOF
label: gpt
@ -24,7 +24,6 @@ device: /tmp/zzz
unit: sectors
first-lba: 2048
last-lba: 2097118
EOF
mkdir /tmp/definitions
@ -50,7 +49,7 @@ EOF
systemd-repart /tmp/zzz --dry-run=no --seed=$SEED --definitions=/tmp/definitions
sfdisk -d /tmp/zzz > /tmp/populated
sfdisk -d /tmp/zzz | grep -v -e 'sector-size' -e '^$' > /tmp/populated
cmp /tmp/populated - <<EOF
label: gpt
@ -59,7 +58,6 @@ device: /tmp/zzz
unit: sectors
first-lba: 2048
last-lba: 2097118
/tmp/zzz1 : start= 2048, size= 591856, type=933AC7E1-2EB4-4F13-B844-0E14E2AEF915, uuid=A6005774-F558-4330-A8E5-D6D2C01C01D6, name="home"
/tmp/zzz2 : start= 593904, size= 591856, type=4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709, uuid=CE9C76EB-A8F1-40FF-813C-11DCA6C0A55B, name="root-x86-64"
/tmp/zzz3 : start= 1185760, size= 591864, type=4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709, uuid=AC60A837-550C-43BD-B5C4-9CB73B884E79, name="root-x86-64-2"
@ -79,7 +77,7 @@ EOF
systemd-repart /tmp/zzz --dry-run=no --seed=$SEED --definitions=/tmp/definitions
sfdisk -d /tmp/zzz > /tmp/populated2
sfdisk -d /tmp/zzz | grep -v -e 'sector-size' -e '^$' > /tmp/populated2
cmp /tmp/populated2 - <<EOF
label: gpt
@ -88,7 +86,6 @@ device: /tmp/zzz
unit: sectors
first-lba: 2048
last-lba: 2097118
/tmp/zzz1 : start= 2048, size= 591856, type=933AC7E1-2EB4-4F13-B844-0E14E2AEF915, uuid=A6005774-F558-4330-A8E5-D6D2C01C01D6, name="home"
/tmp/zzz2 : start= 593904, size= 591856, type=4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709, uuid=CE9C76EB-A8F1-40FF-813C-11DCA6C0A55B, name="root-x86-64"
/tmp/zzz3 : start= 1185760, size= 591864, type=4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709, uuid=AC60A837-550C-43BD-B5C4-9CB73B884E79, name="root-x86-64-2"
@ -100,7 +97,7 @@ truncate -s 2G /tmp/zzz
systemd-repart /tmp/zzz --dry-run=no --seed=$SEED --definitions=/tmp/definitions
sfdisk -d /tmp/zzz > /tmp/populated3
sfdisk -d /tmp/zzz | grep -v -e 'sector-size' -e '^$' > /tmp/populated3
cmp /tmp/populated3 - <<EOF
label: gpt
@ -109,7 +106,6 @@ device: /tmp/zzz
unit: sectors
first-lba: 2048
last-lba: 4194270
/tmp/zzz1 : start= 2048, size= 591856, type=933AC7E1-2EB4-4F13-B844-0E14E2AEF915, uuid=A6005774-F558-4330-A8E5-D6D2C01C01D6, name="home"
/tmp/zzz2 : start= 593904, size= 591856, type=4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709, uuid=CE9C76EB-A8F1-40FF-813C-11DCA6C0A55B, name="root-x86-64"
/tmp/zzz3 : start= 1185760, size= 591864, type=4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709, uuid=AC60A837-550C-43BD-B5C4-9CB73B884E79, name="root-x86-64-2"

View File

@ -33,7 +33,7 @@ ProtectKernelLogs=yes
ProtectSystem=strict
Restart=on-failure
RestartSec=0
RestrictAddressFamilies=AF_UNIX AF_NETLINK AF_INET AF_INET6 AF_PACKET
RestrictAddressFamilies=AF_UNIX AF_NETLINK AF_INET AF_INET6 AF_PACKET AF_ALG
RestrictNamespaces=yes
RestrictRealtime=yes
RestrictSUIDSGID=yes