Compare commits
32 Commits
58abbbcc6b
...
7d20404816
Author | SHA1 | Date |
---|---|---|
Lennart Poettering | 7d20404816 | |
Lennart Poettering | b940fb1f4f | |
Ashley Davis | 8bc943b472 | |
Lennart Poettering | e0db55a643 | |
Lennart Poettering | 10c238b2cc | |
Lennart Poettering | e5667705fa | |
Lennart Poettering | 979bdc47c9 | |
Zbigniew Jędrzejewski-Szmek | ebe2ab60cc | |
Zbigniew Jędrzejewski-Szmek | d2b45da40a | |
Lennart Poettering | 8615bec7a0 | |
Yu Watanabe | 1b3cccfdac | |
Lennart Poettering | 4523f1db0f | |
Yu Watanabe | 11a182aa1e | |
dann frazier | 37b9966e25 | |
Lennart Poettering | 766840af42 | |
Lennart Poettering | 006c44c1e8 | |
Kevin Kuehler | 022d334561 | |
Yu Watanabe | 732e3a6104 | |
Yu Watanabe | a6a36dea2d | |
Yu Watanabe | 0e72e469f8 | |
Yu Watanabe | 46dc83440f | |
Kevin Kuehler | 9f37272a19 | |
Kevin Kuehler | fc64760dda | |
Yu Watanabe | fe5a698f76 | |
Yu Watanabe | a14c18ba7b | |
Zbigniew Jędrzejewski-Szmek | dc972b0740 | |
Zbigniew Jędrzejewski-Szmek | 19ce38ce62 | |
Lennart Poettering | 4acf0cfd2f | |
Lennart Poettering | 269e4d2d6b | |
Yu Watanabe | 2c0d7ed393 | |
Yu Watanabe | 0ce0e3470e | |
Yu Watanabe | 8ae7b8a1e1 |
37
TODO
37
TODO
|
@ -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.
|
||||
|
|
|
@ -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`.
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -192,6 +192,7 @@ All execution-related settings are available for transient units.
|
|||
✓ PrivateUsers=
|
||||
✓ ProtectSystem=
|
||||
✓ ProtectHome=
|
||||
✓ ProtectClock=
|
||||
✓ MountFlags=
|
||||
✓ MountAPIVFS=
|
||||
✓ Personality=
|
||||
|
|
|
@ -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", &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", &x);</programlisting>
|
||||
|
||||
<para>Read all types of integers:</para>
|
||||
|
||||
<programlisting>uint8_t y;
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -29,22 +29,27 @@
|
|||
#define SHELL_NEED_ESCAPE_POSIX "\\\'"
|
||||
|
||||
typedef enum UnescapeFlags {
|
||||
UNESCAPE_RELAX = 1,
|
||||
UNESCAPE_RELAX = 1 << 0,
|
||||
UNESCAPE_ACCEPT_NUL = 1 << 1,
|
||||
} UnescapeFlags;
|
||||
|
||||
typedef enum EscapeStyle {
|
||||
ESCAPE_BACKSLASH = 1,
|
||||
ESCAPE_POSIX = 2,
|
||||
ESCAPE_POSIX = 2,
|
||||
} EscapeStyle;
|
||||
|
||||
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) {
|
||||
|
|
|
@ -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++] = '\\';
|
||||
|
|
|
@ -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:
|
||||
;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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 },
|
||||
{}
|
||||
};
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -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);
|
|
@ -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",
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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[];
|
||||
|
|
|
@ -10,24 +10,11 @@
|
|||
#include "pretty-print.h"
|
||||
#include "terminal-util.h"
|
||||
|
||||
int id128_pretty_print(sd_id128_t id, Id128PrettyPrintMode mode) {
|
||||
_cleanup_free_ char *man_link = NULL, *mod_link = NULL;
|
||||
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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue